iSDIO Library for TOSHIBA FlashAir. include HTTP or HTTPS Client.

Dependencies:   SDFileSystem

Dependents:   FlashAir_Twitter Neon_F303K8_04

Fork of HTTPClient by Donatien Garnier

iSDIO.cpp

Committer:
ban4jp
Date:
2014-12-15
Revision:
20:51abf34bcc06

File content as of revision 20:51abf34bcc06:

#include "mbed.h"
#include "iSDIO.h"

#define CMD48 0x30
#define CMD49 0x31

SD_iSDIO::SD_iSDIO(PinName mosi, PinName miso, PinName sclk, PinName cs, const char* name) :
    SDFileSystem(mosi, miso, sclk, cs, name)
{
    //disk_initialize();
    instance = this;
    sequenceId = 0;
}

SD_iSDIO* SD_iSDIO::instance = 0;

SD_iSDIO* SD_iSDIO::getInstance()
{
    return SD_iSDIO::instance;
}

uint32_t SD_iSDIO::getSequenceId()
{
    return sequenceId++;
}

uint8_t SD_iSDIO::readExtDataPort(uint8_t mio, uint8_t func, uint16_t addr, uint8_t* dst)
{
    uint32_t arg =
        (((uint32_t)mio & 0x1) << 31) |
        (mio ? (((uint32_t)func & 0x7) << 28) : (((uint32_t)func & 0xF) << 27)) |
        (((uint32_t)addr & 0x1FE00) << 9);
    return readExt(arg, dst, 512);
}

uint8_t SD_iSDIO::readExtMemory(uint8_t mio, uint8_t func, uint32_t addr, uint16_t count, uint8_t* dst)
{
    uint32_t offset = addr & 0x1FF;
    if (offset + count > 512) count = 512 - offset;
    if (count == 0) return true;
    uint32_t arg =
        (((uint32_t)mio & 0x1) << 31) |
        (mio ? (((uint32_t)func & 0x7) << 28) : (((uint32_t)func & 0xF) << 27)) |
        ((addr & 0x1FFFF) << 9) |
        ((count - 1) & 0x1FF);
    return readExt(arg, dst, count);
}

uint8_t SD_iSDIO::writeExtDataPort(uint8_t mio, uint8_t func, uint16_t addr, const uint8_t* src)
{
    uint32_t arg =
        (((uint32_t)mio & 0x1) << 31) |
        (mio ? (((uint32_t)func & 0x7) << 28) : (((uint32_t)func & 0xF) << 27)) |
        (((uint32_t)addr & 0x1FE00) << 9);
    return writeExt(arg, src, 512);
}

uint8_t SD_iSDIO::writeExtMemory(uint8_t mio, uint8_t func, uint32_t addr, uint16_t count, const uint8_t* src)
{
    uint32_t arg =
        (((uint32_t)mio & 0x1) << 31) |
        (mio ? (((uint32_t)func & 0x7) << 28) : (((uint32_t)func & 0xF) << 27)) |
        ((addr & 0x1FFFF) << 9) |
        ((count - 1) & 0x1FF);
    return writeExt(arg, src, count);
}

uint8_t SD_iSDIO::writeExtMask(uint8_t mio, uint8_t func, uint32_t addr, uint8_t mask, const uint8_t* src)
{
    uint32_t arg =
        (((uint32_t)mio & 0x1) << 31) |
        (mio ? (((uint32_t)func & 0x7) << 28) : (((uint32_t)func & 0xF) << 27)) |
        (0x1 << 26) |
        ((addr & 0x1FFFF) << 9) |
        mask;
    return writeExt(arg, src, 1);
}

uint8_t SD_iSDIO::waitResponse(uint32_t sequenceId)
{
    uint8_t buffer[0x14];
    
    //printf("\nWaiting response ");
    uint8_t prev = 0xFF;
    for (int i = 0; i < 20; ++i) {
        memset(buffer, 0, 0x14);
        // Read command response status.
        if (!readExtMemory(1, 1, 0x440, 0x14, buffer)) {
            return false;
        }
        uint8_t resp = get_u8(buffer + 8);
        if (sequenceId == get_u32(buffer + 4)) {
            if (prev != resp) {
                switch (resp) {
                    case 0x00:
                        //printf("\n  Initial");
                        break;
                    case 0x01:
                        //printf("\n  Command Processing");
                        break;
                    case 0x02:
                        //printf("\n  Command Rejected");
                        return false;
                    case 0x03:
                        //printf("\n  Process Succeeded");
                        return true;
                    case 0x04:
                        //printf("\n  Process Terminated");
                        return false;
                    default:
                        //printf("\n  Process Failed ");
                        //printf("%x", resp);
                        return false;
                }
                prev = resp;
            }
        }
        //printf(".");
        wait_ms(1000);
    }
    return false;
}

/** Perform Extention Read. */
uint8_t SD_iSDIO::readExt(uint32_t arg, uint8_t* dst, uint16_t count)
{
    uint16_t i;
    // send command and argument.
    if (_cmd(CMD48, arg)) {
        error("SD_CARD_ERROR_CMD48");
        _cs = 1;
        return false;
    }

    _cs = 0;

    /*
    // wait for start block token.
    if (!waitStartBlock()) {
        _cs = 1;
        return false;
    }
    */
    while (_spi.write(0xFF) == 0xFF);

    // receive data
    for (i = 0; i < count; ++i) {
        dst[i] = _spi.write(0xFF);
    }
    // skip dummy bytes and 16-bit crc.
    for (; i < 514; ++i) {
        _spi.write(0xFF);
    }
    _cs = 1;
    _spi.write(0xFF); // dummy clock to force FlashAir finish the command.
    return true;
}

/** Perform Extention Write. */
uint8_t SD_iSDIO::writeExt(uint32_t arg, const uint8_t* src, uint16_t count)
{
    uint16_t i;
    uint8_t status;
    // send command and argument.
    if (_cmd(CMD49, arg)) {
        error("SD_CARD_ERROR_CMD49");
        _cs = 1;
        return false;
    }

    _cs = 0;

    // send start block token.
    //_spi.write(DATA_START_BLOCK);
    _spi.write(0xFE);
    // send data
    for (i = 0; i < count; ++i) {
        _spi.write(src[i]);
    }
    // send dummy bytes until 512 bytes.
    for (; i < 512; ++i) {
        _spi.write(0xFF);
    }
    // dummy 16-bit crc
    _spi.write(0xFF);
    _spi.write(0xFF);
    // wait a data response token
    status = _spi.write(0xFF);
    //if ((status & DATA_RES_MASK) != DATA_RES_ACCEPTED) {
    if ((status & 0x1F) != 0x05) {
        error("SD_CARD_ERROR_WRITE");
        _cs = 1;
        return false;
    }
    // wait for flash programming to complete
    /*
    if (!waitNotBusy(SD_WRITE_TIMEOUT)) {
        error("SD_CARD_ERROR_WRITE_TIMEOUT");
        _cs = 1;
        return false;
    }
    */
    while (_spi.write(0xFF) == 0);

    _cs = 1;
    return true;
}