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

📄 sharpflash.c

📁 norflash的文件系统。 用于中低端手机开发的参考
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************
 
  FILE NAME: sharpflash.c

  DESCRIPTION:

    Sharp flash driver.

 Copyright (c) 2002, VIA Technologies, Inc.
*****************************************************************************/


#include "fsmdefs.h"
#include "FsmFlash.h"
#include "sharpflash.h"
#include "ostype.h"


#define FSM_DATA_START_ADDR     0x07300000  /* Address at which data volume begins. */
#define FSM_DATA_BLOCK_COUNT    8
#define FSM_DATA_BLOCK_SIZE     0x10000     /* Number of bytes in each block of
                                             * the data volume. */
#define BUFFER_SIZE             16


#define ALIGN_ADDRESS(addr) \
    ((uint32) ((addr) & ((uint32) ~(sizeof(FLASH_DATA) - 1))))

#define UNALIGNED_BYTES(addr) \
    ((uint32) ((addr) & ((uint32) (sizeof(FLASH_DATA) - 1))))

#define GET_MIN(a, b)   (((a) < (b)) ? (a) : (b))


#define LOCK_BLOCK(addr) \
	do \
	{  \
		*(addr) = FLASH_COMMAND_LOCK; \
		*(addr) = FLASH_COMMAND_LOCK_CONFIRM; \
	} while(0)

#define UNLOCK_BLOCK(addr) \
	do \
	{  \
		*(addr) = FLASH_COMMAND_LOCK; \
		*(addr) = FLASH_COMMAND_UNLOCK_CONFIRM; \
	} while(0)


/* Function prototypes. */
uint32 FsmSharpFlashInit(FsmDevObjHdrT *DevObjP);
uint32 FsmSharpFlashWrite(FsmDevObjHdrT *DevObjP, uint8 *buf, uint32 addr, uint32 len);
uint32 FsmSharpFlashErase(FsmDevObjHdrT *DevObjP, uint32 addr);
uint32 FsmSharpFlashCopy(FsmDevObjHdrT *DevObjP, uint32 DstAddr, uint32 SrcAddr, uint32 len);
uint32 FsmSharpFlashRead(FsmDevObjHdrT *DevObjP, uint8 *buf, uint32 addr, uint32 len);
uint32 FsmSharpFlashCtrl(FsmDevObjHdrT *DevObjP, uint32 CtrlCode, void *arg);

/* global variables */
const FsmDevDrvT	SharpFlashDrv =
					{
						FsmSharpFlashRead,
						FsmSharpFlashWrite,
						FsmSharpFlashCopy,
						FsmSharpFlashErase,
						FsmSharpFlashCtrl,
						FsmSharpFlashInit
					};

FsmFlashDevT		FlashDev = 
					{
						{ (FsmDevDrvT *)&SharpFlashDrv, DEV_TYPE_FLASH, NULL },
						NULL,
						NULL,
						FSM_DATA_BLOCK_SIZE,
						FSM_DATA_BLOCK_COUNT,
						FSM_DATA_START_ADDR
					};

volatile uint8	FsmStarting = FALSE;


/**********************************************
*                FUNCTIONS                    *
**********************************************/

/******************************************************************************
 * WriteToFlash()
 *
 * descriptions:
 *   Writes data to flash.
 *
 * parameters:
 *   FLASH_DATA_PTR flash_ptr - A pointer to the data destination.
 *   FLASH_DATA_PTR ram_ptr - A pointer to the data source.
 *   uint32  size  - The number of FLASH_DATA units to write.
 *
 * return:
 *   If any portion of the data is not written successfully, the function
 *   returns HW_ERR_WRITE; otherwise, the function returns HW_ERR_NONE.
 *
 *****************************************************************************/

static uint32
WriteToFlash(
	volatile FLASH_DATA *flash_ptr, 
	const FLASH_DATA *ram_ptr,
	uint32 size
	)
{
    FLASH_DATA  buffer_size;
    uint32      size_to_write;
    uint32      i;

    uint32 status = HW_ERR_NONE;


    while (size > 0)
    {
        /* no enough data, use single data program */
        if (size == 1)
        {
            DISABLE_INTERRUPTS();
            UNLOCK_BLOCK(flash_ptr);
            *flash_ptr = FLASH_COMMAND_WRITE;
            *flash_ptr = *ram_ptr;
            ENABLE_INTERRUPTS();

            ram_ptr++;
            size--;
        }
        else
        {
            /* determine the size of the buffer */
            size_to_write = GET_MIN(size, BUFFER_SIZE / sizeof(FLASH_DATA));
            buffer_size = (uint32)(size_to_write - 1);

            /* wait until buffer is ready */
            DISABLE_INTERRUPTS();
            UNLOCK_BLOCK(flash_ptr);
            do
            {
                *flash_ptr = FLASH_COMMAND_WRITE_BUFFER;
            } while ((*flash_ptr & FLASH_STATUS_READY) != FLASH_STATUS_READY);

            /* send size of data and fill buffer */
            *flash_ptr = buffer_size;
            for (i = 0; i < size_to_write; i++)
            {
                *flash_ptr = *ram_ptr;
                flash_ptr++;
                ram_ptr++;
            }

            /* make sure pointer is in the same block and commit buffer */
            flash_ptr--;
            *flash_ptr = FLASH_COMMAND_CONFIRM;
            ENABLE_INTERRUPTS();

            size -= size_to_write;
        }

        /* wait until flash is done */
        while ((*flash_ptr & FLASH_STATUS_READY) != FLASH_STATUS_READY)
        {
        }

        /* Lock the block */
        DISABLE_INTERRUPTS();
        LOCK_BLOCK(flash_ptr);
        ENABLE_INTERRUPTS();

        /* check for errors */
        if (*flash_ptr & FLASH_STATUS_ERROR)
        {
            *flash_ptr = FLASH_COMMAND_CLEAR;
            status = HW_ERR_WRITE;
            break;
        }

        /* increment flash pointer */
        flash_ptr++;
    }

    return status;
}


/******************************************************************************
 * FsmSharpFlashInit()
 *
 * descriptions:
 *   reset flash device to read-mode.
 *
 * parameters:
 *    FsmDevObjHdrT * DevObjP - device object
 *
 * return:
 *   HW_ERR_NONE.
 *
 *****************************************************************************/

uint32 FsmSharpFlashInit(FsmDevObjHdrT *DevObjP)
{
    volatile FLASH_DATA_PTR  flash_ptr;

    FsmFlashDevT *  pDev;

    pDev = (FsmFlashDevT *)DevObjP;

    flash_ptr = (volatile FLASH_DATA_PTR)(pDev->DevStartAddr);
    
    /* Place flash into read state. */
    *flash_ptr = FLASH_COMMAND_READ;
    
    return HW_ERR_NONE;
}


/******************************************************************************
 * FsmSharpFlashRead()
 *
 * descriptions:
 *   reset flash device to read-mode.
 *
 * parameters:
 *    FsmDevObjHdrT * DevObjP - device object
 *    uint8 * buf - buffer to receive the returned data
 *    uint32 Addr - where to read from within flash.
 *    uint32 length - number of bytes to read.
 *
 * return:
 *   HW_ERR_NONE.
 *
 *****************************************************************************/

uint32 FsmSharpFlashRead(FsmDevObjHdrT *DevObjP, uint8 *buf, uint32 addr, uint32 len)
{
    volatile FLASH_DATA_PTR  flash_data_ptr;
    volatile uint8          *flash_byte_ptr;
    
    FLASH_DATA_PTR  ram_data_ptr;
    uint8          *ram_byte_ptr;
    
    uint32 flash_offset, ram_offset;
    
    uint8  suspended = (uint8)FALSE;

    FsmFlashDevT *pDev;
    
    pDev = (FsmFlashDevT *)DevObjP;
    
    /* Validate address. */
#ifdef VALIDATE_ADDRESS
    if ((addr + len) > (pDev->BlockSize * pDev->Blocks))
    {
        return HW_ERR_PARAM;
    }
#endif /* VALIDATE_ADDRESS */
    
    addr += pDev->DevStartAddr;
    
    /* Return if nothing to read. */
    if (len == 0)
    {
        return HW_ERR_NONE;
    }
    
    /* Set up pointers. */
    flash_data_ptr = (FLASH_DATA_PTR)ALIGN_ADDRESS(addr);
    flash_byte_ptr = (uint8 *)addr;
    ram_byte_ptr = buf;
    
    /* calculate alignment offsets */
    flash_offset = UNALIGNED_BYTES(addr);
    ram_offset = UNALIGNED_BYTES((uint32)buf);
    
    *flash_data_ptr = FLASH_COMMAND_STATUS;
	/* Partition ready? */
    if ((*flash_data_ptr & FLASH_STATUS_PARTITION_READY) == 0)
    {
        *flash_data_ptr = FLASH_COMMAND_SUSPEND;
        *flash_data_ptr = FLASH_COMMAND_STATUS;
        while ((*flash_data_ptr & FLASH_STATUS_READY) != FLASH_STATUS_READY)
        {
        }

        if (*flash_data_ptr &
            (FLASH_STATUS_WRITE_SUSPENDED | FLASH_STATUS_ERASE_SUSPENDED))
        {
            suspended = (uint8)TRUE;
        }
    }
   
    /*
     * determine if source and destination addresses allow the reading on
     * aligned addresses
     */
    *flash_data_ptr = FLASH_COMMAND_READ;
    
    if ((flash_offset == ram_offset) &&  (len > sizeof(FLASH_DATA)))
    {
        /* Read the initial unaligned bytes. */
        if (flash_offset != 0)
        {
            while (flash_offset < sizeof(FLASH_DATA))
            {
                *ram_byte_ptr = *flash_byte_ptr;
                ram_byte_ptr++;
                flash_byte_ptr++;
                len--;
                flash_offset++;
            }
        }
        
        /* Read aligned data. */
        ram_data_ptr = (FLASH_DATA_PTR)ram_byte_ptr;
        flash_data_ptr = (FLASH_DATA_PTR)flash_byte_ptr;
        while (len >= sizeof(FLASH_DATA))
        {
            *ram_data_ptr = *flash_data_ptr;
            ram_data_ptr++;
            flash_data_ptr++;
            len -= sizeof(FLASH_DATA);
        }
        
        /* Read the remaining unaligned bytes. */
        if (len > 0)
        {
            ram_byte_ptr = (uint8 *)ram_data_ptr;
            flash_byte_ptr = (uint8 *)flash_data_ptr;
            
            while (len > 0)
            {
                *ram_byte_ptr = *flash_byte_ptr;
                ram_byte_ptr++;
                flash_byte_ptr++;
                len--;
            }
        }
    }
    else /* We have to read byte by byte if the source and destination addresses
          * do not allow the reading on aligned addresses.
          */
    {
        while (len > 0)
        {
            *ram_byte_ptr = *flash_byte_ptr;
            ram_byte_ptr++;
            flash_byte_ptr++;
            len--;
        }
    }
    
    /* if suspended, resume */
    if (suspended)
    {
        *flash_data_ptr = FLASH_COMMAND_STATUS;
        if (*flash_data_ptr & FLASH_STATUS_WRITE_SUSPENDED)
        {
            /* Resume write suspended flash. */
            *flash_data_ptr = FLASH_COMMAND_RESUME;
            *flash_data_ptr = FLASH_COMMAND_STATUS;
        }
        else
        {
            *flash_data_ptr = FLASH_COMMAND_RESUME;
        }
    }
    
    return HW_ERR_NONE;
}


/******************************************************************************
 * FsmSharpFlashWrite()
 *
 * descriptions:
 *   write data to flash.

⌨️ 快捷键说明

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