- Main Page
- Modules
- Data Structures
- Files
- Related Pages

- File List
- Globals

# df.c

Go to the documentation of this file.

    00001 /*C**************************************************************************
    00002 * NAME:         df.c
    00003 *----------------------------------------------------------------------------
    00004 * Copyright (c) 2006 Atmel.
    00005 *----------------------------------------------------------------------------
    00006 * RELEASE:      at90usb162-2enum-mouse_ms-1_0_1
    00007 * REVISION:     1.4
    00008 *----------------------------------------------------------------------------
    00009 * PURPOSE:
    00010 * This file contains the low-level dataflash routines
    00011 *
    00012 * NOTES:
    00013 * Global Variables:
    00014 *   - gl_ptr_mem: long in data space
    00015 *****************************************************************************/
    00016
    00017 /*_____ I N C L U D E S ____________________________________________________*/
    00018 #include "config.h"                         /* system configuration */
    00019 #ifdef DF_VALIDATION
    00020 #include "virtual_usb.h"
    00021 #else
    00022 #include "lib_mcu\usb\usb_drv.h"            /* usb driver definition */
    00023 #endif
    00024 #include "lib_mcu\spi\spi_drv.h"            /* spi driver definition */
    00025 #include "df.h"                             /* dataflash definition */
    00026
    00027
    00028 /*_____ M A C R O S ________________________________________________________*/
    00029
    00030
    00031 /*_____ D E F I N I T I O N ________________________________________________*/
    00032
    00033 extern  data    Uint32  gl_ptr_mem;         /* memory data pointer     */
    00034
    00035 static  U8      df_mem_busy;                /* memories in busy state  */
    00036 static  U8      df_select;                  /* current memory selected */
    00037
    00038 /*_____ D E C L A R A T I O N ______________________________________________*/
    00039
    00040 static  void    df_wait_busy(void);
    00041 static  void    df_chipselect_current(void);
    00042
    00043 code s_format  df_tab_format[]=
    00044   {
    00045    /* nb_cylinder, nb_head, nb_sector, nb_hidden, nb_sector_per_cluster */
    00046     { (Uint16)255, (Byte)4, (Byte)8,   (Byte)15,  (Byte)8 },    /* DF_SIZE_4MB */
    00047     { (Uint16)510, (Byte)4, (Byte)8,   (Byte)15,  (Byte)8 },    /* DF_SIZE_8MB */
    00048     { (Uint16)510, (Byte)4, (Byte)16,  (Byte)15,  (Byte)8 },    /* DF_SIZE_16MB */
    00049     { (Uint16)510, (Byte)8, (Byte)16,  (Byte)15,  (Byte)8 },    /* DF_SIZE_32MB */
    00050   };
    00051
    00052
    00053 #ifdef DF_4_MB            /* AT45DB321 memories */
    00054   #if(DF_NB_MEM == 4)
    00055     xdata Uint32 DF_DISK_SIZE   = DF_SIZE_16MB;
    00056   #elif (DF_NB_MEM == 2)
    00057     xdata Uint32 DF_DISK_SIZE   = DF_SIZE_8MB;
    00058   #elif (DF_NB_MEM ==1)
    00059     xdata Uint32 DF_DISK_SIZE   = DF_SIZE_4MB;
    00060   #endif
    00061 #endif
    00062
    00063 #ifdef DF_8_MB             /* AT45DB642 memories */
    00064   #if(DF_NB_MEM == 4)
    00065     xdata Uint32 DF_DISK_SIZE   = DF_SIZE_32MB;
    00066   #elif (DF_NB_MEM == 2)
    00067     xdata Uint32 DF_DISK_SIZE   = DF_SIZE_16MB;
    00068   #elif (DF_NB_MEM ==1)
    00069     xdata Uint32 DF_DISK_SIZE   = DF_SIZE_8MB;
    00070   #endif
    00071 #endif
    00072
    00073
    00084 static void df_spi_init(void)
    00085 {
    00086    Spi_set_mode(SPI_MASTER_MODE_3);
    00087    //Spi_set_rate(SPI_RATE_0);   //impossible in AVR mode in spi_drv.h
    00088    Spi_config_speed(SPI_RATE_1); //theses 2 lines replace the Spi_set_rate(SPI_RATE_0)
    00089    Spi_set_doublespeed();        //theses 2 lines replace the Spi_set_rate(SPI_RATE_0)
    00090    // Spi_set_rate(SPI_RATE_0) -> SCK freq == fosc/2.
    00091    // ==
    00092    // Spi_config_speed(SPI_RATE_1) -> SCK freq == fosc/4
    00093    // +
    00094    // Spi_set_doublespeed() -> SCK freq == fosc/2
    00095
    00096    Spi_disable_ss();
    00097    Spi_enable();
    00098 }
    00099
    00111 bit df_init (void)
    00112 {
    00113    // Init the SPI communication link between the DF and the DF driver.
    00114    df_spi_init();
    00115
    00116    // Data Flash Controller init.
    00117    df_mem_busy = 0;     // all memories ready
    00118    df_select = MEM_DF0;
    00119    return(OK);
    00120 }
    00121
    00122
    00123
    00135 static void df_chipselect_memzone(U8 memzone)
    00136 {
    00137 #if (DF_NB_MEM == 1)
    00138    df_select = MEM_DF0;
    00139 #else
    00140    #if (DF_NB_MEM == 2)
    00141       #if (DF_PAGE_SIZE == 512)
    00142          if ((memzone&0x01) == 0)                 // each page parity matches a memory
    00143            df_select = MEM_DF0;
    00144          else
    00145            df_select = MEM_DF1;
    00146       #else
    00147          if ((memzone&0x02) == 0)                 // each double page parity matches a memory
    00148            df_select = MEM_DF0;
    00149          else
    00150            df_select = MEM_DF1;
    00151       #endif
    00152    #else
    00153       #if (DF_PAGE_SIZE == 512)
    00154          switch(memzone&0x3)
    00155          {
    00156             case 0:
    00157               df_select = MEM_DF0;
    00158               break;
    00159             case 1:
    00160               df_select = MEM_DF1;
    00161               break;
    00162             case 2:
    00163               df_select = MEM_DF2;
    00164               break;
    00165             case 3:
    00166               df_select = MEM_DF3;
    00167               break;
    00168             default:
    00169               break;
    00170          }
    00171       #else
    00172          switch((memzone>>1)&0x3)
    00173          {
    00174             case 0:
    00175               df_select = MEM_DF0;
    00176               break;
    00177             case 1:
    00178               df_select = MEM_DF1;
    00179               break;
    00180             case 2:
    00181               df_select = MEM_DF2;
    00182               break;
    00183             case 3:
    00184               df_select = MEM_DF3;
    00185               break;
    00186             default:
    00187               break;
    00188          }
    00189       #endif
    00190    #endif
    00191 #endif
    00192 }
    00193
    00194
    00195
    00205 static void df_chipselect_current(void)
    00206 {
    00207    Df_desel_all();
    00208 #ifndef AVRGCC
    00209
    00210    #if (DF_NB_MEM == 1)
    00211       Df_select_df(0,DF_SELECT_MEM);
    00212    #else
    00213       #if (DF_NB_MEM == 2)
    00214          if (df_select == MEM_DF0)
    00215            Df_select_df(0,DF_SELECT_MEM);
    00216          else
    00217            Df_select_df(1,DF_SELECT_MEM);
    00218       #else
    00219          switch (df_select)
    00220          {
    00221          case MEM_DF0:
    00222            Df_select_df(0,DF_SELECT_MEM);
    00223            break;
    00224          case MEM_DF1:
    00225            Df_select_df(1,DF_SELECT_MEM);
    00226            break;
    00227          case MEM_DF2:
    00228            Df_select_df(2,DF_SELECT_MEM);
    00229            break;
    00230          default:
    00231            Df_select_df(3,DF_SELECT_MEM);
    00232            break;
    00233          }
    00234       #endif
    00235    #endif
    00236
    00237 #else // FOR AVRGCC...
    00238
    00239    #if (DF_NB_MEM == 1)
    00240       DF_CS_PORT &= (U8)(~(1<<DF_CS0));
    00241    #else
    00242       #if (DF_NB_MEM == 2)
    00243          if (df_select == MEM_DF0)
    00244            DF_CS_PORT &= (U8)(~(1<<DF_CS0));
    00245          else
    00246            DF_CS_PORT &= (U8)(~(1<<DF_CS1));
    00247       #else
    00248          switch (df_select)
    00249          {
    00250          case MEM_DF0:
    00251            DF_CS_PORT &= (U8)(~(1<<DF_CS0));
    00252            break;
    00253          case MEM_DF1:
    00254            DF_CS_PORT &= (U8)(~(1<<DF_CS1));
    00255            break;
    00256          case MEM_DF2:
    00257            DF_CS_PORT &= (U8)(~(1<<DF_CS2));
    00258            break;
    00259          default:
    00260            DF_CS_PORT &= (U8)(~(1<<DF_CS3));
    00261            break;
    00262          }
    00263       #endif
    00264    #endif
    00265
    00266 #endif
    00267 }
    00268
    00269
    00301 static U32 df_translate_addr(Uint32 log_sect_addr)
    00302 {
    00303 #if (DF_NB_MEM == 1)
    00304    return (log_sect_addr << 9);  // this case if only one memory...
    00305 #else
    00306    #if (DF_NB_MEM == 2)
    00307       #if (DF_PAGE_SIZE == 512)
    00308          return ((log_sect_addr&0xFFFFFFFE) << 8);
    00309       #else
    00310          return (((log_sect_addr&0xFFFFFFFC) << 8) | ((log_sect_addr&0x00000001) << 9));
    00311       #endif
    00312    #else
    00313       #if (DF_PAGE_SIZE == 512)
    00314          return ((log_sect_addr&0xFFFFFFFC) << 7);
    00315       #else
    00316          return (((log_sect_addr&0xFFFFFFF8) << 7) | ((log_sect_addr&0x00000001) << 9));
    00317       #endif
    00318    #endif
    00319 #endif
    00320 }
    00321
    00322
    00323
    00336 bit df_mem_check (void)
    00337 {
    00338    //# DF memory check.
    00339    for(df_select=0; df_select<DF_NB_MEM; df_select++)
    00340    {
    00341       df_chipselect_current();
    00342       Spi_write_data(DF_RD_STATUS); /* Send the read status register cmd
    00343                                        + 1st step to clear the SPIF bit */
    00344       Spi_write_dummy();            /* dummy write that:
    00345                                     (.) finalize the clear of the SPIF bit (access to SPDR)
    00346                                     (.) get status register
    00347                                     (.) does the 1st step to clear the SPIF bit  */
    00348       /* Following Spi_read_data() finalize the clear of SPIF by accessing SPDR. */
    00349       // Check the DF density.
    00350       if ((Spi_read_data() & DF_MSK_DENSITY) != DF_DENSITY)
    00351       {   // Unexpected value.
    00352         Df_desel_all();
    00353         return (KO);
    00354       }
    00355       Df_desel_all();
    00356    }
    00357
    00358    return OK;
    00359 }
    00360
    00361
    00362
    00372 static void df_wait_busy (void)
    00373 {
    00374   // Read the status register until the DataFlash is not busy.
    00375   df_chipselect_current();
    00376   Spi_write_data(DF_RD_STATUS); /* Send the read status register cmd
    00377                                    + 1st step to clear the SPIF bit */
    00378   Spi_write_dummy();            /* dummy write that:
    00379                                     (.) finalize the clear of the SPIF bit (access to SPDR)
    00380                                     (.) get status register
    00381                                     (.) does the 1st step to clear the SPIF bit */
    00382   // Following Spi_read_data() finalize the clear of SPIF by accessing SPDR
    00383   while ((Spi_read_data() & DF_MSK_BIT_BUSY) == DF_MEM_BUSY)
    00384   {
    00385     Spi_write_dummy();           /* dummy write to get new status
    00386                                    + 1st step to clear the SPIF bit */
    00387   }
    00388   Df_desel_all();                /* unselect memory to leave STATUS request mode */
    00389   Spi_ack_write();               /* Final step to clear the SPIF bit. */
    00390 }
    00391
    00392
    00393
    00406 bit df_read_open (Uint32 pos)
    00407 {
    00408   // Set the global memory ptr at a Byte address.
    00409   gl_ptr_mem = df_translate_addr(pos);
    00410
    00411   // Select the DF that memory "pos" points to (the "df_select" variable will be updated)
    00412   df_chipselect_memzone(LSB0(pos));
    00413
    00414   // If the DF memory is busy, wait until it's not.
    00415   if (is_df_busy(df_select))
    00416   {
    00417     df_release_busy(df_select);
    00418     df_wait_busy();                              /* wait end of programming */
    00419   }
    00420
    00421   // Physically assert the selected dataflash
    00422   df_chipselect_current();
    00423
    00424   //#
    00425   //# Initiate a page read at a given sector address.
    00426   //#
    00427   // Send read main command, + first step to clear the SPIF bit
    00428   Spi_write_data(DF_RD_MAIN);
    00429   // Final step to clear the SPIF bit will be done on the next write
    00430
    00431   // Send the three address Bytes made of:
    00432   //  (.) the page-address(first xbits),
    00433   //  (.) the Byte-address within the page(last ybits).
    00434   // (x and y depending on the DF type).
    00435   // NOTE: the bits of gl_ptr_mem above the 24bits are not useful for the local
    00436   // DF addressing. They are used for DF discrimination when there are several
    00437   // DFs.
    00438   Spi_write_data((MSB1(gl_ptr_mem) << DF_SHFT_B1) | (MSB2(gl_ptr_mem) >> DF_SHFT_B2));
    00439   Spi_write_data(((MSB2(gl_ptr_mem) & ~DF_PAGE_MASK) << DF_SHFT_B1) | (MSB2(gl_ptr_mem) & DF_PAGE_MASK));
    00440   Spi_write_data(MSB3(gl_ptr_mem));
    00441   // Final step to clear the SPIF bit will be done on the next write
    00442
    00443   // 4 dummy writes for reading delay
    00444   Spi_write_data(0xFF);
    00445   Spi_write_data(0xFF);
    00446   Spi_write_data(0xFF);
    00447   Spi_write_data(0xFF); /* Tx 0xFF, first step to clear the SPIF bit */
    00448   Spi_ack_write();      /* Final step to clear the SPIF bit. */
    00449
    00450   return OK;
    00451 }
    00452
    00453
    00463 void df_read_close (void)
    00464 {
    00465   Df_desel_all();   /* Unselect memory */
    00466 }
    00467
    00468
    00469
    00493 bit df_read_sector (Uint16 nb_sector)
    00494 {
    00495    U8 i;
    00496    do
    00497    {
    00498       for (i = 8; i != 0; i--)
    00499       {
    00500          Disable_interrupt();    // Global disable.
    00501
    00502          // Principle: send any Byte to get a Byte.
    00503          // Spi_write_dummy(): send any Byte + 1st step to clear the SPIF bit.
    00504          // Spi_read_data(): get the Byte + final step to clear the SPIF bit.
    00505          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00506          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00507          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00508          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00509          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00510          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00511          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00512          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00513          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00514          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00515          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00516          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00517          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00518          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00519          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00520          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00521          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00522          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00523          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00524          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00525          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00526          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00527          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00528          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00529          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00530          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00531          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00532          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00533          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00534          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00535          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00536          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00537          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00538          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00539          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00540          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00541          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00542          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00543          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00544          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00545          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00546          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00547          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00548          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00549          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00550          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00551          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00552          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00553          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00554          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00555          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00556          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00557          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00558          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00559          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00560          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00561          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00562          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00563          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00564          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00565          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00566          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00567          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00568          Spi_write_dummy(); Usb_write_byte(Spi_read_data());
    00569
    00570          //# Send the USB FIFO IN content to the USB Host.
    00571          Usb_send_in();       // Send the FIFO IN content to the USB Host.
    00572
    00573          Enable_interrupt();     // Global interrupt re-enable.
    00574
    00575          // Wait until the tx is done so that we may write to the FIFO IN again.
    00576          while(Is_usb_write_enabled()==FALSE);
    00577       }
    00578       gl_ptr_mem += 512;      // increment global address pointer
    00579       nb_sector--;            // 1 more sector read
    00580       #if (DF_NB_MEM == 1)    // end of page ?
    00581          #if (DF_PAGE_SIZE == 512)
    00582             Df_desel_all();
    00583             if (nb_sector != 0)
    00584               df_read_open(gl_ptr_mem>>9);
    00585          #else
    00586             if ((MSB2(gl_ptr_mem) & DF_PAGE_MASK) == 0x00)
    00587             {
    00588                Df_desel_all();
    00589                if (nb_sector != 0)
    00590                  df_read_open(gl_ptr_mem>>9);
    00591             }
    00592          #endif
    00593       #endif
    00594    }
    00595    while (nb_sector != 0);
    00596
    00597   return OK;   // Read done.
    00598 }
    00599
    00600
    00615 bit df_write_open (Uint32 pos)
    00616 {
    00617   // Set the global memory ptr at a Byte address.
    00618   gl_ptr_mem = df_translate_addr(pos);
    00619
    00620   // Select the DF that memory "pos" points to
    00621   df_chipselect_memzone(LSB0(pos));
    00622
    00623   // If the DF memory is busy, wait until it's not.
    00624   if (is_df_busy(df_select))
    00625   {
    00626     df_release_busy(df_select);
    00627     df_wait_busy();                              /* wait end of programming */
    00628   }
    00629
    00630 #if DF_PAGE_SIZE > 512
    00631   // Physically assert the selected dataflash
    00632   df_chipselect_current();
    00633
    00634   //#
    00635   //# Transfer the current page content in buffer1.
    00636   //#
    00637   // Send Main Mem page to Buffer1 command, + first step to clear the SPIF bit
    00638   Spi_write_data(DF_TF_BUF_1);
    00639   // Final step to clear the SPIF bit will be done on the next write
    00640
    00641   // Send the three address Bytes made of:
    00642   //  (.) the page-address(first xbits),
    00643   //  (.) remaining don't care bits(last ybits).
    00644   // (x and y depending on the DF type).
    00645   // NOTE: the bits of gl_ptr_mem above the 24bits are not useful for the local
    00646   // DF addressing. They are used for DF discrimination when there are several
    00647   // DFs.
    00648   Spi_write_data((MSB1(gl_ptr_mem) << DF_SHFT_B1) | (MSB2(gl_ptr_mem) >> DF_SHFT_B2));
    00649   Spi_write_data(MSB2(gl_ptr_mem) << DF_SHFT_B1);
    00650   Spi_write_dummy();       // Remaining don't care bits.
    00651   Spi_ack_write();         // Final step to clear the SPIF bit.
    00652
    00653   Df_desel_all();          // Unselect memory to validate the command
    00654
    00655   df_wait_busy();               // Wait end of page transfer
    00656 #endif
    00657
    00658   // Physically assert the selected dataflash
    00659   df_chipselect_current();
    00660
    00661   //#
    00662   //# Initiate a page write at a given sector address.
    00663   //#
    00664   // Send Main Memory Page Program Through Buffer1 command,
    00665   // + first step to clear the SPIF bit
    00666   Spi_write_data(DF_PG_BUF_1);
    00667   // Final step to clear the SPIF bit will be done on the next write
    00668
    00669   // Send the three address Bytes made of:
    00670   //  (.) the page-address(first xbits),
    00671   //  (.) the Byte-address within the page(last ybits).
    00672   // (x and y depending on the DF type).
    00673   // NOTE: the bits of gl_ptr_mem above the 24bits are not useful for the local
    00674   // DF addressing. They are used for DF discrimination when there are several
    00675   // DFs.
    00676   Spi_write_data((MSB1(gl_ptr_mem) << DF_SHFT_B1) | (MSB2(gl_ptr_mem) >> DF_SHFT_B2));
    00677   Spi_write_data(((MSB2(gl_ptr_mem) & ~DF_PAGE_MASK) << DF_SHFT_B1) | (MSB2(gl_ptr_mem) & DF_PAGE_MASK));
    00678   Spi_write_data(MSB3(gl_ptr_mem));
    00679   Spi_ack_write();         // Final step to clear the SPIF bit.
    00680
    00681   return OK;
    00682 }
    00683
    00684
    00695 void df_write_close (void)
    00696 {
    00697   //#
    00698   //# While end of logical sector (512B) not reached, zero-fill the remaining
    00699   //# memory Bytes.
    00700   //#
    00701   while ((MSB3(gl_ptr_mem) != 0x00) || ((MSB2(gl_ptr_mem) & 0x01) != 0x00))
    00702   {
    00703     Spi_write_data(0x00);  // (.) Final step to clear the SPIF bit,
    00704                            // (.) Write 0x00
    00705                            // (.) first step to clear the SPIF bit.
    00706     gl_ptr_mem++;
    00707   }
    00708   Spi_ack_write();            // Final step to clear the SPIF bit.
    00709
    00710   Df_desel_all();             // Launch page programming (or simply unselect memory
    00711                               // if the while loop was not performed).
    00712   df_set_busy(df_select);     // Current memory is busy
    00713 }
    00714
    00715
    00716
    00739 bit df_write_sector (Uint16 nb_sector)
    00740 {
    00741   Byte i;
    00742
    00743    do
    00744    {
    00745     //# Write 8x64b = 512b from the USB FIFO OUT.
    00746     for (i = 8; i != 0; i--)
    00747     {
    00748       // Wait end of rx in USB EPOUT.
    00749       while(Is_usb_read_enabled()==FALSE);
    00750
    00751       Disable_interrupt();    // Global disable.
    00752
    00753       // SPI write principle: send a Byte then clear the SPIF flag.
    00754       // Spi_write_data(Usb_read_byte()): (.) Final step to clear the SPIF bit,
    00755       //                                  (.) send a Byte read from USB,
    00756       //                                  (.) 1st step to clear the SPIF bit.
    00757       Spi_write_data(Usb_read_byte());
    00758       Spi_write_data(Usb_read_byte());
    00759       Spi_write_data(Usb_read_byte());
    00760       Spi_write_data(Usb_read_byte());
    00761       Spi_write_data(Usb_read_byte());
    00762       Spi_write_data(Usb_read_byte());
    00763       Spi_write_data(Usb_read_byte());
    00764       Spi_write_data(Usb_read_byte());
    00765       Spi_write_data(Usb_read_byte());
    00766       Spi_write_data(Usb_read_byte());
    00767       Spi_write_data(Usb_read_byte());
    00768       Spi_write_data(Usb_read_byte());
    00769       Spi_write_data(Usb_read_byte());
    00770       Spi_write_data(Usb_read_byte());
    00771       Spi_write_data(Usb_read_byte());
    00772       Spi_write_data(Usb_read_byte());
    00773       Spi_write_data(Usb_read_byte());
    00774       Spi_write_data(Usb_read_byte());
    00775       Spi_write_data(Usb_read_byte());
    00776       Spi_write_data(Usb_read_byte());
    00777       Spi_write_data(Usb_read_byte());
    00778       Spi_write_data(Usb_read_byte());
    00779       Spi_write_data(Usb_read_byte());
    00780       Spi_write_data(Usb_read_byte());
    00781       Spi_write_data(Usb_read_byte());
    00782       Spi_write_data(Usb_read_byte());
    00783       Spi_write_data(Usb_read_byte());
    00784       Spi_write_data(Usb_read_byte());
    00785       Spi_write_data(Usb_read_byte());
    00786       Spi_write_data(Usb_read_byte());
    00787       Spi_write_data(Usb_read_byte());
    00788       Spi_write_data(Usb_read_byte());
    00789       Spi_write_data(Usb_read_byte());
    00790       Spi_write_data(Usb_read_byte());
    00791       Spi_write_data(Usb_read_byte());
    00792       Spi_write_data(Usb_read_byte());
    00793       Spi_write_data(Usb_read_byte());
    00794       Spi_write_data(Usb_read_byte());
    00795       Spi_write_data(Usb_read_byte());
    00796       Spi_write_data(Usb_read_byte());
    00797       Spi_write_data(Usb_read_byte());
    00798       Spi_write_data(Usb_read_byte());
    00799       Spi_write_data(Usb_read_byte());
    00800       Spi_write_data(Usb_read_byte());
    00801       Spi_write_data(Usb_read_byte());
    00802       Spi_write_data(Usb_read_byte());
    00803       Spi_write_data(Usb_read_byte());
    00804       Spi_write_data(Usb_read_byte());
    00805       Spi_write_data(Usb_read_byte());
    00806       Spi_write_data(Usb_read_byte());
    00807       Spi_write_data(Usb_read_byte());
    00808       Spi_write_data(Usb_read_byte());
    00809       Spi_write_data(Usb_read_byte());
    00810       Spi_write_data(Usb_read_byte());
    00811       Spi_write_data(Usb_read_byte());
    00812       Spi_write_data(Usb_read_byte());
    00813       Spi_write_data(Usb_read_byte());
    00814       Spi_write_data(Usb_read_byte());
    00815       Spi_write_data(Usb_read_byte());
    00816       Spi_write_data(Usb_read_byte());
    00817       Spi_write_data(Usb_read_byte());
    00818       Spi_write_data(Usb_read_byte());
    00819       Spi_write_data(Usb_read_byte());
    00820       Spi_write_data(Usb_read_byte());
    00821       Spi_ack_write();        // Final step to clear the SPIF bit.
    00822
    00823       Usb_ack_receive_out();  // USB EPOUT read acknowledgement.
    00824
    00825       Enable_interrupt();     // Global re-enable.
    00826     } // for (i = 8; i != 0; i--)
    00827
    00828       gl_ptr_mem += 512;        // Update the memory pointer.
    00829       nb_sector--;              // 1 more sector written
    00830
    00831       //# Launch page programming if end of page.
    00832       //#
    00833       #if DF_PAGE_SIZE > 512
    00834          // Check if end of 1024b page.
    00835          if ((MSB2(gl_ptr_mem) & DF_PAGE_MASK) == 0x00)
    00836          {
    00837             Df_desel_all();         // Launch page programming
    00838             df_set_busy(df_select);     // memory is busy
    00839             #if (DF_NB_MEM == 1)
    00840                if (nb_sector != 0)
    00841                  df_write_open(gl_ptr_mem>>9);
    00842             #endif
    00843          }
    00844       #else
    00845          // Always end of page.
    00846          Df_desel_all();           // Launch page programming
    00847          df_set_busy(df_select);     // memory is busy
    00848          #if (DF_NB_MEM == 1)
    00849             if (nb_sector != 0)
    00850               df_write_open(gl_ptr_mem>>9);
    00851          #endif
    00852       #endif
    00853    }
    00854    while (nb_sector != 0);
    00855
    00856   return OK;                  // Write done
    00857 }
    00858
    00859
    00860
    00874 bit df_read_sector_2_ram(U8 *ram)
    00875 {
    00876    U16 i;
    00877    for(i=0;i<DF_SECTOR_SIZE;i++)
    00878    {
    00879       Spi_write_dummy();
    00880       *ram=Spi_read_data();
    00881       ram++;
    00882    }
    00883    gl_ptr_mem += 512;     // Update the memory pointer.
    00884    return OK;
    00885 }
    00886
    00900 bit df_write_sector_from_ram(U8 *ram)
    00901 {
    00902    U16 i;
    00903    for(i=0;i<DF_SECTOR_SIZE;i++)
    00904    {
    00905       Spi_write_data(*ram);
    00906       *ram++;
    00907    }
    00908    Spi_ack_write();        // Final step to clear the SPIF bit.
    00909    gl_ptr_mem += 512;      // Update the memory pointer.
    00910    return OK;
    00911 }
    00912
    00913
    00914
    00915 /*F**************************************************************************
    00916 * NAME: df_format
    00917 *----------------------------------------------------------------------------
    00918 * PARAMS:
    00919 *
    00920 * return:
    00921 *   Address of the format parameter structure in code
    00922 *----------------------------------------------------------------------------
    00923 * PURPOSE:
    00924 *   This function is called by the fat_format function and returns a pointer
    00925 *   to a table containing the format parameters.
    00926 *----------------------------------------------------------------------------
    00927 * EXAMPLE:
    00928 *----------------------------------------------------------------------------
    00929 * NOTE:
    00930 *   DF FORMAT PARAMETERS
    00931 *   CAPACITY  LBAs      CYL   HDs   S/T   CLUSTs  S/C   S/F   FAT   HID
    00932 *   4MB        8160     255   4     8             8                 15
    00933 *   8MB       16320     510   4     8             8     12    12    15
    00934 *   16MB      32640     510   4     16    4080    8     12    12    15
    00935 *   32MB      65280     510   8     16    8160    8     12    16    15
    00936 *----------------------------------------------------------------------------
    00937 * REQUIREMENTS:
    00938 *****************************************************************************/
    00939 s_format * df_format (void)
    00940 {
    00941
    00942   /* -- DF Type Selection -- */
    00943   switch (DF_DISK_SIZE)
    00944   {
    00945     case DF_SIZE_4MB:
    00946          return (s_format*)&df_tab_format[DF_4MB];
    00947     break;
    00948     case DF_SIZE_8MB:
    00949          return (s_format*)&df_tab_format[DF_8MB];
    00950     break;
    00951     case DF_SIZE_16MB:
    00952          return (s_format*)&df_tab_format[DF_16MB];
    00953     break;
    00954     case DF_SIZE_32MB:
    00955          return (s_format*)&df_tab_format[DF_32MB];
    00956     break;
    00957     default:
    00958     break;
    00959   }
    00960   return(NULL);
    00961 }
    00962