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

📄 sdcard.java

📁 java 编写的一个FAT16读写源代码 支持长文件名和子目录
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
            crc = (short)(((crc >> 8) & 0x0FF) | (crc << 8));
            crc ^= (data[i] & 0x0FF);
            crc ^= (crc & 0x0FF) >> 4;;
            crc ^= (crc << 8) << 4;
            crc ^= ((crc & 0xFF) << 4) << 1;
        }
/*
        short crc = 0;
        for(int i = 0; i < len; i++)
        {
            for(int x = 7; x >= 0; x--)
            {
                boolean flip = (crc & 0x8000) == 0x8000;
                crc <<= 1;
                crc |= ((data[offset + i] >> x) & 1);
                if(flip)
                {
                    crc ^= 0x1021;
                }
            }
        }

        for(int x = 0; x < 16; x++)
        {
            boolean flip = (crc & 0x8000) == 0x8000;
            crc <<= 1;
            if(flip)
            {
                crc ^= 0x1021;
            }
        }
*/
        return crc;
    }

    private CachedSector getCachedSector(int address, int length)
    {
        CachedSector sector;

        for(int i = 0; i < cache.size(); i++)
        {
            sector = (CachedSector)cache.elementAt(i);
            if(sector.isSector(address, length))
            {
                cache.removeElementAt(i);
                cache.insertElementAt(sector, 0);
                return sector;
            }
        }

        if(cache.size() == CACHE_SIZE)
        {
            sector = (CachedSector)cache.lastElement();
            if(sector.dirty)
            {
                writeblock(sector);
            }
            cache.removeElement(sector);
            cache.insertElementAt(sector, 0);

            sector.address = address - (address % blockSize);
            readblock(sector);
            sector.dirty = false;
        }
        else
        {
            sector = new CachedSector(address - (address % blockSize));
            cache.insertElementAt(sector, 0);
        }
        return sector;
    }

    private boolean readblock(CachedSector sector)
    {
        int result;
        cmd[1] = (byte)((sector.address & 0xff000000) >> 24);
        cmd[2] = (byte)((sector.address & 0x00ff0000) >> 16);
        cmd[3] = (byte)((sector.address & 0x0000ff00) >> 8);
        cmd[4] = (byte)(sector.address & 0x000000ff);

        try
        {
            if(sendCommand(CMD17_READ_SINGLE_BLOCK) != R1_NOERROR)
            {
                return false;
            }

            receiveData(sector.cache, 0, blockSize + 2);
            verifyCRC16(sector.cache, 0, blockSize,(short)((sector.cache[blockSize] << 8) | (sector.cache[blockSize + 1] & 0x0FF)));
            return true;
        }
        catch(Exception ex)
        {
            return false;
        }
    }
    


    private boolean writeblock(CachedSector sector)
    {
        short crc = crc16(sector.cache, 0, blockSize);
        sector.cache[blockSize + 0] = (byte)(crc >> 8);
        sector.cache[blockSize + 1] = (byte)(crc & 0x00ff);

        // This byte address is stored MSB-first in the argument buffer
        cmd[1] = (byte)((sector.address & 0xff000000) >> 24);
        cmd[2] = (byte)((sector.address & 0x00ff0000) >> 16);
        cmd[3] = (byte)((sector.address & 0x0000ff00) >> 8);
        cmd[4] = (byte)(sector.address & 0x000000ff);

        try
        {
            // Transmit the write command plus the byte address argument
            if(sendCommand(CMD24_WRITE_BLOCK) != R1_NOERROR)
            {
                return false;
            }
        }
        catch(Exception x)
        {
            return false;
        }

        sendSPI((byte)0xFE);
        spi.xmit(sector.cache, 0, blockSize + 2);

        byte recv;
        int tries = 0;
        do
        {
            if(tries++ > 32768)
            {
                return false;
            }
            recv = sendSPI((byte)0xFF);
        }
        while(((recv & 0x10) != 0) || ((recv & 0x01) == 0));

        tries = 0;
        do
        {
            if(tries++ > 32768)
            {
                return false;
            }
            recv = sendSPI((byte)0xFF);
        } while(recv != (byte)0xFF);

        return true;
    }

    public void init(String[] args)
    {
//TODO
/*
        int interval = 2000;
        int count;
        if(args.length > 0)
        {
            interval = Integer.parseInt(args[0]);
        }

        immediateWrite = false;
        if(interval == 0)
        {
            immediateWrite = true;
        }
        else if(interval == -1)
        {
        }
        else
        {
            count = 1;
            if(args.length > 1)
            {
                count = Integer.parseInt(args[1]);
            }

            (new FlushThread(interval, count)).start();
        }
*/        
    }

    private class FlushThread extends Thread
    {
        private int delay;
        private int count;

        FlushThread(int interval, int count)
        {
            this.delay = interval;
            this.count = count;
        }

        public void run()
        {
            while(true)
            {
                try
                {
                    Thread.sleep(delay);
                    int cnt = count;
                    synchronized (cache)
                    {
                        for(int i = 0; i < cache.size(); i++)
                        {
                            CachedSector sector = (CachedSector)cache.elementAt(i);
                            if(sector.dirty)
                            {
                                writeblock(sector);
                                sector.dirty = false;
                                if(--cnt == 0)
                                {
                                    break;
                                }
                            }
                        }
                    }
                }
                catch(Exception x)
                {
                }
            }
        }
    }

    public void setOffset(int offset)
    {
        startAddress = offset;
    }

    //TODO handle reads across multiple sectors (or at least throw an exception).
    public boolean read(int address, byte[] buff, int offset, int length)
    {
        address += startAddress;
        synchronized (cache)
        {
            CachedSector sector = getCachedSector(address, length);
            System.arraycopy(sector.cache, address - sector.address, buff, offset, length);
        }
        return true;
    }

    //TODO - need to handle writes across multiple sectors (or at least throw an exception).
    public boolean write(int address, byte[] buff, int offset, int length)
    {
        address += startAddress;
        synchronized (cache)
        {
            CachedSector sector = getCachedSector(address, length);
            System.arraycopy(buff, offset, sector.cache, (address - sector.address), length);
            sector.dirty = true;
            if(immediateWrite)
            {
                flush();
            }
        }
        return true;
    }

    public void flush()
    {
        synchronized (cache)
        {
            for(int i = 0; i < cache.size(); i++)
            {
                CachedSector sector = (CachedSector)cache.elementAt(i);
                if(sector.dirty)
                {
                    writeblock(sector);
                    sector.dirty = false;
                }
            }
        }
    }

    public int size()
    {
        return cardSize;
    }
/*
    public static void dumpData(byte[] b, int off, int len)
    {
        int x, c;
        int line;

        String newLine = System.getProperty("line.separator");
        StringBuffer sb = new StringBuffer();

        sb.append("ADDR|  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F | ASCII");
        sb.append(newLine);
        sb.append("------------------------------------------------------------------------");
        sb.append(newLine);
        for(line = 0; line < ((len % 16 != 0) ? (len / 16) + 1 : (len / 16)); line++)
        {
            String hex = toHexString(line * 16, 4);

            sb.append(hex);
            sb.append("| ");
            for(x = 0; x < 16; x++)
            {
                if(x + (line * 16) < len)
                {
	                c = b[off + x + line * 16];
	                hex = toHexString(c, 2);
	                sb.append(hex);
                    sb.append(" ");
                }
                else
                {
                    sb.append("   ");
                }
            }
            sb.append("| ");

            for(x = 0; x < 16; x++)
            {
                if(x + (line * 16) < len)
                {
	                c = b[off + x + line * 16];
	                if((c > 0x1f) && (c < 0x7f))
                    {
                        sb.append((char)c);
                    }
                    else
                    {
                        sb.append(".");
                    }
                 }
                 else
                 {
                     sb.append(" ");
                 }
            }
            sb.append(newLine);
        }
        sb.append("------------------------------------------------------------------------");
        FATFS.sendMessage(sb.toString());
    }
    private static String toHexString(int x, int len)
    {
        int mask = (1 << (len * 4)) - 1;
        x = x & mask;
        String ret = Integer.toHexString(x);
        while(ret.length() < len)
        {
            ret = '0' + ret;
        }
        return ret;
    }
*/
}

⌨️ 快捷键说明

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