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

📄 bootloader_atmega2560.c

📁 atmega2560 bootloader source code
💻 C
📖 第 1 页 / 共 3 页
字号:

        boot_rww_enable();  								// enable Read-While-Write section
		address_page1 += SPM_PAGESIZE ;
	}	
	address_flash += n_bytes ;
	for(i = 0; i < MAX_BUF_SIZE; i++) { 
		rx_buffer[i] = 0xFF;  // clear data buffer
	}
	msg_size = 2;  			// set message length		
	*(tx_pntr++) = CMD_PROGRAM_FLASH_ISP;
	*(tx_pntr++) = STATUS_CMD_OK; 	
} // end of programFlashIsp
 
int main(void)
{
	unsigned char rx_data;  // received USART data byte
	unsigned char state = STATE_READY;  // actual state

	initPorts();
	bootCheck();
	initUart();
	//testCode();
	for(;;)
	{
		rx_data=getch();  // get one byte from USART
		msg_cs ^= rx_data;


		switch( state )  {
			// start processing when byte received
			case STATE_READY :	
				if(rx_data == MESSAGE_START)  // wait for message start
	      		{
			        rx_pntr = &rx_buffer[0];  // reset pointer 
			        msg_size = 0x00;  // reset message size
			        state = STATE_GET_SEQ_NUM;  // get sequence number next
	      		}
	      		else {
	      			msg_cs = 0x00;  // clear old checksum
#ifdef MONITOR	      		
	      			if ( rx_data == MONITOR_FLAG )  {
	      				monitor_cnt ++;
	      				if( monitor_cnt == 3 ) {
	      					monitorMain();	
	      				}
	      			}
	      			else {
	      				monitor_cnt = 0;	
	      			}
#endif	      			
	      		}
	        	break;		
	        	
	        // Get Sequence Number	
			case STATE_GET_SEQ_NUM :
				sequence_number = rx_data;  // store sequence number
				state = STATE_GET_MSG_SIZE1;  // get message size LSB next			
				break; 	 
				
			// Get Message Size 1	
			case STATE_GET_MSG_SIZE1:	
				msg_size = (((unsigned int)rx_data)<<8);  // store message size MSB
				state = STATE_GET_MSG_SIZE2;  // get message size LSB next			
				break;
			
			// Get Message Size 2	
			case STATE_GET_MSG_SIZE2:
				msg_size += (unsigned int) rx_data; // make message size from MSB and LSB
		                                            // +1 because we check if >0
				state = STATE_GET_TOKEN;  // get token next			
				break;
				
			// Get Token		
			case STATE_GET_TOKEN:
				if(rx_data == TOKEN)  // check if token is correct
					state = STATE_GET_DATA;  // get data next
				else
					state = STATE_READY; // wait for new message			
				break;  
				
			// Get Data	
			case STATE_GET_DATA:
				*rx_pntr++ = rx_data;
				--msg_size;
				
				if(msg_size == 0)
				{
					state = STATE_GET_CS;
				}			
				break;	
		
			// Get Checksum and handle message if correct
			case STATE_GET_CS:
				if( msg_cs == 0x00) { // check for valid checksum
					handleMessage();
				} 			
				state = STATE_READY;
				break; 					       		
		}
    
	}  // end for endless loop

	return 0; // main return value

} // end of main
 
/*----------------------------------------------------------------------------*/
/* Handle message                                                             */
/*----------------------------------------------------------------------------*/ 
void handleMessage(void) {
	 	
// new code begin  	
 		tx_pntr = &tx_buffer[0];
 		*(tx_pntr++) = MESSAGE_START ;
 		*(tx_pntr++) = sequence_number ; 
 		tx_pntr += 2;  // space reserved for message size
 		*(tx_pntr++) = TOKEN ;		
        rx_pntr = &rx_buffer[0];  // reset pointer
        
        switch( *rx_pntr ) {
        	case CMD_SIGN_ON:
				cmdSignOn();
        		break;	
        	case CMD_GET_PARAMETER:
        		cmdGetParameter();
        		break;
        	case CMD_SET_PARAMETER:
        		cmdSetParameter();
        		break;
        	case CMD_ENTER_PROGMODE_ISP:
        		cmdEnterProgmodeIsp();
        		break;
        	case CMD_LEAVE_PROGMODE_ISP:
        		cmdLeaveProgmodeIsp();
        		break;
        	case CMD_CHIP_ERASE_ISP:
        		cmdChipEraseIsp();
        		break;
        	case CMD_READ_SIGNATURE_ISP:
        		cmdReadSignatureIsp();
        		break;
        	case CMD_LOAD_ADDRESS:
        		cmdLoadAddress();
        		break;
        	case CMD_PROGRAM_FLASH_ISP:
        		cmdProgramFlashIsp();
        		break;
        	case CMD_READ_FLASH_ISP:
				cmdReadFlashIsp();        	
        		break;	
        	case CMD_PROGRAM_EEPROM_ISP:
        		cmdProgramEepromIsp();
        		break;
        	case CMD_READ_EEPROM_ISP:
        		cmdReadEepromIsp();
        		break;      
        	case CMD_READ_FUSE_ISP:
        	case CMD_READ_LOCK_ISP:        	
        		cmdReadFuseLockIsp();
        		break;         		        		  			
        			
        }
        
        sendResponse();
         
        // leave bootloader at programming end
/*
        if( *answer_id_pntr == CMD_LEAVE_PROGMODE_ISP)
        {
        	if(pgm_read_byte_near(0x0000) != 0xFF) {	
          		app_start();
        	}	
        }
*/        
       	
} // end handleMessage
 

/*----------------------------------------------------------------------------*/ 
/* send response message                                                      */
/*----------------------------------------------------------------------------*/
void sendResponse(void) {
	unsigned int msg_len, idx;

    size_pntr[0] = (unsigned char) (msg_size >> 8);
    size_pntr[1]=  (unsigned char) (msg_size & 0xFF);
		
	msg_len = tx_pntr - tx_buffer;
	msg_cs = 0;
	for( idx = 0; idx < msg_len; idx++ )  {
		putch( tx_buffer[idx] );
		msg_cs ^= tx_buffer[idx];		
	}	
	putch(msg_cs);	
	msg_cs = 0x00;  // reset checksum
}
 
/*----------------------------------------------------------------------------*/ 
/* execute command  CMD_SIGN_ON                                               */
/*----------------------------------------------------------------------------*/ 
 
void cmdSignOn(void)  {

	msg_size = 11;  		// set message length
	*(tx_pntr++) = CMD_SIGN_ON;
	*(tx_pntr++) = STATUS_CMD_OK;
	
	*(tx_pntr++) = 0x08;  	// send signature length
	*(tx_pntr++) = 'S';		// send identifier
	*(tx_pntr++) = 'T';
	*(tx_pntr++) = 'K';
	*(tx_pntr++) = '5';
	*(tx_pntr++) = '0';
	*(tx_pntr++) = '0';
	*(tx_pntr++) = '_';
	*(tx_pntr++) = '2';
	
} 
 
/*----------------------------------------------------------------------------*/ 
/* execute command  CMD_READ_SIGNATURE_ISP                                    */
/*----------------------------------------------------------------------------*/ 
 
void cmdReadSignatureIsp(void)  {

	msg_size = 4;  		// set message length
	*(tx_pntr++) = CMD_READ_SIGNATURE_ISP;
	*(tx_pntr++) = STATUS_CMD_OK;

	if( *(rx_pntr+4) == 0 )  {  // 1st sig byte
		*(tx_pntr++) = SIG1;	
	}    
	else if ( *(rx_pntr+4) == 1 ) { // 2nd sig byte
		*(tx_pntr++) = SIG2;								
	} 
	else if ( *(rx_pntr+4) == 2 ) { // 3rd sig byte
		*(tx_pntr++) = SIG3;								
	} 
	else {
		*(tx_pntr++) = 0x00;   // error 	
	}
    *(tx_pntr++) = STATUS_CMD_OK;	
	
}  
 
/*----------------------------------------------------------------------------*/ 
/* execute command  CMD_SET_PARAMETER                                         */
/*----------------------------------------------------------------------------*/ 
 
void cmdSetParameter(void)  {


	msg_size = 2;  			// set message length		
	*(tx_pntr++) = CMD_SET_PARAMETER;
	*(tx_pntr++) = STATUS_CMD_OK; 
} 

/*----------------------------------------------------------------------------*/ 
/* execute command  CMD_ENTER_PROGMODE_ISP                                    */
/*----------------------------------------------------------------------------*/ 
 
void cmdEnterProgmodeIsp(void)  {


	msg_size = 2;  			// set message length		
	*(tx_pntr++) = CMD_ENTER_PROGMODE_ISP;
	*(tx_pntr++) = STATUS_CMD_OK; 
} 

/*----------------------------------------------------------------------------*/ 
/* execute command  CMD_LEAVE_PROGMODE_ISP                                    */
/*----------------------------------------------------------------------------*/ 
 
void cmdLeaveProgmodeIsp(void)  {


	msg_size = 2;  			// set message length		
	*(tx_pntr++) = CMD_LEAVE_PROGMODE_ISP;
	*(tx_pntr++) = STATUS_CMD_OK; 
} 
 
/*----------------------------------------------------------------------------*/ 
/* execute command  CMD_CHIP_ERASE_ISP                                        */
/*----------------------------------------------------------------------------*/ 
 
void cmdChipEraseIsp(void)  {

	// clear only first page becuase of timeout in AvrStudio
	boot_page_erase((unsigned long)(0L));  	// clear 1st page
	while(boot_spm_busy());	        				
    boot_rww_enable();  			// enable Read-While-Write section
	msg_size = 2;  			// set message length		
	*(tx_pntr++) = CMD_CHIP_ERASE_ISP;
	*(tx_pntr++) = STATUS_CMD_OK; 
} 
 
/*----------------------------------------------------------------------------*/ 
/* execute command  CMD_LOAD_ADDRESS                                          */
/*----------------------------------------------------------------------------*/ 
 
void cmdLoadAddress(void)  {

    address_eeprom = ((*(rx_pntr+3)*256)+*(rx_pntr+4));
    address_flash  = ((*(rx_pntr+3)*256)+*(rx_pntr+4))*2;


	msg_size = 2;  			// set message length		
	*(tx_pntr++) = CMD_LOAD_ADDRESS;
	*(tx_pntr++) = STATUS_CMD_OK; 
}  
 
/*----------------------------------------------------------------------------*/ 
/* execute command  CMD_GET_PARAMETER                                         */
/*----------------------------------------------------------------------------*/ 
 
void cmdGetParameter(void)  {


	msg_size = 3;  			// set message length		
	*(tx_pntr++) = CMD_GET_PARAMETER;
	*(tx_pntr++) = STATUS_CMD_OK;

	switch( *(rx_pntr+1) )  {
		case PARAM_HW_VER: 
            *(tx_pntr++) = HARDWARE_VERSION;  // send hardware version          				
			break;
		case PARAM_SW_MAJOR: 
            *(tx_pntr++) = SOFTWARE_MAJOR; // send software major version         				
			break;        			
		case PARAM_SW_MINOR: 
            *(tx_pntr++) = SOFTWARE_MINOR;  // send software minor version          				
			break;			
		case PARAM_VTARGET: 
            *(tx_pntr++) = VTARGET; // target supply voltage         				
			break;        			
		case PARAM_VADJUST: 
            *(tx_pntr++) = VADJUST; // target VREF voltage          				
			break;  
		case PARAM_OSC_PSCALE: 
            *(tx_pntr++) = PSCALE_FSYS; // oscilator prescaler value         				
			break;
		case PARAM_OSC_CMATCH: 
            *(tx_pntr++) = CMATCH_DEF; // oscilator compare value         				
			break;			
		case PARAM_SCK_DURATION: 
            *(tx_pntr++) = SCK_DURATION_DEF; // oscilator compare value         				
        			break;        			       			        			        			
#if defined(__AVR_ATmega128__) || defined(__AVR_AT90CAN128__) //|| defined(__AVR_ATmega2560__)
		case PARAM_TOPCARD_DETECT: 
            *(tx_pntr++) =  STK501; // STK501 is expected          				
			break;		
#endif        			
		default: 	
            *(tx_pntr++) = 0x00; // send dummy value for not supported parameters   
        break;      			
	}			
} 

/*----------------------------------------------------------------------------*/ 
/* execute command  CMD_PROGRAM_EEPROM_ISP                                     */
/*----------------------------------------------------------------------------*/ 

void cmdProgramEepromIsp(void) {
	
	n_bytes = ((*(rx_pntr+1)*256)+*(rx_pntr+2));  	// number of databytes to flash
	rx_pntr += 10;  								// set pointer to flash data
	for( j = 0; j < n_bytes; j++ )  {
	    eeprom_wb(address_eeprom++,*(rx_pntr++));		
	}

	for(i = 0; i < MAX_BUF_SIZE; i++) { 
		rx_buffer[i] = 0xFF;  // clear data buffer
	}
		
	msg_size = 2;  			// set message length		
	*(tx_pntr++) = CMD_PROGRAM_EEPROM_ISP;
	*(tx_pntr++) = STATUS_CMD_OK; 	
	
} // end of programEepromIsp 
 
/*----------------------------------------------------------------------------*/ 
/* execute command  CMD_READ_EEPROM_ISP                                        */
/*----------------------------------------------------------------------------*/ 
 
void cmdReadEepromIsp(void) {

	*(tx_pntr++) = CMD_READ_EEPROM_ISP;
	*(tx_pntr++) = STATUS_CMD_OK;
	
	n_bytes=((*(rx_pntr+1)*256)+*(rx_pntr+2));  // number of databytes to read from flash 
	for(i=0;i < n_bytes; i++) { // fill data buffer with n_bytes
    	*(tx_pntr++) = eeprom_rb( address_eeprom++ );
	}
	msg_size = n_bytes + 3;  // set message length
	*(tx_pntr++) = STATUS_CMD_OK;	
	
}   // end of readEepromIsp 
/*----------------------------------------------------------------------------*/ 
/* set pin direction for bootloader pin and enable pullup                     */
/*----------------------------------------------------------------------------*/
void initPorts(void)  {

#if defined(__AVR_ATmega128__) || defined(__AVR_AT90CAN128__)
  	BL_DDR &= ~(1 << BL0);
  	BL_DDR &= ~(1 << BL1);
  	BL_PORT |= (1 << BL0);
  	BL_PORT |= (1 << BL1);
  	
#else
	BL_DDR &= ~(1 << BL);
	BL_PORT |= (1 << BL);
#endif

#ifdef MONITOR

#endif

} 
 
/*----------------------------------------------------------------------------*/ 
/* initialize UART(s) depending on CPU defined                                */
/*----------------------------------------------------------------------------*/ 
void initUart(void)  {

⌨️ 快捷键说明

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