This is test program for running 192GC00(240 x 320 dot, 65K Color TFT LCD module ) on Star Board Orange.

Dependencies:   TextLCD mbed

Committer:
y_notsu
Date:
Fri Jan 21 12:51:26 2011 +0000
Revision:
0:0e2aded4edb0

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
y_notsu 0:0e2aded4edb0 1 /* mbed SDFileSystem Library, for providing file access to SD cards
y_notsu 0:0e2aded4edb0 2 * Copyright (c) 2008-2010, sford
y_notsu 0:0e2aded4edb0 3 *
y_notsu 0:0e2aded4edb0 4 * Permission is hereby granted, free of charge, to any person obtaining a copy
y_notsu 0:0e2aded4edb0 5 * of this software and associated documentation files (the "Software"), to deal
y_notsu 0:0e2aded4edb0 6 * in the Software without restriction, including without limitation the rights
y_notsu 0:0e2aded4edb0 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
y_notsu 0:0e2aded4edb0 8 * copies of the Software, and to permit persons to whom the Software is
y_notsu 0:0e2aded4edb0 9 * furnished to do so, subject to the following conditions:
y_notsu 0:0e2aded4edb0 10 *
y_notsu 0:0e2aded4edb0 11 * The above copyright notice and this permission notice shall be included in
y_notsu 0:0e2aded4edb0 12 * all copies or substantial portions of the Software.
y_notsu 0:0e2aded4edb0 13 *
y_notsu 0:0e2aded4edb0 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
y_notsu 0:0e2aded4edb0 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
y_notsu 0:0e2aded4edb0 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
y_notsu 0:0e2aded4edb0 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
y_notsu 0:0e2aded4edb0 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
y_notsu 0:0e2aded4edb0 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
y_notsu 0:0e2aded4edb0 20 * THE SOFTWARE.
y_notsu 0:0e2aded4edb0 21 */
y_notsu 0:0e2aded4edb0 22
y_notsu 0:0e2aded4edb0 23 //* Introduction
y_notsu 0:0e2aded4edb0 24 // * ------------
y_notsu 0:0e2aded4edb0 25 // * SD and MMC cards support a number of interfaces, but common to them all
y_notsu 0:0e2aded4edb0 26 // * is one based on SPI. This is the one I'm implmenting because it means
y_notsu 0:0e2aded4edb0 27 // * it is much more portable even though not so performant, and we already
y_notsu 0:0e2aded4edb0 28 // * have the mbed SPI Interface!
y_notsu 0:0e2aded4edb0 29 // *
y_notsu 0:0e2aded4edb0 30 // * The main reference I'm using is Chapter 7, "SPI Mode" of:
y_notsu 0:0e2aded4edb0 31 // * http://www.sdcard.org/developers/tech/sdcard/pls/Simplified_Physical_Layer_Spec.pdf
y_notsu 0:0e2aded4edb0 32 // *
y_notsu 0:0e2aded4edb0 33 // * SPI Startup
y_notsu 0:0e2aded4edb0 34 // * -----------
y_notsu 0:0e2aded4edb0 35 // * The SD card powers up in SD mode. The SPI interface mode is selected by
y_notsu 0:0e2aded4edb0 36 // * asserting CS low and sending the reset command (CMD0). The card will
y_notsu 0:0e2aded4edb0 37 // * respond with a (R1) response.
y_notsu 0:0e2aded4edb0 38 // *
y_notsu 0:0e2aded4edb0 39 // * CMD8 is optionally sent to determine the voltage range supported, and
y_notsu 0:0e2aded4edb0 40 // * indirectly determine whether it is a version 1.x SD/non-SD card or
y_notsu 0:0e2aded4edb0 41 // * version 2.x. I'll just ignore this for now.
y_notsu 0:0e2aded4edb0 42 // *
y_notsu 0:0e2aded4edb0 43 // * ACMD41 is repeatedly issued to initialise the card, until "in idle"
y_notsu 0:0e2aded4edb0 44 // * (bit 0) of the R1 response goes to '0', indicating it is initialised.
y_notsu 0:0e2aded4edb0 45 // *
y_notsu 0:0e2aded4edb0 46 // * You should also indicate whether the host supports High Capicity cards,
y_notsu 0:0e2aded4edb0 47 // * and check whether the card is high capacity - i'll also ignore this
y_notsu 0:0e2aded4edb0 48 // *
y_notsu 0:0e2aded4edb0 49 // * SPI Protocol
y_notsu 0:0e2aded4edb0 50 // * ------------
y_notsu 0:0e2aded4edb0 51 // * The SD SPI protocol is based on transactions made up of 8-bit words, with
y_notsu 0:0e2aded4edb0 52 //* the host starting every bus transaction by asserting the CS signal low. The
y_notsu 0:0e2aded4edb0 53 // * card always responds to commands, data blocks and errors.
y_notsu 0:0e2aded4edb0 54 // *
y_notsu 0:0e2aded4edb0 55 // * The protocol supports a CRC, but by default it is off (except for the
y_notsu 0:0e2aded4edb0 56 // * first reset CMD0, where the CRC can just be pre-calculated, and CMD8)
y_notsu 0:0e2aded4edb0 57 // * I'll leave the CRC off I think!
y_notsu 0:0e2aded4edb0 58 // *
y_notsu 0:0e2aded4edb0 59 // * Standard capacity cards have variable data block sizes, whereas High
y_notsu 0:0e2aded4edb0 60 // * Capacity cards fix the size of data block to 512 bytes. I'll therefore
y_notsu 0:0e2aded4edb0 61 // * just always use the Standard Capacity cards with a block size of 512 bytes.
y_notsu 0:0e2aded4edb0 62 // * This is set with CMD16.
y_notsu 0:0e2aded4edb0 63 // *
y_notsu 0:0e2aded4edb0 64 // * You can read and write single blocks (CMD17, CMD25) or multiple blocks
y_notsu 0:0e2aded4edb0 65 // * (CMD18, CMD25). For simplicity, I'll just use single block accesses. When
y_notsu 0:0e2aded4edb0 66 // * the card gets a read command, it responds with a response token, and then
y_notsu 0:0e2aded4edb0 67 // * a data token or an error.
y_notsu 0:0e2aded4edb0 68 // *
y_notsu 0:0e2aded4edb0 69 // * SPI Command Format
y_notsu 0:0e2aded4edb0 70 // * ------------------
y_notsu 0:0e2aded4edb0 71 // * Commands are 6-bytes long, containing the command, 32-bit argument, and CRC.
y_notsu 0:0e2aded4edb0 72 // *
y_notsu 0:0e2aded4edb0 73 // * +---------------+------------+------------+-----------+----------+--------------+
y_notsu 0:0e2aded4edb0 74 // * | 01 | cmd[5:0] | arg[31:24] | arg[23:16] | arg[15:8] | arg[7:0] | crc[6:0] | 1 |
y_notsu 0:0e2aded4edb0 75 // * +---------------+------------+------------+-----------+----------+--------------+
y_notsu 0:0e2aded4edb0 76 // *
y_notsu 0:0e2aded4edb0 77 // * As I'm not using CRC, I can fix that byte to what is needed for CMD0 (0x95)
y_notsu 0:0e2aded4edb0 78 // *
y_notsu 0:0e2aded4edb0 79 // * All Application Specific commands shall be preceded with APP_CMD (CMD55).
y_notsu 0:0e2aded4edb0 80 // *
y_notsu 0:0e2aded4edb0 81 // * SPI Response Format
y_notsu 0:0e2aded4edb0 82 // * -------------------
y_notsu 0:0e2aded4edb0 83 // * The main response format (R1) is a status byte (normally zero). Key flags:
y_notsu 0:0e2aded4edb0 84 // * idle - 1 if the card is in an idle state/initialising
y_notsu 0:0e2aded4edb0 85 // * cmd - 1 if an illegal command code was detected
y_notsu 0:0e2aded4edb0 86 // *
y_notsu 0:0e2aded4edb0 87 // * +-------------------------------------------------+
y_notsu 0:0e2aded4edb0 88 // * R1 | 0 | arg | addr | seq | crc | cmd | erase | idle |
y_notsu 0:0e2aded4edb0 89 // * +-------------------------------------------------+
y_notsu 0:0e2aded4edb0 90 // *
y_notsu 0:0e2aded4edb0 91 // * R1b is the same, except it is followed by a busy signal (zeros) until
y_notsu 0:0e2aded4edb0 92 // * the first non-zero byte when it is ready again.
y_notsu 0:0e2aded4edb0 93 // *
y_notsu 0:0e2aded4edb0 94 // * Data Response Token
y_notsu 0:0e2aded4edb0 95 // * -------------------
y_notsu 0:0e2aded4edb0 96 // * Every data block written to the card is acknowledged by a byte
y_notsu 0:0e2aded4edb0 97 // * response token
y_notsu 0:0e2aded4edb0 98 // *
y_notsu 0:0e2aded4edb0 99 // * +----------------------+
y_notsu 0:0e2aded4edb0 100 // * | xxx | 0 | status | 1 |
y_notsu 0:0e2aded4edb0 101 // * +----------------------+
y_notsu 0:0e2aded4edb0 102 // * 010 - OK!
y_notsu 0:0e2aded4edb0 103 // * 101 - CRC Error
y_notsu 0:0e2aded4edb0 104 // * 110 - Write Error
y_notsu 0:0e2aded4edb0 105 // *
y_notsu 0:0e2aded4edb0 106 // * Single Block Read and Write
y_notsu 0:0e2aded4edb0 107 // * ---------------------------
y_notsu 0:0e2aded4edb0 108 // *
y_notsu 0:0e2aded4edb0 109 // * Block transfers have a byte header, followed by the data, followed
y_notsu 0:0e2aded4edb0 110 // * by a 16-bit CRC. In our case, the data will always be 512 bytes.
y_notsu 0:0e2aded4edb0 111 // *
y_notsu 0:0e2aded4edb0 112 // * +------+---------+---------+- - - -+---------+-----------+----------+
y_notsu 0:0e2aded4edb0 113 // * | 0xFE | data[0] | data[1] | | data[n] | crc[15:8] | crc[7:0] |
y_notsu 0:0e2aded4edb0 114 // * +------+---------+---------+- - - -+---------+-----------+----------+
y_notsu 0:0e2aded4edb0 115 // */
y_notsu 0:0e2aded4edb0 116 //
y_notsu 0:0e2aded4edb0 117 //*
y_notsu 0:0e2aded4edb0 118 // * Comment: Changes for SDHC support till 32GB
y_notsu 0:0e2aded4edb0 119 // * Name: KB
y_notsu 0:0e2aded4edb0 120 // * Date: 07/24/2010
y_notsu 0:0e2aded4edb0 121 // * Release: 0.1
y_notsu 0:0e2aded4edb0 122 // */
y_notsu 0:0e2aded4edb0 123
y_notsu 0:0e2aded4edb0 124 /* mbed SDFileSystem Library, for providing file access to SD cards
y_notsu 0:0e2aded4edb0 125 * Copyright (c) 2008-2010, sford
y_notsu 0:0e2aded4edb0 126 *
y_notsu 0:0e2aded4edb0 127 * Permission is hereby granted, free of charge, to any person obtaining a copy
y_notsu 0:0e2aded4edb0 128 * of this software and associated documentation files (the "Software"), to deal
y_notsu 0:0e2aded4edb0 129 * in the Software without restriction, including without limitation the rights
y_notsu 0:0e2aded4edb0 130 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
y_notsu 0:0e2aded4edb0 131 * copies of the Software, and to permit persons to whom the Software is
y_notsu 0:0e2aded4edb0 132 * furnished to do so, subject to the following conditions:
y_notsu 0:0e2aded4edb0 133 *
y_notsu 0:0e2aded4edb0 134 * The above copyright notice and this permission notice shall be included in
y_notsu 0:0e2aded4edb0 135 * all copies or substantial portions of the Software.
y_notsu 0:0e2aded4edb0 136 *
y_notsu 0:0e2aded4edb0 137 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
y_notsu 0:0e2aded4edb0 138 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
y_notsu 0:0e2aded4edb0 139 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
y_notsu 0:0e2aded4edb0 140 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
y_notsu 0:0e2aded4edb0 141 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
y_notsu 0:0e2aded4edb0 142 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
y_notsu 0:0e2aded4edb0 143 * THE SOFTWARE.
y_notsu 0:0e2aded4edb0 144 */
y_notsu 0:0e2aded4edb0 145
y_notsu 0:0e2aded4edb0 146 //* Introduction
y_notsu 0:0e2aded4edb0 147 // * ------------
y_notsu 0:0e2aded4edb0 148 // * SD and MMC cards support a number of interfaces, but common to them all
y_notsu 0:0e2aded4edb0 149 // * is one based on SPI. This is the one I'm implmenting because it means
y_notsu 0:0e2aded4edb0 150 // * it is much more portable even though not so performant, and we already
y_notsu 0:0e2aded4edb0 151 // * have the mbed SPI Interface!
y_notsu 0:0e2aded4edb0 152 // *
y_notsu 0:0e2aded4edb0 153 // * The main reference I'm using is Chapter 7, "SPI Mode" of:
y_notsu 0:0e2aded4edb0 154 // * http://www.sdcard.org/developers/tech/sdcard/pls/Simplified_Physical_Layer_Spec.pdf
y_notsu 0:0e2aded4edb0 155 // *
y_notsu 0:0e2aded4edb0 156 // * SPI Startup
y_notsu 0:0e2aded4edb0 157 // * -----------
y_notsu 0:0e2aded4edb0 158 // * The SD card powers up in SD mode. The SPI interface mode is selected by
y_notsu 0:0e2aded4edb0 159 // * asserting CS low and sending the reset command (CMD0). The card will
y_notsu 0:0e2aded4edb0 160 // * respond with a (R1) response.
y_notsu 0:0e2aded4edb0 161 // *
y_notsu 0:0e2aded4edb0 162 // * CMD8 is optionally sent to determine the voltage range supported, and
y_notsu 0:0e2aded4edb0 163 // * indirectly determine whether it is a version 1.x SD/non-SD card or
y_notsu 0:0e2aded4edb0 164 // * version 2.x. I'll just ignore this for now.
y_notsu 0:0e2aded4edb0 165 // *
y_notsu 0:0e2aded4edb0 166 // * ACMD41 is repeatedly issued to initialise the card, until "in idle"
y_notsu 0:0e2aded4edb0 167 // * (bit 0) of the R1 response goes to '0', indicating it is initialised.
y_notsu 0:0e2aded4edb0 168 // *
y_notsu 0:0e2aded4edb0 169 // * You should also indicate whether the host supports High Capicity cards,
y_notsu 0:0e2aded4edb0 170 // * and check whether the card is high capacity - i'll also ignore this
y_notsu 0:0e2aded4edb0 171 // *
y_notsu 0:0e2aded4edb0 172 // * SPI Protocol
y_notsu 0:0e2aded4edb0 173 // * ------------
y_notsu 0:0e2aded4edb0 174 // * The SD SPI protocol is based on transactions made up of 8-bit words, with
y_notsu 0:0e2aded4edb0 175 //* the host starting every bus transaction by asserting the CS signal low. The
y_notsu 0:0e2aded4edb0 176 // * card always responds to commands, data blocks and errors.
y_notsu 0:0e2aded4edb0 177 // *
y_notsu 0:0e2aded4edb0 178 // * The protocol supports a CRC, but by default it is off (except for the
y_notsu 0:0e2aded4edb0 179 // * first reset CMD0, where the CRC can just be pre-calculated, and CMD8)
y_notsu 0:0e2aded4edb0 180 // * I'll leave the CRC off I think!
y_notsu 0:0e2aded4edb0 181 // *
y_notsu 0:0e2aded4edb0 182 // * Standard capacity cards have variable data block sizes, whereas High
y_notsu 0:0e2aded4edb0 183 // * Capacity cards fix the size of data block to 512 bytes. I'll therefore
y_notsu 0:0e2aded4edb0 184 // * just always use the Standard Capacity cards with a block size of 512 bytes.
y_notsu 0:0e2aded4edb0 185 // * This is set with CMD16.
y_notsu 0:0e2aded4edb0 186 // *
y_notsu 0:0e2aded4edb0 187 // * You can read and write single blocks (CMD17, CMD25) or multiple blocks
y_notsu 0:0e2aded4edb0 188 // * (CMD18, CMD25). For simplicity, I'll just use single block accesses. When
y_notsu 0:0e2aded4edb0 189 // * the card gets a read command, it responds with a response token, and then
y_notsu 0:0e2aded4edb0 190 // * a data token or an error.
y_notsu 0:0e2aded4edb0 191 // *
y_notsu 0:0e2aded4edb0 192 // * SPI Command Format
y_notsu 0:0e2aded4edb0 193 // * ------------------
y_notsu 0:0e2aded4edb0 194 // * Commands are 6-bytes long, containing the command, 32-bit argument, and CRC.
y_notsu 0:0e2aded4edb0 195 // *
y_notsu 0:0e2aded4edb0 196 // * +---------------+------------+------------+-----------+----------+--------------+
y_notsu 0:0e2aded4edb0 197 // * | 01 | cmd[5:0] | arg[31:24] | arg[23:16] | arg[15:8] | arg[7:0] | crc[6:0] | 1 |
y_notsu 0:0e2aded4edb0 198 // * +---------------+------------+------------+-----------+----------+--------------+
y_notsu 0:0e2aded4edb0 199 // *
y_notsu 0:0e2aded4edb0 200 // * As I'm not using CRC, I can fix that byte to what is needed for CMD0 (0x95)
y_notsu 0:0e2aded4edb0 201 // *
y_notsu 0:0e2aded4edb0 202 // * All Application Specific commands shall be preceded with APP_CMD (CMD55).
y_notsu 0:0e2aded4edb0 203 // *
y_notsu 0:0e2aded4edb0 204 // * SPI Response Format
y_notsu 0:0e2aded4edb0 205 // * -------------------
y_notsu 0:0e2aded4edb0 206 // * The main response format (R1) is a status byte (normally zero). Key flags:
y_notsu 0:0e2aded4edb0 207 // * idle - 1 if the card is in an idle state/initialising
y_notsu 0:0e2aded4edb0 208 // * cmd - 1 if an illegal command code was detected
y_notsu 0:0e2aded4edb0 209 // *
y_notsu 0:0e2aded4edb0 210 // * +-------------------------------------------------+
y_notsu 0:0e2aded4edb0 211 // * R1 | 0 | arg | addr | seq | crc | cmd | erase | idle |
y_notsu 0:0e2aded4edb0 212 // * +-------------------------------------------------+
y_notsu 0:0e2aded4edb0 213 // *
y_notsu 0:0e2aded4edb0 214 // * R1b is the same, except it is followed by a busy signal (zeros) until
y_notsu 0:0e2aded4edb0 215 // * the first non-zero byte when it is ready again.
y_notsu 0:0e2aded4edb0 216 // *
y_notsu 0:0e2aded4edb0 217 // * Data Response Token
y_notsu 0:0e2aded4edb0 218 // * -------------------
y_notsu 0:0e2aded4edb0 219 // * Every data block written to the card is acknowledged by a byte
y_notsu 0:0e2aded4edb0 220 // * response token
y_notsu 0:0e2aded4edb0 221 // *
y_notsu 0:0e2aded4edb0 222 // * +----------------------+
y_notsu 0:0e2aded4edb0 223 // * | xxx | 0 | status | 1 |
y_notsu 0:0e2aded4edb0 224 // * +----------------------+
y_notsu 0:0e2aded4edb0 225 // * 010 - OK!
y_notsu 0:0e2aded4edb0 226 // * 101 - CRC Error
y_notsu 0:0e2aded4edb0 227 // * 110 - Write Error
y_notsu 0:0e2aded4edb0 228 // *
y_notsu 0:0e2aded4edb0 229 // * Single Block Read and Write
y_notsu 0:0e2aded4edb0 230 // * ---------------------------
y_notsu 0:0e2aded4edb0 231 // *
y_notsu 0:0e2aded4edb0 232 // * Block transfers have a byte header, followed by the data, followed
y_notsu 0:0e2aded4edb0 233 // * by a 16-bit CRC. In our case, the data will always be 512 bytes.
y_notsu 0:0e2aded4edb0 234 // *
y_notsu 0:0e2aded4edb0 235 // * +------+---------+---------+- - - -+---------+-----------+----------+
y_notsu 0:0e2aded4edb0 236 // * | 0xFE | data[0] | data[1] | | data[n] | crc[15:8] | crc[7:0] |
y_notsu 0:0e2aded4edb0 237 // * +------+---------+---------+- - - -+---------+-----------+----------+
y_notsu 0:0e2aded4edb0 238 // */
y_notsu 0:0e2aded4edb0 239 //
y_notsu 0:0e2aded4edb0 240 //*
y_notsu 0:0e2aded4edb0 241 // * Comment: Changes for SDHC support till 32GB
y_notsu 0:0e2aded4edb0 242 // * Name: KB
y_notsu 0:0e2aded4edb0 243 // * Date: 07/24/2010
y_notsu 0:0e2aded4edb0 244 // * Release: 0.1
y_notsu 0:0e2aded4edb0 245 // */
y_notsu 0:0e2aded4edb0 246
y_notsu 0:0e2aded4edb0 247 #include "SDHCFileSystem.h"
y_notsu 0:0e2aded4edb0 248
y_notsu 0:0e2aded4edb0 249 #define DEBUG
y_notsu 0:0e2aded4edb0 250 #define SD_COMMAND_TIMEOUT 5000
y_notsu 0:0e2aded4edb0 251
y_notsu 0:0e2aded4edb0 252
y_notsu 0:0e2aded4edb0 253 SDFileSystem::SDFileSystem(PinName mosi, PinName miso, PinName sclk, PinName cs, const char* name) :
y_notsu 0:0e2aded4edb0 254 FATFileSystem(name), _spi(mosi, miso, sclk), _cs(cs) {
y_notsu 0:0e2aded4edb0 255 _cs = 1;
y_notsu 0:0e2aded4edb0 256 }
y_notsu 0:0e2aded4edb0 257
y_notsu 0:0e2aded4edb0 258 #define R1_IDLE_STATE (1 << 0)
y_notsu 0:0e2aded4edb0 259 #define R1_ERASE_RESET (1 << 1)
y_notsu 0:0e2aded4edb0 260 #define R1_ILLEGAL_COMMAND (1 << 2)
y_notsu 0:0e2aded4edb0 261 #define R1_COM_CRC_ERROR (1 << 3)
y_notsu 0:0e2aded4edb0 262 #define R1_ERASE_SEQUENCE_ERROR (1 << 4)
y_notsu 0:0e2aded4edb0 263 #define R1_ADDRESS_ERROR (1 << 5)
y_notsu 0:0e2aded4edb0 264 #define R1_PARAMETER_ERROR (1 << 6)
y_notsu 0:0e2aded4edb0 265
y_notsu 0:0e2aded4edb0 266 // Types
y_notsu 0:0e2aded4edb0 267 // - v1.x Standard Capacity
y_notsu 0:0e2aded4edb0 268 // - v2.x Standard Capacity
y_notsu 0:0e2aded4edb0 269 // - v2.x High Capacity
y_notsu 0:0e2aded4edb0 270 // - Not recognised as an SD Card
y_notsu 0:0e2aded4edb0 271
y_notsu 0:0e2aded4edb0 272 #define SDCARD_FAIL 0
y_notsu 0:0e2aded4edb0 273 #define SDCARD_V1 1
y_notsu 0:0e2aded4edb0 274 #define SDCARD_V2 2
y_notsu 0:0e2aded4edb0 275 #define SDCARD_V2HC 3
y_notsu 0:0e2aded4edb0 276
y_notsu 0:0e2aded4edb0 277 int SDFileSystem::initialise_card() {
y_notsu 0:0e2aded4edb0 278 // Set to 100kHz for initialisation, and clock card with cs = 1
y_notsu 0:0e2aded4edb0 279 _spi.frequency(40000000);
y_notsu 0:0e2aded4edb0 280 _cs = 1;
y_notsu 0:0e2aded4edb0 281 for(int i=0; i<16; i++) {
y_notsu 0:0e2aded4edb0 282 _spi.write(0xFF);
y_notsu 0:0e2aded4edb0 283 }
y_notsu 0:0e2aded4edb0 284
y_notsu 0:0e2aded4edb0 285 // send CMD0, should return with all zeros except IDLE STATE set (bit 0)
y_notsu 0:0e2aded4edb0 286 if(_cmd(0, 0) != R1_IDLE_STATE) {
y_notsu 0:0e2aded4edb0 287 fprintf(stderr, "No disk, or could not put SD card in to SPI idle state\n");
y_notsu 0:0e2aded4edb0 288 return SDCARD_FAIL;
y_notsu 0:0e2aded4edb0 289 }
y_notsu 0:0e2aded4edb0 290
y_notsu 0:0e2aded4edb0 291 // send CMD8 to determine whther it is ver 2.x
y_notsu 0:0e2aded4edb0 292 int r = _cmd8();
y_notsu 0:0e2aded4edb0 293 if(r == R1_IDLE_STATE) {
y_notsu 0:0e2aded4edb0 294 return initialise_card_v2();
y_notsu 0:0e2aded4edb0 295 } else if(r == (R1_IDLE_STATE | R1_ILLEGAL_COMMAND)) {
y_notsu 0:0e2aded4edb0 296 return initialise_card_v1();
y_notsu 0:0e2aded4edb0 297 } else {
y_notsu 0:0e2aded4edb0 298 fprintf(stderr, "Not in idle state after sending CMD8 (not an SD card?)\n");
y_notsu 0:0e2aded4edb0 299 return SDCARD_FAIL;
y_notsu 0:0e2aded4edb0 300 }
y_notsu 0:0e2aded4edb0 301 }
y_notsu 0:0e2aded4edb0 302
y_notsu 0:0e2aded4edb0 303 int SDFileSystem::initialise_card_v1() {
y_notsu 0:0e2aded4edb0 304 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) {
y_notsu 0:0e2aded4edb0 305 _cmd(55, 0);
y_notsu 0:0e2aded4edb0 306 if(_cmd(41, 0) == 0) {
y_notsu 0:0e2aded4edb0 307 cdv = 512;
y_notsu 0:0e2aded4edb0 308 #ifdef DEBUG
y_notsu 0:0e2aded4edb0 309 printf("\n\rInit: SEDCARD_V1\n\r");
y_notsu 0:0e2aded4edb0 310 #endif
y_notsu 0:0e2aded4edb0 311 return SDCARD_V1;
y_notsu 0:0e2aded4edb0 312 }
y_notsu 0:0e2aded4edb0 313 }
y_notsu 0:0e2aded4edb0 314
y_notsu 0:0e2aded4edb0 315 fprintf(stderr, "Timeout waiting for v1.x card\n");
y_notsu 0:0e2aded4edb0 316 return SDCARD_FAIL;
y_notsu 0:0e2aded4edb0 317 }
y_notsu 0:0e2aded4edb0 318
y_notsu 0:0e2aded4edb0 319 int SDFileSystem::initialise_card_v2() {
y_notsu 0:0e2aded4edb0 320
y_notsu 0:0e2aded4edb0 321 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) {
y_notsu 0:0e2aded4edb0 322 wait_ms(50);
y_notsu 0:0e2aded4edb0 323 _cmd58();
y_notsu 0:0e2aded4edb0 324 _cmd(55, 0);
y_notsu 0:0e2aded4edb0 325 if(_cmd(41, 0x40000000) == 0) {
y_notsu 0:0e2aded4edb0 326 _cmd58();
y_notsu 0:0e2aded4edb0 327 #ifdef DEBUG
y_notsu 0:0e2aded4edb0 328 printf("\n\rInit: SDCARD_V2\n\r");
y_notsu 0:0e2aded4edb0 329 #endif
y_notsu 0:0e2aded4edb0 330 cdv = 1;
y_notsu 0:0e2aded4edb0 331 return SDCARD_V2;
y_notsu 0:0e2aded4edb0 332 }
y_notsu 0:0e2aded4edb0 333 }
y_notsu 0:0e2aded4edb0 334
y_notsu 0:0e2aded4edb0 335 fprintf(stderr, "Timeout waiting for v2.x card\n");
y_notsu 0:0e2aded4edb0 336 return SDCARD_FAIL;
y_notsu 0:0e2aded4edb0 337 }
y_notsu 0:0e2aded4edb0 338
y_notsu 0:0e2aded4edb0 339 int SDFileSystem::disk_initialize() {
y_notsu 0:0e2aded4edb0 340
y_notsu 0:0e2aded4edb0 341 int i = initialise_card();
y_notsu 0:0e2aded4edb0 342 #ifdef DEBUG
y_notsu 0:0e2aded4edb0 343 printf("init card = %d\n", i);
y_notsu 0:0e2aded4edb0 344 #endif
y_notsu 0:0e2aded4edb0 345 _sectors = _sd_sectors();
y_notsu 0:0e2aded4edb0 346
y_notsu 0:0e2aded4edb0 347 // Set block length to 512 (CMD16)
y_notsu 0:0e2aded4edb0 348 if(_cmd(16, 512) != 0) {
y_notsu 0:0e2aded4edb0 349 fprintf(stderr, "Set 512-byte block timed out\n");
y_notsu 0:0e2aded4edb0 350 return 1;
y_notsu 0:0e2aded4edb0 351 }
y_notsu 0:0e2aded4edb0 352
y_notsu 0:0e2aded4edb0 353 _spi.frequency(40000000); // Set to 1MHz for data transfer
y_notsu 0:0e2aded4edb0 354 return 0;
y_notsu 0:0e2aded4edb0 355 }
y_notsu 0:0e2aded4edb0 356
y_notsu 0:0e2aded4edb0 357 int SDFileSystem::disk_write(const char *buffer, int block_number) {
y_notsu 0:0e2aded4edb0 358 // set write address for single block (CMD24)
y_notsu 0:0e2aded4edb0 359 if(_cmd(24, block_number * cdv) != 0) {
y_notsu 0:0e2aded4edb0 360 return 1;
y_notsu 0:0e2aded4edb0 361 }
y_notsu 0:0e2aded4edb0 362
y_notsu 0:0e2aded4edb0 363 // send the data block
y_notsu 0:0e2aded4edb0 364 _write(buffer, 512);
y_notsu 0:0e2aded4edb0 365 return 0;
y_notsu 0:0e2aded4edb0 366 }
y_notsu 0:0e2aded4edb0 367
y_notsu 0:0e2aded4edb0 368 int SDFileSystem::disk_read(char *buffer, int block_number) {
y_notsu 0:0e2aded4edb0 369 // set read address for single block (CMD17)
y_notsu 0:0e2aded4edb0 370 if(_cmd(17, block_number * cdv) != 0) {
y_notsu 0:0e2aded4edb0 371 return 1;
y_notsu 0:0e2aded4edb0 372 }
y_notsu 0:0e2aded4edb0 373
y_notsu 0:0e2aded4edb0 374 // receive the data
y_notsu 0:0e2aded4edb0 375 _read(buffer, 512);
y_notsu 0:0e2aded4edb0 376 return 0;
y_notsu 0:0e2aded4edb0 377 }
y_notsu 0:0e2aded4edb0 378
y_notsu 0:0e2aded4edb0 379 int SDFileSystem::disk_status() { return 0; }
y_notsu 0:0e2aded4edb0 380 int SDFileSystem::disk_sync() { return 0; }
y_notsu 0:0e2aded4edb0 381 int SDFileSystem::disk_sectors() { return _sectors; }
y_notsu 0:0e2aded4edb0 382
y_notsu 0:0e2aded4edb0 383 // PRIVATE FUNCTIONS
y_notsu 0:0e2aded4edb0 384
y_notsu 0:0e2aded4edb0 385 int SDFileSystem::_cmd(int cmd, int arg) {
y_notsu 0:0e2aded4edb0 386 _cs = 0;
y_notsu 0:0e2aded4edb0 387
y_notsu 0:0e2aded4edb0 388 // send a command
y_notsu 0:0e2aded4edb0 389 _spi.write(0x40 | cmd);
y_notsu 0:0e2aded4edb0 390 _spi.write(arg >> 24);
y_notsu 0:0e2aded4edb0 391 _spi.write(arg >> 16);
y_notsu 0:0e2aded4edb0 392 _spi.write(arg >> 8);
y_notsu 0:0e2aded4edb0 393 _spi.write(arg >> 0);
y_notsu 0:0e2aded4edb0 394 _spi.write(0x95);
y_notsu 0:0e2aded4edb0 395
y_notsu 0:0e2aded4edb0 396 // wait for the repsonse (response[7] == 0)
y_notsu 0:0e2aded4edb0 397 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) {
y_notsu 0:0e2aded4edb0 398 int response = _spi.write(0xFF);
y_notsu 0:0e2aded4edb0 399 if(!(response & 0x80)) {
y_notsu 0:0e2aded4edb0 400 _cs = 1;
y_notsu 0:0e2aded4edb0 401 _spi.write(0xFF);
y_notsu 0:0e2aded4edb0 402 return response;
y_notsu 0:0e2aded4edb0 403 }
y_notsu 0:0e2aded4edb0 404 }
y_notsu 0:0e2aded4edb0 405 _cs = 1;
y_notsu 0:0e2aded4edb0 406 _spi.write(0xFF);
y_notsu 0:0e2aded4edb0 407 return -1; // timeout
y_notsu 0:0e2aded4edb0 408 }
y_notsu 0:0e2aded4edb0 409 int SDFileSystem::_cmdx(int cmd, int arg) {
y_notsu 0:0e2aded4edb0 410 _cs = 0;
y_notsu 0:0e2aded4edb0 411
y_notsu 0:0e2aded4edb0 412 // send a command
y_notsu 0:0e2aded4edb0 413 _spi.write(0x40 | cmd);
y_notsu 0:0e2aded4edb0 414 _spi.write(arg >> 24);
y_notsu 0:0e2aded4edb0 415 _spi.write(arg >> 16);
y_notsu 0:0e2aded4edb0 416 _spi.write(arg >> 8);
y_notsu 0:0e2aded4edb0 417 _spi.write(arg >> 0);
y_notsu 0:0e2aded4edb0 418 _spi.write(0x95);
y_notsu 0:0e2aded4edb0 419
y_notsu 0:0e2aded4edb0 420 // wait for the repsonse (response[7] == 0)
y_notsu 0:0e2aded4edb0 421 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) {
y_notsu 0:0e2aded4edb0 422 int response = _spi.write(0xFF);
y_notsu 0:0e2aded4edb0 423 if(!(response & 0x80)) {
y_notsu 0:0e2aded4edb0 424 return response;
y_notsu 0:0e2aded4edb0 425 }
y_notsu 0:0e2aded4edb0 426 }
y_notsu 0:0e2aded4edb0 427 _cs = 1;
y_notsu 0:0e2aded4edb0 428 _spi.write(0xFF);
y_notsu 0:0e2aded4edb0 429 return -1; // timeout
y_notsu 0:0e2aded4edb0 430 }
y_notsu 0:0e2aded4edb0 431
y_notsu 0:0e2aded4edb0 432
y_notsu 0:0e2aded4edb0 433 int SDFileSystem::_cmd58() {
y_notsu 0:0e2aded4edb0 434 _cs = 0;
y_notsu 0:0e2aded4edb0 435 int arg = 0;
y_notsu 0:0e2aded4edb0 436
y_notsu 0:0e2aded4edb0 437 // send a command
y_notsu 0:0e2aded4edb0 438 _spi.write(0x40 | 58);
y_notsu 0:0e2aded4edb0 439 _spi.write(arg >> 24);
y_notsu 0:0e2aded4edb0 440 _spi.write(arg >> 16);
y_notsu 0:0e2aded4edb0 441 _spi.write(arg >> 8);
y_notsu 0:0e2aded4edb0 442 _spi.write(arg >> 0);
y_notsu 0:0e2aded4edb0 443 _spi.write(0x95);
y_notsu 0:0e2aded4edb0 444
y_notsu 0:0e2aded4edb0 445 // wait for the repsonse (response[7] == 0)
y_notsu 0:0e2aded4edb0 446 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) {
y_notsu 0:0e2aded4edb0 447 int response = _spi.write(0xFF);
y_notsu 0:0e2aded4edb0 448 if(!(response & 0x80)) {
y_notsu 0:0e2aded4edb0 449 int ocr = _spi.write(0xFF) << 24;
y_notsu 0:0e2aded4edb0 450 ocr |= _spi.write(0xFF) << 16;
y_notsu 0:0e2aded4edb0 451 ocr |= _spi.write(0xFF) << 8;
y_notsu 0:0e2aded4edb0 452 ocr |= _spi.write(0xFF) << 0;
y_notsu 0:0e2aded4edb0 453 // printf("OCR = 0x%08X\n", ocr);
y_notsu 0:0e2aded4edb0 454 _cs = 1;
y_notsu 0:0e2aded4edb0 455 _spi.write(0xFF);
y_notsu 0:0e2aded4edb0 456 return response;
y_notsu 0:0e2aded4edb0 457 }
y_notsu 0:0e2aded4edb0 458 }
y_notsu 0:0e2aded4edb0 459 _cs = 1;
y_notsu 0:0e2aded4edb0 460 _spi.write(0xFF);
y_notsu 0:0e2aded4edb0 461 return -1; // timeout
y_notsu 0:0e2aded4edb0 462 }
y_notsu 0:0e2aded4edb0 463
y_notsu 0:0e2aded4edb0 464 int SDFileSystem::_cmd8() {
y_notsu 0:0e2aded4edb0 465 _cs = 0;
y_notsu 0:0e2aded4edb0 466
y_notsu 0:0e2aded4edb0 467 // send a command
y_notsu 0:0e2aded4edb0 468 _spi.write(0x40 | 8); // CMD8
y_notsu 0:0e2aded4edb0 469 _spi.write(0x00); // reserved
y_notsu 0:0e2aded4edb0 470 _spi.write(0x00); // reserved
y_notsu 0:0e2aded4edb0 471 _spi.write(0x01); // 3.3v
y_notsu 0:0e2aded4edb0 472 _spi.write(0xAA); // check pattern
y_notsu 0:0e2aded4edb0 473 _spi.write(0x87); // crc
y_notsu 0:0e2aded4edb0 474
y_notsu 0:0e2aded4edb0 475 // wait for the repsonse (response[7] == 0)
y_notsu 0:0e2aded4edb0 476 for(int i=0; i<SD_COMMAND_TIMEOUT * 1000; i++) {
y_notsu 0:0e2aded4edb0 477 char response[5];
y_notsu 0:0e2aded4edb0 478 response[0] = _spi.write(0xFF);
y_notsu 0:0e2aded4edb0 479 if(!(response[0] & 0x80)) {
y_notsu 0:0e2aded4edb0 480 for(int j=1; j<5; j++) {
y_notsu 0:0e2aded4edb0 481 response[i] = _spi.write(0xFF);
y_notsu 0:0e2aded4edb0 482 }
y_notsu 0:0e2aded4edb0 483 _cs = 1;
y_notsu 0:0e2aded4edb0 484 _spi.write(0xFF);
y_notsu 0:0e2aded4edb0 485 return response[0];
y_notsu 0:0e2aded4edb0 486 }
y_notsu 0:0e2aded4edb0 487 }
y_notsu 0:0e2aded4edb0 488 _cs = 1;
y_notsu 0:0e2aded4edb0 489 _spi.write(0xFF);
y_notsu 0:0e2aded4edb0 490 return -1; // timeout
y_notsu 0:0e2aded4edb0 491 }
y_notsu 0:0e2aded4edb0 492
y_notsu 0:0e2aded4edb0 493 int SDFileSystem::_read(char *buffer, int length) {
y_notsu 0:0e2aded4edb0 494 _cs = 0;
y_notsu 0:0e2aded4edb0 495
y_notsu 0:0e2aded4edb0 496 // read until start byte (0xFF)
y_notsu 0:0e2aded4edb0 497 while(_spi.write(0xFF) != 0xFE);
y_notsu 0:0e2aded4edb0 498
y_notsu 0:0e2aded4edb0 499 // read data
y_notsu 0:0e2aded4edb0 500 for(int i=0; i<length; i++) {
y_notsu 0:0e2aded4edb0 501 buffer[i] = _spi.write(0xFF);
y_notsu 0:0e2aded4edb0 502 }
y_notsu 0:0e2aded4edb0 503 _spi.write(0xFF); // checksum
y_notsu 0:0e2aded4edb0 504 _spi.write(0xFF);
y_notsu 0:0e2aded4edb0 505
y_notsu 0:0e2aded4edb0 506 _cs = 1;
y_notsu 0:0e2aded4edb0 507 _spi.write(0xFF);
y_notsu 0:0e2aded4edb0 508 return 0;
y_notsu 0:0e2aded4edb0 509 }
y_notsu 0:0e2aded4edb0 510
y_notsu 0:0e2aded4edb0 511 int SDFileSystem::_write(const char *buffer, int length) {
y_notsu 0:0e2aded4edb0 512 _cs = 0;
y_notsu 0:0e2aded4edb0 513
y_notsu 0:0e2aded4edb0 514 // indicate start of block
y_notsu 0:0e2aded4edb0 515 _spi.write(0xFE);
y_notsu 0:0e2aded4edb0 516
y_notsu 0:0e2aded4edb0 517 // write the data
y_notsu 0:0e2aded4edb0 518 for(int i=0; i<length; i++) {
y_notsu 0:0e2aded4edb0 519 _spi.write(buffer[i]);
y_notsu 0:0e2aded4edb0 520 }
y_notsu 0:0e2aded4edb0 521
y_notsu 0:0e2aded4edb0 522 // write the checksum
y_notsu 0:0e2aded4edb0 523 _spi.write(0xFF);
y_notsu 0:0e2aded4edb0 524 _spi.write(0xFF);
y_notsu 0:0e2aded4edb0 525
y_notsu 0:0e2aded4edb0 526 // check the repsonse token
y_notsu 0:0e2aded4edb0 527 if((_spi.write(0xFF) & 0x1F) != 0x05) {
y_notsu 0:0e2aded4edb0 528 _cs = 1;
y_notsu 0:0e2aded4edb0 529 _spi.write(0xFF);
y_notsu 0:0e2aded4edb0 530 return 1;
y_notsu 0:0e2aded4edb0 531 }
y_notsu 0:0e2aded4edb0 532
y_notsu 0:0e2aded4edb0 533 // wait for write to finish
y_notsu 0:0e2aded4edb0 534 while(_spi.write(0xFF) == 0);
y_notsu 0:0e2aded4edb0 535
y_notsu 0:0e2aded4edb0 536 _cs = 1;
y_notsu 0:0e2aded4edb0 537 _spi.write(0xFF);
y_notsu 0:0e2aded4edb0 538 return 0;
y_notsu 0:0e2aded4edb0 539 }
y_notsu 0:0e2aded4edb0 540
y_notsu 0:0e2aded4edb0 541 static int ext_bits(char *data, int msb, int lsb) {
y_notsu 0:0e2aded4edb0 542 int bits = 0;
y_notsu 0:0e2aded4edb0 543 int size = 1 + msb - lsb;
y_notsu 0:0e2aded4edb0 544 for(int i=0; i<size; i++) {
y_notsu 0:0e2aded4edb0 545 int position = lsb + i;
y_notsu 0:0e2aded4edb0 546 int byte = 15 - (position >> 3);
y_notsu 0:0e2aded4edb0 547 int bit = position & 0x7;
y_notsu 0:0e2aded4edb0 548 int value = (data[byte] >> bit) & 1;
y_notsu 0:0e2aded4edb0 549 bits |= value << i;
y_notsu 0:0e2aded4edb0 550 }
y_notsu 0:0e2aded4edb0 551 return bits;
y_notsu 0:0e2aded4edb0 552 }
y_notsu 0:0e2aded4edb0 553
y_notsu 0:0e2aded4edb0 554 int SDFileSystem::_sd_sectors() {
y_notsu 0:0e2aded4edb0 555
y_notsu 0:0e2aded4edb0 556 int c_size, c_size_mult, read_bl_len;
y_notsu 0:0e2aded4edb0 557 int block_len, mult, blocknr, capacity;
y_notsu 0:0e2aded4edb0 558 int blocks, hc_c_size;
y_notsu 0:0e2aded4edb0 559 uint64_t hc_capacity;
y_notsu 0:0e2aded4edb0 560
y_notsu 0:0e2aded4edb0 561 // CMD9, Response R2 (R1 byte + 16-byte block read)
y_notsu 0:0e2aded4edb0 562 if(_cmdx(9, 0) != 0) {
y_notsu 0:0e2aded4edb0 563 fprintf(stderr, "Didn't get a response from the disk\n");
y_notsu 0:0e2aded4edb0 564 return 0;
y_notsu 0:0e2aded4edb0 565 }
y_notsu 0:0e2aded4edb0 566
y_notsu 0:0e2aded4edb0 567 char csd[16];
y_notsu 0:0e2aded4edb0 568 if(_read(csd, 16) != 0) {
y_notsu 0:0e2aded4edb0 569 fprintf(stderr, "Couldn't read csd response from disk\n");
y_notsu 0:0e2aded4edb0 570 return 0;
y_notsu 0:0e2aded4edb0 571 }
y_notsu 0:0e2aded4edb0 572
y_notsu 0:0e2aded4edb0 573 // csd_structure : csd[127:126]
y_notsu 0:0e2aded4edb0 574 // c_size : csd[73:62]
y_notsu 0:0e2aded4edb0 575 // c_size_mult : csd[49:47]
y_notsu 0:0e2aded4edb0 576 // read_bl_len : csd[83:80] - the *maximum* read block length
y_notsu 0:0e2aded4edb0 577
y_notsu 0:0e2aded4edb0 578 int csd_structure = ext_bits(csd, 127, 126);
y_notsu 0:0e2aded4edb0 579
y_notsu 0:0e2aded4edb0 580 #ifdef DEBUG
y_notsu 0:0e2aded4edb0 581 printf("\n\rCSD_STRUCT = %d\n", csd_structure);
y_notsu 0:0e2aded4edb0 582 #endif
y_notsu 0:0e2aded4edb0 583
y_notsu 0:0e2aded4edb0 584 switch (csd_structure){
y_notsu 0:0e2aded4edb0 585 case 0:
y_notsu 0:0e2aded4edb0 586 cdv = 512;
y_notsu 0:0e2aded4edb0 587 c_size = ext_bits(csd, 73, 62);
y_notsu 0:0e2aded4edb0 588 c_size_mult = ext_bits(csd, 49, 47);
y_notsu 0:0e2aded4edb0 589 read_bl_len = ext_bits(csd, 83, 80);
y_notsu 0:0e2aded4edb0 590
y_notsu 0:0e2aded4edb0 591 block_len = 1 << read_bl_len;
y_notsu 0:0e2aded4edb0 592 mult = 1 << (c_size_mult + 2);
y_notsu 0:0e2aded4edb0 593 blocknr = (c_size + 1) * mult;
y_notsu 0:0e2aded4edb0 594 capacity = blocknr * block_len;
y_notsu 0:0e2aded4edb0 595 blocks = capacity / 512;
y_notsu 0:0e2aded4edb0 596 #ifdef DEBUG
y_notsu 0:0e2aded4edb0 597 printf("\n\rSDCard\n\rc_size: %.4X \n\rcapacity: %.ld \n\rsectors: %d\n\r", c_size, capacity, blocks);
y_notsu 0:0e2aded4edb0 598 #endif
y_notsu 0:0e2aded4edb0 599 break;
y_notsu 0:0e2aded4edb0 600
y_notsu 0:0e2aded4edb0 601 case 1:
y_notsu 0:0e2aded4edb0 602 cdv = 1;
y_notsu 0:0e2aded4edb0 603 hc_c_size = ext_bits(csd, 63, 48);
y_notsu 0:0e2aded4edb0 604 int hc_read_bl_len = ext_bits(csd, 83, 80);
y_notsu 0:0e2aded4edb0 605 hc_capacity = hc_c_size+1;
y_notsu 0:0e2aded4edb0 606 blocks = (hc_c_size+1)*1024;
y_notsu 0:0e2aded4edb0 607 #ifdef DEBUG
y_notsu 0:0e2aded4edb0 608 printf("\n\rSDHC Card \n\rhc_c_size: %.4X \n\rcapacity: %.lld \n\rsectors: %d\n\r", hc_c_size, hc_capacity*512*1024, blocks);
y_notsu 0:0e2aded4edb0 609 #endif
y_notsu 0:0e2aded4edb0 610 break;
y_notsu 0:0e2aded4edb0 611
y_notsu 0:0e2aded4edb0 612 default:
y_notsu 0:0e2aded4edb0 613 fprintf(stderr, "This disk tastes funny! I only know about type 0 CSD structures\n");
y_notsu 0:0e2aded4edb0 614 return 0;
y_notsu 0:0e2aded4edb0 615 // break;
y_notsu 0:0e2aded4edb0 616 };
y_notsu 0:0e2aded4edb0 617 return blocks;
y_notsu 0:0e2aded4edb0 618 }