?? flash_uploader_appl.c
字號(hào):
//*----------------------------------------------------------------------------
//* 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");
}
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -