📄 flash.c
字号:
enum EE_flash_cmd {
#ifdef EE_FLASH_TYPE_INTEL_AO
// Intel / Micron / Sharp / ST
EE_read_intel = 0xFF,
EE_read_status_intel = 0x70,
EE_clear_status_intel = 0x50,
EE_program_intel = 0x40,
EE_erase_intel = 0x20,
EE_erase_confirm_intel = 0xD0,
EE_suspend_intel = 0xB0,
EE_config_setup_intel = 0x60,
EE_config_read_intel = 0x90,
EE_resume_intel = 0xD0,
// Intel
EE_identify_device_intel = 0x90,
EE_Read_query_intel = 0x98,
// Intel / Sharp / ST
EE_unlock_block_intel = 0xD0,
// Micron
EE_identify_device_micron = 0x90,
// Sharp
EE_identify_device_sharp = 0x90,
// ST
EE_identify_device_st = 0x90
#endif
};
/****************************************************************
*
* FUNCTION: low_level_erase_flash_block (local, must be located in RAM)
*
* PARAMETERS: block_ptr : Pointer to the block to be erase
* bank_switch: bank switch option
* boomerang_suspend: boomerang option
* sector_erase: Indicates an SST sector erase
*
* RETURNS: None
*
* DESCRIPTION: Don't call this function directly, use the erase_flash_block function
* Used to erase a flash block in idle mode.
* Essential intr. requests can be monitored and allowed.
* When inside this function /WR to /CS0 is enabled with the
* flash inhibit register.
*
* CREATED: 28.06.00 by EC
*
* IMPORTANT: Any changes made to this function shall also be changed in the dummy
* function to take effect.
* If changes is made the located area in RAM for the dummy function
* shall also be changed.
*
* MODIFIED: 15.08.00 by EC
* - Is modyfied and tested ok.
* 02.11.00 by EC
* Code re-written in assembler to avoid changes in the code
* due to compiler options/revisions, and to avoid the JMPA
* instruktion which will course problems then the code is
* copied from the flash-function.
* 21.09.01 by EC
* NOP's added to avoid 2 writes in succession (timing violation).
*
****************************************************************/
#pragma class PR=EE_RAMCODE
void low_level_erase_flash_block(unsigned int *block_ptr, unsigned int boomerang_suspend, BOOL sector_erase)
{
#ifdef PAGEMODE_BUSCON0_SUPPORTED
unsigned char pagemode_on = 0;
#endif
#if defined(EE_FLASH_TYPE_sst)
unsigned int toggle1;
unsigned int toggle2;
#endif
unsigned int timeout;
#if !defined(EE_FLASH_TYPE_sst)
sector_erase = 0; // Get free of warning
#endif
if ((unsigned int huge *)block_ptr == erase_block_addr_resumed_from_other_ptr)
{
// Erase has been recalled after interrupt but erase of the block has been executed
// from another task. The block has allready been erased.
return;
}
#ifdef PAGEMODE_BUSCON0_SUPPORTED // If CS0 is used then page mode must be disabled before proceeding
if ((pagemode_on = clk_sw_pagemode_is_active(0))) // BUSCON0 - Disable page mode if it is enabled
clk_sw_pagemode_disable(0); // BUSCON0
#endif
DISABLE_INTR // Disable all intr
FLASHIN = 0x0066; // Enable write to flash
timeout = 0;
erase_block_addr1_ptr = erase_block_addr2_ptr = block_ptr; // Erase ongoing mark is set, NO other erase must be initiated
#if defined(EE_FLASH_TYPE_sst)
if (fujitsu_suspend_active) // Check if erase suspended
{
*block_ptr = EE_resume_sst; // Resume erase operation
fujitsu_suspend_active = 0;
}
else
{
// Command sequence:
*((unsigned int*)(EE_FLASH_BASE_CS_ADDRESS+EE_cmd1_address_sst)) = EE_cmd1_sst;
*((unsigned int*)(EE_FLASH_BASE_CS_ADDRESS+EE_cmd2_address_sst)) = EE_cmd2_sst;
*((unsigned int*)(EE_FLASH_BASE_CS_ADDRESS+EE_cmd3_address_sst)) = EE_cmd3_sst;
*((unsigned int*)(EE_FLASH_BASE_CS_ADDRESS+EE_cmd4_address_sst)) = EE_cmd4_sst;
*((unsigned int*)(EE_FLASH_BASE_CS_ADDRESS+EE_cmd5_address_sst)) = EE_cmd5_sst;
if (sector_erase)
*block_ptr = EE_erase_sector_sst; // Start sector erase
else
*block_ptr = EE_erase_block_sst; // Start block erase
}
do
{
if (EE_essential_intr_request || timeout > TIMEOUT)
{
timeout = 0; // To allow low priority intr.
block_erased = *block_ptr == 0xFFFF;
if (!block_erased) // If ongoing erase
{
*block_ptr = EE_suspend_sst; // Suspend erase operation
do
{
toggle1 = *block_ptr & 0xC0;
toggle2 = *block_ptr & 0xC0;
} while (!(toggle1 == 0xC0 && toggle2 == 0xC0)); // Wait for suspend active
fujitsu_suspend_active = 1;
#ifdef PAGEMODE_BUSCON0_SUPPORTED
if (pagemode_on) // Enable page mode if it was enabled before erase
clk_sw_pagemode_enable();
#endif
if (boomerang_suspend) //Interrupts and code have to be executed*/
break;
FLASHIN = 0x0060; // Disable write to flash
ENABLE_INTR // Allow intr. to be executed
DISABLE_INTR
FLASHIN = 0x0066; // Enable write to flash
fujitsu_suspend_active = 0;
if (erase_block_addr1_ptr == NULL)
{
FLASHIN = 0x0060; // Disable write to flash
ENABLE_INTR
return; // Erase have been resumed from other task and is allready finished
}
#ifdef PAGEMODE_BUSCON0_SUPPORTED
clk_sw_pagemode_disable(0); // BUSCON0 - Disable page mode
#endif
*block_ptr = EE_resume_sst; // Continue erase
}
}
timeout++;
block_erased = *block_ptr == 0xFFFF;
} while (!block_erased);
// EE_FLASH_TYPE == EE_intel a.o.
*block_ptr = EE_read_status_intel; // Check if erase suspended
if (*block_ptr & 0x40)
{
*block_ptr = EE_resume_intel; // Resume erase operation
}
else
{
*block_ptr = EE_config_setup_intel; // Send unlock cmd.
_nop(); // NOP added to avoid 2 writes in succession (timing violation)
*block_ptr = EE_unlock_block_intel;
_nop(); // NOP added to avoid 2 writes in succession (timing violation)
*block_ptr = EE_erase_intel; // Start block erase
_nop(); // NOP added to avoid 2 writes in succession (timing violation)
*block_ptr = EE_erase_confirm_intel; // Block erase confirm
}
do
{
*block_ptr = EE_read_status_intel;
block_erased = *block_ptr & 128;
if (!block_erased && (EE_essential_intr_request || timeout > TIMEOUT)) // Check for int req. or timeout
{
timeout = 0; // To allow low priority intr.
*block_ptr = EE_suspend_intel; // Suspend erase operation
_nop(); // NOP added to avoid 2 writes in succession (timing violation)
*block_ptr = EE_read_status_intel; // Set flash in read mode
while (!(*block_ptr & 128)); // Wait for state machine ready
block_erased = !(*block_ptr & 64); // Check block erase status
if (!block_erased) // If ongoing erase
{
*block_ptr = EE_read_intel; // Change direction
#ifdef PAGEMODE_BUSCON0_SUPPORTED
if (pagemode_on) // Enable page mode if it was enabled before erase.
clk_sw_pagemode_enable();
#endif
if (boomerang_suspend) // Interrupts and code have to be executed
break;
FLASHIN = 0x0060; // Disable write to flash
ENABLE_INTR // Allow intr. to be executed
DISABLE_INTR
FLASHIN = 0x0066; // Enable write to flash
if (erase_block_addr1_ptr == NULL)
{
FLASHIN = 0x0060; // Disable write to flash
ENABLE_INTR
return; // Erase have been resumed from other task and is finished
}
#ifdef PAGEMODE_BUSCON0_SUPPORTED
clk_sw_pagemode_disable(0); // BUSCON0 - Disable page mode
#endif
*block_ptr = EE_resume_intel; // Continue erase
}
}
timeout++;
} while (!block_erased);
*block_ptr = EE_read_intel; // Change direction
// EE_FLASH_TYPE condition
if (block_erased)
{
erase_block_addr1_ptr = erase_block_addr2_ptr = NULL; // Erase ongoing mark is deleted, ready for new erase
}
#ifdef PAGEMODE_BUSCON0_SUPPORTED
if (pagemode_on) // Enable page mode if it was enabled before erase.
clk_sw_pagemode_enable();
#endif
FLASHIN = 0x0060; // Disable write to flash
ENABLE_INTR // Re-enable all intr.
}
#pragma default_attributes
/****************************************************************
*
* FUNCTION: program_word (local, must be located in RAM)
*
* PARAMETERS: w_ptr : determines which word to program.
* value : value to program
*
* RETURNS: None
*
* DESCRIPTION: Is writing a word in the flash.
* No suspend is carried out. And int. enable/disabled is done external.
*
* IMPORTANT: Any changes made to this function shall also be changed in the dummy
* function to take effect.
* If changes is made the located area in RAM for the dummy function
* shall also be changed.
*
* CREATED: 10.05.00 by EC
*
* MODIFIED: 28.06.00 by EC
* Intel flash can now be programmed / suspended / resumed.
* When inside this function /WR to /CS0 is enabled with the
* flash inhibit register.
* 18.08.00 by EC
* IEN control moved to the calling function.
* 04.09.00 by EC
* Suspend part removed.
* 02.11.00 by EC
* Code re-written in assembler to avoid changes in the code
* due to compiler options/revisions, and to avoid the JMPA
* instruktion which will course problems then the code is
* copied from the flash-function.
* 21.09.01 by EC
* NOP's added to avoid 2 writes in succession (timing violation).
*
****************************************************************/
#pragma class PR=EE_RAMCODE
static BOOL program_word(unsigned int *w_ptr, unsigned int value)
{
#ifdef PAGEMODE_BUSCON0_SUPPORTED
unsigned char pagemode_on = 0;
#endif
BOOL status = TRUE;
FLASHIN = 0x0066; // Enable write to flash
#ifdef PAGEMODE_BUSCON0_SUPPORTED // If CS0 is used then page mode must be disabled before proceeding
if ((pagemode_on = clk_sw_pagemode_is_active(0))) // BUSCON0 - Disable page mode if it is enabled
clk_sw_pagemode_disable(0);
#endif
value &= *w_ptr;
// EE_FLASH_TYPE == EE_Intel a.o.
#if defined(EE_FLASH_TYPE_sharp)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -