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

📄 flash_uploader_appl.c

📁 使用JTAG口对AT91R40008芯片进行FLASH编程的程序
💻 C
字号:
//*----------------------------------------------------------------------------
//*      ATMEL Microcontroller Software Support  -  ROUSSET  -
//*----------------------------------------------------------------------------
//* The software is delivered "AS IS" without warranty or condition of any
//* kind, either express, implied or statutory. This includes without
//* limitation any warranty or condition with respect to merchantability or
//* fitness for any particular purpose, or against the infringements of
//* intellectual property rights of others.
//*----------------------------------------------------------------------------
//* File Name           : Flash_uploader_appl.c
//* Object              : Flash uploader application
//*
//* 1.0 9/04/02 NL    : Creation
//*----------------------------------------------------------------------------

#ifdef SEMIHOSTING
#include <stdio.h>
#endif

#include    "parts/r40008/lib_r40008.h"
#include    "targets/eb40a/eb40a.h"
#include    "parts/r40008/reg_r40008.h"

#include 	"global.h"
#include	"lib_flash_at29.h"
#include	"lib_flash_at49.h"

#include 	"eb_desc.h"
#include	"jtag.h"
#include	"Flash_uploader.h"
#include	"Flash_uploader_appl.h"


//*----------------------------------------------------------------------------
//* Global variables
Target	*eval_board = NULL;

extern  u_int	Current_Scan_Chain;
extern  u_int	context[16];
extern	Target  Target_Table[];

//*----------------------------------------------------------------------------
//* Function Name       : Recognize_Target
//* Object              : Identify the target according to the ID
//* Input Parameters    : id
//* Output Parameters   : TRUE or FALSE
//*----------------------------------------------------------------------------
int Recognize_Target(u_int id){
	
	u_short target = 0;

	while ( ((id & SF_CIDR_MASK) != Target_Table[target].id_chip ) &&
			(target < NB_TARGET_SUPPORTED) ){
			
			target++;
	}
	
	if (target < NB_TARGET_SUPPORTED){
		eval_board = & Target_Table[target];	
		return (TRUE);
	}

	return (FALSE);
}

//*----------------------------------------------------------------------------
//* Function Name       : Initialize_Periph
//* Object              : Initialize target's EBI or PLL 
//* Input Parameters    : periph (EBI or PLL)
//* Output Parameters   : none
//*----------------------------------------------------------------------------
void Initialize_Periph(u_int periph){

	Instr		*ptr_instr = eval_board->ebi.instruction;
	u_short 	nb_instr = eval_board->ebi.nb_instr;
	u_short 	wait_state = NO_WAIT_STATE;
	u_int 		value, mask;
	
	if (periph){ //* periph == PLL
		wait_state = WAIT_STATE;
		ptr_instr = eval_board->pll.instruction;
		nb_instr = eval_board->pll.nb_instr;
	}
	
	while (nb_instr > 0){
			
			switch (ptr_instr->type_instr){
				
				case WRITE :
					JTAG_Write_Memory(ptr_instr->address,
									  ptr_instr->data,
									  WORD, wait_state);
					break;
					
				case POLL :
					
					mask = ptr_instr->data;
				
					JTAG_Read_Memory(ptr_instr->address, &value, WORD, wait_state);
				
					while ((value & mask) != mask){
						JTAG_Read_Memory(ptr_instr->address, &value, WORD, wait_state);
					}
					
					break;
	
				default : break;
			}
			
			ptr_instr++;
			nb_instr--;		
	}

}

//*----------------------------------------------------------------------------
//* Function Name       : Pause
//* Object              : Wait 20 ms
//* Input Parameters    : none
//* Output Parameters   : none
//*----------------------------------------------------------------------------
void Pause(){
	
	int count;
	
    for (count=0; count < WAIT; count++)
    {
        /* Do nothing - just wait */
    }

}

//*----------------------------------------------------------------------------
//* Function Name       : Identify_Flash_LV
//* Object              : Identify the LV Flash
//* Input Parameters    : none
//* Output Parameters   : flash device_code 
//*----------------------------------------------------------------------------
u_int Identify_Flash(u_int *code){

	u_int	i;
	u_int   manuf_code;
	u_int	base_addr = FLASH_BASE_ADDR;

	//* Load the program to identify the flash
	Load_Program( (u_int *)&(eval_board->flash_ident) );

	//* Set a context
	for (i=0; i<15; i++){
		context[i] = 0;
	}

	//* Launch the program
	JTAG_Go(START_PRG);
	
	//* Send the flash base_addr
	if (Com_Channel_Write_Data(base_addr) != TRUE){
		return 	FALSE;
	}
	
	//* Read Manufacturer and device code from the device
	if (Com_Channel_Read_Data(&manuf_code) != TRUE){
		return FALSE;
	}
	manuf_code &= FLASH_CODE_MASK;
	
	if (Com_Channel_Read_Data(code) != TRUE){
		return FALSE;
	}
	*code &= FLASH_CODE_MASK;

    /* Check the Manufacturer - Fail if not known */
    if (manuf_code != ATMEL_MANUFACTURED) {
        at91_print(&COM0,"Flash not recognized!!!\n\r");
        return FALSE;
    } else {
    	at91_print(&COM0,"Flash recognized\n\r");
    }
	
	return TRUE;
}

//*----------------------------------------------------------------------------
//* Function Name       : Load_Flash_Program
//* Object              : Load the flash program in the target
//* Input Parameters    : none
//* Output Parameters   : none
//*----------------------------------------------------------------------------
void Load_Program(u_int *program){
	
	Program	 *prog = (Program *)program;
	u_int i, mask = 0;
	u_int size, load_addr, *prg;
	
	Current_Scan_Chain = -1;
	size = prog->size;
	load_addr = prog->load_addr;
	prg = prog->prg;
	
	//* Set the mask for the Store_Multiple function
	for (i=NB_REG; i>0; i--){
		mask |= (1<<(NB_REG-i));
	}
	
	while (size>((NB_REG-1)*SIZE_DATA)){
	
		//* Copy the program
		JTAG_Load_Multiple(NB_REG, prg);	
		JTAG_Store_Multiple(load_addr, mask);

		JTAG_Read_Register(R0, NULL); //* Avoid scratch of next reading	
	
		prg += NB_REG;
		load_addr += (NB_REG*SIZE_DATA);
		size -= NB_REG*SIZE_DATA;
	}
	
	//* Copy the end of the program
	if (size > 0){
		
		mask = 0;
		
		//* Set the mask
		for (i=(size>>2); i>0; i--){
			mask |= (1<<((size>>2)-i));
		}
	
		//* Copy the program
		JTAG_Load_Multiple((size>>2), prg);
		JTAG_Store_Multiple(load_addr, mask);
		
		JTAG_Read_Register(R0, NULL); //* Avoid scratch of next reading	
	}
	
	return;
}

//*----------------------------------------------------------------------------
//* Function Name       : Flash_LV_Send_Data
//* Object              : Send Data for Flash LV
//* Input Parameters    : addr, *data, size in bytes
//* Output Parameters   : none
//*----------------------------------------------------------------------------
u_int Flash_LV_Send_Data(u_int *program, u_short erase){

	Program	*prog = (Program *)program;
	u_int  	i, size, load_addr, *prg;
	u_int  	end = 0;
	u_int 	value;

	size = prog->size;
	load_addr = prog->load_addr;
	prg = prog->prg;	

	while (size > SIZE_256_BYTES){
		
		if (Com_Channel_Write_Data(load_addr) != TRUE){
			return FALSE;
		}
		
		i=0;
			
		//* Store 64 32 bits words from the Comm Channel to a buffer 
		while (i < PACKET_SIZE){
		
			if (erase){
			
				if (Com_Channel_Write_Data(ERASE_DATA) != TRUE){
					return FALSE;
				}
		
			} else {
		
				if (Com_Channel_Write_Data( *(prg++) ) != TRUE){
					return FALSE;
				}
			}
		
			i++;
		}

		if (Com_Channel_Write_Data(end) != TRUE){
			return FALSE;
		}

		load_addr += SIZE_256_BYTES;
		size -= SIZE_256_BYTES;
	}
	
	//* Flag for the last packet to send
	end = 1;
	
	if (size > 0){
	
		if (Com_Channel_Write_Data(load_addr) != TRUE){
			return FALSE;
		}
		
		i=0;
			
		//* Store 64 32 bits words from the Comm Channel to a buffer 
		while (i < PACKET_SIZE){
		
			if (size > 0){
				
				if (erase){
					if (Com_Channel_Write_Data(ERASE_DATA) != TRUE){
						return FALSE;
					}
				} else {
					if (Com_Channel_Write_Data( *(prg++) ) != TRUE){
						return FALSE;
					}
				}
				size -= SIZE_DATA;
			
			} else {
				//* 128 bytes MUST be sent
				if (Com_Channel_Write_Data(ERASE_DATA) != TRUE){
					return FALSE;
				} 
			}
			
			i++;
		}

		if (Com_Channel_Write_Data(end) != TRUE){
			return FALSE;
		}

		//* Wait target has finished
		if (Com_Channel_Read_Data(&value) != TRUE){
			return FALSE;
		}
	
		if (value != 0xCAFECAFE){
			return FALSE;
		}

	}
	
	return TRUE;
}


//*----------------------------------------------------------------------------
//* Function Name       : Flash_BV_Send_Data
//* Object              : Send Data for Flash BV
//* Input Parameters    : ptr towards data, flash device_code
//* Output Parameters   : none
//*----------------------------------------------------------------------------
u_int Flash_BV_Send_Data(u_int *program, u_int code, u_short erase){
	
	Program	*prog = (Program *)program;
	u_int  size, load_addr, *prg;
	u_int  count, value;

	//* Init local variables
	size = prog->size;
	load_addr = prog->load_addr;
	prg = prog->prg;	
	
	Current_Scan_Chain = -1;
	
	//* Send the load address on the target
	if (Com_Channel_Write_Data(load_addr) != TRUE){
		return FALSE;
	}
	
	//* Send the flash device code 
	if (Com_Channel_Write_Data(code) != TRUE){
		return FALSE;
	}
	
	//* Send program size in bytes
	if (Com_Channel_Write_Data(size) != TRUE){
		return FALSE;
	}
	
	//* Send data
	for (count = 0; count<size; count += SIZE_DATA){
		
		if (erase){
			
			if (Com_Channel_Write_Data(ERASE_DATA) != TRUE){
				return FALSE;
			}
		
		} else {
		
			if (Com_Channel_Write_Data( *(prg++) ) != TRUE){
				return FALSE;
			}
		}
	
	}
	
	//* Wait target has finished
	if (Com_Channel_Read_Data(&value) != TRUE){
		return FALSE;
	}
	
	if (value != 0xCAFECAFE){
		return FALSE;
	}
	
	return TRUE;
}


//*----------------------------------------------------------------------------
//* Function Name       : JTAG_Flash_uploader
//* Object              : Flash uploader application
//* Input Parameters    : none
//* Output Parameters   : none
//*----------------------------------------------------------------------------
void JTAG_Flash_uploader(u_short erase, u_short mirror){

	u_int	value, i, nb_prg = 0;
	u_int 	*ptr_prg;
	u_int 	device_code;
	u_int 	watchdog = 0;
	u_int 	flash_recognized = FALSE;
	
	//* The JTAG must be resetted and the core must be stopped !!!

	//* Read ID of the target and identify 
	//* Be careful, the target may be clocked at 32 kHz so wait_states added to prevent bug
	JTAG_Read_Memory(SF_CHIP_ID, &value, WORD, WAIT_STATE);
	
	if ( Recognize_Target(value) != TRUE ){
		at91_print(&COM0,"Target not recognized!!!\n\r");
		return;
	} else {
		sprintf(message,"The target ID chip is : 0x%08X\n\r", eval_board->id_chip);
   		at91_print(&COM0,message);
   		
   		if ((mirror) && (eval_board->id_chip != EB40A)){
   			at91_print(&COM0,"Mode Mirror is not possible with this target!!!\n\r");
   			return;
   		}
   		
	}

	//* Initialize PLL if necessary
	Initialize_Periph(PLL);	
	
	//* Initialize EBI
	Initialize_Periph(EBI);
	
	while ((flash_recognized != TRUE) && (watchdog++ < NB_TRY)){ //* Get the index in the flash table
	
		//* Verify that you are still in Supervisor Mode before launching the program
		JTAG_Read_CPSR(&value);
		
		if ( (value & 0x1F) != SUPERVISOR_MODE){	
			//* Pass in supervisor mode
			//* IRQ and FIQ disabled, ARM mode
			JTAG_Write_CPSR(SUPERVISOR_MODE, (IRQ_BIT)0x1, (FIQ_BIT)0x1, (THUMB_BIT)0x0);
		}
	
		//* Set supervisor mode 
		//* IRQ and FIQ disabled, ARM mode
		//* JTAG_Write_CPSR(SUPERVISOR_MODE, (IRQ_BIT)0x1, (FIQ_BIT)0x1, (THUMB_BIT)0x0);	
		
		//* Flash Identify
		if (Identify_Flash(&device_code) == TRUE){
			flash_recognized = TRUE;
		} else {
			JTAG_Stop();
		}
	
	}
	 
	if (flash_recognized == TRUE){
		watchdog = 0;
	}

	while ( (nb_prg < NB_PRG) && (watchdog < NB_TRY) ){
	
		sprintf(message,"LOOP : %d\n\r", nb_prg);
   		at91_print(&COM0,message);
	
		//* STOP the target
		JTAG_Stop();
		
		//* Verify that you are still in Supervisor Mode before launching the program
		JTAG_Read_CPSR(&value);
		
		JTAG_Analyse_CPSR(value);	//* Debug
		
		if ( (value & 0x1F) != SUPERVISOR_MODE){
		
			//* Pass in supervisor mode
			//* IRQ and FIQ disabled, ARM mode
			JTAG_Write_CPSR(SUPERVISOR_MODE, (IRQ_BIT)0x1, (FIQ_BIT)0x1, (THUMB_BIT)0x0);
		}
	
		//* Load Flash program in the target
		Load_Program( (u_int *)&(eval_board->flash_prg) );
		
		//* Set the following context in supervisor mode
		for (i=0; i<15; i++){
			context[i] = 0;
		}
		
		//* Launch the program
		JTAG_Go(START_PRG);

		if (mirror) {
			ptr_prg = (u_int *)&(eval_board->mirror);
		} else {
			//* Select data to load
			switch (nb_prg){
		
				case 0 : //* boot
					ptr_prg = (u_int *)&(eval_board->boot);
					break;
				case 1 : //* angel
					ptr_prg = (u_int *)&(eval_board->angel);
					break;
				case 2 : //* appli
					ptr_prg = (u_int *)&(eval_board->appli);
					break;
				default : break;
			}
		} //* End if mirror
	
		//* Send data according to the flash type
		if (eval_board->flash){
			//* Flash BV
			if (Flash_BV_Send_Data(ptr_prg, device_code, erase) == TRUE){
				if (mirror){
					nb_prg = NB_PRG;
				} else {
					nb_prg++;
				}
				
				sprintf(message,"watchdog : %d\n\r", watchdog);
   				at91_print(&COM0,message);
   				
				watchdog = 0;
			
			} else {
				watchdog++;
			}
			
		} else {
			//* Flash LV
			if (Flash_LV_Send_Data(ptr_prg, erase) == TRUE){
				if (mirror){
					nb_prg = NB_PRG;
				} else {
					nb_prg++;
				}
				
				sprintf(message,"watchdog : %d\n\r", watchdog);
   				at91_print(&COM0,message);
   				
				watchdog = 0;
			
			} else {
				watchdog++;
			}	
		} //* End if Flash Type
	
	} //* End while

	if (watchdog > NB_TRY){
		at91_print(&COM0,"\n\rPROBLEM!!!\n\r");
		return;
	}
		
	if (erase){
		at91_print(&COM0,"\n\rThe target is erased!!!\n\r");	
	} else {
		at91_print(&COM0,"\n\rThe target is ready!!!\n\r");	
	}
	
}

⌨️ 快捷键说明

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