virtual_mem.c File Reference


Detailed Description

Management of the virtual memory.

This file manages the virtual memory.

Author:
Atmel Corporation: http://www.atmel.com
Support and FAQ: http://support.atmel.no/

Definition in file virtual_mem.c.

#include "conf_access.h"
#include "virtual_mem.h"
#include "usb_drv.h"
#include "scsi_decoder.h"
#include <string.h>

Go to the source code of this file.

Defines

#define VIRTUAL_MEM_TEST_CHANGE_STATE   ENABLED

Functions

static void virtual_check_init (void)
 This function initializes the memory.
Ctrl_status virtual_mem_2_ram (U32 addr, void *ram)
 This function tranfers 1 data sector from memory to RAM sector = 512 bytes.
Ctrl_status virtual_ram_2_mem (U32 addr, const void *ram)
 This function tranfers 1 data sector from memory to RAM sector = 512 bytes.
Ctrl_status virtual_read_capacity (U32 *u32_nb_sector)
 This function returns the address of the last valid sector.
Bool virtual_removal (void)
 This function informs about the memory type.
Ctrl_status virtual_test_unit_ready (void)
 This function tests memory state, and starts memory initialization.
Ctrl_status virtual_usb_read_10 (U32 addr, U16 nb_sector)
 This function transfers the memory data (programmed in sbc_read_10) directly to the USB interface sector = 512 bytes.
Ctrl_status virtual_usb_write_10 (U32 addr, U16 nb_sector)
 This function transfers the USB data (programmed in sbc_write_10) directly to the memory interface sector = 512 bytes.
Bool virtual_wr_protect (void)
 This function returns the write-protected mode Only used by memory removal with a HARDWARE-SPECIFIC write-protected detection.

Variables

static Bool cram_init = FALSE
static volatile Bool s_b_data_modify = FALSE
static U8 vmem_data [VMEM_NB_SECTOR *VMEM_SECTOR_SIZE]


Define Documentation

#define VIRTUAL_MEM_TEST_CHANGE_STATE   ENABLED

Definition at line 60 of file virtual_mem.c.


Function Documentation

static void virtual_check_init ( void   )  [static]

This function initializes the memory.

Definition at line 79 of file virtual_mem.c.

References cram_init, FAT_SECTOR, PBR_SECTOR, VMEM_CLUSTER_SIZE, vmem_data, VMEM_MEDIA_TYPE, VMEM_NB_FATS, VMEM_NB_HEAD, VMEM_NB_HIDDEN_SECT, VMEM_NB_ROOT_ENTRY, VMEM_NB_SECTOR, VMEM_RESERVED_SIZE, VMEM_SECT_PER_TRACK, VMEM_SECTOR_SIZE, VMEM_SIZE_FAT, and VMEN_DRIVE_NUMBER.

Referenced by virtual_mem_2_ram(), virtual_ram_2_mem(), virtual_read_capacity(), virtual_test_unit_ready(), virtual_usb_read_10(), and virtual_usb_write_10().

00080 {
00081   U8 i;
00082 
00083   if (cram_init) return;
00084 
00085   // PBR sector init
00086   // Offset 0
00087   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +   0] = 0xEB;  // JMP inst to PBR boot code
00088   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +   1] = 0x3C;
00089   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +   2] = 0x90;
00090 
00091   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +   3] = 'A'; // OEM name
00092   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +   4] = 'T';
00093   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +   5] = 'M';
00094   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +   6] = 'E';
00095   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +   7] = 'L';
00096   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +   8] = ' ';
00097   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +   9] = ' ';
00098   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  10] = ' ';
00099 
00100   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  11] = (U8)VMEM_SECTOR_SIZE;            // Bytes per sector
00101   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  12] = VMEM_SECTOR_SIZE >> 8;
00102   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  13] = VMEM_CLUSTER_SIZE;               // Sectors per cluster
00103   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  14] = (U8)VMEM_RESERVED_SIZE;          // Number of reserved sectors
00104   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  15] = VMEM_RESERVED_SIZE >> 8;
00105   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  16] = VMEM_NB_FATS;                    // Number of FATs
00106   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  17] = (U8)VMEM_NB_ROOT_ENTRY;          // Number of root directory entries
00107   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  18] = VMEM_NB_ROOT_ENTRY >> 8;
00108   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  19] = (U8)VMEM_NB_SECTOR;
00109   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  20] = VMEM_NB_SECTOR >> 8;
00110   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  21] = VMEM_MEDIA_TYPE;                 // Media type
00111   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  22] = (U8)VMEM_SIZE_FAT;               // FAT size
00112   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  23] = VMEM_SIZE_FAT >> 8;
00113   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  24] = (U8)VMEM_SECT_PER_TRACK;         // Sectors per track
00114   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  25] = VMEM_SECT_PER_TRACK >> 8;
00115   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  26] = (U8)VMEM_NB_HEAD;                // Number of heads
00116   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  27] = VMEM_NB_HEAD >> 8;
00117   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  28] = (U8)VMEM_NB_HIDDEN_SECT;         // Number of hidden sectors
00118   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  29] = (U8)(VMEM_NB_HIDDEN_SECT >> 8);
00119   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  30] = (U8)(VMEM_NB_HIDDEN_SECT >> 16);
00120   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  31] = VMEM_NB_HIDDEN_SECT >> 24;
00121   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  32] = 0x00;                            // Number of sectors for FAT 32 only
00122   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  33] = 0x00;
00123   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  34] = 0x00;
00124   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  35] = 0x00;
00125   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  36] = VMEN_DRIVE_NUMBER;               // Driver number
00126   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  37] = 0x00;                            // Reserved (it must be 0x00, set to 0x01 by Windows after error)
00127   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  38] = 0x29;                            // Extended boot signature
00128   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  39] = 0x00;                            // Volume ID
00129   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  40] = 0x00;
00130   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  41] = 0x00;
00131   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  42] = 0x00;
00132 
00133   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  43] = 'V'; // Volume Label
00134   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  44] = 'I';
00135   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  45] = 'R';
00136   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  46] = 'T';
00137   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  47] = 'U';
00138   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  48] = 'A';
00139   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  49] = 'L';
00140   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  50] = ' ';
00141   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  51] = 'M';
00142   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  52] = 'E';
00143   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  53] = 'M';
00144 
00145   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  54] = 'F'; // File System Type in ASCII
00146   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  55] = 'A';
00147   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  56] = 'T';
00148   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  57] = '1';
00149   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  58] = '2';
00150   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  59] = ' ';
00151   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  60] = ' ';
00152   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE +  61] = ' ';
00153 
00154   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE + 510] = 0x55;
00155   vmem_data[PBR_SECTOR * VMEM_SECTOR_SIZE + 511] = 0xAA;
00156   // End of PBR
00157 
00158   for (i = 0; i < VMEM_NB_FATS; i++)
00159   {
00160     // FAT sector init
00161     vmem_data[(FAT_SECTOR + i * VMEM_SIZE_FAT) * VMEM_SECTOR_SIZE + 0] = 0xF8;
00162     vmem_data[(FAT_SECTOR + i * VMEM_SIZE_FAT) * VMEM_SECTOR_SIZE + 1] = 0xFF;
00163     vmem_data[(FAT_SECTOR + i * VMEM_SIZE_FAT) * VMEM_SECTOR_SIZE + 2] = 0xFF;  // Other sectors set to 0x00
00164   }
00165 
00166   cram_init = TRUE;
00167 }

Ctrl_status virtual_mem_2_ram ( U32  addr,
void *  ram 
)

This function tranfers 1 data sector from memory to RAM sector = 512 bytes.

Parameters:
addr Sector address to start read
ram Address of RAM buffer
Returns:
Ctrl_status It is ready -> CTRL_GOOD Memory unplug -> CTRL_NO_PRESENT Not initialized or changed -> CTRL_BUSY An error occurred -> CTRL_FAIL

Definition at line 330 of file virtual_mem.c.

References virtual_check_init(), vmem_data, VMEM_NB_SECTOR, and VMEM_SECTOR_SIZE.

00331 {
00332   virtual_check_init();
00333   if (addr + 1 > Max(VMEM_NB_SECTOR, 8)) return CTRL_FAIL;
00334 
00335   // If overflow (possible with size virtual mem < 8 sectors) then read the last sector
00336   addr = min(addr, VMEM_NB_SECTOR - 1);
00337 
00338   memcpy(ram, &vmem_data[addr * VMEM_SECTOR_SIZE], VMEM_SECTOR_SIZE);
00339 
00340   return CTRL_GOOD;
00341 }

Ctrl_status virtual_ram_2_mem ( U32  addr,
const void *  ram 
)

This function tranfers 1 data sector from memory to RAM sector = 512 bytes.

Parameters:
addr Sector address to start write
ram Address of RAM buffer
Returns:
Ctrl_status It is ready -> CTRL_GOOD Memory unplug -> CTRL_NO_PRESENT Not initialized or changed -> CTRL_BUSY An error occurred -> CTRL_FAIL

Definition at line 353 of file virtual_mem.c.

References FILE_SECTOR, s_b_data_modify, virtual_check_init(), vmem_data, VMEM_NB_SECTOR, and VMEM_SECTOR_SIZE.

00354 {
00355   virtual_check_init();
00356   if (addr + 1 > VMEM_NB_SECTOR) return CTRL_FAIL;
00357 
00358 #if VIRTUAL_MEM_TEST_CHANGE_STATE == ENABLED
00359   if (addr + 1 > FILE_SECTOR && addr <= FILE_SECTOR)
00360     s_b_data_modify = TRUE;
00361 #endif
00362 
00363   memcpy(&vmem_data[addr * VMEM_SECTOR_SIZE], ram, VMEM_SECTOR_SIZE);
00364 
00365   return CTRL_GOOD;
00366 }

Ctrl_status virtual_read_capacity ( U32 *  u32_nb_sector  ) 

This function returns the address of the last valid sector.

Parameters:
u32_nb_sector Pointer to number of sectors (sector = 512 bytes)
Returns:
Ctrl_status It is ready -> CTRL_GOOD Memory unplug -> CTRL_NO_PRESENT Not initialized or changed -> CTRL_BUSY An error occurred -> CTRL_FAIL

Definition at line 191 of file virtual_mem.c.

References virtual_check_init(), and VMEM_NB_SECTOR.

00192 {
00193   virtual_check_init();
00194   *u32_nb_sector = Max(VMEM_NB_SECTOR, 8) - 1;
00195 
00196   return CTRL_GOOD;
00197 }

Bool virtual_removal ( void   ) 

This function informs about the memory type.

Returns:
TRUE if the memory is removable

Definition at line 212 of file virtual_mem.c.

00213 {
00214   return FALSE;
00215 }

Ctrl_status virtual_test_unit_ready ( void   ) 

This function tests memory state, and starts memory initialization.

Returns:
Ctrl_status It is ready -> CTRL_GOOD Memory unplug -> CTRL_NO_PRESENT Not initialized or changed -> CTRL_BUSY An error occurred -> CTRL_FAIL

Definition at line 176 of file virtual_mem.c.

References virtual_check_init().

00177 {
00178   virtual_check_init();
00179 
00180   return CTRL_GOOD;
00181 }

Ctrl_status virtual_usb_read_10 ( U32  addr,
U16  nb_sector 
)

This function transfers the memory data (programmed in sbc_read_10) directly to the USB interface sector = 512 bytes.

Parameters:
addr Sector address to start read
nb_sector Number of sectors to transfer
Returns:
Ctrl_status It is ready -> CTRL_GOOD Memory unplug -> CTRL_NO_PRESENT Not initialized or changed -> CTRL_BUSY An error occurred -> CTRL_FAIL

Definition at line 234 of file virtual_mem.c.

References data_to_transfer, g_scsi_ep_ms_in, virtual_check_init(), vmem_data, VMEM_NB_SECTOR, and VMEM_SECTOR_SIZE.

00235 {
00236   const void *ptr_cram;
00237   U16 data_to_transfer;
00238 
00239   virtual_check_init();
00240   if (addr + nb_sector > Max(VMEM_NB_SECTOR, 8)) return CTRL_FAIL;
00241 
00242   while (nb_sector--)
00243   {
00244     // If overflow (possible with size virtual mem < 8 sectors) then read the last sector
00245     addr = min(addr, VMEM_NB_SECTOR - 1);
00246 
00247     ptr_cram = &vmem_data[addr++ * VMEM_SECTOR_SIZE];
00248     data_to_transfer = VMEM_SECTOR_SIZE;
00249     while (data_to_transfer)
00250     {
00251       while (!Is_usb_in_ready(g_scsi_ep_ms_in))
00252       {
00253          if(!Is_usb_endpoint_enabled(g_scsi_ep_ms_in))
00254             return CTRL_FAIL; // USB Reset
00255       }         
00256 
00257       Usb_reset_endpoint_fifo_access(g_scsi_ep_ms_in);
00258       data_to_transfer = usb_write_ep_txpacket(g_scsi_ep_ms_in, ptr_cram,
00259                                                data_to_transfer, &ptr_cram);
00260       Usb_ack_in_ready_send(g_scsi_ep_ms_in);
00261     }
00262   }
00263 
00264   return CTRL_GOOD;
00265 }

Ctrl_status virtual_usb_write_10 ( U32  addr,
U16  nb_sector 
)

This function transfers the USB data (programmed in sbc_write_10) directly to the memory interface sector = 512 bytes.

Parameters:
addr Sector address to start write
nb_sector Number of sectors to transfer
Returns:
Ctrl_status It is ready -> CTRL_GOOD Memory unplug -> CTRL_NO_PRESENT Not initialized or changed -> CTRL_BUSY An error occurred -> CTRL_FAIL

Definition at line 277 of file virtual_mem.c.

References data_to_transfer, FILE_SECTOR, g_scsi_ep_ms_out, s_b_data_modify, virtual_check_init(), vmem_data, VMEM_NB_SECTOR, and VMEM_SECTOR_SIZE.

00278 {
00279   void *ptr_cram;
00280   U16 data_to_transfer;
00281 
00282   virtual_check_init();
00283   if (addr + nb_sector > VMEM_NB_SECTOR) return CTRL_FAIL;
00284 
00285 #if VIRTUAL_MEM_TEST_CHANGE_STATE == ENABLED
00286   if (addr + nb_sector > FILE_SECTOR && addr <= FILE_SECTOR)
00287     s_b_data_modify = TRUE;
00288 #endif
00289 
00290   ptr_cram = &vmem_data[addr * VMEM_SECTOR_SIZE];
00291   while (nb_sector--)
00292   {
00293     data_to_transfer = VMEM_SECTOR_SIZE;
00294     while (data_to_transfer)
00295     {
00296       while (!Is_usb_out_received(g_scsi_ep_ms_out))
00297       {
00298          if(!Is_usb_endpoint_enabled(g_scsi_ep_ms_out))
00299             return CTRL_FAIL; // USB Reset
00300       }         
00301 
00302       Usb_reset_endpoint_fifo_access(g_scsi_ep_ms_out);
00303       data_to_transfer = usb_read_ep_rxpacket(g_scsi_ep_ms_out, ptr_cram,
00304                                               data_to_transfer, &ptr_cram);
00305       Usb_ack_out_received_free(g_scsi_ep_ms_out);
00306     }
00307   }
00308 
00309   return CTRL_GOOD;
00310 }

Bool virtual_wr_protect ( void   ) 

This function returns the write-protected mode Only used by memory removal with a HARDWARE-SPECIFIC write-protected detection.

Warning:
The customer must unplug the memory to change this write-protected mode.
Returns:
TRUE if the memory is protected

Definition at line 204 of file virtual_mem.c.

00205 {
00206   return FALSE;
00207 }


Variable Documentation

Bool cram_init = FALSE [static]

Definition at line 70 of file virtual_mem.c.

Referenced by virtual_check_init().

volatile Bool s_b_data_modify = FALSE [static]

Definition at line 72 of file virtual_mem.c.

Referenced by virtual_ram_2_mem(), and virtual_usb_write_10().

U8 vmem_data[VMEM_NB_SECTOR *VMEM_SECTOR_SIZE] [static]


Generated on Fri Feb 19 02:33:39 2010 for AVR32 - USB Mass-Storage on FreeRTOS Example by  doxygen 1.5.5