1 // client.cpp : functions for monitor download and communication.
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
10 // do the baudrate configuration for the Player
11 int ConfigFirstlevelPlayer (tUartHandle serial_handle
)
15 if(!UartConfig(serial_handle
, 4800, eMARKPARITY
, eTWOSTOPBITS
, 8))
17 UINT32 dwErr
= GET_LAST_ERR();
18 printf("Error %lu setting up COM params for baudrate byte\n", dwErr
);
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);
26 UINT32 dwErr
= GET_LAST_ERR();
27 printf("Error %lu setting up COM params for baudrate byte\n", dwErr
);
30 SLEEP(100); // wait for the chars to be sent, is there a better way?
32 // the read 0x19 means 14423 baud with 12 MHz
33 if(!UartConfig(serial_handle
, 14400, eNOPARITY
, eONESTOPBIT
, 8))
35 printf("Error setting up COM params for 1st level loader\n");
43 // do the baudrate configuration for the Recoder/FM
44 int ConfigFirstlevelRecorder (tUartHandle serial_handle
)
48 if(!UartConfig(serial_handle
, 4800, eNOPARITY
, eTWOSTOPBITS
, 8))
50 UINT32 dwErr
= GET_LAST_ERR();
51 printf("Error %lu setting up COM params for baudrate byte\n", dwErr
);
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);
59 printf("Error transmitting baudrate byte\n");
63 SLEEP(100); // wait for the chars to be sent, is there a better way?
65 // the read 0x08 means 38400 baud with 11.0592 MHz
66 if(!UartConfig(serial_handle
, 38400, eNOPARITY
, eONESTOPBIT
, 8))
68 UINT32 dwErr
= GET_LAST_ERR();
69 printf("Error %lu setting up COM params for 1st level loader\n", dwErr
);
77 // transfer a byte for the monitor download, with or without acknowledge
78 int DownloadByte(tUartHandle serial_handle
, unsigned char byte
, bool bAck
)
80 unsigned char received
;
84 UartWrite(serial_handle
, &byte
, 1);
87 UartRead(serial_handle
, &received
, 1);
90 UartWrite(serial_handle
, (UINT8
*)"\x01", 1); // ack success
91 break; // exit the loop
95 printf("Error transmitting monitor byte 0x%02X, got 0x%0X\n", byte
, received
);
96 UartWrite(serial_handle
, (UINT8
*)"\x00", 1); // ack fail, try again
106 // download our little monitor, the box must have been just freshly switched on for this to work
107 int DownloadMonitor(tUartHandle serial_handle
, bool bRecorder
, char* szFilename
)
114 // hard-coded parameters
115 bool bAck
= true; // configure if acknowledged download (without useful for remote pin boot)
116 UINT32 TargetLoad
= 0x0FFFF000; // target load address
118 pFile
= fopen(szFilename
, "rb");
121 printf("\nMonitor file %s not found, exiting\n", szFilename
);
125 // determine file size
126 fseek(pFile
, 0, SEEK_END
);
127 filesize
= ftell(pFile
);
128 fseek(pFile
, 0, SEEK_SET
);
130 // This is _really_ tricky! The box expects a BRR value in a nonstandard baudrate,
131 // which a PC can't generate. I'm using a higher one with some wild settings
132 // to generate a pulse series that:
133 // 1) looks like a stable byte when sampled with the nonstandard baudrate
134 // 2) gives a BRR value to the box which results in a baudrate the PC can also use
137 ConfigFirstlevelRecorder(serial_handle
);
141 ConfigFirstlevelPlayer(serial_handle
);
144 UartWrite(serial_handle
, bAck
? (UINT8
*)"\x01" : (UINT8
*)"\x00", 1); // ACK mode
146 // transmit the size, little endian
147 DownloadByte(serial_handle
, (UINT8
)( filesize
& 0xFF), bAck
);
148 DownloadByte(serial_handle
, (UINT8
)((filesize
>>8) & 0xFF), bAck
);
149 DownloadByte(serial_handle
, (UINT8
)((filesize
>>16) & 0xFF), bAck
);
150 DownloadByte(serial_handle
, (UINT8
)((filesize
>>24) & 0xFF), bAck
);
152 // transmit the load address, little endian
153 DownloadByte(serial_handle
, (UINT8
)( TargetLoad
& 0xFF), bAck
);
154 DownloadByte(serial_handle
, (UINT8
)((TargetLoad
>>8) & 0xFF), bAck
);
155 DownloadByte(serial_handle
, (UINT8
)((TargetLoad
>>16) & 0xFF), bAck
);
156 DownloadByte(serial_handle
, (UINT8
)((TargetLoad
>>24) & 0xFF), bAck
);
158 // transmit the command byte
159 DownloadByte(serial_handle
, 0xFF, bAck
); // 0xFF means execute the transferred image
161 // transmit the image
162 for (i
=0; i
<filesize
; i
++)
164 fread(&byte
, 1, 1, pFile
);
165 DownloadByte(serial_handle
, byte
, bAck
);
170 // now the image should have been started, red LED off
176 // wait for a fixed string to be received (no foolproof algorithm,
177 // may overlook if the searched string contains repeatitions)
178 int WaitForString(tUartHandle serial_handle
, char* pszWait
)
181 unsigned char received
;
183 while(pszWait
[i
] != '\0')
185 UartRead(serial_handle
, &received
, 1);
187 printf("%c", received
); // debug
189 if (received
== pszWait
[i
])
192 i
=0; // mismatch, start over
198 // send a sting and check the echo
199 int SendWithEcho(tUartHandle serial_handle
, char* pszSend
)
202 unsigned char received
;
204 while(pszSend
[i
] != '\0')
206 UartWrite(serial_handle
, (unsigned char*)(pszSend
+ i
), 1); // send char
209 UartRead(serial_handle
, &received
, 1); // receive echo
210 printf("%c", received
); // debug
212 while (received
!= pszSend
[i
]); // should normally be equal
219 // rarely used variant: download our monitor using the built-in Archos monitor
220 int DownloadArchosMonitor(tUartHandle serial_handle
, char* szFilename
)
228 // the onboard monitor uses 115200 baud
229 if(!UartConfig(serial_handle
, 115200, eNOPARITY
, eONESTOPBIT
, 8))
231 UINT32 dwErr
= GET_LAST_ERR();
232 printf("Error %lu setting up COM params for baudrate %d\n", dwErr
, 115200);
236 // wait for receiving "#SERIAL#"
237 WaitForString(serial_handle
, "#SERIAL#");
239 // send magic "SRL" command to get interactive mode
240 SendWithEcho(serial_handle
, "SRL\r");
242 // wait for menu completion: "ROOT>" at the end
243 WaitForString(serial_handle
, "ROOT>");
245 // send upload command "UP"
246 SendWithEcho(serial_handle
, "UP\r");
248 pFile
= fopen(szFilename
, "rb");
251 printf("\nMonitor file %s not found, exiting\n", szFilename
);
255 // determine file size
256 fseek(pFile
, 0, SEEK_END
);
257 filesize
= ftell(pFile
);
258 fseek(pFile
, 0, SEEK_SET
);
260 // calculate checksum
261 for (i
=0; i
<filesize
; i
++)
263 fread(&byte
, 1, 1, pFile
);
266 fseek(pFile
, 0, SEEK_SET
);
270 // size as 32 bit little endian
271 byte
= (UINT8
)( filesize
& 0xFF);
272 UartWrite(serial_handle
, &byte
, 1);
273 byte
= (UINT8
)((filesize
>>8) & 0xFF);
274 UartWrite(serial_handle
, &byte
, 1);
275 byte
= (UINT8
)((filesize
>>16) & 0xFF);
276 UartWrite(serial_handle
, &byte
, 1);
277 byte
= (UINT8
)((filesize
>>24) & 0xFF);
278 UartWrite(serial_handle
, &byte
, 1);
280 // checksum as 16 bit little endian
281 byte
= (UINT8
)( checksum
& 0xFF);
282 UartWrite(serial_handle
, &byte
, 1);
283 byte
= (UINT8
)((checksum
>>8) & 0xFF);
284 UartWrite(serial_handle
, &byte
, 1);
286 UartWrite(serial_handle
, (unsigned char*)"\x00", 1); // kind (3 means flash)
287 UartWrite(serial_handle
, (unsigned char*)"\x00", 1); // ignored byte
289 // wait for monitor to accept data
290 WaitForString(serial_handle
, "#OKCTRL#");
292 // transmit the image
293 for (i
=0; i
<filesize
; i
++)
295 fread(&byte
, 1, 1, pFile
);
296 UartWrite(serial_handle
, &byte
, 1); // payload
300 UartWrite(serial_handle
, (unsigned char*)"\x00", 1); // ignored byte
302 // wait for menu completion: "ROOT>" at the end
303 WaitForString(serial_handle
, "ROOT>");
305 // send start program command "SPRO"
306 SendWithEcho(serial_handle
, "SPRO\r");
308 SLEEP(100); // wait a little while for startup
314 /********** Target functions using the Monitor Protocol **********/
316 // read a byte using the target monitor
317 UINT8
ReadByte(tUartHandle serial_handle
, UINT32 addr
)
322 // send the address command
324 UartWrite(serial_handle
, &send
, 1);
326 // transmit the address, big endian
327 send
= (UINT8
)((addr
>>24) & 0xFF);
328 UartWrite(serial_handle
, &send
, 1);
329 send
= (UINT8
)((addr
>>16) & 0xFF);
330 UartWrite(serial_handle
, &send
, 1);
331 send
= (UINT8
)((addr
>>8) & 0xFF);
332 UartWrite(serial_handle
, &send
, 1);
333 send
= (UINT8
)(addr
& 0xFF);
334 UartWrite(serial_handle
, &send
, 1);
336 UartRead(serial_handle
, &received
, 1); // response
337 if (received
!= ADDRESS
)
339 printf("Protocol error!\n");
343 // send the read command
345 UartWrite(serial_handle
, &send
, 1);
347 UartRead(serial_handle
, &received
, 1); // response
353 // write a byte using the target monitor
354 int WriteByte(tUartHandle serial_handle
, UINT32 addr
, UINT8 byte
)
359 // send the address command
361 UartWrite(serial_handle
, &send
, 1);
363 // transmit the address, big endian
364 send
= (UINT8
)((addr
>>24) & 0xFF);
365 UartWrite(serial_handle
, &send
, 1);
366 send
= (UINT8
)((addr
>>16) & 0xFF);
367 UartWrite(serial_handle
, &send
, 1);
368 send
= (UINT8
)((addr
>>8) & 0xFF);
369 UartWrite(serial_handle
, &send
, 1);
370 send
= (UINT8
)(addr
& 0xFF);
371 UartWrite(serial_handle
, &send
, 1);
373 UartRead(serial_handle
, &received
, 1); // response
374 if (received
!= ADDRESS
)
376 printf("Protocol error, receiced 0x%02X!\n", received
);
380 // send the write command
382 UartWrite(serial_handle
, &send
, 1);
385 UartWrite(serial_handle
, &byte
, 1);
387 UartRead(serial_handle
, &received
, 1); // response
389 if (received
!= BYTE_WRITE
)
391 printf("Protocol error!\n");
399 // read many bytes using the target monitor
400 int ReadByteMultiple(tUartHandle serial_handle
, UINT32 addr
, UINT32 size
, UINT8
* pBuffer
)
402 UINT8 send
, received
;
404 // send the address command
406 UartWrite(serial_handle
, &send
, 1);
408 // transmit the address, big endian
409 send
= (UINT8
)((addr
>>24) & 0xFF);
410 UartWrite(serial_handle
, &send
, 1);
411 send
= (UINT8
)((addr
>>16) & 0xFF);
412 UartWrite(serial_handle
, &send
, 1);
413 send
= (UINT8
)((addr
>>8) & 0xFF);
414 UartWrite(serial_handle
, &send
, 1);
415 send
= (UINT8
)(addr
& 0xFF);
416 UartWrite(serial_handle
, &send
, 1);
418 UartRead(serial_handle
, &received
, 1); // response
419 if (received
!= ADDRESS
)
421 printf("Protocol error!\n");
428 { // we can use a "burst" command
430 UartWrite(serial_handle
, &send
, 1); // send the read command
431 UartRead(serial_handle
, pBuffer
, 16); // data response
436 { // use single byte command
438 UartWrite(serial_handle
, &send
, 1); // send the read command
439 UartRead(serial_handle
, pBuffer
++, 1); // data response
448 // write many bytes using the target monitor
449 int WriteByteMultiple(tUartHandle serial_handle
, UINT32 addr
, UINT32 size
, UINT8
* pBuffer
)
451 UINT8 send
, received
;
453 // send the address command
455 UartWrite(serial_handle
, &send
, 1);
457 // transmit the address, big endian
458 send
= (UINT8
)((addr
>>24) & 0xFF);
459 UartWrite(serial_handle
, &send
, 1);
460 send
= (UINT8
)((addr
>>16) & 0xFF);
461 UartWrite(serial_handle
, &send
, 1);
462 send
= (UINT8
)((addr
>>8) & 0xFF);
463 UartWrite(serial_handle
, &send
, 1);
464 send
= (UINT8
)(addr
& 0xFF);
465 UartWrite(serial_handle
, &send
, 1);
467 UartRead(serial_handle
, &received
, 1); // response
468 if (received
!= ADDRESS
)
470 printf("Protocol error!\n");
477 { // we can use a "burst" command
479 UartWrite(serial_handle
, &send
, 1); // send the write command
480 UartWrite(serial_handle
, pBuffer
, 16); // transmit the data
481 UartRead(serial_handle
, &received
, 1); // response
482 if (received
!= BYTE_WRITE16
)
484 printf("Protocol error!\n");
491 { // use single byte command
493 UartWrite(serial_handle
, &send
, 1); // send the write command
494 UartWrite(serial_handle
, pBuffer
++, 1); // transmit the data
495 UartRead(serial_handle
, &received
, 1); // response
496 if (received
!= BYTE_WRITE
)
498 printf("Protocol error!\n");
509 // write many bytes using the target monitor
510 int FlashByteMultiple(tUartHandle serial_handle
, UINT32 addr
, UINT32 size
, UINT8
* pBuffer
)
512 UINT8 send
, received
;
514 // send the address command
516 UartWrite(serial_handle
, &send
, 1);
518 // transmit the address, big endian
519 send
= (UINT8
)((addr
>>24) & 0xFF);
520 UartWrite(serial_handle
, &send
, 1);
521 send
= (UINT8
)((addr
>>16) & 0xFF);
522 UartWrite(serial_handle
, &send
, 1);
523 send
= (UINT8
)((addr
>>8) & 0xFF);
524 UartWrite(serial_handle
, &send
, 1);
525 send
= (UINT8
)(addr
& 0xFF);
526 UartWrite(serial_handle
, &send
, 1);
528 UartRead(serial_handle
, &received
, 1); // response
529 if (received
!= ADDRESS
)
531 printf("Protocol error!\n");
538 { // we can use a "burst" command
540 UartWrite(serial_handle
, &send
, 1); // send the write command
541 UartWrite(serial_handle
, pBuffer
, 16); // transmit the data
542 UartRead(serial_handle
, &received
, 1); // response
543 if (received
!= BYTE_FLASH16
)
545 printf("Protocol error!\n");
552 { // use single byte command
554 UartWrite(serial_handle
, &send
, 1); // send the write command
555 UartWrite(serial_handle
, pBuffer
++, 1); // transmit the data
556 UartRead(serial_handle
, &received
, 1); // response
557 if (received
!= BYTE_FLASH
)
559 printf("Protocol error!\n");
570 // read a 16bit halfword using the target monitor
571 UINT16
ReadHalfword(tUartHandle serial_handle
, UINT32 addr
)
577 // send the address command
579 UartWrite(serial_handle
, &send
, 1);
581 // transmit the address, big endian
582 send
= (UINT8
)((addr
>>24) & 0xFF);
583 UartWrite(serial_handle
, &send
, 1);
584 send
= (UINT8
)((addr
>>16) & 0xFF);
585 UartWrite(serial_handle
, &send
, 1);
586 send
= (UINT8
)((addr
>>8) & 0xFF);
587 UartWrite(serial_handle
, &send
, 1);
588 send
= (UINT8
)(addr
& 0xFF);
589 UartWrite(serial_handle
, &send
, 1);
591 UartRead(serial_handle
, &received
, 1); // response
592 if (received
!= ADDRESS
)
594 printf("Protocol error!\n");
598 // send the read command
599 send
= HALFWORD_READ
;
600 UartWrite(serial_handle
, &send
, 1);
602 UartRead(serial_handle
, &received
, 1); // response
603 halfword
= received
<< 8; // highbyte
604 UartRead(serial_handle
, &received
, 1);
605 halfword
|= received
; // lowbyte
611 // write a 16bit halfword using the target monitor
612 int WriteHalfword(tUartHandle serial_handle
, UINT32 addr
, UINT16 halfword
)
617 // send the address command
619 UartWrite(serial_handle
, &send
, 1);
621 // transmit the address, big endian
622 send
= (UINT8
)((addr
>>24) & 0xFF);
623 UartWrite(serial_handle
, &send
, 1);
624 send
= (UINT8
)((addr
>>16) & 0xFF);
625 UartWrite(serial_handle
, &send
, 1);
626 send
= (UINT8
)((addr
>>8) & 0xFF);
627 UartWrite(serial_handle
, &send
, 1);
628 send
= (UINT8
)(addr
& 0xFF);
629 UartWrite(serial_handle
, &send
, 1);
631 UartRead(serial_handle
, &received
, 1); // response
632 if (received
!= ADDRESS
)
634 printf("Protocol error!\n");
638 // send the write command
639 send
= HALFWORD_WRITE
;
640 UartWrite(serial_handle
, &send
, 1);
643 send
= halfword
>> 8; // highbyte
644 UartWrite(serial_handle
, &send
, 1);
645 send
= halfword
& 0xFF; // lowbyte
646 UartWrite(serial_handle
, &send
, 1);
648 UartRead(serial_handle
, &received
, 1); // response
650 if (received
!= HALFWORD_WRITE
)
652 printf("Protocol error!\n");
660 // change baudrate using target monitor
661 int SetTargetBaudrate(tUartHandle serial_handle
, long lClock
, long lBaudrate
)
668 lBRR
= lClock
/ lBaudrate
;
669 lBRR
= ((lBRR
+ 16) / 32) - 1; // with rounding
674 UartWrite(serial_handle
, &send
, 1);
675 UartWrite(serial_handle
, &brr
, 1); // send the BRR value
676 UartRead(serial_handle
, &received
, 1); // response ack
678 if (received
!= BAUDRATE
)
679 { // bad situation, now we're unclear about the baudrate of the target
680 printf("Protocol error!\n");
684 SLEEP(100); // give it some time to settle
686 // change our baudrate, too
687 UartConfig(serial_handle
, lBaudrate
, eNOPARITY
, eONESTOPBIT
, 8);
693 // call a subroutine using the target monitor
694 int Execute(tUartHandle serial_handle
, UINT32 addr
, bool bReturns
)
699 // send the address command
701 UartWrite(serial_handle
, &send
, 1);
703 // transmit the address, big endian
704 send
= (UINT8
)((addr
>>24) & 0xFF);
705 UartWrite(serial_handle
, &send
, 1);
706 send
= (UINT8
)((addr
>>16) & 0xFF);
707 UartWrite(serial_handle
, &send
, 1);
708 send
= (UINT8
)((addr
>>8) & 0xFF);
709 UartWrite(serial_handle
, &send
, 1);
710 send
= (UINT8
)(addr
& 0xFF);
711 UartWrite(serial_handle
, &send
, 1);
713 UartRead(serial_handle
, &received
, 1); // response
714 if (received
!= ADDRESS
)
716 printf("Protocol error!\n");
720 // send the execute command
722 UartWrite(serial_handle
, &send
, 1);
724 { // we expect the call to return control to minimon
725 UartRead(serial_handle
, &received
, 1); // response
727 if (received
!= EXECUTE
)
729 printf("Protocol error!\n");