Animation demo with MIP8F_SPI_Ver60

Dependencies:   mbed MIP8F_SPI_Ver60 MIP8f_FRDM_LineBuffer_sample MIP8f_FRDM_TransferMode_sample

Introduction

Animation Demo. Some Goldfish swin in water, from left to right, from bottom to top. Color and monochrome version

Only for LPM027M128x (400x240) ,JDI DIsplay.

Other information , please refer to https://os.mbed.com/teams/JapanDisplayInc/code/MIP8f_FRDM_sample/

Usage

Copy Setting File and Image to micro SD-CARD. you can NOT use same sample color images of OTHER VERSION SAMPLE.

a) Download the following file corresponding to the target panel, and rename file identifier (.bin -> .zip), and unzip the file on micro SD Card's root directory.

LPM027M128x (400x240) :/media/uploads/JDI_Mbed_Team/goldfish_400x240.bin

b) Insert micro SD-CARD to FRDM-K64F. c) Upload binary file to FRDM-K64F.and push Reset Button.

Other information

refer to Usage on https://os.mbed.com/teams/JapanDisplayInc/code/MIP8f_FRDM_sample/

this Sample Code (.bin)

/media/uploads/JDI_Mbed_Team/mip8f_frdm_animation_sample.k64f.bin

Committer:
JDI_Mbed_Team
Date:
Tue Sep 04 06:44:01 2018 +0000
Revision:
0:33fe30a2b785
JDI_MIP8F sample

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JDI_Mbed_Team 0:33fe30a2b785 1 /* SD/MMC File System Library
JDI_Mbed_Team 0:33fe30a2b785 2 * Copyright (c) 2016 Neil Thiessen
JDI_Mbed_Team 0:33fe30a2b785 3 *
JDI_Mbed_Team 0:33fe30a2b785 4 * Licensed under the Apache License, Version 2.0 (the "License");
JDI_Mbed_Team 0:33fe30a2b785 5 * you may not use this file except in compliance with the License.
JDI_Mbed_Team 0:33fe30a2b785 6 * You may obtain a copy of the License at
JDI_Mbed_Team 0:33fe30a2b785 7 *
JDI_Mbed_Team 0:33fe30a2b785 8 * http://www.apache.org/licenses/LICENSE-2.0
JDI_Mbed_Team 0:33fe30a2b785 9 *
JDI_Mbed_Team 0:33fe30a2b785 10 * Unless required by applicable law or agreed to in writing, software
JDI_Mbed_Team 0:33fe30a2b785 11 * distributed under the License is distributed on an "AS IS" BASIS,
JDI_Mbed_Team 0:33fe30a2b785 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
JDI_Mbed_Team 0:33fe30a2b785 13 * See the License for the specific language governing permissions and
JDI_Mbed_Team 0:33fe30a2b785 14 * limitations under the License.
JDI_Mbed_Team 0:33fe30a2b785 15 */
JDI_Mbed_Team 0:33fe30a2b785 16
JDI_Mbed_Team 0:33fe30a2b785 17 #include "SDFileSystem.h"
JDI_Mbed_Team 0:33fe30a2b785 18 #include "diskio.h"
JDI_Mbed_Team 0:33fe30a2b785 19 #include "pinmap.h"
JDI_Mbed_Team 0:33fe30a2b785 20 #include "SDCRC.h"
JDI_Mbed_Team 0:33fe30a2b785 21
JDI_Mbed_Team 0:33fe30a2b785 22 SDFileSystem::SDFileSystem(PinName mosi, PinName miso, PinName sclk, PinName cs, const char* name, PinName cd, SwitchType cdtype, int hz)
JDI_Mbed_Team 0:33fe30a2b785 23 : FATFileSystem(name),
JDI_Mbed_Team 0:33fe30a2b785 24 m_Spi(mosi, miso, sclk),
JDI_Mbed_Team 0:33fe30a2b785 25 m_Cs(cs, 1),
JDI_Mbed_Team 0:33fe30a2b785 26 m_Cd(cd),
JDI_Mbed_Team 0:33fe30a2b785 27 m_FREQ(hz)
JDI_Mbed_Team 0:33fe30a2b785 28 {
JDI_Mbed_Team 0:33fe30a2b785 29 //Initialize the member variables
JDI_Mbed_Team 0:33fe30a2b785 30 m_CardType = CARD_NONE;
JDI_Mbed_Team 0:33fe30a2b785 31 m_Crc = true;
JDI_Mbed_Team 0:33fe30a2b785 32 m_LargeFrames = false;
JDI_Mbed_Team 0:33fe30a2b785 33 m_WriteValidation = true;
JDI_Mbed_Team 0:33fe30a2b785 34 m_Status = STA_NOINIT;
JDI_Mbed_Team 0:33fe30a2b785 35
JDI_Mbed_Team 0:33fe30a2b785 36 //Enable the internal pull-up resistor on MISO
JDI_Mbed_Team 0:33fe30a2b785 37 pin_mode(miso, PullUp);
JDI_Mbed_Team 0:33fe30a2b785 38
JDI_Mbed_Team 0:33fe30a2b785 39 //Configure the SPI bus
JDI_Mbed_Team 0:33fe30a2b785 40 m_Spi.format(8, 0);
JDI_Mbed_Team 0:33fe30a2b785 41
JDI_Mbed_Team 0:33fe30a2b785 42 //Configure the card detect pin
JDI_Mbed_Team 0:33fe30a2b785 43 if (cdtype == SWITCH_POS_NO) {
JDI_Mbed_Team 0:33fe30a2b785 44 m_Cd.mode(PullDown);
JDI_Mbed_Team 0:33fe30a2b785 45 m_CdAssert = 1;
JDI_Mbed_Team 0:33fe30a2b785 46 m_Cd.fall(this, &SDFileSystem::onCardRemoval);
JDI_Mbed_Team 0:33fe30a2b785 47 } else if (cdtype == SWITCH_POS_NC) {
JDI_Mbed_Team 0:33fe30a2b785 48 m_Cd.mode(PullDown);
JDI_Mbed_Team 0:33fe30a2b785 49 m_CdAssert = 0;
JDI_Mbed_Team 0:33fe30a2b785 50 m_Cd.rise(this, &SDFileSystem::onCardRemoval);
JDI_Mbed_Team 0:33fe30a2b785 51 } else if (cdtype == SWITCH_NEG_NO) {
JDI_Mbed_Team 0:33fe30a2b785 52 m_Cd.mode(PullUp);
JDI_Mbed_Team 0:33fe30a2b785 53 m_CdAssert = 0;
JDI_Mbed_Team 0:33fe30a2b785 54 m_Cd.rise(this, &SDFileSystem::onCardRemoval);
JDI_Mbed_Team 0:33fe30a2b785 55 } else if (cdtype == SWITCH_NEG_NC) {
JDI_Mbed_Team 0:33fe30a2b785 56 m_Cd.mode(PullUp);
JDI_Mbed_Team 0:33fe30a2b785 57 m_CdAssert = 1;
JDI_Mbed_Team 0:33fe30a2b785 58 m_Cd.fall(this, &SDFileSystem::onCardRemoval);
JDI_Mbed_Team 0:33fe30a2b785 59 } else {
JDI_Mbed_Team 0:33fe30a2b785 60 m_CdAssert = -1;
JDI_Mbed_Team 0:33fe30a2b785 61 }
JDI_Mbed_Team 0:33fe30a2b785 62 }
JDI_Mbed_Team 0:33fe30a2b785 63
JDI_Mbed_Team 0:33fe30a2b785 64 bool SDFileSystem::card_present()
JDI_Mbed_Team 0:33fe30a2b785 65 {
JDI_Mbed_Team 0:33fe30a2b785 66 //Check the card socket
JDI_Mbed_Team 0:33fe30a2b785 67 checkSocket();
JDI_Mbed_Team 0:33fe30a2b785 68
JDI_Mbed_Team 0:33fe30a2b785 69 //Return whether or not a card is present
JDI_Mbed_Team 0:33fe30a2b785 70 return !(m_Status & STA_NODISK);
JDI_Mbed_Team 0:33fe30a2b785 71 }
JDI_Mbed_Team 0:33fe30a2b785 72
JDI_Mbed_Team 0:33fe30a2b785 73 SDFileSystem::CardType SDFileSystem::card_type()
JDI_Mbed_Team 0:33fe30a2b785 74 {
JDI_Mbed_Team 0:33fe30a2b785 75 //Check the card socket
JDI_Mbed_Team 0:33fe30a2b785 76 checkSocket();
JDI_Mbed_Team 0:33fe30a2b785 77
JDI_Mbed_Team 0:33fe30a2b785 78 //Return the card type
JDI_Mbed_Team 0:33fe30a2b785 79 return m_CardType;
JDI_Mbed_Team 0:33fe30a2b785 80 }
JDI_Mbed_Team 0:33fe30a2b785 81
JDI_Mbed_Team 0:33fe30a2b785 82 bool SDFileSystem::crc()
JDI_Mbed_Team 0:33fe30a2b785 83 {
JDI_Mbed_Team 0:33fe30a2b785 84 //Return whether or not CRC is enabled
JDI_Mbed_Team 0:33fe30a2b785 85 return m_Crc;
JDI_Mbed_Team 0:33fe30a2b785 86 }
JDI_Mbed_Team 0:33fe30a2b785 87
JDI_Mbed_Team 0:33fe30a2b785 88 void SDFileSystem::crc(bool enabled)
JDI_Mbed_Team 0:33fe30a2b785 89 {
JDI_Mbed_Team 0:33fe30a2b785 90 //Check the card socket
JDI_Mbed_Team 0:33fe30a2b785 91 checkSocket();
JDI_Mbed_Team 0:33fe30a2b785 92
JDI_Mbed_Team 0:33fe30a2b785 93 //Just update the member variable if the card isn't initialized
JDI_Mbed_Team 0:33fe30a2b785 94 if (m_Status & STA_NOINIT) {
JDI_Mbed_Team 0:33fe30a2b785 95 m_Crc = enabled;
JDI_Mbed_Team 0:33fe30a2b785 96 return;
JDI_Mbed_Team 0:33fe30a2b785 97 }
JDI_Mbed_Team 0:33fe30a2b785 98
JDI_Mbed_Team 0:33fe30a2b785 99 //Enable or disable CRC
JDI_Mbed_Team 0:33fe30a2b785 100 if (enabled && !m_Crc) {
JDI_Mbed_Team 0:33fe30a2b785 101 //Send CMD59(0x00000001) to enable CRC
JDI_Mbed_Team 0:33fe30a2b785 102 m_Crc = true;
JDI_Mbed_Team 0:33fe30a2b785 103 commandTransaction(CMD59, 0x00000001);
JDI_Mbed_Team 0:33fe30a2b785 104 } else if (!enabled && m_Crc) {
JDI_Mbed_Team 0:33fe30a2b785 105 //Send CMD59(0x00000000) to disable CRC
JDI_Mbed_Team 0:33fe30a2b785 106 commandTransaction(CMD59, 0x00000000);
JDI_Mbed_Team 0:33fe30a2b785 107 m_Crc = false;
JDI_Mbed_Team 0:33fe30a2b785 108 }
JDI_Mbed_Team 0:33fe30a2b785 109 }
JDI_Mbed_Team 0:33fe30a2b785 110
JDI_Mbed_Team 0:33fe30a2b785 111 bool SDFileSystem::large_frames()
JDI_Mbed_Team 0:33fe30a2b785 112 {
JDI_Mbed_Team 0:33fe30a2b785 113 //Return whether or not 16-bit frames are enabled
JDI_Mbed_Team 0:33fe30a2b785 114 return m_LargeFrames;
JDI_Mbed_Team 0:33fe30a2b785 115 }
JDI_Mbed_Team 0:33fe30a2b785 116
JDI_Mbed_Team 0:33fe30a2b785 117 void SDFileSystem::large_frames(bool enabled)
JDI_Mbed_Team 0:33fe30a2b785 118 {
JDI_Mbed_Team 0:33fe30a2b785 119 //Set whether or not 16-bit frames are enabled
JDI_Mbed_Team 0:33fe30a2b785 120 m_LargeFrames = enabled;
JDI_Mbed_Team 0:33fe30a2b785 121 }
JDI_Mbed_Team 0:33fe30a2b785 122
JDI_Mbed_Team 0:33fe30a2b785 123 bool SDFileSystem::write_validation()
JDI_Mbed_Team 0:33fe30a2b785 124 {
JDI_Mbed_Team 0:33fe30a2b785 125 //Return whether or not write validation is enabled
JDI_Mbed_Team 0:33fe30a2b785 126 return m_WriteValidation;
JDI_Mbed_Team 0:33fe30a2b785 127 }
JDI_Mbed_Team 0:33fe30a2b785 128
JDI_Mbed_Team 0:33fe30a2b785 129 void SDFileSystem::write_validation(bool enabled)
JDI_Mbed_Team 0:33fe30a2b785 130 {
JDI_Mbed_Team 0:33fe30a2b785 131 //Set whether or not write validation is enabled
JDI_Mbed_Team 0:33fe30a2b785 132 m_WriteValidation = enabled;
JDI_Mbed_Team 0:33fe30a2b785 133 }
JDI_Mbed_Team 0:33fe30a2b785 134
JDI_Mbed_Team 0:33fe30a2b785 135 int SDFileSystem::unmount()
JDI_Mbed_Team 0:33fe30a2b785 136 {
JDI_Mbed_Team 0:33fe30a2b785 137 //Unmount the filesystem
JDI_Mbed_Team 0:33fe30a2b785 138 FATFileSystem::unmount();
JDI_Mbed_Team 0:33fe30a2b785 139
JDI_Mbed_Team 0:33fe30a2b785 140 //Change the status to not initialized, and the card type to unknown
JDI_Mbed_Team 0:33fe30a2b785 141 m_Status |= STA_NOINIT;
JDI_Mbed_Team 0:33fe30a2b785 142 m_CardType = CARD_UNKNOWN;
JDI_Mbed_Team 0:33fe30a2b785 143
JDI_Mbed_Team 0:33fe30a2b785 144 //Always succeeds
JDI_Mbed_Team 0:33fe30a2b785 145 return 0;
JDI_Mbed_Team 0:33fe30a2b785 146 }
JDI_Mbed_Team 0:33fe30a2b785 147
JDI_Mbed_Team 0:33fe30a2b785 148 int SDFileSystem::disk_initialize()
JDI_Mbed_Team 0:33fe30a2b785 149 {
JDI_Mbed_Team 0:33fe30a2b785 150 char token;
JDI_Mbed_Team 0:33fe30a2b785 151 unsigned int resp;
JDI_Mbed_Team 0:33fe30a2b785 152 Timer timer;
JDI_Mbed_Team 0:33fe30a2b785 153
JDI_Mbed_Team 0:33fe30a2b785 154 //Make sure there's a card in the socket before proceeding
JDI_Mbed_Team 0:33fe30a2b785 155 checkSocket();
JDI_Mbed_Team 0:33fe30a2b785 156 if (m_Status & STA_NODISK)
JDI_Mbed_Team 0:33fe30a2b785 157 return m_Status;
JDI_Mbed_Team 0:33fe30a2b785 158
JDI_Mbed_Team 0:33fe30a2b785 159 //Make sure we're not already initialized before proceeding
JDI_Mbed_Team 0:33fe30a2b785 160 if (!(m_Status & STA_NOINIT))
JDI_Mbed_Team 0:33fe30a2b785 161 return m_Status;
JDI_Mbed_Team 0:33fe30a2b785 162
JDI_Mbed_Team 0:33fe30a2b785 163 //Set the SPI frequency to 400kHz for initialization
JDI_Mbed_Team 0:33fe30a2b785 164 m_Spi.frequency(400000);
JDI_Mbed_Team 0:33fe30a2b785 165
JDI_Mbed_Team 0:33fe30a2b785 166 //Try to reset the card up to 3 times
JDI_Mbed_Team 0:33fe30a2b785 167 for (int f = 0; f < 3; f++) {
JDI_Mbed_Team 0:33fe30a2b785 168 //Send 80 dummy clocks with /CS deasserted and DI held high
JDI_Mbed_Team 0:33fe30a2b785 169 m_Cs = 1;
JDI_Mbed_Team 0:33fe30a2b785 170 for (int i = 0; i < 10; i++) {
JDI_Mbed_Team 0:33fe30a2b785 171 m_Spi.write(0xFF);
JDI_Mbed_Team 0:33fe30a2b785 172 }
JDI_Mbed_Team 0:33fe30a2b785 173
JDI_Mbed_Team 0:33fe30a2b785 174 //Send CMD0(0x00000000) to reset the card
JDI_Mbed_Team 0:33fe30a2b785 175 token = commandTransaction(CMD0, 0x00000000);
JDI_Mbed_Team 0:33fe30a2b785 176 if (token == 0x01) {
JDI_Mbed_Team 0:33fe30a2b785 177 break;
JDI_Mbed_Team 0:33fe30a2b785 178 }
JDI_Mbed_Team 0:33fe30a2b785 179 }
JDI_Mbed_Team 0:33fe30a2b785 180
JDI_Mbed_Team 0:33fe30a2b785 181 //Check if the card reset
JDI_Mbed_Team 0:33fe30a2b785 182 if (token != 0x01) {
JDI_Mbed_Team 0:33fe30a2b785 183 //Initialization failed
JDI_Mbed_Team 0:33fe30a2b785 184 m_CardType = CARD_UNKNOWN;
JDI_Mbed_Team 0:33fe30a2b785 185 return m_Status;
JDI_Mbed_Team 0:33fe30a2b785 186 }
JDI_Mbed_Team 0:33fe30a2b785 187
JDI_Mbed_Team 0:33fe30a2b785 188 //Send CMD59(0x00000001) to enable CRC if necessary
JDI_Mbed_Team 0:33fe30a2b785 189 if (m_Crc) {
JDI_Mbed_Team 0:33fe30a2b785 190 if (commandTransaction(CMD59, 0x00000001) != 0x01) {
JDI_Mbed_Team 0:33fe30a2b785 191 //Initialization failed
JDI_Mbed_Team 0:33fe30a2b785 192 m_CardType = CARD_UNKNOWN;
JDI_Mbed_Team 0:33fe30a2b785 193 return m_Status;
JDI_Mbed_Team 0:33fe30a2b785 194 }
JDI_Mbed_Team 0:33fe30a2b785 195 }
JDI_Mbed_Team 0:33fe30a2b785 196
JDI_Mbed_Team 0:33fe30a2b785 197 //Send CMD8(0x000001AA) to see if this is an SDCv2 card
JDI_Mbed_Team 0:33fe30a2b785 198 if (commandTransaction(CMD8, 0x000001AA, &resp) == 0x01) {
JDI_Mbed_Team 0:33fe30a2b785 199 //This is an SDCv2 card, get the 32-bit return value and verify the voltage range/check pattern
JDI_Mbed_Team 0:33fe30a2b785 200 if ((resp & 0xFFF) != 0x1AA) {
JDI_Mbed_Team 0:33fe30a2b785 201 //Initialization failed
JDI_Mbed_Team 0:33fe30a2b785 202 m_CardType = CARD_UNKNOWN;
JDI_Mbed_Team 0:33fe30a2b785 203 return m_Status;
JDI_Mbed_Team 0:33fe30a2b785 204 }
JDI_Mbed_Team 0:33fe30a2b785 205
JDI_Mbed_Team 0:33fe30a2b785 206 //Send CMD58(0x00000000) to read the OCR, and verify that the card supports 3.2-3.3V
JDI_Mbed_Team 0:33fe30a2b785 207 if (commandTransaction(CMD58, 0x00000000, &resp) != 0x01 || !(resp & (1 << 20))) {
JDI_Mbed_Team 0:33fe30a2b785 208 //Initialization failed
JDI_Mbed_Team 0:33fe30a2b785 209 m_CardType = CARD_UNKNOWN;
JDI_Mbed_Team 0:33fe30a2b785 210 return m_Status;
JDI_Mbed_Team 0:33fe30a2b785 211 }
JDI_Mbed_Team 0:33fe30a2b785 212
JDI_Mbed_Team 0:33fe30a2b785 213 //Try to initialize the card using ACMD41(0x40100000) for up to 2 seconds
JDI_Mbed_Team 0:33fe30a2b785 214 timer.start();
JDI_Mbed_Team 0:33fe30a2b785 215 do {
JDI_Mbed_Team 0:33fe30a2b785 216 token = commandTransaction(ACMD41, 0x40100000);
JDI_Mbed_Team 0:33fe30a2b785 217 } while (token == 0x01 && timer.read_ms() < 2000);
JDI_Mbed_Team 0:33fe30a2b785 218 timer.stop();
JDI_Mbed_Team 0:33fe30a2b785 219 timer.reset();
JDI_Mbed_Team 0:33fe30a2b785 220
JDI_Mbed_Team 0:33fe30a2b785 221 //Check if the card initialized
JDI_Mbed_Team 0:33fe30a2b785 222 if (token != 0x00) {
JDI_Mbed_Team 0:33fe30a2b785 223 //Initialization failed
JDI_Mbed_Team 0:33fe30a2b785 224 m_CardType = CARD_UNKNOWN;
JDI_Mbed_Team 0:33fe30a2b785 225 return m_Status;
JDI_Mbed_Team 0:33fe30a2b785 226 }
JDI_Mbed_Team 0:33fe30a2b785 227
JDI_Mbed_Team 0:33fe30a2b785 228 //Send CMD58(0x00000000) to read the OCR
JDI_Mbed_Team 0:33fe30a2b785 229 if (commandTransaction(CMD58, 0x00000000, &resp) == 0x00) {
JDI_Mbed_Team 0:33fe30a2b785 230 //Check the CCS bit to determine if this is a high capacity card
JDI_Mbed_Team 0:33fe30a2b785 231 if (resp & (1 << 30))
JDI_Mbed_Team 0:33fe30a2b785 232 m_CardType = CARD_SDHC;
JDI_Mbed_Team 0:33fe30a2b785 233 else
JDI_Mbed_Team 0:33fe30a2b785 234 m_CardType = CARD_SD;
JDI_Mbed_Team 0:33fe30a2b785 235
JDI_Mbed_Team 0:33fe30a2b785 236 //Increase the SPI frequency to full speed (up to 50MHz for SDCv2)
JDI_Mbed_Team 0:33fe30a2b785 237 if (m_FREQ > 25000000) {
JDI_Mbed_Team 0:33fe30a2b785 238 if (enableHighSpeedMode()) {
JDI_Mbed_Team 0:33fe30a2b785 239 if (m_FREQ > 50000000) {
JDI_Mbed_Team 0:33fe30a2b785 240 m_Spi.frequency(50000000);
JDI_Mbed_Team 0:33fe30a2b785 241 } else {
JDI_Mbed_Team 0:33fe30a2b785 242 m_Spi.frequency(m_FREQ);
JDI_Mbed_Team 0:33fe30a2b785 243 }
JDI_Mbed_Team 0:33fe30a2b785 244 } else {
JDI_Mbed_Team 0:33fe30a2b785 245 m_Spi.frequency(25000000);
JDI_Mbed_Team 0:33fe30a2b785 246 }
JDI_Mbed_Team 0:33fe30a2b785 247 } else {
JDI_Mbed_Team 0:33fe30a2b785 248 m_Spi.frequency(m_FREQ);
JDI_Mbed_Team 0:33fe30a2b785 249 }
JDI_Mbed_Team 0:33fe30a2b785 250 } else {
JDI_Mbed_Team 0:33fe30a2b785 251 //Initialization failed
JDI_Mbed_Team 0:33fe30a2b785 252 m_CardType = CARD_UNKNOWN;
JDI_Mbed_Team 0:33fe30a2b785 253 return m_Status;
JDI_Mbed_Team 0:33fe30a2b785 254 }
JDI_Mbed_Team 0:33fe30a2b785 255 } else {
JDI_Mbed_Team 0:33fe30a2b785 256 //Didn't respond or illegal command, this is either an SDCv1 or MMC card
JDI_Mbed_Team 0:33fe30a2b785 257 //Send CMD58(0x00000000) to read the OCR, and verify that the card supports 3.2-3.3V
JDI_Mbed_Team 0:33fe30a2b785 258 if (commandTransaction(CMD58, 0x00000000, &resp) != 0x01 || !(resp & (1 << 20))) {
JDI_Mbed_Team 0:33fe30a2b785 259 //Initialization failed
JDI_Mbed_Team 0:33fe30a2b785 260 m_CardType = CARD_UNKNOWN;
JDI_Mbed_Team 0:33fe30a2b785 261 return m_Status;
JDI_Mbed_Team 0:33fe30a2b785 262 }
JDI_Mbed_Team 0:33fe30a2b785 263
JDI_Mbed_Team 0:33fe30a2b785 264 //Try to initialize the card using ACMD41(0x40100000) for up to 2 seconds
JDI_Mbed_Team 0:33fe30a2b785 265 timer.start();
JDI_Mbed_Team 0:33fe30a2b785 266 do {
JDI_Mbed_Team 0:33fe30a2b785 267 token = commandTransaction(ACMD41, 0x40100000);
JDI_Mbed_Team 0:33fe30a2b785 268 } while (token == 0x01 && timer.read_ms() < 2000);
JDI_Mbed_Team 0:33fe30a2b785 269 timer.stop();
JDI_Mbed_Team 0:33fe30a2b785 270 timer.reset();
JDI_Mbed_Team 0:33fe30a2b785 271
JDI_Mbed_Team 0:33fe30a2b785 272 //Check if the card initialized
JDI_Mbed_Team 0:33fe30a2b785 273 if (token == 0x00) {
JDI_Mbed_Team 0:33fe30a2b785 274 //This is an SDCv1 standard capacity card
JDI_Mbed_Team 0:33fe30a2b785 275 m_CardType = CARD_SD;
JDI_Mbed_Team 0:33fe30a2b785 276
JDI_Mbed_Team 0:33fe30a2b785 277 //Increase the SPI frequency to full speed (up to 25MHz for SDCv1)
JDI_Mbed_Team 0:33fe30a2b785 278 if (m_FREQ > 25000000)
JDI_Mbed_Team 0:33fe30a2b785 279 m_Spi.frequency(25000000);
JDI_Mbed_Team 0:33fe30a2b785 280 else
JDI_Mbed_Team 0:33fe30a2b785 281 m_Spi.frequency(m_FREQ);
JDI_Mbed_Team 0:33fe30a2b785 282 } else {
JDI_Mbed_Team 0:33fe30a2b785 283 //Try to initialize the card using CMD1(0x00100000) for up to 2 seconds
JDI_Mbed_Team 0:33fe30a2b785 284 timer.start();
JDI_Mbed_Team 0:33fe30a2b785 285 do {
JDI_Mbed_Team 0:33fe30a2b785 286 token = commandTransaction(CMD1, 0x00100000);
JDI_Mbed_Team 0:33fe30a2b785 287 } while (token == 0x01 && timer.read_ms() < 2000);
JDI_Mbed_Team 0:33fe30a2b785 288 timer.stop();
JDI_Mbed_Team 0:33fe30a2b785 289 timer.reset();
JDI_Mbed_Team 0:33fe30a2b785 290
JDI_Mbed_Team 0:33fe30a2b785 291 //Check if the card initialized
JDI_Mbed_Team 0:33fe30a2b785 292 if (token == 0x00) {
JDI_Mbed_Team 0:33fe30a2b785 293 //This is an MMCv3 card
JDI_Mbed_Team 0:33fe30a2b785 294 m_CardType = CARD_MMC;
JDI_Mbed_Team 0:33fe30a2b785 295
JDI_Mbed_Team 0:33fe30a2b785 296 //Increase the SPI frequency to full speed (up to 20MHz for MMCv3)
JDI_Mbed_Team 0:33fe30a2b785 297 if (m_FREQ > 20000000)
JDI_Mbed_Team 0:33fe30a2b785 298 m_Spi.frequency(20000000);
JDI_Mbed_Team 0:33fe30a2b785 299 else
JDI_Mbed_Team 0:33fe30a2b785 300 m_Spi.frequency(m_FREQ);
JDI_Mbed_Team 0:33fe30a2b785 301 } else {
JDI_Mbed_Team 0:33fe30a2b785 302 //Initialization failed
JDI_Mbed_Team 0:33fe30a2b785 303 m_CardType = CARD_UNKNOWN;
JDI_Mbed_Team 0:33fe30a2b785 304 return m_Status;
JDI_Mbed_Team 0:33fe30a2b785 305 }
JDI_Mbed_Team 0:33fe30a2b785 306 }
JDI_Mbed_Team 0:33fe30a2b785 307 }
JDI_Mbed_Team 0:33fe30a2b785 308
JDI_Mbed_Team 0:33fe30a2b785 309 //Send ACMD42(0x00000000) to disconnect the internal pull-up resistor on pin 1 if necessary
JDI_Mbed_Team 0:33fe30a2b785 310 if (m_CardType != CARD_MMC) {
JDI_Mbed_Team 0:33fe30a2b785 311 if (commandTransaction(ACMD42, 0x00000000) != 0x00) {
JDI_Mbed_Team 0:33fe30a2b785 312 //Initialization failed
JDI_Mbed_Team 0:33fe30a2b785 313 m_CardType = CARD_UNKNOWN;
JDI_Mbed_Team 0:33fe30a2b785 314 return m_Status;
JDI_Mbed_Team 0:33fe30a2b785 315 }
JDI_Mbed_Team 0:33fe30a2b785 316 }
JDI_Mbed_Team 0:33fe30a2b785 317
JDI_Mbed_Team 0:33fe30a2b785 318 //Send CMD16(0x00000200) to force the block size to 512B if necessary
JDI_Mbed_Team 0:33fe30a2b785 319 if (m_CardType != CARD_SDHC) {
JDI_Mbed_Team 0:33fe30a2b785 320 if (commandTransaction(CMD16, 0x00000200) != 0x00) {
JDI_Mbed_Team 0:33fe30a2b785 321 //Initialization failed
JDI_Mbed_Team 0:33fe30a2b785 322 m_CardType = CARD_UNKNOWN;
JDI_Mbed_Team 0:33fe30a2b785 323 return m_Status;
JDI_Mbed_Team 0:33fe30a2b785 324 }
JDI_Mbed_Team 0:33fe30a2b785 325 }
JDI_Mbed_Team 0:33fe30a2b785 326
JDI_Mbed_Team 0:33fe30a2b785 327 //The card is now initialized
JDI_Mbed_Team 0:33fe30a2b785 328 m_Status &= ~STA_NOINIT;
JDI_Mbed_Team 0:33fe30a2b785 329
JDI_Mbed_Team 0:33fe30a2b785 330 //Return the disk status
JDI_Mbed_Team 0:33fe30a2b785 331 return m_Status;
JDI_Mbed_Team 0:33fe30a2b785 332 }
JDI_Mbed_Team 0:33fe30a2b785 333
JDI_Mbed_Team 0:33fe30a2b785 334 int SDFileSystem::disk_status()
JDI_Mbed_Team 0:33fe30a2b785 335 {
JDI_Mbed_Team 0:33fe30a2b785 336 //Check the card socket
JDI_Mbed_Team 0:33fe30a2b785 337 checkSocket();
JDI_Mbed_Team 0:33fe30a2b785 338
JDI_Mbed_Team 0:33fe30a2b785 339 //Return the disk status
JDI_Mbed_Team 0:33fe30a2b785 340 return m_Status;
JDI_Mbed_Team 0:33fe30a2b785 341 }
JDI_Mbed_Team 0:33fe30a2b785 342
JDI_Mbed_Team 0:33fe30a2b785 343 int SDFileSystem::disk_read(uint8_t* buffer, uint32_t sector, uint32_t count)
JDI_Mbed_Team 0:33fe30a2b785 344 {
JDI_Mbed_Team 0:33fe30a2b785 345 //Make sure the card is initialized before proceeding
JDI_Mbed_Team 0:33fe30a2b785 346 if (m_Status & STA_NOINIT)
JDI_Mbed_Team 0:33fe30a2b785 347 return RES_NOTRDY;
JDI_Mbed_Team 0:33fe30a2b785 348
JDI_Mbed_Team 0:33fe30a2b785 349 //Read a single block, or multiple blocks
JDI_Mbed_Team 0:33fe30a2b785 350 if (count > 1) {
JDI_Mbed_Team 0:33fe30a2b785 351 return readBlocks((char*)buffer, sector, count) ? RES_OK : RES_ERROR;
JDI_Mbed_Team 0:33fe30a2b785 352 } else {
JDI_Mbed_Team 0:33fe30a2b785 353 return readBlock((char*)buffer, sector) ? RES_OK : RES_ERROR;
JDI_Mbed_Team 0:33fe30a2b785 354 }
JDI_Mbed_Team 0:33fe30a2b785 355 }
JDI_Mbed_Team 0:33fe30a2b785 356
JDI_Mbed_Team 0:33fe30a2b785 357 int SDFileSystem::disk_write(const uint8_t* buffer, uint32_t sector, uint32_t count)
JDI_Mbed_Team 0:33fe30a2b785 358 {
JDI_Mbed_Team 0:33fe30a2b785 359 //Make sure the card is initialized before proceeding
JDI_Mbed_Team 0:33fe30a2b785 360 if (m_Status & STA_NOINIT)
JDI_Mbed_Team 0:33fe30a2b785 361 return RES_NOTRDY;
JDI_Mbed_Team 0:33fe30a2b785 362
JDI_Mbed_Team 0:33fe30a2b785 363 //Make sure the card isn't write protected before proceeding
JDI_Mbed_Team 0:33fe30a2b785 364 if (m_Status & STA_PROTECT)
JDI_Mbed_Team 0:33fe30a2b785 365 return RES_WRPRT;
JDI_Mbed_Team 0:33fe30a2b785 366
JDI_Mbed_Team 0:33fe30a2b785 367 //Write a single block, or multiple blocks
JDI_Mbed_Team 0:33fe30a2b785 368 if (count > 1) {
JDI_Mbed_Team 0:33fe30a2b785 369 return writeBlocks((const char*)buffer, sector, count) ? RES_OK : RES_ERROR;
JDI_Mbed_Team 0:33fe30a2b785 370 } else {
JDI_Mbed_Team 0:33fe30a2b785 371 return writeBlock((const char*)buffer, sector) ? RES_OK : RES_ERROR;
JDI_Mbed_Team 0:33fe30a2b785 372 }
JDI_Mbed_Team 0:33fe30a2b785 373 }
JDI_Mbed_Team 0:33fe30a2b785 374
JDI_Mbed_Team 0:33fe30a2b785 375 int SDFileSystem::disk_sync()
JDI_Mbed_Team 0:33fe30a2b785 376 {
JDI_Mbed_Team 0:33fe30a2b785 377 //Select the card so we're forced to wait for the end of any internal write processes
JDI_Mbed_Team 0:33fe30a2b785 378 if (select()) {
JDI_Mbed_Team 0:33fe30a2b785 379 deselect();
JDI_Mbed_Team 0:33fe30a2b785 380 return RES_OK;
JDI_Mbed_Team 0:33fe30a2b785 381 } else {
JDI_Mbed_Team 0:33fe30a2b785 382 return RES_ERROR;
JDI_Mbed_Team 0:33fe30a2b785 383 }
JDI_Mbed_Team 0:33fe30a2b785 384 }
JDI_Mbed_Team 0:33fe30a2b785 385
JDI_Mbed_Team 0:33fe30a2b785 386 uint32_t SDFileSystem::disk_sectors()
JDI_Mbed_Team 0:33fe30a2b785 387 {
JDI_Mbed_Team 0:33fe30a2b785 388 //Make sure the card is initialized before proceeding
JDI_Mbed_Team 0:33fe30a2b785 389 if (m_Status & STA_NOINIT)
JDI_Mbed_Team 0:33fe30a2b785 390 return 0;
JDI_Mbed_Team 0:33fe30a2b785 391
JDI_Mbed_Team 0:33fe30a2b785 392 //Try to read the CSD register up to 3 times
JDI_Mbed_Team 0:33fe30a2b785 393 for (int f = 0; f < 3; f++) {
JDI_Mbed_Team 0:33fe30a2b785 394 //Select the card, and wait for ready
JDI_Mbed_Team 0:33fe30a2b785 395 if(!select())
JDI_Mbed_Team 0:33fe30a2b785 396 break;
JDI_Mbed_Team 0:33fe30a2b785 397
JDI_Mbed_Team 0:33fe30a2b785 398 //Send CMD9(0x00000000) to read the CSD register
JDI_Mbed_Team 0:33fe30a2b785 399 if (writeCommand(CMD9, 0x00000000) == 0x00) {
JDI_Mbed_Team 0:33fe30a2b785 400 //Read the 16B CSD data block
JDI_Mbed_Team 0:33fe30a2b785 401 char csd[16];
JDI_Mbed_Team 0:33fe30a2b785 402 bool success = readData(csd, 16);
JDI_Mbed_Team 0:33fe30a2b785 403 deselect();
JDI_Mbed_Team 0:33fe30a2b785 404 if (success) {
JDI_Mbed_Team 0:33fe30a2b785 405 //Calculate the sector count based on the card type
JDI_Mbed_Team 0:33fe30a2b785 406 if ((csd[0] >> 6) == 0x01) {
JDI_Mbed_Team 0:33fe30a2b785 407 //Calculate the sector count for a high capacity card
JDI_Mbed_Team 0:33fe30a2b785 408 unsigned int size = (((csd[7] & 0x3F) << 16) | (csd[8] << 8) | csd[9]) + 1;
JDI_Mbed_Team 0:33fe30a2b785 409 return size << 10;
JDI_Mbed_Team 0:33fe30a2b785 410 } else {
JDI_Mbed_Team 0:33fe30a2b785 411 //Calculate the sector count for a standard capacity card
JDI_Mbed_Team 0:33fe30a2b785 412 unsigned int size = (((csd[6] & 0x03) << 10) | (csd[7] << 2) | ((csd[8] & 0xC0) >> 6)) + 1;
JDI_Mbed_Team 0:33fe30a2b785 413 size <<= ((((csd[9] & 0x03) << 1) | ((csd[10] & 0x80) >> 7)) + 2);
JDI_Mbed_Team 0:33fe30a2b785 414 size <<= (csd[5] & 0x0F);
JDI_Mbed_Team 0:33fe30a2b785 415 return size >> 9;
JDI_Mbed_Team 0:33fe30a2b785 416 }
JDI_Mbed_Team 0:33fe30a2b785 417 }
JDI_Mbed_Team 0:33fe30a2b785 418 } else {
JDI_Mbed_Team 0:33fe30a2b785 419 //The command failed, get out
JDI_Mbed_Team 0:33fe30a2b785 420 break;
JDI_Mbed_Team 0:33fe30a2b785 421 }
JDI_Mbed_Team 0:33fe30a2b785 422 }
JDI_Mbed_Team 0:33fe30a2b785 423
JDI_Mbed_Team 0:33fe30a2b785 424 //The read operation failed 3 times
JDI_Mbed_Team 0:33fe30a2b785 425 deselect();
JDI_Mbed_Team 0:33fe30a2b785 426 return 0;
JDI_Mbed_Team 0:33fe30a2b785 427 }
JDI_Mbed_Team 0:33fe30a2b785 428
JDI_Mbed_Team 0:33fe30a2b785 429 void SDFileSystem::onCardRemoval()
JDI_Mbed_Team 0:33fe30a2b785 430 {
JDI_Mbed_Team 0:33fe30a2b785 431 //Check the card socket
JDI_Mbed_Team 0:33fe30a2b785 432 checkSocket();
JDI_Mbed_Team 0:33fe30a2b785 433 }
JDI_Mbed_Team 0:33fe30a2b785 434
JDI_Mbed_Team 0:33fe30a2b785 435 inline void SDFileSystem::checkSocket()
JDI_Mbed_Team 0:33fe30a2b785 436 {
JDI_Mbed_Team 0:33fe30a2b785 437 //Use the card detect switch (if available) to determine if the socket is occupied
JDI_Mbed_Team 0:33fe30a2b785 438 if (m_CdAssert != -1) {
JDI_Mbed_Team 0:33fe30a2b785 439 if (m_Status & STA_NODISK) {
JDI_Mbed_Team 0:33fe30a2b785 440 if (m_Cd == m_CdAssert) {
JDI_Mbed_Team 0:33fe30a2b785 441 //The socket is now occupied
JDI_Mbed_Team 0:33fe30a2b785 442 m_Status &= ~STA_NODISK;
JDI_Mbed_Team 0:33fe30a2b785 443 m_CardType = CARD_UNKNOWN;
JDI_Mbed_Team 0:33fe30a2b785 444 }
JDI_Mbed_Team 0:33fe30a2b785 445 } else {
JDI_Mbed_Team 0:33fe30a2b785 446 if (m_Cd != m_CdAssert) {
JDI_Mbed_Team 0:33fe30a2b785 447 //The socket is now empty
JDI_Mbed_Team 0:33fe30a2b785 448 m_Status |= (STA_NODISK | STA_NOINIT);
JDI_Mbed_Team 0:33fe30a2b785 449 m_CardType = CARD_NONE;
JDI_Mbed_Team 0:33fe30a2b785 450 }
JDI_Mbed_Team 0:33fe30a2b785 451 }
JDI_Mbed_Team 0:33fe30a2b785 452 }
JDI_Mbed_Team 0:33fe30a2b785 453 }
JDI_Mbed_Team 0:33fe30a2b785 454
JDI_Mbed_Team 0:33fe30a2b785 455 inline bool SDFileSystem::waitReady(int timeout)
JDI_Mbed_Team 0:33fe30a2b785 456 {
JDI_Mbed_Team 0:33fe30a2b785 457 char resp;
JDI_Mbed_Team 0:33fe30a2b785 458
JDI_Mbed_Team 0:33fe30a2b785 459 //Keep sending dummy clocks with DI held high until the card releases the DO line
JDI_Mbed_Team 0:33fe30a2b785 460 m_Timer.start();
JDI_Mbed_Team 0:33fe30a2b785 461 do {
JDI_Mbed_Team 0:33fe30a2b785 462 resp = m_Spi.write(0xFF);
JDI_Mbed_Team 0:33fe30a2b785 463 } while (resp == 0x00 && m_Timer.read_ms() < timeout);
JDI_Mbed_Team 0:33fe30a2b785 464 m_Timer.stop();
JDI_Mbed_Team 0:33fe30a2b785 465 m_Timer.reset();
JDI_Mbed_Team 0:33fe30a2b785 466
JDI_Mbed_Team 0:33fe30a2b785 467 //Return success/failure
JDI_Mbed_Team 0:33fe30a2b785 468 return (resp > 0x00);
JDI_Mbed_Team 0:33fe30a2b785 469 }
JDI_Mbed_Team 0:33fe30a2b785 470
JDI_Mbed_Team 0:33fe30a2b785 471 inline bool SDFileSystem::select()
JDI_Mbed_Team 0:33fe30a2b785 472 {
JDI_Mbed_Team 0:33fe30a2b785 473 //Assert /CS
JDI_Mbed_Team 0:33fe30a2b785 474 m_Cs = 0;
JDI_Mbed_Team 0:33fe30a2b785 475
JDI_Mbed_Team 0:33fe30a2b785 476 //Send 8 dummy clocks with DI held high to enable DO
JDI_Mbed_Team 0:33fe30a2b785 477 m_Spi.write(0xFF);
JDI_Mbed_Team 0:33fe30a2b785 478
JDI_Mbed_Team 0:33fe30a2b785 479 //Wait for up to 500ms for the card to become ready
JDI_Mbed_Team 0:33fe30a2b785 480 if (waitReady(500)) {
JDI_Mbed_Team 0:33fe30a2b785 481 return true;
JDI_Mbed_Team 0:33fe30a2b785 482 } else {
JDI_Mbed_Team 0:33fe30a2b785 483 //We timed out, deselect and return false
JDI_Mbed_Team 0:33fe30a2b785 484 deselect();
JDI_Mbed_Team 0:33fe30a2b785 485 return false;
JDI_Mbed_Team 0:33fe30a2b785 486 }
JDI_Mbed_Team 0:33fe30a2b785 487 }
JDI_Mbed_Team 0:33fe30a2b785 488
JDI_Mbed_Team 0:33fe30a2b785 489 inline void SDFileSystem::deselect()
JDI_Mbed_Team 0:33fe30a2b785 490 {
JDI_Mbed_Team 0:33fe30a2b785 491 //Deassert /CS
JDI_Mbed_Team 0:33fe30a2b785 492 m_Cs = 1;
JDI_Mbed_Team 0:33fe30a2b785 493
JDI_Mbed_Team 0:33fe30a2b785 494 //Send 8 dummy clocks with DI held high to disable DO
JDI_Mbed_Team 0:33fe30a2b785 495 m_Spi.write(0xFF);
JDI_Mbed_Team 0:33fe30a2b785 496 }
JDI_Mbed_Team 0:33fe30a2b785 497
JDI_Mbed_Team 0:33fe30a2b785 498 inline char SDFileSystem::commandTransaction(char cmd, unsigned int arg, unsigned int* resp)
JDI_Mbed_Team 0:33fe30a2b785 499 {
JDI_Mbed_Team 0:33fe30a2b785 500 //Select the card, and wait for ready
JDI_Mbed_Team 0:33fe30a2b785 501 if(!select())
JDI_Mbed_Team 0:33fe30a2b785 502 return 0xFF;
JDI_Mbed_Team 0:33fe30a2b785 503
JDI_Mbed_Team 0:33fe30a2b785 504 //Perform the command transaction
JDI_Mbed_Team 0:33fe30a2b785 505 char token = writeCommand(cmd, arg, resp);
JDI_Mbed_Team 0:33fe30a2b785 506
JDI_Mbed_Team 0:33fe30a2b785 507 //Deselect the card, and return the R1 response token
JDI_Mbed_Team 0:33fe30a2b785 508 deselect();
JDI_Mbed_Team 0:33fe30a2b785 509 return token;
JDI_Mbed_Team 0:33fe30a2b785 510 }
JDI_Mbed_Team 0:33fe30a2b785 511
JDI_Mbed_Team 0:33fe30a2b785 512 char SDFileSystem::writeCommand(char cmd, unsigned int arg, unsigned int* resp)
JDI_Mbed_Team 0:33fe30a2b785 513 {
JDI_Mbed_Team 0:33fe30a2b785 514 char token;
JDI_Mbed_Team 0:33fe30a2b785 515
JDI_Mbed_Team 0:33fe30a2b785 516 //Try to send the command up to 3 times
JDI_Mbed_Team 0:33fe30a2b785 517 for (int f = 0; f < 3; f++) {
JDI_Mbed_Team 0:33fe30a2b785 518 //Send CMD55(0x00000000) prior to an application specific command
JDI_Mbed_Team 0:33fe30a2b785 519 if (cmd == ACMD22 || cmd == ACMD23 || cmd == ACMD41 || cmd == ACMD42) {
JDI_Mbed_Team 0:33fe30a2b785 520 token = writeCommand(CMD55, 0x00000000);
JDI_Mbed_Team 0:33fe30a2b785 521 if (token > 0x01)
JDI_Mbed_Team 0:33fe30a2b785 522 return token;
JDI_Mbed_Team 0:33fe30a2b785 523
JDI_Mbed_Team 0:33fe30a2b785 524 //Deselect and reselect the card between CMD55 and an ACMD
JDI_Mbed_Team 0:33fe30a2b785 525 deselect();
JDI_Mbed_Team 0:33fe30a2b785 526 if(!select())
JDI_Mbed_Team 0:33fe30a2b785 527 return 0xFF;
JDI_Mbed_Team 0:33fe30a2b785 528 }
JDI_Mbed_Team 0:33fe30a2b785 529
JDI_Mbed_Team 0:33fe30a2b785 530 //Prepare the command packet
JDI_Mbed_Team 0:33fe30a2b785 531 char cmdPacket[6];
JDI_Mbed_Team 0:33fe30a2b785 532 cmdPacket[0] = cmd;
JDI_Mbed_Team 0:33fe30a2b785 533 cmdPacket[1] = arg >> 24;
JDI_Mbed_Team 0:33fe30a2b785 534 cmdPacket[2] = arg >> 16;
JDI_Mbed_Team 0:33fe30a2b785 535 cmdPacket[3] = arg >> 8;
JDI_Mbed_Team 0:33fe30a2b785 536 cmdPacket[4] = arg;
JDI_Mbed_Team 0:33fe30a2b785 537 if (m_Crc || cmd == CMD0 || cmd == CMD8)
JDI_Mbed_Team 0:33fe30a2b785 538 cmdPacket[5] = (SDCRC::crc7(cmdPacket, 5) << 1) | 0x01;
JDI_Mbed_Team 0:33fe30a2b785 539 else
JDI_Mbed_Team 0:33fe30a2b785 540 cmdPacket[5] = 0x01;
JDI_Mbed_Team 0:33fe30a2b785 541
JDI_Mbed_Team 0:33fe30a2b785 542 //Send the command packet
JDI_Mbed_Team 0:33fe30a2b785 543 for (int i = 0; i < 6; i++)
JDI_Mbed_Team 0:33fe30a2b785 544 m_Spi.write(cmdPacket[i]);
JDI_Mbed_Team 0:33fe30a2b785 545
JDI_Mbed_Team 0:33fe30a2b785 546 //Discard the stuff byte immediately following CMD12
JDI_Mbed_Team 0:33fe30a2b785 547 if (cmd == CMD12)
JDI_Mbed_Team 0:33fe30a2b785 548 m_Spi.write(0xFF);
JDI_Mbed_Team 0:33fe30a2b785 549
JDI_Mbed_Team 0:33fe30a2b785 550 //Allow up to 8 bytes of delay for the R1 response token
JDI_Mbed_Team 0:33fe30a2b785 551 for (int i = 0; i < 9; i++) {
JDI_Mbed_Team 0:33fe30a2b785 552 token = m_Spi.write(0xFF);
JDI_Mbed_Team 0:33fe30a2b785 553 if (!(token & 0x80))
JDI_Mbed_Team 0:33fe30a2b785 554 break;
JDI_Mbed_Team 0:33fe30a2b785 555 }
JDI_Mbed_Team 0:33fe30a2b785 556
JDI_Mbed_Team 0:33fe30a2b785 557 //Verify the R1 response token
JDI_Mbed_Team 0:33fe30a2b785 558 if (token == 0xFF) {
JDI_Mbed_Team 0:33fe30a2b785 559 //No data was received, get out early
JDI_Mbed_Team 0:33fe30a2b785 560 break;
JDI_Mbed_Team 0:33fe30a2b785 561 } else if (token & (1 << 3)) {
JDI_Mbed_Team 0:33fe30a2b785 562 //There was a CRC error, try again
JDI_Mbed_Team 0:33fe30a2b785 563 continue;
JDI_Mbed_Team 0:33fe30a2b785 564 } else if (token > 0x01) {
JDI_Mbed_Team 0:33fe30a2b785 565 //An error occured, get out early
JDI_Mbed_Team 0:33fe30a2b785 566 break;
JDI_Mbed_Team 0:33fe30a2b785 567 }
JDI_Mbed_Team 0:33fe30a2b785 568
JDI_Mbed_Team 0:33fe30a2b785 569 //Handle R2 and R3/R7 response tokens
JDI_Mbed_Team 0:33fe30a2b785 570 if (cmd == CMD13 && resp != NULL) {
JDI_Mbed_Team 0:33fe30a2b785 571 //Read the R2 response value
JDI_Mbed_Team 0:33fe30a2b785 572 *resp = m_Spi.write(0xFF);
JDI_Mbed_Team 0:33fe30a2b785 573 } else if ((cmd == CMD8 || cmd == CMD58) && resp != NULL) {
JDI_Mbed_Team 0:33fe30a2b785 574 //Read the R3/R7 response value
JDI_Mbed_Team 0:33fe30a2b785 575 *resp = (m_Spi.write(0xFF) << 24);
JDI_Mbed_Team 0:33fe30a2b785 576 *resp |= (m_Spi.write(0xFF) << 16);
JDI_Mbed_Team 0:33fe30a2b785 577 *resp |= (m_Spi.write(0xFF) << 8);
JDI_Mbed_Team 0:33fe30a2b785 578 *resp |= m_Spi.write(0xFF);
JDI_Mbed_Team 0:33fe30a2b785 579 }
JDI_Mbed_Team 0:33fe30a2b785 580
JDI_Mbed_Team 0:33fe30a2b785 581 //The command was successful
JDI_Mbed_Team 0:33fe30a2b785 582 break;
JDI_Mbed_Team 0:33fe30a2b785 583 }
JDI_Mbed_Team 0:33fe30a2b785 584
JDI_Mbed_Team 0:33fe30a2b785 585 //Return the R1 response token
JDI_Mbed_Team 0:33fe30a2b785 586 return token;
JDI_Mbed_Team 0:33fe30a2b785 587 }
JDI_Mbed_Team 0:33fe30a2b785 588
JDI_Mbed_Team 0:33fe30a2b785 589 bool SDFileSystem::readData(char* buffer, int length)
JDI_Mbed_Team 0:33fe30a2b785 590 {
JDI_Mbed_Team 0:33fe30a2b785 591 char token;
JDI_Mbed_Team 0:33fe30a2b785 592 unsigned short crc;
JDI_Mbed_Team 0:33fe30a2b785 593
JDI_Mbed_Team 0:33fe30a2b785 594 //Wait for up to 500ms for a token to arrive
JDI_Mbed_Team 0:33fe30a2b785 595 m_Timer.start();
JDI_Mbed_Team 0:33fe30a2b785 596 do {
JDI_Mbed_Team 0:33fe30a2b785 597 token = m_Spi.write(0xFF);
JDI_Mbed_Team 0:33fe30a2b785 598 } while (token == 0xFF && m_Timer.read_ms() < 500);
JDI_Mbed_Team 0:33fe30a2b785 599 m_Timer.stop();
JDI_Mbed_Team 0:33fe30a2b785 600 m_Timer.reset();
JDI_Mbed_Team 0:33fe30a2b785 601
JDI_Mbed_Team 0:33fe30a2b785 602 //Check if a valid start block token was received
JDI_Mbed_Team 0:33fe30a2b785 603 if (token != 0xFE)
JDI_Mbed_Team 0:33fe30a2b785 604 return false;
JDI_Mbed_Team 0:33fe30a2b785 605
JDI_Mbed_Team 0:33fe30a2b785 606 //Check if large frames are enabled or not
JDI_Mbed_Team 0:33fe30a2b785 607 if (m_LargeFrames) {
JDI_Mbed_Team 0:33fe30a2b785 608 //Switch to 16-bit frames for better performance
JDI_Mbed_Team 0:33fe30a2b785 609 m_Spi.format(16, 0);
JDI_Mbed_Team 0:33fe30a2b785 610
JDI_Mbed_Team 0:33fe30a2b785 611 //Read the data block into the buffer
JDI_Mbed_Team 0:33fe30a2b785 612 unsigned short dataWord;
JDI_Mbed_Team 0:33fe30a2b785 613 for (int i = 0; i < length; i += 2) {
JDI_Mbed_Team 0:33fe30a2b785 614 dataWord = m_Spi.write(0xFFFF);
JDI_Mbed_Team 0:33fe30a2b785 615 buffer[i] = dataWord >> 8;
JDI_Mbed_Team 0:33fe30a2b785 616 buffer[i + 1] = dataWord;
JDI_Mbed_Team 0:33fe30a2b785 617 }
JDI_Mbed_Team 0:33fe30a2b785 618
JDI_Mbed_Team 0:33fe30a2b785 619 //Read the CRC16 checksum for the data block
JDI_Mbed_Team 0:33fe30a2b785 620 crc = m_Spi.write(0xFFFF);
JDI_Mbed_Team 0:33fe30a2b785 621
JDI_Mbed_Team 0:33fe30a2b785 622 //Switch back to 8-bit frames
JDI_Mbed_Team 0:33fe30a2b785 623 m_Spi.format(8, 0);
JDI_Mbed_Team 0:33fe30a2b785 624 } else {
JDI_Mbed_Team 0:33fe30a2b785 625 //Read the data into the buffer
JDI_Mbed_Team 0:33fe30a2b785 626 for (int i = 0; i < length; i++)
JDI_Mbed_Team 0:33fe30a2b785 627 buffer[i] = m_Spi.write(0xFF);
JDI_Mbed_Team 0:33fe30a2b785 628
JDI_Mbed_Team 0:33fe30a2b785 629 //Read the CRC16 checksum for the data block
JDI_Mbed_Team 0:33fe30a2b785 630 crc = (m_Spi.write(0xFF) << 8);
JDI_Mbed_Team 0:33fe30a2b785 631 crc |= m_Spi.write(0xFF);
JDI_Mbed_Team 0:33fe30a2b785 632 }
JDI_Mbed_Team 0:33fe30a2b785 633
JDI_Mbed_Team 0:33fe30a2b785 634 //Return the validity of the CRC16 checksum (if enabled)
JDI_Mbed_Team 0:33fe30a2b785 635 return (!m_Crc || crc == SDCRC::crc16(buffer, length));
JDI_Mbed_Team 0:33fe30a2b785 636 }
JDI_Mbed_Team 0:33fe30a2b785 637
JDI_Mbed_Team 0:33fe30a2b785 638 char SDFileSystem::writeData(const char* buffer, char token)
JDI_Mbed_Team 0:33fe30a2b785 639 {
JDI_Mbed_Team 0:33fe30a2b785 640 //Calculate the CRC16 checksum for the data block (if enabled)
JDI_Mbed_Team 0:33fe30a2b785 641 unsigned short crc = (m_Crc) ? SDCRC::crc16(buffer, 512) : 0xFFFF;
JDI_Mbed_Team 0:33fe30a2b785 642
JDI_Mbed_Team 0:33fe30a2b785 643 //Wait for up to 500ms for the card to become ready
JDI_Mbed_Team 0:33fe30a2b785 644 if (!waitReady(500))
JDI_Mbed_Team 0:33fe30a2b785 645 return false;
JDI_Mbed_Team 0:33fe30a2b785 646
JDI_Mbed_Team 0:33fe30a2b785 647 //Send the start block token
JDI_Mbed_Team 0:33fe30a2b785 648 m_Spi.write(token);
JDI_Mbed_Team 0:33fe30a2b785 649
JDI_Mbed_Team 0:33fe30a2b785 650 //Check if large frames are enabled or not
JDI_Mbed_Team 0:33fe30a2b785 651 if (m_LargeFrames) {
JDI_Mbed_Team 0:33fe30a2b785 652 //Switch to 16-bit frames for better performance
JDI_Mbed_Team 0:33fe30a2b785 653 m_Spi.format(16, 0);
JDI_Mbed_Team 0:33fe30a2b785 654
JDI_Mbed_Team 0:33fe30a2b785 655 //Write the data block from the buffer
JDI_Mbed_Team 0:33fe30a2b785 656 for (int i = 0; i < 512; i += 2)
JDI_Mbed_Team 0:33fe30a2b785 657 m_Spi.write((buffer[i] << 8) | buffer[i + 1]);
JDI_Mbed_Team 0:33fe30a2b785 658
JDI_Mbed_Team 0:33fe30a2b785 659 //Send the CRC16 checksum for the data block
JDI_Mbed_Team 0:33fe30a2b785 660 m_Spi.write(crc);
JDI_Mbed_Team 0:33fe30a2b785 661
JDI_Mbed_Team 0:33fe30a2b785 662 //Switch back to 8-bit frames
JDI_Mbed_Team 0:33fe30a2b785 663 m_Spi.format(8, 0);
JDI_Mbed_Team 0:33fe30a2b785 664 } else {
JDI_Mbed_Team 0:33fe30a2b785 665 //Write the data block from the buffer
JDI_Mbed_Team 0:33fe30a2b785 666 for (int i = 0; i < 512; i++)
JDI_Mbed_Team 0:33fe30a2b785 667 m_Spi.write(buffer[i]);
JDI_Mbed_Team 0:33fe30a2b785 668
JDI_Mbed_Team 0:33fe30a2b785 669 //Send the CRC16 checksum for the data block
JDI_Mbed_Team 0:33fe30a2b785 670 m_Spi.write(crc >> 8);
JDI_Mbed_Team 0:33fe30a2b785 671 m_Spi.write(crc);
JDI_Mbed_Team 0:33fe30a2b785 672 }
JDI_Mbed_Team 0:33fe30a2b785 673
JDI_Mbed_Team 0:33fe30a2b785 674 //Return the data response token
JDI_Mbed_Team 0:33fe30a2b785 675 return (m_Spi.write(0xFF) & 0x1F);
JDI_Mbed_Team 0:33fe30a2b785 676 }
JDI_Mbed_Team 0:33fe30a2b785 677
JDI_Mbed_Team 0:33fe30a2b785 678 inline bool SDFileSystem::readBlock(char* buffer, unsigned int lba)
JDI_Mbed_Team 0:33fe30a2b785 679 {
JDI_Mbed_Team 0:33fe30a2b785 680 //Try to read the block up to 3 times
JDI_Mbed_Team 0:33fe30a2b785 681 for (int f = 0; f < 3; f++) {
JDI_Mbed_Team 0:33fe30a2b785 682 //Select the card, and wait for ready
JDI_Mbed_Team 0:33fe30a2b785 683 if(!select())
JDI_Mbed_Team 0:33fe30a2b785 684 break;
JDI_Mbed_Team 0:33fe30a2b785 685
JDI_Mbed_Team 0:33fe30a2b785 686 //Send CMD17(block) to read a single block
JDI_Mbed_Team 0:33fe30a2b785 687 if (writeCommand(CMD17, (m_CardType == CARD_SDHC) ? lba : lba << 9) == 0x00) {
JDI_Mbed_Team 0:33fe30a2b785 688 //Try to read the block, and deselect the card
JDI_Mbed_Team 0:33fe30a2b785 689 bool success = readData(buffer, 512);
JDI_Mbed_Team 0:33fe30a2b785 690 deselect();
JDI_Mbed_Team 0:33fe30a2b785 691
JDI_Mbed_Team 0:33fe30a2b785 692 //Return if successful
JDI_Mbed_Team 0:33fe30a2b785 693 if (success)
JDI_Mbed_Team 0:33fe30a2b785 694 return true;
JDI_Mbed_Team 0:33fe30a2b785 695 } else {
JDI_Mbed_Team 0:33fe30a2b785 696 //The command failed, get out
JDI_Mbed_Team 0:33fe30a2b785 697 break;
JDI_Mbed_Team 0:33fe30a2b785 698 }
JDI_Mbed_Team 0:33fe30a2b785 699 }
JDI_Mbed_Team 0:33fe30a2b785 700
JDI_Mbed_Team 0:33fe30a2b785 701 //The single block read failed
JDI_Mbed_Team 0:33fe30a2b785 702 deselect();
JDI_Mbed_Team 0:33fe30a2b785 703 return false;
JDI_Mbed_Team 0:33fe30a2b785 704 }
JDI_Mbed_Team 0:33fe30a2b785 705
JDI_Mbed_Team 0:33fe30a2b785 706 inline bool SDFileSystem::readBlocks(char* buffer, unsigned int lba, unsigned int count)
JDI_Mbed_Team 0:33fe30a2b785 707 {
JDI_Mbed_Team 0:33fe30a2b785 708 //Try to read each block up to 3 times
JDI_Mbed_Team 0:33fe30a2b785 709 for (int f = 0; f < 3;) {
JDI_Mbed_Team 0:33fe30a2b785 710 //Select the card, and wait for ready
JDI_Mbed_Team 0:33fe30a2b785 711 if(!select())
JDI_Mbed_Team 0:33fe30a2b785 712 break;
JDI_Mbed_Team 0:33fe30a2b785 713
JDI_Mbed_Team 0:33fe30a2b785 714 //Send CMD18(block) to read multiple blocks
JDI_Mbed_Team 0:33fe30a2b785 715 if (writeCommand(CMD18, (m_CardType == CARD_SDHC) ? lba : lba << 9) == 0x00) {
JDI_Mbed_Team 0:33fe30a2b785 716 //Try to read all of the data blocks
JDI_Mbed_Team 0:33fe30a2b785 717 do {
JDI_Mbed_Team 0:33fe30a2b785 718 //Read the next block, and break on errors
JDI_Mbed_Team 0:33fe30a2b785 719 if (!readData(buffer, 512)) {
JDI_Mbed_Team 0:33fe30a2b785 720 f++;
JDI_Mbed_Team 0:33fe30a2b785 721 break;
JDI_Mbed_Team 0:33fe30a2b785 722 }
JDI_Mbed_Team 0:33fe30a2b785 723
JDI_Mbed_Team 0:33fe30a2b785 724 //Update the variables
JDI_Mbed_Team 0:33fe30a2b785 725 lba++;
JDI_Mbed_Team 0:33fe30a2b785 726 buffer += 512;
JDI_Mbed_Team 0:33fe30a2b785 727 f = 0;
JDI_Mbed_Team 0:33fe30a2b785 728 } while (--count);
JDI_Mbed_Team 0:33fe30a2b785 729
JDI_Mbed_Team 0:33fe30a2b785 730 //Send CMD12(0x00000000) to stop the transmission
JDI_Mbed_Team 0:33fe30a2b785 731 if (writeCommand(CMD12, 0x00000000) != 0x00) {
JDI_Mbed_Team 0:33fe30a2b785 732 //The command failed, get out
JDI_Mbed_Team 0:33fe30a2b785 733 break;
JDI_Mbed_Team 0:33fe30a2b785 734 }
JDI_Mbed_Team 0:33fe30a2b785 735
JDI_Mbed_Team 0:33fe30a2b785 736 //Deselect the card, and return if successful
JDI_Mbed_Team 0:33fe30a2b785 737 deselect();
JDI_Mbed_Team 0:33fe30a2b785 738 if (count == 0)
JDI_Mbed_Team 0:33fe30a2b785 739 return true;
JDI_Mbed_Team 0:33fe30a2b785 740 } else {
JDI_Mbed_Team 0:33fe30a2b785 741 //The command failed, get out
JDI_Mbed_Team 0:33fe30a2b785 742 break;
JDI_Mbed_Team 0:33fe30a2b785 743 }
JDI_Mbed_Team 0:33fe30a2b785 744 }
JDI_Mbed_Team 0:33fe30a2b785 745
JDI_Mbed_Team 0:33fe30a2b785 746 //The multiple block read failed
JDI_Mbed_Team 0:33fe30a2b785 747 deselect();
JDI_Mbed_Team 0:33fe30a2b785 748 return false;
JDI_Mbed_Team 0:33fe30a2b785 749 }
JDI_Mbed_Team 0:33fe30a2b785 750
JDI_Mbed_Team 0:33fe30a2b785 751 inline bool SDFileSystem::writeBlock(const char* buffer, unsigned int lba)
JDI_Mbed_Team 0:33fe30a2b785 752 {
JDI_Mbed_Team 0:33fe30a2b785 753 //Try to write the block up to 3 times
JDI_Mbed_Team 0:33fe30a2b785 754 for (int f = 0; f < 3; f++) {
JDI_Mbed_Team 0:33fe30a2b785 755 //Select the card, and wait for ready
JDI_Mbed_Team 0:33fe30a2b785 756 if(!select())
JDI_Mbed_Team 0:33fe30a2b785 757 break;
JDI_Mbed_Team 0:33fe30a2b785 758
JDI_Mbed_Team 0:33fe30a2b785 759 //Send CMD24(block) to write a single block
JDI_Mbed_Team 0:33fe30a2b785 760 if (writeCommand(CMD24, (m_CardType == CARD_SDHC) ? lba : lba << 9) == 0x00) {
JDI_Mbed_Team 0:33fe30a2b785 761 //Try to write the block, and deselect the card
JDI_Mbed_Team 0:33fe30a2b785 762 char token = writeData(buffer, 0xFE);
JDI_Mbed_Team 0:33fe30a2b785 763 deselect();
JDI_Mbed_Team 0:33fe30a2b785 764
JDI_Mbed_Team 0:33fe30a2b785 765 //Check the data response token
JDI_Mbed_Team 0:33fe30a2b785 766 if (token == 0x0A) {
JDI_Mbed_Team 0:33fe30a2b785 767 //A CRC error occured, try again
JDI_Mbed_Team 0:33fe30a2b785 768 continue;
JDI_Mbed_Team 0:33fe30a2b785 769 } else if (token == 0x0C) {
JDI_Mbed_Team 0:33fe30a2b785 770 //A write error occured, get out
JDI_Mbed_Team 0:33fe30a2b785 771 break;
JDI_Mbed_Team 0:33fe30a2b785 772 }
JDI_Mbed_Team 0:33fe30a2b785 773
JDI_Mbed_Team 0:33fe30a2b785 774 //Send CMD13(0x00000000) to verify that the programming was successful if enabled
JDI_Mbed_Team 0:33fe30a2b785 775 if (m_WriteValidation) {
JDI_Mbed_Team 0:33fe30a2b785 776 unsigned int resp;
JDI_Mbed_Team 0:33fe30a2b785 777 if (commandTransaction(CMD13, 0x00000000, &resp) != 0x00 || resp != 0x00) {
JDI_Mbed_Team 0:33fe30a2b785 778 //Some manner of unrecoverable write error occured during programming, get out
JDI_Mbed_Team 0:33fe30a2b785 779 break;
JDI_Mbed_Team 0:33fe30a2b785 780 }
JDI_Mbed_Team 0:33fe30a2b785 781 }
JDI_Mbed_Team 0:33fe30a2b785 782
JDI_Mbed_Team 0:33fe30a2b785 783 //The data was written successfully
JDI_Mbed_Team 0:33fe30a2b785 784 return true;
JDI_Mbed_Team 0:33fe30a2b785 785 } else {
JDI_Mbed_Team 0:33fe30a2b785 786 //The command failed, get out
JDI_Mbed_Team 0:33fe30a2b785 787 break;
JDI_Mbed_Team 0:33fe30a2b785 788 }
JDI_Mbed_Team 0:33fe30a2b785 789 }
JDI_Mbed_Team 0:33fe30a2b785 790
JDI_Mbed_Team 0:33fe30a2b785 791 //The single block write failed
JDI_Mbed_Team 0:33fe30a2b785 792 deselect();
JDI_Mbed_Team 0:33fe30a2b785 793 return false;
JDI_Mbed_Team 0:33fe30a2b785 794 }
JDI_Mbed_Team 0:33fe30a2b785 795
JDI_Mbed_Team 0:33fe30a2b785 796 inline bool SDFileSystem::writeBlocks(const char* buffer, unsigned int lba, unsigned int count)
JDI_Mbed_Team 0:33fe30a2b785 797 {
JDI_Mbed_Team 0:33fe30a2b785 798 char token;
JDI_Mbed_Team 0:33fe30a2b785 799 const char* currentBuffer = buffer;
JDI_Mbed_Team 0:33fe30a2b785 800 unsigned int currentLba = lba;
JDI_Mbed_Team 0:33fe30a2b785 801 int currentCount = count;
JDI_Mbed_Team 0:33fe30a2b785 802
JDI_Mbed_Team 0:33fe30a2b785 803 //Try to write each block up to 3 times
JDI_Mbed_Team 0:33fe30a2b785 804 for (int f = 0; f < 3;) {
JDI_Mbed_Team 0:33fe30a2b785 805 //If this is an SD card, send ACMD23(count) to set the number of blocks to pre-erase
JDI_Mbed_Team 0:33fe30a2b785 806 if (m_CardType != CARD_MMC) {
JDI_Mbed_Team 0:33fe30a2b785 807 if (commandTransaction(ACMD23, currentCount) != 0x00) {
JDI_Mbed_Team 0:33fe30a2b785 808 //The command failed, get out
JDI_Mbed_Team 0:33fe30a2b785 809 break;
JDI_Mbed_Team 0:33fe30a2b785 810 }
JDI_Mbed_Team 0:33fe30a2b785 811 }
JDI_Mbed_Team 0:33fe30a2b785 812
JDI_Mbed_Team 0:33fe30a2b785 813 //Select the card, and wait for ready
JDI_Mbed_Team 0:33fe30a2b785 814 if(!select())
JDI_Mbed_Team 0:33fe30a2b785 815 break;
JDI_Mbed_Team 0:33fe30a2b785 816
JDI_Mbed_Team 0:33fe30a2b785 817 //Send CMD25(block) to write multiple blocks
JDI_Mbed_Team 0:33fe30a2b785 818 if (writeCommand(CMD25, (m_CardType == CARD_SDHC) ? currentLba : currentLba << 9) == 0x00) {
JDI_Mbed_Team 0:33fe30a2b785 819 //Try to write all of the data blocks
JDI_Mbed_Team 0:33fe30a2b785 820 do {
JDI_Mbed_Team 0:33fe30a2b785 821 //Write the next block and break on errors
JDI_Mbed_Team 0:33fe30a2b785 822 token = writeData(currentBuffer, 0xFC);
JDI_Mbed_Team 0:33fe30a2b785 823 if (token != 0x05) {
JDI_Mbed_Team 0:33fe30a2b785 824 f++;
JDI_Mbed_Team 0:33fe30a2b785 825 break;
JDI_Mbed_Team 0:33fe30a2b785 826 }
JDI_Mbed_Team 0:33fe30a2b785 827
JDI_Mbed_Team 0:33fe30a2b785 828 //Update the variables
JDI_Mbed_Team 0:33fe30a2b785 829 currentBuffer += 512;
JDI_Mbed_Team 0:33fe30a2b785 830 f = 0;
JDI_Mbed_Team 0:33fe30a2b785 831 } while (--currentCount);
JDI_Mbed_Team 0:33fe30a2b785 832
JDI_Mbed_Team 0:33fe30a2b785 833 //Wait for up to 500ms for the card to finish processing the last block
JDI_Mbed_Team 0:33fe30a2b785 834 if (!waitReady(500))
JDI_Mbed_Team 0:33fe30a2b785 835 break;
JDI_Mbed_Team 0:33fe30a2b785 836
JDI_Mbed_Team 0:33fe30a2b785 837 //Finalize the transmission
JDI_Mbed_Team 0:33fe30a2b785 838 if (currentCount == 0) {
JDI_Mbed_Team 0:33fe30a2b785 839 //Send the stop tran token, and deselect the card
JDI_Mbed_Team 0:33fe30a2b785 840 m_Spi.write(0xFD);
JDI_Mbed_Team 0:33fe30a2b785 841 deselect();
JDI_Mbed_Team 0:33fe30a2b785 842
JDI_Mbed_Team 0:33fe30a2b785 843 //Send CMD13(0x00000000) to verify that the programming was successful if enabled
JDI_Mbed_Team 0:33fe30a2b785 844 if (m_WriteValidation) {
JDI_Mbed_Team 0:33fe30a2b785 845 unsigned int resp;
JDI_Mbed_Team 0:33fe30a2b785 846 if (commandTransaction(CMD13, 0x00000000, &resp) != 0x00 || resp != 0x00) {
JDI_Mbed_Team 0:33fe30a2b785 847 //Some manner of unrecoverable write error occured during programming, get out
JDI_Mbed_Team 0:33fe30a2b785 848 break;
JDI_Mbed_Team 0:33fe30a2b785 849 }
JDI_Mbed_Team 0:33fe30a2b785 850 }
JDI_Mbed_Team 0:33fe30a2b785 851
JDI_Mbed_Team 0:33fe30a2b785 852 //The data was written successfully
JDI_Mbed_Team 0:33fe30a2b785 853 return true;
JDI_Mbed_Team 0:33fe30a2b785 854 } else {
JDI_Mbed_Team 0:33fe30a2b785 855 //Send CMD12(0x00000000) to abort the transmission
JDI_Mbed_Team 0:33fe30a2b785 856 if (writeCommand(CMD12, 0x00000000) != 0x00) {
JDI_Mbed_Team 0:33fe30a2b785 857 //The command failed, get out
JDI_Mbed_Team 0:33fe30a2b785 858 break;
JDI_Mbed_Team 0:33fe30a2b785 859 }
JDI_Mbed_Team 0:33fe30a2b785 860
JDI_Mbed_Team 0:33fe30a2b785 861 //Deselect the card
JDI_Mbed_Team 0:33fe30a2b785 862 deselect();
JDI_Mbed_Team 0:33fe30a2b785 863
JDI_Mbed_Team 0:33fe30a2b785 864 //Check the error token
JDI_Mbed_Team 0:33fe30a2b785 865 if (token == 0x0A) {
JDI_Mbed_Team 0:33fe30a2b785 866 //Determine the number of well written blocks if possible
JDI_Mbed_Team 0:33fe30a2b785 867 unsigned int writtenBlocks = 0;
JDI_Mbed_Team 0:33fe30a2b785 868 if (m_CardType != CARD_MMC && select()) {
JDI_Mbed_Team 0:33fe30a2b785 869 //Send ACMD22(0x00000000) to get the number of well written blocks
JDI_Mbed_Team 0:33fe30a2b785 870 if (writeCommand(ACMD22, 0x00000000) == 0x00) {
JDI_Mbed_Team 0:33fe30a2b785 871 //Read the data
JDI_Mbed_Team 0:33fe30a2b785 872 char acmdData[4];
JDI_Mbed_Team 0:33fe30a2b785 873 if (readData(acmdData, 4)) {
JDI_Mbed_Team 0:33fe30a2b785 874 //Extract the number of well written blocks
JDI_Mbed_Team 0:33fe30a2b785 875 writtenBlocks = acmdData[0] << 24;
JDI_Mbed_Team 0:33fe30a2b785 876 writtenBlocks |= acmdData[1] << 16;
JDI_Mbed_Team 0:33fe30a2b785 877 writtenBlocks |= acmdData[2] << 8;
JDI_Mbed_Team 0:33fe30a2b785 878 writtenBlocks |= acmdData[3];
JDI_Mbed_Team 0:33fe30a2b785 879 }
JDI_Mbed_Team 0:33fe30a2b785 880 }
JDI_Mbed_Team 0:33fe30a2b785 881 deselect();
JDI_Mbed_Team 0:33fe30a2b785 882 }
JDI_Mbed_Team 0:33fe30a2b785 883
JDI_Mbed_Team 0:33fe30a2b785 884 //Roll back the variables based on the number of well written blocks
JDI_Mbed_Team 0:33fe30a2b785 885 currentBuffer = buffer + (writtenBlocks << 9);
JDI_Mbed_Team 0:33fe30a2b785 886 currentLba = lba + writtenBlocks;
JDI_Mbed_Team 0:33fe30a2b785 887 currentCount = count - writtenBlocks;
JDI_Mbed_Team 0:33fe30a2b785 888
JDI_Mbed_Team 0:33fe30a2b785 889 //Try again
JDI_Mbed_Team 0:33fe30a2b785 890 continue;
JDI_Mbed_Team 0:33fe30a2b785 891 } else {
JDI_Mbed_Team 0:33fe30a2b785 892 //A write error occured, get out
JDI_Mbed_Team 0:33fe30a2b785 893 break;
JDI_Mbed_Team 0:33fe30a2b785 894 }
JDI_Mbed_Team 0:33fe30a2b785 895 }
JDI_Mbed_Team 0:33fe30a2b785 896 } else {
JDI_Mbed_Team 0:33fe30a2b785 897 //The command failed, get out
JDI_Mbed_Team 0:33fe30a2b785 898 break;
JDI_Mbed_Team 0:33fe30a2b785 899 }
JDI_Mbed_Team 0:33fe30a2b785 900 }
JDI_Mbed_Team 0:33fe30a2b785 901
JDI_Mbed_Team 0:33fe30a2b785 902 //The multiple block write failed
JDI_Mbed_Team 0:33fe30a2b785 903 deselect();
JDI_Mbed_Team 0:33fe30a2b785 904 return false;
JDI_Mbed_Team 0:33fe30a2b785 905 }
JDI_Mbed_Team 0:33fe30a2b785 906
JDI_Mbed_Team 0:33fe30a2b785 907 bool SDFileSystem::enableHighSpeedMode()
JDI_Mbed_Team 0:33fe30a2b785 908 {
JDI_Mbed_Team 0:33fe30a2b785 909 //Try to issue CMD6 up to 3 times
JDI_Mbed_Team 0:33fe30a2b785 910 for (int f = 0; f < 3; f++) {
JDI_Mbed_Team 0:33fe30a2b785 911 //Select the card, and wait for ready
JDI_Mbed_Team 0:33fe30a2b785 912 if(!select())
JDI_Mbed_Team 0:33fe30a2b785 913 break;
JDI_Mbed_Team 0:33fe30a2b785 914
JDI_Mbed_Team 0:33fe30a2b785 915 //Send CMD6(0x80FFFFF1) to change the access mode to high speed
JDI_Mbed_Team 0:33fe30a2b785 916 if (writeCommand(CMD6, 0x80FFFFF1) == 0x00) {
JDI_Mbed_Team 0:33fe30a2b785 917 //Read the 64B status data block
JDI_Mbed_Team 0:33fe30a2b785 918 char status[64];
JDI_Mbed_Team 0:33fe30a2b785 919 bool success = readData(status, 64);
JDI_Mbed_Team 0:33fe30a2b785 920 deselect();
JDI_Mbed_Team 0:33fe30a2b785 921 if (success) {
JDI_Mbed_Team 0:33fe30a2b785 922 //Return whether or not the operation was successful
JDI_Mbed_Team 0:33fe30a2b785 923 return ((status[16] & 0x0F) == 0x1);
JDI_Mbed_Team 0:33fe30a2b785 924 }
JDI_Mbed_Team 0:33fe30a2b785 925 } else {
JDI_Mbed_Team 0:33fe30a2b785 926 //The command failed, get out
JDI_Mbed_Team 0:33fe30a2b785 927 break;
JDI_Mbed_Team 0:33fe30a2b785 928 }
JDI_Mbed_Team 0:33fe30a2b785 929 }
JDI_Mbed_Team 0:33fe30a2b785 930
JDI_Mbed_Team 0:33fe30a2b785 931 //The operation failed 3 times
JDI_Mbed_Team 0:33fe30a2b785 932 deselect();
JDI_Mbed_Team 0:33fe30a2b785 933 return false;
JDI_Mbed_Team 0:33fe30a2b785 934 }