diff options
Diffstat (limited to 'flash/uart_boot')
-rw-r--r-- | flash/uart_boot/README | 8 | ||||
-rw-r--r-- | flash/uart_boot/client.c | 738 | ||||
-rw-r--r-- | flash/uart_boot/client.h | 21 | ||||
-rw-r--r-- | flash/uart_boot/flash.c | 77 | ||||
-rw-r--r-- | flash/uart_boot/flash.h | 9 | ||||
-rw-r--r-- | flash/uart_boot/minimon.h | 23 | ||||
-rw-r--r-- | flash/uart_boot/scalar_types.h | 44 | ||||
-rw-r--r-- | flash/uart_boot/uart.h | 56 | ||||
-rw-r--r-- | flash/uart_boot/uart_boot.c | 337 | ||||
-rw-r--r-- | flash/uart_boot/uart_boot.dsp | 130 | ||||
-rw-r--r-- | flash/uart_boot/uart_win.c | 138 |
11 files changed, 1581 insertions, 0 deletions
diff --git a/flash/uart_boot/README b/flash/uart_boot/README new file mode 100644 index 0000000000..edfa20c121 --- /dev/null +++ b/flash/uart_boot/README | |||
@@ -0,0 +1,8 @@ | |||
1 | (c) 2003 by Jörg Hohensohn | ||
2 | |||
3 | This is the client side for MiniMon, a command line program that communicates with it. | ||
4 | It can be used to reflash a box from ground up, load a program like gdb stub or Rockbox, | ||
5 | and other diagnostics. | ||
6 | |||
7 | Current implementation is for Windows, but with a different UART implementation | ||
8 | it should work for other platforms (Linux) as well. | ||
diff --git a/flash/uart_boot/client.c b/flash/uart_boot/client.c new file mode 100644 index 0000000000..a98edc60cb --- /dev/null +++ b/flash/uart_boot/client.c | |||
@@ -0,0 +1,738 @@ | |||
1 | // client.cpp : functions for monitor download and communication. | ||
2 | // | ||
3 | |||
4 | #include <stdio.h> | ||
5 | #include <stdlib.h> | ||
6 | #include "scalar_types.h" // (U)INT8/16/32 | ||
7 | #include "Uart.h" // platform abstraction for UART | ||
8 | #include "minimon.h" // protocol of my little monitor | ||
9 | |||
10 | // do the baudrate configuration for the Player | ||
11 | int ConfigFirstlevelPlayer (tUartHandle serial_handle) | ||
12 | { | ||
13 | UINT32 result_nbr; | ||
14 | |||
15 | if(!UartConfig(serial_handle, 4800, eMARKPARITY, eTWOSTOPBITS, 8)) | ||
16 | { | ||
17 | UINT32 dwErr = GET_LAST_ERR(); | ||
18 | printf("Error %d setting up COM params for baudrate byte\n", dwErr); | ||
19 | exit(1); | ||
20 | } | ||
21 | |||
22 | // this will read as 0x19 when viewed with 2300 baud like the player does | ||
23 | result_nbr = UartWrite(serial_handle, (UINT8*)"\x86\xC0", 2); | ||
24 | if (result_nbr != 2) | ||
25 | { | ||
26 | UINT32 dwErr = GET_LAST_ERR(); | ||
27 | printf("Error %d setting up COM params for baudrate byte\n", dwErr); | ||
28 | } | ||
29 | |||
30 | SLEEP(100); // wait for the chars to be sent, is there a better way? | ||
31 | |||
32 | // the read 0x19 means 14423 baud with 12 MHz | ||
33 | if(!UartConfig(serial_handle, 14400, eNOPARITY, eONESTOPBIT, 8)) | ||
34 | { | ||
35 | printf("Error setting up COM params for 1st level loader\n"); | ||
36 | exit(1); | ||
37 | } | ||
38 | |||
39 | return 0; | ||
40 | } | ||
41 | |||
42 | |||
43 | // do the baudrate configuration for the Recoder/FM | ||
44 | int ConfigFirstlevelRecorder (tUartHandle serial_handle) | ||
45 | { | ||
46 | UINT32 result_nbr; | ||
47 | |||
48 | if(!UartConfig(serial_handle, 4800, eNOPARITY, eTWOSTOPBITS, 8)) | ||
49 | { | ||
50 | UINT32 dwErr = GET_LAST_ERR(); | ||
51 | printf("Error %d setting up COM params for baudrate byte\n", dwErr); | ||
52 | exit(1); | ||
53 | } | ||
54 | |||
55 | // this will read as 0x08 when viewed with 2120 baud like the recorder does | ||
56 | result_nbr = UartWrite(serial_handle, (UINT8*)"\x00\x00", 2); | ||
57 | if(result_nbr != 2) | ||
58 | { | ||
59 | printf("Error transmitting baudrate byte\n"); | ||
60 | exit(1); | ||
61 | } | ||
62 | |||
63 | SLEEP(100); // wait for the chars to be sent, is there a better way? | ||
64 | |||
65 | // the read 0x08 means 38400 baud with 11.0592 MHz | ||
66 | if(!UartConfig(serial_handle, 38400, eNOPARITY, eONESTOPBIT, 8)) | ||
67 | { | ||
68 | UINT32 dwErr = GET_LAST_ERR(); | ||
69 | printf("Error %d setting up COM params for 1st level loader\n", dwErr); | ||
70 | exit(1); | ||
71 | } | ||
72 | |||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | |||
77 | // transfer a byte for the monitor download, with or without acknowledge | ||
78 | int DownloadByte(tUartHandle serial_handle, unsigned char byte, bool bAck) | ||
79 | { | ||
80 | unsigned char received; | ||
81 | bool bRecorder = true; // false for player | ||
82 | |||
83 | while (1) | ||
84 | { | ||
85 | UartWrite(serial_handle, &byte, 1); | ||
86 | if (bAck) | ||
87 | { | ||
88 | UartRead(serial_handle, &received, 1); | ||
89 | if (received == byte) | ||
90 | { | ||
91 | UartWrite(serial_handle, (UINT8*)"\x01", 1); // ack success | ||
92 | break; // exit the loop | ||
93 | } | ||
94 | else | ||
95 | { | ||
96 | printf("Error transmitting monitor byte 0x%02X, got 0x%0X\n", byte, received); | ||
97 | UartWrite(serial_handle, (UINT8*)"\x00", 1); // ack fail, try again | ||
98 | } | ||
99 | } | ||
100 | else | ||
101 | break; // no loop | ||
102 | } | ||
103 | return 1; | ||
104 | } | ||
105 | |||
106 | |||
107 | // download our little monitor, the box must have been just freshly switched on for this to work | ||
108 | int DownloadMonitor(tUartHandle serial_handle, bool bRecorder, char* szFilename) | ||
109 | { | ||
110 | FILE* pFile; | ||
111 | size_t filesize; | ||
112 | UINT8 byte; | ||
113 | unsigned i; | ||
114 | |||
115 | // hard-coded parameters | ||
116 | bool bAck = true; // configure if acknowledged download (without useful for remote pin boot) | ||
117 | UINT32 TargetLoad = 0x0FFFF000; // target load address | ||
118 | |||
119 | pFile = fopen(szFilename, "rb"); | ||
120 | if (pFile == NULL) | ||
121 | { | ||
122 | printf("\nMonitor file %s not found, exiting\n", szFilename); | ||
123 | exit(1); | ||
124 | } | ||
125 | |||
126 | // determine file size | ||
127 | fseek(pFile, 0, SEEK_END); | ||
128 | filesize = ftell(pFile); | ||
129 | fseek(pFile, 0, SEEK_SET); | ||
130 | |||
131 | // This is _really_ tricky! The box expects a BRR value in a nonstandard baudrate, | ||
132 | // which a PC can't generate. I'm using a higher one with some wild settings | ||
133 | // to generate a pulse series that: | ||
134 | // 1) looks like a stable byte when sampled with the nonstandard baudrate | ||
135 | // 2) gives a BRR value to the box which results in a baudrate the PC can also use | ||
136 | if (bRecorder) | ||
137 | { | ||
138 | ConfigFirstlevelRecorder(serial_handle); | ||
139 | } | ||
140 | else | ||
141 | { | ||
142 | ConfigFirstlevelPlayer(serial_handle); | ||
143 | } | ||
144 | |||
145 | UartWrite(serial_handle, bAck ? (UINT8*)"\x01" : (UINT8*)"\x00", 1); // ACK mode | ||
146 | |||
147 | // transmit the size, little endian | ||
148 | DownloadByte(serial_handle, (UINT8)( filesize & 0xFF), bAck); | ||
149 | DownloadByte(serial_handle, (UINT8)((filesize>>8) & 0xFF), bAck); | ||
150 | DownloadByte(serial_handle, (UINT8)((filesize>>16) & 0xFF), bAck); | ||
151 | DownloadByte(serial_handle, (UINT8)((filesize>>24) & 0xFF), bAck); | ||
152 | |||
153 | // transmit the load address, little endian | ||
154 | DownloadByte(serial_handle, (UINT8)( TargetLoad & 0xFF), bAck); | ||
155 | DownloadByte(serial_handle, (UINT8)((TargetLoad>>8) & 0xFF), bAck); | ||
156 | DownloadByte(serial_handle, (UINT8)((TargetLoad>>16) & 0xFF), bAck); | ||
157 | DownloadByte(serial_handle, (UINT8)((TargetLoad>>24) & 0xFF), bAck); | ||
158 | |||
159 | // transmit the command byte | ||
160 | DownloadByte(serial_handle, 0xFF, bAck); // 0xFF means execute the transferred image | ||
161 | |||
162 | // transmit the image | ||
163 | for (i=0; i<filesize; i++) | ||
164 | { | ||
165 | fread(&byte, 1, 1, pFile); | ||
166 | DownloadByte(serial_handle, byte, bAck); | ||
167 | } | ||
168 | |||
169 | fclose (pFile); | ||
170 | |||
171 | // now the image should have been started, red LED off | ||
172 | |||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | |||
177 | // wait for a fixed string to be received (no foolproof algorithm, | ||
178 | // may overlook if the searched string contains repeatitions) | ||
179 | int WaitForString(tUartHandle serial_handle, char* pszWait) | ||
180 | { | ||
181 | int i = 0; | ||
182 | unsigned char received; | ||
183 | |||
184 | while(pszWait[i] != '\0') | ||
185 | { | ||
186 | UartRead(serial_handle, &received, 1); | ||
187 | |||
188 | printf("%c", received); // debug | ||
189 | |||
190 | if (received == pszWait[i]) | ||
191 | i++; // continue | ||
192 | else | ||
193 | i=0; // mismatch, start over | ||
194 | } | ||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | |||
199 | // send a sting and check the echo | ||
200 | int SendWithEcho(tUartHandle serial_handle, char* pszSend) | ||
201 | { | ||
202 | int i = 0; | ||
203 | unsigned char received; | ||
204 | |||
205 | while(pszSend[i] != '\0') | ||
206 | { | ||
207 | UartWrite(serial_handle, (unsigned char*)(pszSend + i), 1); // send char | ||
208 | do | ||
209 | { | ||
210 | UartRead(serial_handle, &received, 1); // receive echo | ||
211 | printf("%c", received); // debug | ||
212 | } | ||
213 | while (received != pszSend[i]); // should normally be equal | ||
214 | i++; // next char | ||
215 | } | ||
216 | return 0; | ||
217 | } | ||
218 | |||
219 | |||
220 | // rarely used variant: download our monitor using the built-in Archos monitor | ||
221 | int DownloadArchosMonitor(tUartHandle serial_handle, char* szFilename) | ||
222 | { | ||
223 | FILE* pFile; | ||
224 | size_t filesize; | ||
225 | UINT8 byte; | ||
226 | UINT16 checksum = 0; | ||
227 | unsigned i; | ||
228 | |||
229 | // the onboard monitor uses 115200 baud | ||
230 | if(!UartConfig(serial_handle, 115200, eNOPARITY, eONESTOPBIT, 8)) | ||
231 | { | ||
232 | UINT32 dwErr = GET_LAST_ERR(); | ||
233 | printf("Error %d setting up COM params for baudrate %d\n", dwErr, 115200); | ||
234 | exit(1); | ||
235 | } | ||
236 | |||
237 | // wait for receiving "#SERIAL#" | ||
238 | WaitForString(serial_handle, "#SERIAL#"); | ||
239 | |||
240 | // send magic "SRL" command to get interactive mode | ||
241 | SendWithEcho(serial_handle, "SRL\r"); | ||
242 | |||
243 | // wait for menu completion: "ROOT>" at the end | ||
244 | WaitForString(serial_handle, "ROOT>"); | ||
245 | |||
246 | // send upload command "UP" | ||
247 | SendWithEcho(serial_handle, "UP\r"); | ||
248 | |||
249 | pFile = fopen(szFilename, "rb"); | ||
250 | if (pFile == NULL) | ||
251 | { | ||
252 | printf("\nMonitor file %s not found, exiting\n", szFilename); | ||
253 | exit(1); | ||
254 | } | ||
255 | |||
256 | // determine file size | ||
257 | fseek(pFile, 0, SEEK_END); | ||
258 | filesize = ftell(pFile); | ||
259 | fseek(pFile, 0, SEEK_SET); | ||
260 | |||
261 | // calculate checksum | ||
262 | for (i=0; i<filesize; i++) | ||
263 | { | ||
264 | fread(&byte, 1, 1, pFile); | ||
265 | checksum += byte; | ||
266 | } | ||
267 | fseek(pFile, 0, SEEK_SET); | ||
268 | |||
269 | // send header | ||
270 | |||
271 | // size as 32 bit little endian | ||
272 | byte = (UINT8)( filesize & 0xFF); | ||
273 | UartWrite(serial_handle, &byte, 1); | ||
274 | byte = (UINT8)((filesize>>8) & 0xFF); | ||
275 | UartWrite(serial_handle, &byte, 1); | ||
276 | byte = (UINT8)((filesize>>16) & 0xFF); | ||
277 | UartWrite(serial_handle, &byte, 1); | ||
278 | byte = (UINT8)((filesize>>24) & 0xFF); | ||
279 | UartWrite(serial_handle, &byte, 1); | ||
280 | |||
281 | // checksum as 16 bit little endian | ||
282 | byte = (UINT8)( checksum & 0xFF); | ||
283 | UartWrite(serial_handle, &byte, 1); | ||
284 | byte = (UINT8)((checksum>>8) & 0xFF); | ||
285 | UartWrite(serial_handle, &byte, 1); | ||
286 | |||
287 | UartWrite(serial_handle, (unsigned char*)"\x00", 1); // kind (3 means flash) | ||
288 | UartWrite(serial_handle, (unsigned char*)"\x00", 1); // ignored byte | ||
289 | |||
290 | // wait for monitor to accept data | ||
291 | WaitForString(serial_handle, "#OKCTRL#"); | ||
292 | |||
293 | // transmit the image | ||
294 | for (i=0; i<filesize; i++) | ||
295 | { | ||
296 | fread(&byte, 1, 1, pFile); | ||
297 | UartWrite(serial_handle, &byte, 1); // payload | ||
298 | } | ||
299 | fclose (pFile); | ||
300 | |||
301 | UartWrite(serial_handle, (unsigned char*)"\x00", 1); // ignored byte | ||
302 | |||
303 | // wait for menu completion: "ROOT>" at the end | ||
304 | WaitForString(serial_handle, "ROOT>"); | ||
305 | |||
306 | // send start program command "SPRO" | ||
307 | SendWithEcho(serial_handle, "SPRO\r"); | ||
308 | |||
309 | SLEEP(100); // wait a little while for startup | ||
310 | |||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | |||
315 | /********** Target functions using the Monitor Protocol **********/ | ||
316 | |||
317 | // read a byte using the target monitor | ||
318 | UINT8 ReadByte(tUartHandle serial_handle, UINT32 addr) | ||
319 | { | ||
320 | UINT8 send; | ||
321 | UINT8 received; | ||
322 | |||
323 | // send the address command | ||
324 | send = ADDRESS; | ||
325 | UartWrite(serial_handle, &send, 1); | ||
326 | |||
327 | // transmit the address, big endian | ||
328 | send = (UINT8)((addr>>24) & 0xFF); | ||
329 | UartWrite(serial_handle, &send, 1); | ||
330 | send = (UINT8)((addr>>16) & 0xFF); | ||
331 | UartWrite(serial_handle, &send, 1); | ||
332 | send = (UINT8)((addr>>8) & 0xFF); | ||
333 | UartWrite(serial_handle, &send, 1); | ||
334 | send = (UINT8)(addr & 0xFF); | ||
335 | UartWrite(serial_handle, &send, 1); | ||
336 | |||
337 | UartRead(serial_handle, &received, 1); // response | ||
338 | if (received != ADDRESS) | ||
339 | { | ||
340 | printf("Protocol error!\n"); | ||
341 | return 1; | ||
342 | } | ||
343 | |||
344 | // send the read command | ||
345 | send = BYTE_READ; | ||
346 | UartWrite(serial_handle, &send, 1); | ||
347 | |||
348 | UartRead(serial_handle, &received, 1); // response | ||
349 | |||
350 | return received; | ||
351 | } | ||
352 | |||
353 | |||
354 | // write a byte using the target monitor | ||
355 | int WriteByte(tUartHandle serial_handle, UINT32 addr, UINT8 byte) | ||
356 | { | ||
357 | UINT8 send; | ||
358 | UINT8 received; | ||
359 | |||
360 | // send the address command | ||
361 | send = ADDRESS; | ||
362 | UartWrite(serial_handle, &send, 1); | ||
363 | |||
364 | // transmit the address, big endian | ||
365 | send = (UINT8)((addr>>24) & 0xFF); | ||
366 | UartWrite(serial_handle, &send, 1); | ||
367 | send = (UINT8)((addr>>16) & 0xFF); | ||
368 | UartWrite(serial_handle, &send, 1); | ||
369 | send = (UINT8)((addr>>8) & 0xFF); | ||
370 | UartWrite(serial_handle, &send, 1); | ||
371 | send = (UINT8)(addr & 0xFF); | ||
372 | UartWrite(serial_handle, &send, 1); | ||
373 | |||
374 | UartRead(serial_handle, &received, 1); // response | ||
375 | if (received != ADDRESS) | ||
376 | { | ||
377 | printf("Protocol error, receiced 0x%02X!\n", received); | ||
378 | return 1; | ||
379 | } | ||
380 | |||
381 | // send the write command | ||
382 | send = BYTE_WRITE; | ||
383 | UartWrite(serial_handle, &send, 1); | ||
384 | |||
385 | // transmit the data | ||
386 | UartWrite(serial_handle, &byte, 1); | ||
387 | |||
388 | UartRead(serial_handle, &received, 1); // response | ||
389 | |||
390 | if (received != BYTE_WRITE) | ||
391 | { | ||
392 | printf("Protocol error!\n"); | ||
393 | return 1; | ||
394 | } | ||
395 | |||
396 | return 0; | ||
397 | } | ||
398 | |||
399 | |||
400 | // read many bytes using the target monitor | ||
401 | int ReadByteMultiple(tUartHandle serial_handle, UINT32 addr, UINT32 size, UINT8* pBuffer) | ||
402 | { | ||
403 | UINT8 send, received; | ||
404 | |||
405 | // send the address command | ||
406 | send = ADDRESS; | ||
407 | UartWrite(serial_handle, &send, 1); | ||
408 | |||
409 | // transmit the address, big endian | ||
410 | send = (UINT8)((addr>>24) & 0xFF); | ||
411 | UartWrite(serial_handle, &send, 1); | ||
412 | send = (UINT8)((addr>>16) & 0xFF); | ||
413 | UartWrite(serial_handle, &send, 1); | ||
414 | send = (UINT8)((addr>>8) & 0xFF); | ||
415 | UartWrite(serial_handle, &send, 1); | ||
416 | send = (UINT8)(addr & 0xFF); | ||
417 | UartWrite(serial_handle, &send, 1); | ||
418 | |||
419 | UartRead(serial_handle, &received, 1); // response | ||
420 | if (received != ADDRESS) | ||
421 | { | ||
422 | printf("Protocol error!\n"); | ||
423 | return 1; | ||
424 | } | ||
425 | |||
426 | while (size) | ||
427 | { | ||
428 | if (size >= 16) | ||
429 | { // we can use a "burst" command | ||
430 | send = BYTE_READ16; | ||
431 | UartWrite(serial_handle, &send, 1); // send the read command | ||
432 | UartRead(serial_handle, pBuffer, 16); // data response | ||
433 | pBuffer += 16; | ||
434 | size -= 16; | ||
435 | } | ||
436 | else | ||
437 | { // use single byte command | ||
438 | send = BYTE_READ; | ||
439 | UartWrite(serial_handle, &send, 1); // send the read command | ||
440 | UartRead(serial_handle, pBuffer++, 1); // data response | ||
441 | size--; | ||
442 | } | ||
443 | } | ||
444 | |||
445 | return 0; | ||
446 | } | ||
447 | |||
448 | |||
449 | // write many bytes using the target monitor | ||
450 | int WriteByteMultiple(tUartHandle serial_handle, UINT32 addr, UINT32 size, UINT8* pBuffer) | ||
451 | { | ||
452 | UINT8 send, received; | ||
453 | |||
454 | // send the address command | ||
455 | send = ADDRESS; | ||
456 | UartWrite(serial_handle, &send, 1); | ||
457 | |||
458 | // transmit the address, big endian | ||
459 | send = (UINT8)((addr>>24) & 0xFF); | ||
460 | UartWrite(serial_handle, &send, 1); | ||
461 | send = (UINT8)((addr>>16) & 0xFF); | ||
462 | UartWrite(serial_handle, &send, 1); | ||
463 | send = (UINT8)((addr>>8) & 0xFF); | ||
464 | UartWrite(serial_handle, &send, 1); | ||
465 | send = (UINT8)(addr & 0xFF); | ||
466 | UartWrite(serial_handle, &send, 1); | ||
467 | |||
468 | UartRead(serial_handle, &received, 1); // response | ||
469 | if (received != ADDRESS) | ||
470 | { | ||
471 | printf("Protocol error!\n"); | ||
472 | return 1; | ||
473 | } | ||
474 | |||
475 | while (size) | ||
476 | { | ||
477 | if (size >= 16) | ||
478 | { // we can use a "burst" command | ||
479 | send = BYTE_WRITE16; | ||
480 | UartWrite(serial_handle, &send, 1); // send the write command | ||
481 | UartWrite(serial_handle, pBuffer, 16); // transmit the data | ||
482 | UartRead(serial_handle, &received, 1); // response | ||
483 | if (received != BYTE_WRITE16) | ||
484 | { | ||
485 | printf("Protocol error!\n"); | ||
486 | return 1; | ||
487 | } | ||
488 | pBuffer += 16; | ||
489 | size -= 16; | ||
490 | } | ||
491 | else | ||
492 | { // use single byte command | ||
493 | send = BYTE_WRITE; | ||
494 | UartWrite(serial_handle, &send, 1); // send the write command | ||
495 | UartWrite(serial_handle, pBuffer++, 1); // transmit the data | ||
496 | UartRead(serial_handle, &received, 1); // response | ||
497 | if (received != BYTE_WRITE) | ||
498 | { | ||
499 | printf("Protocol error!\n"); | ||
500 | return 1; | ||
501 | } | ||
502 | size--; | ||
503 | } | ||
504 | } | ||
505 | |||
506 | return 0; | ||
507 | } | ||
508 | |||
509 | |||
510 | // write many bytes using the target monitor | ||
511 | int FlashByteMultiple(tUartHandle serial_handle, UINT32 addr, UINT32 size, UINT8* pBuffer) | ||
512 | { | ||
513 | UINT8 send, received; | ||
514 | |||
515 | // send the address command | ||
516 | send = ADDRESS; | ||
517 | UartWrite(serial_handle, &send, 1); | ||
518 | |||
519 | // transmit the address, big endian | ||
520 | send = (UINT8)((addr>>24) & 0xFF); | ||
521 | UartWrite(serial_handle, &send, 1); | ||
522 | send = (UINT8)((addr>>16) & 0xFF); | ||
523 | UartWrite(serial_handle, &send, 1); | ||
524 | send = (UINT8)((addr>>8) & 0xFF); | ||
525 | UartWrite(serial_handle, &send, 1); | ||
526 | send = (UINT8)(addr & 0xFF); | ||
527 | UartWrite(serial_handle, &send, 1); | ||
528 | |||
529 | UartRead(serial_handle, &received, 1); // response | ||
530 | if (received != ADDRESS) | ||
531 | { | ||
532 | printf("Protocol error!\n"); | ||
533 | return 1; | ||
534 | } | ||
535 | |||
536 | while (size) | ||
537 | { | ||
538 | if (size >= 16) | ||
539 | { // we can use a "burst" command | ||
540 | send = BYTE_FLASH16; | ||
541 | UartWrite(serial_handle, &send, 1); // send the write command | ||
542 | UartWrite(serial_handle, pBuffer, 16); // transmit the data | ||
543 | UartRead(serial_handle, &received, 1); // response | ||
544 | if (received != BYTE_FLASH16) | ||
545 | { | ||
546 | printf("Protocol error!\n"); | ||
547 | return 1; | ||
548 | } | ||
549 | pBuffer += 16; | ||
550 | size -= 16; | ||
551 | } | ||
552 | else | ||
553 | { // use single byte command | ||
554 | send = BYTE_FLASH; | ||
555 | UartWrite(serial_handle, &send, 1); // send the write command | ||
556 | UartWrite(serial_handle, pBuffer++, 1); // transmit the data | ||
557 | UartRead(serial_handle, &received, 1); // response | ||
558 | if (received != BYTE_FLASH) | ||
559 | { | ||
560 | printf("Protocol error!\n"); | ||
561 | return 1; | ||
562 | } | ||
563 | size--; | ||
564 | } | ||
565 | } | ||
566 | |||
567 | return 0; | ||
568 | } | ||
569 | |||
570 | |||
571 | // read a 16bit halfword using the target monitor | ||
572 | UINT16 ReadHalfword(tUartHandle serial_handle, UINT32 addr) | ||
573 | { | ||
574 | UINT8 send; | ||
575 | UINT8 received; | ||
576 | UINT16 halfword; | ||
577 | |||
578 | // send the address command | ||
579 | send = ADDRESS; | ||
580 | UartWrite(serial_handle, &send, 1); | ||
581 | |||
582 | // transmit the address, big endian | ||
583 | send = (UINT8)((addr>>24) & 0xFF); | ||
584 | UartWrite(serial_handle, &send, 1); | ||
585 | send = (UINT8)((addr>>16) & 0xFF); | ||
586 | UartWrite(serial_handle, &send, 1); | ||
587 | send = (UINT8)((addr>>8) & 0xFF); | ||
588 | UartWrite(serial_handle, &send, 1); | ||
589 | send = (UINT8)(addr & 0xFF); | ||
590 | UartWrite(serial_handle, &send, 1); | ||
591 | |||
592 | UartRead(serial_handle, &received, 1); // response | ||
593 | if (received != ADDRESS) | ||
594 | { | ||
595 | printf("Protocol error!\n"); | ||
596 | return 1; | ||
597 | } | ||
598 | |||
599 | // send the read command | ||
600 | send = HALFWORD_READ; | ||
601 | UartWrite(serial_handle, &send, 1); | ||
602 | |||
603 | UartRead(serial_handle, &received, 1); // response | ||
604 | halfword = received << 8; // highbyte | ||
605 | UartRead(serial_handle, &received, 1); | ||
606 | halfword |= received; // lowbyte | ||
607 | |||
608 | return halfword; | ||
609 | } | ||
610 | |||
611 | |||
612 | // write a 16bit halfword using the target monitor | ||
613 | int WriteHalfword(tUartHandle serial_handle, UINT32 addr, UINT16 halfword) | ||
614 | { | ||
615 | UINT8 send; | ||
616 | UINT8 received; | ||
617 | |||
618 | // send the address command | ||
619 | send = ADDRESS; | ||
620 | UartWrite(serial_handle, &send, 1); | ||
621 | |||
622 | // transmit the address, big endian | ||
623 | send = (UINT8)((addr>>24) & 0xFF); | ||
624 | UartWrite(serial_handle, &send, 1); | ||
625 | send = (UINT8)((addr>>16) & 0xFF); | ||
626 | UartWrite(serial_handle, &send, 1); | ||
627 | send = (UINT8)((addr>>8) & 0xFF); | ||
628 | UartWrite(serial_handle, &send, 1); | ||
629 | send = (UINT8)(addr & 0xFF); | ||
630 | UartWrite(serial_handle, &send, 1); | ||
631 | |||
632 | UartRead(serial_handle, &received, 1); // response | ||
633 | if (received != ADDRESS) | ||
634 | { | ||
635 | printf("Protocol error!\n"); | ||
636 | return 1; | ||
637 | } | ||
638 | |||
639 | // send the write command | ||
640 | send = HALFWORD_WRITE; | ||
641 | UartWrite(serial_handle, &send, 1); | ||
642 | |||
643 | // transmit the data | ||
644 | send = halfword >> 8; // highbyte | ||
645 | UartWrite(serial_handle, &send, 1); | ||
646 | send = halfword & 0xFF; // lowbyte | ||
647 | UartWrite(serial_handle, &send, 1); | ||
648 | |||
649 | UartRead(serial_handle, &received, 1); // response | ||
650 | |||
651 | if (received != HALFWORD_WRITE) | ||
652 | { | ||
653 | printf("Protocol error!\n"); | ||
654 | return 1; | ||
655 | } | ||
656 | |||
657 | return 0; | ||
658 | } | ||
659 | |||
660 | |||
661 | // change baudrate using target monitor | ||
662 | int SetTargetBaudrate(tUartHandle serial_handle, long lClock, long lBaudrate) | ||
663 | { | ||
664 | UINT8 send; | ||
665 | UINT8 received; | ||
666 | UINT8 brr; | ||
667 | long lBRR; | ||
668 | |||
669 | lBRR = lClock / lBaudrate; | ||
670 | lBRR = ((lBRR + 16) / 32) - 1; // with rounding | ||
671 | brr = (UINT8)lBRR; | ||
672 | |||
673 | // send the command | ||
674 | send = BAUDRATE; | ||
675 | UartWrite(serial_handle, &send, 1); | ||
676 | UartWrite(serial_handle, &brr, 1); // send the BRR value | ||
677 | UartRead(serial_handle, &received, 1); // response ack | ||
678 | |||
679 | if (received != BAUDRATE) | ||
680 | { // bad situation, now we're unclear about the baudrate of the target | ||
681 | printf("Protocol error!\n"); | ||
682 | return 1; | ||
683 | } | ||
684 | |||
685 | SLEEP(100); // give it some time to settle | ||
686 | |||
687 | // change our baudrate, too | ||
688 | UartConfig(serial_handle, lBaudrate, eNOPARITY, eONESTOPBIT, 8); | ||
689 | |||
690 | return 0; | ||
691 | } | ||
692 | |||
693 | |||
694 | // call a subroutine using the target monitor | ||
695 | int Execute(tUartHandle serial_handle, UINT32 addr, bool bReturns) | ||
696 | { | ||
697 | UINT8 send; | ||
698 | UINT8 received; | ||
699 | |||
700 | // send the address command | ||
701 | send = ADDRESS; | ||
702 | UartWrite(serial_handle, &send, 1); | ||
703 | |||
704 | // transmit the address, big endian | ||
705 | send = (UINT8)((addr>>24) & 0xFF); | ||
706 | UartWrite(serial_handle, &send, 1); | ||
707 | send = (UINT8)((addr>>16) & 0xFF); | ||
708 | UartWrite(serial_handle, &send, 1); | ||
709 | send = (UINT8)((addr>>8) & 0xFF); | ||
710 | UartWrite(serial_handle, &send, 1); | ||
711 | send = (UINT8)(addr & 0xFF); | ||
712 | UartWrite(serial_handle, &send, 1); | ||
713 | |||
714 | UartRead(serial_handle, &received, 1); // response | ||
715 | if (received != ADDRESS) | ||
716 | { | ||
717 | printf("Protocol error!\n"); | ||
718 | return 1; | ||
719 | } | ||
720 | |||
721 | // send the execute command | ||
722 | send = EXECUTE; | ||
723 | UartWrite(serial_handle, &send, 1); | ||
724 | if (bReturns) | ||
725 | { // we expect the call to return control to minimon | ||
726 | UartRead(serial_handle, &received, 1); // response | ||
727 | |||
728 | if (received != EXECUTE) | ||
729 | { | ||
730 | printf("Protocol error!\n"); | ||
731 | return 1; | ||
732 | } | ||
733 | } | ||
734 | |||
735 | return 0; | ||
736 | } | ||
737 | |||
738 | |||
diff --git a/flash/uart_boot/client.h b/flash/uart_boot/client.h new file mode 100644 index 0000000000..d2ef29aa2e --- /dev/null +++ b/flash/uart_boot/client.h | |||
@@ -0,0 +1,21 @@ | |||
1 | #ifndef _CLIENT_H | ||
2 | #define _CLIENT_H | ||
3 | |||
4 | |||
5 | // setup function for monitor download | ||
6 | int DownloadMonitor(tUartHandle serial_handle, bool bRecorder, char* szFilename); | ||
7 | int DownloadArchosMonitor(tUartHandle serial_handle, char* szFilename); | ||
8 | |||
9 | // target functions using the Monitor Protocol | ||
10 | UINT8 ReadByte(tUartHandle serial_handle, UINT32 addr); | ||
11 | int WriteByte(tUartHandle serial_handle, UINT32 addr, UINT8 byte); | ||
12 | int ReadByteMultiple(tUartHandle serial_handle, UINT32 addr, UINT32 size, UINT8* pBuffer); | ||
13 | int WriteByteMultiple(tUartHandle serial_handle, UINT32 addr, UINT32 size, UINT8* pBuffer); | ||
14 | int FlashByteMultiple(tUartHandle serial_handle, UINT32 addr, UINT32 size, UINT8* pBuffer); | ||
15 | UINT16 ReadHalfword(tUartHandle serial_handle, UINT32 addr); | ||
16 | int WriteHalfword(tUartHandle serial_handle, UINT32 addr, UINT16 halfword); | ||
17 | int SetTargetBaudrate(tUartHandle serial_handle, long lClock, long lBaudrate); | ||
18 | int Execute(tUartHandle serial_handle, UINT32 addr, bool bReturns); | ||
19 | |||
20 | |||
21 | #endif \ No newline at end of file | ||
diff --git a/flash/uart_boot/flash.c b/flash/uart_boot/flash.c new file mode 100644 index 0000000000..f27bb7ec0a --- /dev/null +++ b/flash/uart_boot/flash.c | |||
@@ -0,0 +1,77 @@ | |||
1 | // flash.cpp : higher-level functions for flashing the chip | ||
2 | // | ||
3 | |||
4 | #include "scalar_types.h" // (U)INT8/16/32 | ||
5 | #include "Uart.h" // platform abstraction for UART | ||
6 | #include "client.h" // client functions | ||
7 | |||
8 | |||
9 | // read the manufacturer and device ID | ||
10 | int ReadID(tUartHandle serial_handle, UINT32 base, UINT8* pManufacturerID, UINT8* pDeviceID) | ||
11 | { | ||
12 | base &= 0xFFF80000; // round down to 512k align, to make shure | ||
13 | |||
14 | WriteByte(serial_handle, base + 0x5555, 0xAA); // enter command mode | ||
15 | WriteByte(serial_handle, base + 0x2AAA, 0x55); | ||
16 | WriteByte(serial_handle, base + 0x5555, 0x90); // ID command | ||
17 | SLEEP(20); // Atmel wants 20ms pause here | ||
18 | |||
19 | *pManufacturerID = ReadByte(serial_handle, base + 0); | ||
20 | *pDeviceID = ReadByte(serial_handle, base + 1); | ||
21 | |||
22 | WriteByte(serial_handle, base + 0, 0xF0); // reset flash (back to normal read mode) | ||
23 | SLEEP(20); // Atmel wants 20ms pause here | ||
24 | |||
25 | return 0; | ||
26 | } | ||
27 | |||
28 | |||
29 | // erase the sector which contains the given address | ||
30 | int EraseSector(tUartHandle serial_handle, UINT32 address) | ||
31 | { | ||
32 | UINT32 base = address & 0xFFF80000; // round down to 512k align | ||
33 | |||
34 | WriteByte(serial_handle, base + 0x5555, 0xAA); // enter command mode | ||
35 | WriteByte(serial_handle, base + 0x2AAA, 0x55); | ||
36 | WriteByte(serial_handle, base + 0x5555, 0x80); // eraze command | ||
37 | WriteByte(serial_handle, base + 0x5555, 0xAA); // enter command mode | ||
38 | WriteByte(serial_handle, base + 0x2AAA, 0x55); | ||
39 | WriteByte(serial_handle, address, 0x30); // eraze the sector | ||
40 | SLEEP(25); // sector eraze time: 25ms | ||
41 | |||
42 | return 0; | ||
43 | } | ||
44 | |||
45 | |||
46 | // erase the whole flash | ||
47 | int EraseChip(tUartHandle serial_handle, UINT32 base) | ||
48 | { | ||
49 | base &= 0xFFF80000; // round down to 512k align, to make shure | ||
50 | |||
51 | WriteByte(serial_handle, base + 0x5555, 0xAA); // enter command mode | ||
52 | WriteByte(serial_handle, base + 0x2AAA, 0x55); | ||
53 | WriteByte(serial_handle, base + 0x5555, 0x80); // eraze command | ||
54 | WriteByte(serial_handle, base + 0x5555, 0xAA); // enter command mode | ||
55 | WriteByte(serial_handle, base + 0x2AAA, 0x55); | ||
56 | WriteByte(serial_handle, base + 0x5555, 0x10); // chip eraze command | ||
57 | SLEEP(100); // chip eraze time: 100ms | ||
58 | |||
59 | return 0; | ||
60 | } | ||
61 | |||
62 | |||
63 | // program a bunch of bytes "by hand" | ||
64 | int ProgramBytes(tUartHandle serial_handle, UINT32 address, UINT8* pData, UINT32 size) | ||
65 | { | ||
66 | UINT32 base = address & 0xFFF80000; // round down to 512k align | ||
67 | |||
68 | while (size--) | ||
69 | { | ||
70 | WriteByte(serial_handle, base + 0x5555, 0xAA); // enter command mode | ||
71 | WriteByte(serial_handle, base + 0x2AAA, 0x55); | ||
72 | WriteByte(serial_handle, base + 0x5555, 0xA0); // byte program command | ||
73 | WriteByte(serial_handle, address++, *pData++); | ||
74 | // UART protocol is slow enough such that I don't have to wait 20us here | ||
75 | } | ||
76 | return 0; | ||
77 | } \ No newline at end of file | ||
diff --git a/flash/uart_boot/flash.h b/flash/uart_boot/flash.h new file mode 100644 index 0000000000..70c620108d --- /dev/null +++ b/flash/uart_boot/flash.h | |||
@@ -0,0 +1,9 @@ | |||
1 | #ifndef _FLASH_H | ||
2 | #define _FLASH_H | ||
3 | |||
4 | int ReadID(tUartHandle serial_handle, UINT32 base, UINT8* pManufacturerID, UINT8* pDeviceID); | ||
5 | int EraseSector(tUartHandle serial_handle, UINT32 address); | ||
6 | int EraseChip(tUartHandle serial_handle, UINT32 base); | ||
7 | int ProgramBytes(tUartHandle serial_handle, UINT32 address, UINT8* pData, UINT32 size); | ||
8 | |||
9 | #endif \ No newline at end of file | ||
diff --git a/flash/uart_boot/minimon.h b/flash/uart_boot/minimon.h new file mode 100644 index 0000000000..51406d4b12 --- /dev/null +++ b/flash/uart_boot/minimon.h | |||
@@ -0,0 +1,23 @@ | |||
1 | #ifndef _MINIMON_H | ||
2 | #define _MINIMON_H | ||
3 | |||
4 | |||
5 | // Commands | ||
6 | // all multibyte values (address, halfwords) are passed as big endian | ||
7 | // (most significant of the bytes first) | ||
8 | |||
9 | // set the address (all read/write commands will auto-increment it) | ||
10 | #define BAUDRATE 0x00 // followed by BRR value; response: command byte | ||
11 | #define ADDRESS 0x01 // followed by 4 bytes address; response: command byte | ||
12 | #define BYTE_READ 0x02 // response: 1 byte content | ||
13 | #define BYTE_WRITE 0x03 // followed by 1 byte content; response: command byte | ||
14 | #define BYTE_READ16 0x04 // response: 16 bytes content | ||
15 | #define BYTE_WRITE16 0x05 // followed by 16 bytes; response: command byte | ||
16 | #define BYTE_FLASH 0x06 // followed by 1 byte content; response: command byte | ||
17 | #define BYTE_FLASH16 0x07 // followed by 16 bytes; response: command byte | ||
18 | #define HALFWORD_READ 0x08 // response: 2 byte content | ||
19 | #define HALFWORD_WRITE 0x09 // followed by 2 byte content; response: command byte | ||
20 | #define EXECUTE 0x0A // response: command byte if call returns | ||
21 | |||
22 | |||
23 | #endif // _MINIMON_H | ||
diff --git a/flash/uart_boot/scalar_types.h b/flash/uart_boot/scalar_types.h new file mode 100644 index 0000000000..88d82c4ec1 --- /dev/null +++ b/flash/uart_boot/scalar_types.h | |||
@@ -0,0 +1,44 @@ | |||
1 | // this is meant to resolve platform dependency | ||
2 | |||
3 | #ifndef _SCALAR_TYPES_H | ||
4 | #define _SCALAR_TYPES_H | ||
5 | |||
6 | |||
7 | #ifdef WIN32 | ||
8 | #include <windows.h> | ||
9 | #define SLEEP Sleep | ||
10 | #define GET_LAST_ERR GetLastError | ||
11 | #endif | ||
12 | // ToDo: add stuff for Linux | ||
13 | |||
14 | |||
15 | |||
16 | #ifndef UINT8 | ||
17 | #define UINT8 unsigned char | ||
18 | #endif | ||
19 | |||
20 | #ifndef UINT16 | ||
21 | #define UINT16 unsigned short | ||
22 | #endif | ||
23 | |||
24 | #ifndef UINT32 | ||
25 | #define UINT32 unsigned long | ||
26 | #endif | ||
27 | |||
28 | #ifndef bool | ||
29 | #define bool int | ||
30 | #endif | ||
31 | |||
32 | #ifndef true | ||
33 | #define true 1 | ||
34 | #endif | ||
35 | |||
36 | #ifndef false | ||
37 | #define false 0 | ||
38 | #endif | ||
39 | |||
40 | |||
41 | |||
42 | |||
43 | |||
44 | #endif \ No newline at end of file | ||
diff --git a/flash/uart_boot/uart.h b/flash/uart_boot/uart.h new file mode 100644 index 0000000000..46b082c497 --- /dev/null +++ b/flash/uart_boot/uart.h | |||
@@ -0,0 +1,56 @@ | |||
1 | // A general definition for the required UART functionality. | ||
2 | // This will be used to gain platform abstraction. | ||
3 | |||
4 | #ifndef _UART_H | ||
5 | #define _UART_H | ||
6 | |||
7 | // data types | ||
8 | |||
9 | typedef void* tUartHandle; | ||
10 | #define INVALID_UART_HANDLE (tUartHandle)-1 | ||
11 | |||
12 | typedef enum | ||
13 | { | ||
14 | eNOPARITY, | ||
15 | eODDPARITY, | ||
16 | eEVENPARITY, | ||
17 | eMARKPARITY, | ||
18 | eSPACEPARITY, | ||
19 | } tParity; | ||
20 | |||
21 | typedef enum | ||
22 | { | ||
23 | eONESTOPBIT, | ||
24 | eONE5STOPBITS, | ||
25 | eTWOSTOPBITS, | ||
26 | } tStopBits; | ||
27 | |||
28 | |||
29 | // prototypes | ||
30 | |||
31 | tUartHandle UartOpen( // returns NULL on error | ||
32 | char* szPortName); // COMx for windows | ||
33 | |||
34 | bool UartConfig( // returns true on success, false on error | ||
35 | tUartHandle handle, // the handle returned from UartOpen() | ||
36 | long lBaudRate, // must be one of the "standard" baudrates | ||
37 | tParity nParity, // what kind of parity | ||
38 | tStopBits nStopBits, // how many stop bits | ||
39 | int nByteSize); // size of the "payload", can be 5 to 8 | ||
40 | |||
41 | long UartWrite( // returns how much data was actually transmitted | ||
42 | tUartHandle handle, // the handle returned from UartOpen() | ||
43 | unsigned char* pData, // pointer to the data to be transmitted | ||
44 | long lSize); // how many bytes | ||
45 | |||
46 | long UartRead( // returns how much data was actually received | ||
47 | tUartHandle handle, // the handle returned from UartOpen() | ||
48 | unsigned char* pBuffer, // pointer to the destination | ||
49 | long lSize); // how many bytes to read (pBuffer must have enough room) | ||
50 | |||
51 | |||
52 | void UartClose(tUartHandle handle); | ||
53 | |||
54 | |||
55 | |||
56 | #endif // _UART_H \ No newline at end of file | ||
diff --git a/flash/uart_boot/uart_boot.c b/flash/uart_boot/uart_boot.c new file mode 100644 index 0000000000..8110e9b678 --- /dev/null +++ b/flash/uart_boot/uart_boot.c | |||
@@ -0,0 +1,337 @@ | |||
1 | // uart_boot.cpp : Defines the entry point for the console application. | ||
2 | // | ||
3 | |||
4 | #include <stdio.h> | ||
5 | #include <stdlib.h> | ||
6 | #include <string.h> | ||
7 | #include "scalar_types.h" // (U)INT8/16/32 | ||
8 | #include "Uart.h" // platform abstraction for UART | ||
9 | #include "client.h" // client functions | ||
10 | #include "flash.h" // flash high level functions | ||
11 | |||
12 | // command line configuration: what shall we do? | ||
13 | struct | ||
14 | { | ||
15 | char* szPort; // COM port to use | ||
16 | bool bRecorder; // it's a recorder | ||
17 | bool bArchos; // use the Archos monitor to load, instead of UART boot | ||
18 | bool bSpindown; // spindown the harddisk | ||
19 | bool bReadID; // read manufacturer+device ID | ||
20 | char* szFlashfile; // file to be programmed | ||
21 | char* szDumpfile; // file to dump into | ||
22 | char* szExecfile; // file with the executable | ||
23 | bool bTest; // debug action | ||
24 | bool bBlink; // blink red LED | ||
25 | bool bNoDownload; | ||
26 | } gCmd; | ||
27 | |||
28 | |||
29 | int ProcessCmdLine(int argc, char* argv[]) | ||
30 | { | ||
31 | argc--; // exclude our name | ||
32 | argv++; | ||
33 | |||
34 | memset(&gCmd, 0, sizeof(gCmd)); | ||
35 | |||
36 | if (argc == 0) | ||
37 | { | ||
38 | printf("Usage: uart_boot [-option {filename}]\n"); | ||
39 | printf(" uses activated UART boot mod, box has to be fresh started\n"); | ||
40 | printf("The order of the options does not matter, one letter is sufficient.\n"); | ||
41 | printf("Possible options are (in the order of later processing):\n"); | ||
42 | printf("-port <name of COM port to use>\n"); | ||
43 | printf("-recorder (this is a recorder/FM, default is player if not specified)\n"); | ||
44 | printf("-archos (use Archos bootloader, this one needs powerup while program waits)\n"); | ||
45 | printf("-nodownload (no MiniMon download, it's already active)\n"); | ||
46 | printf("-spindown (spindown the harddisk, else it stays on by default)\n"); | ||
47 | printf("-id (read manufacturer and device ID of flash, no checks)\n"); | ||
48 | printf("-flash <filename of binary to program into flash>\n"); | ||
49 | printf("-dump <filename to write flash content to>\n"); | ||
50 | printf("-exec <filename of executable for 0x09000000:0x09000200>\n"); | ||
51 | printf("-test (some test action currently under development, don't use!)\n"); | ||
52 | printf("-blink (blink red LED forever, meant as diagnostics)\n"); | ||
53 | printf("\n"); | ||
54 | printf("Examples:\n"); | ||
55 | printf("uart_boot -r -p COM1 -s -f flashfile.bin -d dumpfile.bin\n"); | ||
56 | printf(" recorder on COM1, spindown HD, program and dump (for e.g. offline verify)\n"); | ||
57 | printf("uart_boot -r -p COM2 -e rockbox.bin\n"); | ||
58 | printf(" recorder on COM2, load Rockbox from file and start it\n"); | ||
59 | exit (0); | ||
60 | } | ||
61 | |||
62 | |||
63 | while (argc) | ||
64 | { | ||
65 | if (!strncmp("-port", *argv, 2)) | ||
66 | { | ||
67 | gCmd.szPort = *++argv; | ||
68 | if (--argc <= 0 || **argv == '-') | ||
69 | { | ||
70 | printf("No argument given for option %s, aborting.\n", argv[-1]); | ||
71 | exit (-2); | ||
72 | } | ||
73 | } | ||
74 | else if (!strncmp("-recorder", *argv, 2)) | ||
75 | { | ||
76 | gCmd.bRecorder = true; | ||
77 | } | ||
78 | else if (!strncmp("-archos", *argv, 2)) | ||
79 | { | ||
80 | gCmd.bArchos = true; | ||
81 | } | ||
82 | else if (!strncmp("-nodownload", *argv, 2)) | ||
83 | { | ||
84 | gCmd.bNoDownload = true; | ||
85 | } | ||
86 | else if (!strncmp("-spindown", *argv, 2)) | ||
87 | { | ||
88 | gCmd.bSpindown = true; | ||
89 | } | ||
90 | else if (!strncmp("-id", *argv, 2)) | ||
91 | { | ||
92 | gCmd.bReadID = true; | ||
93 | } | ||
94 | else if (!strncmp("-flash", *argv, 2)) | ||
95 | { | ||
96 | gCmd.szFlashfile = *++argv; | ||
97 | if (--argc <= 0 || **argv == '-') | ||
98 | { | ||
99 | printf("No argument given for option %s, aborting.\n", argv[-1]); | ||
100 | exit (-2); | ||
101 | } | ||
102 | } | ||
103 | else if (!strncmp("-dump", *argv, 2)) | ||
104 | { | ||
105 | gCmd.szDumpfile = *++argv; | ||
106 | if (--argc <= 0 || **argv == '-') | ||
107 | { | ||
108 | printf("No argument given for option %s, aborting.\n", argv[-1]); | ||
109 | exit (-3); | ||
110 | } | ||
111 | } | ||
112 | else if (!strncmp("-exec", *argv, 2)) | ||
113 | { | ||
114 | gCmd.szExecfile = *++argv; | ||
115 | if (--argc <= 0 || **argv == '-') | ||
116 | { | ||
117 | printf("No argument given for option %s, aborting.\n", argv[-1]); | ||
118 | exit (-4); | ||
119 | } | ||
120 | } | ||
121 | else if (!strncmp("-test", *argv, 2)) | ||
122 | { | ||
123 | gCmd.bTest = true; | ||
124 | } | ||
125 | else if (!strncmp("-blink", *argv, 2)) | ||
126 | { | ||
127 | gCmd.bBlink = true; | ||
128 | } | ||
129 | else | ||
130 | { | ||
131 | printf("Unknown option %s, aborting. Use 'uart_boot' without options for help.\n", *argv); | ||
132 | exit(-1); | ||
133 | } | ||
134 | |||
135 | argv++; | ||
136 | argc--; | ||
137 | } | ||
138 | |||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | |||
143 | int main(int argc, char* argv[]) | ||
144 | { | ||
145 | tUartHandle serial_handle; | ||
146 | UINT16 reg; | ||
147 | FILE* pFile; | ||
148 | size_t size; | ||
149 | UINT8 abFirmware[512*1024]; // blocksize | ||
150 | memset(abFirmware, 0xFF, sizeof(abFirmware)); | ||
151 | |||
152 | ProcessCmdLine(argc, argv); // what to do | ||
153 | |||
154 | if (!gCmd.szPort) | ||
155 | { | ||
156 | printf("No serial port given, use 'uart_boot' without parameters for options.\n"); | ||
157 | exit(-1); | ||
158 | } | ||
159 | |||
160 | serial_handle = UartOpen(gCmd.szPort); // opening serial port | ||
161 | if (serial_handle == NULL) | ||
162 | { | ||
163 | printf("Cannot open port %s\n", gCmd.szPort); | ||
164 | return -1; | ||
165 | } | ||
166 | |||
167 | if (gCmd.bNoDownload) | ||
168 | { // just set our speed | ||
169 | if (!UartConfig(serial_handle, gCmd.bRecorder ? 115200 : 14400, eNOPARITY, eONESTOPBIT, 8)) | ||
170 | { | ||
171 | printf("Error setting up COM params\n"); | ||
172 | exit(1); | ||
173 | } | ||
174 | } | ||
175 | else | ||
176 | { // download the monitor program | ||
177 | if (gCmd.bArchos) | ||
178 | { | ||
179 | printf("Waiting for box startup to download monitor..."); | ||
180 | DownloadArchosMonitor(serial_handle, "minimon_v2.bin"); // load the monitor image | ||
181 | printf("\b\b\b done.\n"); | ||
182 | } | ||
183 | else | ||
184 | { | ||
185 | printf("Downloading monitor..."); | ||
186 | DownloadMonitor(serial_handle, gCmd.bRecorder, "minimon.bin"); // load the monitor image | ||
187 | // From now on, we can talk to the box. | ||
188 | printf("\b\b\b done.\n"); | ||
189 | |||
190 | if (gCmd.bRecorder) | ||
191 | { // we can be faster | ||
192 | SetTargetBaudrate(serial_handle, 11059200, 115200); // set to 115200 | ||
193 | } | ||
194 | } | ||
195 | } | ||
196 | |||
197 | // do the action | ||
198 | |||
199 | if (gCmd.bSpindown) | ||
200 | { | ||
201 | // spindown the disk (works only for master) | ||
202 | UINT32 ata; // address of ATA_ALT_STATUS | ||
203 | printf("Harddisk spindown..."); | ||
204 | ata = (gCmd.bRecorder && (ReadHalfword(serial_handle, 0x020000FC) & 0x0100)) ? 0x06200206 : 0x06200306; | ||
205 | WriteHalfword(serial_handle, 0x05FFFFCA, 0xBF99); // PACR2 (was 0xFF99) | ||
206 | WriteHalfword(serial_handle, 0x05FFFFC4, 0x0280); // PAIOR (was 0x0000) | ||
207 | WriteHalfword(serial_handle, 0x05FFFFC0, 0xA27F); // PADR (was 0xA0FF) | ||
208 | while (ReadByte(serial_handle, ata) & 0x80); // ATA_ALT_STATUS & STATUS_BSY | ||
209 | WriteByte(serial_handle, 0x06100107, 0xE0); // ATA_COMMAND = CMD_STANDBY_IMMEDIATE; | ||
210 | //while (ReadByte(serial_handle, ata) & 0x80); // ATA_ALT_STATUS & STATUS_BSY | ||
211 | printf("\b\b\b done.\n"); | ||
212 | } | ||
213 | |||
214 | |||
215 | if (gCmd.bReadID) | ||
216 | { | ||
217 | UINT8 bMan, bID; | ||
218 | ReadID(serial_handle, 0x02000000, &bMan, &bID); | ||
219 | printf("Manufacturer ID = 0x%02X, Device ID = 0x%02X\n", bMan, bID); | ||
220 | } | ||
221 | |||
222 | |||
223 | if (gCmd.szFlashfile) | ||
224 | { | ||
225 | // flash a firmware file | ||
226 | printf("Flashing file %s...", gCmd.szFlashfile); | ||
227 | pFile = fopen(gCmd.szFlashfile, "rb"); | ||
228 | if (pFile == NULL) | ||
229 | { | ||
230 | printf("\nFlash file %s not found, exiting.\n", gCmd.szFlashfile); | ||
231 | return -2; | ||
232 | } | ||
233 | size = fread(abFirmware, 1, sizeof(abFirmware), pFile); | ||
234 | fclose (pFile); | ||
235 | |||
236 | EraseChip(serial_handle, 0x02000000); | ||
237 | FlashByteMultiple(serial_handle, 0x02000000, size, abFirmware); | ||
238 | printf("\b\b\b done.\n"); | ||
239 | } | ||
240 | |||
241 | |||
242 | if (gCmd.szDumpfile) | ||
243 | { | ||
244 | // dump the flash content | ||
245 | printf("Writing flash dump into file %s...", gCmd.szDumpfile); | ||
246 | ReadByteMultiple(serial_handle, 0x02000000, sizeof(abFirmware), abFirmware); | ||
247 | pFile = fopen(gCmd.szDumpfile, "wb"); | ||
248 | if (pFile == NULL) | ||
249 | { | ||
250 | printf("\nDump file %s cannot be opened, exiting.\n", gCmd.szDumpfile); | ||
251 | return -3; | ||
252 | } | ||
253 | fwrite(abFirmware, 1, sizeof(abFirmware), pFile); | ||
254 | fclose (pFile); | ||
255 | printf("\b\b\b done.\n"); | ||
256 | } | ||
257 | |||
258 | |||
259 | if (gCmd.szExecfile) | ||
260 | { | ||
261 | UINT32 size; | ||
262 | |||
263 | printf("Downloading program..."); | ||
264 | |||
265 | // init the DRAM controller like the flash boot does | ||
266 | reg = ReadHalfword(serial_handle, 0x05FFFFCA); // PACR2 | ||
267 | reg &= 0xFFFB; // PA1 config: /RAS | ||
268 | reg |= 0x0008; | ||
269 | WriteHalfword(serial_handle, 0x05FFFFCA, reg); // PACR2 | ||
270 | reg = 0xAFFF; // CS1, CS3 config: /CASH. /CASL | ||
271 | WriteHalfword(serial_handle, 0x05FFFFEE, reg); // CASCR | ||
272 | reg = ReadHalfword(serial_handle, 0x05FFFFA0); // BCR | ||
273 | reg |= 0x8000; // DRAM enable, default bus | ||
274 | WriteHalfword(serial_handle, 0x05FFFFA0, reg); // BCR | ||
275 | reg = ReadHalfword(serial_handle, 0x05FFFFA2); // WCR1 | ||
276 | reg &= 0xFDFD; // 1-cycle CAS | ||
277 | WriteHalfword(serial_handle, 0x05FFFFA2, reg); // WCR1 | ||
278 | reg = 0x0E00; // CAS 35%, multiplexed, 10 bit row addr. | ||
279 | WriteHalfword(serial_handle, 0x05FFFFA8, reg); // DCR | ||
280 | reg = 0x5AB0; // refresh, 4 cycle waitstate | ||
281 | WriteHalfword(serial_handle, 0x05FFFFAC, reg); // RCR | ||
282 | reg = 0x9605; // refresh constant | ||
283 | WriteHalfword(serial_handle, 0x05FFFFB2, reg); // RTCOR | ||
284 | reg = 0xA518; // phi/32 | ||
285 | WriteHalfword(serial_handle, 0x05FFFFAE, reg); // RTCSR | ||
286 | |||
287 | |||
288 | // download Rockbox/gdb | ||
289 | pFile = fopen(gCmd.szExecfile, "rb"); | ||
290 | if (pFile == NULL) | ||
291 | { | ||
292 | printf("\nExecutable file %s cannot be opened, exiting.\n", gCmd.szExecfile); | ||
293 | return -3; | ||
294 | } | ||
295 | |||
296 | size = fread(abFirmware, 1, sizeof(abFirmware), pFile); | ||
297 | WriteByteMultiple(serial_handle, 0x09000000, size, abFirmware); | ||
298 | fclose (pFile); | ||
299 | printf("\b\b\b done.\n"); | ||
300 | |||
301 | // start rockbox/gdb | ||
302 | printf("Starting program..."); | ||
303 | Execute(serial_handle, 0x09000200, false); | ||
304 | printf("\b\b\b done.\n"); | ||
305 | } | ||
306 | |||
307 | |||
308 | if (gCmd.bTest) | ||
309 | { | ||
310 | // test code: query keypad | ||
311 | while (1) | ||
312 | { | ||
313 | WriteByte(serial_handle, 0x05FFFEE8, 0x24); // ADCSR | ||
314 | while (!(ReadByte(serial_handle, 0x05FFFEE8) & 0x80)); | ||
315 | reg = ReadHalfword(serial_handle, 0x05FFFEE0); // ADDRA | ||
316 | printf("ADC(4): %d\n", reg>>6); | ||
317 | } | ||
318 | } | ||
319 | |||
320 | |||
321 | if (gCmd.bBlink) | ||
322 | { | ||
323 | // blinking LED | ||
324 | UINT8 byte; | ||
325 | printf("Flashing red LED forever... (stop with Ctrl-C)\n"); | ||
326 | byte = ReadByte(serial_handle, 0x05FFFFC3); | ||
327 | while (1) | ||
328 | { | ||
329 | byte ^= 0x40; | ||
330 | WriteByte(serial_handle, 0x05FFFFC3, byte); | ||
331 | Sleep(200); | ||
332 | } | ||
333 | } | ||
334 | |||
335 | return 0; | ||
336 | } | ||
337 | |||
diff --git a/flash/uart_boot/uart_boot.dsp b/flash/uart_boot/uart_boot.dsp new file mode 100644 index 0000000000..4d94c72530 --- /dev/null +++ b/flash/uart_boot/uart_boot.dsp | |||
@@ -0,0 +1,130 @@ | |||
1 | # Microsoft Developer Studio Project File - Name="uart_boot" - Package Owner=<4> | ||
2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 | ||
3 | # ** DO NOT EDIT ** | ||
4 | |||
5 | # TARGTYPE "Win32 (x86) Console Application" 0x0103 | ||
6 | |||
7 | CFG=uart_boot - Win32 Debug | ||
8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, | ||
9 | !MESSAGE use the Export Makefile command and run | ||
10 | !MESSAGE | ||
11 | !MESSAGE NMAKE /f "uart_boot.mak". | ||
12 | !MESSAGE | ||
13 | !MESSAGE You can specify a configuration when running NMAKE | ||
14 | !MESSAGE by defining the macro CFG on the command line. For example: | ||
15 | !MESSAGE | ||
16 | !MESSAGE NMAKE /f "uart_boot.mak" CFG="uart_boot - Win32 Debug" | ||
17 | !MESSAGE | ||
18 | !MESSAGE Possible choices for configuration are: | ||
19 | !MESSAGE | ||
20 | !MESSAGE "uart_boot - Win32 Release" (based on "Win32 (x86) Console Application") | ||
21 | !MESSAGE "uart_boot - Win32 Debug" (based on "Win32 (x86) Console Application") | ||
22 | !MESSAGE | ||
23 | |||
24 | # Begin Project | ||
25 | # PROP AllowPerConfigDependencies 0 | ||
26 | # PROP Scc_ProjName "" | ||
27 | # PROP Scc_LocalPath "" | ||
28 | CPP=cl.exe | ||
29 | RSC=rc.exe | ||
30 | |||
31 | !IF "$(CFG)" == "uart_boot - Win32 Release" | ||
32 | |||
33 | # PROP BASE Use_MFC 0 | ||
34 | # PROP BASE Use_Debug_Libraries 0 | ||
35 | # PROP BASE Output_Dir "Release" | ||
36 | # PROP BASE Intermediate_Dir "Release" | ||
37 | # PROP BASE Target_Dir "" | ||
38 | # PROP Use_MFC 0 | ||
39 | # PROP Use_Debug_Libraries 0 | ||
40 | # PROP Output_Dir "Release" | ||
41 | # PROP Intermediate_Dir "Release" | ||
42 | # PROP Target_Dir "" | ||
43 | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c | ||
44 | # ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FR /FD /c | ||
45 | # SUBTRACT CPP /YX /Yc /Yu | ||
46 | # ADD BASE RSC /l 0x407 /d "NDEBUG" | ||
47 | # ADD RSC /l 0x407 /d "NDEBUG" | ||
48 | BSC32=bscmake.exe | ||
49 | # ADD BASE BSC32 /nologo | ||
50 | # ADD BSC32 /nologo | ||
51 | LINK32=link.exe | ||
52 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 | ||
53 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 | ||
54 | |||
55 | !ELSEIF "$(CFG)" == "uart_boot - Win32 Debug" | ||
56 | |||
57 | # PROP BASE Use_MFC 0 | ||
58 | # PROP BASE Use_Debug_Libraries 1 | ||
59 | # PROP BASE Output_Dir "Debug" | ||
60 | # PROP BASE Intermediate_Dir "Debug" | ||
61 | # PROP BASE Target_Dir "" | ||
62 | # PROP Use_MFC 0 | ||
63 | # PROP Use_Debug_Libraries 1 | ||
64 | # PROP Output_Dir "Debug" | ||
65 | # PROP Intermediate_Dir "Debug" | ||
66 | # PROP Target_Dir "" | ||
67 | # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c | ||
68 | # ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c | ||
69 | # SUBTRACT CPP /YX /Yc /Yu | ||
70 | # ADD BASE RSC /l 0x407 /d "_DEBUG" | ||
71 | # ADD RSC /l 0x407 /d "_DEBUG" | ||
72 | BSC32=bscmake.exe | ||
73 | # ADD BASE BSC32 /nologo | ||
74 | # ADD BSC32 /nologo | ||
75 | LINK32=link.exe | ||
76 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept | ||
77 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept | ||
78 | |||
79 | !ENDIF | ||
80 | |||
81 | # Begin Target | ||
82 | |||
83 | # Name "uart_boot - Win32 Release" | ||
84 | # Name "uart_boot - Win32 Debug" | ||
85 | # Begin Group "Source Files" | ||
86 | |||
87 | # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" | ||
88 | # Begin Source File | ||
89 | |||
90 | SOURCE=.\client.c | ||
91 | # End Source File | ||
92 | # Begin Source File | ||
93 | |||
94 | SOURCE=.\flash.c | ||
95 | # End Source File | ||
96 | # Begin Source File | ||
97 | |||
98 | SOURCE=.\uart_boot.c | ||
99 | # End Source File | ||
100 | # Begin Source File | ||
101 | |||
102 | SOURCE=.\uart_win.c | ||
103 | # End Source File | ||
104 | # End Group | ||
105 | # Begin Group "Header Files" | ||
106 | |||
107 | # PROP Default_Filter "h;hpp;hxx;hm;inl" | ||
108 | # Begin Source File | ||
109 | |||
110 | SOURCE=.\client.h | ||
111 | # End Source File | ||
112 | # Begin Source File | ||
113 | |||
114 | SOURCE=.\flash.h | ||
115 | # End Source File | ||
116 | # Begin Source File | ||
117 | |||
118 | SOURCE=.\minimon.h | ||
119 | # End Source File | ||
120 | # Begin Source File | ||
121 | |||
122 | SOURCE=.\scalar_types.h | ||
123 | # End Source File | ||
124 | # Begin Source File | ||
125 | |||
126 | SOURCE=.\uart.h | ||
127 | # End Source File | ||
128 | # End Group | ||
129 | # End Target | ||
130 | # End Project | ||
diff --git a/flash/uart_boot/uart_win.c b/flash/uart_boot/uart_win.c new file mode 100644 index 0000000000..243017ac88 --- /dev/null +++ b/flash/uart_boot/uart_win.c | |||
@@ -0,0 +1,138 @@ | |||
1 | // UART wrapper implementation for the Win32 platform | ||
2 | // make a new version of this file for different systems, e.g. Linux | ||
3 | |||
4 | #include <windows.h> | ||
5 | #include "scalar_types.h" // (U)INT8/16/32 | ||
6 | #include "Uart.h" | ||
7 | |||
8 | // COMx for windows, returns NULL on error | ||
9 | tUartHandle UartOpen(char* szPortName) | ||
10 | { | ||
11 | HANDLE serial_handle; | ||
12 | DCB dcb; | ||
13 | COMMTIMEOUTS cto = { 0, 0, 0, 0, 0 }; | ||
14 | |||
15 | memset(&dcb,0,sizeof(dcb)); | ||
16 | |||
17 | /* -------------------------------------------------------------------- */ | ||
18 | // set DCB to configure the serial port | ||
19 | dcb.DCBlength = sizeof(dcb); | ||
20 | |||
21 | dcb.fOutxCtsFlow = 0; | ||
22 | dcb.fOutxDsrFlow = 0; | ||
23 | dcb.fDtrControl = DTR_CONTROL_ENABLE; // enable for power | ||
24 | dcb.fDsrSensitivity = 0; | ||
25 | dcb.fRtsControl = RTS_CONTROL_ENABLE; // enable for power | ||
26 | dcb.fOutX = 0; | ||
27 | dcb.fInX = 0; | ||
28 | |||
29 | /* ----------------- misc parameters ----- */ | ||
30 | dcb.fErrorChar = 0; | ||
31 | dcb.fBinary = 1; | ||
32 | dcb.fNull = 0; | ||
33 | dcb.fAbortOnError = 0; | ||
34 | dcb.wReserved = 0; | ||
35 | dcb.XonLim = 2; | ||
36 | dcb.XoffLim = 4; | ||
37 | dcb.XonChar = 0x13; | ||
38 | dcb.XoffChar = 0x19; | ||
39 | dcb.EvtChar = 0; | ||
40 | |||
41 | /* ----------------- defaults ----- */ | ||
42 | dcb.BaudRate = 4800; | ||
43 | dcb.Parity = NOPARITY; | ||
44 | dcb.fParity = 0; | ||
45 | dcb.StopBits = ONESTOPBIT; | ||
46 | dcb.ByteSize = 8; | ||
47 | |||
48 | |||
49 | /* -------------------------------------------------------------------- */ | ||
50 | // opening serial port | ||
51 | serial_handle = CreateFile(szPortName, GENERIC_READ | GENERIC_WRITE, | ||
52 | 0, NULL, OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH, NULL); | ||
53 | |||
54 | if (serial_handle == INVALID_HANDLE_VALUE) | ||
55 | { | ||
56 | //printf("Cannot open port \n"); | ||
57 | return NULL; | ||
58 | } | ||
59 | |||
60 | SetCommMask(serial_handle, 0); | ||
61 | SetCommTimeouts(serial_handle, &cto); | ||
62 | |||
63 | if(!SetCommState(serial_handle, &dcb)) | ||
64 | { | ||
65 | //printf("Error setting up COM params\n"); | ||
66 | CloseHandle(serial_handle); | ||
67 | return NULL; | ||
68 | } | ||
69 | |||
70 | return serial_handle; | ||
71 | } | ||
72 | |||
73 | // returns true on success, false on error | ||
74 | bool UartConfig(tUartHandle handle, long lBaudRate, tParity nParity, tStopBits nStopBits, int nByteSize) | ||
75 | { | ||
76 | DCB dcb; | ||
77 | |||
78 | if (!GetCommState (handle, &dcb)) | ||
79 | { | ||
80 | return false; | ||
81 | } | ||
82 | |||
83 | dcb.BaudRate = lBaudRate; | ||
84 | dcb.Parity = nParity; | ||
85 | dcb.StopBits = nStopBits; | ||
86 | dcb.ByteSize = nByteSize; | ||
87 | |||
88 | if(!SetCommState(handle, &dcb)) | ||
89 | { | ||
90 | //DWORD dwErr = GetLastError(); | ||
91 | //printf("Error %d setting up COM params for baudrate byte\n", dwErr); | ||
92 | return false; | ||
93 | } | ||
94 | |||
95 | return true; | ||
96 | } | ||
97 | |||
98 | // returns how much data was actually transmitted | ||
99 | long UartWrite(tUartHandle handle, unsigned char* pData, long lSize) | ||
100 | { | ||
101 | BOOL success; | ||
102 | DWORD result_nbr; | ||
103 | |||
104 | success = WriteFile(handle, pData, lSize, &result_nbr, NULL); | ||
105 | |||
106 | if(!success) | ||
107 | { | ||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | return result_nbr; | ||
112 | } | ||
113 | |||
114 | // returns how much data was actually received | ||
115 | long UartRead(tUartHandle handle, unsigned char* pBuffer, long lSize) | ||
116 | { | ||
117 | BOOL success; | ||
118 | DWORD read_nbr; | ||
119 | |||
120 | success = ReadFile(handle, pBuffer, lSize, &read_nbr, NULL); | ||
121 | if(!success) | ||
122 | { | ||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | return read_nbr; | ||
127 | } | ||
128 | |||
129 | |||
130 | void UartClose(tUartHandle handle) | ||
131 | { | ||
132 | if (handle != NULL) | ||
133 | { | ||
134 | CloseHandle(handle); | ||
135 | } | ||
136 | |||
137 | return; | ||
138 | } | ||