Contiki 2.6

sdcard-arch.c

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 }