Contiki 2.6
|
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) /* fPCLK / 32 */ 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 /* Borrowed from at91_spi.c (c)2006 Martin Thomas */ 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 /* Borrowed from lpc2000_spi.c (c)2005 Martin Thomas */ 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 /* printf(">%02x <%02x\n", outgoing, ingoing); */ 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 /* TODO take whence int account */ 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 /* Cause a compile time error if expr is false */ 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 /* Mark all file descriptors as free */ 00297 for (fd = 0; fd < MAX_FDS; fd++) { 00298 file_setAttr(&file_descriptors[fd], FILE_STATUS_OPEN,0); 00299 } 00300 /* Card not inserted */ 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 /* Card removed */ 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 }