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

📄 bootloader.bu.c

📁 GCC source code for do it yoursel a avr programer and jtagice debuger.
💻 C
字号:
/**************************** 	IsoJTAG Bootloader*	For ATmega16***************************/#include <inttypes.h>#include <avr/io.h>#include <avr/interrupt.h>#include <avr/wdt.h>#include <avr/boot.h>#include <avr/pgmspace.h>
#include "crystal.h"
#include "memory.h"
#define BOOTDDR		DDRC#define BOOTPIN		PINC#define BOOTPORT	PORTC#define	BOOTPNUM	6

#define LEDDDR		DDRB
#define LEDPORT		PORTB
#define LEDBIT		3

#define devtype 0x75       // Mega16 device code
  
#define APP_PAGES ((2*8192 / SPM_PAGESIZE)- (2*1024 / SPM_PAGESIZE )) 
#define APP_END APP_PAGES * SPM_PAGESIZE 
// Prototypes
int main(void) 			__attribute__ ((section (".bloader")));
void send_boot(void)  	__attribute__ ((section (".bloader")));
void send_usart (unsigned char)  __attribute__ ((section (".bloader")));void USART_Init (void)  __attribute__ ((section (".bloader")));unsigned char read_usart (void)  __attribute__ ((section (".bloader")));
void jump_to_jtag(void) __attribute__ ((section (".bloader")));

extern void isp_start(void)  __attribute__ ((section ("text")));
unsigned int baddress;
unsigned int waddress;unsigned char device;

unsigned char vals[200];
unsigned char valscnt = 0;
int main(void){	
	asm volatile("clr r1"::);	

	unsigned int temp_int = 0;	unsigned char val;    
	unsigned int patch = 0;
	unsigned int patch2 = 0;
	unsigned char wait_time_x2 = 0;
	cli();		MCUCR = (1<<IVCE);   	// move interruptvectors to the Boot sector    	MCUCR = (1<<IVSEL);  	// device specific !		BOOTDDR  &= ~(1<<BOOTPNUM);		// set as Input	BOOTPORT |= (1<<BOOTPNUM);		// Enable pullup

	LEDDDR |= (1 << LEDBIT);		// set as Output		USART_Init();	//TCCR1A = 0; // timer setup		#define WAIT_VALUE ((FREQ / 1024) * 5)	// *2 seconds
		
	TCCR1B |= _BV(CS10);	// .
	TCCR1B |= _BV(CS12);	// .. /1024 

	TCNT1 = 0x00;	int pulseCount = 0;	
	while(1)	{			if (pulseCount == ((FREQ / 1000)+3000))
		{
			LEDPORT ^= (1 << LEDBIT);	// Pulse the LED, show in waiting mode.
			pulseCount = 0;
		}
		pulseCount++;

		if ((BOOTPIN & (1<<BOOTPNUM)) == 0)	// If in ISP mode don't enter bootloader		{			LEDPORT |= (1 << LEDBIT);		// Turn LED OFF
			MCUCR = (1<<IVCE); 			MCUCR = (0<<IVSEL);             //move interruptvectors to the Application sector			TCCR1B = 0; 					// timer off			BOOTPORT &= ~(1<<BOOTPNUM);  	// set to default			isp_start();					// Jump to application sector		}				if(UCSRA & (1<<RXC))		{			unsigned char data = UDR;
			if (data == 'S')				// If the Prog Start command is received start bootloader				break;		}		

		if (TCNT1 >= WAIT_VALUE)			// If the start command timeout runs out start main program		{		
			if (wait_time_x2 != 1)
			{
				wait_time_x2 = 1;
			}
			else
			{
				LEDPORT |= (1 << LEDBIT);		// Turn LED OFF
				MCUCR = (1<<IVCE); 				MCUCR = (0<<IVSEL);            	//move interruptvectors to the Application sector				TCCR1B = 0; 					// timer off						if ((BOOTPIN & (1<<BOOTPNUM)) != 0)				{					BOOTPORT &= ~(1<<BOOTPNUM); // set to default					jump_to_jtag();				// Jump to application sector				}				else				{					BOOTPORT &= ~(1<<BOOTPNUM); // set to default					isp_start();				// Jump to application sector				}			}
		}	}

	LEDPORT |= (1 << LEDBIT);	// Turn LED OFF	TCCR1B = 0; // timer off	send_boot();	    while(1)                                 {   

		val=read_usart();        
        switch (val)		{        	//No Data
			case 0:
			break;

			// Return Programmer Type			case 'p':			send_usart('S');			break;						// Auto inc support			case 'a':											send_usart('Y');			break;						// Return Software Identifier			case 'S':										send_boot();			break;						// Return supported devices			case 't':                   			send_usart(0x74);			send_usart(0x00);			break;						// Return Software Version        	case 'V':                  			send_usart('1');			send_usart('0');			break;			        	// set device			case 'T':								read_usart();			send_usart('\r');			break;						// Set Address        	case 'A':											baddress = (read_usart()<<8)|read_usart();	// get address			waddress = baddress * 2;               	// convert word addr to byte			send_usart('\r');			break;        				// Enter Programming Mode			case 'P':											send_usart('\r');			break;  							// Leave Programming mode			case 'L':   			send_usart('\r');			break;			        	// Read Signature			case 's':			send_usart(0x02);			send_usart(0x94);
			send_usart(0x1E);			break;						// Read Data			case 'd' :
			EEARL = baddress; // Setup EEPROM address.            EEARH = (baddress >> 8);			while(EECR & (1<<EEWE)) 
			 ;			EECR |= (1<<EERE);			send_usart(EEDR);			break;						// Read Program memory			case 'R' :              // Send high byte, then low byte of flash word.
#ifdef PATCH
			if (patch != 0)
			{
				if (waddress == patch)
				{
					send_usart(0xBD);
					send_usart(0x10);
					waddress +=2;
					break;
				}

				if (waddress == patch2)
				{
					send_usart(0xB9);
					send_usart(0x09);
					waddress +=2;
					break;
				}

			}
#endif
            boot_spm_busy_wait();                    boot_rww_enable();            send_usart( pgm_read_byte_near( waddress+1 ) );            send_usart( pgm_read_byte_near( waddress+0 ) );            waddress +=2; // Auto-advance to next Flash word.			break;						// Write Code low			case 'c' :			LEDPORT &= ~(1 << LEDBIT);
			temp_int=read_usart(); 	// Get low byte for later boot_page_fill.            
			send_usart('\r'); 		// Send OK back.			break;						// Write Code high			case 'C' :
			temp_int |= (read_usart()<<8); // Get and insert high byte.
#ifdef PATCH
			if (temp_int == 0xBD10)
			{
				temp_int = 0x940E;
				patch = waddress;
			}


			if (temp_int == 0xB909)
			{
				temp_int = UBRRSTART;
				patch2 = waddress;
			}
#endif
			
			LEDPORT |= (1 << LEDBIT);
			boot_spm_busy_wait();           	boot_page_fill( waddress, temp_int ); 
			waddress +=2; // Auto-advance to next Flash word.            send_usart('\r'); // Send OK back.					
			break;						// Write Page			case 'm' :			if( baddress >= (ISPSTART) ) // Protect bootloader and ISP area.			{				send_usart('\r');			} 			else			{				boot_spm_busy_wait();        				boot_page_write( waddress ); 				send_usart('\r'); // Send OK back.
			}			break;						case 'e':                   //Chip erase 			// erase only main section (bootloader and isp protection)			baddress = 0; 			while ( (ISPSTART - SPM_PAGESIZE) >= baddress )			{				boot_page_erase(baddress);	// Perform page erase				boot_spm_busy_wait();		// Wait until the memory is erased.				baddress += SPM_PAGESIZE;			}			boot_rww_enable();			send_usart('\r');        			break;						case 'x':			read_usart();
			LEDPORT &= ~(1 << LEDBIT);			send_usart('\r'); 			break;						case 'y':			read_usart();
			LEDPORT |= (1 << LEDBIT);			send_usart('\r'); 			break;			        	case 'E':                   //Exit upgrade			wdt_enable(WDTO_15MS); // Enable Watchdog Timer to give reset			send_usart('\r');			break;       			        	case 0x1b: 				// Reset
			waddress = 0;
			baddress = 0;			break;						default:			send_usart('?');			break;		}            }				return 0;}void send_boot(void){	send_usart('A');	send_usart('V');	send_usart('R');	send_usart('B');	send_usart('O');	send_usart('O');	send_usart('T');}
/*
void send_boot(void){	send_usart('I');	send_usart('S');	send_usart('O');	send_usart('J');	send_usart('T');	send_usart('A');	send_usart('G');}*/unsigned char read_usart(void){

	while ( (UCSRA & (1<<RXC)) == 0)
	 ;
    unsigned char val = UDR;

//	vals[valscnt] = val;
//	valscnt ++;
//	if ((valscnt) > 196)
//	{
//		valscnt = 0;
//	}
	
	return val;
}void send_usart(unsigned char data){	
	while ( ( UCSRA & (1<<UDRE)) == 0 )	;
	
//	vals[valscnt] = 0xFF;
//	valscnt ++;
//	vals[valscnt] = data;
//	valscnt ++;
//
//	if ((valscnt) > 196)
//	{
//		valscnt = 0;
//	}
	
	UDR = data;}void USART_Init(void){    //UBRRL = 23;		
	UBRRL = N19200;

    UCSRB = (1<<RXEN) | (1<<TXEN);		// Enable RX and TX    UCSRC = (1<<URSEL)|(3<<UCSZ0);		// Set Frame Formats }


void jump_to_jtag(void){	asm volatile (	"LDI r31,0			\n\t"					"LDI r30,0			\n\t"					"IJMP				\n\t"	::);}
void bload_starter(void) __attribute__ ((naked)) __attribute__ ((section (".bload_start"))) ;
void bload_starter(void){	asm volatile (	"rjmp main"::);}

⌨️ 快捷键说明

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