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

📄 boot.c

📁 PIC24FJ32GA002单片机bootloader rs485通信移植
💻 C
📖 第 1 页 / 共 3 页
字号:
/********************************************************************
*
* PIC24F Serial Bootloader
*
*********************************************************************
* FileName:		boot.c
* Dependencies: memory.c, config.h, GenericTypeDefs.h 
* Processor:	PIC24F Family
* Compiler:		C30 v3.00 or later
* Company:		Microchip Technology, Inc.
*
* Software License Agreement:
*
* The software supplied herewith by Microchip Technology Incorporated
* (the 揅ompany? for its PICmicro?Microcontroller is intended and
* supplied to you, the Company抯 customer, for use solely and
* exclusively on Microchip PICmicro Microcontroller products. The
* software is owned by the Company and/or its supplier, and is
* protected under applicable copyright laws. All rights are reserved.
* Any use in violation of the foregoing restrictions may subject the
* user to criminal sanctions under applicable laws, as well as to
* civil liability for the breach of the terms and conditions of this
* license.
*
* THIS SOFTWARE IS PROVIDED IN AN 揂S IS?CONDITION. NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
* TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FrOR A
* PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
* IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
* 
* File Description:
*
* Bootloader for PIC24F devices compatable with AN851 communication protocol
* Based on PIC24F UART bootloader and PIC16/18 AN851 bootloader
*
*
* Change History:
*
* Author      	Revision #      Date        Comment
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Brant Ivey	1.00   			1-17-2008	Initial release of AN1157
* Brant Ivey    1.02            11-17-2008  Updated 'K' device support
*                                           Added extra configuration options
********************************************************************/

//Includes *******************************
#include "PIC24F Serial Bootloader\config.h"
//****************************************


//Globals ********************************
WORD responseBytes;		//number of bytes in command response
DWORD_VAL sourceAddr;	//general purpose address variable
DWORD_VAL userReset;	//user code reset vector
DWORD_VAL userTimeout; 	//bootloader entry timeout value
WORD userResetRead;		//bool - for relocating user reset vector

//Variables for storing runaway code protection keys
#ifdef USE_RUNAWAY_PROTECT
volatile WORD writeKey1 = 0xFFFF;
volatile WORD writeKey2 = 0x5555;
volatile WORD keyTest1 = 0x0000;
volatile WORD keyTest2 = 0xAAAA;
#endif

#define CLR_DT   PORTBbits.RB12=0
#define SET_DT   PORTBbits.RB12=1
//Transmit/Recieve Buffer
BYTE buffer[MAX_PACKET_SIZE+1];
//****************************************

//Configuration bits *********************
_CONFIG1( JTAGEN_OFF & GCP_OFF & GWRP_OFF & COE_OFF & FWDTEN_ON& ICS_PGx2);

_CONFIG2( FCKSM_CSDCMD & OSCIOFNC_ON & POSCMOD_HS & FNOSC_PRIPLL & I2C1SEL_PRI& IOL1WAY_OFF);


//****************************************


/********************************************************************
* Function: 	int main()
*
* Precondition: None.
*
* Input: 		None.
*
* Output:		None.
*
* Side Effects:	Enables 32-bit Timer2/3.  Enables UART.
*
* Overview: 	Initialization of program and main loop.
*			
* Note:		 	None.
********************************************************************/
unsigned  num,subnum; 
int main()
{
	DWORD_VAL delay;
	
	//Setup bootloader entry delay
	sourceAddr.Val = DELAY_TIME_ADDR;	//bootloader timer address
	delay.Val = ReadLatch(sourceAddr.word.HW, sourceAddr.word.LW); //read BL timeout
	
	//Setup user reset vector
	sourceAddr.Val = USER_PROG_RESET;
	userReset.Val = ReadLatch(sourceAddr.word.HW, sourceAddr.word.LW);

	//Prevent bootloader lockout - if no user reset vector, reset to BL start
	if(userReset.Val == 0xFFFFFF){
		userReset.Val = BOOT_ADDR_LOW;	
	}
	userResetRead = 0;


	//If timeout is zero, check reset state.
	if(delay.v[0] == 0){

		//If device is returning from reset, BL is disabled call user code
		//otherwise assume the BL was called from use code and enter BL
		if(RCON & 0xFED3){
			//If bootloader disabled, go to user code
			ResetDevice(userReset.Val); 
		}else{
			delay.Val = 0xFF;
		}
	}


	T2CONbits.TON = 0;
	T2CONbits.T32 = 1; // Setup Timer 2/3 as 32 bit timer incrementing every clock
	IFS0bits.T3IF = 0; // Clear the Timer3 Interrupt Flag 
	IEC0bits.T3IE = 0; // Disable Timer3 Interrupt Service Routine 

	//Enable timer if not in always-BL mode
	if((delay.Val & 0x000000FF) != 0xFF){
		//Convert seconds into timer count value 
		delay.Val = ((DWORD)(FCY)) * ((DWORD)(delay.v[0])); 

		PR3 = delay.word.HW; //setup timer timeout value
		PR2 = delay.word.LW;

		TMR2 = 0;
		TMR3 = 0;
		T2CONbits.TON=1;  //enable timer
	}


	TRISBbits.TRISB6=0;
	TRISBbits.TRISB7=1;
	TRISBbits.TRISB12=0;
//	asm volatile("MOV #OSCCON, w1 \n"
//				  "MOV #0x46, w2   \n"
//				  "MOV #0x57, w3   \n"
//				  "MOV.b w2, [w1]  \n"
//				  "MOV.b w3, [w1]  \n"
//				  "BCLR OSCCON, #6");

	RPINR18bits.U1RXR=7;
	RPOR3bits.RP6R=3;
	
//	asm volatile("MOV #OSCCON, w1 \n"
//				  "MOV #0x46, w2   \n"
//				  "MOV #0x57, w3   \n"
//				  "MOV.b w2, [w1]  \n"
//				  "MOV.b w3, [w1]  \n"
//				  "BSET OSCCON, #6");

	U1BRG = ((FCY/9600)/16)-1  ;      /*  BAUD Rate Setting of Uart1  */
	U1MODE = 0x8000; /* Reset UART to 8-n-1, alt pins, and enable */
	U1STA  = 0x0400; /* Reset status register and enable TX */
	

	//TRISAbits.TRISA4=0;	
	
	//PORTAbits.RA4=0;
		
	CLR_DT;

	while(1){

		#ifdef USE_RUNAWAY_PROTECT
			writeKey1 = 0xFFFF;	// Modify keys to ensure proper program flow
			writeKey2 = 0x5555;
		#endif

		GetCommand();		//Get full AN851 command from UART

		#ifdef USE_RUNAWAY_PROTECT
			writeKey1 += 10;	// Modify keys to ensure proper program flow
			writeKey2 += 42;
		#endif

		HandleCommand();	//Handle the command

		PutResponse(responseBytes);		//Respond to sent command

	}//end while(1)

}//end main(void)




/********************************************************************
* Function: 	void GetCommand()
*
* Precondition: UART Setup
*
* Input: 		None.
*
* Output:		None.
*
* Side Effects:	None.
*
* Overview: 	Polls the UART to recieve a complete AN851 command.
*			 	Fills buffer[1024] with recieved data.
*			
* Note:		 	None.
********************************************************************/
void GetCommand(){

	BYTE RXByte;
	BYTE checksum;
	WORD dataCount;

	while(1){

		#ifndef USE_AUTOBAUD
        GetChar(&RXByte);   //Get first STX
        if(RXByte == STX){ 
        #else
        AutoBaud();			//Get first STX and calculate baud rate
		RXByte = U1RXREG;	//Dummy read
        #endif

		T2CONbits.TON = 0;  //disable timer - data received

		GetChar(&RXByte);	//Read second byte
		if(RXByte == STX){	//2 STX, beginning of data
		
			checksum = 0;	//reset data and checksum
			dataCount = 0;

			while(dataCount <= MAX_PACKET_SIZE+1){	//maximum num bytes
				GetChar(&RXByte);		
				switch(RXByte){   
					case STX: 			//Start over if STX
						checksum = 0;
						dataCount = 0;
						break;

					case ETX:			//End of packet if ETX
						checksum = ~checksum +1; //test checksum
						Nop();
						if(checksum == 0) return;	//return if OK
						dataCount = 0xFFFF;	//otherwise restart
						break;

					case DLE:			//If DLE, treat next as data
						GetChar(&RXByte);
					default:			//get data, put in buffer
						checksum += RXByte;
						buffer[dataCount++] = RXByte;
						break;

				}//end switch(RXByte)
			}//end while(byteCount <= 1024)
		}//end if(RXByte == STX)

        #ifndef USE_AUTOBAUD
        }//end if(RXByte == STX)
        #endif
	}//end while(1)				
		
}//end GetCommand()




/********************************************************************
* Function: 	void HandleCommand()
*
* Precondition: data in buffer
*
* Input: 		None.
*
* Output:		None.
*
* Side Effects:	None.
*
* Overview: 	Handles commands received from host
*			
* Note:		 	None.
********************************************************************/
void HandleCommand()
{
	
	BYTE Command;
	BYTE length;

	//variables used in EE and CONFIG read/writes
	#if (defined(DEV_HAS_EEPROM) || defined(DEV_HAS_CONFIG_BITS))	
		WORD i=0;
		WORD_VAL temp;
		WORD bytesRead = 0;	
	#endif

	Command = buffer[0];	//get command from buffer
	length = buffer[1];		//get data length from buffer

	//RESET Command
	if(length == 0x00){
        UxMODEbits.UARTEN = 0;  //Disable UART
		ResetDevice(userReset.Val);
	}

	//get 24-bit address from buffer
	sourceAddr.v[0] = buffer[2];		
	sourceAddr.v[1] = buffer[3];
	sourceAddr.v[2] = buffer[4];
	sourceAddr.v[3] = 0;

	#ifdef USE_RUNAWAY_PROTECT
	writeKey1 |= (WORD)sourceAddr.Val;	// Modify keys to ensure proper program flow
	writeKey2 =  writeKey2 << 1;
	#endif

	//Handle Commands		
	switch(Command)
	{
		case RD_VER:						//Read version	
			buffer[2] = MINOR_VERSION;
			buffer[3] = MAJOR_VERSION;

			responseBytes = 4; //set length of reply
			break;
		
		case RD_FLASH:						//Read flash memory
			ReadPM(length, sourceAddr); 

				responseBytes = length*PM_INSTR_SIZE + 5; //set length of reply    									  
			break;
		
		case WT_FLASH:						//Write flash memory

			#ifdef USE_RUNAWAY_PROTECT
				writeKey1 -= length;	// Modify keys to ensure proper program flow
				writeKey2 += Command;		
			#endif

			WritePM(length, sourceAddr);	

			responseBytes = 1; //set length of reply
 			break;

		case ER_FLASH:						//Erase flash memory

			#ifdef USE_RUNAWAY_PROTECT
				writeKey1 += length;	// Modify keys to ensure proper program flow
				writeKey2 -= Command;
			#endif

			ErasePM(length, sourceAddr);	

			responseBytes = 1; //set length of reply
			break;
	
		#ifdef DEV_HAS_EEPROM
		case RD_EEDATA:						//Read EEPROM
			//if device has onboard EEPROM, allow EE reads

			//Read length words of EEPROM
			while(i < length*2){
				temp.Val = ReadLatch(sourceAddr.word.HW, 
									 sourceAddr.word.LW);
				buffer[5+i++] = temp.v[0];
				buffer[5+i++] = temp.v[1];
				sourceAddr.Val += 2;
			}

			responseBytes = length*2 + 5; //set length of reply
			break;
		
		case WT_EEDATA:						//Write EEPROM
        
			#ifdef USE_RUNAWAY_PROTECT
				writeKey1 -= length;	// Modify keys to ensure proper program flow
				writeKey2 += Command;		
			#endif
            
			//Write length words of EEPROM
			while(i < length*2){
				temp.byte.LB = buffer[5+i++];  //load data to write
				temp.byte.HB = buffer[5+i++];
	
				WriteLatch(sourceAddr.word.HW,sourceAddr.word.LW,
						   0, temp.Val);  //write data to latch

				#ifdef USE_RUNAWAY_PROTECT
					writeKey1++;
					writeKey2--;

					//setup program flow protection test keys
					keyTest1 =	(((0x0009 | (WORD)(sourceAddr.Val-i)) -
								length) + i/2) - 5;

⌨️ 快捷键说明

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