Modification of Mbed-dev library for LQFP48 package microcontrollers: STM32F103C8 (STM32F103C8T6) and STM32F103CB (STM32F103CBT6) (Bluepill boards, Maple mini etc. )

Fork of mbed-STM32F103C8_org by Nothing Special

Library for STM32F103C8 (Bluepill boards etc.).
Use this instead of mbed library.
This library allows the size of the code in the FLASH up to 128kB. Therefore, code also runs on microcontrollers STM32F103CB (eg. Maple mini).
But in the case of STM32F103C8, check the size of the resulting code would not exceed 64kB.

To compile a program with this library, use NUCLEO-F103RB as the target name. !

Changes:

  • Corrected initialization of the HSE + crystal clock (mbed permanent bug), allowing the use of on-board xtal (8MHz).(1)
  • Additionally, it also set USB clock (48Mhz).(2)
  • Definitions of pins and peripherals adjusted to LQFP48 case.
  • Board led LED1 is now PC_13 (3)
  • USER_BUTTON is now PC_14 (4)

    Now the library is complete rebuilt based on mbed-dev v160 (and not yet fully tested).

notes
(1) - In case 8MHz xtal on board, CPU frequency is 72MHz. Without xtal is 64MHz.
(2) - Using the USB interface is only possible if STM32 is clocking by on-board 8MHz xtal or external clock signal 8MHz on the OSC_IN pin.
(3) - On Bluepill board led operation is reversed, i.e. 0 - led on, 1 - led off.
(4) - Bluepill board has no real user button

Information

After export to SW4STM (AC6):

  • add line #include "mbed_config.h" in files Serial.h and RawSerial.h
  • in project properties change Optimisation Level to Optimise for size (-Os)
Committer:
mega64
Date:
Thu Apr 27 23:56:38 2017 +0000
Revision:
148:8b0b02bf146f
Parent:
146:03e976389d16
Remove unnecessary folders

Who changed what in which revision?

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