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

📄 df.c

📁 ATMEL 90usb128 USB source,include USB protocol stack.
💻 C
📖 第 1 页 / 共 4 页
字号:
/*C**************************************************************************
* NAME:         df.c
*----------------------------------------------------------------------------
* Copyright (c) 2006 Atmel.
*----------------------------------------------------------------------------
* RELEASE:      at90usb128-usbkey-demo-3enum-host-mouse-1_0_4
* REVISION:     1.12
*----------------------------------------------------------------------------
* PURPOSE:
* This file contains the low-level dataflash routines
*
* NOTES:
* Global Variables:
*   - gl_ptr_mem: long in data space
*****************************************************************************/

/*_____ I N C L U D E S ____________________________________________________*/
#include "config.h"                         /* system configuration */
#ifdef DF_VALIDATION
#include "virtual_usb.h"
#else
#include "lib_mcu\usb\usb_drv.h"            /* usb driver definition */
#endif
#include "lib_mcu\spi\spi_drv.h"            /* spi driver definition */
#include "df.h"                             /* dataflash definition */


/*_____ M A C R O S ________________________________________________________*/


/*_____ D E F I N I T I O N ________________________________________________*/

extern  data    Uint32  gl_ptr_mem;         /* memory data pointer     */

static  U8      df_mem_busy;                /* memories in busy state  */
static  U8      df_select;                  /* current memory selected */

/*_____ D E C L A R A T I O N ______________________________________________*/

static  void    df_wait_busy(void);
static  void    df_chipselect_current(void);

code s_format  df_tab_format[]=
  {
   /* nb_cylinder, nb_head, nb_sector, nb_hidden, nb_sector_per_cluster */
    { (Uint16)255, (Byte)4, (Byte)8,   (Byte)15,  (Byte)8 },    /* DF_SIZE_4MB */
    { (Uint16)510, (Byte)4, (Byte)8,   (Byte)15,  (Byte)8 },    /* DF_SIZE_8MB */
    { (Uint16)510, (Byte)4, (Byte)16,  (Byte)15,  (Byte)8 },    /* DF_SIZE_16MB */
    { (Uint16)510, (Byte)8, (Byte)16,  (Byte)15,  (Byte)8 },    /* DF_SIZE_32MB */
  };


#ifdef DF_4_MB            /* AT45DB321 memories */
  #if(DF_NB_MEM == 4)
    xdata Uint32 DF_DISK_SIZE   = DF_SIZE_16MB;
  #elif (DF_NB_MEM == 2)
    xdata Uint32 DF_DISK_SIZE   = DF_SIZE_8MB;
  #elif (DF_NB_MEM ==1)
    xdata Uint32 DF_DISK_SIZE   = DF_SIZE_4MB;
  #endif
#endif

#ifdef DF_8_MB             /* AT45DB642 memories */
  #if(DF_NB_MEM == 4)
    xdata Uint32 DF_DISK_SIZE   = DF_SIZE_32MB;
  #elif (DF_NB_MEM == 2)
    xdata Uint32 DF_DISK_SIZE   = DF_SIZE_16MB;
  #elif (DF_NB_MEM ==1)
    xdata Uint32 DF_DISK_SIZE   = DF_SIZE_8MB;
  #endif
#endif


//!
//! @brief This function initializes the SPI communication link between the DF and the DF driver.
//!
//! @warning Code:?? bytes (function code length)
//!
//! @param none
//!
//! @return none
//!
//!/
static void df_spi_init(void)
{
   Spi_set_mode(SPI_MASTER_MODE_3);
   //Spi_set_rate(SPI_RATE_0);   //impossible in AVR mode in spi_drv.h
   Spi_config_speed(SPI_RATE_1); //theses 2 lines replace the Spi_set_rate(SPI_RATE_0)
   Spi_set_doublespeed();        //theses 2 lines replace the Spi_set_rate(SPI_RATE_0)
   // Spi_set_rate(SPI_RATE_0) -> SCK freq == fosc/2.
   // ==
   // Spi_config_speed(SPI_RATE_1) -> SCK freq == fosc/4
   // +
   // Spi_set_doublespeed() -> SCK freq == fosc/2

   Spi_disable_ss();
   Spi_enable();
}

//!
//! @brief This function initializes the Dataflash controller & the SPI bus(over which the DF is controlled).
//!
//!
//! @warning Code:?? bytes (function code length)
//!
//! @param none
//!
//! @return bit
//!   The memory is ready     -> OK (always)
//!/
bit df_init (void)
{
   // Init the SPI communication link between the DF and the DF driver.
   df_spi_init();

   // Data Flash Controller init.
   df_mem_busy = 0;     // all memories ready
   df_select = MEM_DF0;
   return(OK);
}



//!
//! @brief This function selects a DF memory according to the sector pointer
//!        The "df_select" variable contains the current memory addressed
//!        Refer to the documentation of the function df_translate_addr() for more information about zones management
//!
//! @warning Code:?? bytes (function code length)
//!
//! @param memzone    LSB of logical sector address to open
//!
//! @return none
//!/
static void df_chipselect_memzone(U8 memzone)
{
#if (DF_NB_MEM == 1)
   df_select = MEM_DF0;
#else
   #if (DF_NB_MEM == 2)
      #if (DF_PAGE_SIZE == 512)
         if ((memzone&0x01) == 0)                 // each page parity matches a memory
           df_select = MEM_DF0;
         else
           df_select = MEM_DF1;
      #else
         if ((memzone&0x02) == 0)                 // each double page parity matches a memory
           df_select = MEM_DF0;
         else
           df_select = MEM_DF1;
      #endif
   #else
      #if (DF_PAGE_SIZE == 512)
         switch(memzone&0x3)
         {
            case 0:
              df_select = MEM_DF0;
              break;
            case 1:
              df_select = MEM_DF1;
              break;
            case 2:
              df_select = MEM_DF2;
              break;
            case 3:
              df_select = MEM_DF3;
              break;
            default:
              break;
         }
      #else
         switch((memzone>>1)&0x3)
         {
            case 0:
              df_select = MEM_DF0;
              break;
            case 1:
              df_select = MEM_DF1;
              break;
            case 2:
              df_select = MEM_DF2;
              break;
            case 3:
              df_select = MEM_DF3;
              break;
            default:
              break;
         }
      #endif
   #endif
#endif
}



//!
//! @brief This function physically selects the current addressed memory
//!
//! @warning Code:?? bytes (function code length)
//!
//! @param  none
//!
//! @return none
//!/
static void df_chipselect_current(void)
{
   Df_desel_all();
#ifndef AVRGCC

   #if (DF_NB_MEM == 1)
      Df_select_df(0,DF_SELECT_MEM);
   #else
      #if (DF_NB_MEM == 2)
         if (df_select == MEM_DF0)
           Df_select_df(0,DF_SELECT_MEM);
         else
           Df_select_df(1,DF_SELECT_MEM);
      #else
         switch (df_select)
         {
         case MEM_DF0:
           Df_select_df(0,DF_SELECT_MEM);
           break;
         case MEM_DF1:
           Df_select_df(1,DF_SELECT_MEM);
           break;
         case MEM_DF2:
           Df_select_df(2,DF_SELECT_MEM);
           break;
         default:
           Df_select_df(3,DF_SELECT_MEM);
           break;
         }
      #endif
   #endif

#else // FOR AVRGCC...

   #if (DF_NB_MEM == 1)
      DF_CS_PORT &= (U8)(~(1<<DF_CS0));
   #else
      #if (DF_NB_MEM == 2)
         if (df_select == MEM_DF0)
           DF_CS_PORT &= (U8)(~(1<<DF_CS0));
         else
           DF_CS_PORT &= (U8)(~(1<<DF_CS1));
      #else
         switch (df_select)
         {
         case MEM_DF0:
           DF_CS_PORT &= (U8)(~(1<<DF_CS0));
           break;
         case MEM_DF1:
           DF_CS_PORT &= (U8)(~(1<<DF_CS1));
           break;
         case MEM_DF2:
           DF_CS_PORT &= (U8)(~(1<<DF_CS2));
           break;
         default:
           DF_CS_PORT &= (U8)(~(1<<DF_CS3));
           break;
         }
      #endif
   #endif

#endif
}


//!
//! @brief This function translates the logical sector address to the physical byte address (1 logical sector = 512 bytes)
//!        In function of the memory configuration (number 1x/2x/4x, pages 512b/1024b) :
//!
//!   MEMORIES WITH PAGES OF 512 BYTES :
//!   ==================================
//!   Consider the logical sector address as "xx..xxba", where 'b' and 'a' are the two last bits, and "xx..xx" an undefined number of more significant bits
//!      - If 1 memory is used, this logical sector address directly matches with the physical sector address
//!        So the physical sector address is "xx..xxba"
//!      - If 2 memories are used, the bit 'a' indicates the memory concerned, and the rest of the address indicates the physical address
//!        So the physical sector address is "xx...xxb"
//!      - If 4 memories are used, the bits 'ba' indicates the memory concerned, and the rest of the address indicates the physical address
//!        So the physical sector address is "xx....xx"
//!
//!   MEMORIES WITH PAGES OF 1024 BYTES :
//!   ==================================
//!   Consider the logical sector address as "xx..xxcba", where 'c', 'b' and 'a' are the three last bits, and "xx..xx" an undefined number of more significant bits
//!      - If 1 memory is used, this logical sector address directly matches with the physical sector address
//!        So the physical sector address is "xx..xxcba"
//!      - If 2 memories are used, the bit 'b' indicates the memory concerned, and the rest of the address indicates the physical address
//!        So the physical sector address is "xx...xxca"
//!      - If 4 memories are used, the bits 'cb' indicates the memory concerned, and the rest of the address indicates the physical address
//!        So the physical sector address is "xx....xxa"
//!
//!
//! @warning Code:?? bytes (function code length)
//!
//! @param  log_sect_addr     logical sector address
//!
//! @return U32               physical byte address
//!/
static U32 df_translate_addr(Uint32 log_sect_addr)
{
#if (DF_NB_MEM == 1)
   return (log_sect_addr << 9);  // this case if only one memory...
#else
   #if (DF_NB_MEM == 2)
      #if (DF_PAGE_SIZE == 512)
         return ((log_sect_addr&0xFFFFFFFE) << 8);
      #else
         return (((log_sect_addr&0xFFFFFFFC) << 8) | ((log_sect_addr&0x00000001) << 9));
      #endif
   #else
      #if (DF_PAGE_SIZE == 512)
         return ((log_sect_addr&0xFFFFFFFC) << 7);
      #else
         return (((log_sect_addr&0xFFFFFFF8) << 7) | ((log_sect_addr&0x00000001) << 9));
      #endif
   #endif
#endif
}



//!
//! @brief This function performs a memory check on all DF.
//!
//!
//! @warning Code:?? bytes (function code length)
//!
//! @param none
//!
//! @return bit
//!   The memory is ready     -> OK

⌨️ 快捷键说明

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