iSDIO library for FlashAir

Dependents:   FlashAir_iSDIO_sample FlashAir_iSDIO_16seg_ADT7410_step1 FlashAir_iSDIO_16seg_ADT7410 FlashAir_iSDIO_sample_OS5_ ... more

Committer:
hogejun
Date:
Wed Aug 29 04:04:52 2018 +0000
Revision:
1:dc888b9028cf
Parent:
0:89c6aae3a486
Child:
2:b8b33621e7fe
add header to each file

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hogejun 0:89c6aae3a486 1 /* mbed SD iSDIO Library
hogejun 1:dc888b9028cf 2 * Copyright (C) 2018 by Junichi SHIBA, PIAX Inc.
hogejun 0:89c6aae3a486 3 *
hogejun 0:89c6aae3a486 4 * Arduino Sdio Library
hogejun 0:89c6aae3a486 5 * Copyright (C) 2014 by Munehiro Doi
hogejun 0:89c6aae3a486 6 *
hogejun 0:89c6aae3a486 7 * This file is an SD extension of the Arduino Sd2Card Library
hogejun 0:89c6aae3a486 8 * Copyright (C) 2009 by William Greiman
hogejun 0:89c6aae3a486 9 *
hogejun 0:89c6aae3a486 10 * This Library is free software: you can redistribute it and/or modify
hogejun 0:89c6aae3a486 11 * it under the terms of the GNU General Public License as published by
hogejun 0:89c6aae3a486 12 * the Free Software Foundation, either version 3 of the License, or
hogejun 0:89c6aae3a486 13 * (at your option) any later version.
hogejun 0:89c6aae3a486 14 *
hogejun 0:89c6aae3a486 15 * This Library is distributed in the hope that it will be useful,
hogejun 0:89c6aae3a486 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
hogejun 0:89c6aae3a486 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
hogejun 0:89c6aae3a486 18 * GNU General Public License for more details.
hogejun 0:89c6aae3a486 19 *
hogejun 0:89c6aae3a486 20 * You should have received a copy of the GNU General Public License
hogejun 0:89c6aae3a486 21 * along with the Arduino Sd2Card Library. If not, see
hogejun 0:89c6aae3a486 22 * <http://www.gnu.org/licenses/>.
hogejun 0:89c6aae3a486 23 */
hogejun 0:89c6aae3a486 24 #include "mbed.h"
hogejun 0:89c6aae3a486 25 #include "iSDIO.h"
hogejun 0:89c6aae3a486 26
hogejun 0:89c6aae3a486 27 //------------------------------------------------------------------------------
hogejun 0:89c6aae3a486 28 // SD extension commands
hogejun 0:89c6aae3a486 29 /** EXTENSION READ - Extension Register Read Command (Single Block) */
hogejun 0:89c6aae3a486 30 uint8_t const CMD48 = 0X30;
hogejun 0:89c6aae3a486 31 /** EXTENSION WRITE - Extension Register Write Command (Single Block) */
hogejun 0:89c6aae3a486 32 uint8_t const CMD49 = 0X31;
hogejun 0:89c6aae3a486 33 /** EXTENSION READ - Extension Register Read Command (Multi Block) */
hogejun 0:89c6aae3a486 34 uint8_t const CMD17 = 17;
hogejun 0:89c6aae3a486 35 /** EXTENSION READ - Extension Register Read Command (Multi Block) */
hogejun 0:89c6aae3a486 36 uint8_t const CMD24 = 24;
hogejun 0:89c6aae3a486 37
hogejun 0:89c6aae3a486 38 //------------------------------------------------------------------------------
hogejun 0:89c6aae3a486 39 // SD extension error codes.
hogejun 0:89c6aae3a486 40 /** card returned an error response for CMD48 (read extension block) */
hogejun 0:89c6aae3a486 41 uint8_t const SD_CARD_ERROR_CMD48 = 0X80;
hogejun 0:89c6aae3a486 42 /** card returned an error response for CMD49 (write extension block) */
hogejun 0:89c6aae3a486 43 uint8_t const SD_CARD_ERROR_CMD49 = 0X81;
hogejun 0:89c6aae3a486 44 //------------------------------------------------------------------------------
hogejun 0:89c6aae3a486 45
hogejun 0:89c6aae3a486 46 iSDIO::iSDIO(PinName mosi, PinName miso, PinName sclk, PinName cs, const char* name, Serial* console) :
hogejun 0:89c6aae3a486 47 SDFileSystem(mosi, miso, sclk, cs, name)
hogejun 0:89c6aae3a486 48 {
hogejun 0:89c6aae3a486 49 instance = this;
hogejun 0:89c6aae3a486 50 _console = console;
hogejun 0:89c6aae3a486 51 sequenceId = 0;
hogejun 0:89c6aae3a486 52 _console->printf("new iSDIO\n");
hogejun 0:89c6aae3a486 53 }
hogejun 0:89c6aae3a486 54
hogejun 0:89c6aae3a486 55 iSDIO::~iSDIO(void) {}
hogejun 0:89c6aae3a486 56
hogejun 0:89c6aae3a486 57 iSDIO* iSDIO::instance = 0;
hogejun 0:89c6aae3a486 58
hogejun 0:89c6aae3a486 59 iSDIO* iSDIO::getInstance()
hogejun 0:89c6aae3a486 60 {
hogejun 0:89c6aae3a486 61 return iSDIO::instance;
hogejun 0:89c6aae3a486 62 }
hogejun 0:89c6aae3a486 63
hogejun 0:89c6aae3a486 64 uint32_t iSDIO::getSequenceId()
hogejun 0:89c6aae3a486 65 {
hogejun 0:89c6aae3a486 66 _console->printf("sequenceId: %d\n", sequenceId);
hogejun 0:89c6aae3a486 67 return sequenceId;
hogejun 0:89c6aae3a486 68 }
hogejun 0:89c6aae3a486 69
hogejun 0:89c6aae3a486 70 uint32_t iSDIO::getNextSequenceId()
hogejun 0:89c6aae3a486 71 {
hogejun 0:89c6aae3a486 72 sequenceId++;
hogejun 0:89c6aae3a486 73 _console->printf("Next sequenceId: %d\n", sequenceId);
hogejun 0:89c6aae3a486 74 return sequenceId;
hogejun 0:89c6aae3a486 75 }
hogejun 0:89c6aae3a486 76
hogejun 0:89c6aae3a486 77 uint8_t const DATA_START_BLOCK = 0XFE ;
hogejun 0:89c6aae3a486 78 uint8_t const DATA_RES_MASK = 0X1F ;
hogejun 0:89c6aae3a486 79 uint8_t const DATA_RES_ACCEPTED = 0X05 ;
hogejun 0:89c6aae3a486 80
hogejun 0:89c6aae3a486 81 //------------------------------------------------------------------------------
hogejun 0:89c6aae3a486 82 /** Perform Extention Read. */
hogejun 0:89c6aae3a486 83 uint8_t iSDIO::readExt(uint32_t arg, uint8_t* dst, uint16_t count)
hogejun 0:89c6aae3a486 84 {
hogejun 0:89c6aae3a486 85 uint16_t i;
hogejun 0:89c6aae3a486 86 // send command and argument.
hogejun 0:89c6aae3a486 87 if (_cmd(CMD48, arg) && _cmd(CMD17, arg)) {
hogejun 0:89c6aae3a486 88 error("SD_CARD_ERROR_CMD48");
hogejun 0:89c6aae3a486 89 _cs = 1;
hogejun 0:89c6aae3a486 90 return false;
hogejun 0:89c6aae3a486 91 }
hogejun 0:89c6aae3a486 92
hogejun 0:89c6aae3a486 93 _cs = 0;
hogejun 0:89c6aae3a486 94
hogejun 0:89c6aae3a486 95 // wait for start block token.
hogejun 0:89c6aae3a486 96 while (_spi.write(0xFF) == 0xFF);
hogejun 0:89c6aae3a486 97
hogejun 0:89c6aae3a486 98 // receive data
hogejun 0:89c6aae3a486 99 for (i = 0; i < count; ++i) {
hogejun 0:89c6aae3a486 100 dst[i] = _spi.write(0xFF);
hogejun 0:89c6aae3a486 101 }
hogejun 0:89c6aae3a486 102 // skip dummy bytes and 16-bit crc.
hogejun 0:89c6aae3a486 103 for (; i < 514; ++i) {
hogejun 0:89c6aae3a486 104 _spi.write(0xFF);
hogejun 0:89c6aae3a486 105 }
hogejun 0:89c6aae3a486 106 _cs = 1;
hogejun 0:89c6aae3a486 107 _spi.write(0xFF); // dummy clock to force FlashAir finish the command.
hogejun 0:89c6aae3a486 108 return true;
hogejun 0:89c6aae3a486 109 }
hogejun 0:89c6aae3a486 110
hogejun 0:89c6aae3a486 111 //------------------------------------------------------------------------------
hogejun 0:89c6aae3a486 112 /** Perform Extention Write. */
hogejun 0:89c6aae3a486 113 uint8_t iSDIO::writeExt(uint32_t arg, const uint8_t* src, uint16_t count)
hogejun 0:89c6aae3a486 114 {
hogejun 0:89c6aae3a486 115 uint16_t i;
hogejun 0:89c6aae3a486 116 uint8_t status;
hogejun 0:89c6aae3a486 117 // send command and argument.
hogejun 0:89c6aae3a486 118 if (_cmd(CMD49, arg) && _cmd(CMD24, arg)) {
hogejun 0:89c6aae3a486 119 error("SD_CARD_ERROR_CMD49");
hogejun 0:89c6aae3a486 120 _cs = 1;
hogejun 0:89c6aae3a486 121 return false;
hogejun 0:89c6aae3a486 122 }
hogejun 0:89c6aae3a486 123
hogejun 0:89c6aae3a486 124 _cs = 0;
hogejun 0:89c6aae3a486 125
hogejun 0:89c6aae3a486 126 // send start block token.
hogejun 0:89c6aae3a486 127 _spi.write(DATA_START_BLOCK);
hogejun 0:89c6aae3a486 128 //////_spi.write(0xFE);
hogejun 0:89c6aae3a486 129 // send data
hogejun 0:89c6aae3a486 130 for (i = 0; i < count; ++i) {
hogejun 0:89c6aae3a486 131 _spi.write(src[i]);
hogejun 0:89c6aae3a486 132 }
hogejun 0:89c6aae3a486 133 // send dummy bytes until 512 bytes.
hogejun 0:89c6aae3a486 134 for (; i < 512; ++i) {
hogejun 0:89c6aae3a486 135 _spi.write(0xFF);
hogejun 0:89c6aae3a486 136 }
hogejun 0:89c6aae3a486 137 // dummy 16-bit crc
hogejun 0:89c6aae3a486 138 _spi.write(0xFF);
hogejun 0:89c6aae3a486 139 _spi.write(0xFF);
hogejun 0:89c6aae3a486 140 // wait a data response token
hogejun 0:89c6aae3a486 141 status = _spi.write(0xFF);
hogejun 0:89c6aae3a486 142 if ((status & DATA_RES_MASK) != DATA_RES_ACCEPTED) {
hogejun 0:89c6aae3a486 143 //////if ((status & 0x1F) != 0x05) {
hogejun 0:89c6aae3a486 144 error("SD_CARD_ERROR_WRITE");
hogejun 0:89c6aae3a486 145 _cs = 1;
hogejun 0:89c6aae3a486 146 return false;
hogejun 0:89c6aae3a486 147 }
hogejun 0:89c6aae3a486 148 // wait for flash programming to complete
hogejun 0:89c6aae3a486 149 while (_spi.write(0xFF) == 0);
hogejun 0:89c6aae3a486 150
hogejun 0:89c6aae3a486 151 _cs = 1;
hogejun 0:89c6aae3a486 152 return true;
hogejun 0:89c6aae3a486 153 }
hogejun 0:89c6aae3a486 154
hogejun 0:89c6aae3a486 155 //------------------------------------------------------------------------------
hogejun 0:89c6aae3a486 156 /**
hogejun 0:89c6aae3a486 157 * Read a 512 byte data port in an extension register space.
hogejun 0:89c6aae3a486 158 *
hogejun 0:89c6aae3a486 159 * \return The value one, true, is returned for success and
hogejun 0:89c6aae3a486 160 * the value zero, false, is returned for failure.
hogejun 0:89c6aae3a486 161 */
hogejun 0:89c6aae3a486 162 uint8_t iSDIO::readExtDataPort(uint8_t mio, uint8_t func, uint16_t addr, uint8_t* dst)
hogejun 0:89c6aae3a486 163 {
hogejun 0:89c6aae3a486 164 uint32_t arg =
hogejun 0:89c6aae3a486 165 (((uint32_t)mio & 0x1) << 31) |
hogejun 0:89c6aae3a486 166 (mio ? (((uint32_t)func & 0x7) << 28) : (((uint32_t)func & 0xF) << 27)) |
hogejun 0:89c6aae3a486 167 (((uint32_t)addr & 0x1FE00) << 9);
hogejun 0:89c6aae3a486 168 return readExt(arg, dst, 512);
hogejun 0:89c6aae3a486 169 }
hogejun 0:89c6aae3a486 170
hogejun 0:89c6aae3a486 171 //------------------------------------------------------------------------------
hogejun 0:89c6aae3a486 172 /**
hogejun 0:89c6aae3a486 173 * Read an extension register space.
hogejun 0:89c6aae3a486 174 *
hogejun 0:89c6aae3a486 175 * \return The value one, true, is returned for success and
hogejun 0:89c6aae3a486 176 * the value zero, false, is returned for failure.
hogejun 0:89c6aae3a486 177 */
hogejun 0:89c6aae3a486 178 uint8_t iSDIO::readExtMemory(uint8_t mio, uint8_t func, uint32_t addr, uint16_t count, uint8_t* dst)
hogejun 0:89c6aae3a486 179 {
hogejun 0:89c6aae3a486 180 uint32_t offset = addr & 0x1FF;
hogejun 0:89c6aae3a486 181 if (offset + count > 512) count = 512 - offset;
hogejun 0:89c6aae3a486 182 if (count == 0) return true;
hogejun 0:89c6aae3a486 183 uint32_t arg =
hogejun 0:89c6aae3a486 184 (((uint32_t)mio & 0x1) << 31) |
hogejun 0:89c6aae3a486 185 (mio ? (((uint32_t)func & 0x7) << 28) : (((uint32_t)func & 0xF) << 27)) |
hogejun 0:89c6aae3a486 186 ((addr & 0x1FFFF) << 9) |
hogejun 0:89c6aae3a486 187 ((count - 1) & 0x1FF);
hogejun 0:89c6aae3a486 188 return readExt(arg, dst, count);
hogejun 0:89c6aae3a486 189 }
hogejun 0:89c6aae3a486 190
hogejun 0:89c6aae3a486 191 //------------------------------------------------------------------------------
hogejun 0:89c6aae3a486 192 /**
hogejun 0:89c6aae3a486 193 * Write a 512 byte data port into an extension register space.
hogejun 0:89c6aae3a486 194 *
hogejun 0:89c6aae3a486 195 * \return The value one, true, is returned for success and
hogejun 0:89c6aae3a486 196 * the value zero, false, is returned for failure.
hogejun 0:89c6aae3a486 197 */
hogejun 0:89c6aae3a486 198 uint8_t iSDIO::writeExtDataPort(uint8_t mio, uint8_t func, uint16_t addr, const uint8_t* src)
hogejun 0:89c6aae3a486 199 {
hogejun 0:89c6aae3a486 200 uint32_t arg =
hogejun 0:89c6aae3a486 201 (((uint32_t)mio & 0x1) << 31) |
hogejun 0:89c6aae3a486 202 (mio ? (((uint32_t)func & 0x7) << 28) : (((uint32_t)func & 0xF) << 27)) |
hogejun 0:89c6aae3a486 203 (((uint32_t)addr & 0x1FE00) << 9);
hogejun 0:89c6aae3a486 204 _console->printf("arg = %08x\n", arg);
hogejun 0:89c6aae3a486 205 return writeExt(arg, src, 512);
hogejun 0:89c6aae3a486 206 }
hogejun 0:89c6aae3a486 207
hogejun 0:89c6aae3a486 208 //------------------------------------------------------------------------------
hogejun 0:89c6aae3a486 209 /**
hogejun 0:89c6aae3a486 210 * Write an extension register space.
hogejun 0:89c6aae3a486 211 *
hogejun 0:89c6aae3a486 212 * \return The value one, true, is returned for success and
hogejun 0:89c6aae3a486 213 * the value zero, false, is returned for failure.
hogejun 0:89c6aae3a486 214 */
hogejun 0:89c6aae3a486 215 uint8_t iSDIO::writeExtMemory(uint8_t mio, uint8_t func, uint32_t addr, uint16_t count, const uint8_t* src)
hogejun 0:89c6aae3a486 216 {
hogejun 0:89c6aae3a486 217 uint32_t arg =
hogejun 0:89c6aae3a486 218 (((uint32_t)mio & 0x1) << 31) |
hogejun 0:89c6aae3a486 219 (mio ? (((uint32_t)func & 0x7) << 28) : (((uint32_t)func & 0xF) << 27)) |
hogejun 0:89c6aae3a486 220 ((addr & 0x1FFFF) << 9) |
hogejun 0:89c6aae3a486 221 ((count - 1) & 0x1FF);
hogejun 0:89c6aae3a486 222 _console->printf("writeExtMemory: ");
hogejun 0:89c6aae3a486 223 _console->printf(" addr: %08x\n", addr);
hogejun 0:89c6aae3a486 224 _console->printf(" src: ");
hogejun 0:89c6aae3a486 225 printHex((uint8_t*)src, (uint32_t)count);
hogejun 0:89c6aae3a486 226 _console->printf(" count: %d\n", count);
hogejun 0:89c6aae3a486 227 return writeExt(arg, src, count);
hogejun 0:89c6aae3a486 228 }
hogejun 0:89c6aae3a486 229
hogejun 0:89c6aae3a486 230 //------------------------------------------------------------------------------
hogejun 0:89c6aae3a486 231 /**
hogejun 0:89c6aae3a486 232 * Writes a byte-data with mask into an extension register space.
hogejun 0:89c6aae3a486 233 *
hogejun 0:89c6aae3a486 234 * \return The value one, true, is returned for success and
hogejun 0:89c6aae3a486 235 * the value zero, false, is returned for failure.
hogejun 0:89c6aae3a486 236 */
hogejun 0:89c6aae3a486 237 uint8_t iSDIO::writeExtMask(uint8_t mio, uint8_t func, uint32_t addr, uint8_t mask, const uint8_t* src)
hogejun 0:89c6aae3a486 238 {
hogejun 0:89c6aae3a486 239 uint32_t arg =
hogejun 0:89c6aae3a486 240 (((uint32_t)mio & 0x1) << 31) |
hogejun 0:89c6aae3a486 241 (mio ? (((uint32_t)func & 0x7) << 28) : (((uint32_t)func & 0xF) << 27)) |
hogejun 0:89c6aae3a486 242 (0x1 << 26) |
hogejun 0:89c6aae3a486 243 ((addr & 0x1FFFF) << 9) |
hogejun 0:89c6aae3a486 244 mask;
hogejun 0:89c6aae3a486 245 return writeExt(arg, src, 1);
hogejun 0:89c6aae3a486 246 }
hogejun 0:89c6aae3a486 247
hogejun 0:89c6aae3a486 248
hogejun 0:89c6aae3a486 249 uint8_t iSDIO::waitResponse(uint32_t sequenceId)
hogejun 0:89c6aae3a486 250 {
hogejun 0:89c6aae3a486 251 uint8_t buffer[ISDIO_STATUS_QUEUE_SIZE];
hogejun 0:89c6aae3a486 252
hogejun 0:89c6aae3a486 253 _console->printf("\nWaiting response ");
hogejun 0:89c6aae3a486 254 uint8_t prev = 0xFF;
hogejun 0:89c6aae3a486 255 for (int i = 0; i < 20; ++i) {
hogejun 0:89c6aae3a486 256 memset(buffer, 0, ISDIO_STATUS_QUEUE_SIZE);
hogejun 0:89c6aae3a486 257 // Read command response status.
hogejun 0:89c6aae3a486 258 if (!readExtMemory(MIO_IO, FUNC1, ISDIO_STATUS_QUEUE, ISDIO_STATUS_QUEUE_SIZE, buffer)) {
hogejun 0:89c6aae3a486 259 return false;
hogejun 0:89c6aae3a486 260 }
hogejun 0:89c6aae3a486 261 uint8_t resp = get_u8(buffer + 8);
hogejun 0:89c6aae3a486 262 if (sequenceId == get_u32(buffer + 4)) {
hogejun 0:89c6aae3a486 263 if (prev != resp) {
hogejun 0:89c6aae3a486 264 switch (resp) {
hogejun 0:89c6aae3a486 265 case 0x00:
hogejun 0:89c6aae3a486 266 _console->printf("\n Initial");
hogejun 0:89c6aae3a486 267 break;
hogejun 0:89c6aae3a486 268 case 0x01:
hogejun 0:89c6aae3a486 269 _console->printf("\n Command Processing");
hogejun 0:89c6aae3a486 270 break;
hogejun 0:89c6aae3a486 271 case 0x02:
hogejun 0:89c6aae3a486 272 _console->printf("\n Command Rejected");
hogejun 0:89c6aae3a486 273 return false;
hogejun 0:89c6aae3a486 274 case 0x03:
hogejun 0:89c6aae3a486 275 _console->printf("\n Process Succeeded");
hogejun 0:89c6aae3a486 276 return true;
hogejun 0:89c6aae3a486 277 case 0x04:
hogejun 0:89c6aae3a486 278 _console->printf("\n Process Terminated");
hogejun 0:89c6aae3a486 279 return false;
hogejun 0:89c6aae3a486 280 default:
hogejun 0:89c6aae3a486 281 _console->printf("\n Process Failed ");
hogejun 0:89c6aae3a486 282 _console->printf("%x", resp);
hogejun 0:89c6aae3a486 283 return false;
hogejun 0:89c6aae3a486 284 }
hogejun 0:89c6aae3a486 285 prev = resp;
hogejun 0:89c6aae3a486 286 }
hogejun 0:89c6aae3a486 287 }
hogejun 0:89c6aae3a486 288 _console->printf(".");
hogejun 0:89c6aae3a486 289 wait_ms(1000);
hogejun 0:89c6aae3a486 290 }
hogejun 0:89c6aae3a486 291 return false;
hogejun 0:89c6aae3a486 292 }
hogejun 0:89c6aae3a486 293
hogejun 0:89c6aae3a486 294
hogejun 0:89c6aae3a486 295
hogejun 0:89c6aae3a486 296 void iSDIO::printByte(uint8_t value)
hogejun 0:89c6aae3a486 297 {
hogejun 0:89c6aae3a486 298 _console->printf("%x", value >> 4);
hogejun 0:89c6aae3a486 299 _console->printf("%x", value & 0xF);
hogejun 0:89c6aae3a486 300 }
hogejun 0:89c6aae3a486 301 void iSDIO::printBytes(uint8_t* p, uint32_t len)
hogejun 0:89c6aae3a486 302 {
hogejun 0:89c6aae3a486 303 for (int i = 0; i < len; ++i) {
hogejun 0:89c6aae3a486 304 printByte(p[i]);
hogejun 0:89c6aae3a486 305 }
hogejun 0:89c6aae3a486 306 }
hogejun 0:89c6aae3a486 307 void iSDIO::printHex(uint8_t* p, uint32_t len) {
hogejun 0:89c6aae3a486 308 int i = 0;
hogejun 0:89c6aae3a486 309 while (i < len) {
hogejun 0:89c6aae3a486 310 if ((i & 0xf) == 0) {
hogejun 0:89c6aae3a486 311 _console->printf("\n");
hogejun 0:89c6aae3a486 312 printByte(i >> 4);
hogejun 0:89c6aae3a486 313 _console->printf(": ");
hogejun 0:89c6aae3a486 314 }
hogejun 0:89c6aae3a486 315 printByte(*p++);
hogejun 0:89c6aae3a486 316 i++;
hogejun 0:89c6aae3a486 317 }
hogejun 0:89c6aae3a486 318 _console->printf("\n");
hogejun 0:89c6aae3a486 319 }