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

📄 uart.c

📁 mega128的bootload, 支持flash(128k)读写,eepron读写,外部扩展rom读写, 主机可发命令提高波特率,可发命令重启.编译环境IAR for AVR4.20
💻 C
字号:
/*
*********************************************************************************************************
*                                              Atmega128
*                                          UART
*
*
* File    : UART.C
* Version : V0.01
* Data: March 20, 2007
*********************************************************************************************************
*/

#include "bootloader.h"

char Slip_inbuf[SLIP_BUFFER_SIZE];
char LedT;

/*
*********************************************************************************************************
*                                         UART_putc
*
* Description      :
* Arguments        :
* Returned Values  : none
* Note(s)/Warnings :
*********************************************************************************************************
*/
void UART_putc(BYTE c)
{
    while ( !(UCSR0A & (1<<UDRE0)));
    UDR0 = c;
}

/*
*********************************************************************************************************
*                                         UART_getc
*
* Description      :
* Arguments        :
* Returned Values  : none
* Note(s)/Warnings :
*********************************************************************************************************
*/
char UART_getc(void)
{
	while(1){
		if(UCSR0A & (1<<RXC0)) return 1;										//if(UCSR0A & (1<<UDRE0)) return 1;														
		if(Wait && (TIMER_OVERFLOW)){
			TIMER_CLEAR;
			if(--Wait == 0) return 0; 
		}
	}
}

/*
*********************************************************************************************************
*                                        Slip_unpackage
*
* Description      :
* Arguments        :
* Returned Values  :
* Note(s)/Warnings :
*********************************************************************************************************
*/
char Sumcheck(LENGTH_TYPE 	num)
{ 
	char *p = Slip_inbuf;
	char sum = 0;
	
	while(num--)
		sum += *p++;
	return ~sum;
}

char Slip_unpackage(void)
{
	int 			tmp;
	char  			cmd;
	char 			*p;
	unsigned int 	addr;
	LENGTH_TYPE 	num;
	LENGTH_TYPE   	i;
	LENGTH_TYPE 	length;
    #ifdef EN_EXROM 
	char			highaddr;
    #endif
	#ifdef EN_ERROR
	char			Err0;
	char			Err1;
	#endif
        
    Led(LedT = ~LedT);
	length = 0;
	p = Slip_inbuf;
	while(1) {
		
        if(UART_getc() == 0) return 0;
		cmd = UDR0;
		
		if(cmd == SLIP_END){
			if(length) break;
			else continue;
			
		}else if(cmd == SLIP_ESC){
            if(UART_getc() == 0) return 0;
			cmd = UDR0;

			if(cmd == SLIP_ESC_END) 	{cmd = SLIP_END;}
			else if(cmd == SLIP_ESC_ESC){cmd = SLIP_ESC;}
			else 						{return 0;}
		}
		
		if(length <= SLIP_BUFFER_SIZE) {
			*p++ = cmd;
			length++;
		}else {
			return 0;
		}
	}
	        
	if(Sumcheck(length)){
		#ifdef EN_ERROR
		Err0 = SLIP_ER_SUMCHECK;
		#endif
		goto Error;
	}			
    
	p = Slip_inbuf + 1;
	cmd = *p++;
	addr = *p++;
	addr += (*p++)<<8;
	#ifdef EN_PAMPZ
	RAMPZ = *p++;
	#endif

	num = *p++;
	#if	(FLASH_PAGE_WIDTH == 2)
	num += (*p++)<<8;
	#endif
	
#ifdef EN_EXROM
	highaddr = (Slip_inbuf[SLIP_PKG_ADDR+1]>>4) + (Slip_inbuf[SLIP_PKG_ADDR+2] <<4);
    Flash_Sector_Set(highaddr);
	
	if(cmd == SLIP_W_EXROM){	
        addr &= 0x0fff;
		Flash_Write_String(addr, p, num);
		length = 2 + FLASH_ADDRESS_WIDTH + FLASH_PAGE_WIDTH + 1;
		
	}else if(cmd == SLIP_R_EXROM){
        addr &= 0x0fff;
		Flash_Read_String(addr, p, num);
		length += num;
		
	}else if(cmd == SLIP_E_EXROM){
        addr &= 0x0fff;
		Flash_Erase_Sector(highaddr);
		length = 2 + FLASH_ADDRESS_WIDTH + FLASH_PAGE_WIDTH + 1;
		
	}else if(cmd == SLIP_R_EXROMID){
		Flash_Read_ID(p);
		length += num;
		
	}else if(cmd == SLIP_START){
#else
	if(cmd == SLIP_START){
#endif
		  	Slip_inbuf[SLIP_PKG_CTRL0] = BOOT_CTRL0;	
			Slip_inbuf[SLIP_PKG_CTRL1] = BOOT_CTRL1;
            #ifdef EN_EXPAND
            Slip_inbuf[SLIP_PKG_EXCTRL0] = BOOT_EXCTRL0;	
			Slip_inbuf[SLIP_PKG_EXCTRL1] = BOOT_EXCTRL1;
            length = 6+1;
            #else
			length = 4+1;	
            #endif            
		
	}else if(cmd == SLIP_FINISH){
		  	Goto_app();
            
	}else if(cmd == SLIP_BAUD){
            length = 2+1;
			
	}else if(cmd <= 0x03){														// write package
		if(cmd == SLIP_W_FLASH){
		
			Spm_page_erase(addr);												// erase one page                   							
		
			for(i=0 ; i<num;  i+=2){               								// write data to flash buffer
				tmp  = *p++;
				tmp += *p++ <<8;
				Spm_page_fill(i, tmp);
			}
			Spm_page_write(addr);												// write flash buffer to flash
#ifdef VERIFY_FLASH
			while(i--){
				if(Read_flash(addr + i) != *p--){
					#ifdef ERROR_INFO
					Err0 = SLIP_ER_VERIFY;
					#endif
					goto Error;
				}
			}
#endif
		}else{
			for(i=0; i<num; i++){
				if(cmd == SLIP_W_EEPROM) {										// write eeprom
#ifdef VERIFY_EEPROM //-------------------			
					EEPPUT(addr+i, *p);
					if(EEPGET((addr+i) != *p++){
 						#ifdef EN_ERROR
						Err0 = SLIP_ER_VERIFY;
 						#endif
						goto Error;
					}
#else				//-------------------		
					EEPPUT(addr+i, *p++);
#endif
				}else {															// write fuse
					Spm_fuse_write(i, *p++);
				}
			}
		}
		length = 2 + FLASH_ADDRESS_WIDTH + FLASH_PAGE_WIDTH + 1;
		
	}else{																		// read and unknow packages
			for(i=0; i<num; i++){
			  	if(cmd == SLIP_R_FLASH) 	 	*p++ = Read_flash(addr+i);		// read flash
				else if( cmd == SLIP_R_EEPROM) 	*p++ = EEPGET(addr+i);			// read eeprom
				else if (cmd == SLIP_R_FUSE) 	*p++ = Read_fuse(addr+i);		// read fuse
				else {															// unknow package
 					#ifdef EN_ERROR
					Err0 = SLIP_ER_UNKNOWPKG;
 					#endif
					goto Error;							
				}
		  	}
			length += num;
	}
	
	#ifdef ALWAYS_CHECK_LINK
	Wait = BOOT_WAIT;
	#endif
    
    if(length > (SPM_PAGESIZE+8 )) 
        goto Error;                         //?????
	Slip_package(SLIP_ACK|cmd, length-1);
	return 1;
	
Error:
	#ifdef EN_ERROR
  	Slip_inbuf[SLIP_PKG_CTRL0] = Err0;
	Slip_inbuf[SLIP_PKG_CTRL1] = Err1;
	Slip_package(SLIP_ACK|SLIP_ERROR,4);
	#else
	Slip_package(SLIP_ACK|SLIP_ERROR,2);
	#endif
	return 0;
}

/*
*********************************************************************************************************
*                                        Slip_package
*
* Description      :
* Arguments        :
* Returned Values  :
* Note(s)/Warnings :			
*********************************************************************************************************
*/
void Slip_package(char cmd, LENGTH_TYPE len)
{
	char *p = Slip_inbuf;
	
	Slip_inbuf[SLIP_PKG_CMD] = cmd;
	Slip_inbuf[len] = Sumcheck(len);
	len++;
	
	UART_putc(SLIP_END);
	while(len--) {
		if(*p == SLIP_END){
			UART_putc(SLIP_ESC);
			UART_putc(SLIP_ESC_END);
		}else if(*p == SLIP_ESC){
			UART_putc(SLIP_ESC);
			UART_putc(SLIP_ESC_ESC);
		}else{
			UART_putc(*p);
		}
		p++;
	}
	UART_putc(SLIP_END);
	while ( !(UCSR0A & (1<<UDRE0)));
    
#ifdef EN_BAUD_CHANGE    
    if(cmd == (SLIP_ACK | SLIP_BAUD)){                                            // baud change
        #ifdef USE_UBRR0H
		UBRR0H = HIGH(BAUD_HIGH);
        #endif
		UBRR0L = LOW(BAUD_HIGH);
    }
#endif 
}

⌨️ 快捷键说明

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