⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 尽量朝“单片”方向设计硬件系统。系统器件越多
💻 C
字号:
 /*----------------------------------------------------------------------------
                           Title: DK3300_RS232_IAP
                       Project Name: DK3300_RS232_IAP
                              Date: November 12, 2003
                              Author: Marian ILECKO

    Description: In-Application-Programming Driven by RS232 demonstration program

    Copyright 2003 ST Microelectronics
         This example demo code is provided as is and has no warranty,
     implied or otherwise.  You are free to use/modify any of the provided
    code at your own risk in your applications with the expressed limitation
    of liability (see below) so long as your product using the code contains
                      at least one uPSD products (device).

    LIMITATION OF LIABILITY:   NEITHER STMicroelectronics NOR ITS VENDORS OR
   AGENTS SHALL BE LIABLE FOR ANY LOSS OF PROFITS, LOSS OF USE, LOSS OF DATA,
       INTERRUPTION OF BUSINESS, NOR FOR INDIRECT, SPECIAL, INCIDENTAL OR
       CONSEQUENTIAL DAMAGES OF ANY KIND WHETHER UNDER THIS AGREEMENT OR
         OTHERWISE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 ----------------------------------------------------------------------------*/

#include "upsd3300.h"           // special function register declarations for UPSD
#include "turbolite_hardware.h" // Specific hardware configurations

#include "lcd_io.h"				// Char LCD routines
#include "iap_lib\sio.h"		// Serial IO routines
#include "iap_lib\flashcode.h"  // Flash memory routines                   

#include <string.h> // prototype declarations for standard Keil library functions

xdata PSD_REGS PSD8xx_reg _at_ PSD_REG_ADDR;	// Define PSD registers at address "csiop" space
extern xdata char LCD_buffer[LCD_ColNumBuf*LCD_RowNum]; // IAP&D Memory

/////////////////// Prototypes

// Demo Program routines


// Sets the PAGE register, returns its old value
uchar page_set(uchar desired_page){
	uchar x,y;
	x = PSD8xx_reg.PAGE;        // read page reg from PSD8XX first
	y = (x & SWAP_MASK) | (desired_page & ~SWAP_MASK);
	PSD8xx_reg.PAGE = y;		// set new page   
	return(x);	          		// return old page   
}

#define PACKET_HEADER 0x21 // control byte to indicate start of the packet

// Converts one hexadecimal character to byte
unsigned char atoh_nibble(char *string){
	if ((string[0]>='a')&&(string[0]<='z')) return(string[0]-'a'+10);
	if ((string[0]>='A')&&(string[0]<='Z')) return(string[0]-'A'+10);
	if ((string[0]>='0')&&(string[0]<='9')) return(string[0]-'0');
	return 0;
}

// Converts pair of hexadecimal characters to byte
unsigned char atoh(char *string){
	return (16*atoh_nibble(string)+atoh_nibble(string+1));
}

// IAP commands parser/processor
void parse_command(uchar *command_data, int command_data_length){

	uchar xdata *pointer_data;
	uchar code *pointer_code;
	uchar *pointer;

	static volatile uchar tmp[4];
	uchar write_result;
	uchar write_block_result;
	uchar page,vm;
	int i;
	int i_max;
	uchar unknown_command;

	i=command_data_length; //only dummy to prevent the warning

// List of implemented commands (in order of appearance):
// write flash toggle	WFT
// write flash poll		WFP
// write RAM code		WRC
// write RAM data		WRD
// read RAM code		RRC (RFC unimplemented, same functionality achieved using RRC)
// read RAM data		RRD (RFD unimplemented, same functionality achieved using RRD)
// set PAGE register    PG
// set VM register      VM
// write text to LCD    LCD
// reset the board      RST
// erase Main Flash     EM
// erase Boot Flash     EB
// get board type       BRD
// get LCD content      MIR

	unknown_command = 0;

	if (!strncmp(command_data,"PG ",3))
	{
		page = atoh(command_data+3);

		write_result = page_set(page);
		
		tmp[0] = htoa_hi(write_result);
		tmp[1] = htoa_lo(write_result);
		tmp[2] = htoa_hi(page);
		tmp[3] = htoa_lo(page);
		
		com_putstring(command_data,2);
		com_putstring(" set ",5);
		com_putstring(tmp,2);
		com_putstring("->",2);
		com_putstring(tmp+2,2);

		printfLCD("PG%x->%x  \n\r",write_result,page);
	}	

	else if (!strncmp(command_data,"VM ",3))
	{
		vm = atoh(command_data+3);

		write_result = PSD8xx_reg.VM;
		PSD8xx_reg.VM = vm;
		
		tmp[0] = htoa_hi(write_result);
		tmp[1] = htoa_lo(write_result);
		tmp[2] = htoa_hi(vm);
		tmp[3] = htoa_lo(vm);
		
		com_putstring(command_data,2);
		com_putstring(" set ",5);
		com_putstring(tmp,2);
		com_putstring("->",2);
		com_putstring(tmp+2,2);

		lcd_clear();		
		printfLCD("VM%x->%x  \n\r",write_result,vm);
	}

	else if (!strncmp(command_data,"BRD",3))
	{
		com_putstring(command_data,3);
		com_putstring(" DK3300",7);
	}
	
	else if (!strncmp(command_data,"LCD ",4))
	{
		lcd_clear();
		for(i=4;i<20;i++)
		printfLCD("%c",command_data[i]);
		printfLCD("\n\r");
		for(i=20;i<36;i++)
		printfLCD("%c",command_data[i]);
		com_putstring(command_data,21);
		com_putstring(" OK",3);
	}
	
	else if (!strncmp(command_data,"MIR",3))
	{
		com_putstring(command_data,3);
		com_putstring(" ",1);
		com_putstring(LCD_buffer,LCD_BUFFER_SIZE);
		com_putstring(" OK",3);
	}
	
	else if (!strncmp(command_data,"RST",3))
	{
		lcd_clear();
		printfLCD("BOARD RESET\n\rIN PROGRESS");
		com_putstring(command_data,3);
		com_putstring(" OK",3);
		WDKEY=0; // watchdog will trigger reset in a second
		while(1);
	}

	else if ((command_data[0]=='W')||(command_data[0]=='R'))
	{
		lcd_clear();
		printfLCD("%c%c%c(",command_data[0],command_data[1],command_data[2]);
		pointer = (uchar *)(((unsigned int)256)*((unsigned int)command_data[3])+((unsigned int)command_data[4]));

		printfLCD("%w",(unsigned int)pointer);
		printfLCD(")\n\r");
		
		tmp[0] = htoa_hi((unsigned char)(((unsigned int)pointer)>>8));
		tmp[1] = htoa_lo((unsigned char)(((unsigned int)pointer)>>8));
		tmp[2] = htoa_hi((unsigned char)((unsigned int)pointer));
		tmp[3] = htoa_lo((unsigned char)((unsigned int)pointer));

		com_putstring(command_data,3);
		com_putstring(" at 0x",6);
		com_putstring(tmp,4);
		com_putstring(": ",2);
		if (command_data[0]=='R') //read operation
		{
			i_max=(int)command_data[5];
				     
			if (command_data[1]=='R') //RAM (volatile memory)
			{
				if (command_data[2]=='C') //code area (code, movc)
				{
					pointer_code = (uchar code *)pointer;
					com_putstring(pointer_code,i_max);
				}
				else if (command_data[2]=='D') //data area (xdata, movx)
				{
					pointer_data = (uchar xdata *)pointer;
					com_putstring(pointer_data,i_max);
				}
				else unknown_command = 1;
			}
			else unknown_command = 2;
		}	
			
		else if (command_data[0]=='W') //write operation
		{	
			if (command_data[1]=='F') //FLASH (non-volatile memory)
			{
				write_block_result = 0;
				if (command_data[2]=='T') //write using toggle method
				{
					for (i=0; i<command_data[5]; i++, pointer++){
					if(pointer>=0x8000)
					write_result = 0;//flash_write_with_toggle(pointer,command_data[6+i]);
					else 
					write_result = 0;//flash_boot_write_with_toggle(pointer,command_data[6+i]);
					write_block_result += write_result;
					}
				}
				else if (command_data[2]=='P') //write using poll method
				{
					for (i=0; i<command_data[5]; i++, pointer++){
						if(pointer>=0x8000)
							write_result = flash_write_with_poll(pointer,command_data[6+i]);
						else 
							write_result = flash_boot_write_with_poll(pointer,command_data[6+i]);
						write_block_result += write_result;
					}
				}
				else unknown_command = 4;

				tmp[0] = htoa_hi(write_block_result);
				tmp[1] = htoa_lo(write_block_result);
				com_putstring(tmp, 2);
				com_putstring(" B WRITTEN", 10);
			}
			else unknown_command = 5;
		}
		else unknown_command = 6;
	}

	else if (command_data[0]=='E') //erase operation
	{
		lcd_clear();
		pointer = (uchar *)(((unsigned int)256)*((unsigned int)command_data[2])+((unsigned int)command_data[3]));

	 	printfLCD("ERASE(");
		printfLCD("%w",(unsigned int)pointer);

		if(command_data[1]=='M'){
			com_putstring(command_data,2);
			com_putstring(" MAIN OK",8);
       		printfLCD(")MAIN");
	   		flash_erase_sector((volatile uchar xdata*) pointer);
		}
		else if(command_data[1]=='B'){
       		printfLCD(")BOOT");
			com_putstring(command_data,2);
			com_putstring(" BOOT OK",8);
        	flash_boot_erase_sector((volatile uchar xdata*) pointer);
		}
		else unknown_command = 7;
	}
	else unknown_command = 8;
	if (unknown_command)
	{
//		printfLCD("\nNoCommand! (#%x)",unknown_command);
		com_putstring("Unknown command!",16);
	}
}

void process_received_packet(uchar *packet_data, int packet_length){
   unsigned char sum1=0, sum2=0;
   int i;
   for (i=0; i<packet_length-2; i++){
      sum1 += packet_data[i];
      sum2 ^= packet_data[i];
   }
   if ((sum1==packet_data[packet_length-2])&&(sum2==packet_data[packet_length-1])) {
	  parse_command(packet_data, packet_length-2);
   }
   else {
		com_putstring("csum BAD",8);
//      printfLCD("\nBAD CHECKSUM !!!\n");
   }
}

// main program of IAP Demo
void main (void){

	static int recv_data_length;                 // length of received data
	static int packet_expected_length;           // expected length of the packet arriving
	static int recv_part_length;				 // length of received fragment of the packet
	static unsigned char packet_parts;           // how many parts the packet arrived divided in
	static unsigned char packet_length_MSB;      // MSB of packet length value
	static unsigned char packet_length_LSB;      // LSB of packet length value
	static unsigned char packet_checksum;        // checksum of the packet header
	xdata unsigned char recv_string_buffer[800]; // buffer for received data (you can optimize this value)
	static int recv_timeout;                     // receive timeout counter 

	#define RECV_TIMEOUT 10                      // receive timeout constant

	WDKEY = 0x55;                       // disable the watchdog
	PSD8xx_reg.VM |= 0x80;              // enable peripheral I/O mode for LCD display
	initLCD();                          // initialize LCD
	com_initialize();					// initialize RS232 line

	packet_parts = 0;
	recv_data_length = 0;
	recv_timeout = 0;

	printfLCD("RS232 IAP Demo\n\rfor DK3300 READY\n\r");   // display the intro message
//	com_putstring("\nRS232 IAP Demo for DK3300 READY\n",33); // transmit the intro message

	while (TRUE)
	{
		if(recv_timeout==1) // if receive timeout occured
		{
			recv_data_length = 0; // trash the received data
			packet_parts = 0;
			com_putstring("RX Timeout\x0d\x0a",12);
		}
		if(recv_timeout)
		   recv_timeout--;

   		if (recv_part_length = com_getstring(recv_string_buffer+recv_data_length))
		{
			recv_timeout = RECV_TIMEOUT;
			if (!packet_parts)
			{
				if (recv_part_length >= 4) // this is the first part of the packet (or maybe the complete packet)
				{ 
					if (recv_string_buffer[0] != PACKET_HEADER) 
						recv_data_length=0; // trash the received data
					else 
					{
						packet_length_MSB = recv_string_buffer[1];
						packet_length_LSB = recv_string_buffer[2];
						packet_checksum = - packet_length_MSB - packet_length_LSB;
						if (packet_checksum != recv_string_buffer[3]) 
							recv_data_length=0; // trash the received data
						else
						{
							recv_timeout = RECV_TIMEOUT;
							packet_parts++;
							packet_expected_length = packet_length_MSB * 256 + packet_length_LSB;
							if (recv_part_length > 4)
							{
								recv_data_length += recv_part_length;
								if (recv_data_length >= packet_expected_length){
									// do something with the data here
									process_received_packet(recv_string_buffer+4, packet_expected_length-4);
									// flush the processed packet
									recv_data_length = 0;
									packet_parts = 0;
									recv_timeout = 0;
								}
							}
						}
					}
				}
			}
			else { // if this is not first part of the packet
				recv_timeout = RECV_TIMEOUT;
				packet_parts++;
				recv_data_length += recv_part_length;
				if (recv_data_length >= packet_expected_length)
				{
					// do something with the data here
					process_received_packet(recv_string_buffer+4, packet_expected_length-4);
					// flush the processed packet
					recv_data_length = 0;
					packet_parts = 0;
					recv_timeout = 0;
				}
			}
		}
	delay_ms(10); // Wait, basic time quantum
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -