first
Dependencies: SDFileSystemDMA mbed
Refer to:
https://developer.mbed.org/users/mimi3/code/SDFileSystemDMA
Caution
If your board has SRAM less than or equal to 8KB, the 'buffer' size must be set to 512 Bytes.
NUCLEO-F411RE
About 2.5MBytes/sec
NUCLEO-L152RE
About 1MBytes/sec
main.cpp@25:1e42edbeacca, 2017-01-17 (annotated)
- Committer:
- mimi3
- Date:
- Tue Jan 17 12:21:46 2017 +0900
- Revision:
- 25:1e42edbeacca
- Parent:
- 24:bea03d091636
- Child:
- 26:1a610f9aec1a
added: Message for creating test file at first time.
added: Comment for RTC error.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mimi3 | 0:8f297fe0c66a | 1 | #include "mbed.h" |
mimi3 | 0:8f297fe0c66a | 2 | #include "SDFileSystemDMA.h" |
mimi3 | 3:8b77055a68ec | 3 | |
mimi3 | 9:289de1b6d378 | 4 | /* SD card Interface connection |
mimi3 | 9:289de1b6d378 | 5 | * : aitendo : General |
mimi3 | 9:289de1b6d378 | 6 | * MCU sig. : IFB-254-SD : PIN name |
mimi3 | 9:289de1b6d378 | 7 | --- : 1 : 9 dat2 |
mimi3 | 9:289de1b6d378 | 8 | CS : 2 : 1 cs/dat3 |
mimi3 | 9:289de1b6d378 | 9 | MOSI : 3 : 2 di/cmd |
mimi3 | 9:289de1b6d378 | 10 | GND : 4 : 3 vss1 |
mimi3 | 9:289de1b6d378 | 11 | VCC : 5 : 4 vdd |
mimi3 | 9:289de1b6d378 | 12 | CLK : 6 : 5 clk |
mimi3 | 9:289de1b6d378 | 13 | GND : 7 : 6 vss2 |
mimi3 | 9:289de1b6d378 | 14 | MISO : 8 : 7 do/dat0 |
mimi3 | 9:289de1b6d378 | 15 | --- : 9 : 8 dat1 |
mimi3 | 9:289de1b6d378 | 16 | --- : 10 : 11 wp |
mimi3 | 9:289de1b6d378 | 17 | --- : 11 : 10 cd1 |
mimi3 | 9:289de1b6d378 | 18 | --- : 12 : - case GND |
mimi3 | 9:289de1b6d378 | 19 | */ |
dinau | 21:6253a88675a5 | 20 | /* SD card pin |
dinau | 21:6253a88675a5 | 21 | Pin side |
dinau | 21:6253a88675a5 | 22 | --------------\ |
dinau | 21:6253a88675a5 | 23 | 9 = \ DAT2/NC |
dinau | 21:6253a88675a5 | 24 | 1 ===| CS/DAT3 [CS] |
dinau | 21:6253a88675a5 | 25 | 2 ===| CMD/DI [DI] |
dinau | 21:6253a88675a5 | 26 | 3 ===| VSS1 |
dinau | 21:6253a88675a5 | 27 | Bottom 4 ===| VDD |
dinau | 21:6253a88675a5 | 28 | View 5 ===| CLK [CLK] |
dinau | 21:6253a88675a5 | 29 | 6 ===| VSS2 |
dinau | 21:6253a88675a5 | 30 | 7 ===| DO/DAT0 [DO] |
dinau | 21:6253a88675a5 | 31 | 8 =| DAT1/IRQ |
dinau | 21:6253a88675a5 | 32 | ----------------- |
dinau | 21:6253a88675a5 | 33 | |
dinau | 21:6253a88675a5 | 34 | Arduino NUCLEO-F411 NUCLEO-F030R8 |
dinau | 21:6253a88675a5 | 35 | Logo side |
dinau | 21:6253a88675a5 | 36 | ----------------- |
dinau | 21:6253a88675a5 | 37 | 8 =| DAT1/IRQ |
dinau | 21:6253a88675a5 | 38 | 7 ===| DO/DAT0 [DO] D12 D12/PA_6 D5/PB_4 |
dinau | 21:6253a88675a5 | 39 | 6 ===| VSS2 |
dinau | 21:6253a88675a5 | 40 | Top 5 ===| CLK [CLK] D13 D13/PA_5 D3/PB_3 |
dinau | 21:6253a88675a5 | 41 | View 4 ===| VDD |
dinau | 21:6253a88675a5 | 42 | 3 ===| VSS1 |
dinau | 21:6253a88675a5 | 43 | 2 ===| CMD/DI [DI] D11 D11/PA_7 D4/PB_5 |
dinau | 21:6253a88675a5 | 44 | 1 ===| CS/DAT3 [CS] D8 D10/PB_6 D10/PB_6 |
dinau | 21:6253a88675a5 | 45 | 9 = / DAT2/NC |
dinau | 21:6253a88675a5 | 46 | --------------/ |
dinau | 21:6253a88675a5 | 47 | */ |
dinau | 21:6253a88675a5 | 48 | |
mimi3 | 9:289de1b6d378 | 49 | |
mimi3 | 10:5f6fc7dc119b | 50 | /* You should confirm SPI_DEV macro in "spi_device.h" to specify SPI device number. |
mimi3 | 10:5f6fc7dc119b | 51 | * (default is 1 (SPI1)) |
mimi3 | 10:5f6fc7dc119b | 52 | */ |
mimi3 | 9:289de1b6d378 | 53 | #include "spi_device.h" |
mimi3 | 3:8b77055a68ec | 54 | #define UART_KEY_PRESS 1 |
mimi3 | 3:8b77055a68ec | 55 | |
mimi3 | 10:5f6fc7dc119b | 56 | #define SPI_CLOCK_HZ ( 12 * 1000000 ) |
dinau | 20:e34f5e5f307b | 57 | |
mimi3 | 0:8f297fe0c66a | 58 | Timer timer; |
mimi3 | 12:dfa39c797789 | 59 | //Serial pc(PA_9,PA_10); |
dinau | 21:6253a88675a5 | 60 | Serial pc(USBTX,USBRX); /* Baudrate is 9600bps*/ |
mimi3 | 0:8f297fe0c66a | 61 | |
mimi3 | 3:8b77055a68ec | 62 | SDFileSystem sd( MOSI, MISO, SCLK, CS, "sd", SPI_CLOCK_HZ); |
mimi3 | 1:c39cfc31349d | 63 | |
mimi3 | 25:1e42edbeacca | 64 | /* Set buffer size */ |
mimi3 | 25:1e42edbeacca | 65 | char buffer[512*1] __attribute__ ((aligned (4))) ; /* 512 bytes */ |
dinau | 21:6253a88675a5 | 66 | //char buffer[512*2] __attribute__ ((aligned (4))) ; /* 1024 bytes */ |
mimi3 | 25:1e42edbeacca | 67 | //char buffer[512*4] __attribute__ ((aligned (4))) ; /* 2048 bytes */ |
dinau | 21:6253a88675a5 | 68 | //char buffer[512*8] __attribute__ ((aligned (4))) ; /* 4096 bytes */ |
dinau | 21:6253a88675a5 | 69 | //char buffer[512*16] __attribute__ ((aligned (4))) ; /* 8192 bytes */ |
dinau | 21:6253a88675a5 | 70 | //char buffer[512*32] __attribute__ ((aligned (4))) ; /* 16384 bytes */ |
mimi3 | 12:dfa39c797789 | 71 | |
mimi3 | 0:8f297fe0c66a | 72 | #define X_MEGA_BYTE ((1)*1024*1024) /* 1Mbyte */ |
mimi3 | 0:8f297fe0c66a | 73 | #define FILE_NAME "GPATH" |
dinau | 20:e34f5e5f307b | 74 | |
dinau | 22:5c133291a01d | 75 | #if defined(__CC_ARM) /* ARMCC */ |
dinau | 22:5c133291a01d | 76 | #define TOOLCHAIN "ARM/uARM" |
mimi3 | 25:1e42edbeacca | 77 | #define C_VERSION __ARMCC_VERSION |
dinau | 22:5c133291a01d | 78 | #elif defined(__GNUC__) /* GCC */ |
dinau | 21:6253a88675a5 | 79 | #define TOOLCHAIN "GCC_ARM" |
dinau | 21:6253a88675a5 | 80 | #elif defined(__ICCARM__) /* IAR */ |
dinau | 21:6253a88675a5 | 81 | #define TOOLCHAIN "IAR" |
dinau | 24:bea03d091636 | 82 | #else |
dinau | 24:bea03d091636 | 83 | #define TOOLCHAIN "Unknown" |
dinau | 21:6253a88675a5 | 84 | #warning "This compiler is not yet supported." |
dinau | 21:6253a88675a5 | 85 | #endif |
dinau | 21:6253a88675a5 | 86 | |
dinau | 21:6253a88675a5 | 87 | int wait_key_press(){ |
mimi3 | 3:8b77055a68ec | 88 | #if UART_KEY_PRESS |
mimi3 | 12:dfa39c797789 | 89 | while(!pc.readable()); |
dinau | 21:6253a88675a5 | 90 | return pc.getc(); |
mimi3 | 3:8b77055a68ec | 91 | #endif |
mimi3 | 0:8f297fe0c66a | 92 | } |
mimi3 | 0:8f297fe0c66a | 93 | |
mimi3 | 0:8f297fe0c66a | 94 | void writeTest() |
mimi3 | 0:8f297fe0c66a | 95 | { |
dinau | 20:e34f5e5f307b | 96 | #if !_FS_READONLY |
mimi3 | 12:dfa39c797789 | 97 | //Test write performance by creating a 1MB file |
dinau | 21:6253a88675a5 | 98 | pc.printf("[Write]: Testing %d bytes buffer: write performance...", sizeof(buffer)); |
mimi3 | 12:dfa39c797789 | 99 | fflush(stdout); |
mimi3 | 12:dfa39c797789 | 100 | for(uint32_t k = 0; k < sizeof(buffer); k++){ |
mimi3 | 12:dfa39c797789 | 101 | buffer[k] = k & 0xff; |
mimi3 | 12:dfa39c797789 | 102 | } |
mimi3 | 12:dfa39c797789 | 103 | |
mimi3 | 12:dfa39c797789 | 104 | FileHandle* file = sd.open(FILE_NAME, O_WRONLY | O_CREAT | O_TRUNC); |
mimi3 | 12:dfa39c797789 | 105 | if (file != NULL) { |
mimi3 | 12:dfa39c797789 | 106 | timer.start(); |
mimi3 | 12:dfa39c797789 | 107 | for (uint32_t i = 0; i < (X_MEGA_BYTE / sizeof(buffer)); i++) { |
mimi3 | 12:dfa39c797789 | 108 | if (file->write(buffer, sizeof(buffer)) != sizeof(buffer)) { |
mimi3 | 12:dfa39c797789 | 109 | timer.stop(); |
mimi3 | 12:dfa39c797789 | 110 | pc.printf("write error!\n"); |
mimi3 | 12:dfa39c797789 | 111 | timer.reset(); |
mimi3 | 12:dfa39c797789 | 112 | return; |
mimi3 | 12:dfa39c797789 | 113 | } |
mimi3 | 12:dfa39c797789 | 114 | } |
mimi3 | 12:dfa39c797789 | 115 | timer.stop(); |
mimi3 | 12:dfa39c797789 | 116 | if (file->close()) |
mimi3 | 12:dfa39c797789 | 117 | pc.printf("failed to close file!\n"); |
mimi3 | 12:dfa39c797789 | 118 | else{ |
mimi3 | 12:dfa39c797789 | 119 | pc.printf("done!\n\tResult: %d KB/s\n", ( 1024 * 1000000 ) / timer.read_us() ); |
mimi3 | 12:dfa39c797789 | 120 | } |
mimi3 | 12:dfa39c797789 | 121 | timer.reset(); |
mimi3 | 12:dfa39c797789 | 122 | } else { |
mimi3 | 12:dfa39c797789 | 123 | pc.printf("failed to create file!\n"); |
mimi3 | 12:dfa39c797789 | 124 | } |
dinau | 20:e34f5e5f307b | 125 | #endif |
mimi3 | 0:8f297fe0c66a | 126 | } |
mimi3 | 0:8f297fe0c66a | 127 | |
mimi3 | 0:8f297fe0c66a | 128 | void readTest() |
mimi3 | 0:8f297fe0c66a | 129 | { |
mimi3 | 12:dfa39c797789 | 130 | //Test read performance by reading the 1MB file created by writeTest() |
dinau | 21:6253a88675a5 | 131 | pc.printf("[Read]: Testing %d bytes buffer: read performance...", sizeof(buffer)); |
mimi3 | 12:dfa39c797789 | 132 | fflush(stdout); |
mimi3 | 12:dfa39c797789 | 133 | FileHandle* file = sd.open(FILE_NAME, O_RDONLY); |
mimi3 | 12:dfa39c797789 | 134 | if (file != NULL) { |
mimi3 | 12:dfa39c797789 | 135 | timer.start(); |
mimi3 | 12:dfa39c797789 | 136 | int iterations = 0; |
mimi3 | 12:dfa39c797789 | 137 | while (file->read(buffer, sizeof(buffer)) == sizeof(buffer)){ |
mimi3 | 12:dfa39c797789 | 138 | iterations++; |
mimi3 | 12:dfa39c797789 | 139 | } |
mimi3 | 12:dfa39c797789 | 140 | timer.stop(); |
mimi3 | 12:dfa39c797789 | 141 | if (iterations != (X_MEGA_BYTE / sizeof(buffer))){ |
mimi3 | 12:dfa39c797789 | 142 | pc.printf("read error!\n"); |
mimi3 | 12:dfa39c797789 | 143 | } |
mimi3 | 12:dfa39c797789 | 144 | else if (file->close()){ |
mimi3 | 12:dfa39c797789 | 145 | pc.printf("failed to close file!\n"); |
mimi3 | 12:dfa39c797789 | 146 | } |
mimi3 | 12:dfa39c797789 | 147 | else{ |
mimi3 | 12:dfa39c797789 | 148 | pc.printf("done!\n\tResult: %d KB/s\n", ( 1024 * 1000000 ) / timer.read_us()); |
mimi3 | 12:dfa39c797789 | 149 | } |
mimi3 | 12:dfa39c797789 | 150 | timer.reset(); |
mimi3 | 12:dfa39c797789 | 151 | } else { |
mimi3 | 12:dfa39c797789 | 152 | pc.printf("failed to open file!\n"); |
mimi3 | 12:dfa39c797789 | 153 | } |
mimi3 | 12:dfa39c797789 | 154 | } |
mimi3 | 12:dfa39c797789 | 155 | |
mimi3 | 12:dfa39c797789 | 156 | void verifyTest() |
mimi3 | 12:dfa39c797789 | 157 | { |
mimi3 | 12:dfa39c797789 | 158 | int errorCount = 0; |
mimi3 | 12:dfa39c797789 | 159 | //Test read performance by reading the 1MB file created by writeTest() |
dinau | 21:6253a88675a5 | 160 | pc.printf("[Read]: Verifying %d bytes buffer ...", sizeof(buffer)); |
mimi3 | 12:dfa39c797789 | 161 | fflush(stdout); |
mimi3 | 12:dfa39c797789 | 162 | FileHandle* file = sd.open(FILE_NAME, O_RDONLY); |
mimi3 | 12:dfa39c797789 | 163 | if (file != NULL) { |
mimi3 | 12:dfa39c797789 | 164 | timer.start(); |
mimi3 | 12:dfa39c797789 | 165 | int iterations = 0; |
mimi3 | 12:dfa39c797789 | 166 | while (file->read(buffer, sizeof(buffer)) == sizeof(buffer)){ |
mimi3 | 12:dfa39c797789 | 167 | iterations++; |
mimi3 | 12:dfa39c797789 | 168 | for(uint32_t k = 0; k < sizeof(buffer); k++){ |
mimi3 | 12:dfa39c797789 | 169 | if ( buffer[k] != (k & 0xff) ){ |
mimi3 | 12:dfa39c797789 | 170 | errorCount++; |
mimi3 | 12:dfa39c797789 | 171 | } |
mimi3 | 12:dfa39c797789 | 172 | } |
mimi3 | 12:dfa39c797789 | 173 | } |
mimi3 | 12:dfa39c797789 | 174 | timer.stop(); |
mimi3 | 12:dfa39c797789 | 175 | if (iterations != (X_MEGA_BYTE / sizeof(buffer))){ |
mimi3 | 12:dfa39c797789 | 176 | pc.printf("read error!\n"); |
mimi3 | 12:dfa39c797789 | 177 | } |
mimi3 | 12:dfa39c797789 | 178 | else if (file->close()){ |
mimi3 | 12:dfa39c797789 | 179 | pc.printf("failed to close file!\n"); |
mimi3 | 12:dfa39c797789 | 180 | } |
mimi3 | 12:dfa39c797789 | 181 | else{ |
mimi3 | 12:dfa39c797789 | 182 | // pc.printf("done!\n\tResult: %d KB/s\n", ( 1024 * 1000000 ) / timer.read_us()); |
mimi3 | 12:dfa39c797789 | 183 | |
mimi3 | 12:dfa39c797789 | 184 | } |
mimi3 | 12:dfa39c797789 | 185 | timer.reset(); |
mimi3 | 12:dfa39c797789 | 186 | } else { |
mimi3 | 12:dfa39c797789 | 187 | pc.printf("failed to open file!\n"); |
mimi3 | 12:dfa39c797789 | 188 | } |
mimi3 | 12:dfa39c797789 | 189 | pc.printf("\n Error Count : %d", errorCount); |
mimi3 | 0:8f297fe0c66a | 190 | } |
mimi3 | 0:8f297fe0c66a | 191 | |
mimi3 | 25:1e42edbeacca | 192 | void warning(){ |
mimi3 | 25:1e42edbeacca | 193 | FileHandle* file = sd.open(FILE_NAME, O_RDONLY); |
mimi3 | 25:1e42edbeacca | 194 | if (file == NULL) { |
mimi3 | 25:1e42edbeacca | 195 | pc.printf("\n***************************************"); |
mimi3 | 25:1e42edbeacca | 196 | pc.printf("\n*** First, you must execute [w] command"); |
mimi3 | 25:1e42edbeacca | 197 | pc.printf("\n*** to generate test file ( %s ).",FILE_NAME); |
mimi3 | 25:1e42edbeacca | 198 | pc.printf("\n***************************************"); |
mimi3 | 25:1e42edbeacca | 199 | } else { |
mimi3 | 25:1e42edbeacca | 200 | file->close(); |
mimi3 | 25:1e42edbeacca | 201 | } |
mimi3 | 25:1e42edbeacca | 202 | } |
mimi3 | 25:1e42edbeacca | 203 | |
mimi3 | 25:1e42edbeacca | 204 | time_t read_rtc(void) { |
mimi3 | 25:1e42edbeacca | 205 | return 0; |
mimi3 | 25:1e42edbeacca | 206 | } |
dinau | 21:6253a88675a5 | 207 | |
mimi3 | 0:8f297fe0c66a | 208 | int main(){ |
dinau | 21:6253a88675a5 | 209 | int i = 1; |
mimi3 | 25:1e42edbeacca | 210 | /* setbuf( stdout, NULL ); */ |
mimi3 | 25:1e42edbeacca | 211 | /* |
mimi3 | 25:1e42edbeacca | 212 | * Refer to https://developer.mbed.org/questions/69644/RTC-error-LSE-clock-initialization-faile/ |
mimi3 | 25:1e42edbeacca | 213 | */ |
mimi3 | 25:1e42edbeacca | 214 | attach_rtc(&read_rtc, NULL, NULL, NULL); |
mimi3 | 25:1e42edbeacca | 215 | /**/ |
mimi3 | 12:dfa39c797789 | 216 | while(1){ |
mimi3 | 25:1e42edbeacca | 217 | pc.printf("\n(%2d) ------ SDFileSystemDMA Test ----------------------------",i++); |
dinau | 24:bea03d091636 | 218 | pc.printf("\nR/W Buffer size = %8d Bytes", sizeof(buffer) ); |
dinau | 24:bea03d091636 | 219 | pc.printf("\nSystemClock = %d Hz",SystemCoreClock); |
mimi3 | 25:1e42edbeacca | 220 | pc.printf("\nSPI(%d), Max SPI Clock = %d Hz (Probably)",SPI_DEV,SystemCoreClock>>1); |
mimi3 | 25:1e42edbeacca | 221 | pc.printf("\nCompiler = %s", TOOLCHAIN); |
mimi3 | 25:1e42edbeacca | 222 | pc.printf("\nmbed-lib = Rev.%d", MBED_LIBRARY_VERSION); |
dinau | 24:bea03d091636 | 223 | pc.printf("\n\nStart SD card accsess test !"); |
mimi3 | 9:289de1b6d378 | 224 | pc.printf("\n[r]: Start Read Test. At least execute [w] onece"); |
mimi3 | 9:289de1b6d378 | 225 | pc.printf("\n[w]: Start Write and Read Test"); |
mimi3 | 12:dfa39c797789 | 226 | pc.printf("\n[v]: Start Read Verify Test. At least execute [w] onece"); |
mimi3 | 25:1e42edbeacca | 227 | pc.printf("\nNote: Writing is very slow, wait tens of seconds."); |
mimi3 | 25:1e42edbeacca | 228 | warning(); |
dinau | 24:bea03d091636 | 229 | pc.printf("\n--- Select [r] or [w] or [v]---\n"); |
mimi3 | 9:289de1b6d378 | 230 | fflush(stdout); |
dinau | 21:6253a88675a5 | 231 | char ch = wait_key_press(); |
mimi3 | 9:289de1b6d378 | 232 | if( ch =='r' ){ |
mimi3 | 9:289de1b6d378 | 233 | readTest(); |
mimi3 | 9:289de1b6d378 | 234 | } else if( ch =='w' ){ |
mimi3 | 12:dfa39c797789 | 235 | writeTest(); |
mimi3 | 12:dfa39c797789 | 236 | readTest(); |
mimi3 | 12:dfa39c797789 | 237 | } else if( ch =='v' ){ |
mimi3 | 12:dfa39c797789 | 238 | verifyTest(); |
mimi3 | 9:289de1b6d378 | 239 | } |
dinau | 21:6253a88675a5 | 240 | else{ |
dinau | 21:6253a88675a5 | 241 | continue; |
dinau | 21:6253a88675a5 | 242 | } |
dinau | 21:6253a88675a5 | 243 | pc.printf("\n--- Press any key ---\n"); |
dinau | 21:6253a88675a5 | 244 | fflush(stdout); |
dinau | 21:6253a88675a5 | 245 | wait_key_press(); |
mimi3 | 12:dfa39c797789 | 246 | } |
mimi3 | 0:8f297fe0c66a | 247 | } |
mimi3 | 5:fef1667b832e | 248 |