📄 altera_avalon_cfi_flash_intel.c
字号:
/******************************************************************************
* *
* License Agreement *
* *
* Copyright (c) 2003-2004 Altera Corporation, San Jose, California, USA. *
* All rights reserved. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *
* DEALINGS IN THE SOFTWARE. *
* *
* This agreement shall be governed in all respects by the laws of the State *
* of California and by the laws of the United States of America. *
* *
* altera_avalon_cfi_flash_intel.c *
* *
* Programming algorithms and associated functions for Intel and Intel Strata *
* flash parts *
* *
* Author PRR *
* This has not been tested on hardware yet, so it will almost certainly not *
* work *
* *
******************************************************************************/
#include <errno.h>
#include <io.h>
#include <unistd.h>
#include "alt_types.h"
#include "altera_avalon_cfi_flash.h"
#include "altera_avalon_cfi_flash_funcs.h"
static int alt_write_word_intel( alt_flash_cfi_dev* flash,
const int offset,
const alt_u8* src_addr);
static int alt_unlock_block_intel(alt_flash_cfi_dev* flash, int block_offset);
/******************************************************************************
* *
* Functions used as the interface to a flash programming algorithm by the * *
* common flash code *
* *
******************************************************************************/
/*
* alt_program_intel
*
* Program a block (or part of one)
*/
int alt_program_intel(alt_flash_dev* flash_info, int block_offset,
int offset, const void* src_addr,
int length)
{
int ret_code = 0;
alt_flash_cfi_dev* flash = (alt_flash_cfi_dev*)flash_info;
/*
* If this block is locked then unlock it
*/
ret_code = alt_unlock_block_intel(flash, block_offset);
if (!ret_code)
{
ret_code = alt_flash_program_block( flash, offset, src_addr, length,
alt_write_word_intel);
}
return ret_code;
}
/*
* alt_erase_block_intel
*
* Erase the selected erase block
*/
int alt_erase_block_intel(alt_flash_dev* flash_info, int block_offset)
{
int ret_code = 0;
alt_flash_cfi_dev* flash = (alt_flash_cfi_dev*)flash_info;
volatile alt_u8 status;
int timeout = flash->erase_timeout;
/*
* If this block is locked then unlock it
*/
ret_code = alt_unlock_block_intel(flash, block_offset);
if (!ret_code)
{
flash->write_native((alt_u8*)flash->dev.base_addr + block_offset, 0x20);
flash->write_native((alt_u8*)flash->dev.base_addr + block_offset, 0xD0);
do
{
status = IORD_8DIRECT(flash->dev.base_addr, block_offset);
if (status & 0x80)
{
break;
}
usleep(1);
timeout--;
}while(timeout > 0);
if (timeout == 0)
{
ret_code = -ETIMEDOUT;
}
else if (status & 0x7f)
{
/* If we have an error of some kind bomb out */
ret_code = -EIO;
status = IORD_8DIRECT(flash->dev.base_addr, block_offset);
}
/* Put the device back into read array mode */
flash->write_native((alt_u8*)flash->dev.base_addr + block_offset, 0xFF);
}
return ret_code;
}
/*
* Private Intel specific functions
*/
static int alt_unlock_block_intel(alt_flash_cfi_dev* flash, int block_offset)
{
alt_u8 locked;
alt_u8 status;
int ret_code = 0;
int timeout = flash->write_timeout * 100;
/*
* Is this block locked?
*/
flash->write_native((alt_u8*)flash->dev.base_addr + block_offset, 0x90);
locked = IORD_8DIRECT(flash->dev.base_addr, block_offset + 4);
if (locked & 0x1)
{
flash->write_native((alt_u8*)flash->dev.base_addr + block_offset, 0x60);
flash->write_native((alt_u8*)flash->dev.base_addr + block_offset, 0xD0);
do
{
status = IORD_8DIRECT(flash->dev.base_addr, block_offset);
if (status & 0x80)
{
break;
}
timeout--;
usleep(1);
}while(timeout > 0);
if (timeout == 0)
{
ret_code = -ETIMEDOUT;
}
else if (status & 0x7f)
{
/* If we have an error of some kind bomb out */
ret_code = -EIO;
}
}
/*
* Back to Read Array mode
*/
flash->write_native((alt_u8*)flash->dev.base_addr + block_offset, 0xFF);
return ret_code;
}
/*
* alt_write_word_intel
*
* Program the native word size of the flash from src_addr
* offset bytes into the flash
*/
int alt_write_word_intel( alt_flash_cfi_dev* flash,
const int offset, const alt_u8* src_addr)
{
int ret_code = 0;
alt_u8 status;
(*flash->write_native)((alt_u8*)flash->dev.base_addr+offset, 0x40);
alt_write_value_to_flash(flash, offset, src_addr);
do
{
status = IORD_8DIRECT(flash->dev.base_addr, offset);
}while(!(status & 0x80));
/* If we have an error of some kind bomb out */
if (status & 0x7f)
{
ret_code = -EIO;
}
/* Put the device back into read array mode */
flash->write_native((alt_u8*)flash->dev.base_addr + offset, 0xFF);
return ret_code;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -