c519e6365e
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5439 a1c6a512-1295-4272-9138-f99709370657
737 lines
18 KiB
C
737 lines
18 KiB
C
// client.cpp : functions for monitor download and communication.
|
|
//
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include "scalar_types.h" // (U)INT8/16/32
|
|
#include "Uart.h" // platform abstraction for UART
|
|
#include "minimon.h" // protocol of my little monitor
|
|
|
|
// do the baudrate configuration for the Player
|
|
int ConfigFirstlevelPlayer (tUartHandle serial_handle)
|
|
{
|
|
UINT32 result_nbr;
|
|
|
|
if(!UartConfig(serial_handle, 4800, eMARKPARITY, eTWOSTOPBITS, 8))
|
|
{
|
|
UINT32 dwErr = GET_LAST_ERR();
|
|
printf("Error %lu setting up COM params for baudrate byte\n", dwErr);
|
|
exit(1);
|
|
}
|
|
|
|
// this will read as 0x19 when viewed with 2300 baud like the player does
|
|
result_nbr = UartWrite(serial_handle, (UINT8*)"\x86\xC0", 2);
|
|
if (result_nbr != 2)
|
|
{
|
|
UINT32 dwErr = GET_LAST_ERR();
|
|
printf("Error %lu setting up COM params for baudrate byte\n", dwErr);
|
|
}
|
|
|
|
SLEEP(100); // wait for the chars to be sent, is there a better way?
|
|
|
|
// the read 0x19 means 14423 baud with 12 MHz
|
|
if(!UartConfig(serial_handle, 14400, eNOPARITY, eONESTOPBIT, 8))
|
|
{
|
|
printf("Error setting up COM params for 1st level loader\n");
|
|
exit(1);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
// do the baudrate configuration for the Recoder/FM
|
|
int ConfigFirstlevelRecorder (tUartHandle serial_handle)
|
|
{
|
|
UINT32 result_nbr;
|
|
|
|
if(!UartConfig(serial_handle, 4800, eNOPARITY, eTWOSTOPBITS, 8))
|
|
{
|
|
UINT32 dwErr = GET_LAST_ERR();
|
|
printf("Error %lu setting up COM params for baudrate byte\n", dwErr);
|
|
exit(1);
|
|
}
|
|
|
|
// this will read as 0x08 when viewed with 2120 baud like the recorder does
|
|
result_nbr = UartWrite(serial_handle, (UINT8*)"\x00\x00", 2);
|
|
if(result_nbr != 2)
|
|
{
|
|
printf("Error transmitting baudrate byte\n");
|
|
exit(1);
|
|
}
|
|
|
|
SLEEP(100); // wait for the chars to be sent, is there a better way?
|
|
|
|
// the read 0x08 means 38400 baud with 11.0592 MHz
|
|
if(!UartConfig(serial_handle, 38400, eNOPARITY, eONESTOPBIT, 8))
|
|
{
|
|
UINT32 dwErr = GET_LAST_ERR();
|
|
printf("Error %lu setting up COM params for 1st level loader\n", dwErr);
|
|
exit(1);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
// transfer a byte for the monitor download, with or without acknowledge
|
|
int DownloadByte(tUartHandle serial_handle, unsigned char byte, bool bAck)
|
|
{
|
|
unsigned char received;
|
|
|
|
while (1)
|
|
{
|
|
UartWrite(serial_handle, &byte, 1);
|
|
if (bAck)
|
|
{
|
|
UartRead(serial_handle, &received, 1);
|
|
if (received == byte)
|
|
{
|
|
UartWrite(serial_handle, (UINT8*)"\x01", 1); // ack success
|
|
break; // exit the loop
|
|
}
|
|
else
|
|
{
|
|
printf("Error transmitting monitor byte 0x%02X, got 0x%0X\n", byte, received);
|
|
UartWrite(serial_handle, (UINT8*)"\x00", 1); // ack fail, try again
|
|
}
|
|
}
|
|
else
|
|
break; // no loop
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
|
|
// download our little monitor, the box must have been just freshly switched on for this to work
|
|
int DownloadMonitor(tUartHandle serial_handle, bool bRecorder, char* szFilename)
|
|
{
|
|
FILE* pFile;
|
|
size_t filesize;
|
|
UINT8 byte;
|
|
unsigned i;
|
|
|
|
// hard-coded parameters
|
|
bool bAck = true; // configure if acknowledged download (without useful for remote pin boot)
|
|
UINT32 TargetLoad = 0x0FFFF000; // target load address
|
|
|
|
pFile = fopen(szFilename, "rb");
|
|
if (pFile == NULL)
|
|
{
|
|
printf("\nMonitor file %s not found, exiting\n", szFilename);
|
|
exit(1);
|
|
}
|
|
|
|
// determine file size
|
|
fseek(pFile, 0, SEEK_END);
|
|
filesize = ftell(pFile);
|
|
fseek(pFile, 0, SEEK_SET);
|
|
|
|
// This is _really_ tricky! The box expects a BRR value in a nonstandard baudrate,
|
|
// which a PC can't generate. I'm using a higher one with some wild settings
|
|
// to generate a pulse series that:
|
|
// 1) looks like a stable byte when sampled with the nonstandard baudrate
|
|
// 2) gives a BRR value to the box which results in a baudrate the PC can also use
|
|
if (bRecorder)
|
|
{
|
|
ConfigFirstlevelRecorder(serial_handle);
|
|
}
|
|
else
|
|
{
|
|
ConfigFirstlevelPlayer(serial_handle);
|
|
}
|
|
|
|
UartWrite(serial_handle, bAck ? (UINT8*)"\x01" : (UINT8*)"\x00", 1); // ACK mode
|
|
|
|
// transmit the size, little endian
|
|
DownloadByte(serial_handle, (UINT8)( filesize & 0xFF), bAck);
|
|
DownloadByte(serial_handle, (UINT8)((filesize>>8) & 0xFF), bAck);
|
|
DownloadByte(serial_handle, (UINT8)((filesize>>16) & 0xFF), bAck);
|
|
DownloadByte(serial_handle, (UINT8)((filesize>>24) & 0xFF), bAck);
|
|
|
|
// transmit the load address, little endian
|
|
DownloadByte(serial_handle, (UINT8)( TargetLoad & 0xFF), bAck);
|
|
DownloadByte(serial_handle, (UINT8)((TargetLoad>>8) & 0xFF), bAck);
|
|
DownloadByte(serial_handle, (UINT8)((TargetLoad>>16) & 0xFF), bAck);
|
|
DownloadByte(serial_handle, (UINT8)((TargetLoad>>24) & 0xFF), bAck);
|
|
|
|
// transmit the command byte
|
|
DownloadByte(serial_handle, 0xFF, bAck); // 0xFF means execute the transferred image
|
|
|
|
// transmit the image
|
|
for (i=0; i<filesize; i++)
|
|
{
|
|
fread(&byte, 1, 1, pFile);
|
|
DownloadByte(serial_handle, byte, bAck);
|
|
}
|
|
|
|
fclose (pFile);
|
|
|
|
// now the image should have been started, red LED off
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
// wait for a fixed string to be received (no foolproof algorithm,
|
|
// may overlook if the searched string contains repeatitions)
|
|
int WaitForString(tUartHandle serial_handle, char* pszWait)
|
|
{
|
|
int i = 0;
|
|
unsigned char received;
|
|
|
|
while(pszWait[i] != '\0')
|
|
{
|
|
UartRead(serial_handle, &received, 1);
|
|
|
|
printf("%c", received); // debug
|
|
|
|
if (received == pszWait[i])
|
|
i++; // continue
|
|
else
|
|
i=0; // mismatch, start over
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
// send a sting and check the echo
|
|
int SendWithEcho(tUartHandle serial_handle, char* pszSend)
|
|
{
|
|
int i = 0;
|
|
unsigned char received;
|
|
|
|
while(pszSend[i] != '\0')
|
|
{
|
|
UartWrite(serial_handle, (unsigned char*)(pszSend + i), 1); // send char
|
|
do
|
|
{
|
|
UartRead(serial_handle, &received, 1); // receive echo
|
|
printf("%c", received); // debug
|
|
}
|
|
while (received != pszSend[i]); // should normally be equal
|
|
i++; // next char
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
// rarely used variant: download our monitor using the built-in Archos monitor
|
|
int DownloadArchosMonitor(tUartHandle serial_handle, char* szFilename)
|
|
{
|
|
FILE* pFile;
|
|
size_t filesize;
|
|
UINT8 byte;
|
|
UINT16 checksum = 0;
|
|
unsigned i;
|
|
|
|
// the onboard monitor uses 115200 baud
|
|
if(!UartConfig(serial_handle, 115200, eNOPARITY, eONESTOPBIT, 8))
|
|
{
|
|
UINT32 dwErr = GET_LAST_ERR();
|
|
printf("Error %lu setting up COM params for baudrate %d\n", dwErr, 115200);
|
|
exit(1);
|
|
}
|
|
|
|
// wait for receiving "#SERIAL#"
|
|
WaitForString(serial_handle, "#SERIAL#");
|
|
|
|
// send magic "SRL" command to get interactive mode
|
|
SendWithEcho(serial_handle, "SRL\r");
|
|
|
|
// wait for menu completion: "ROOT>" at the end
|
|
WaitForString(serial_handle, "ROOT>");
|
|
|
|
// send upload command "UP"
|
|
SendWithEcho(serial_handle, "UP\r");
|
|
|
|
pFile = fopen(szFilename, "rb");
|
|
if (pFile == NULL)
|
|
{
|
|
printf("\nMonitor file %s not found, exiting\n", szFilename);
|
|
exit(1);
|
|
}
|
|
|
|
// determine file size
|
|
fseek(pFile, 0, SEEK_END);
|
|
filesize = ftell(pFile);
|
|
fseek(pFile, 0, SEEK_SET);
|
|
|
|
// calculate checksum
|
|
for (i=0; i<filesize; i++)
|
|
{
|
|
fread(&byte, 1, 1, pFile);
|
|
checksum += byte;
|
|
}
|
|
fseek(pFile, 0, SEEK_SET);
|
|
|
|
// send header
|
|
|
|
// size as 32 bit little endian
|
|
byte = (UINT8)( filesize & 0xFF);
|
|
UartWrite(serial_handle, &byte, 1);
|
|
byte = (UINT8)((filesize>>8) & 0xFF);
|
|
UartWrite(serial_handle, &byte, 1);
|
|
byte = (UINT8)((filesize>>16) & 0xFF);
|
|
UartWrite(serial_handle, &byte, 1);
|
|
byte = (UINT8)((filesize>>24) & 0xFF);
|
|
UartWrite(serial_handle, &byte, 1);
|
|
|
|
// checksum as 16 bit little endian
|
|
byte = (UINT8)( checksum & 0xFF);
|
|
UartWrite(serial_handle, &byte, 1);
|
|
byte = (UINT8)((checksum>>8) & 0xFF);
|
|
UartWrite(serial_handle, &byte, 1);
|
|
|
|
UartWrite(serial_handle, (unsigned char*)"\x00", 1); // kind (3 means flash)
|
|
UartWrite(serial_handle, (unsigned char*)"\x00", 1); // ignored byte
|
|
|
|
// wait for monitor to accept data
|
|
WaitForString(serial_handle, "#OKCTRL#");
|
|
|
|
// transmit the image
|
|
for (i=0; i<filesize; i++)
|
|
{
|
|
fread(&byte, 1, 1, pFile);
|
|
UartWrite(serial_handle, &byte, 1); // payload
|
|
}
|
|
fclose (pFile);
|
|
|
|
UartWrite(serial_handle, (unsigned char*)"\x00", 1); // ignored byte
|
|
|
|
// wait for menu completion: "ROOT>" at the end
|
|
WaitForString(serial_handle, "ROOT>");
|
|
|
|
// send start program command "SPRO"
|
|
SendWithEcho(serial_handle, "SPRO\r");
|
|
|
|
SLEEP(100); // wait a little while for startup
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/********** Target functions using the Monitor Protocol **********/
|
|
|
|
// read a byte using the target monitor
|
|
UINT8 ReadByte(tUartHandle serial_handle, UINT32 addr)
|
|
{
|
|
UINT8 send;
|
|
UINT8 received;
|
|
|
|
// send the address command
|
|
send = ADDRESS;
|
|
UartWrite(serial_handle, &send, 1);
|
|
|
|
// transmit the address, big endian
|
|
send = (UINT8)((addr>>24) & 0xFF);
|
|
UartWrite(serial_handle, &send, 1);
|
|
send = (UINT8)((addr>>16) & 0xFF);
|
|
UartWrite(serial_handle, &send, 1);
|
|
send = (UINT8)((addr>>8) & 0xFF);
|
|
UartWrite(serial_handle, &send, 1);
|
|
send = (UINT8)(addr & 0xFF);
|
|
UartWrite(serial_handle, &send, 1);
|
|
|
|
UartRead(serial_handle, &received, 1); // response
|
|
if (received != ADDRESS)
|
|
{
|
|
printf("Protocol error!\n");
|
|
return 1;
|
|
}
|
|
|
|
// send the read command
|
|
send = BYTE_READ;
|
|
UartWrite(serial_handle, &send, 1);
|
|
|
|
UartRead(serial_handle, &received, 1); // response
|
|
|
|
return received;
|
|
}
|
|
|
|
|
|
// write a byte using the target monitor
|
|
int WriteByte(tUartHandle serial_handle, UINT32 addr, UINT8 byte)
|
|
{
|
|
UINT8 send;
|
|
UINT8 received;
|
|
|
|
// send the address command
|
|
send = ADDRESS;
|
|
UartWrite(serial_handle, &send, 1);
|
|
|
|
// transmit the address, big endian
|
|
send = (UINT8)((addr>>24) & 0xFF);
|
|
UartWrite(serial_handle, &send, 1);
|
|
send = (UINT8)((addr>>16) & 0xFF);
|
|
UartWrite(serial_handle, &send, 1);
|
|
send = (UINT8)((addr>>8) & 0xFF);
|
|
UartWrite(serial_handle, &send, 1);
|
|
send = (UINT8)(addr & 0xFF);
|
|
UartWrite(serial_handle, &send, 1);
|
|
|
|
UartRead(serial_handle, &received, 1); // response
|
|
if (received != ADDRESS)
|
|
{
|
|
printf("Protocol error, receiced 0x%02X!\n", received);
|
|
return 1;
|
|
}
|
|
|
|
// send the write command
|
|
send = BYTE_WRITE;
|
|
UartWrite(serial_handle, &send, 1);
|
|
|
|
// transmit the data
|
|
UartWrite(serial_handle, &byte, 1);
|
|
|
|
UartRead(serial_handle, &received, 1); // response
|
|
|
|
if (received != BYTE_WRITE)
|
|
{
|
|
printf("Protocol error!\n");
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
// read many bytes using the target monitor
|
|
int ReadByteMultiple(tUartHandle serial_handle, UINT32 addr, UINT32 size, UINT8* pBuffer)
|
|
{
|
|
UINT8 send, received;
|
|
|
|
// send the address command
|
|
send = ADDRESS;
|
|
UartWrite(serial_handle, &send, 1);
|
|
|
|
// transmit the address, big endian
|
|
send = (UINT8)((addr>>24) & 0xFF);
|
|
UartWrite(serial_handle, &send, 1);
|
|
send = (UINT8)((addr>>16) & 0xFF);
|
|
UartWrite(serial_handle, &send, 1);
|
|
send = (UINT8)((addr>>8) & 0xFF);
|
|
UartWrite(serial_handle, &send, 1);
|
|
send = (UINT8)(addr & 0xFF);
|
|
UartWrite(serial_handle, &send, 1);
|
|
|
|
UartRead(serial_handle, &received, 1); // response
|
|
if (received != ADDRESS)
|
|
{
|
|
printf("Protocol error!\n");
|
|
return 1;
|
|
}
|
|
|
|
while (size)
|
|
{
|
|
if (size >= 16)
|
|
{ // we can use a "burst" command
|
|
send = BYTE_READ16;
|
|
UartWrite(serial_handle, &send, 1); // send the read command
|
|
UartRead(serial_handle, pBuffer, 16); // data response
|
|
pBuffer += 16;
|
|
size -= 16;
|
|
}
|
|
else
|
|
{ // use single byte command
|
|
send = BYTE_READ;
|
|
UartWrite(serial_handle, &send, 1); // send the read command
|
|
UartRead(serial_handle, pBuffer++, 1); // data response
|
|
size--;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
// write many bytes using the target monitor
|
|
int WriteByteMultiple(tUartHandle serial_handle, UINT32 addr, UINT32 size, UINT8* pBuffer)
|
|
{
|
|
UINT8 send, received;
|
|
|
|
// send the address command
|
|
send = ADDRESS;
|
|
UartWrite(serial_handle, &send, 1);
|
|
|
|
// transmit the address, big endian
|
|
send = (UINT8)((addr>>24) & 0xFF);
|
|
UartWrite(serial_handle, &send, 1);
|
|
send = (UINT8)((addr>>16) & 0xFF);
|
|
UartWrite(serial_handle, &send, 1);
|
|
send = (UINT8)((addr>>8) & 0xFF);
|
|
UartWrite(serial_handle, &send, 1);
|
|
send = (UINT8)(addr & 0xFF);
|
|
UartWrite(serial_handle, &send, 1);
|
|
|
|
UartRead(serial_handle, &received, 1); // response
|
|
if (received != ADDRESS)
|
|
{
|
|
printf("Protocol error!\n");
|
|
return 1;
|
|
}
|
|
|
|
while (size)
|
|
{
|
|
if (size >= 16)
|
|
{ // we can use a "burst" command
|
|
send = BYTE_WRITE16;
|
|
UartWrite(serial_handle, &send, 1); // send the write command
|
|
UartWrite(serial_handle, pBuffer, 16); // transmit the data
|
|
UartRead(serial_handle, &received, 1); // response
|
|
if (received != BYTE_WRITE16)
|
|
{
|
|
printf("Protocol error!\n");
|
|
return 1;
|
|
}
|
|
pBuffer += 16;
|
|
size -= 16;
|
|
}
|
|
else
|
|
{ // use single byte command
|
|
send = BYTE_WRITE;
|
|
UartWrite(serial_handle, &send, 1); // send the write command
|
|
UartWrite(serial_handle, pBuffer++, 1); // transmit the data
|
|
UartRead(serial_handle, &received, 1); // response
|
|
if (received != BYTE_WRITE)
|
|
{
|
|
printf("Protocol error!\n");
|
|
return 1;
|
|
}
|
|
size--;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
// write many bytes using the target monitor
|
|
int FlashByteMultiple(tUartHandle serial_handle, UINT32 addr, UINT32 size, UINT8* pBuffer)
|
|
{
|
|
UINT8 send, received;
|
|
|
|
// send the address command
|
|
send = ADDRESS;
|
|
UartWrite(serial_handle, &send, 1);
|
|
|
|
// transmit the address, big endian
|
|
send = (UINT8)((addr>>24) & 0xFF);
|
|
UartWrite(serial_handle, &send, 1);
|
|
send = (UINT8)((addr>>16) & 0xFF);
|
|
UartWrite(serial_handle, &send, 1);
|
|
send = (UINT8)((addr>>8) & 0xFF);
|
|
UartWrite(serial_handle, &send, 1);
|
|
send = (UINT8)(addr & 0xFF);
|
|
UartWrite(serial_handle, &send, 1);
|
|
|
|
UartRead(serial_handle, &received, 1); // response
|
|
if (received != ADDRESS)
|
|
{
|
|
printf("Protocol error!\n");
|
|
return 1;
|
|
}
|
|
|
|
while (size)
|
|
{
|
|
if (size >= 16)
|
|
{ // we can use a "burst" command
|
|
send = BYTE_FLASH16;
|
|
UartWrite(serial_handle, &send, 1); // send the write command
|
|
UartWrite(serial_handle, pBuffer, 16); // transmit the data
|
|
UartRead(serial_handle, &received, 1); // response
|
|
if (received != BYTE_FLASH16)
|
|
{
|
|
printf("Protocol error!\n");
|
|
return 1;
|
|
}
|
|
pBuffer += 16;
|
|
size -= 16;
|
|
}
|
|
else
|
|
{ // use single byte command
|
|
send = BYTE_FLASH;
|
|
UartWrite(serial_handle, &send, 1); // send the write command
|
|
UartWrite(serial_handle, pBuffer++, 1); // transmit the data
|
|
UartRead(serial_handle, &received, 1); // response
|
|
if (received != BYTE_FLASH)
|
|
{
|
|
printf("Protocol error!\n");
|
|
return 1;
|
|
}
|
|
size--;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
// read a 16bit halfword using the target monitor
|
|
UINT16 ReadHalfword(tUartHandle serial_handle, UINT32 addr)
|
|
{
|
|
UINT8 send;
|
|
UINT8 received;
|
|
UINT16 halfword;
|
|
|
|
// send the address command
|
|
send = ADDRESS;
|
|
UartWrite(serial_handle, &send, 1);
|
|
|
|
// transmit the address, big endian
|
|
send = (UINT8)((addr>>24) & 0xFF);
|
|
UartWrite(serial_handle, &send, 1);
|
|
send = (UINT8)((addr>>16) & 0xFF);
|
|
UartWrite(serial_handle, &send, 1);
|
|
send = (UINT8)((addr>>8) & 0xFF);
|
|
UartWrite(serial_handle, &send, 1);
|
|
send = (UINT8)(addr & 0xFF);
|
|
UartWrite(serial_handle, &send, 1);
|
|
|
|
UartRead(serial_handle, &received, 1); // response
|
|
if (received != ADDRESS)
|
|
{
|
|
printf("Protocol error!\n");
|
|
return 1;
|
|
}
|
|
|
|
// send the read command
|
|
send = HALFWORD_READ;
|
|
UartWrite(serial_handle, &send, 1);
|
|
|
|
UartRead(serial_handle, &received, 1); // response
|
|
halfword = received << 8; // highbyte
|
|
UartRead(serial_handle, &received, 1);
|
|
halfword |= received; // lowbyte
|
|
|
|
return halfword;
|
|
}
|
|
|
|
|
|
// write a 16bit halfword using the target monitor
|
|
int WriteHalfword(tUartHandle serial_handle, UINT32 addr, UINT16 halfword)
|
|
{
|
|
UINT8 send;
|
|
UINT8 received;
|
|
|
|
// send the address command
|
|
send = ADDRESS;
|
|
UartWrite(serial_handle, &send, 1);
|
|
|
|
// transmit the address, big endian
|
|
send = (UINT8)((addr>>24) & 0xFF);
|
|
UartWrite(serial_handle, &send, 1);
|
|
send = (UINT8)((addr>>16) & 0xFF);
|
|
UartWrite(serial_handle, &send, 1);
|
|
send = (UINT8)((addr>>8) & 0xFF);
|
|
UartWrite(serial_handle, &send, 1);
|
|
send = (UINT8)(addr & 0xFF);
|
|
UartWrite(serial_handle, &send, 1);
|
|
|
|
UartRead(serial_handle, &received, 1); // response
|
|
if (received != ADDRESS)
|
|
{
|
|
printf("Protocol error!\n");
|
|
return 1;
|
|
}
|
|
|
|
// send the write command
|
|
send = HALFWORD_WRITE;
|
|
UartWrite(serial_handle, &send, 1);
|
|
|
|
// transmit the data
|
|
send = halfword >> 8; // highbyte
|
|
UartWrite(serial_handle, &send, 1);
|
|
send = halfword & 0xFF; // lowbyte
|
|
UartWrite(serial_handle, &send, 1);
|
|
|
|
UartRead(serial_handle, &received, 1); // response
|
|
|
|
if (received != HALFWORD_WRITE)
|
|
{
|
|
printf("Protocol error!\n");
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
// change baudrate using target monitor
|
|
int SetTargetBaudrate(tUartHandle serial_handle, long lClock, long lBaudrate)
|
|
{
|
|
UINT8 send;
|
|
UINT8 received;
|
|
UINT8 brr;
|
|
long lBRR;
|
|
|
|
lBRR = lClock / lBaudrate;
|
|
lBRR = ((lBRR + 16) / 32) - 1; // with rounding
|
|
brr = (UINT8)lBRR;
|
|
|
|
// send the command
|
|
send = BAUDRATE;
|
|
UartWrite(serial_handle, &send, 1);
|
|
UartWrite(serial_handle, &brr, 1); // send the BRR value
|
|
UartRead(serial_handle, &received, 1); // response ack
|
|
|
|
if (received != BAUDRATE)
|
|
{ // bad situation, now we're unclear about the baudrate of the target
|
|
printf("Protocol error!\n");
|
|
return 1;
|
|
}
|
|
|
|
SLEEP(100); // give it some time to settle
|
|
|
|
// change our baudrate, too
|
|
UartConfig(serial_handle, lBaudrate, eNOPARITY, eONESTOPBIT, 8);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
// call a subroutine using the target monitor
|
|
int Execute(tUartHandle serial_handle, UINT32 addr, bool bReturns)
|
|
{
|
|
UINT8 send;
|
|
UINT8 received;
|
|
|
|
// send the address command
|
|
send = ADDRESS;
|
|
UartWrite(serial_handle, &send, 1);
|
|
|
|
// transmit the address, big endian
|
|
send = (UINT8)((addr>>24) & 0xFF);
|
|
UartWrite(serial_handle, &send, 1);
|
|
send = (UINT8)((addr>>16) & 0xFF);
|
|
UartWrite(serial_handle, &send, 1);
|
|
send = (UINT8)((addr>>8) & 0xFF);
|
|
UartWrite(serial_handle, &send, 1);
|
|
send = (UINT8)(addr & 0xFF);
|
|
UartWrite(serial_handle, &send, 1);
|
|
|
|
UartRead(serial_handle, &received, 1); // response
|
|
if (received != ADDRESS)
|
|
{
|
|
printf("Protocol error!\n");
|
|
return 1;
|
|
}
|
|
|
|
// send the execute command
|
|
send = EXECUTE;
|
|
UartWrite(serial_handle, &send, 1);
|
|
if (bReturns)
|
|
{ // we expect the call to return control to minimon
|
|
UartRead(serial_handle, &received, 1); // response
|
|
|
|
if (received != EXECUTE)
|
|
{
|
|
printf("Protocol error!\n");
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|