forked from len0rd/rockbox
		
	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;
 | |
| }
 | |
| 
 | |
| 
 |