Mercurial > ~darius > hgwebdir.cgi > stm32temp
comparison fatfs_sd.c @ 50:d7207a9d3c3b
Add write support. LFN still broken though.
Make sure we wait for the card to be done after a read or write (didn't seem to break reading but hosed writes).
author | Daniel O'Connor <darius@dons.net.au> |
---|---|
date | Fri, 05 Apr 2013 00:08:31 +1030 |
parents | ace431a0d0f5 |
children | 590886732da9 |
comparison
equal
deleted
inserted
replaced
49:ace431a0d0f5 | 50:d7207a9d3c3b |
---|---|
30 #include <inttypes.h> | 30 #include <inttypes.h> |
31 #include <stdio.h> | 31 #include <stdio.h> |
32 #include <stdint.h> | 32 #include <stdint.h> |
33 #include <stdlib.h> | 33 #include <stdlib.h> |
34 #include <string.h> | 34 #include <string.h> |
35 | 35 #include <time.h> |
36 | |
37 #include "delay.h" | |
36 #include "stm32f10x.h" | 38 #include "stm32f10x.h" |
37 #include "stm32_eval_sdio_sd.h" | 39 #include "stm32_eval_sdio_sd.h" |
38 #include "diskio.h" | 40 #include "diskio.h" |
39 | 41 |
42 #if 0 | |
43 #define DEBUG(fmt, ...) printf("%s: " fmt, __FUNCTION__, ## __VA_ARGS__) | |
44 #else | |
45 #define DEBUG(...) | |
46 #endif | |
47 | |
48 char *sderr2str(SD_Error err); | |
49 void dump_buf(uint8_t *buf, uint32_t size); | |
50 | |
51 static SD_CardInfo cardinfo; | |
52 | |
40 DSTATUS | 53 DSTATUS |
41 disk_initialize(BYTE pdrv) { | 54 disk_initialize(BYTE pdrv) { |
42 SD_Error err; | 55 SD_Error err; |
43 | 56 |
57 DEBUG("disk_initialize(%d)\n", pdrv); | |
58 | |
44 /* Only have 1 disk */ | 59 /* Only have 1 disk */ |
45 if (pdrv != 0) | 60 if (pdrv != 0) |
46 return STA_NOINIT; | 61 return STA_NOINIT; |
47 | 62 |
48 if ((err = SD_Init()) != SD_OK) { | 63 if ((err = SD_Init()) != SD_OK) { |
49 printf("Failed init: %d\r\n", err); | 64 printf("Failed init: %s\n", sderr2str(err)); |
65 return STA_NOINIT; | |
66 } | |
67 if ((err = SD_GetCardInfo(&cardinfo)) != SD_OK) { | |
68 printf("Get card info failed: %s\n", sderr2str(err)); | |
50 return STA_NOINIT; | 69 return STA_NOINIT; |
51 } | 70 } |
52 | 71 |
53 return 0; | 72 return 0; |
54 } | 73 } |
55 | 74 |
56 DSTATUS | 75 DSTATUS |
57 disk_status(BYTE pdrv) { | 76 disk_status(BYTE pdrv) { |
77 DEBUG("disk_status(%d)\n", pdrv); | |
78 | |
58 if (pdrv != 0) | 79 if (pdrv != 0) |
59 return STA_NOINIT; | 80 return STA_NOINIT; |
60 | 81 |
61 return 0; | 82 return 0; |
62 } | 83 } |
63 | 84 |
64 DRESULT | 85 DRESULT |
65 disk_read(BYTE pdrv, BYTE *buff, DWORD sector, BYTE count) { | 86 disk_read(BYTE pdrv, BYTE *buff, DWORD sector, BYTE count) { |
66 SD_Error err; | 87 SD_Error err; |
67 | 88 |
89 DEBUG("disk_read(%d, 0x%08x, %d, %d)\n", pdrv, buff, sector, count); | |
90 | |
68 if (pdrv != 0) | 91 if (pdrv != 0) |
69 return STA_NOINIT; | 92 return STA_NOINIT; |
70 | 93 |
71 if (count == 1) | 94 if (count == 1) |
72 err = SD_ReadBlock(buff, sector * SD_BLOCK_SIZE, SD_BLOCK_SIZE); | 95 err = SD_ReadBlock(buff, sector * SD_BLOCK_SIZE, SD_BLOCK_SIZE); |
73 else | 96 else |
74 err = SD_ReadMultiBlocks(buff, sector * SD_BLOCK_SIZE, SD_BLOCK_SIZE, count); | 97 err = SD_ReadMultiBlocks(buff, sector * SD_BLOCK_SIZE, SD_BLOCK_SIZE, count); |
75 | 98 |
99 #ifdef SD_DMA_MODE | |
100 if ((err = SD_WaitReadOperation()) != SD_OK) { | |
101 printf("Wait returned %s\n", sderr2str(err)); | |
102 goto read_exit; | |
103 } | |
104 #endif | |
76 if (err != SD_OK) { | 105 if (err != SD_OK) { |
77 printf("Read failed: %d\r\n", err); | 106 printf("Read failed: %s\n", sderr2str(err)); |
78 return STA_NOINIT; | 107 return STA_NOINIT; |
79 } | 108 } |
80 | 109 |
110 while(SD_GetStatus() != SD_TRANSFER_OK) | |
111 ; | |
112 | |
81 return RES_OK; | 113 return RES_OK; |
82 } | 114 } |
83 | 115 |
84 DRESULT | 116 DRESULT |
85 disk_write(BYTE pdrv, const BYTE *buff, DWORD sector, BYTE count) { | 117 disk_write(BYTE pdrv, const BYTE *buff, DWORD sector, BYTE count) { |
86 if (pdrv != 0) | 118 SD_Error err; |
87 return STA_NOINIT; | 119 |
88 | 120 DEBUG("disk_write(%d, 0x%08x, %d, %d)\n", pdrv, buff, sector, count); |
89 return RES_WRPRT; | 121 if (pdrv != 0) |
122 return RES_NOTRDY; | |
123 | |
124 if (count == 1) | |
125 err = SD_WriteBlock(buff, sector * SD_BLOCK_SIZE, SD_BLOCK_SIZE); | |
126 else | |
127 err = SD_WriteMultiBlocks(buff, sector * SD_BLOCK_SIZE, SD_BLOCK_SIZE, count); | |
128 | |
129 #ifdef SD_DMA_MODE | |
130 if ((err = SD_WaitReadOperation()) != SD_OK) { | |
131 printf("Wait returned %s\n", sderr2str(err)); | |
132 goto read_exit; | |
133 } | |
134 #endif | |
135 if (err != SD_OK) { | |
136 printf("Write failed: %s\n", sderr2str(err)); | |
137 return RES_ERROR; | |
138 } | |
139 | |
140 while(SD_GetStatus() != SD_TRANSFER_OK) | |
141 ; | |
142 | |
143 return RES_OK; | |
90 } | 144 } |
91 | 145 |
92 DRESULT | 146 DRESULT |
93 disk_ioctl(BYTE pdrv, BYTE cmd, void *buff) { | 147 disk_ioctl(BYTE pdrv, BYTE cmd, void *buff) { |
94 WORD *wd; | 148 WORD *wd; |
95 DWORD *dwd; | 149 DWORD *dwd; |
96 SD_CardInfo cardinfo; | 150 SD_Error err; |
97 SD_Error err; | 151 |
152 DEBUG("disk_ioctl(%d, %d, ...)\n", pdrv, cmd); | |
98 | 153 |
99 wd = buff; | 154 wd = buff; |
100 dwd = buff; | 155 dwd = buff; |
101 | 156 |
102 if (pdrv != 0) | 157 if (pdrv != 0) |
103 return STA_NOINIT; | 158 return STA_NOINIT; |
104 switch (cmd) { | 159 switch (cmd) { |
105 case CTRL_SYNC: | 160 case CTRL_SYNC: |
106 printf("Sync\r\n"); | 161 DEBUG("Sync\n"); |
107 break; | 162 break; |
108 | 163 |
109 case GET_SECTOR_SIZE: | 164 case GET_SECTOR_SIZE: |
110 printf("Get sector size\r\n"); | |
111 *wd = SD_BLOCK_SIZE; | 165 *wd = SD_BLOCK_SIZE; |
166 DEBUG("Get sector size (%d)\n", *wd); | |
112 break; | 167 break; |
113 | 168 |
114 case GET_SECTOR_COUNT: | 169 case GET_SECTOR_COUNT: |
115 printf("Get sector count\r\n"); | |
116 | |
117 if ((err = SD_GetCardInfo(&cardinfo)) != SD_OK) { | |
118 printf("Get card info failed: %d\r\b", err); | |
119 return RES_ERROR; | |
120 } | |
121 *dwd = cardinfo.CardCapacity / SD_BLOCK_SIZE; | 170 *dwd = cardinfo.CardCapacity / SD_BLOCK_SIZE; |
171 DEBUG("Get sector count (%d)\n", *dwd); | |
122 break; | 172 break; |
123 | 173 |
124 case GET_BLOCK_SIZE: | 174 case GET_BLOCK_SIZE: |
125 printf("Get block size\r\n"); | |
126 | |
127 if ((err = SD_GetCardInfo(&cardinfo)) != SD_OK) { | |
128 printf("Get card info failed: %d\r\b", err); | |
129 return RES_ERROR; | |
130 } | |
131 | |
132 /* FatFS wants log2(blocksize) */ | 175 /* FatFS wants log2(blocksize) */ |
133 *dwd = 0; | 176 *dwd = 0; |
134 while (cardinfo.CardBlockSize > 0) { | 177 while (cardinfo.CardBlockSize > 0) { |
135 *dwd++; | 178 *dwd = *dwd + 1; |
136 cardinfo.CardBlockSize >>= 1; | 179 cardinfo.CardBlockSize >>= 1; |
137 } | 180 } |
181 DEBUG("Get block size (%d)\n", *dwd); | |
138 break; | 182 break; |
139 | 183 |
140 case CTRL_ERASE_SECTOR: | 184 case CTRL_ERASE_SECTOR: |
141 return RES_ERROR; | 185 return RES_ERROR; |
142 } | 186 } |
153 bit 10: 5 Minute (0..59) | 197 bit 10: 5 Minute (0..59) |
154 bit 4: 0 Second / 2 (0..29) | 198 bit 4: 0 Second / 2 (0..29) |
155 */ | 199 */ |
156 DWORD | 200 DWORD |
157 get_fattime(void) { | 201 get_fattime(void) { |
158 return 0; | 202 struct tm now; |
203 time_t t; | |
204 DWORD res; | |
205 | |
206 t = time(NULL); | |
207 localtime_r(&t, &now); | |
208 res = ((now.tm_year - 80) << 25 | | |
209 ((now.tm_mon + 1) << 21) | | |
210 (now.tm_mday << 16) | | |
211 (now.tm_hour << 11) | | |
212 (now.tm_min << 5) | | |
213 (now.tm_sec >> 1)); | |
214 | |
215 return res; | |
159 } | 216 } |
160 | 217 |
161 void * | 218 void * |
162 ff_memalloc(UINT msize) { | 219 ff_memalloc(UINT msize) { |
163 return malloc(msize); | 220 return malloc(msize); |