Development mbed library for MAX32630FTHR

Dependents:   blinky_max32630fthr

Committer:
switches
Date:
Fri Dec 16 16:27:57 2016 +0000
Revision:
3:1198227e6421
Parent:
0:5c4d7b2438d3
Changed ADC scale for MAX32625 platforms to 1.2V full scale to match MAX32630 platforms

Who changed what in which revision?

UserRevisionLine numberNew contents of line
switches 0:5c4d7b2438d3 1 /* mbed Microcontroller Library
switches 0:5c4d7b2438d3 2 * Copyright (c) 2006-2013 ARM Limited
switches 0:5c4d7b2438d3 3 *
switches 0:5c4d7b2438d3 4 * Licensed under the Apache License, Version 2.0 (the "License");
switches 0:5c4d7b2438d3 5 * you may not use this file except in compliance with the License.
switches 0:5c4d7b2438d3 6 * You may obtain a copy of the License at
switches 0:5c4d7b2438d3 7 *
switches 0:5c4d7b2438d3 8 * http://www.apache.org/licenses/LICENSE-2.0
switches 0:5c4d7b2438d3 9 *
switches 0:5c4d7b2438d3 10 * Unless required by applicable law or agreed to in writing, software
switches 0:5c4d7b2438d3 11 * distributed under the License is distributed on an "AS IS" BASIS,
switches 0:5c4d7b2438d3 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
switches 0:5c4d7b2438d3 13 * See the License for the specific language governing permissions and
switches 0:5c4d7b2438d3 14 * limitations under the License.
switches 0:5c4d7b2438d3 15 */
switches 0:5c4d7b2438d3 16 #include "drivers/LocalFileSystem.h"
switches 0:5c4d7b2438d3 17
switches 0:5c4d7b2438d3 18 #if DEVICE_LOCALFILESYSTEM
switches 0:5c4d7b2438d3 19
switches 0:5c4d7b2438d3 20 #include "platform/semihost_api.h"
switches 0:5c4d7b2438d3 21 #include <string.h>
switches 0:5c4d7b2438d3 22 #include <stdio.h>
switches 0:5c4d7b2438d3 23
switches 0:5c4d7b2438d3 24 namespace mbed {
switches 0:5c4d7b2438d3 25
switches 0:5c4d7b2438d3 26 /* Extension to FINFO type defined in RTL.h (in Keil RL) - adds 'create time'. */
switches 0:5c4d7b2438d3 27 typedef struct {
switches 0:5c4d7b2438d3 28 unsigned char hr; /* Hours [0..23] */
switches 0:5c4d7b2438d3 29 unsigned char min; /* Minutes [0..59] */
switches 0:5c4d7b2438d3 30 unsigned char sec; /* Seconds [0..59] */
switches 0:5c4d7b2438d3 31 unsigned char day; /* Day [1..31] */
switches 0:5c4d7b2438d3 32 unsigned char mon; /* Month [1..12] */
switches 0:5c4d7b2438d3 33 unsigned short year; /* Year [1980..2107] */
switches 0:5c4d7b2438d3 34 } FTIME;
switches 0:5c4d7b2438d3 35
switches 0:5c4d7b2438d3 36 typedef struct { /* File Search info record */
switches 0:5c4d7b2438d3 37 char name[32]; /* File name */
switches 0:5c4d7b2438d3 38 long size; /* File size in bytes */
switches 0:5c4d7b2438d3 39 int fileID; /* System File Identification */
switches 0:5c4d7b2438d3 40 FTIME create_time; /* Date & time file was created */
switches 0:5c4d7b2438d3 41 FTIME write_time; /* Date & time of last write */
switches 0:5c4d7b2438d3 42 } XFINFO;
switches 0:5c4d7b2438d3 43
switches 0:5c4d7b2438d3 44 #define RESERVED_FOR_USER_APPLICATIONS (0x100) /* 0x100 - 0x1ff */
switches 0:5c4d7b2438d3 45 #define USR_XFFIND (RESERVED_FOR_USER_APPLICATIONS + 0)
switches 0:5c4d7b2438d3 46
switches 0:5c4d7b2438d3 47 static int xffind (const char *pattern, XFINFO *info) {
switches 0:5c4d7b2438d3 48 unsigned param[4];
switches 0:5c4d7b2438d3 49
switches 0:5c4d7b2438d3 50 param[0] = (unsigned long)pattern;
switches 0:5c4d7b2438d3 51 param[1] = (unsigned long)strlen(pattern);
switches 0:5c4d7b2438d3 52 param[2] = (unsigned long)info;
switches 0:5c4d7b2438d3 53 param[3] = (unsigned long)sizeof(XFINFO);
switches 0:5c4d7b2438d3 54
switches 0:5c4d7b2438d3 55 return __semihost(USR_XFFIND, param);
switches 0:5c4d7b2438d3 56 }
switches 0:5c4d7b2438d3 57
switches 0:5c4d7b2438d3 58 #define OPEN_R 0
switches 0:5c4d7b2438d3 59 #define OPEN_B 1
switches 0:5c4d7b2438d3 60 #define OPEN_PLUS 2
switches 0:5c4d7b2438d3 61 #define OPEN_W 4
switches 0:5c4d7b2438d3 62 #define OPEN_A 8
switches 0:5c4d7b2438d3 63 #define OPEN_INVALID -1
switches 0:5c4d7b2438d3 64
switches 0:5c4d7b2438d3 65 int posix_to_semihost_open_flags(int flags) {
switches 0:5c4d7b2438d3 66 /* POSIX flags -> semihosting open mode */
switches 0:5c4d7b2438d3 67 int openmode;
switches 0:5c4d7b2438d3 68 if (flags & O_RDWR) {
switches 0:5c4d7b2438d3 69 /* a plus mode */
switches 0:5c4d7b2438d3 70 openmode = OPEN_PLUS;
switches 0:5c4d7b2438d3 71 if (flags & O_APPEND) {
switches 0:5c4d7b2438d3 72 openmode |= OPEN_A;
switches 0:5c4d7b2438d3 73 } else if (flags & O_TRUNC) {
switches 0:5c4d7b2438d3 74 openmode |= OPEN_W;
switches 0:5c4d7b2438d3 75 } else {
switches 0:5c4d7b2438d3 76 openmode |= OPEN_R;
switches 0:5c4d7b2438d3 77 }
switches 0:5c4d7b2438d3 78 } else if (flags & O_WRONLY) {
switches 0:5c4d7b2438d3 79 /* write or append */
switches 0:5c4d7b2438d3 80 if (flags & O_APPEND) {
switches 0:5c4d7b2438d3 81 openmode = OPEN_A;
switches 0:5c4d7b2438d3 82 } else {
switches 0:5c4d7b2438d3 83 openmode = OPEN_W;
switches 0:5c4d7b2438d3 84 }
switches 0:5c4d7b2438d3 85 } else if (flags == O_RDONLY) {
switches 0:5c4d7b2438d3 86 /* read mode */
switches 0:5c4d7b2438d3 87 openmode = OPEN_R;
switches 0:5c4d7b2438d3 88 } else {
switches 0:5c4d7b2438d3 89 /* invalid flags */
switches 0:5c4d7b2438d3 90 openmode = OPEN_INVALID;
switches 0:5c4d7b2438d3 91 }
switches 0:5c4d7b2438d3 92
switches 0:5c4d7b2438d3 93 return openmode;
switches 0:5c4d7b2438d3 94 }
switches 0:5c4d7b2438d3 95
switches 0:5c4d7b2438d3 96 FILEHANDLE local_file_open(const char* name, int flags) {
switches 0:5c4d7b2438d3 97 int openmode = posix_to_semihost_open_flags(flags);
switches 0:5c4d7b2438d3 98 if (openmode == OPEN_INVALID) {
switches 0:5c4d7b2438d3 99 return (FILEHANDLE)NULL;
switches 0:5c4d7b2438d3 100 }
switches 0:5c4d7b2438d3 101
switches 0:5c4d7b2438d3 102 FILEHANDLE fh = semihost_open(name, openmode);
switches 0:5c4d7b2438d3 103 if (fh == -1) {
switches 0:5c4d7b2438d3 104 return (FILEHANDLE)NULL;
switches 0:5c4d7b2438d3 105 }
switches 0:5c4d7b2438d3 106
switches 0:5c4d7b2438d3 107 return fh;
switches 0:5c4d7b2438d3 108 }
switches 0:5c4d7b2438d3 109
switches 0:5c4d7b2438d3 110 LocalFileHandle::LocalFileHandle(FILEHANDLE fh) : _fh(fh), pos(0) {
switches 0:5c4d7b2438d3 111 // No lock needed in constructor
switches 0:5c4d7b2438d3 112 }
switches 0:5c4d7b2438d3 113
switches 0:5c4d7b2438d3 114 int LocalFileHandle::close() {
switches 0:5c4d7b2438d3 115 int retval = semihost_close(_fh);
switches 0:5c4d7b2438d3 116 delete this;
switches 0:5c4d7b2438d3 117 return retval;
switches 0:5c4d7b2438d3 118 }
switches 0:5c4d7b2438d3 119
switches 0:5c4d7b2438d3 120 ssize_t LocalFileHandle::write(const void *buffer, size_t length) {
switches 0:5c4d7b2438d3 121 lock();
switches 0:5c4d7b2438d3 122 ssize_t n = semihost_write(_fh, (const unsigned char*)buffer, length, 0); // number of characters not written
switches 0:5c4d7b2438d3 123 n = length - n; // number of characters written
switches 0:5c4d7b2438d3 124 pos += n;
switches 0:5c4d7b2438d3 125 unlock();
switches 0:5c4d7b2438d3 126 return n;
switches 0:5c4d7b2438d3 127 }
switches 0:5c4d7b2438d3 128
switches 0:5c4d7b2438d3 129 ssize_t LocalFileHandle::read(void *buffer, size_t length) {
switches 0:5c4d7b2438d3 130 lock();
switches 0:5c4d7b2438d3 131 ssize_t n = semihost_read(_fh, (unsigned char*)buffer, length, 0); // number of characters not read
switches 0:5c4d7b2438d3 132 n = length - n; // number of characters read
switches 0:5c4d7b2438d3 133 pos += n;
switches 0:5c4d7b2438d3 134 unlock();
switches 0:5c4d7b2438d3 135 return n;
switches 0:5c4d7b2438d3 136 }
switches 0:5c4d7b2438d3 137
switches 0:5c4d7b2438d3 138 int LocalFileHandle::isatty() {
switches 0:5c4d7b2438d3 139 lock();
switches 0:5c4d7b2438d3 140 int ret = semihost_istty(_fh);
switches 0:5c4d7b2438d3 141 unlock();
switches 0:5c4d7b2438d3 142 return ret;
switches 0:5c4d7b2438d3 143 }
switches 0:5c4d7b2438d3 144
switches 0:5c4d7b2438d3 145 off_t LocalFileHandle::lseek(off_t position, int whence) {
switches 0:5c4d7b2438d3 146 lock();
switches 0:5c4d7b2438d3 147 if (whence == SEEK_CUR) {
switches 0:5c4d7b2438d3 148 position += pos;
switches 0:5c4d7b2438d3 149 } else if (whence == SEEK_END) {
switches 0:5c4d7b2438d3 150 position += semihost_flen(_fh);
switches 0:5c4d7b2438d3 151 } /* otherwise SEEK_SET, so position is fine */
switches 0:5c4d7b2438d3 152
switches 0:5c4d7b2438d3 153 /* Always seems to return -1, so just ignore for now. */
switches 0:5c4d7b2438d3 154 semihost_seek(_fh, position);
switches 0:5c4d7b2438d3 155 pos = position;
switches 0:5c4d7b2438d3 156 unlock();
switches 0:5c4d7b2438d3 157 return position;
switches 0:5c4d7b2438d3 158 }
switches 0:5c4d7b2438d3 159
switches 0:5c4d7b2438d3 160 int LocalFileHandle::fsync() {
switches 0:5c4d7b2438d3 161 lock();
switches 0:5c4d7b2438d3 162 int ret = semihost_ensure(_fh);
switches 0:5c4d7b2438d3 163 unlock();
switches 0:5c4d7b2438d3 164 return ret;
switches 0:5c4d7b2438d3 165 }
switches 0:5c4d7b2438d3 166
switches 0:5c4d7b2438d3 167 off_t LocalFileHandle::flen() {
switches 0:5c4d7b2438d3 168 lock();
switches 0:5c4d7b2438d3 169 off_t off = semihost_flen(_fh);
switches 0:5c4d7b2438d3 170 unlock();
switches 0:5c4d7b2438d3 171 return off;
switches 0:5c4d7b2438d3 172 }
switches 0:5c4d7b2438d3 173
switches 0:5c4d7b2438d3 174 void LocalFileHandle::lock() {
switches 0:5c4d7b2438d3 175 _mutex.lock();
switches 0:5c4d7b2438d3 176 }
switches 0:5c4d7b2438d3 177
switches 0:5c4d7b2438d3 178 void LocalFileHandle::unlock() {
switches 0:5c4d7b2438d3 179 _mutex.unlock();
switches 0:5c4d7b2438d3 180 }
switches 0:5c4d7b2438d3 181
switches 0:5c4d7b2438d3 182 class LocalDirHandle : public DirHandle {
switches 0:5c4d7b2438d3 183
switches 0:5c4d7b2438d3 184 public:
switches 0:5c4d7b2438d3 185 struct dirent cur_entry;
switches 0:5c4d7b2438d3 186 XFINFO info;
switches 0:5c4d7b2438d3 187
switches 0:5c4d7b2438d3 188 LocalDirHandle() : cur_entry(), info() {
switches 0:5c4d7b2438d3 189 }
switches 0:5c4d7b2438d3 190
switches 0:5c4d7b2438d3 191 virtual int closedir() {
switches 0:5c4d7b2438d3 192 // No lock can be used in destructor
switches 0:5c4d7b2438d3 193 delete this;
switches 0:5c4d7b2438d3 194 return 0;
switches 0:5c4d7b2438d3 195 }
switches 0:5c4d7b2438d3 196
switches 0:5c4d7b2438d3 197 virtual struct dirent *readdir() {
switches 0:5c4d7b2438d3 198 lock();
switches 0:5c4d7b2438d3 199 if (xffind("*", &info)!=0) {
switches 0:5c4d7b2438d3 200 unlock();
switches 0:5c4d7b2438d3 201 return NULL;
switches 0:5c4d7b2438d3 202 }
switches 0:5c4d7b2438d3 203 memcpy(cur_entry.d_name, info.name, sizeof(info.name));
switches 0:5c4d7b2438d3 204 unlock();
switches 0:5c4d7b2438d3 205 return &cur_entry;
switches 0:5c4d7b2438d3 206 }
switches 0:5c4d7b2438d3 207
switches 0:5c4d7b2438d3 208 virtual void rewinddir() {
switches 0:5c4d7b2438d3 209 lock();
switches 0:5c4d7b2438d3 210 info.fileID = 0;
switches 0:5c4d7b2438d3 211 unlock();
switches 0:5c4d7b2438d3 212 }
switches 0:5c4d7b2438d3 213
switches 0:5c4d7b2438d3 214 virtual off_t telldir() {
switches 0:5c4d7b2438d3 215 lock();
switches 0:5c4d7b2438d3 216 int fileId = info.fileID;
switches 0:5c4d7b2438d3 217 unlock();
switches 0:5c4d7b2438d3 218 return fileId;
switches 0:5c4d7b2438d3 219 }
switches 0:5c4d7b2438d3 220
switches 0:5c4d7b2438d3 221 virtual void seekdir(off_t offset) {
switches 0:5c4d7b2438d3 222 lock();
switches 0:5c4d7b2438d3 223 info.fileID = offset;
switches 0:5c4d7b2438d3 224 unlock();
switches 0:5c4d7b2438d3 225 }
switches 0:5c4d7b2438d3 226
switches 0:5c4d7b2438d3 227 protected:
switches 0:5c4d7b2438d3 228 PlatformMutex _mutex;
switches 0:5c4d7b2438d3 229
switches 0:5c4d7b2438d3 230 virtual void lock() {
switches 0:5c4d7b2438d3 231 _mutex.lock();
switches 0:5c4d7b2438d3 232 }
switches 0:5c4d7b2438d3 233
switches 0:5c4d7b2438d3 234 virtual void unlock() {
switches 0:5c4d7b2438d3 235 _mutex.unlock();
switches 0:5c4d7b2438d3 236 }
switches 0:5c4d7b2438d3 237 };
switches 0:5c4d7b2438d3 238
switches 0:5c4d7b2438d3 239 FileHandle *LocalFileSystem::open(const char* name, int flags) {
switches 0:5c4d7b2438d3 240 // No global state modified so function is thread safe
switches 0:5c4d7b2438d3 241
switches 0:5c4d7b2438d3 242 /* reject filenames with / in them */
switches 0:5c4d7b2438d3 243 for (const char *tmp = name; *tmp; tmp++) {
switches 0:5c4d7b2438d3 244 if (*tmp == '/') {
switches 0:5c4d7b2438d3 245 return NULL;
switches 0:5c4d7b2438d3 246 }
switches 0:5c4d7b2438d3 247 }
switches 0:5c4d7b2438d3 248
switches 0:5c4d7b2438d3 249 int openmode = posix_to_semihost_open_flags(flags);
switches 0:5c4d7b2438d3 250 if (openmode == OPEN_INVALID) {
switches 0:5c4d7b2438d3 251 return NULL;
switches 0:5c4d7b2438d3 252 }
switches 0:5c4d7b2438d3 253
switches 0:5c4d7b2438d3 254 FILEHANDLE fh = semihost_open(name, openmode);
switches 0:5c4d7b2438d3 255 if (fh == -1) {
switches 0:5c4d7b2438d3 256 return NULL;
switches 0:5c4d7b2438d3 257 }
switches 0:5c4d7b2438d3 258 return new LocalFileHandle(fh);
switches 0:5c4d7b2438d3 259 }
switches 0:5c4d7b2438d3 260
switches 0:5c4d7b2438d3 261 int LocalFileSystem::remove(const char *filename) {
switches 0:5c4d7b2438d3 262 // No global state modified so function is thread safe
switches 0:5c4d7b2438d3 263
switches 0:5c4d7b2438d3 264 return semihost_remove(filename);
switches 0:5c4d7b2438d3 265 }
switches 0:5c4d7b2438d3 266
switches 0:5c4d7b2438d3 267 DirHandle *LocalFileSystem::opendir(const char *name) {
switches 0:5c4d7b2438d3 268 // No global state modified so function is thread safe
switches 0:5c4d7b2438d3 269
switches 0:5c4d7b2438d3 270 return new LocalDirHandle();
switches 0:5c4d7b2438d3 271 }
switches 0:5c4d7b2438d3 272
switches 0:5c4d7b2438d3 273 } // namespace mbed
switches 0:5c4d7b2438d3 274
switches 0:5c4d7b2438d3 275 #endif