00001 #include <stm32f10x_map.h>
00002 #include <sdcard.h>
00003 #include <sys/process.h>
00004 #include <sys/etimer.h>
00005 #include <cfs/cfs.h>
00006 #include <efs.h>
00007 #include <ls.h>
00008 #include <interfaces/sd.h>
00009 #include <gpio.h>
00010 #include <stdio.h>
00011
00012 process_event_t sdcard_inserted_event;
00013
00014 process_event_t sdcard_removed_event;
00015
00016 static struct process *event_process = NULL;
00017
00018 #if 0
00019 #undef TXT
00020 #define TXT(x) x
00021 #undef DBG
00022 #define DBG(x) printf x
00023 #endif
00024
00025 static void
00026 init_spi()
00027 {
00028 SPI1->CR1 &= ~SPI_CR1_SPE;
00029 RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
00030 GPIO_CONF_INPUT_PORT(A,0,FLOATING);
00031 GPIO_CONF_INPUT_PORT(A,1,FLOATING);
00032 GPIO_CONF_OUTPUT_PORT(A,4,PUSH_PULL,50);
00033 GPIOA->BSRR = GPIO_BSRR_BS4;
00034 GPIO_CONF_OUTPUT_PORT(A,5,ALT_PUSH_PULL,50);
00035 GPIO_CONF_INPUT_PORT(A,6,FLOATING);
00036 GPIO_CONF_OUTPUT_PORT(A,7,ALT_PUSH_PULL,50);
00037 RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
00038 SPI1->CR2 = SPI_CR2_SSOE;
00039 SPI1->CR1 = (SPI_CR1_SPE
00040 | (SPI_CR1_BR_2)
00041 | SPI_CR1_MSTR
00042 | SPI_CR1_CPOL | SPI_CR1_CPHA
00043 | SPI_CR1_SSM | SPI_CR1_SSI);
00044
00045 }
00046
00047 void
00048 if_spiInit(hwInterface *iface)
00049 {
00050 unsigned int i;
00051 GPIOA->BSRR = GPIO_BSRR_BS4;
00052 for(i=0;i<20;i++) {
00053 if_spiSend(iface, 0xff);
00054 }
00055 GPIOA->BSRR = GPIO_BSRR_BR4;
00056 }
00057
00058
00059 esint8
00060 if_initInterface(hwInterface* file, eint8* opts)
00061 {
00062 euint32 sc;
00063 if_spiInit(file);
00064 if(sd_Init(file)<0) {
00065 DBG((TXT("Card failed to init, breaking up...\n")));
00066 return(-1);
00067 }
00068
00069 if(sd_State(file)<0){
00070 DBG((TXT("Card didn't return the ready state, breaking up...\n")
00071 ));
00072 return(-2);
00073 }
00074
00075
00076
00077 sd_getDriveSize(file, &sc);
00078 file->sectorCount = sc/512;
00079 DBG((TXT("Card Capacity is %lu Bytes (%lu Sectors)\n"), sc, file->sectorCount));
00080
00081
00082 return(0);
00083 }
00084
00085
00086
00087 esint8
00088 if_readBuf(hwInterface* file,euint32 address,euint8* buf)
00089 {
00090 return(sd_readSector(file,address,buf,512));
00091 }
00092
00093 esint8
00094 if_writeBuf(hwInterface* file,euint32 address,euint8* buf)
00095 {
00096 return(sd_writeSector(file,address, buf));
00097 }
00098
00099 esint8
00100 if_setPos(hwInterface* file,euint32 address)
00101 {
00102 return(0);
00103 }
00104
00105
00106 euint8
00107 if_spiSend(hwInterface *iface, euint8 outgoing)
00108 {
00109 euint8 ingoing;
00110 SPI1->DR = outgoing;
00111 while(!(SPI1->SR & SPI_SR_RXNE));
00112 ingoing = SPI1->DR;
00113
00114 return ingoing;
00115 }
00116
00117 #define MAX_FDS 4
00118
00119 static EmbeddedFileSystem sdcard_efs;
00120 static File file_descriptors[MAX_FDS];
00121
00122 static int
00123 find_free_fd()
00124 {
00125 int fd;
00126 for (fd = 0; fd < MAX_FDS; fd++) {
00127 if (!file_getAttr(&file_descriptors[fd], FILE_STATUS_OPEN)) {
00128 return fd;
00129 }
00130 }
00131 return -1;
00132 }
00133
00134 static File *
00135 get_file(int fd)
00136 {
00137 if (sdcard_efs.myCard.sectorCount == 0) return NULL;
00138 if (fd >= MAX_FDS || fd < 0) return NULL;
00139 if (!file_getAttr(&file_descriptors[fd], FILE_STATUS_OPEN)) return NULL;
00140 return &file_descriptors[fd];
00141 }
00142
00143 int
00144 cfs_open (const char *name, int flags)
00145 {
00146 eint8 mode;
00147 int fd;
00148 if (sdcard_efs.myCard.sectorCount == 0) return -1;
00149 fd = find_free_fd();
00150 if (fd < 0) return -1;
00151 if (flags == CFS_READ) {
00152 mode = MODE_READ;
00153 } else {
00154 mode = MODE_APPEND;
00155 }
00156 if (file_fopen(&file_descriptors[fd], &sdcard_efs.myFs,
00157 (char*)name, mode) < 0) {
00158 return -1;
00159 }
00160 return fd;
00161 }
00162
00163 void
00164 cfs_close(int fd)
00165 {
00166 File *file = get_file(fd);
00167 if (!file) return;
00168 file_fclose(file);
00169 fs_flushFs(&sdcard_efs.myFs);
00170 }
00171
00172 int
00173 cfs_read (int fd, void *buf, unsigned int len)
00174 {
00175 File *file = get_file(fd);
00176 if (!file) return 0;
00177 return file_read(file, len, (euint8*)buf);
00178 }
00179
00180 int
00181 cfs_write (int fd, const void *buf, unsigned int len)
00182 {
00183 File *file = get_file(fd);
00184 if (!file) return 0;
00185 return file_write(file, len, (euint8*)buf);
00186 }
00187
00188 cfs_offset_t
00189 cfs_seek (int fd, cfs_offset_t offset, int whence)
00190 {
00191 File *file = get_file(fd);
00192 if (!file) return 0;
00193
00194 if (file_setpos(file, offset) != 0) return -1;
00195 return file->FilePtr;
00196 }
00197
00198 int
00199 cfs_remove(const char *name)
00200 {
00201 return (rmfile(&sdcard_efs.myFs,(euint8*)name) == 0) ? 0 : -1;
00202 }
00203
00204
00205 #ifdef __GNUC__
00206 #define COMPILE_TIME_CHECK(expr) \
00207 (void) (__builtin_choose_expr ((expr), 0, ((void)0))+3)
00208 #else
00209 #define COMPILE_TIME_CHECK(expr)
00210 #endif
00211
00212 #define MAX_DIR_LISTS 4
00213 DirList dir_lists[MAX_DIR_LISTS];
00214
00215 static DirList *
00216 find_free_dir_list()
00217 {
00218 unsigned int l;
00219 for(l = 0; l < MAX_DIR_LISTS; l++) {
00220 if (dir_lists[l].fs == NULL) {
00221 return &dir_lists[l];
00222 }
00223 }
00224 return NULL;
00225 }
00226
00227 int
00228 cfs_opendir (struct cfs_dir *dirp, const char *name)
00229 {
00230 DirList *dirs;
00231 COMPILE_TIME_CHECK(sizeof(DirList*) <= sizeof(struct cfs_dir));
00232 if (sdcard_efs.myCard.sectorCount == 0) return -1;
00233 dirs = find_free_dir_list();
00234 if (!dirs) return -1;
00235 if (ls_openDir(dirs, &sdcard_efs.myFs, (eint8*)name) != 0) {
00236 dirs->fs = NULL;
00237 return -1;
00238 }
00239 *(DirList**)dirp = dirs;
00240 return 0;
00241 }
00242
00243 int
00244 cfs_readdir (struct cfs_dir *dirp, struct cfs_dirent *dirent)
00245 {
00246 euint8 *start;
00247 euint8 *end;
00248 char *to = dirent->name;
00249 DirList *dirs = *(DirList**)dirp;
00250 if (sdcard_efs.myCard.sectorCount == 0) return 1;
00251 if (ls_getNext(dirs) != 0) return 1;
00252 start = dirs->currentEntry.FileName;
00253 end = start + 7;
00254 while(end > start) {
00255 if (*end > ' ') {
00256 end++;
00257 break;
00258 }
00259 end--;
00260 }
00261 while(start < end) {
00262 *to++ = *start++;
00263 }
00264 start = dirs->currentEntry.FileName + 8;
00265 end = start + 3;
00266 if (*start > ' ') {
00267 *to++ = '.';
00268 *to++ = *start++;
00269 while(start < end && *start > ' ') {
00270 *to++ = *start++;
00271 }
00272 }
00273 *to = '\0';
00274 if (dirs->currentEntry.Attribute & ATTR_DIRECTORY) {
00275 dirent->size = 0;
00276 } else {
00277 dirent->size = dirs->currentEntry.FileSize;
00278 }
00279 return 0;
00280 }
00281
00282 void
00283 cfs_closedir (struct cfs_dir *dirp)
00284 {
00285 (*(DirList**)dirp)->fs = NULL;
00286 }
00287
00288
00289 PROCESS(sdcard_process, "SD card process");
00290
00291 PROCESS_THREAD(sdcard_process, ev , data)
00292 {
00293 int fd;
00294 static struct etimer timer;
00295 PROCESS_BEGIN();
00296
00297 for (fd = 0; fd < MAX_FDS; fd++) {
00298 file_setAttr(&file_descriptors[fd], FILE_STATUS_OPEN,0);
00299 }
00300
00301 sdcard_efs.myCard.sectorCount = 0;
00302 init_spi();
00303
00304 etimer_set(&timer, CLOCK_SECOND);
00305 while(1) {
00306 PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_EXIT ||
00307 ev== PROCESS_EVENT_TIMER || ev == PROCESS_EVENT_POLL);
00308 if (ev == PROCESS_EVENT_EXIT) break;
00309 if (ev == PROCESS_EVENT_TIMER) {
00310 if (!(GPIOA->IDR & (1<<0))) {
00311 if (sdcard_efs.myCard.sectorCount == 0) {
00312 etimer_set(&timer,CLOCK_SECOND/2);
00313 PROCESS_WAIT_EVENT_UNTIL(ev== PROCESS_EVENT_TIMER);
00314 if (efs_init(&sdcard_efs,0) == 0) {
00315 if (event_process) {
00316 process_post(event_process, sdcard_inserted_event, NULL);
00317 }
00318 printf("SD card inserted\n");
00319 } else {
00320 printf("SD card insertion failed\n");
00321 }
00322 }
00323 } else {
00324 if (sdcard_efs.myCard.sectorCount != 0) {
00325
00326 fs_umount(&sdcard_efs.myFs);
00327 sdcard_efs.myCard.sectorCount = 0;
00328 if (event_process) {
00329 process_post(event_process, sdcard_removed_event, NULL);
00330 }
00331 printf("SD card removed\n");
00332 }
00333 }
00334 etimer_set(&timer, CLOCK_SECOND);
00335
00336 }
00337 }
00338 PROCESS_END();
00339 }
00340
00341 void
00342 sdcard_init()
00343 {
00344 sdcard_inserted_event = process_alloc_event();
00345 sdcard_removed_event = process_alloc_event();
00346 process_start(&sdcard_process, NULL);
00347 }
00348
00349 int
00350 sdcard_ready()
00351 {
00352 return sdcard_efs.myCard.sectorCount > 0;
00353 }
00354
00355 void
00356 sdcard_event_process(struct process *p)
00357 {
00358 event_process = p;
00359 }