Contiki 2.5
sdcard-arch.c
1 #include <efs-sdcard.h>
2 #include <sys/process.h>
3 #include <sys/etimer.h>
4 #include <cfs/cfs.h>
5 #include <debug-uart.h>
6 #include <efs.h>
7 #include <ls.h>
8 #include <stdio.h>
9 
10 
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 
19 #define MAX_FDS 4
20 
21 static File file_descriptors[MAX_FDS];
22 
23 static int
24 find_free_fd()
25 {
26  int fd;
27  for (fd = 0; fd < MAX_FDS; fd++) {
28  if (!file_getAttr(&file_descriptors[fd], FILE_STATUS_OPEN)) {
29  return fd;
30  }
31  }
32  return -1;
33 }
34 
35 static File *
36 get_file(int fd)
37 {
38  if (!sdcard_ready()) return 0;
39  if (fd >= MAX_FDS || fd < 0) return NULL;
40  if (!file_getAttr(&file_descriptors[fd], FILE_STATUS_OPEN)) return NULL;
41  return &file_descriptors[fd];
42 }
43 
44 int
45 cfs_open (const char *name, int flags)
46 {
47  eint8 mode;
48  int fd;
49  if (!sdcard_ready()) return -1;
50  fd = find_free_fd();
51  if (fd < 0) return -1;
52  if (flags == CFS_READ) {
53  mode = MODE_READ;
54  } else {
55  mode = MODE_APPEND;
56  }
57  if (file_fopen(&file_descriptors[fd], &sdcard_efs.myFs,
58  (char*)name, mode) < 0) {
59  return -1;
60  }
61  return fd;
62 }
63 
64 void
65 cfs_close(int fd)
66 {
67  File *file = get_file(fd);
68  if (!file) return;
69  file_fclose(file);
70  fs_flushFs(efs_sdcard_get_fs());
71 }
72 
73 int
74 cfs_read (int fd, void *buf, unsigned int len)
75 {
76  File *file = get_file(fd);
77  if (!file) return 0;
78  return file_read(file, len, (euint8*)buf);
79 }
80 
81 int
82 cfs_write (int fd, const void *buf, unsigned int len)
83 {
84  File *file = get_file(fd);
85  if (!file) return 0;
86  return file_write(file, len, (euint8*)buf);
87 }
88 
89 cfs_offset_t
90 cfs_seek (int fd, cfs_offset_t offset, int whence)
91 {
92  File *file;
93  if (whence != CFS_SEEK_SET) return -1;
94  file = get_file(fd);
95  if (!file) return 0;
96  if (file_setpos(file, offset) != 0) return -1;
97  return file->FilePtr;
98 }
99 
100 
101 /* Cause a compile time error if expr is false */
102 #ifdef __GNUC__
103 #define COMPILE_TIME_CHECK(expr) \
104 (void) (__builtin_choose_expr ((expr), 0, ((void)0))+3)
105 #else
106 #define COMPILE_TIME_CHECK(expr)
107 #endif
108 
109 #define MAX_DIR_LISTS 4
110 DirList dir_lists[MAX_DIR_LISTS];
111 
112 static DirList *
113 find_free_dir_list()
114 {
115  unsigned int l;
116  for(l = 0; l < MAX_DIR_LISTS; l++) {
117  if (dir_lists[l].fs == NULL) {
118  return &dir_lists[l];
119  }
120  }
121  return NULL;
122 }
123 
124 int
125 cfs_opendir (struct cfs_dir *dirp, const char *name)
126 {
127  DirList *dirs;
128  COMPILE_TIME_CHECK(sizeof(DirList*) <= sizeof(struct cfs_dir));
129  if (!sdcard_ready()) return -1;
130  dirs = find_free_dir_list();
131  if (!dirs) return -1;
132  if (ls_openDir(dirs, efs_sdcard_get_fs(), (eint8*)name) != 0) {
133  dirs->fs = NULL;
134  return -1;
135  }
136  *(DirList**)dirp = dirs;
137  return 0;
138 }
139 
140 int
141 cfs_readdir (struct cfs_dir *dirp, struct cfs_dirent *dirent)
142 {
143  euint8 *start;
144  euint8 *end;
145  char *to = dirent->name;
146  DirList *dirs = *(DirList**)dirp;
147  if (!sdcard_ready()) return 1;
148  if (ls_getNext(dirs) != 0) return 1;
149  start = dirs->currentEntry.FileName;
150  end = start + 7;
151  while(end > start) {
152  if (*end > ' ') {
153  end++;
154  break;
155  }
156  end--;
157  }
158  while(start < end) {
159  *to++ = *start++;
160  }
161  start = dirs->currentEntry.FileName + 8;
162  end = start + 3;
163  if (*start > ' ') {
164  *to++ = '.';
165  *to++ = *start++;
166  while(start < end && *start > ' ') {
167  *to++ = *start++;
168  }
169  }
170  *to = '\0';
171  if (dirs->currentEntry.Attribute & ATTR_DIRECTORY) {
172  dirent->size = 0;
173  } else {
174  dirent->size = dirs->currentEntry.FileSize;
175  }
176  return 0;
177 }
178 
179 void
180 cfs_closedir (struct cfs_dir *dirp)
181 {
182  (*(DirList**)dirp)->fs = NULL;
183 }