diff options
Diffstat (limited to 'flash/uart_boot/client.c')
-rw-r--r-- | flash/uart_boot/client.c | 738 |
1 files changed, 738 insertions, 0 deletions
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 | |||