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

📄 uart.c

📁 mega88的bootload, 基于串口,支持flash读写,eeprom读写,fuse读写,编译环境IAR for AVR 4.20, 包含xcl配置文件
💻 C
字号:
/*
*********************************************************************************************************
*                                              Atmega48
*                                          UART
*
*                          	(c) Copyright 2006-2007, Sky Channel Tech. Ltd.
*                                           All Rights Reserved
*
* File    : UART.C
* By      : Jason Yang
* Version : V0.01
* Data	  : March 20, 2007
*********************************************************************************************************
*/

#include "bootloader.h"

char Slip_inbuf[SLIP_BUFFER_SIZE];

/*
*********************************************************************************************************
*                                         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_ERROR
	char			Err0;
	char			Err1;
#endif
	
	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
	
	if(cmd == SLIP_START){
		Slip_inbuf[SLIP_PKG_CTRL0] = BOOT_CTRL0;	
		Slip_inbuf[SLIP_PKG_CTRL1] = BOOT_CTRL1;	
		length = 4+1;	
		
	}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{                                                                  // SLIP_W_EEPROM                                                         
			for(i=0; i<num; i++){
				if(cmd == SLIP_W_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 {                                                         // SLIP_W_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);
				else if( cmd == SLIP_R_EEPROM) 	*p++ = EEPGET(addr+i);
				else if (cmd == SLIP_R_FUSE) 	*p++ = Read_fuse(addr+i);
				else {
#ifdef EN_ERROR
					Err0 = SLIP_ER_UNKNOWPKG;
#endif
					goto Error;		
				}
		  	}
			length += num;
	}
	
#ifdef ALWAYS_CHECK_LINK
	Wait = BOOT_WAIT;
#endif
	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 + -