Contiki 2.6
|
00001 #include <AT91SAM7S64.h> 00002 #include <interfaces/sd.h> 00003 #include <efs-sdcard.h> 00004 #include <sys/etimer.h> 00005 #include <stdio.h> 00006 00007 #define SPI_SPEED 10000000 /* 10MHz clock*/ 00008 00009 #define SPI_TRANSFER (AT91C_PA12_MISO | AT91C_PA13_MOSI | AT91C_PA14_SPCK) 00010 00011 #define SPI_CS (AT91C_PA11_NPCS0) 00012 00013 static struct process *event_process = NULL; 00014 00015 static void 00016 init_spi() 00017 { 00018 *AT91C_SPI_CR = AT91C_SPI_SPIDIS | AT91C_SPI_SWRST; 00019 *AT91C_PMC_PCER = (1 << AT91C_ID_SPI); 00020 *AT91C_PIOA_ASR = SPI_TRANSFER | SPI_CS; 00021 *AT91C_PIOA_PDR = SPI_TRANSFER | SPI_CS; 00022 *AT91C_PIOA_PPUER = AT91C_PA12_MISO | SPI_CS; 00023 *AT91C_SPI_MR = (AT91C_SPI_MSTR | AT91C_SPI_PS_FIXED 00024 | AT91C_SPI_MODFDIS); 00025 00026 /* It seems necessary to set the clock speed for chip select 0 00027 even if it's not used. */ 00028 00029 AT91C_SPI_CSR[0] = 00030 ((((MCK+SPI_SPEED/2)/SPI_SPEED)<<8) | AT91C_SPI_CPOL 00031 | AT91C_SPI_BITS_8 | AT91C_SPI_CSAAT); 00032 *AT91C_SPI_CR = AT91C_SPI_SPIEN; 00033 00034 } 00035 00036 void 00037 if_spiInit(hwInterface *iface) 00038 { 00039 unsigned int i; 00040 *AT91C_PIOA_SODR = AT91C_PA11_NPCS0; 00041 *AT91C_PIOA_PER = AT91C_PA11_NPCS0; 00042 for(i=0;i<20;i++) { 00043 if_spiSend(iface, 0xff); 00044 } 00045 *AT91C_PIOA_PDR = AT91C_PA11_NPCS0; 00046 } 00047 00048 /* Borrowed from at91_spi.c (c)2006 Martin Thomas */ 00049 00050 esint8 00051 if_initInterface(hwInterface* file, eint8* opts) 00052 { 00053 euint32 sc; 00054 00055 if_spiInit(file); 00056 if(sd_Init(file)<0) { 00057 DBG((TXT("Card failed to init, breaking up...\n"))); 00058 return(-1); 00059 } 00060 00061 if(sd_State(file)<0){ 00062 DBG((TXT("Card didn't return the ready state, breaking up...\n") 00063 )); 00064 return(-2); 00065 } 00066 00067 00068 00069 sd_getDriveSize(file, &sc); 00070 file->sectorCount = sc/512; 00071 if( (sc%512) != 0) { 00072 file->sectorCount--; 00073 } 00074 DBG((TXT("Card Capacity is %lu Bytes (%lu Sectors)\n"), sc, file->sectorCount)); 00075 00076 00077 return(0); 00078 } 00079 00080 /* Borrowed from lpc2000_spi.c (c)2005 Martin Thomas */ 00081 00082 esint8 00083 if_readBuf(hwInterface* file,euint32 address,euint8* buf) 00084 { 00085 return(sd_readSector(file,address,buf,512)); 00086 } 00087 00088 esint8 00089 if_writeBuf(hwInterface* file,euint32 address,euint8* buf) 00090 { 00091 return(sd_writeSector(file,address, buf)); 00092 } 00093 00094 esint8 00095 if_setPos(hwInterface* file,euint32 address) 00096 { 00097 return(0); 00098 } 00099 00100 00101 euint8 00102 if_spiSend(hwInterface *iface, euint8 outgoing) 00103 { 00104 euint8 ingoing; 00105 *AT91C_SPI_TDR = outgoing; 00106 while(!(*AT91C_SPI_SR & AT91C_SPI_RDRF)); 00107 ingoing = *AT91C_SPI_RDR; 00108 /* printf(">%02x <%02x\n", outgoing, ingoing); */ 00109 return ingoing; 00110 } 00111 00112 static EmbeddedFileSystem sdcard_efs; 00113 00114 PROCESS(sdcard_process, "SD card process"); 00115 00116 PROCESS_THREAD(sdcard_process, ev , data) 00117 { 00118 static struct etimer timer; 00119 PROCESS_BEGIN(); 00120 *AT91C_PIOA_PER = AT91C_PIO_PA20 | AT91C_PIO_PA1; 00121 *AT91C_PIOA_ODR = AT91C_PIO_PA20 | AT91C_PIO_PA1; 00122 00123 00124 /* Card not inserted */ 00125 sdcard_efs.myCard.sectorCount = 0; 00126 init_spi(); 00127 00128 while(1) { 00129 if (!(*AT91C_PIOA_PDSR & AT91C_PA20_IRQ0)) { 00130 if (sdcard_efs.myCard.sectorCount == 0) { 00131 if (efs_init(&sdcard_efs,0) == 0) { 00132 if (event_process) { 00133 process_post(event_process, sdcard_inserted_event, NULL); 00134 } 00135 printf("SD card inserted\n"); 00136 } else { 00137 printf("SD card insertion failed\n"); 00138 } 00139 } 00140 } else { 00141 if (sdcard_efs.myCard.sectorCount != 0) { 00142 /* Card removed */ 00143 fs_umount(&sdcard_efs.myFs); 00144 sdcard_efs.myCard.sectorCount = 0; 00145 if (event_process) { 00146 process_post(event_process, sdcard_removed_event, NULL); 00147 } 00148 printf("SD card removed\n"); 00149 } 00150 } 00151 00152 etimer_set(&timer, CLOCK_SECOND); 00153 PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_EXIT || 00154 ev == PROCESS_EVENT_TIMER); 00155 if (ev == PROCESS_EVENT_EXIT) break; 00156 if (!(*AT91C_PIOA_PDSR & AT91C_PA20_IRQ0)) { 00157 /* Wait for card to be preperly inserted */ 00158 etimer_set(&timer,CLOCK_SECOND/2); 00159 PROCESS_WAIT_EVENT_UNTIL(ev== PROCESS_EVENT_TIMER); 00160 } 00161 00162 } 00163 PROCESS_END(); 00164 } 00165 00166 FileSystem * 00167 efs_sdcard_get_fs() 00168 { 00169 efs_sdcard_init(); 00170 return &sdcard_efs.myFs; 00171 } 00172 00173 void 00174 efs_sdcard_init() 00175 { 00176 static int initialized = 0; 00177 if (!initialized) { 00178 sdcard_inserted_event = process_alloc_event(); 00179 sdcard_removed_event = process_alloc_event(); 00180 process_start(&sdcard_process, NULL); 00181 initialized = 1; 00182 } 00183 } 00184 00185 int 00186 sdcard_ready() 00187 { 00188 return sdcard_efs.myCard.sectorCount > 0; 00189 } 00190 00191 void 00192 sdcard_event_process(struct process *p) 00193 { 00194 event_process = p; 00195 }