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

📄 bfsa_internal.c

📁 ATMEL公司的demo程序,USB驱动程序,与识别片上flash,并进行枚举和操作.
💻 C
📖 第 1 页 / 共 3 页
字号:
//  ----------------------------------------------------------------------------
//          ATMEL Microcontroller Software Support  -  ROUSSET  -
//  ----------------------------------------------------------------------------
//  DISCLAIMER:  CONDITIONS AS PER SIGNED LIMITED LICENSE AGREEMENT (AT91
//  SOFTWARE AND USER DOCUMENTATION)
//  ALL SOFTWARE IS PROVIDED AS IS, WITH ALL FAULTS, AND WITH NO WARRANTY
//  WHATSOEVER.  ATMEL EXPRESSLY DISCLAIMS ALL WARRANTIES, EXPRESS, IMPLIED,
//  OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.
//  ----------------------------------------------------------------------------
// File Name           : bfsa_internal.c
// Object              : Internal functions to perfom basic IO on disk sectors
// Creation            : FB  10/feb/2005
// Modif               : JCB 15/apr/2005
// --------------------------------------------------------------------------
#include "po_types.h"
#include "po_kernel.h"
#include "trace.h"
#include "flash.h"
#include "bfsa_flash.h"
#include "bfsa_api.h"
#include "bfsa_internal.h"
#include "board.h"

#ifdef NANDFLASH
#include <stdlib.h>
#include "nand.h"
#include "nand_ids.h"
#include "jffs2.h"

#include "NandFlash.h"

extern unsigned char bBlock[SIZEONESECTOR];
#endif

// **************************************************
//     Global
// **************************************************

UCHAR* FlashBaseAdd = FILE_MGR_BEGIN_ADDRESS;      // Flash base address, only for read operations


/*****************************************************************
*
*
* S U B - R O U T I N E  : readBPB
*
*-----------------------------------------------------------------
*
* int readBPB(UCHAR *pucBuff, USHORT uSize)
*
* Object :
*   This function read BPB from Flash.
*
* Argument:
*       pucBuff         :[OUT] pointer to buffer that will receive the BPB,
*                        allocated by caller.
*       uSize           :[IN]  size of pucBuff.
*
* Return value : 0 if success,
*       on error :      NO_MEDIA_FOUND
*                       FLASH_ACCESS_ERROR
*
*****************************************************************/
ULONG readBPB(UCHAR *pucBuff, USHORT uSize)
{
  ULONG _status = BFSA_SUCCESS;

  if (uSize > BPB_SIZE)
  {
    _status = FLASH_ACCESS_ERROR;
  }
  else
  {
    // Copy first bytes from FLASH
     AT91F_ReadMedia((unsigned int)FlashBaseAdd, uSize, pucBuff);
  }
  return _status;
}

/*****************************************************************
*
*
* S U B - R O U T I N E  : readFAT
*
*-----------------------------------------------------------------
*
* void readFAT(void)
*
* Object :
*   This function copy the FAT from disk to global buffer.
*
* Argument:
*       none.
*
*****************************************************************/
void readFAT(void)
{
  ULONG _fatSizeFromDisk = BFSA_media.SectPerFAT*BFSA_media.bytesPerSector;

#ifdef NANDFLASH
  size_t total;
#endif

  #ifndef NANDFLASH
    po_memcpy((void*)BFSABuffer.BFSA_fatBuff,
              (void*)(BFSA_media.FATSectStart*BFSA_media.bytesPerSector + (ULONG)FlashBaseAdd),
              min(_fatSizeFromDisk,sizeofBFSA_fatBuff));
  #else
    nand_rw(nand_dev_desc + curr_device,
            NANDRW_READ,
            BFSA_media.FATSectStart*BFSA_media.bytesPerSector + (ULONG)FlashBaseAdd - AT91_SMARTMEDIA_BASE,
            sizeofBFSA_fatBuff,
            &total,
            BFSA_fatBuff);
  #endif
}

/*****************************************************************
*
*
* S U B - R O U T I N E  : writeFAT
*
*-----------------------------------------------------------------
*
* ULONG writeFAT(void)
*
* Object :
*   This function writes back the FAT from global buffer to disk.
*
* Argument:
*       none.
*
* Return value :
*       BFSA_SUCCESS       on success
*       FLASH_ACCESS_ERROR on error
*
*****************************************************************/
ULONG writeFAT(void)
{
  UCHAR _i;
  ULONG status = BFSA_SUCCESS;

  for (_i=0; _i<BFSA_media.numFAT; _i++)
  {
    if( FALSE == AT91F_Flash_Write_Address(BFSA_media.FATSectStart*BFSA_media.bytesPerSector     // Destination
                               + (ULONG) FlashBaseAdd
                               + (_i*BFSA_media.SectPerFAT*BFSA_media.bytesPerSector),
                               min(sizeofBFSA_fatBuff, BFSA_media.SectPerFAT*BFSA_media.bytesPerSector), // Size
                               (unsigned char*)BFSABuffer.BFSA_fatBuff, FALSE))                                          // Source
    {
      status = FLASH_ACCESS_ERROR;
      break;
    }
  }
  return status;
}

/*****************************************************************
*
*
* S U B - R O U T I N E  : readFatEntry
*
*-----------------------------------------------------------------
*
* USHORT readFatEntry(USHORT cluster)
*
* Object :
*   This function returns the value of the FAT entry for the cluster number.
*
* Argument:
*       cluster         [IN] : cluster number.
*
* Return value :
*       the value of the FAT entry for this cluster,
*       0x0FF7 if the cluster is over the max cluster number.
*
*****************************************************************/
USHORT readFatEntry( USHORT cluster )
{
  USHORT fatOffset;
  USHORT fatEntry = (BFSA_media.FATtype == BFSA_FAT12?BAD12:BAD16);  // Bad Cluster

  if (cluster > BFSA_media.MaxCluster)
  {
    TRACE_DEBUG_H( "dbg:PBcluster:0x%X\n\r",cluster);
  }
  else
  {
    if (BFSA_media.FATtype == BFSA_FAT12)
    {
      // Divide the cluster number by 2, resulting in an integer quotient
      // Add the same cluster number to this quotient, producing the offset of the cluster's entry in the FAT.
      fatOffset = cluster + (cluster / 2);

      // Pb with FAT > buffer of FAT
/*      if( fatOffset > sizeofBFSA_fatBuff )
      {
        // Read next of FAT
        po_memcpy( BFSA_fatBuff,
                   (void*)(BFSA_media.FATSectStart*BFSA_media.bytesPerSector + (ULONG)FlashBaseAdd+sizeof( BFSA_fatBuff ) ),
                   sizeofBFSA_fatBuff );
        fatOffset -= sizeof( BFSA_fatBuff );
      }
*/

/*
      if( fatOffset > sizeofBFSA_fatBuff )
      {
        AT91F_ReadMedia( (void*)(BFSA_media.FATSectStart*BFSA_media.bytesPerSector + (ULONG)FlashBaseAdd+sizeof( BFSA_fatBuff ), 
                       sizeofBFSA_fatBuff ), 
                       BFSA_fatBuff ) );
        fatOffset -= sizeofBFSA_fatBuff );
      }

*/


      if( fatOffset < sizeofBFSA_fatBuff )
      {
        fatEntry  = BFSABuffer.BFSA_fatBuff[fatOffset]+BFSABuffer.BFSA_fatBuff[fatOffset+1]*0x100;

        // Cluster is ODD or EVEN ?
        if (cluster & 0x0001)
        {
          // If the current cluster number is odd, keep the highest 12 bits of the 16-bit word.
          fatEntry = fatEntry >> 4;
        }
        else
        {
          // If the current cluster number is even, keep the lowest 12 bits of the 16-bit word.
          fatEntry = fatEntry & 0x0FFF;
        }
      }
    }
    else
    {
      TRACE_DEBUG_L( "dbg:NO FAT 12\n\r");
      if( (cluster*2) < sizeofBFSA_fatBuff )
      {
        // In a 16-bit FAT, cluster n is represented by the entry at offset n * 2 in the table.
        fatEntry = *((USHORT*) &BFSABuffer.BFSA_fatBuff[cluster*2]);
      }
    }
  }
  return( fatEntry );
}

/*****************************************************************
*
*
* S U B - R O U T I N E  : writeFatEntry
*
*-----------------------------------------------------------------
*
* USHORT writeFatEntry(USHORT cluster,USHORT value)
*
* Object :
*   This function write a value to FAT entry for cluster
*
* Argument:
*       cluster         [IN] : cluster number.
*       value           [IN] : value.
*
* Return value :
*       0 on success,
*       0x0FF7 if the cluster is over the max cluster number.
*
*****************************************************************/
ULONG writeFatEntry( USHORT cluster, USHORT value )
{
  USHORT fatOffset;
  ULONG  status = (BFSA_media.FATtype == BFSA_FAT12?BAD12:BAD16);  // Bad Cluster

  if (cluster > BFSA_media.MaxCluster)
  {
  }
  else
  {
    if (BFSA_media.FATtype == BFSA_FAT12)
    {
      USHORT valueForFATBuff;

      // Divide the cluster number by 2, resulting in an integer quotient
      // Add the same cluster number to this quotient, producing the offset of the cluster's entry in the FAT.
      fatOffset = cluster + (cluster / 2);

      // Pb with FAT > buffer of FAT
/*      if( fatOffset > sizeofBFSA_fatBuff )
      {
        // Read next of FAT
        po_memcpy( BFSA_fatBuff,
                   (void*)(BFSA_media.FATSectStart*BFSA_media.bytesPerSector + (ULONG)FlashBaseAdd+sizeofBFSA_fatBuff ),
                   sizeofBFSA_fatBuff );
        fatOffset -= sizeofBFSA_fatBuff;
      }
*/
      if( fatOffset < sizeofBFSA_fatBuff )
      {
        // Cluster is ODD or EVEN ?
        if (cluster & 0x0001)
        {
          valueForFATBuff = BFSABuffer.BFSA_fatBuff[fatOffset] + BFSABuffer.BFSA_fatBuff[fatOffset+1]*0x100;
          valueForFATBuff &= 0x000F;
          value = value << 4;
        }
        else
        {
          valueForFATBuff = BFSABuffer.BFSA_fatBuff[fatOffset] + BFSABuffer.BFSA_fatBuff[fatOffset+1]*0x100;
          valueForFATBuff &= 0xF000;
          value = value & 0x0FFF;
        }

        BFSABuffer.BFSA_fatBuff[fatOffset]   = (value&0x000000FF)     | (valueForFATBuff&0x000000FF);
        BFSABuffer.BFSA_fatBuff[fatOffset+1] =(char)((value&0x0000FF00)>>8) |((valueForFATBuff&0x0000FF00)>>8);
      }
    }
    else
    {
      if( (cluster*2) < sizeofBFSA_fatBuff )
      {
        // In a 16-bit FAT, cluster n is represented by the entry at offset n * 2 in the table.
        *((USHORT*) &BFSABuffer.BFSA_fatBuff[cluster*2]) = value;
      }
    }
    status = BFSA_SUCCESS;
  }

  return( status );

}

/*****************************************************************
*
*
* S U B - R O U T I N E  : findFreeCluster
*
*-----------------------------------------------------------------
*
* int findFreeCluster(void)
*
* Object :
*   This function returns the next free cluster from the FAT ,
*   marks it EOF (0x0FF8 or 0xFFFF8) and fill it with 0.
*
* Argument:
*       none.
*
* Return value :
*       free cluster if any,
*       0 if there is no more free cluster
*
*****************************************************************/
USHORT findFreeCluster(void)
{
  USHORT _currentCluster;
  USHORT _freeCluster = 0;
  USHORT _numberFatEntries;
  UCHAR *_pucCluster = NULL;

  // Compute the number of FAT entries = Number of clusters
  _numberFatEntries = (BFSA_media.MaxCluster - BFSA_media.ClusterStart);

  // Find a free cluster in FAT
  for (_currentCluster = 2;                               // the 2 first clusters are reserved
       _currentCluster < _numberFatEntries + 2;
       _currentCluster++)
  {
    if (readFatEntry(_currentCluster) == FREE)
    {
      unsigned int value;
      value = 0;

      _freeCluster = _currentCluster;

      // Mark it EOC (0x0FF8 for FAT12 0xFFF8 for FAT16)
      if( BFSA_SUCCESS != writeFatEntry(_freeCluster,BFSA_media.FATtype == BFSA_FAT12?EOC12:EOC16) )
      {
        // Problem
        _freeCluster = 0;
        break;
      }
      // Fill it by 0
      _pucCluster = (UCHAR*) (FIRST_SECTOR_DATACLUSTER(_currentCluster) * BFSA_media.bytesPerSector);
      if (!AT91F_Flash_Write_Address((unsigned int)FlashBaseAdd + (unsigned int)_pucCluster, // Add
                                      BFSA_media.bytesPerSector*BFSA_media.SectPerCluster,   // Size
                                      (unsigned char*) &value,                               // data
                                      TRUE))                                                 // MemSet
      {

⌨️ 快捷键说明

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