iSDIO Library for TOSHIBA FlashAir. include HTTP or HTTPS Client.
Dependents: FlashAir_Twitter Neon_F303K8_04
Fork of HTTPClient by
Revision 20:51abf34bcc06, committed 2014-12-15
- Comitter:
- ban4jp
- Date:
- Mon Dec 15 12:23:22 2014 +0000
- Parent:
- 19:3b1625dbd7e9
- Commit message:
- Initial commit.
Changed in this revision
diff -r 3b1625dbd7e9 -r 51abf34bcc06 HTTPClient.cpp --- a/HTTPClient.cpp Sun Dec 14 19:05:31 2014 +0000 +++ b/HTTPClient.cpp Mon Dec 15 12:23:22 2014 +0000 @@ -18,7 +18,7 @@ */ //Debug is disabled by default -#if 0 +#if 1 //Enable debug #include <cstdio> #define DBG(x, ...) std::printf("[HTTPClient : DBG]"x"\r\n", ##__VA_ARGS__); @@ -41,15 +41,18 @@ #define MAX(x,y) (((x)>(y))?(x):(y)) #define CHUNK_SIZE 256 +#define HEADER_KEY_MAXLENGTH 64 +#define HEADER_VALUE_MAXLENGTH 128 #include <cstring> #include "HTTPClient.h" HTTPClient::HTTPClient() : - m_sock(), m_basicAuthUser(NULL), m_basicAuthPassword(NULL), m_httpResponseCode(0) + m_basicAuthUser(NULL), m_basicAuthPassword(NULL), m_httpResponseCode(0) { - + bufferPos = buffer; + recvCount = 0; } HTTPClient::~HTTPClient() @@ -100,7 +103,6 @@ #define CHECK_CONN_ERR(ret) \ do{ \ if(ret) { \ - m_sock.close(); \ ERR("Connection error (%d)", ret); \ return HTTP_CONN; \ } \ @@ -108,7 +110,6 @@ #define PRTCL_ERR() \ do{ \ - m_sock.close(); \ ERR("Protocol error"); \ return HTTP_PRTCL; \ } while(0) @@ -125,6 +126,7 @@ char scheme[8]; uint16_t port; + uint16_t cmd; char host[32]; char path[64]; //First we need to parse the url (http[s]://host[:port][/[path]]) -- HTTPS not supported (yet?) @@ -137,20 +139,36 @@ if(port == 0) { //TODO do handle HTTPS->443 port = 80; } + if(strcmp(scheme, "http") == 0) { + cmd = 0x21; //SendHTTPMessageByRegister + } else if(strcmp(scheme, "https") == 0) { + cmd = 0x23; //SendHTTPSSLMessageByRegister + } else { + ERR("Not support scheme %s", scheme); + return HTTP_PARSE; + } DBG("Scheme: %s", scheme); DBG("Host: %s", host); DBG("Port: %d", port); + DBG("Cmd: %x", cmd); DBG("Path: %s", path); - //Connect - DBG("Connecting socket to server"); - int ret = m_sock.connect(host, port); - if (ret < 0) { - m_sock.close(); - ERR("Could not connect"); - return HTTP_CONN; - } + int ret; + + //Get card instance + card = SD_iSDIO::getInstance(); + sequenceId = card->getSequenceId(); + + //Create card command + memset(buffer, 0, 1024); + bufferPos = buffer; + bufferPos = put_command_header(bufferPos, 1, 0); + bufferPos = put_command_info_header(bufferPos, cmd, sequenceId, 2); + bufferPos = put_str_arg(bufferPos, host); + + uint8_t* bodyLenPos = bufferPos; + bufferPos += 4; //skip value of data size //Send request DBG("Sending request"); @@ -159,7 +177,6 @@ snprintf(buf, sizeof(buf), "%s %s HTTP/1.1\r\nHost: %s\r\n", meth, path, host); //Write request ret = send(buf); if(ret) { - m_sock.close(); ERR("Could not write request"); return HTTP_CONN; } @@ -244,6 +261,38 @@ } } + put_u32(bodyLenPos, (bufferPos - bodyLenPos - 4)); + put_command_header(buffer, 1, (bufferPos - buffer)); + +#if 0 + for (int i = 0; i < 0x400; i++) { + printf("%2x ", buffer[i]); + if ((i & 0xf) == 0xf) printf("\n"); + if (i == 0x200-1) printf("----\n"); + } + printf((char *)bodyLenPos + 4); + printf("\n"); +#endif + + DBG("Send data size %d", (bufferPos - buffer)); + + if( card->writeExtDataPort(1, 1, 0x000, buffer) != true ) { + ERR("writeExtDataPort error (1)\n"); + return HTTP_PRTCL; + } + if( (bufferPos - buffer) > 512 ) { + if( card->writeExtDataPort(1, 1, 0x000, &buffer[512]) != true ) { + ERR("writeExtDataPort error (2)\n"); + return HTTP_PRTCL; + } + } + + DBG("waitResponse"); + card->waitResponse(sequenceId); + + bufferPos = buffer; + recvCount = 0; + //Receive response DBG("Receiving response"); ret = recv(buf, 1, CHUNK_SIZE - 1, &trfLen); //Read n bytes @@ -285,7 +334,8 @@ PRTCL_ERR(); } - if( (m_httpResponseCode < 200) || (m_httpResponseCode >= 300) ) { + //if( (m_httpResponseCode < 200) || (m_httpResponseCode >= 300) ) { + if( (m_httpResponseCode < 100) || (m_httpResponseCode >= 600) ) { //Did not return a 2xx code; TODO fetch headers/(&data?) anyway and implement a mean of writing/reading headers WARN("Response code %d", m_httpResponseCode); PRTCL_ERR(); @@ -327,14 +377,14 @@ buf[crlfPos] = '\0'; - char key[32]; - char value[32]; + char key[HEADER_KEY_MAXLENGTH]; + char value[HEADER_VALUE_MAXLENGTH]; //key[31] = '\0'; //value[31] = '\0'; - memset(key, 0, 32); - memset(value, 0, 32); + memset(key, 0, HEADER_KEY_MAXLENGTH); + memset(value, 0, HEADER_VALUE_MAXLENGTH); //int n = sscanf(buf, "%31[^:]: %31[^\r\n]", key, value); @@ -343,12 +393,12 @@ char* keyEnd = strchr(buf, ':'); if(keyEnd != NULL) { *keyEnd = '\0'; - if(strlen(buf) < 32) { + if(strlen(buf) < HEADER_KEY_MAXLENGTH) { strcpy(key, buf); n++; char* valueStart = keyEnd + 2; if( (valueStart - buf) < crlfPos ) { - if(strlen(valueStart) < 32) { + if(strlen(valueStart) < HEADER_VALUE_MAXLENGTH) { strcpy(value, valueStart); n++; } @@ -356,7 +406,7 @@ } } if ( n == 2 ) { - DBG("Read header : %s: %s\n", key, value); + DBG("Read header : %s: %s", key, value); if( !strcmp(key, "Content-Length") ) { sscanf(value, "%d", &recvContentLength); recvLengthUnknown = false; @@ -484,7 +534,6 @@ } - m_sock.close(); DBG("Completed HTTP transaction"); return HTTP_OK; @@ -495,41 +544,93 @@ DBG("Trying to read between %d and %d bytes", minLen, maxLen); size_t readLen = 0; - if(!m_sock.is_connected()) { - WARN("Connection was closed by server"); - return HTTP_CLOSED; //Connection was closed by server - } + DBG(" recvCount: %d", recvCount); + + if (recvCount == 0) { - int ret; - while(readLen < maxLen) { - if(readLen < minLen) { - DBG("Trying to read at most %d bytes [Blocking]", minLen - readLen); - m_sock.set_blocking(false, m_timeout); - ret = m_sock.receive_all(buf + readLen, minLen - readLen); - } else { - DBG("Trying to read at most %d bytes [Not blocking]", maxLen - readLen); - m_sock.set_blocking(false, 0); - ret = m_sock.receive(buf + readLen, maxLen - readLen); + // Read header and data. + if (!card->readExtDataPort(1, 1, 0x200, buffer)) { + return HTTP_PRTCL; + } +#if 0 + for (int i = 0; i < 0x200; i++) { + printf("%2x ", buffer[i]); + if ((i & 0xf) == 0xf) printf("\n"); + } +#endif + if (buffer[0] != 0x02) { + return HTTP_CONN; } - if( ret > 0) { - readLen += ret; - } else if( ret == 0 ) { - break; + recvTotalSize = get_u32(buffer + 20); + uint32_t recvSize = recvTotalSize > 488 ? 488 : recvTotalSize; + uint32_t pos = 24; + + if (recvSize < maxLen) { + memcpy(buf, &buffer[pos], recvSize); + readLen = recvSize; } else { - if(!m_sock.is_connected()) { - ERR("Connection error (recv returned %d)", ret); - *pReadLen = readLen; - return HTTP_CONN; + memcpy(buf, &buffer[pos], maxLen); + readLen = maxLen; + } + bufferPos = &buffer[pos] + readLen; + recvAvailableSize = recvTotalSize - readLen; + + DBG(" recvTotalSize: %d", recvTotalSize); + DBG(" recvAvailableSize: %d", recvAvailableSize); + + recvCount++; + + } else { + + uint32_t recvSize = 512 - (bufferPos - buffer); + if (recvAvailableSize < recvSize) recvSize = recvAvailableSize; + + DBG(" recvAvailableSize: %d", recvAvailableSize); + DBG(" recvSize: %d", recvSize); + + if (recvSize > 0) { + + if (recvSize < maxLen) { + memcpy(buf, bufferPos, recvSize); + readLen = recvSize; } else { - break; + memcpy(buf, bufferPos, maxLen); + readLen = maxLen; + } + bufferPos += readLen; + recvAvailableSize -= readLen; + + } else if (recvAvailableSize > 0) { + + // Read next data. + if (!card->readExtDataPort(1, 1, 0x200, buffer)) { + return HTTP_PRTCL; } +#if 0 + for (int i = 0; i < 0x200; i++) { + printf("%2x ", buffer[i]); + if ((i & 0xf) == 0xf) printf("\n"); + } +#endif + recvSize = recvAvailableSize > 512 ? 512 : recvAvailableSize; + + if (recvSize < maxLen) { + memcpy(buf, buffer, recvSize); + readLen = recvSize; + } else { + memcpy(buf, buffer, maxLen); + readLen = maxLen; + } + bufferPos = buffer + readLen; + recvAvailableSize -= readLen; + + recvCount++; + } - if(!m_sock.is_connected()) { - break; - } } + DBG("Read %d bytes", readLen); *pReadLen = readLen; return HTTP_OK; @@ -543,22 +644,13 @@ DBG("Trying to write %d bytes", len); size_t writtenLen = 0; - if(!m_sock.is_connected()) { - WARN("Connection was closed by server"); - return HTTP_CLOSED; //Connection was closed by server + if(((buffer + 1024) - bufferPos) >= len) { + writtenLen = len; + } else { + writtenLen = ((buffer + 1024) - bufferPos); } - - m_sock.set_blocking(false, m_timeout); - int ret = m_sock.send_all(buf, len); - if(ret > 0) { - writtenLen += ret; - } else if( ret == 0 ) { - WARN("Connection was closed by server"); - return HTTP_CLOSED; //Connection was closed by server - } else { - ERR("Connection error (send returned %d)", ret); - return HTTP_CONN; - } + memcpy(bufferPos, buf, writtenLen); + bufferPos += writtenLen; DBG("Written %d bytes", writtenLen); return HTTP_OK;
diff -r 3b1625dbd7e9 -r 51abf34bcc06 HTTPClient.h --- a/HTTPClient.h Sun Dec 14 19:05:31 2014 +0000 +++ b/HTTPClient.h Mon Dec 15 12:23:22 2014 +0000 @@ -24,7 +24,7 @@ #ifndef HTTP_CLIENT_H #define HTTP_CLIENT_H -#include "TCPSocketConnection.h" +#include "iSDIO.h" #define HTTP_CLIENT_DEFAULT_TIMEOUT 15000 @@ -140,7 +140,14 @@ HTTPResult parseURL(const char* url, char* scheme, size_t maxSchemeLen, char* host, size_t maxHostLen, uint16_t* port, char* path, size_t maxPathLen); //Parse URL //Parameters - TCPSocketConnection m_sock; + SD_iSDIO* card; + uint32_t sequenceId; + + uint8_t buffer[512 * 2]; + uint8_t* bufferPos; + uint8_t recvCount; + uint32_t recvTotalSize; + uint32_t recvAvailableSize; int m_timeout;
diff -r 3b1625dbd7e9 -r 51abf34bcc06 SDFileSystem.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SDFileSystem.lib Mon Dec 15 12:23:22 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/teams/mbed/code/SDFileSystem/#7b35d1709458
diff -r 3b1625dbd7e9 -r 51abf34bcc06 iSDIO.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/iSDIO.cpp Mon Dec 15 12:23:22 2014 +0000 @@ -0,0 +1,207 @@ +#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; +}
diff -r 3b1625dbd7e9 -r 51abf34bcc06 iSDIO.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/iSDIO.h Mon Dec 15 12:23:22 2014 +0000 @@ -0,0 +1,32 @@ +#ifndef SD_iSDIO_h +#define SD_iSDIO_h + +#include "mbed.h" +#include "SDFileSystem.h" +#include "iSDIO_helper.h" + +class SD_iSDIO : public SDFileSystem +{ +public: + SD_iSDIO(PinName mosi, PinName miso, PinName sclk, PinName cs, const char* name); + + static SD_iSDIO* getInstance(); + uint32_t getSequenceId(); + + uint8_t readExtDataPort(uint8_t mio, uint8_t func, uint16_t addr, uint8_t* dst); + uint8_t readExtMemory(uint8_t mio, uint8_t func, uint32_t addr, uint16_t count, uint8_t* dst); + uint8_t writeExtDataPort(uint8_t mio, uint8_t func, uint16_t addr, const uint8_t* src); + uint8_t writeExtMemory(uint8_t mio, uint8_t func, uint32_t addr, uint16_t count, const uint8_t* src); + uint8_t writeExtMask(uint8_t mio, uint8_t func, uint32_t addr, uint8_t mask, const uint8_t* src); + + uint8_t waitResponse(uint32_t sequenceId); + +protected: + uint8_t readExt(uint32_t arg, uint8_t* src, uint16_t count); + uint8_t writeExt(uint32_t arg, const uint8_t* src, uint16_t count); + + static SD_iSDIO* instance; + uint32_t sequenceId; +}; + +#endif // SD_iSDIO_h
diff -r 3b1625dbd7e9 -r 51abf34bcc06 iSDIO_helper.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/iSDIO_helper.cpp Mon Dec 15 12:23:22 2014 +0000 @@ -0,0 +1,51 @@ +/* Arduino Sdio Library + * Copyright (C) 2014 by Munehiro Doi, Fixstars Corporation + * All rights reserved. + * Released under the BSD 2-Clause license. + * http://flashair-developers.com/documents/license.html + */ + +#include "iSDIO_helper.h" + +//------------------------------------------------------------------------------ +/** specific version for string. it adds padding bytes after text data. */ +template <> +uint8_t* put_T(uint8_t* p, const char* value) { + while (*value != 0) { + *p++ = *((uint8_t*)value++); + } + return p; +} + +template <> +uint8_t* put_T_arg(uint8_t* p, const char* value) { + uint8_t* orig = p; + p += sizeof(uint32_t); // skip length area. + p = put_T(p, value); // data + uint32_t len = p - orig - sizeof(uint32_t); + put_T(orig, len); // write length. + for (int i = 0; i < ((4 - (len & 3)) & 3); ++i) { // padding + *p++ = 0; + } + return p; +} + +uint8_t* put_command_header(uint8_t* p, uint8_t num_commands, + uint32_t command_bytes) { + p = put_u8(p, 0x01); // Write Data ID + p = put_u8(p, num_commands); // Number of commands. + p = put_u16(p, 0); // reserved. + p = put_u32(p, command_bytes); // size of command write data. + p = put_u32(p, 0); // reserved. + return p; +} + +uint8_t* put_command_info_header(uint8_t* p, uint16_t command_id, + uint32_t sequence_id, uint16_t num_args) { + p = put_u16(p, 0); // reserved. + p = put_u16(p, command_id); // iSDIO command id. + p = put_u32(p, sequence_id); // iSDIO command sequence id. + p = put_u16(p, num_args); // Number of Arguments. + p = put_u16(p, 0); // Reserved. + return p; +}
diff -r 3b1625dbd7e9 -r 51abf34bcc06 iSDIO_helper.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/iSDIO_helper.h Mon Dec 15 12:23:22 2014 +0000 @@ -0,0 +1,220 @@ +/* Arduino Sdio Library + * Copyright (C) 2014 by Munehiro Doi, Fixstars Corporation + * All rights reserved. + * Released under the BSD 2-Clause license. + * http://flashair-developers.com/documents/license.html + */ +#ifndef iSDIO_helper_h +#define iSDIO_helper_h + +#include <stdint.h> + +//------------------------------------------------------------------------------ +// utilities to make a data block. +template <typename T> +uint8_t* put_T(uint8_t* p, T value) { + *((T*)p) = value; + p += sizeof(T); + return p; +} +/** specific version for string. it set length, data, and paddings. */ +template <> +uint8_t* put_T(uint8_t* p, const char* value); + +// utilities for those who want to see value types by function names. +static inline +uint8_t* put_u8(uint8_t* p, uint8_t value) { + return put_T(p, value); +} +static inline +uint8_t* put_u16(uint8_t* p, uint16_t value) { + return put_T(p, value); +} +static inline +uint8_t* put_u32(uint8_t* p, uint32_t value) { + return put_T(p, value); +} +static inline +uint8_t* put_str(uint8_t* p, const char* value) { + return put_T(p, value); +} + +static inline +uint8_t get_u8(uint8_t* p) { + return *((uint8_t*)p); +} +static inline +uint16_t get_u16(uint8_t* p) { + return *((uint16_t*)p); +} +static inline +uint32_t get_u32(uint8_t* p) { + return *((uint32_t*)p); +} + +template <typename T> +uint8_t* put_T_arg(uint8_t* p, T value) { + p = put_T(p, (uint32_t)sizeof(T)); // length + p = put_T(p, value); // data + for (uint8_t i = 0; i < (4 - sizeof(T)) & 0x3; ++i) { // padding + *p++ = 0; + } + return p; +} +template <> +uint8_t* put_T_arg(uint8_t* p, const char* value); + +static inline +uint8_t* put_u8_arg(uint8_t* p, uint8_t value) { + return put_T_arg(p, value); +} +static inline +uint8_t* put_u16_arg(uint8_t* p, uint16_t value) { + return put_T_arg(p, value); +} +static inline +uint8_t* put_u32_arg(uint8_t* p, uint32_t value) { + return put_T_arg(p, value); +} +static inline +uint8_t* put_str_arg(uint8_t* p, const char* value) { + return put_T_arg(p, value); +} +uint8_t* put_command_header(uint8_t* p, uint8_t num_commands, + uint32_t command_bytes); +uint8_t* put_command_info_header(uint8_t* p, uint16_t command_id, + uint32_t sequence_id, uint16_t num_args); + +//------------------------------------------------------------------------------ +/** + * Header data for CMD48/49 param + */ +typedef struct { + uint8_t id; + uint8_t number; + uint16_t _reserved1; + uint32_t size; + uint32_t _reserved2; +} isdio_command_header_t; + +/** + * Information data for CMD48/49 param + */ +typedef struct { + uint16_t _reserved0; + uint16_t command; + uint32_t sequence_id; + uint16_t num_args; + uint16_t _reserved1; +} isdio_command_info_header_t; + +/** + * iSDIO Response Status Register at 0x440 + */ +typedef struct { + uint8_t registration; + uint8_t _reserved0; + uint16_t command_id; + uint32_t sequence_id; + uint8_t status; + uint8_t _reserved1[3]; + uint32_t error_status; + uint32_t data_size; +} isdio_response_status_t; + +/** + * Status Register at 0x400 + */ +typedef struct { + uint8_t CWU :1; // Command Write Update + uint8_t CWA :1; // Command Write Abort + uint8_t _reserved0:6; + uint8_t _reserved1[31]; + uint16_t CRU :1; // Command Response Update + uint16_t ESU :1; // Error Status Update + uint16_t MCU :1; // Media Change Update + uint16_t ASU :1; // Application Status Update + uint16_t _reserved2:12; + uint16_t CRU_ENA :1; // CRU Enabled + uint16_t ESU_ENA :1; // ESU Enabled + uint16_t MCU_ENA :1; // MCU Enabled + uint16_t ASU_ENA :1; // ASU Enabled + uint16_t _reserved3:12; + uint16_t CRE :1; // Command Response Error + uint16_t CWE :1; // Command Write Error + uint16_t RRE :1; // Response Receive Error + uint16_t APE :1; // Application Specific Error + uint16_t _reserved4:12; + uint16_t MEX :1; // Memory Existence + uint16_t FAT :1; // FAT System + uint16_t _reserved5:14; + uint8_t _reserved6[24]; + isdio_response_status_t response[8]; + uint8_t _reserved7[32]; + uint8_t application_status[256]; +} isdio_status_t; + + +typedef struct { + uint8_t ULR :1; + uint8_t DLU :1; + uint8_t CBR :1; + uint8_t CDR :1; + uint8_t _reserved0 :4; + uint8_t ILU :1; + uint8_t FLU :1; + uint8_t _reserved1 :6; + uint8_t RPO :1; + uint8_t RPD :1; + uint8_t RPC :1; + uint8_t CPI :1; + uint8_t DPI :1; + uint8_t CIL :1; + uint8_t _reserved2 :2; + uint8_t _reserved3; + uint8_t application; + uint8_t _reserved4; + uint16_t Scan :1; + uint16_t WPS :2; + uint16_t Group :1; + uint16_t AP_STA :1; + uint16_t Infra_Direct :2; + uint16_t Connected :1; + uint16_t _reserved5 :8; + char SSID[32]; + uint8_t encryption_mode; + uint8_t signal_strength; + uint8_t channel; + uint8_t _reserved6[5]; + uint8_t MACAddress[6]; + uint8_t _reserved7[10]; + uint8_t ID[16]; + uint8_t IPAddress[4]; + uint8_t SubnetMask[4]; + uint8_t DefaultGateway[4]; + uint8_t PreferredDNSServer[4]; + uint8_t AlternateDNSServer[4]; + uint8_t ProxyServer:1; + uint8_t _reserved8:7; +} isdio_wlan_status_t; + +/** + * iSDIO Vendor Status Register at 0x5C0 + */ +typedef struct { + uint32_t vendorId; + uint32_t vendorFunction; + uint32_t HttpBodyTransferSize; + uint32_t HttpBodyTotalSize; + uint32_t HttpBuffSize; + uint32_t LHFStatus:8; + uint32_t PhotoshareStatus:8; + uint32_t FileDownloadStatus:8; + uint32_t rsv0:8; + uint32_t FtpTransferSize; + uint32_t rsv1; + uint32_t rsv2[4]; + uint8_t VendorFwVersion[16]; +} isdio_vender_status_t; + +#endif // iSDIO_helper_h