Compact Flash I/O test

Dependencies:   mbed

Revision:
1:dc171f34db9b
Parent:
0:6b1e6c9e48ba
diff -r 6b1e6c9e48ba -r dc171f34db9b FAT_FS/diskio.c
--- a/FAT_FS/diskio.c	Tue Dec 27 02:03:56 2011 +0000
+++ b/FAT_FS/diskio.c	Fri Dec 30 21:02:16 2011 +0000
@@ -3,8 +3,29 @@
 #include "integer.h"
 #include "diskio.h"
 #include "stdarg.h"
+#include "usbhost_inc.h"
 
-#define _CF_DEBUG_MESSAGES
+
+/*--------------------------------------------------------------------------
+
+   Module Private Functions
+
+---------------------------------------------------------------------------*/
+
+static volatile DSTATUS Stat[3] = {STA_NOINIT | STA_NODISK};    /* Disk status */
+static volatile BYTE DiskProcTimer[3]={0};            /* 100Hz decrement timer */
+
+
+BYTE RAM_DISK[512];
+
+
+//Usb Stuff
+uint32_t _numBlks;
+uint32_t _blkSize;
+USB_INT08U  inquiryResult[INQUIRY_LENGTH];  
+
+
+//#define _CF_DEBUG_MESSAGES
 //#define _CF_DEBUG_READ_ATA
 
 #ifdef _CF_DEBUG_MESSAGES 
@@ -12,11 +33,9 @@
 #else
    #define  CF_DEBUG     
 #endif
-            
 
 void disk_timerproc (void);
 
-
 #define LED1_MASK  (uint32_t )(1<<18)
 #define LED2_MASK  (uint32_t )(1<<20)
 #define LED3_MASK  (uint32_t )(1<<21)
@@ -106,57 +125,39 @@
 #define SET_DATA_BUS_AS_OUTPUTS       LPC_GPIO0->FIODIR|=DATA_BUS_MASK
 #define SET_DATA_BUS_AS_INPUTS        LPC_GPIO0->FIODIR&=~DATA_BUS_MASK
 
-
-
 /* ATA command */
 #define CMD_RESET        0x08    /* DEVICE RESET */
-#define CMD_READ        0x20    /* READ SECTOR(S) */
+#define CMD_READ         0x20    /* READ SECTOR(S) */
 #define CMD_WRITE        0x30    /* WRITE SECTOR(S) */
-#define CMD_IDENTIFY    0xEC    /* DEVICE IDENTIFY */
-#define CMD_SETFEATURES    0xEF    /* SET FEATURES */
+#define CMD_IDENTIFY     0xEC    /* DEVICE IDENTIFY */
+#define CMD_SETFEATURES  0xEF    /* SET FEATURES */
 
 /* ATA register bit definitions */
 #define    LBA             0xE0
 #define    BUSY            0x80
 #define    DRDY            0x40
-#define    DF                0x20
-#define    DRQ                0x08
-#define    ERR                0x01
+#define    DF              0x20
+#define    DRQ             0x08
+#define    ERR             0x01
 #define    SRST            0x40
 #define    nIEN            0x20
 
 /* Bit definitions for Control Port */
 #define    CTL_READ        0x20
-#define    CTL_WRITE        0x40
-#define    CTL_RESET        0x80
+#define    CTL_WRITE       0x40
+#define    CTL_RESET       0x80
 #define    REG_DATA        0x0
-#define    REG_ERROR        0x1
+#define    REG_ERROR       0x1
 #define    REG_FEATURES    0x1
-#define    REG_COUNT        0x2
-#define    REG_SECTOR        0x3
+#define    REG_COUNT       0x2
+#define    REG_SECTOR      0x3
 #define    REG_CYLL        0x4
 #define    REG_CYLH        0x5
-#define    REG_DEV            0x6
-#define    REG_COMMAND        0x7
-#define    REG_STATUS        0x7
-#define    REG_DEVCTRL        0xE
-#define    REG_ALTSTAT        0xE
-
-
-
-/*--------------------------------------------------------------------------
-
-   Module Private Functions
-
----------------------------------------------------------------------------*/
-
-static volatile
-DSTATUS Stat = STA_NOINIT;    /* Disk status */
-
-static volatile
-BYTE DiskProcTimer;            /* 100Hz decrement timer */
-
-
+#define    REG_DEV         0x6
+#define    REG_COMMAND     0x7
+#define    REG_STATUS      0x7
+#define    REG_DEVCTRL     0xE
+#define    REG_ALTSTAT     0xE
 
 void InitCompactFlashInterface()
 {
@@ -176,38 +177,6 @@
     NVIC_SetVector(SysTick_IRQn, (uint32_t)(&disk_timerproc));
 }
 
-
-void  CompactFlashIO_Test()
-{
-
-    SET_DATA_BUS_AS_OUTPUTS;
-    while(1)
-    {
-         
-        wait(0.1);
-        COMPACT_FLASH_RESET_ACTIVE;
-        COMPACT_FLASH_POWER_ENABLE;
-        IOWR_ACTIVE;  
-        IORD_ACTIVE;
-        CS0_ACTIVE; 
-        CS1_ACTIVE;
-        SET_CF_ADDRESS(0x04);
-        SET_CF_DATA(0x80); 
-     
-        wait(0.1);
-        COMPACT_FLASH_RESET_INACTIVE;
-        COMPACT_FLASH_POWER_DISABLE;
-        IOWR_INACTIVE;  
-        IORD_INACTIVE;
-        CS0_INACTIVE;  
-        CS1_ACTIVE;
-        SET_CF_ADDRESS(0x00);
-        SET_CF_DATA(0x00);   
-    }
-}
-
-
-
 /*-----------------------------------------------------------------------*/
 /* Read an ATA register                                                  */
 /*-----------------------------------------------------------------------*/
@@ -218,8 +187,7 @@
 )
 {
     BYTE rd;
-    DWORD i;
-     
+ 
     CS0_ACTIVE; 
     SET_DATA_BUS_AS_INPUTS;
     SET_CF_ADDRESS(reg); 
@@ -254,7 +222,7 @@
     BYTE dat        /* Data to be written */
 )
 {
-    DWORD i;
+   
     __nop();
     CS0_ACTIVE; 
     SET_DATA_BUS_AS_OUTPUTS;
@@ -288,7 +256,6 @@
 )
 {
     BYTE c = 0, dl, dh;
-    DWORD i;
     
     SET_CF_ADDRESS(REG_DATA);        /* Select Data register */
     __nop();
@@ -343,9 +310,9 @@
 {
     BYTE s;
 
-    DiskProcTimer = 100;    /* Time out = 1 sec */
+    DiskProcTimer[CF] = 100;    /* Time out = 1 sec */
     do {
-        if (!DiskProcTimer) return 0;            /* Abort when timeout occured */
+        if (!DiskProcTimer[CF]) return 0;            /* Abort when timeout occured */
         s = read_ata(REG_STATUS);        /* Get status */
     } while ((s & (BUSY|DRQ)) != DRQ);    /* Wait for BUSY goes low and DRQ goes high */
 
@@ -356,75 +323,115 @@
 
 
 
-
 /*-----------------------------------------------------------------------*/
 /* Initialize Disk Drive                                                 */
 /*-----------------------------------------------------------------------*/
 
 DSTATUS disk_initialize (
-    BYTE drv        /* Physical drive nmuber (0) */
+    BYTE drv        /* Physical drive number (0) */
 )
 {
-    if (drv) return STA_NOINIT;                /* Supports only single drive */
-
-    Stat |= STA_NOINIT;
-
-    for (DiskProcTimer = 10; DiskProcTimer; );                /* 100ms */
-
-    if (Stat & STA_NODISK) return Stat;        /* Exit when socket is empty */
-
-    /* Initialize CFC control port */
-    COMPACT_FLASH_POWER_ENABLE;
-    
-    for (DiskProcTimer = 1;DiskProcTimer; );                /* 10ms */
-    
-    SET_DATA_BUS_AS_INPUTS;
-    for (DiskProcTimer = 5; DiskProcTimer; );                /* 50ms */
-    COMPACT_FLASH_RESET_INACTIVE;
-    for (DiskProcTimer = 5; DiskProcTimer; );                /* 50ms */
-    write_ata(REG_DEV, LBA);                /* Select Device 0 */
-    DiskProcTimer = 200;
-    do {                                    /* Wait for card goes ready */
-        if (!DiskProcTimer) 
-        {
-            CF_DEBUG("Timeout waiting for card BUSY to go inactive\r\n");
-            return Stat;
-        }
-    } while (read_ata(REG_STATUS) & BUSY);
+    DSTATUS RetVal;
+    USB_INT32S  rc;
+  
+    switch(drv)
+    {
+        case COMPACT_FLASH:
+                 
+              Stat[CF] |= STA_NOINIT;
+              for (DiskProcTimer[CF] = 10; DiskProcTimer[CF]; );                /* 100ms */
+              if (Stat[CF] & STA_NODISK) return Stat[CF];        /* Exit when socket is empty */
+              COMPACT_FLASH_POWER_ENABLE;     /* Initialize CFC control port */
+              for (DiskProcTimer[CF] = 1;DiskProcTimer[CF]; );                /* 10ms */
+         
+              SET_DATA_BUS_AS_INPUTS;
+              for (DiskProcTimer[CF] = 5; DiskProcTimer[CF]; );                /* 50ms */
+              COMPACT_FLASH_RESET_INACTIVE;
+              for (DiskProcTimer[CF] = 5; DiskProcTimer[CF]; );                /* 50ms */
+              write_ata(REG_DEV, LBA);                /* Select Device 0 */
+              DiskProcTimer[CF] = 200;
+                             
+                do {                                    /* Wait for card goes ready */
+                    if (!DiskProcTimer[CF]) 
+                    {
+                        CF_DEBUG("Timeout waiting for card BUSY to go inactive\r\n");
+                        return Stat[CF];
+                    }
+                } while (read_ata(REG_STATUS) & BUSY);
+      
+      
+                write_ata(REG_DEVCTRL, SRST | nIEN);    /* Software reset */
+                for (DiskProcTimer[CF] = 2; DiskProcTimer[CF]; );                /* 20ms */
+                
+                write_ata(REG_DEVCTRL, nIEN);            /* Release software reset */
+                
+                for (DiskProcTimer[CF] = 2; DiskProcTimer[CF]; );                /* 20ms */
+                
+                DiskProcTimer[CF] = 200;
+                do {                                    /* Wait for card goes ready */
+                    if (!DiskProcTimer[CF])
+                    {
+                        CF_DEBUG("Timeout waiting for card DRDY\r\n");
+                        return Stat[CF];
+                     }
+                } while ((read_ata(REG_STATUS) & (DRDY|BUSY)) != DRDY);
+                
+                CF_DEBUG("Setting to 8-bit PIO MOD\r\n");
+                write_ata(REG_FEATURES, 0x01);            /* Select 8-bit PIO transfer mode */
+                write_ata(REG_COMMAND, CMD_SETFEATURES);
+                DiskProcTimer[CF] = 200;
+                do {
+                    if (!DiskProcTimer[CF])
+                    {
+                        CF_DEBUG("Timeout waiting after trying to call the SETFEATURES command\r\n");
+                        return Stat[CF];
+                    }
+                     
+                } while (read_ata(REG_STATUS) & (BUSY | ERR));
+            
+                Stat[CF] &= ~STA_NOINIT;                    /* When device goes ready, clear STA_NOINIT */
+            
+                RetVal = Stat[CF];
+      
+        break;
+        
+        case USB:
+        
+                Host_Init();
+                if(!Host_EnumDev())
+                {
+              
+                    rc = MS_Init( &_blkSize, &_numBlks, inquiryResult );
+                    if (rc != OK)
+                    {
+                        TERMINAL_PRINTF("Could not initialize mass storage interface: %d\r\n", rc);
+                        Stat[USB] |= STA_NOINIT;
+                    }
+                    else
+                    {
+                         Stat[USB] &= ~STA_NOINIT;
+                    }
+                }
+                else
+                {
+                     Stat[USB] |= STA_NOINIT;
+                }
+                 
+                  RetVal = Stat[USB];
+        break;
+        
+        
+        case RAM:
+             Stat[RAM] &= ~STA_NOINIT;
+              RetVal = Stat[RAM];
+        break; 
+        
+        default:
+             RetVal = STA_NOINIT;
+        break;
+    }
 
-    write_ata(REG_DEVCTRL, SRST | nIEN);    /* Software reset */
-    for (DiskProcTimer = 2; DiskProcTimer; );                /* 20ms */
-    write_ata(REG_DEVCTRL, nIEN);            /* Release software reset */
-    for (DiskProcTimer = 2; DiskProcTimer; );                /* 20ms */
-    DiskProcTimer = 200;
-    do {                                    /* Wait for card goes ready */
-        if (!DiskProcTimer)
-        {
-            CF_DEBUG("Timeout waiting for card DRDY\r\n");
-            return Stat;
-         }
-    } while ((read_ata(REG_STATUS) & (DRDY|BUSY)) != DRDY);
-
-    
-    
-    
-    CF_DEBUG("Setting to 8-bit PIO MOD\r\n");
-    write_ata(REG_FEATURES, 0x01);            /* Select 8-bit PIO transfer mode */
-    write_ata(REG_COMMAND, CMD_SETFEATURES);
-    DiskProcTimer = 100;
-    do {
-        wait(.25);
-        if (!DiskProcTimer)
-        {
-            CF_DEBUG("Timeout waiting after trying to call the SETFEATURES command\r\n");
-            return Stat;
-        }
-         
-    } while (read_ata(REG_STATUS) & (BUSY | ERR));
-
-    Stat &= ~STA_NOINIT;                    /* When device goes ready, clear STA_NOINIT */
-
-    return Stat;
+    return RetVal;
 }
 
 
@@ -434,11 +441,32 @@
 /*-----------------------------------------------------------------------*/
 
 DSTATUS disk_status (
-    BYTE drv        /* Physical drive nmuber (0) */
+    BYTE drv     
 )
 {
-    if (drv) return STA_NOINIT;        /* Supports only single drive */
-    return Stat;
+    DSTATUS RetVal;
+    
+    switch(drv)
+    {
+        case CF:
+             RetVal = Stat[CF];
+        break;
+        
+        
+        case USB:
+           RetVal = Stat[USB];
+        break;
+        
+        case RAM:
+           RetVal = Stat[RAM];
+        break;
+        
+        default:
+             RetVal = STA_NOINIT; 
+        break;
+    }
+    
+    return  RetVal;
 }
 
 
@@ -455,83 +483,104 @@
 )
 {
     BYTE c;
-    DWORD i;
-    
-    
-    if (drv || !count) return RES_PARERR;
-    if (Stat & STA_NOINIT) return RES_NOTRDY;
-
-    /* Issue Read Setor(s) command */
-    write_ata(REG_COUNT, count);
-    write_ata(REG_SECTOR, (BYTE)sector);
-    write_ata(REG_CYLL, (BYTE)(sector >> 8));
-    write_ata(REG_CYLH, (BYTE)(sector >> 16));
-    write_ata(REG_DEV, ((BYTE)(sector >> 24) & 0x0F) | LBA);
-    write_ata(REG_COMMAND, CMD_READ);
-
-
-    do {
-        if (!wait_data()) return RES_ERROR;    /* Wait data ready */
-       
-    
-        SET_CF_ADDRESS(REG_DATA);
-         __nop();
-        __nop();
-        __nop();
-        __nop();
-          CS0_ACTIVE;
-         c = 0;
-       
-          __nop();
-         __nop();
-        __nop();
+    DWORD i,j;
     
-        SET_DATA_BUS_AS_INPUTS;
-        do {
-            IORD_ACTIVE;        /* IORD = L */
-             __nop();
-            __nop();
-            __nop();
-                GET_CF_DATA(*buff++);        /* Get even data */
-          __nop();
-        __nop();
-        __nop();
-    
-          __nop();
-         __nop();
-        __nop();
+    switch(drv)
+    {
+        case CF:
+              if (Stat[CF] & STA_NOINIT) return RES_NOTRDY;
 
-            IORD_INACTIVE;        /* IORD = H */
-        __nop();
-        __nop();
-        __nop();
- 
-            IORD_ACTIVE;        /* IORD = L */
-           __nop();
-        __nop();
-        __nop();
-
-            GET_CF_DATA(*buff++);    /* Get Odd data */
-          __nop();
-        __nop();
-        __nop();
-
-        __nop();
-            IORD_INACTIVE;            /* IORD = H */
-     __nop();
-        __nop();
-        __nop();
-  
-           
-        } while (--c);
-    } while (--count);
-
-    CS0_INACTIVE;
-    read_ata(REG_ALTSTAT);
-    read_ata(REG_STATUS);
-
-
-    return RES_OK;
+                /* Issue Read Setor(s) command */
+                write_ata(REG_COUNT, count);
+                write_ata(REG_SECTOR, (BYTE)sector);
+                write_ata(REG_CYLL, (BYTE)(sector >> 8));
+                write_ata(REG_CYLH, (BYTE)(sector >> 16));
+                write_ata(REG_DEV, ((BYTE)(sector >> 24) & 0x0F) | LBA);
+                write_ata(REG_COMMAND, CMD_READ);
+                
+                 do {
+                         if (!wait_data()) return RES_ERROR;    /* Wait data ready */
+                   
+                                SET_CF_ADDRESS(REG_DATA);
+                                __nop();
+                                __nop();
+                                __nop();
+                                __nop();
+                               CS0_ACTIVE;
+                               c = 0;
+                               
+                                __nop();
+                                __nop();
+                               __nop();
+                            
+                                SET_DATA_BUS_AS_INPUTS;
+                                do {
+                                        IORD_ACTIVE;        /* IORD = L */
+                                        __nop();
+                                        __nop();
+                                        __nop();
+                                        GET_CF_DATA(*buff++);        /* Get even data */
+                                        __nop();
+                                        __nop();
+                                        __nop();
+                                    
+                                        __nop();
+                                        __nop();
+                                        __nop();
+                                
+                                        IORD_INACTIVE;        /* IORD = H */
+                                        __nop();
+                                        __nop();
+                                        __nop();
+                                 
+                                        IORD_ACTIVE;        /* IORD = L */
+                                        __nop();
+                                        __nop();
+                                        __nop();
+                                
+                                        GET_CF_DATA(*buff++);    /* Get Odd data */
+                                        __nop();
+                                        __nop();
+                                        __nop();
+                                
+                                        __nop();
+                                        IORD_INACTIVE;            /* IORD = H */
+                                        __nop();
+                                        __nop();
+                                        __nop();
+                                 
+                                           
+                                        } while (--c);
+                        } while (--count);
+            
+                CS0_INACTIVE;
+                read_ata(REG_ALTSTAT);
+                read_ata(REG_STATUS);
+                
+                return RES_OK;
+        break;
+        
+        
+        case USB:
+        
+         if ( OK == MS_BulkRecv(sector, 1, (USB_INT08U *)buff) )
+             return RES_OK;
+         else
+             return  RES_NOTRDY;
+        break;
+        
+        case RAM:
+                for(i=0;i<512;i++)
+                {
+                    buff[i] = RAM_DISK[i];
+                }
+             return RES_OK;
+        break;
+        
+        default:
+             return RES_PARERR;
+        break;
+    }
 }
 
 
@@ -548,84 +597,112 @@
 {
     BYTE s, c;
     DWORD i;
-    
-    if (drv || !count) return RES_PARERR;
-    if (Stat & STA_NOINIT) return RES_NOTRDY;
-
-    /* Issue Write Setor(s) command */
-    write_ata(REG_COUNT, count);
-    write_ata(REG_SECTOR, (BYTE)sector);
-    write_ata(REG_CYLL, (BYTE)(sector >> 8));
-    write_ata(REG_CYLH, (BYTE)(sector >> 16));
-    write_ata(REG_DEV, ((BYTE)(sector >> 24) & 0x0F) | LBA);
-    write_ata(REG_COMMAND, CMD_WRITE);
-
-
-
-    do {
-        if (!wait_data()) return RES_ERROR;
+    DRESULT RetVal;
       
-        SET_CF_ADDRESS(REG_DATA);
-         __nop();
-         __nop();
-         __nop();
-        CS0_ACTIVE;
-        __nop();
-         __nop();
-         __nop();
-    
-        SET_DATA_BUS_AS_OUTPUTS;
-        c = 0;
-        do {
-            SET_CF_DATA(*buff++);    /* Set even data */
-            __nop();
-            __nop();
-            __nop();
-
-            IOWR_ACTIVE;        /* IOWR = L */
-            __nop();
-            __nop();
-            __nop();
+    switch(drv)
+    {
+        case CF:
+                 /* Issue Write Setor(s) command */
+                write_ata(REG_COUNT, count);
+                write_ata(REG_SECTOR, (BYTE)sector);
+                write_ata(REG_CYLL, (BYTE)(sector >> 8));
+                write_ata(REG_CYLH, (BYTE)(sector >> 16));
+                write_ata(REG_DEV, ((BYTE)(sector >> 24) & 0x0F) | LBA);
+                write_ata(REG_COMMAND, CMD_WRITE);
+                
+                 do {
+                        if (!wait_data()) return RES_ERROR;
+                      
+                        SET_CF_ADDRESS(REG_DATA);
+                        __nop();
+                         __nop();
+                         __nop();
+                        CS0_ACTIVE;
+                        __nop();
+                         __nop();
+                         __nop();
+                    
+                        SET_DATA_BUS_AS_OUTPUTS;
+                        c = 0;
+                        do {
+                            SET_CF_DATA(*buff++);    /* Set even data */
+                            __nop();
+                            __nop();
+                            __nop();
+                
+                            IOWR_ACTIVE;        /* IOWR = L */
+                            __nop();
+                            __nop();
+                            __nop();
+                
+                            IOWR_INACTIVE;        /* IOWR = H */
+                            __nop();
+                            __nop();
+                            __nop();
+                    
+                            SET_CF_DATA(*buff++);    /* Set odd data */
+                            __nop();
+                            __nop();
+                            __nop();
+                 
+                            IOWR_ACTIVE;        /* IOWR = L */
+                            __nop();
+                            __nop();
+                            __nop();
+                
+                            IOWR_INACTIVE;        /* IOWR = H */
+                            __nop();
+                            __nop();
+                            __nop();
+                            } while (--c);
+                 
+                    } while (--count);
+                      
+                       SET_DATA_BUS_AS_INPUTS;
+                       CS0_INACTIVE;
+                
+                    DiskProcTimer[CF] = 100;
+                    do {
+                        if (!DiskProcTimer[CF]) return RES_ERROR;
+                        s = read_ata(REG_STATUS);
+                    } while (s & BUSY);
+                    if (s & ERR) return RES_ERROR;
+                
+                    read_ata(REG_ALTSTAT);
+                    read_ata(REG_STATUS);
 
-            IOWR_INACTIVE;        /* IOWR = H */
-            __nop();
-            __nop();
-            __nop();
-    
-            SET_CF_DATA(*buff++);    /* Set odd data */
-            __nop();
-            __nop();
-            __nop();
- 
-            IOWR_ACTIVE;        /* IOWR = L */
-            __nop();
-            __nop();
-            __nop();
-
-            IOWR_INACTIVE;        /* IOWR = H */
-            __nop();
-            __nop();
-            __nop();
+                RetVal = RES_OK;
+        break;
+        
+        
+        case USB:
+            if ( OK == MS_BulkSend(sector, 1, (USB_INT08U *)buff) )
+               RetVal = RES_OK;
+            else;
+               RetVal =  RES_NOTRDY;
+        break;
+        
+        case RAM:
+          
+                for(i=0;i<512;i++)
+                {
+                     RAM_DISK[i] = buff[i];
+                }
+              RetVal =  RES_OK;
+         
+        break;
+        
+        default:
+              RetVal = RES_PARERR;
+        break;
+        
+        return RetVal;
+    }
 
-        } while (--c);
+ }   
  
-    } while (--count);
-       SET_DATA_BUS_AS_INPUTS;
-        CS0_INACTIVE;
-
-    DiskProcTimer = 100;
-    do {
-        if (!DiskProcTimer) return RES_ERROR;
-        s = read_ata(REG_STATUS);
-    } while (s & BUSY);
-    if (s & ERR) return RES_ERROR;
-
-    read_ata(REG_ALTSTAT);
-    read_ata(REG_STATUS);
-
-    return RES_OK;
-}
-
+  
+   
 
 /*-----------------------------------------------------------------------*/
 /* Miscellaneous Functions                                               */
@@ -638,45 +715,136 @@
 )
 {
     BYTE n, w, ofs, dl, dh, *ptr = (BYTE *)buff;
-
-
-    if (drv) return RES_PARERR;
-    if (Stat & STA_NOINIT) return RES_NOTRDY;
-
-    switch (ctrl) {
-        case GET_SECTOR_COUNT :    /* Get number of sectors on the disk (DWORD) */
-            ofs = 60; w = 2; n = 0;
-            break;
-
-        case GET_BLOCK_SIZE :    /* Get erase block size in sectors (DWORD) */
-            *(DWORD*)buff = 32;
-            return RES_OK;
-
-        case CTRL_SYNC :        /* Nothing to do */
-            return RES_OK;
-
-        case ATA_GET_REV :        /* Get firmware revision (8 chars) */
-            ofs = 23; w = 4; n = 4;
-            break;
-
-        case ATA_GET_MODEL :    /* Get model name (40 chars) */
-            ofs = 27; w = 20; n = 20;
-            break;
-
-        case ATA_GET_SN :        /* Get serial number (20 chars) */
-            ofs = 10; w = 10; n = 10;
-            break;
-
+    USB_INT32S  rc;
+    
+    switch(drv)
+    {
+        case CF:
+            switch (ctrl)
+              {
+                        case GET_SECTOR_COUNT :    /* Get number of sectors on the disk (DWORD) */
+                            ofs = 60; w = 2; n = 0;
+                            break;
+                
+                        case GET_BLOCK_SIZE :    /* Get erase block size in sectors (DWORD) */
+                            *(DWORD*)buff = 32;
+                            return RES_OK;
+                        break;
+                        case CTRL_SYNC :        /* Nothing to do */
+                            return RES_OK;
+                        break;
+                        case ATA_GET_REV :        /* Get firmware revision (8 chars) */
+                            ofs = 23; w = 4; n = 4;
+                            break;
+                
+                        case ATA_GET_MODEL :    /* Get model name (40 chars) */
+                            ofs = 27; w = 20; n = 20;
+                            break;
+                
+                        case ATA_GET_SN :        /* Get serial number (20 chars) */
+                            ofs = 10; w = 10; n = 10;
+                            break;
+                
+                        default:
+                            return RES_PARERR;
+             }
+                    
+            write_ata(REG_COMMAND, CMD_IDENTIFY);
+            
+            if (!wait_data()) return RES_ERROR;
+            
+            read_part(ptr, ofs, w);
+            
+            while (n--)
+             {
+                dl = *ptr; dh = *(ptr+1);
+                *ptr++ = dh; *ptr++ = dl; 
+             }
+                        
+             return RES_OK;
+        break;
+        
+        
+        case USB:
+                    rc = MS_Init( &_blkSize, &_numBlks, inquiryResult );
+                   
+                    if (rc != OK)
+                    {
+                        TERMINAL_PRINTF("Could not get data from USB Inquiry: %d\r\n", rc);
+                        return RES_ERROR;
+                    }
+                    else
+                    {
+                        Stat[USB] &= ~STA_NOINIT;
+                         switch (ctrl)
+                              {
+                                    case GET_SECTOR_COUNT :    
+                                       *(DWORD *)(buff) =_numBlks;
+                                        break;
+                            
+                                    case GET_BLOCK_SIZE :   
+                                       *(DWORD *)(buff) = _blkSize;
+                                        return RES_OK;
+                                    break;
+                                    case CTRL_SYNC :      
+                                        return RES_OK;
+                                    break;
+                                    case ATA_GET_REV :        
+                                       memcpy ((CHAR *)buff,(const char *)&inquiryResult[32],8);
+                                        return RES_OK;
+                                        break;
+                            
+                                    case ATA_GET_MODEL :  
+                                        memcpy ((CHAR *)buff, (const char *)&inquiryResult[8],8);
+                                         return RES_OK;
+                                        break;
+                            
+                                    case ATA_GET_SN :      
+                                         memcpy ((CHAR *)buff,(const char *)&inquiryResult[16],8);
+                                          return RES_OK;
+                                        break;
+                                        
+                                    default:
+                                        return RES_PARERR;
+                               }
+                    }
+             
+        break;
+        
+        case RAM:
+              switch (ctrl)
+              {
+                        case GET_SECTOR_COUNT :    /* Get number of sectors on the disk (DWORD) */
+                           *(DWORD *)(buff) = 1;
+                            break;
+                
+                        case GET_BLOCK_SIZE :    /* Get erase block size in sectors (DWORD) */
+                           *(DWORD *)(buff) = 1;
+                            return RES_OK;
+                        break;
+                        case CTRL_SYNC :        /* Nothing to do */
+                            return RES_OK;
+                        break;
+                        case ATA_GET_REV :        /* Get firmware revision (8 chars) */
+                           strcpy ((CHAR *)buff,"Rev 0.01");
+                            break;
+                
+                        case ATA_GET_MODEL :    /* Get model name (40 chars) */
+                            strcpy ((CHAR *)buff,"Wavenumber RAM Drive");
+                            break;
+                
+                        case ATA_GET_SN :        /* Get serial number (20 chars) */
+                             strcpy ((CHAR *)buff,"12345");
+                            break;
+                        default:
+                            return RES_PARERR;
+             }
+             return RES_OK;
+        break;
+        
         default:
-            return RES_PARERR;
-    }
-
-    write_ata(REG_COMMAND, CMD_IDENTIFY);
-    if (!wait_data()) return RES_ERROR;
-    read_part(ptr, ofs, w);
-    while (n--) {
-        dl = *ptr; dh = *(ptr+1);
-        *ptr++ = dh; *ptr++ = dl; 
+             return RES_PARERR;
+        break;
     }
 
     return RES_OK;
@@ -692,29 +860,43 @@
 {
     static BYTE pv;
     BYTE n;
-
-    LED2_TOGGLE;
+   
+    n = DiskProcTimer[CF];                    /* 100Hz decrement timer */
+    if (n) DiskProcTimer[CF] = --n;
 
-    n = DiskProcTimer;                    /* 100Hz decrement timer */
-    if (n) DiskProcTimer = --n;
+    n = DiskProcTimer[USB];                    /* 100Hz decrement timer */
+    if (n) DiskProcTimer[USB] = --n;
+
+    n = DiskProcTimer[RAM];                    /* 100Hz decrement timer */
+    if (n) DiskProcTimer[RAM] = --n;
 
     n = pv;
     pv = COMPACT_FLASH_CARD_DETECTED ;    /* Sapmle socket switch */
 
+
+    //Check Compact Flash Card Detect
     if (n == pv) {                    /* Have contacts stabled? */
         if (!COMPACT_FLASH_CARD_DETECTED )
         {            /* CD1 or CD2 is high (Socket empty) */
-            Stat |= (STA_NODISK | STA_NOINIT);
+            Stat[CF] |= (STA_NODISK | STA_NOINIT);
             SET_DATA_BUS_TO_INPUTS;        /* Float D0-D7 */
             COMPACT_FLASH_RESET_ACTIVE;    /* Assert RESET# */
             COMPACT_FLASH_POWER_DISABLE;   /* Power OFF */
             LED1_OFF; 
-            
-        } else {                    /* CD1 and CD2 are low (Card inserted) */
-            Stat &= ~STA_NODISK;
+        }
+        else 
+        {                    /* CD1 and CD2 are low (Card inserted) */
+            Stat[CF] &= ~STA_NODISK;
             LED1_ON;
         }
     }
+    
+    //Check to see if a USB drive is connected
+    if(HOST_RhscIntr>0)
+        LED2_ON;
+    else
+        LED2_OFF;
+    
 }