Daiki Kato / Mbed OS GR-PEACH_Audio_WAV_PwmOut Featured

Dependencies:   EasyPlayback

Fork of GR-PEACH_Audio_WAV by Renesas

This is a sample that drives a speaker with PWM. This sample will play a ".wav" file of the microSD or USB memory root folder. If the USER_BUTTON0 is pressed, the next song is played.

/media/uploads/dkato/pwm_speaker_img.png

FormatWav file (RIFF format) ".wav"
Channel1ch and 2ch
Frequencies32kHz, 44.1kHz and 48kHz
Quantization bit rate8bits and 16bits


You can adjust the volume by changing the following.

main.cpp

AudioPlayer.outputVolume(0.5);  // Volume control (min:0.0 max:1.0)


The default setting of serial communication (baud rate etc.) in mbed is shown the following link.
Please refer to the link and change the settings of your PC terminal software.
The default value of baud rate in mbed is 9600, and this application uses baud rate 9600.
https://developer.mbed.org/teams/Renesas/wiki/GR-PEACH-Getting-Started#install-the-usb-serial-communication

Committer:
dkato
Date:
Tue Dec 20 05:41:42 2016 +0000
Revision:
9:c7c0a97fdb7f
Changed to sample to drive the speaker with PWM.

Who changed what in which revision?

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