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

📄 fdi_sprc.c

📁 FDI Intel开发的FLASH文件系统,功能很强大
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright(R) 2001-2002 Intel Corporation */
/* ############################################################################
 ### Object: Low Level Driver
 ###
 ### Module: FDI_Sprc.c - Single Partition Relocatable Code
 ###  $Archive: /FDI/SRC/LOWLVL/fdi_sprc.c $
 ###  $Revision: 33 $
 ###  $Date: 6/03/04 9:45a $
 ###  $Author: Wtiso $
 ###
 ###$NoKeywords: $
 ########################################################################### */

/*                                                               
 *****************************************************************
 * NOTICE OF LICENSE AGREEMENT                                    
 *                                                                
 * This code is provided by Intel Corp., and the use is governed  
 * under the terms of a license agreement. See license agreement  
 * for complete terms of license.                                 
 *                                                                
 * YOU MAY ONLY USE THE SOFTWARE WITH INTEL FLASH PRODUCTS.  YOUR 
 * USE OF THE SOFTWARE WITH ANY OTHER FLASH PRODUCTS IS EXPRESSLY 
 * PROHIBITED UNLESS AND UNTIL YOU APPLY FOR, AND ARE GRANTED IN  
 * INTEL'S SOLE DISCRETION, A SEPARATE WRITTEN SOFTWARE LICENSE   
 * FROM INTEL LICENSING ANY SUCH USE.                             
 *****************************************************************
 */
 

#ifdef CURRENT_FILE_BEING_COMPILED
#undef CURRENT_FILE_BEING_COMPILED
#endif

#define CURRENT_FILE_BEING_COMPILED FDI_SPRC


/*
 *### Include Files
 *#########################
 */

#include "fdi_lowl.h"



/* This code is compiled only in single partition mode */
#if (PARTITIONS == SINGLE)

/*
 *### Local Declarations
 *#########################
 */

/*
 * If FDI block-locking support is enabled, these macros will lock/unlock the
 * block pointed to by its argument
 */
#if ((BLOCK_LOCK_SUPPORT == TRUE) && (ENABLE_FDI_BLOCKLOCKING == TRUE))
#define LOCK_BLOCK(addr_ptr) \
   *(addr_ptr) = FLASH_COMMAND_LOCK; \
   *(addr_ptr) = FLASH_COMMAND_LOCK_CONFIRM
#define UNLOCK_BLOCK(addr_ptr) \
   *(addr_ptr) = FLASH_COMMAND_LOCK; \
   *(addr_ptr) = FLASH_COMMAND_UNLOCK_CONFIRM
#else  /* (!BLOCK_LOCKING_SUPPORT) || (!ENABLE_FDI_BLOCKLOCKING) */
#define LOCK_BLOCK(addr_ptr)
#define UNLOCK_BLOCK(addr_ptr)
#endif /* (BLOCK_LOCKING_SUPPORT) && (ENABLE_FDI_BLOCKLOCKING) */

/* For non-FDI block locking support */
#if (BLOCK_LOCK_SUPPORT == TRUE)
#define BLOCK_LOCK_STATUS_OFFSET             2
#endif

/*
 * When using the hardware buffer on flash components, the user must
 * specify the number of bytes/words being written to the buffer after
 * issuing the write-to-buffer command
 */
#if (BUFFER_SIZE > 0)
#define BUFFER_SIZE_TO_WRITE(s)              CREATE_COMMAND((s) - 1)
#endif /* BUFFER_SIZE */

/* E5.0.480 START */
#if (FLASH_PAIRED == TRUE)
#define ALL_F        ((FLASH_DATA) (-1))
#define SHIFT_FACTOR (sizeof(FLASH_DATA) << 2)
#define DEVICE0_MASK ((FLASH_DATA) (ALL_F >> SHIFT_FACTOR))
#define DEVICE1_MASK ((FLASH_DATA) ((ALL_F >> SHIFT_FACTOR) << SHIFT_FACTOR))

#define RESUME_WRITE_SUSPENDED_FLASH(fp) \
   *(fp) = FLASH_COMMAND_STATUS; \
   if ((*(fp) & DEVICE0_MASK) & FLASH_STATUS_WRITE_SUSPENDED) \
   { \
      *(fp) = ((FLASH_COMMAND_STATUS & DEVICE1_MASK) | \
               (FLASH_COMMAND_RESUME & DEVICE0_MASK)); \
   } \
   if ((*(fp) & DEVICE1_MASK) & FLASH_STATUS_WRITE_SUSPENDED) \
   { \
      *(fp) = ((FLASH_COMMAND_STATUS & DEVICE0_MASK) | \
               (FLASH_COMMAND_RESUME & DEVICE1_MASK)); \
   }

#else /* FLASH_PAIRED != TRUE */
#define RESUME_WRITE_SUSPENDED_FLASH(fp) \
   *(fp) = FLASH_COMMAND_STATUS; \
   if (*(fp) & FLASH_STATUS_WRITE_SUSPENDED) \
   { \
      *(fp) = FLASH_COMMAND_RESUME; \
   }
#endif /* FLASH_PAIRED */
/* E5.0.480 END */



/*
 *### Global Declarations
 *#########################
 */

#if (TIME_MONITOR_ENABLED == TRUE)
extern const DWORD LowLvlTimeNeeded;
#endif /* TIME_MONITOR_ENABLED */

/*
 *### Global Functions
 *#########################
 */

#if (BUFFER_SIZE > 0)
/*#############################################################################
  ### LowLvlWrite (Buffered Version)
  ###
  ### DESCRIPTION:
  ###   Writes the data buffer to the flash hardware.
  ###
  ### PARAMETERS:
  ###    IN:  flash_ptr (FLASH_DATA_PTR) - A pointer to the physical address
  ###          in flash to write the buffer passed.
  ###         ram_ptr (FLASH_DATA_PTR) - A pointer to the buffer in RAM to
  ###          read from.
  ###         size (DWORD) - The size (in FLASH_DATA units) to write.
  ###    OUT: 
  ###
  ### PRECONDITIONS:
  ###  'size' must not exceed the size of the hardware buffer
  ###
  ### RETURNS:
  ###  If one data value was not written properly, the function returns
  ###  HW_ERR_WRITE.  If the function needs to suspend the write operation
  ###  due to a pending interrupt, the function returns HW_ERR_SUSPEND.  If
  ###  the command sequence to write a buffer was interrupted, the function
  ###  returns HW_ERR_ABORT.  If all the data in the data buffer is programmed
  ###  without suspending flash hardware, the function returns HW_ERR_NONE.
  ###
 */

/* E.5.0.652 Begin */
HW_ERROR LowLvlWrite(volatile FLASH_DATA *flash_ptr,
                     FLASH_DATA *ram_ptr, DWORD size)
/* E.5.0.652 End */
{
   static HW_ERROR status = HW_ERR_NONE;


   /* if suspended, resume */
   if (status == HW_ERR_SUSPEND)
   {
      /* E5.0.480 START */
      RESUME_WRITE_SUSPENDED_FLASH(flash_ptr);
      /* E5.0.480 END */
      *flash_ptr = FLASH_COMMAND_STATUS;
   }

   /* otherwise, write data */
   else
   {
      UNLOCK_BLOCK(flash_ptr);
      status = HW_ERR_NONE;

      /* not enough data, use single write */
      if (size == 1)
      {
         *flash_ptr = FLASH_COMMAND_WRITE;
         *flash_ptr = *ram_ptr;
      }

      /* enough data to use hardware buffer */
      else
      {
         /* check for buffer to be ready */
         do
         {
            *flash_ptr = FLASH_COMMAND_WRITE_BUFFER;
         } while ((*flash_ptr & FLASH_STATUS_READY) != FLASH_STATUS_READY);

         /* fill buffer */
         *flash_ptr = BUFFER_SIZE_TO_WRITE(size);
         while (size > 0)
         {
            *flash_ptr = *ram_ptr;
            flash_ptr++;
            ram_ptr++;
            size--;
         }

         /*
          * decrement pointer to make sure that the same block is
          * being addressed, then check for interrupts before committing
          * buffer
          */
         flash_ptr--;
         if (INTERRUPT_PENDING)
         {
            *flash_ptr = FLASH_COMMAND_ABORT;
            *flash_ptr = FLASH_COMMAND_CLEAR;
            status = HW_ERR_ABORT;
         }
         else
         {
            *flash_ptr = FLASH_COMMAND_CONFIRM;
         }
      }
   }

   /* if the write was not aborted, finish write */
   if (status != HW_ERR_ABORT)
   {
      /* wait until flash is ready */
      while (((*flash_ptr & FLASH_STATUS_READY) != FLASH_STATUS_READY) &&
            (!(INTERRUPT_PENDING)))
      {
#if (TIME_MONITOR_ENABLED == TRUE)
         if (TICKS_TILL_NEXT_INTERRUPT() < LowLvlTimeNeeded)
         {
            break;
         }
#endif
      }

      /* if an interrupt occurred, suspend */
      if ((*flash_ptr & FLASH_STATUS_READY) != FLASH_STATUS_READY)
      {
         *flash_ptr = FLASH_COMMAND_SUSPEND;
         *flash_ptr = FLASH_COMMAND_STATUS;
         while ((*flash_ptr & FLASH_STATUS_READY) != FLASH_STATUS_READY)
         {
         }
         status = HW_ERR_SUSPEND;
      }

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

      /* write successful */
      else
      {
         status = HW_ERR_NONE;
      }
   }


#if ((BLOCK_LOCK_SUPPORT == TRUE) && (ENABLE_FDI_BLOCKLOCKING == TRUE))
   /* lock block if not suspended */
   if (status != HW_ERR_SUSPEND)
   {
      LOCK_BLOCK(flash_ptr);
   }
#endif /* BLOCK_LOCK_SUPPORT && ENABLE_FDI_BLOCKLOCKING */

   /* place flash into read array mode */
   *flash_ptr = FLASH_COMMAND_READ;
   return status;
}



#else  /* BUFFER_SIZE == 0 */
/*#############################################################################
  ### LowLvlWrite (Buffered Version)
  ###
  ### DESCRIPTION:
  ###   Writes the data buffer to the flash hardware.
  ###
  ### PARAMETERS:
  ###    IN:  flash_ptr (FLASH_DATA_PTR) - A pointer to the physical address
  ###          in flash to write the buffer passed.
  ###         ram_ptr (FLASH_DATA_PTR) - A pointer to the buffer in RAM to
  ###          read from.
  ###         size (DWORD) - The size (in FLASH_DATA units) to write.
  ###    OUT: 
  ###
  ### RETURNS:
  ###  If one data value was not written properly, the function returns
  ###  HW_ERR_WRITE.  If the function needs to suspend the write operation
  ###  due to a pending interrupt, the function returns HW_ERR_SUSPEND.  If
  ###  the command sequence to write a buffer was interrupted, the function
  ###  returns HW_ERR_ABORT.  If all the data in the data buffer is programmed
  ###  without suspending flash hardware, the function returns HW_ERR_NONE.
  ###
 */

/* E.5.0.652 Begin */
HW_ERROR LowLvlWrite(volatile FLASH_DATA *flash_ptr,
                     FLASH_DATA *ram_ptr)
/* E.5.0.652 End */
{
   static HW_ERROR status = HW_ERR_NONE;


   /* if previously suspended, resume write */
   if (status == HW_ERR_SUSPEND)
   {
      /* E5.0.480 START */
      RESUME_WRITE_SUSPENDED_FLASH(flash_ptr);
      /* E5.0.480 END */
      *flash_ptr = FLASH_COMMAND_STATUS;
   }

   /* otherwise, write data */
   else
   {
      UNLOCK_BLOCK(flash_ptr);
      *flash_ptr = FLASH_COMMAND_WRITE;
      *flash_ptr = *ram_ptr;
   }

   /* wait until flash ready or interrupt occurs */
   while (((*flash_ptr & FLASH_STATUS_READY) != FLASH_STATUS_READY) &&
         (!(INTERRUPT_PENDING)))
   {
#if (TIME_MONITOR_ENABLED == TRUE)
      if (TICKS_TILL_NEXT_INTERRUPT() < LowLvlTimeNeeded)
      {
         break;
      }
#endif
   }

   /* if an interrupt occurred, suspend */
   if ((*flash_ptr & FLASH_STATUS_READY) != FLASH_STATUS_READY)
   {
      *flash_ptr = FLASH_COMMAND_SUSPEND;
      *flash_ptr = FLASH_COMMAND_STATUS;
      while ((*flash_ptr & FLASH_STATUS_READY) != FLASH_STATUS_READY)
      {
      }
      status = HW_ERR_SUSPEND;
   }

   /* write complete, check for errors */
   else if (*flash_ptr & FLASH_STATUS_ERROR)
   {
      *flash_ptr = FLASH_COMMAND_CLEAR;
      status = HW_ERR_WRITE;
   }

   /* write was successful */
   else
   {
      status = HW_ERR_NONE;
   }


#if ((BLOCK_LOCK_SUPPORT == TRUE) && (ENABLE_FDI_BLOCKLOCKING == TRUE))
   /* lock block if not suspended */
   if (status != HW_ERR_SUSPEND)
   {
      LOCK_BLOCK(flash_ptr);
   }
#endif /* BLOCK_LOCK_SUPPORT && ENABLE_FDI_BLOCKLOCKING */

   /* place back into read array mode */
   *flash_ptr = FLASH_COMMAND_READ;
   return status;
}
#endif /* BUFFER_SIZE */



/*#############################################################################
  ### LowLvlEraseBlock
  ###
  ### DESCRIPTION:
  ###   Erases the block containing the address specified in the flash
  ###   hardware.
  ###
  ###   If an interrupt occurs while erasing the flash block, the erase is
  ###   suspended before the function returns.  If an erase was suspended
  ###   and this function called, the function resumes the erase and does
  ###   not start a new one.
  ###
  ### PARAMETERS:
  ###    IN:  address (DWORD) - An absolute physical starting address of the
  ###          block to be erased.
  ###    OUT:
  ###
  ### RETURNS:
  ###   If the flash block could not be erased, the function returns
  ###   HW_ERR_ERASE.  If the funciton needs to suspend the erase due to
  ###   a pending interrupt, the function returns HW_ERR_SUSPEND.  If the
  ###   block is erased successfully, the function returns HW_ERR_NONE.
  ###
 */

⌨️ 快捷键说明

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