Color Oled(SSD1331) connect to STMicroelectronics Nucleo-F466

Dependencies:   ssd1331

Committer:
kadonotakashi
Date:
Thu Oct 11 02:27:46 2018 +0000
Revision:
3:f3764f852aa8
Parent:
0:8fdf9a60065b
Nucreo 446 + SSD1331 test version;

Who changed what in which revision?

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