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

📄 flash_drv_renesas.c

📁 MTK手机平台下载工具FLASHTOOL驱动源码
💻 C
字号:
/*******************************************************************************
*  Copyright Statement:
*  --------------------
*  This software is protected by Copyright and the information contained
*  herein is confidential. The software may not be copied and the information
*  contained herein may not be used or disclosed except with the written
*  permission of MediaTek Inc. (C) 2004
*
*******************************************************************************/

/*******************************************************************************
 *
 * Filename:
 * ---------
 *	  flash_drv_RENESAS.c
 *
 * Project:
 * --------
 *    FlashTool Download Agent 
 *
 * Description:
 * ------------
 *    This Module defines the RENESAS flash driver. 
 *
 * Author:
 * -------
 *	  Amos Hsu
 *
 *==============================================================================
 * 				HISTORY
 * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!! 
 *------------------------------------------------------------------------------
 * $Revision:   1.4  $ 
 * $Modtime:   Jun 15 2005 12:07:56  $
 * $Log:   //mtkvs01/vmdata/flash_tool/archives/DA/SRC/flash_drv_RENESAS.c-arc  $
 * 
 *    Rev 1.4   Jun 15 2005 12:23:06   mtk00539
 *  1. [DA][New] Support new flash devices TV0057A002AABD and TV0057A002AABD.
 *  2. [DA][New] Support RENESAS flash with F-WP#(LOW).
 * Resolution for 118: [BROM_DLL v2.4.1013][New] Support RENESAS flash with F-WP#(LOW).
 * 
 *    Rev 1.3   Nov 30 2004 17:20:04   mtk00539
 * [FIX BUG] DON'T use fixed 128 WORDs Page-Program method. 
 * Because when length_in_word is less than 128, Page-Program will fail! 
 * Therefore, we have to use another program method.  
 * First, load variant length data to Page-Buffer, then flush Page-Buffer to flash.                                         
 * Resolution for 99: [BROM_DLL v2.4.1008][New] Support INTEL family flash Buffered-Program method.
 * 
 *    Rev 1.2   Nov 22 2004 12:25:36   mtk00539
 *  1. [DA][BUG FIX] Add data verification in status polling during erase or program operation.
 *  2. [DA][BUG FIX] Fix two dies flash detection fail in INTEL_CheckDevID(). 
 *  3. [DA][Change Behavior] When RX_BUFFER_FULL occurs, flush data queued in UART ring buffer til data is less than 512KB.
 *  4. [DA][New] Support Buffered-Program method for INTEL family flashes.
 *  5. [DA][New] Support new flashes [SHARP]LRS1828C and [RENESAS]M6MGB64BM34CDG.
 * Resolution for 99: [BROM_DLL v2.4.1008][New] Support INTEL family flash Buffered-Program method.
 * 
 *    Rev 1.1   Oct 29 2004 11:46:46   mtk00539
 *  1. [DA][BUG FIX] Read CFI boot sector flag to determine AM49DL3208GT and S71PL032J, since both flashes have the same id, but different layout.
 *  2. [DA][BUG FIX] Fix INTEL and RENESAS status checking flow.
 *  3. [DA][Enhance] Dump more logs in TEST_ExtSRAM().
 *  4. [DA][New] Support new flashes
 * 				[SAMSUNG] K5J6316CTM
 * 				[TOSHIBA] TH50VPF5682CDSB
 * 				[TOSHIBA] TH50VPF5683CDSB
 * 				[ISSI] IS75V16F128GS32
 * 				[RENESAS] M6MGT64BM34CDG
 * 				[ST] M30L0T7000T0, M36L0T7050T0
 * 				[ST] M30L0T7000B0, M36L0T7050B0
 * 				[SHARP] LRS1862
 * 				[SHARP] LRS1806A
 * 				[AMD] AM49DL3208GT
 * 				[SPANSION] S29PL032J, S71PL032J
 * Resolution for 92: [BROM_DLL v2.4.1006][BUG FIX] Fix AM49DL3208GT & S71PL032J download fail problem and some enhancement.
 * 
 *    Rev 1.0   Aug 03 2004 10:39:54   mtk00539
 * Initial revision.
 * 
 *------------------------------------------------------------------------------
 * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!! 
 *==============================================================================
 *******************************************************************************/
#include "flash_drv_RENESAS.h"

//------------------------------------------------------------------------------
// Callback Function Set                                                        
//------------------------------------------------------------------------------
const NOR_CMD_Callback_S	RENESAS_CMD_CB_WORD_PGM = {
	INTEL_CheckDevID,
	DUMMY_CheckDevIdle,
	RENESAS_Erase_Block_CMD,
	RENESAS_CheckDone,
	DUMMY_Program_PreProcess,
	DUMMY_Program_PostProcess,
	DUMMY_Program_Enter,
	DUMMY_Program_Exit,
	RENESAS_Word_Program,
	RENESAS_CheckDone,
	NULL,
	NULL
};

const NOR_CMD_Callback_S	RENESAS_CMD_CB_128WORD_PAGE_PGM = {
	INTEL_CheckDevID,
	DUMMY_CheckDevIdle,
	RENESAS_Erase_Block_CMD,
	RENESAS_CheckDone,
	RENESAS_PreProcess_128WORD_BUFPGM,
	DUMMY_Program_PostProcess,
	DUMMY_Program_Enter,
	DUMMY_Program_Exit,
	RENESAS_Word_Program,
	RENESAS_CheckDone,
	RENESAS_FixedPage_Program,
	RENESAS_CheckDone
};

//------------------------------------------------------------------------------
// Memory Sector Layout Set                                                     
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// Check Device ID Callback Function                                            
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// Check If Device Is Idle Callback Function                                    
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// Erase Related Callback Function                                              
//------------------------------------------------------------------------------
void RENESAS_Erase_Block_CMD(const uint32 blockaddr)
{
	volatile uint16 *ba = (volatile uint16 *)blockaddr;
	
	// clear status register first 
	ba[0x0] = INTEL_CMD_CLR_SR;

	// sw lock release preprocess 
	RENESAS_SoftwareLockRelease_Preprocess(blockaddr);

	// no need to unlock, just erase 
	ba[0x0] = INTEL_CMD_ERASE_STEP1;
	ba[0x0] = INTEL_CMD_ERASE_STEP2;
}

STATUS_E RENESAS_CheckDone(const uint32 blockaddr)
{
	volatile uint16 *ba = (volatile uint16 *)blockaddr;
	volatile uint16 sr;

	// read SR 
	ba[0x0] = INTEL_CMD_READ_SR;
	sr = *ba;

	if( !(sr&RENESAS_SR7_DWS_BIT) ) {
		return S_IN_PROGRESS;
	}
	else if( (sr&RENESAS_SR4_PS_BIT) && (sr&RENESAS_SR5_ES_BIT) ) {
		return S_CMD_ERR;
	}
	else if(sr&RENESAS_SR5_ES_BIT) {
		return S_ERASE_FAILED;
	}
	else if(sr&RENESAS_SR4_PS_BIT) {
		return S_PGM_FAILED;
	}
	else if(sr&RENESAS_SR3_BSAE_BIT) {
		return S_BLOCK_UNSTABLE;
	}

	// rest to read mode 
	ba[0x0] = INTEL_CMD_READ_ARRAY;
	return S_DONE;
}

//------------------------------------------------------------------------------
// Program Related Callback Function                                            
//------------------------------------------------------------------------------
void RENESAS_PreProcess_128WORD_BUFPGM(const uint16 dev) {
	// set max buffered program size 
	g_FLASH_MAX_BUFPGM_SIZE_IN_BYTE = 256; // 128 WORDs 
}

void RENESAS_Word_Program(const uint32 blockaddr, const uint32 prog_addr, const uint16 data)
{
	volatile uint16 *pa = (volatile uint16 *)prog_addr;
	
	// clear status register first 
	*pa = INTEL_CMD_CLR_SR;

	// sw lock release preprocess 
	RENESAS_SoftwareLockRelease_Preprocess(blockaddr);

	// word program 
	*pa = INTEL_CMD_WORD_PGM;
	*pa = data;
}

void RENESAS_FixedPage_Program(const uint32 blockaddr, const uint32 prog_addr, const uint16 *data, const uint32 length_in_word)
{
	//                                                                                
	// Be careful!! Before you invoke this function, please follow the rules          
	//                                                                                
	// 1. A reasonable length_in_word and make sure the program data won't exceed the 
	//    sector boundary.                                                            
	// 2. length_in_word MUST be equal to 128 WORDs.                                  
	//                                                                                
	volatile uint16 *pa = (volatile uint16 *)prog_addr;
	uint32		i;

	// clear status register first 
	*pa = INTEL_CMD_CLR_SR;

	// sw lock release preprocess 
	RENESAS_SoftwareLockRelease_Preprocess(blockaddr);

	// enter page programming 
	*pa = RENESAS_CMD_PAGE_PGM;
		
	for(i=0; i<length_in_word; i++) {
		// fill data to device buffer 
		pa[i] = data[i];
	}
}

#if 0
void RENESAS_DynamicBuf_Program(const uint32 blockaddr, const uint32 prog_addr, const uint16 *data, const uint32 length_in_word)
{
	//                                                                                     
	// Be careful!! Before you invoke this function, you must calculate a reasonable       
	// length_in_word and make sure the program data won't exceed the sector boundary.     
	//                                                                                     
	volatile uint16 *pa = (volatile uint16 *)prog_addr;
	uint32		i;

	// clear status register first 
	*pa = INTEL_CMD_CLR_SR;

	//                                                               
	// WARNING!!! DON'T use fixed 128 WORDs Page-Program method when 
	// length_in_word is not equal to 128 WORDS.                     
	//                                                               
	// Because when length_in_word is less than 128, Page-Program    
	// will fail! Therefore, we have to use another program method.  
	// First, load variant length data to Page-Buffer, then flush    
	// Page-Buffer to flash.                                         
	//                                                               

	// load data to Page-Buffer 
	for(i=0; i<length_in_word; i++) {
		// sw lock release preprocess 
		RENESAS_SoftwareLockRelease_Preprocess(blockaddr);
		// fill data to Page-Buffer 
		*pa = RENESAS_CMD_DATA_LOAD_TO_PAGE_BUF;
		pa[i] = data[i];
	}

	// sw lock release preprocess 
	RENESAS_SoftwareLockRelease_Preprocess(blockaddr);
	// flush Page-Buffer to flash 
	*pa = RENESAS_CMD_PAGE_BUF_TO_FLASH;
	*pa = RENESAS_CMD_PAGE_BUF_TO_FLASH_CNF;
}
#endif

//------------------------------------------------------------------------------
// Protection Related Callback Function                                         
//------------------------------------------------------------------------------

void RENESAS_SoftwareLockRelease_Preprocess(const uint32 blockaddr)
{
	volatile uint16 *ba = (volatile uint16 *)blockaddr;
	uint16	block_num;

	//                     DQ7  DQ6  DQ5  DQ4  DQ3  DQ2  DQ1  DQ0        
	// ----------------------------------------------------------------- 
	//         Block Addr: A22  A21  A20  A19  A18  A17  A16  A15        
	// Block Addr Inverse: A22# A21# A20# A19# A18# A17# A16# A15#       
	//                                                                   
	// STEP 1: Right shift 1 bit to convert BYTE address to WORD address 
	// STEP 2: Right shift 15 bit to convert to block address            
	block_num = (blockaddr>>(1+15));

	ba[0x0] = RENESAS_CMD_SWLOCK_RELEASE_CMD_1;
	ba[0x0] = block_num;	// block address 
	ba[0x0] = RENESAS_CMD_SWLOCK_RELEASE_CMD_2;
	ba[0x0] = ~block_num;	// block address inverse 
	ba[0x0] = RENESAS_CMD_SWLOCK_RELEASE_CMD_3;
}

⌨️ 快捷键说明

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