16bit resolution PWM wave player with SD card, super lite version.
Dependencies: mbed DirectSPI FastPWM
Supported boards (confirmed):
Nucleo-F030R8
Nucleo-L152RE
Nucleo-F401RE
Nucleo-F411RE
Only compilation is OK (unchecked, but may work):
Nucleo-L073RZ
Nucleo-F334R8
Nucleo-F303RE
Nucleo-F429ZI
Nucleo-F446RE
Nucleo-F446ZE
Nucleo-L476RG
Supported SD card:
SDSC/SDHC card,
FAT16 and FAT32.
(1) At first, format SD card using SD Card Formatter
https://www.sdcard.org/downloads/formatter_4/index.html
(2) Copy PCM wav files to the SD card.
Supported file:
PCM wave file that have file extension ".wav" on root directory.
16bit/8bit, fs(sampling rate)=32kHz,44.1kHz,48kHz.
Stereo/Mono.
Hardware setting:
Refer to the file port_setting.txt
PWM output port:
Left upper(Hi) PWM 8bit out: PB_5 (TM3_CH2)
Right upper(Hi) PWM 8bit out: PB4 (TM3_CH1)
Left lower(Low) PWM 8bit out: PC_9 (TM3_CH4)
Right lower(Low) PWM 8bit out: PC_8 (TM3_CH3)
USER_BUTTON: PC_13(default button)
Next song: One click in Play mode.
Pause : Push long time .
Play : One click from Pause.
sd_card.cpp@21:dc161a192ba7, 2020-10-09 (annotated)
- Committer:
- mimi3
- Date:
- Fri Oct 09 07:47:36 2020 +0900
- Revision:
- 21:dc161a192ba7
- Parent:
- 4:8c1772c05eaf
trivial change
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mimi3 | 0:9a5c2fb0d96f | 1 | /* |
mimi3 | 0:9a5c2fb0d96f | 2 | -- Title: Library for communicating with SD memory cards |
mimi3 | 0:9a5c2fb0d96f | 3 | -- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved. |
mimi3 | 0:9a5c2fb0d96f | 4 | -- Adapted-by: |
mimi3 | 0:9a5c2fb0d96f | 5 | -- Compiler: >=2.4q2 |
mimi3 | 0:9a5c2fb0d96f | 6 | -- Revision: $Revision: 3534 $ |
mimi3 | 0:9a5c2fb0d96f | 7 | -- |
mimi3 | 0:9a5c2fb0d96f | 8 | -- This file is part of jallib (http://jallib.googlecode.com) |
mimi3 | 0:9a5c2fb0d96f | 9 | -- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html) |
mimi3 | 0:9a5c2fb0d96f | 10 | -- |
mimi3 | 0:9a5c2fb0d96f | 11 | -- Description: this library provides functions for SD memory cards. |
mimi3 | 0:9a5c2fb0d96f | 12 | -- |
mimi3 | 0:9a5c2fb0d96f | 13 | -- Notes: SD card SPI mode is 1,1 |
mimi3 | 0:9a5c2fb0d96f | 14 | -- |
mimi3 | 0:9a5c2fb0d96f | 15 | -- This version works with standard capacity sd cards up to 4gb and |
mimi3 | 0:9a5c2fb0d96f | 16 | -- high capacity up to 32 gb. Extended Capacity up to 2TB |
mimi3 | 0:9a5c2fb0d96f | 17 | -- may be supported later on. |
mimi3 | 0:9a5c2fb0d96f | 18 | -- |
mimi3 | 0:9a5c2fb0d96f | 19 | -- Sources: |
mimi3 | 0:9a5c2fb0d96f | 20 | -- SanDisk Secure Digital Card - http://www.cs.ucr.edu/~amitra/sdcard/ProdManualSDCardv1.9.pdf |
mimi3 | 0:9a5c2fb0d96f | 21 | -- How to use MMC/SDC - http://forums.parallax.com/forums/attach.aspx?a=32012 |
mimi3 | 0:9a5c2fb0d96f | 22 | -- |
mimi3 | 0:9a5c2fb0d96f | 23 | */ |
mimi3 | 0:9a5c2fb0d96f | 24 | |
mimi3 | 0:9a5c2fb0d96f | 25 | #include "sys.h" |
mimi3 | 0:9a5c2fb0d96f | 26 | #include "sd_card.h" |
mimi3 | 0:9a5c2fb0d96f | 27 | #if HAVE_DIRECT_SPI |
mimi3 | 0:9a5c2fb0d96f | 28 | # include "DirectSPI.h" |
mimi3 | 0:9a5c2fb0d96f | 29 | DirectSPI spi(SPI_MOSI,SPI_MISO,SPI_SCK); |
mimi3 | 0:9a5c2fb0d96f | 30 | # define spi_write(m) spi.directWrite8(m) |
mimi3 | 0:9a5c2fb0d96f | 31 | #else |
mimi3 | 0:9a5c2fb0d96f | 32 | SPI spi(SPI_MOSI,SPI_MISO,SPI_SCK); |
mimi3 | 0:9a5c2fb0d96f | 33 | # define spi_write(m) spi.write(m) |
mimi3 | 0:9a5c2fb0d96f | 34 | #endif |
mimi3 | 0:9a5c2fb0d96f | 35 | DigitalOut sd_chip_select(SPI_CS); |
mimi3 | 0:9a5c2fb0d96f | 36 | |
mimi3 | 0:9a5c2fb0d96f | 37 | #define _usec_delay(m) wait_us(m) |
mimi3 | 0:9a5c2fb0d96f | 38 | |
mimi3 | 0:9a5c2fb0d96f | 39 | |
mimi3 | 0:9a5c2fb0d96f | 40 | #define SD_BYTE_PER_SECTOR 512 |
mimi3 | 0:9a5c2fb0d96f | 41 | |
mimi3 | 0:9a5c2fb0d96f | 42 | void sd_ready(); |
mimi3 | 0:9a5c2fb0d96f | 43 | |
mimi3 | 0:9a5c2fb0d96f | 44 | //-- counters |
mimi3 | 0:9a5c2fb0d96f | 45 | word sd_byte_count = 0; |
mimi3 | 0:9a5c2fb0d96f | 46 | word sd_sector_count = 0; |
mimi3 | 0:9a5c2fb0d96f | 47 | dword sd_sector_select; |
mimi3 | 0:9a5c2fb0d96f | 48 | |
mimi3 | 0:9a5c2fb0d96f | 49 | //-- Basic Commands |
mimi3 | 0:9a5c2fb0d96f | 50 | #define SD_GO_IDLE_STATE 0 |
mimi3 | 0:9a5c2fb0d96f | 51 | #define SD_SEND_OP_COND 1 |
mimi3 | 0:9a5c2fb0d96f | 52 | #define SD_SEND_IF_COND 8 //-- for SDHC only |
mimi3 | 0:9a5c2fb0d96f | 53 | #define SD_SEND_CSD 9 //-- sd sends "Card Specific Data" standard or high capacity |
mimi3 | 0:9a5c2fb0d96f | 54 | #define SD_SEND_CID 10 |
mimi3 | 0:9a5c2fb0d96f | 55 | #define SD_STOP_TRANSMISSION 12 |
mimi3 | 0:9a5c2fb0d96f | 56 | #define SD_SEND_STATUS 13 |
mimi3 | 0:9a5c2fb0d96f | 57 | |
mimi3 | 0:9a5c2fb0d96f | 58 | //-- Read Commands |
mimi3 | 0:9a5c2fb0d96f | 59 | #define SD_SET_BLOCKLEN 16 |
mimi3 | 0:9a5c2fb0d96f | 60 | #define SD_READ_SINGLE_BLOCK 17 |
mimi3 | 0:9a5c2fb0d96f | 61 | #define SD_READ_MULTIPLE_BLOCK 18 |
mimi3 | 0:9a5c2fb0d96f | 62 | |
mimi3 | 0:9a5c2fb0d96f | 63 | //-- Write Commands |
mimi3 | 0:9a5c2fb0d96f | 64 | #define SD_WRITE_BLOCK 24 |
mimi3 | 0:9a5c2fb0d96f | 65 | #define SD_WRITE_MULTIPLE_BLOCK 25 |
mimi3 | 0:9a5c2fb0d96f | 66 | #define SD_PROGRAM_CSD 27 |
mimi3 | 0:9a5c2fb0d96f | 67 | |
mimi3 | 0:9a5c2fb0d96f | 68 | //-- Write Protection Commands |
mimi3 | 0:9a5c2fb0d96f | 69 | #define SD_SET_WRITE_PROT 28 |
mimi3 | 0:9a5c2fb0d96f | 70 | #define SD_CLR_WRITE_PROT 29 |
mimi3 | 0:9a5c2fb0d96f | 71 | #define SD_SEND_WRITE_PROT 30 |
mimi3 | 0:9a5c2fb0d96f | 72 | |
mimi3 | 0:9a5c2fb0d96f | 73 | //-- Erase Commands |
mimi3 | 0:9a5c2fb0d96f | 74 | #define SD_ERASE_WR_BLK_START 32 |
mimi3 | 0:9a5c2fb0d96f | 75 | #define SD_ERASE_WR_BLK_END 33 |
mimi3 | 0:9a5c2fb0d96f | 76 | #define SD_ERASE 38 |
mimi3 | 0:9a5c2fb0d96f | 77 | |
mimi3 | 0:9a5c2fb0d96f | 78 | //-- Application Specific Commands |
mimi3 | 0:9a5c2fb0d96f | 79 | #define SD_APP_CMD 55 //-- indicate that the next command is a application specific command |
mimi3 | 0:9a5c2fb0d96f | 80 | #define SD_GEN_CMD 56 |
mimi3 | 0:9a5c2fb0d96f | 81 | |
mimi3 | 0:9a5c2fb0d96f | 82 | //-- Other Commands |
mimi3 | 0:9a5c2fb0d96f | 83 | #define SD_READ_OCR 58 |
mimi3 | 0:9a5c2fb0d96f | 84 | #define SD_CRC_ON_OFF 59 //-- default is off |
mimi3 | 0:9a5c2fb0d96f | 85 | |
mimi3 | 0:9a5c2fb0d96f | 86 | //-- application specific command, must write command 55 first |
mimi3 | 0:9a5c2fb0d96f | 87 | #define SD_SD_STATUS 13 |
mimi3 | 0:9a5c2fb0d96f | 88 | #define SD_SEND_NUM_WR_BLOCKS 22 |
mimi3 | 0:9a5c2fb0d96f | 89 | #define SD_SET_WR_BLK_ERASE_COUNT 23 |
mimi3 | 0:9a5c2fb0d96f | 90 | #define SD_SD_APP_OP_COND 41 |
mimi3 | 0:9a5c2fb0d96f | 91 | #define SD_SET_CLR_CARD_DETECT 42 |
mimi3 | 0:9a5c2fb0d96f | 92 | #define SD_SEND_SCR 51 |
mimi3 | 0:9a5c2fb0d96f | 93 | |
mimi3 | 0:9a5c2fb0d96f | 94 | //-- R1 RESPONCE boolS |
mimi3 | 0:9a5c2fb0d96f | 95 | #define SD_IN_IDLE_STATE 0 |
mimi3 | 0:9a5c2fb0d96f | 96 | #define SD_ERASE_RESET 1 |
mimi3 | 0:9a5c2fb0d96f | 97 | #define SD_ILLEGAL_COMMAND 2 |
mimi3 | 0:9a5c2fb0d96f | 98 | #define SD_COM_CRC_ERROR 3 |
mimi3 | 0:9a5c2fb0d96f | 99 | #define SD_ERASE_SEQUENCE_ERROR 4 |
mimi3 | 0:9a5c2fb0d96f | 100 | #define SD_ADDRESS_ERROR 5 |
mimi3 | 0:9a5c2fb0d96f | 101 | #define SD_PARAMETER_ERROR 6 |
mimi3 | 0:9a5c2fb0d96f | 102 | |
mimi3 | 0:9a5c2fb0d96f | 103 | bool sd_error = false; |
mimi3 | 0:9a5c2fb0d96f | 104 | bool sd_card_type = 0; |
mimi3 | 0:9a5c2fb0d96f | 105 | #define SD_HIGH_CAPACITY 0 |
mimi3 | 0:9a5c2fb0d96f | 106 | #define SD_STANDARD_CAPACITY 1 |
mimi3 | 0:9a5c2fb0d96f | 107 | |
mimi3 | 0:9a5c2fb0d96f | 108 | //-- carrier used to access SD-Card (pseudo-var dealing with SPI) |
mimi3 | 0:9a5c2fb0d96f | 109 | |
mimi3 | 0:9a5c2fb0d96f | 110 | //-- number of sectors variable |
mimi3 | 0:9a5c2fb0d96f | 111 | //dword sd_number_of_sectors; //-- number of sectors * 512 = sd card size |
mimi3 | 0:9a5c2fb0d96f | 112 | void sd_get_number_of_sectors(){} |
mimi3 | 0:9a5c2fb0d96f | 113 | |
mimi3 | 0:9a5c2fb0d96f | 114 | //-------------------------------------------------------------------------------- |
mimi3 | 0:9a5c2fb0d96f | 115 | //-- send a command to the sd card (commands with 1 response only) |
mimi3 | 0:9a5c2fb0d96f | 116 | //-------------------------------------------------------------------------------- |
mimi3 | 0:9a5c2fb0d96f | 117 | void send_command(byte command,dword _data, byte *response){ |
mimi3 | 0:9a5c2fb0d96f | 118 | byte x; |
mimi3 | 0:9a5c2fb0d96f | 119 | uint16_t i; |
mimi3 | 0:9a5c2fb0d96f | 120 | |
mimi3 | 0:9a5c2fb0d96f | 121 | //-- send a valid CRC byte only for set idle command |
mimi3 | 0:9a5c2fb0d96f | 122 | //-- right bool must always be 1 (stop bool) |
mimi3 | 0:9a5c2fb0d96f | 123 | if( command == SD_GO_IDLE_STATE){ |
mimi3 | 0:9a5c2fb0d96f | 124 | x = 0x95; |
mimi3 | 0:9a5c2fb0d96f | 125 | }else if( command == SD_SEND_IF_COND){ |
mimi3 | 0:9a5c2fb0d96f | 126 | x = 0x87; |
mimi3 | 0:9a5c2fb0d96f | 127 | }else{ |
mimi3 | 0:9a5c2fb0d96f | 128 | x = 0xFF; |
mimi3 | 0:9a5c2fb0d96f | 129 | } |
mimi3 | 0:9a5c2fb0d96f | 130 | |
mimi3 | 0:9a5c2fb0d96f | 131 | command = command + 64;// -- left bools must be 01 (start bools) |
mimi3 | 0:9a5c2fb0d96f | 132 | |
mimi3 | 0:9a5c2fb0d96f | 133 | spi_write(0xFF); //-- send 8 clock pulses |
mimi3 | 0:9a5c2fb0d96f | 134 | |
mimi3 | 0:9a5c2fb0d96f | 135 | spi_write(command); //-- send the command |
mimi3 | 0:9a5c2fb0d96f | 136 | spi_write((byte)(_data>>24) ); //-- send command parameters |
mimi3 | 0:9a5c2fb0d96f | 137 | spi_write((byte)(_data>>16) ); //-- send command parameters |
mimi3 | 0:9a5c2fb0d96f | 138 | spi_write((byte)(_data>>8 ) ); //-- send command parameters |
mimi3 | 0:9a5c2fb0d96f | 139 | spi_write((byte)(_data ) ); //-- send command parameters |
mimi3 | 0:9a5c2fb0d96f | 140 | |
mimi3 | 0:9a5c2fb0d96f | 141 | //-- CRC data byte, crc disabled in this lib, but required for SD_GO_IDLE_STATE & SD_SEND_IF_COND commands. |
mimi3 | 0:9a5c2fb0d96f | 142 | spi_write( x ); |
mimi3 | 0:9a5c2fb0d96f | 143 | |
mimi3 | 0:9a5c2fb0d96f | 144 | //-- Get a responce from the card after each command |
mimi3 | 0:9a5c2fb0d96f | 145 | #define RETRY 10 |
mimi3 | 0:9a5c2fb0d96f | 146 | for(i=0;i<RETRY;i++){ |
mimi3 | 0:9a5c2fb0d96f | 147 | *response = spi_read(); |
mimi3 | 0:9a5c2fb0d96f | 148 | //printf("\ncmd resp = %02X ",*response); |
mimi3 | 0:9a5c2fb0d96f | 149 | //if( *response != 0xFF){ |
mimi3 | 0:9a5c2fb0d96f | 150 | if( !(*response & 0x80 ) ){ |
mimi3 | 0:9a5c2fb0d96f | 151 | break; |
mimi3 | 0:9a5c2fb0d96f | 152 | } |
mimi3 | 0:9a5c2fb0d96f | 153 | } |
mimi3 | 0:9a5c2fb0d96f | 154 | #if DEBUG_SD_CARD |
mimi3 | 0:9a5c2fb0d96f | 155 | if(i>=RETRY){ printf("\n Fail Command [0x%02X]",command);} |
mimi3 | 0:9a5c2fb0d96f | 156 | #endif |
mimi3 | 0:9a5c2fb0d96f | 157 | } |
mimi3 | 0:9a5c2fb0d96f | 158 | |
mimi3 | 0:9a5c2fb0d96f | 159 | //-------------------------------------------------------------------------------- |
mimi3 | 0:9a5c2fb0d96f | 160 | //-- check if the sd card is ready after last command. |
mimi3 | 0:9a5c2fb0d96f | 161 | //-------------------------------------------------------------------------------- |
mimi3 | 0:9a5c2fb0d96f | 162 | void sd_ready(){ |
mimi3 | 0:9a5c2fb0d96f | 163 | byte response = 1; |
mimi3 | 0:9a5c2fb0d96f | 164 | while (response != 0) {// -- wait till last command has been completed |
mimi3 | 0:9a5c2fb0d96f | 165 | //;start sdcard initialize |
mimi3 | 0:9a5c2fb0d96f | 166 | send_command(SD_SEND_OP_COND,1, &response); // CMD1 |
mimi3 | 0:9a5c2fb0d96f | 167 | } |
mimi3 | 0:9a5c2fb0d96f | 168 | } |
mimi3 | 0:9a5c2fb0d96f | 169 | |
mimi3 | 0:9a5c2fb0d96f | 170 | |
mimi3 | 0:9a5c2fb0d96f | 171 | //-------------------------------------------------------------------------------- |
mimi3 | 0:9a5c2fb0d96f | 172 | //-- initalize the sd card in SPI data transfer mode. |
mimi3 | 0:9a5c2fb0d96f | 173 | //-------------------------------------------------------------------------------- |
mimi3 | 0:9a5c2fb0d96f | 174 | void sd_init(){ |
mimi3 | 0:9a5c2fb0d96f | 175 | byte response = 0;// -- shows if sd card init is ok |
mimi3 | 0:9a5c2fb0d96f | 176 | byte i; |
mimi3 | 0:9a5c2fb0d96f | 177 | uint16_t count1 = 0; |
mimi3 | 0:9a5c2fb0d96f | 178 | spi.frequency(500*1000);//500khz |
mimi3 | 0:9a5c2fb0d96f | 179 | spi.format(8,0); |
mimi3 | 0:9a5c2fb0d96f | 180 | //bool illegal_command at response : SD_ILLEGAL_COMMAND; |
mimi3 | 0:9a5c2fb0d96f | 181 | #define illegal_command ( response & (1<<SD_ILLEGAL_COMMAND) ) |
mimi3 | 0:9a5c2fb0d96f | 182 | //-- steps to set sd card to use SPI |
mimi3 | 0:9a5c2fb0d96f | 183 | _usec_delay(1000);// -- delay |
mimi3 | 0:9a5c2fb0d96f | 184 | sd_chip_select = 1;// -- chip select high |
mimi3 | 0:9a5c2fb0d96f | 185 | for(i=0;i<10;i++){ |
mimi3 | 0:9a5c2fb0d96f | 186 | spi_write(0xFF);// -- send clock pulses (0xFF 10 times) |
mimi3 | 0:9a5c2fb0d96f | 187 | } |
mimi3 | 0:9a5c2fb0d96f | 188 | //;-- try to contact the sd card |
mimi3 | 0:9a5c2fb0d96f | 189 | while ( response == 0 ) { // -- try 100 times |
mimi3 | 0:9a5c2fb0d96f | 190 | _usec_delay(1000); // -- delay 1ms |
mimi3 | 0:9a5c2fb0d96f | 191 | sd_chip_select = 0; // -- enable the sd card |
mimi3 | 0:9a5c2fb0d96f | 192 | _usec_delay(255); //-- delay 255us |
mimi3 | 0:9a5c2fb0d96f | 193 | // -- command 0, Resets card to idle state, get a response |
mimi3 | 0:9a5c2fb0d96f | 194 | send_command(SD_GO_IDLE_STATE,0,&response); // CMD0 |
mimi3 | 0:9a5c2fb0d96f | 195 | sd_chip_select = 1; // -- disable the sd card |
mimi3 | 0:9a5c2fb0d96f | 196 | count1 = count1 + 1; // -- increment count |
mimi3 | 0:9a5c2fb0d96f | 197 | if( count1 == 100) { |
mimi3 | 0:9a5c2fb0d96f | 198 | sd_error = true; |
mimi3 | 0:9a5c2fb0d96f | 199 | #if DEBUG_SD_CARD |
mimi3 | 0:9a5c2fb0d96f | 200 | printf("\n Error SD card initialize !"); |
mimi3 | 0:9a5c2fb0d96f | 201 | #endif |
mimi3 | 0:9a5c2fb0d96f | 202 | return; |
mimi3 | 0:9a5c2fb0d96f | 203 | } |
mimi3 | 0:9a5c2fb0d96f | 204 | //printf("\n response = 0x%02X",response); |
mimi3 | 0:9a5c2fb0d96f | 205 | } |
mimi3 | 0:9a5c2fb0d96f | 206 | |
mimi3 | 0:9a5c2fb0d96f | 207 | //-- send SD_SEND_IF_COND command |
mimi3 | 0:9a5c2fb0d96f | 208 | sd_chip_select = 0; // -- enable the sd card |
mimi3 | 0:9a5c2fb0d96f | 209 | send_command(SD_SEND_IF_COND, 0x1AA, &response) ; //CMD8 |
mimi3 | 0:9a5c2fb0d96f | 210 | |
mimi3 | 0:9a5c2fb0d96f | 211 | //printf("\n sd_init"); |
mimi3 | 0:9a5c2fb0d96f | 212 | if ( illegal_command ) { //-- SD CARD SPEC 1 |
mimi3 | 0:9a5c2fb0d96f | 213 | #if DEBUG_SD_CARD |
mimi3 | 0:9a5c2fb0d96f | 214 | printf("\n SDv1"); |
mimi3 | 0:9a5c2fb0d96f | 215 | #endif |
mimi3 | 0:9a5c2fb0d96f | 216 | #define print_string(sd,str) //printf(str) |
mimi3 | 0:9a5c2fb0d96f | 217 | sd_card_type = SD_STANDARD_CAPACITY; |
mimi3 | 0:9a5c2fb0d96f | 218 | |
mimi3 | 0:9a5c2fb0d96f | 219 | sd_chip_select = 0;// -- enable the sd card |
mimi3 | 0:9a5c2fb0d96f | 220 | //;start sdcard initialize |
mimi3 | 0:9a5c2fb0d96f | 221 | //sd_ready();// -- CMD1 wait till sd card is ready |
mimi3 | 0:9a5c2fb0d96f | 222 | sd_chip_select = 1;// -- disable the sd card |
mimi3 | 0:9a5c2fb0d96f | 223 | sd_get_number_of_sectors(); |
mimi3 | 0:9a5c2fb0d96f | 224 | return; |
mimi3 | 0:9a5c2fb0d96f | 225 | }else{ //-- SD CARD SPEC 2 |
mimi3 | 0:9a5c2fb0d96f | 226 | #if DEBUG_SD_CARD |
mimi3 | 0:9a5c2fb0d96f | 227 | printf("\n SDv2"); |
mimi3 | 0:9a5c2fb0d96f | 228 | #endif |
mimi3 | 0:9a5c2fb0d96f | 229 | //; read OCR 4 byte |
mimi3 | 0:9a5c2fb0d96f | 230 | response = spi_read(); |
mimi3 | 0:9a5c2fb0d96f | 231 | response = spi_read(); |
mimi3 | 0:9a5c2fb0d96f | 232 | response = spi_read();// ;0x01 |
mimi3 | 0:9a5c2fb0d96f | 233 | response = spi_read();// ;0xAA |
mimi3 | 0:9a5c2fb0d96f | 234 | sd_chip_select = 1;// -- disable the sd card |
mimi3 | 0:9a5c2fb0d96f | 235 | |
mimi3 | 0:9a5c2fb0d96f | 236 | if (response == 0xAA) { |
mimi3 | 0:9a5c2fb0d96f | 237 | sd_chip_select = 0;// -- enable the sd card |
mimi3 | 0:9a5c2fb0d96f | 238 | |
mimi3 | 0:9a5c2fb0d96f | 239 | //-- check if it has completed init |
mimi3 | 0:9a5c2fb0d96f | 240 | while(1){ |
mimi3 | 0:9a5c2fb0d96f | 241 | //; send ACMD41 |
mimi3 | 0:9a5c2fb0d96f | 242 | send_command(SD_APP_CMD, 0, &response); |
mimi3 | 0:9a5c2fb0d96f | 243 | send_command(SD_SD_APP_OP_COND,0x40000000, &response); |
mimi3 | 0:9a5c2fb0d96f | 244 | if( response == 0) { |
mimi3 | 0:9a5c2fb0d96f | 245 | break; |
mimi3 | 0:9a5c2fb0d96f | 246 | } |
mimi3 | 0:9a5c2fb0d96f | 247 | } |
mimi3 | 0:9a5c2fb0d96f | 248 | #if DEBUG_SD_CARD |
mimi3 | 0:9a5c2fb0d96f | 249 | printf("\n ACMD41 OK"); |
mimi3 | 0:9a5c2fb0d96f | 250 | #endif |
mimi3 | 0:9a5c2fb0d96f | 251 | //-- read OCR here |
mimi3 | 0:9a5c2fb0d96f | 252 | send_command(SD_READ_OCR,0, &response);// CMD58 |
mimi3 | 0:9a5c2fb0d96f | 253 | if ((spi_read() & 0x40) > 0) {// ; ocr[0] |
mimi3 | 0:9a5c2fb0d96f | 254 | sd_card_type = SD_HIGH_CAPACITY; //and BLOCK mode |
mimi3 | 0:9a5c2fb0d96f | 255 | #if DEBUG_SD_CARD |
mimi3 | 0:9a5c2fb0d96f | 256 | printf("\nSDHC block mode"); |
mimi3 | 0:9a5c2fb0d96f | 257 | #endif |
mimi3 | 0:9a5c2fb0d96f | 258 | }else{// -- sd card spec 2 standard capacity?? |
mimi3 | 0:9a5c2fb0d96f | 259 | sd_card_type = SD_STANDARD_CAPACITY; //and none BLOCK mode |
mimi3 | 0:9a5c2fb0d96f | 260 | #if DEBUG_SD_CARD |
mimi3 | 0:9a5c2fb0d96f | 261 | printf("\n SDSC none block mode"); |
mimi3 | 0:9a5c2fb0d96f | 262 | #endif |
mimi3 | 0:9a5c2fb0d96f | 263 | } |
mimi3 | 0:9a5c2fb0d96f | 264 | response = spi_read(); |
mimi3 | 0:9a5c2fb0d96f | 265 | response = spi_read(); |
mimi3 | 0:9a5c2fb0d96f | 266 | response = spi_read(); |
mimi3 | 0:9a5c2fb0d96f | 267 | |
mimi3 | 0:9a5c2fb0d96f | 268 | //-- set block size to 512 |
mimi3 | 0:9a5c2fb0d96f | 269 | send_command(SD_SET_BLOCKLEN,512, &response); |
mimi3 | 0:9a5c2fb0d96f | 270 | //sd_ready(); |
mimi3 | 0:9a5c2fb0d96f | 271 | |
mimi3 | 0:9a5c2fb0d96f | 272 | sd_chip_select = 1;// -- disable the sd card |
mimi3 | 0:9a5c2fb0d96f | 273 | #if DEBUG_SD_CARD |
mimi3 | 0:9a5c2fb0d96f | 274 | printf("\n Finished sd card initialize."); |
mimi3 | 0:9a5c2fb0d96f | 275 | #endif |
mimi3 | 0:9a5c2fb0d96f | 276 | }else{ |
mimi3 | 0:9a5c2fb0d96f | 277 | sd_error = true; |
mimi3 | 0:9a5c2fb0d96f | 278 | sd_chip_select = 1;// -- disable the sd card |
mimi3 | 0:9a5c2fb0d96f | 279 | sd_get_number_of_sectors(); |
mimi3 | 0:9a5c2fb0d96f | 280 | return; |
mimi3 | 0:9a5c2fb0d96f | 281 | } |
mimi3 | 0:9a5c2fb0d96f | 282 | } |
mimi3 | 0:9a5c2fb0d96f | 283 | sd_get_number_of_sectors(); |
mimi3 | 4:8c1772c05eaf | 284 | spi.frequency(16*1000000);// |
mimi3 | 0:9a5c2fb0d96f | 285 | } |
mimi3 | 0:9a5c2fb0d96f | 286 | |
mimi3 | 0:9a5c2fb0d96f | 287 | //-------------------------------------------------------------------------------- |
mimi3 | 0:9a5c2fb0d96f | 288 | //-- set the sd card to idle state |
mimi3 | 0:9a5c2fb0d96f | 289 | //-------------------------------------------------------------------------------- |
mimi3 | 0:9a5c2fb0d96f | 290 | void sd_set_idle(){ |
mimi3 | 0:9a5c2fb0d96f | 291 | byte response = 0; |
mimi3 | 0:9a5c2fb0d96f | 292 | sd_chip_select = 0;// -- enable the sd card |
mimi3 | 0:9a5c2fb0d96f | 293 | send_command(SD_STOP_TRANSMISSION,0,&response);// -- stop current transmission |
mimi3 | 0:9a5c2fb0d96f | 294 | send_command(SD_STOP_TRANSMISSION,0,&response);//-- stop current transmission |
mimi3 | 0:9a5c2fb0d96f | 295 | send_command(SD_STOP_TRANSMISSION,0,&response);// -- stop current transmission |
mimi3 | 0:9a5c2fb0d96f | 296 | send_command(SD_STOP_TRANSMISSION,0,&response);// -- stop current transmission |
mimi3 | 0:9a5c2fb0d96f | 297 | sd_chip_select = 1;// -- disable the sd card |
mimi3 | 0:9a5c2fb0d96f | 298 | } |
mimi3 | 0:9a5c2fb0d96f | 299 | |
mimi3 | 0:9a5c2fb0d96f | 300 | //-------------------------------------------------------------------------------- |
mimi3 | 0:9a5c2fb0d96f | 301 | //-- tell sd card you will be reading data from a specified sector |
mimi3 | 0:9a5c2fb0d96f | 302 | //-- do not interupt read process by switching to another spi component |
mimi3 | 0:9a5c2fb0d96f | 303 | //-------------------------------------------------------------------------------- |
mimi3 | 0:9a5c2fb0d96f | 304 | void sd_start_read(dword address){ |
mimi3 | 0:9a5c2fb0d96f | 305 | byte response; |
mimi3 | 0:9a5c2fb0d96f | 306 | |
mimi3 | 0:9a5c2fb0d96f | 307 | sd_sector_select = address; |
mimi3 | 0:9a5c2fb0d96f | 308 | //-- put spi into mode |
mimi3 | 0:9a5c2fb0d96f | 309 | sd_chip_select = 0;// -- enable the sd card |
mimi3 | 0:9a5c2fb0d96f | 310 | if( sd_card_type == SD_STANDARD_CAPACITY) { |
mimi3 | 0:9a5c2fb0d96f | 311 | address = address * SD_BYTE_PER_SECTOR;// -- make sd card sector addressable, sd cards are normally byte addressable. |
mimi3 | 0:9a5c2fb0d96f | 312 | } |
mimi3 | 0:9a5c2fb0d96f | 313 | |
mimi3 | 0:9a5c2fb0d96f | 314 | // -- send read multi block command, ignore response. |
mimi3 | 0:9a5c2fb0d96f | 315 | send_command(SD_READ_MULTIPLE_BLOCK,address,&response); //CMD18 |
mimi3 | 0:9a5c2fb0d96f | 316 | sd_byte_count = 0; |
mimi3 | 0:9a5c2fb0d96f | 317 | sd_sector_count = 0;// -- reset count |
mimi3 | 0:9a5c2fb0d96f | 318 | //wait_idle(); |
mimi3 | 0:9a5c2fb0d96f | 319 | } |
mimi3 | 0:9a5c2fb0d96f | 320 | //-------------------------------------------------------------------------------- |
mimi3 | 0:9a5c2fb0d96f | 321 | //-- read 1 bytes from the sd card (pseudo ) |
mimi3 | 0:9a5c2fb0d96f | 322 | //-------------------------------------------------------------------------------- |
mimi3 | 0:9a5c2fb0d96f | 323 | byte sd_data_byte() { |
mimi3 | 0:9a5c2fb0d96f | 324 | byte data_byte; |
mimi3 | 0:9a5c2fb0d96f | 325 | |
mimi3 | 0:9a5c2fb0d96f | 326 | if( sd_byte_count == 0) { // -- beginning of sector read |
mimi3 | 0:9a5c2fb0d96f | 327 | while( spi_read() != 0xFE){} // -- wait till data is ready to read |
mimi3 | 0:9a5c2fb0d96f | 328 | } |
mimi3 | 0:9a5c2fb0d96f | 329 | |
mimi3 | 0:9a5c2fb0d96f | 330 | data_byte = spi_read();// -- get data byte |
mimi3 | 0:9a5c2fb0d96f | 331 | |
mimi3 | 0:9a5c2fb0d96f | 332 | sd_byte_count = sd_byte_count + 1;// -- increment byte_count |
mimi3 | 0:9a5c2fb0d96f | 333 | if( sd_byte_count == SD_BYTE_PER_SECTOR) {// -- end of sector read |
mimi3 | 0:9a5c2fb0d96f | 334 | sd_byte_count = 0; |
mimi3 | 0:9a5c2fb0d96f | 335 | sd_sector_count = sd_sector_count + 1;// -- increment sector number |
mimi3 | 0:9a5c2fb0d96f | 336 | spi_read();// -- get junk crc data, crc is disabled |
mimi3 | 0:9a5c2fb0d96f | 337 | spi_read();// -- get junk crc data, crc is disabled |
mimi3 | 0:9a5c2fb0d96f | 338 | } |
mimi3 | 0:9a5c2fb0d96f | 339 | |
mimi3 | 0:9a5c2fb0d96f | 340 | return data_byte; |
mimi3 | 0:9a5c2fb0d96f | 341 | } |
mimi3 | 0:9a5c2fb0d96f | 342 | |
mimi3 | 0:9a5c2fb0d96f | 343 | //-------------------------------------------------------------------------------- |
mimi3 | 0:9a5c2fb0d96f | 344 | //-- tell sd card you are finished reading |
mimi3 | 0:9a5c2fb0d96f | 345 | //-- needed to be the same as other mass media libs |
mimi3 | 0:9a5c2fb0d96f | 346 | //-------------------------------------------------------------------------------- |
mimi3 | 0:9a5c2fb0d96f | 347 | void sd_stop_read(){ |
mimi3 | 0:9a5c2fb0d96f | 348 | sd_set_idle(); |
mimi3 | 0:9a5c2fb0d96f | 349 | sd_chip_select = 1;// -- disable the sd card |
mimi3 | 0:9a5c2fb0d96f | 350 | } |
mimi3 | 0:9a5c2fb0d96f | 351 | |
mimi3 | 0:9a5c2fb0d96f | 352 | //-------------------------------------------------------------------------------- |
mimi3 | 0:9a5c2fb0d96f | 353 | //-- send a read pulse to the sd card, go 1 bytes forward in current sector. |
mimi3 | 0:9a5c2fb0d96f | 354 | //-------------------------------------------------------------------------------- |
mimi3 | 0:9a5c2fb0d96f | 355 | void sd_read_pulse_byte(word count1){ |
mimi3 | 0:9a5c2fb0d96f | 356 | uint16_t i; |
mimi3 | 0:9a5c2fb0d96f | 357 | for(i=0;i<count1;i++){// -- loop specified number of times |
mimi3 | 0:9a5c2fb0d96f | 358 | sd_data_byte();// -- do a data read and ignore the incomming data |
mimi3 | 0:9a5c2fb0d96f | 359 | } |
mimi3 | 0:9a5c2fb0d96f | 360 | } |
mimi3 | 0:9a5c2fb0d96f | 361 |