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@22:5c133291a01d, 2016-09-01 (annotated)
- Committer:
- dinau
- Date:
- Thu Sep 01 17:56:13 2016 +0900
- Revision:
- 22:5c133291a01d
- Parent:
- 21:6253a88675a5
- Child:
- 24:bea03d091636
Modified: Toolchain detect order.
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 | |
dinau | 21:6253a88675a5 | 64 | //char buffer[512*1] __attribute__ ((aligned (4))) ; /* 512 bytes */ |
dinau | 21:6253a88675a5 | 65 | //char buffer[512*2] __attribute__ ((aligned (4))) ; /* 1024 bytes */ |
dinau | 21:6253a88675a5 | 66 | char buffer[512*4] __attribute__ ((aligned (4))) ; /* 2048 bytes */ |
dinau | 21:6253a88675a5 | 67 | //char buffer[512*8] __attribute__ ((aligned (4))) ; /* 4096 bytes */ |
dinau | 21:6253a88675a5 | 68 | //char buffer[512*16] __attribute__ ((aligned (4))) ; /* 8192 bytes */ |
dinau | 21:6253a88675a5 | 69 | //char buffer[512*32] __attribute__ ((aligned (4))) ; /* 16384 bytes */ |
mimi3 | 12:dfa39c797789 | 70 | |
mimi3 | 0:8f297fe0c66a | 71 | #define X_MEGA_BYTE ((1)*1024*1024) /* 1Mbyte */ |
mimi3 | 0:8f297fe0c66a | 72 | #define FILE_NAME "GPATH" |
dinau | 20:e34f5e5f307b | 73 | |
dinau | 22:5c133291a01d | 74 | #if defined(__CC_ARM) /* ARMCC */ |
dinau | 22:5c133291a01d | 75 | #define TOOLCHAIN "ARM/uARM" |
dinau | 22:5c133291a01d | 76 | #elif defined(__GNUC__) /* GCC */ |
dinau | 21:6253a88675a5 | 77 | #define TOOLCHAIN "GCC_ARM" |
dinau | 21:6253a88675a5 | 78 | #elif defined(__ICCARM__) /* IAR */ |
dinau | 21:6253a88675a5 | 79 | #define TOOLCHAIN "IAR" |
dinau | 21:6253a88675a5 | 80 | #warning "This compiler is not yet supported." |
dinau | 21:6253a88675a5 | 81 | #endif |
dinau | 21:6253a88675a5 | 82 | |
dinau | 21:6253a88675a5 | 83 | int wait_key_press(){ |
mimi3 | 3:8b77055a68ec | 84 | #if UART_KEY_PRESS |
mimi3 | 12:dfa39c797789 | 85 | while(!pc.readable()); |
dinau | 21:6253a88675a5 | 86 | return pc.getc(); |
mimi3 | 3:8b77055a68ec | 87 | #endif |
mimi3 | 0:8f297fe0c66a | 88 | } |
mimi3 | 0:8f297fe0c66a | 89 | |
mimi3 | 0:8f297fe0c66a | 90 | void writeTest() |
mimi3 | 0:8f297fe0c66a | 91 | { |
dinau | 20:e34f5e5f307b | 92 | #if !_FS_READONLY |
mimi3 | 12:dfa39c797789 | 93 | //Test write performance by creating a 1MB file |
dinau | 21:6253a88675a5 | 94 | pc.printf("[Write]: Testing %d bytes buffer: write performance...", sizeof(buffer)); |
mimi3 | 12:dfa39c797789 | 95 | fflush(stdout); |
mimi3 | 12:dfa39c797789 | 96 | for(uint32_t k = 0; k < sizeof(buffer); k++){ |
mimi3 | 12:dfa39c797789 | 97 | buffer[k] = k & 0xff; |
mimi3 | 12:dfa39c797789 | 98 | } |
mimi3 | 12:dfa39c797789 | 99 | |
mimi3 | 12:dfa39c797789 | 100 | FileHandle* file = sd.open(FILE_NAME, O_WRONLY | O_CREAT | O_TRUNC); |
mimi3 | 12:dfa39c797789 | 101 | if (file != NULL) { |
mimi3 | 12:dfa39c797789 | 102 | timer.start(); |
mimi3 | 12:dfa39c797789 | 103 | for (uint32_t i = 0; i < (X_MEGA_BYTE / sizeof(buffer)); i++) { |
mimi3 | 12:dfa39c797789 | 104 | if (file->write(buffer, sizeof(buffer)) != sizeof(buffer)) { |
mimi3 | 12:dfa39c797789 | 105 | timer.stop(); |
mimi3 | 12:dfa39c797789 | 106 | pc.printf("write error!\n"); |
mimi3 | 12:dfa39c797789 | 107 | timer.reset(); |
mimi3 | 12:dfa39c797789 | 108 | return; |
mimi3 | 12:dfa39c797789 | 109 | } |
mimi3 | 12:dfa39c797789 | 110 | } |
mimi3 | 12:dfa39c797789 | 111 | timer.stop(); |
mimi3 | 12:dfa39c797789 | 112 | if (file->close()) |
mimi3 | 12:dfa39c797789 | 113 | pc.printf("failed to close file!\n"); |
mimi3 | 12:dfa39c797789 | 114 | else{ |
mimi3 | 12:dfa39c797789 | 115 | pc.printf("done!\n\tResult: %d KB/s\n", ( 1024 * 1000000 ) / timer.read_us() ); |
mimi3 | 12:dfa39c797789 | 116 | } |
mimi3 | 12:dfa39c797789 | 117 | timer.reset(); |
mimi3 | 12:dfa39c797789 | 118 | } else { |
mimi3 | 12:dfa39c797789 | 119 | pc.printf("failed to create file!\n"); |
mimi3 | 12:dfa39c797789 | 120 | } |
dinau | 20:e34f5e5f307b | 121 | #endif |
mimi3 | 0:8f297fe0c66a | 122 | } |
mimi3 | 0:8f297fe0c66a | 123 | |
mimi3 | 0:8f297fe0c66a | 124 | void readTest() |
mimi3 | 0:8f297fe0c66a | 125 | { |
mimi3 | 12:dfa39c797789 | 126 | //Test read performance by reading the 1MB file created by writeTest() |
dinau | 21:6253a88675a5 | 127 | pc.printf("[Read]: Testing %d bytes buffer: read performance...", sizeof(buffer)); |
mimi3 | 12:dfa39c797789 | 128 | fflush(stdout); |
mimi3 | 12:dfa39c797789 | 129 | FileHandle* file = sd.open(FILE_NAME, O_RDONLY); |
mimi3 | 12:dfa39c797789 | 130 | if (file != NULL) { |
mimi3 | 12:dfa39c797789 | 131 | timer.start(); |
mimi3 | 12:dfa39c797789 | 132 | int iterations = 0; |
mimi3 | 12:dfa39c797789 | 133 | while (file->read(buffer, sizeof(buffer)) == sizeof(buffer)){ |
mimi3 | 12:dfa39c797789 | 134 | iterations++; |
mimi3 | 12:dfa39c797789 | 135 | } |
mimi3 | 12:dfa39c797789 | 136 | timer.stop(); |
mimi3 | 12:dfa39c797789 | 137 | if (iterations != (X_MEGA_BYTE / sizeof(buffer))){ |
mimi3 | 12:dfa39c797789 | 138 | pc.printf("read error!\n"); |
mimi3 | 12:dfa39c797789 | 139 | } |
mimi3 | 12:dfa39c797789 | 140 | else if (file->close()){ |
mimi3 | 12:dfa39c797789 | 141 | pc.printf("failed to close file!\n"); |
mimi3 | 12:dfa39c797789 | 142 | } |
mimi3 | 12:dfa39c797789 | 143 | else{ |
mimi3 | 12:dfa39c797789 | 144 | pc.printf("done!\n\tResult: %d KB/s\n", ( 1024 * 1000000 ) / timer.read_us()); |
mimi3 | 12:dfa39c797789 | 145 | } |
mimi3 | 12:dfa39c797789 | 146 | timer.reset(); |
mimi3 | 12:dfa39c797789 | 147 | } else { |
mimi3 | 12:dfa39c797789 | 148 | pc.printf("failed to open file!\n"); |
mimi3 | 12:dfa39c797789 | 149 | } |
mimi3 | 12:dfa39c797789 | 150 | } |
mimi3 | 12:dfa39c797789 | 151 | |
mimi3 | 12:dfa39c797789 | 152 | void verifyTest() |
mimi3 | 12:dfa39c797789 | 153 | { |
mimi3 | 12:dfa39c797789 | 154 | int errorCount = 0; |
mimi3 | 12:dfa39c797789 | 155 | //Test read performance by reading the 1MB file created by writeTest() |
dinau | 21:6253a88675a5 | 156 | pc.printf("[Read]: Verifying %d bytes buffer ...", sizeof(buffer)); |
mimi3 | 12:dfa39c797789 | 157 | fflush(stdout); |
mimi3 | 12:dfa39c797789 | 158 | FileHandle* file = sd.open(FILE_NAME, O_RDONLY); |
mimi3 | 12:dfa39c797789 | 159 | if (file != NULL) { |
mimi3 | 12:dfa39c797789 | 160 | timer.start(); |
mimi3 | 12:dfa39c797789 | 161 | int iterations = 0; |
mimi3 | 12:dfa39c797789 | 162 | while (file->read(buffer, sizeof(buffer)) == sizeof(buffer)){ |
mimi3 | 12:dfa39c797789 | 163 | iterations++; |
mimi3 | 12:dfa39c797789 | 164 | for(uint32_t k = 0; k < sizeof(buffer); k++){ |
mimi3 | 12:dfa39c797789 | 165 | if ( buffer[k] != (k & 0xff) ){ |
mimi3 | 12:dfa39c797789 | 166 | errorCount++; |
mimi3 | 12:dfa39c797789 | 167 | } |
mimi3 | 12:dfa39c797789 | 168 | } |
mimi3 | 12:dfa39c797789 | 169 | } |
mimi3 | 12:dfa39c797789 | 170 | timer.stop(); |
mimi3 | 12:dfa39c797789 | 171 | if (iterations != (X_MEGA_BYTE / sizeof(buffer))){ |
mimi3 | 12:dfa39c797789 | 172 | pc.printf("read error!\n"); |
mimi3 | 12:dfa39c797789 | 173 | } |
mimi3 | 12:dfa39c797789 | 174 | else if (file->close()){ |
mimi3 | 12:dfa39c797789 | 175 | pc.printf("failed to close file!\n"); |
mimi3 | 12:dfa39c797789 | 176 | } |
mimi3 | 12:dfa39c797789 | 177 | else{ |
mimi3 | 12:dfa39c797789 | 178 | // pc.printf("done!\n\tResult: %d KB/s\n", ( 1024 * 1000000 ) / timer.read_us()); |
mimi3 | 12:dfa39c797789 | 179 | |
mimi3 | 12:dfa39c797789 | 180 | } |
mimi3 | 12:dfa39c797789 | 181 | timer.reset(); |
mimi3 | 12:dfa39c797789 | 182 | } else { |
mimi3 | 12:dfa39c797789 | 183 | pc.printf("failed to open file!\n"); |
mimi3 | 12:dfa39c797789 | 184 | } |
mimi3 | 12:dfa39c797789 | 185 | pc.printf("\n Error Count : %d", errorCount); |
mimi3 | 0:8f297fe0c66a | 186 | } |
mimi3 | 0:8f297fe0c66a | 187 | |
dinau | 21:6253a88675a5 | 188 | |
mimi3 | 0:8f297fe0c66a | 189 | int main(){ |
dinau | 21:6253a88675a5 | 190 | int i = 1; |
mimi3 | 12:dfa39c797789 | 191 | while(1){ |
dinau | 21:6253a88675a5 | 192 | pc.printf("\n(%2d)------- SDFileSystemDMA --------------------------------",i++); |
dinau | 21:6253a88675a5 | 193 | pc.printf("\nR/W Buffer size: %5d bytes", sizeof(buffer) ); |
dinau | 21:6253a88675a5 | 194 | pc.printf("\nCompiler: %s, mbed lib Rev.%d", TOOLCHAIN, MBED_LIBRARY_VERSION); |
mimi3 | 11:d5fc11ac948a | 195 | pc.printf("\nSPI(%d), SysClock= %d Hz",SPI_DEV, SystemCoreClock); |
dinau | 21:6253a88675a5 | 196 | pc.printf("\n\nStart SD card accsess test!"); |
mimi3 | 9:289de1b6d378 | 197 | pc.printf("\n[r]: Start Read Test. At least execute [w] onece"); |
mimi3 | 9:289de1b6d378 | 198 | pc.printf("\n[w]: Start Write and Read Test"); |
mimi3 | 12:dfa39c797789 | 199 | pc.printf("\n[v]: Start Read Verify Test. At least execute [w] onece"); |
mimi3 | 12:dfa39c797789 | 200 | pc.printf("\nWriting is very slow, wait tens of seconds."); |
dinau | 21:6253a88675a5 | 201 | pc.printf("\n--- Select [r] or [w] ---\n"); |
mimi3 | 9:289de1b6d378 | 202 | fflush(stdout); |
dinau | 21:6253a88675a5 | 203 | char ch = wait_key_press(); |
mimi3 | 9:289de1b6d378 | 204 | if( ch =='r' ){ |
mimi3 | 9:289de1b6d378 | 205 | readTest(); |
mimi3 | 9:289de1b6d378 | 206 | } else if( ch =='w' ){ |
mimi3 | 12:dfa39c797789 | 207 | writeTest(); |
mimi3 | 12:dfa39c797789 | 208 | readTest(); |
mimi3 | 12:dfa39c797789 | 209 | } else if( ch =='v' ){ |
mimi3 | 12:dfa39c797789 | 210 | verifyTest(); |
mimi3 | 9:289de1b6d378 | 211 | } |
dinau | 21:6253a88675a5 | 212 | else{ |
dinau | 21:6253a88675a5 | 213 | continue; |
dinau | 21:6253a88675a5 | 214 | } |
dinau | 21:6253a88675a5 | 215 | pc.printf("\n--- Press any key ---\n"); |
dinau | 21:6253a88675a5 | 216 | fflush(stdout); |
dinau | 21:6253a88675a5 | 217 | wait_key_press(); |
mimi3 | 12:dfa39c797789 | 218 | } |
mimi3 | 0:8f297fe0c66a | 219 | } |
mimi3 | 5:fef1667b832e | 220 |