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

📄 stk500boot.c

📁 与stk相关的avr bootloader程序,采用avr-gcc编写.
💻 C
📖 第 1 页 / 共 2 页
字号:
				    checksum ^= c;
				    if ( i == msgLength )
				    {
					    msgParseState = ST_GET_CHECK;
				    }
				    break;
						
			    case ST_GET_CHECK:
				    if( c == checksum )
				    {
					    msgParseState = ST_PROCESS;					    
				    }
				    else
				    {
				        msgParseState = ST_START;
				    }
				    break;
				}//switch
			}//while(msgParseState)
			
			/*
			 * Now process the STK500 commands, see Atmel Appnote AVR068
			 */
			
	        switch (msgBuffer[0])
	        {
#ifndef REMOVE_CMD_SPI_MULTI
			case CMD_SPI_MULTI:
				{
	                unsigned char answerByte;
					unsigned char flag=0;

					if ( msgBuffer[4]== 0x30 )
					{						
						unsigned char signatureIndex = msgBuffer[6];						

						if ( signatureIndex == 0 )
							answerByte = (SIGNATURE_BYTES >>16) & 0x000000FF;
						else if ( signatureIndex == 1 )
							answerByte = (SIGNATURE_BYTES >> 8) & 0x000000FF;
						else
							answerByte = SIGNATURE_BYTES & 0x000000FF;
					}
					else if ( msgBuffer[4] & 0x50 ) 
					{
						answerByte = 0; //read fuse/lock bits not implemented, return dummy value
					}
					else
					{
						flag = 1;
					}
					if ( !flag ) 
					{
						msgLength = 7;
						msgBuffer[1] = STATUS_CMD_OK;
						msgBuffer[2] = 0;					
						msgBuffer[3] = msgBuffer[4];
						msgBuffer[4] = 0;
						msgBuffer[5] = answerByte;	                
						msgBuffer[6] = STATUS_CMD_OK;
					}
				}
				break;
#endif
            case CMD_SIGN_ON:
		        msgLength = 11;		        
		        msgBuffer[1]  = STATUS_CMD_OK;
		        msgBuffer[2]  = 8;
		        msgBuffer[3]  = 'A';
		        msgBuffer[4]  = 'V';
		        msgBuffer[5]  = 'R';
		        msgBuffer[6]  = 'I';
		        msgBuffer[7]  = 'S';
		        msgBuffer[8]  = 'P';
		        msgBuffer[9]  = '_';
		        msgBuffer[10] = '2';
		        break;
	        
	        case CMD_GET_PARAMETER:
	            {
	                unsigned char value;
	                
    		        switch(msgBuffer[1])
    		        {
    			    case PARAM_BUILD_NUMBER_LOW:
    				    value = CONFIG_PARAM_BUILD_NUMBER_LOW;
    				    break;				    
    			    case PARAM_BUILD_NUMBER_HIGH:
    				    value = CONFIG_PARAM_BUILD_NUMBER_HIGH;
    				    break;				    
    			    case PARAM_HW_VER:
    				    value = CONFIG_PARAM_HW_VER;
    				    break;				    
    			    case PARAM_SW_MAJOR:
    				    value = CONFIG_PARAM_SW_MAJOR;
    				    break;
    			    case PARAM_SW_MINOR:
    				    value = CONFIG_PARAM_SW_MINOR;
    				    break;				
    				default:
    				    value = 0;
    				    break;
    		        }
		            msgLength = 3;		        
		            msgBuffer[1] = STATUS_CMD_OK;
		            msgBuffer[2] = value;
		        }
	            break;
	            
	        case CMD_SET_PARAMETER:
	        case CMD_ENTER_PROGMODE_ISP:
            case CMD_LEAVE_PROGMODE_ISP:                    
		        msgLength = 2;		        
		        msgBuffer[1] = STATUS_CMD_OK;
                break;

            case CMD_READ_SIGNATURE_ISP:
                {
                    unsigned char signatureIndex = msgBuffer[4];
                    unsigned char signature;

                    if ( signatureIndex == 0 )
                        signature = (SIGNATURE_BYTES >>16) & 0x000000FF;
                    else if ( signatureIndex == 1 )
                        signature = (SIGNATURE_BYTES >> 8) & 0x000000FF;
                    else
                        signature = SIGNATURE_BYTES & 0x000000FF;

	                msgLength = 4;
	                msgBuffer[1] = STATUS_CMD_OK;
	                msgBuffer[2] = signature;
	                msgBuffer[3] = STATUS_CMD_OK;	                
	            }
                break;

            case CMD_READ_LOCK_ISP:            
                msgLength = 4;
	            msgBuffer[1] = STATUS_CMD_OK;
	            msgBuffer[2] = boot_lock_fuse_bits_get( GET_LOCK_BITS );
	            msgBuffer[3] = STATUS_CMD_OK;	                                                
                break;
            
            case CMD_READ_FUSE_ISP:
                {                    
                    unsigned char fuseBits;                    
                    
                    if ( msgBuffer[2] == 0x50 )
                    {
                        if ( msgBuffer[3] == 0x08 )
                            fuseBits = boot_lock_fuse_bits_get( GET_EXTENDED_FUSE_BITS );                            
                        else
                            fuseBits = boot_lock_fuse_bits_get( GET_LOW_FUSE_BITS );                            
                    }
                    else 
                    {
                        fuseBits = boot_lock_fuse_bits_get( GET_HIGH_FUSE_BITS );
                    }                    
                    msgLength = 4;    
	                msgBuffer[1] = STATUS_CMD_OK;
	                msgBuffer[2] = fuseBits;	                
	                msgBuffer[3] = STATUS_CMD_OK;	                                    
                }
                break;
                
#ifndef REMOVE_PROGRAM_LOCK_BIT_SUPPORT
            case CMD_PROGRAM_LOCK_ISP:
                {
                    unsigned char lockBits = msgBuffer[4];
                    
                    lockBits = (~lockBits) & 0x3C;  // mask BLBxx bits
				    boot_lock_bits_set(lockBits);	// and program it
				    boot_spm_busy_wait();
                    
                    msgLength = 3;
	                msgBuffer[1] = STATUS_CMD_OK;	                
	                msgBuffer[2] = STATUS_CMD_OK;	                                                        
                }
                break;
#endif
            case CMD_CHIP_ERASE_ISP:
                eraseAddress = 0;
	            msgLength = 2;
	            msgBuffer[1] = STATUS_CMD_OK;
                break;

            case CMD_LOAD_ADDRESS:
#if defined(RAMPZ)
                address = ( ((address_t)(msgBuffer[1])<<24)|((address_t)(msgBuffer[2])<<16)|((address_t)(msgBuffer[3])<<8)|(msgBuffer[4]) )<<1;
#else
		        address = ( ((msgBuffer[3])<<8)|(msgBuffer[4]) )<<1;  //convert word to byte address
#endif
		        msgLength = 2;
		        msgBuffer[1] = STATUS_CMD_OK;
                break;
                
            case CMD_PROGRAM_FLASH_ISP:
            case CMD_PROGRAM_EEPROM_ISP:                
                {
                    unsigned int  size = ((msgBuffer[1])<<8) | msgBuffer[2];
                    unsigned char *p = msgBuffer+10;
                    unsigned int  data;
                    unsigned char highByte, lowByte;                    
                    address_t     tempaddress = address;

                   
                    if ( msgBuffer[0] == CMD_PROGRAM_FLASH_ISP )
                    {
                		// erase only main section (bootloader protection)
                		if  (  eraseAddress < APP_END )
                		{
                			boot_page_erase(eraseAddress);	// Perform page erase
                			boot_spm_busy_wait();		// Wait until the memory is erased.
                			eraseAddress += SPM_PAGESIZE;    // point to next page to be erase
                		}
                        
    		            /* Write FLASH */
        		        do {
        		            lowByte   = *p++;
        		            highByte  = *p++;
        				    
        				    data =  (highByte << 8) | lowByte;
        				    boot_page_fill(address,data);
        											
        				    address = address + 2;  	// Select next word in memory
        				    size -= 2;			// Reduce number of bytes to write by two    
        			    } while(size);			// Loop until all bytes written
        			    
            			boot_page_write(tempaddress);
        	    		boot_spm_busy_wait();	
        		    	boot_rww_enable();				// Re-enable the RWW section                    
    		        }
    		        else
    		        {
    		            /* write EEPROM */
        			    do {
        	 	            EEARL = address;			// Setup EEPROM address
        	                EEARH = (address >> 8);
        				    address++;					// Select next EEPROM byte
        
        				    EEDR= *p++;				    // get byte from buffer
        	                EECR |= (1<<EEMWE);			// Write data into EEPROM
        	                EECR |= (1<<EEWE);
        	            
        				    while (EECR & (1<<EEWE));	// Wait for write operation to finish
        				    size--;						// Decrease number of bytes to write
        			    } while(size);					// Loop until all bytes written    		            
    		        }
           		    msgLength = 2;
		            msgBuffer[1] = STATUS_CMD_OK;    		        
                }
                break;
                
            case CMD_READ_FLASH_ISP:
            case CMD_READ_EEPROM_ISP:                                                
                {
                    unsigned int  size = ((msgBuffer[1])<<8) | msgBuffer[2];                    
                    unsigned char *p = msgBuffer+1;
                    msgLength = size+3;
                    
                    *p++ = STATUS_CMD_OK;                    
                    if (msgBuffer[0] == CMD_READ_FLASH_ISP )
                    {
                        unsigned int data;
                        
                        // Read FLASH
                        do {                            
#if defined(RAMPZ)
                			data = pgm_read_word_far(address);
#else
        		        	data = pgm_read_word_near(address);
#endif
        			        *p++ = (unsigned char)data;         //LSB
        			        *p++ = (unsigned char)(data >> 8);	//MSB  
        			        address    += 2;  	 // Select next word in memory
        			        size -= 2;
                        }while (size);
                    }
                    else
                    {
          			    /* Read EEPROM */
        			    do {
        			        EEARL = address;			// Setup EEPROM address
        			        EEARH = ((address >> 8));
        			        address++;					// Select next EEPROM byte
        			        EECR |= (1<<EERE);			// Read EEPROM
        			        *p++ = EEDR;				// Send EEPROM data
        			        size--;    			        
        		        }while(size);
                    }
                    *p++ = STATUS_CMD_OK;
                }
                break;

	        default:
	            msgLength = 2;   
	            msgBuffer[1] = STATUS_CMD_FAILED;
	            break;
	        }

            /*
             * Now send answer message back
             */
	        sendchar(MESSAGE_START);     
	        checksum = MESSAGE_START^0;
	        
	        sendchar(seqNum);
	        checksum ^= seqNum;
	        
	        c = ((msgLength>>8)&0xFF);
	        sendchar(c);
	        checksum ^= c;
	        
	        c = msgLength&0x00FF;
	        sendchar(c);
	        checksum ^= c;
	        
	        sendchar(TOKEN);
	        checksum ^= TOKEN;

            p = msgBuffer;
            while ( msgLength )
            {                
               c = *p++;
               sendchar(c);
               checksum ^=c;
               msgLength--;               
            }                   
	        sendchar(checksum);	        
	        seqNum++;

	    }//for

#ifndef REMOVE_BOOTLOADER_LED
        PROGLED_DDR  &= ~(1<<PROGLED_PIN);   // set to default     
#endif
    }
    
	/*
	 * Now leave bootloader
	 */
#ifndef REMOVE_PROG_PIN_PULLUP	
	PROG_PORT &= ~(1<<PROG_PIN);    // set to default
#endif	
	boot_rww_enable();              // enable application section
	
    asm volatile ( "push r1" "\n\t"  // Jump to Reset vector in Application Section
                   "push r1" "\n\t" 
                   "ret"     "\n\t" 
                   ::); 

     /*
     * Never return to stop GCC to generate exit return code
     * Actually we will never reach this point, but the compiler doesn't 
     * understand this
     */
    for(;;);
}

⌨️ 快捷键说明

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