Contiki 2.5
sdcard-arch.c
1 #include <stm32f10x_map.h>
2 #include <sdcard.h>
3 #include <sys/process.h>
4 #include <sys/etimer.h>
5 #include <cfs/cfs.h>
6 #include <efs.h>
7 #include <ls.h>
8 #include <interfaces/sd.h>
9 #include <gpio.h>
10 #include <stdio.h>
11 
12 process_event_t sdcard_inserted_event;
13 
14 process_event_t sdcard_removed_event;
15 
16 static struct process *event_process = NULL;
17 
18 #if 0
19 #undef TXT
20 #define TXT(x) x
21 #undef DBG
22 #define DBG(x) printf x
23 #endif
24 
25 static void
26 init_spi()
27 {
28  SPI1->CR1 &= ~SPI_CR1_SPE;
29  RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
30  GPIO_CONF_INPUT_PORT(A,0,FLOATING);
31  GPIO_CONF_INPUT_PORT(A,1,FLOATING);
32  GPIO_CONF_OUTPUT_PORT(A,4,PUSH_PULL,50);
33  GPIOA->BSRR = GPIO_BSRR_BS4;
34  GPIO_CONF_OUTPUT_PORT(A,5,ALT_PUSH_PULL,50);
35  GPIO_CONF_INPUT_PORT(A,6,FLOATING);
36  GPIO_CONF_OUTPUT_PORT(A,7,ALT_PUSH_PULL,50);
37  RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
38  SPI1->CR2 = SPI_CR2_SSOE;
39  SPI1->CR1 = (SPI_CR1_SPE
40  | (SPI_CR1_BR_2) /* fPCLK / 32 */
41  | SPI_CR1_MSTR
42  | SPI_CR1_CPOL | SPI_CR1_CPHA
43  | SPI_CR1_SSM | SPI_CR1_SSI);
44 
45 }
46 
47 void
48 if_spiInit(hwInterface *iface)
49 {
50  unsigned int i;
51  GPIOA->BSRR = GPIO_BSRR_BS4;
52  for(i=0;i<20;i++) {
53  if_spiSend(iface, 0xff);
54  }
55  GPIOA->BSRR = GPIO_BSRR_BR4;
56 }
57 /* Borrowed from at91_spi.c (c)2006 Martin Thomas */
58 
59 esint8
60 if_initInterface(hwInterface* file, eint8* opts)
61 {
62  euint32 sc;
63  if_spiInit(file);
64  if(sd_Init(file)<0) {
65  DBG((TXT("Card failed to init, breaking up...\n")));
66  return(-1);
67  }
68 
69  if(sd_State(file)<0){
70  DBG((TXT("Card didn't return the ready state, breaking up...\n")
71  ));
72  return(-2);
73  }
74 
75 
76 
77  sd_getDriveSize(file, &sc);
78  file->sectorCount = sc/512;
79  DBG((TXT("Card Capacity is %lu Bytes (%lu Sectors)\n"), sc, file->sectorCount));
80 
81 
82  return(0);
83 }
84 
85 /* Borrowed from lpc2000_spi.c (c)2005 Martin Thomas */
86 
87 esint8
88 if_readBuf(hwInterface* file,euint32 address,euint8* buf)
89 {
90  return(sd_readSector(file,address,buf,512));
91 }
92 
93 esint8
94 if_writeBuf(hwInterface* file,euint32 address,euint8* buf)
95 {
96  return(sd_writeSector(file,address, buf));
97 }
98 
99 esint8
100 if_setPos(hwInterface* file,euint32 address)
101 {
102  return(0);
103 }
104 
105 
106 euint8
107 if_spiSend(hwInterface *iface, euint8 outgoing)
108 {
109  euint8 ingoing;
110  SPI1->DR = outgoing;
111  while(!(SPI1->SR & SPI_SR_RXNE));
112  ingoing = SPI1->DR;
113  /* printf(">%02x <%02x\n", outgoing, ingoing); */
114  return ingoing;
115 }
116 
117 #define MAX_FDS 4
118 
119 static EmbeddedFileSystem sdcard_efs;
120 static File file_descriptors[MAX_FDS];
121 
122 static int
123 find_free_fd()
124 {
125  int fd;
126  for (fd = 0; fd < MAX_FDS; fd++) {
127  if (!file_getAttr(&file_descriptors[fd], FILE_STATUS_OPEN)) {
128  return fd;
129  }
130  }
131  return -1;
132 }
133 
134 static File *
135 get_file(int fd)
136 {
137  if (sdcard_efs.myCard.sectorCount == 0) return NULL;
138  if (fd >= MAX_FDS || fd < 0) return NULL;
139  if (!file_getAttr(&file_descriptors[fd], FILE_STATUS_OPEN)) return NULL;
140  return &file_descriptors[fd];
141 }
142 
143 int
144 cfs_open (const char *name, int flags)
145 {
146  eint8 mode;
147  int fd;
148  if (sdcard_efs.myCard.sectorCount == 0) return -1;
149  fd = find_free_fd();
150  if (fd < 0) return -1;
151  if (flags == CFS_READ) {
152  mode = MODE_READ;
153  } else {
154  mode = MODE_APPEND;
155  }
156  if (file_fopen(&file_descriptors[fd], &sdcard_efs.myFs,
157  (char*)name, mode) < 0) {
158  return -1;
159  }
160  return fd;
161 }
162 
163 void
164 cfs_close(int fd)
165 {
166  File *file = get_file(fd);
167  if (!file) return;
168  file_fclose(file);
169  fs_flushFs(&sdcard_efs.myFs);
170 }
171 
172 int
173 cfs_read (int fd, void *buf, unsigned int len)
174 {
175  File *file = get_file(fd);
176  if (!file) return 0;
177  return file_read(file, len, (euint8*)buf);
178 }
179 
180 int
181 cfs_write (int fd, const void *buf, unsigned int len)
182 {
183  File *file = get_file(fd);
184  if (!file) return 0;
185  return file_write(file, len, (euint8*)buf);
186 }
187 
188 cfs_offset_t
189 cfs_seek (int fd, cfs_offset_t offset, int whence)
190 {
191  File *file = get_file(fd);
192  if (!file) return 0;
193  /* TODO take whence int account */
194  if (file_setpos(file, offset) != 0) return -1;
195  return file->FilePtr;
196 }
197 
198 int
199 cfs_remove(const char *name)
200 {
201  return (rmfile(&sdcard_efs.myFs,(euint8*)name) == 0) ? 0 : -1;
202 }
203 
204 /* Cause a compile time error if expr is false */
205 #ifdef __GNUC__
206 #define COMPILE_TIME_CHECK(expr) \
207 (void) (__builtin_choose_expr ((expr), 0, ((void)0))+3)
208 #else
209 #define COMPILE_TIME_CHECK(expr)
210 #endif
211 
212 #define MAX_DIR_LISTS 4
213 DirList dir_lists[MAX_DIR_LISTS];
214 
215 static DirList *
216 find_free_dir_list()
217 {
218  unsigned int l;
219  for(l = 0; l < MAX_DIR_LISTS; l++) {
220  if (dir_lists[l].fs == NULL) {
221  return &dir_lists[l];
222  }
223  }
224  return NULL;
225 }
226 
227 int
228 cfs_opendir (struct cfs_dir *dirp, const char *name)
229 {
230  DirList *dirs;
231  COMPILE_TIME_CHECK(sizeof(DirList*) <= sizeof(struct cfs_dir));
232  if (sdcard_efs.myCard.sectorCount == 0) return -1;
233  dirs = find_free_dir_list();
234  if (!dirs) return -1;
235  if (ls_openDir(dirs, &sdcard_efs.myFs, (eint8*)name) != 0) {
236  dirs->fs = NULL;
237  return -1;
238  }
239  *(DirList**)dirp = dirs;
240  return 0;
241 }
242 
243 int
244 cfs_readdir (struct cfs_dir *dirp, struct cfs_dirent *dirent)
245 {
246  euint8 *start;
247  euint8 *end;
248  char *to = dirent->name;
249  DirList *dirs = *(DirList**)dirp;
250  if (sdcard_efs.myCard.sectorCount == 0) return 1;
251  if (ls_getNext(dirs) != 0) return 1;
252  start = dirs->currentEntry.FileName;
253  end = start + 7;
254  while(end > start) {
255  if (*end > ' ') {
256  end++;
257  break;
258  }
259  end--;
260  }
261  while(start < end) {
262  *to++ = *start++;
263  }
264  start = dirs->currentEntry.FileName + 8;
265  end = start + 3;
266  if (*start > ' ') {
267  *to++ = '.';
268  *to++ = *start++;
269  while(start < end && *start > ' ') {
270  *to++ = *start++;
271  }
272  }
273  *to = '\0';
274  if (dirs->currentEntry.Attribute & ATTR_DIRECTORY) {
275  dirent->size = 0;
276  } else {
277  dirent->size = dirs->currentEntry.FileSize;
278  }
279  return 0;
280 }
281 
282 void
283 cfs_closedir (struct cfs_dir *dirp)
284 {
285  (*(DirList**)dirp)->fs = NULL;
286 }
287 
288 
289 PROCESS(sdcard_process, "SD card process");
290 
291 PROCESS_THREAD(sdcard_process, ev , data)
292 {
293  int fd;
294  static struct etimer timer;
295  PROCESS_BEGIN();
296  /* Mark all file descriptors as free */
297  for (fd = 0; fd < MAX_FDS; fd++) {
298  file_setAttr(&file_descriptors[fd], FILE_STATUS_OPEN,0);
299  }
300  /* Card not inserted */
301  sdcard_efs.myCard.sectorCount = 0;
302  init_spi();
303 
305  while(1) {
306  PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_EXIT ||
307  ev== PROCESS_EVENT_TIMER || ev == PROCESS_EVENT_POLL);
308  if (ev == PROCESS_EVENT_EXIT) break;
309  if (ev == PROCESS_EVENT_TIMER) {
310  if (!(GPIOA->IDR & (1<<0))) {
311  if (sdcard_efs.myCard.sectorCount == 0) {
313  PROCESS_WAIT_EVENT_UNTIL(ev== PROCESS_EVENT_TIMER);
314  if (efs_init(&sdcard_efs,0) == 0) {
315  if (event_process) {
316  process_post(event_process, sdcard_inserted_event, NULL);
317  }
318  printf("SD card inserted\n");
319  } else {
320  printf("SD card insertion failed\n");
321  }
322  }
323  } else {
324  if (sdcard_efs.myCard.sectorCount != 0) {
325  /* Card removed */
326  fs_umount(&sdcard_efs.myFs);
327  sdcard_efs.myCard.sectorCount = 0;
328  if (event_process) {
329  process_post(event_process, sdcard_removed_event, NULL);
330  }
331  printf("SD card removed\n");
332  }
333  }
335 
336  }
337  }
338  PROCESS_END();
339 }
340 
341 void
342 sdcard_init()
343 {
344  sdcard_inserted_event = process_alloc_event();
345  sdcard_removed_event = process_alloc_event();
346  process_start(&sdcard_process, NULL);
347 }
348 
349 int
350 sdcard_ready()
351 {
352  return sdcard_efs.myCard.sectorCount > 0;
353 }
354 
355 void
356 sdcard_event_process(struct process *p)
357 {
358  event_process = p;
359 }