//********************************
int main(int argc,char *argv[])
{
	int fd;
	char *data_file_name;
	char packet_data[ XMODEM_DATA_SIZE ];
//	char frame_data[ XMODEM_DATA_SIZE + XMODEM_CRC_SIZE + XMODEM_FRAME_ID_SIZE + 1 ];
	char frame_data[ XMODEM_DATA_SIZE + XMODEM_CHECKSUM_SIZE + XMODEM_FRAME_ID_SIZE + 1 ];
	unsigned char tmp;
	FILE *datafile;
	int complete,retry_num,pack_counter,read_number,write_number,i;
	unsigned short crc_value;
	unsigned char ack_id;
        unsigned int checksum = 0;

	if (argc == 1) {
		printf("Usage %s <uart device> <file to transfer>\n", argv[0]);
		printf("     Example %s /dev/ttyS0 myfile.bin\n", argv[0]);
		return 0;
	}
		

	printf("Opening Uart %s... ", argv[1]);
	if ( (fd = Initial_SerialPort(argv[1])) == -1) {
		perror ("Failed!\n");
		return -1 ;
	}
	printf("Done\n");

	data_file_name = argv[2];

	if((datafile=fopen(data_file_name,"rb"))==NULL)
	{
		perror ("Can't open file!");
		return -1 ;
	}

	//*******************************
	
	pack_counter = 0;
	complete = 0;
	retry_num = 0;
	ClearReceiveBuffer(fd);

	while((read(fd,&ack_id,1))<=0);
	
	printf("%c\r\n",ack_id);
	ack_id=XMODEM_ACK;
	while(!complete)
	{

		switch(ack_id)
		{
		case XMODEM_ACK:
			retry_num = 0;
			checksum = 0;
			pack_counter++;
			read_number = fread( packet_data, sizeof(char), XMODEM_DATA_SIZE, datafile);
			if(read_number>0)
			{
				if(read_number<XMODEM_DATA_SIZE_SOH)
				{
			
					printf("Start filling the last frame!\r\n");
					for(;read_number<XMODEM_DATA_SIZE;read_number++)
						packet_data[read_number] = 0x00;
				}
				frame_data[0] = XMODEM_HEAD;
				frame_data[1] = (char)pack_counter;
				frame_data[2] = (char)(255-frame_data[1]);
	
				for(i=0;i<XMODEM_DATA_SIZE;i++) {
					frame_data[i+3]=packet_data[i];
					checksum+=packet_data[i];	
				}
				checksum = checksum%256;
//				crc_value = GetCrc16(packet_data,XMODEM_DATA_SIZE);
//				frame_data[XMODEM_DATA_SIZE_SOH+3]=(unsigned char)(crc_value >> 8);
				frame_data[XMODEM_DATA_SIZE_SOH+3]=(unsigned char)(checksum);
//				frame_data[XMODEM_DATA_SIZE_SOH+4]=(unsigned char)(crc_value);
//				write_number = write( fd, frame_data, XMODEM_DATA_SIZE_SOH + 5);
				write_number = write( fd, frame_data, XMODEM_DATA_SIZE_SOH + 4);
				printf("wait for ACK,%d,%d,...",pack_counter,write_number);
				while(1) {
					while((read(fd,&ack_id,1))<=0);			

					if(ack_id == XMODEM_ACK) {
						printf("Ok!       \r");
						break;
					}
					else if(ack_id == XMODEM_NAK) {
						printf("Error! NAK\r");
						break;
					}
					else
						printf("Skip!     \r");
				}
			}
			else
			{
				ack_id = XMODEM_EOT;
				complete = 1;
				printf("Waiting for complete ACK ...");
			
				while(ack_id != XMODEM_ACK)
				{
					ack_id = XMODEM_EOT;	
					write_number=write(fd,&ack_id,1);
					while((read(fd,&ack_id,1))<=0);
				}
				printf("OK\r");
		
				printf("Sending file complete\r\n");
			}
		break;

		case XMODEM_NAK:
			if( retry_num++ > 10) 
			{
				printf("Retry too many times,Quit!\r\n");
				complete = 1;
			}
			else
			{
//				write_number = write(fd,frame_data,XMODEM_DATA_SIZE + 5);
				write_number = write(fd,frame_data,XMODEM_DATA_SIZE + 4);
				printf("Retry for ACK,%d,%d...",pack_counter,write_number);
				while(1) {
					while((read(fd,&ack_id,1))<=0);			

					if(ack_id == XMODEM_ACK) {
						printf("Ok!       \r");
						break;
					}
					else if(ack_id == XMODEM_NAK) {
						printf("Error! NAK\r");
						break;
					}
					else
						printf("Skip!     \r");
				}
			}
		break;

		default:
			printf("Fatal Error!\r\n");
			complete = 1;
		break;
		}

	}

	fclose(datafile);
	close(fd);

	return 0;
}
//********************************
int main(int argc,char *argv[])
{
	int fd;
	char *data_file_name;
	char packet_data[ XMODEM_DATA_SIZE ];
	char frame_data[ XMODEM_DATA_SIZE + XMODEM_CRC_SIZE + XMODEM_FRAME_ID_SIZE + 1 ];
	FILE *datafile;
	int complete,retry_num,pack_counter,read_number,write_number,i;
	unsigned short crc_value;
	unsigned char ack_id;
	unsigned char last_ack_id = 0;
	long filelength;
	long readlength = 0;
        unsigned percent;
        unsigned last_percent = 0;

	setbuf(stderr, NULL);
	
	fprintf(stderr, "sx-at91 started...\n");
	
	//**open serial port1
	if ( (fd = Initial_SerialPort()) == -1)  
		return -1 ;

	data_file_name = argv[1];

	if((datafile=fopen(data_file_name,"rb"))==NULL)
	{
		perror ("Can't open file!");
		return -1 ;
	}

	fseek(datafile, 0, SEEK_END);
	filelength = ftell(datafile);
	fseek(datafile, 0, SEEK_SET);

	//*******************************

	pack_counter = 0;
	complete = 0;
	retry_num = 0;
	ClearReceiveBuffer(fd);

	while((read(fd,&ack_id,1))<=0);
	
	//~ fprintf(stderr, "%c\n", ack_id);
	ack_id=XMODEM_ACK;
	while(!complete)
	{
		switch(ack_id)
		{
		case XMODEM_ACK:
			retry_num = 0;
			pack_counter++;
			read_number = fread( packet_data, sizeof(char), XMODEM_DATA_SIZE, datafile);
			if(read_number>0)
			{
				readlength += read_number;
				if(read_number<XMODEM_DATA_SIZE_SOH)
				{
					fprintf(stderr, "\n");
					fprintf(stderr, "Start filling the last frame!\n");
					for(;read_number<XMODEM_DATA_SIZE;read_number++)
						packet_data[read_number] = 0x00;
				}
				frame_data[0] = XMODEM_HEAD;
				frame_data[1] = (char)pack_counter;
				frame_data[2] = (char)(255-frame_data[1]);
	
				for(i=0;i<XMODEM_DATA_SIZE;i++)
					frame_data[i+3]=packet_data[i];
	
				crc_value = GetCrc16(packet_data,XMODEM_DATA_SIZE);
				frame_data[XMODEM_DATA_SIZE_SOH+3]=(unsigned char)(crc_value >> 8);
				frame_data[XMODEM_DATA_SIZE_SOH+4]=(unsigned char)(crc_value);
				write_number = write( fd, frame_data, XMODEM_DATA_SIZE_SOH + 5);
				//~ fprintf(stderr, "waiting for ACK,%d,%d,...", pack_counter, write_number);
				while((read(fd,&ack_id,1))<=0);

                                percent = (unsigned)(readlength * 100 / filelength);
                                if ((ack_id != last_ack_id) || (percent != last_percent)) {
                                  last_ack_id = ack_id;
                                  last_percent = percent;
                                  if (ack_id == XMODEM_ACK) {
                                    fprintf(stderr, "%u%% ok\r", percent);
                                  } else {
                                    fprintf(stderr, "%u%% error\n", percent);
                                  }
                                }
			}
			else
			{
				ack_id = XMODEM_EOT;
				complete = 1;
				fprintf(stderr, "Waiting for complete ACK ...");
			
				while(ack_id != XMODEM_ACK)
				{
					ack_id = XMODEM_EOT;	
					write_number=write(fd,&ack_id,1);
					while((read(fd,&ack_id,1))<=0);
				}
				fprintf(stderr, "OK\n");
		
				fprintf(stderr, "Sending file complete\n");
			}
		break;

		case XMODEM_NAK:
			if( retry_num++ > 10) 
			{
				fprintf(stderr, "Retry too many times, quit!\n");
				complete = 1;
			}
			else
			{
				write_number = write(fd,frame_data,XMODEM_DATA_SIZE + 5);
				fprintf(stderr, "Retry for ACK,%d,%d...", pack_counter, write_number);
				while((read(fd,&ack_id,1))<=0);

				if( ack_id == XMODEM_ACK )
					fprintf(stderr, "OK\n");
				else
					fprintf(stderr, "Error!\n");
			}
		break;

		default:
			fprintf(stderr, "Fatal Error!\n");
			complete = 1;
		break;
		}