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
mega64 146:03e976389d16 2 /** \addtogroup platform */
mega64 146:03e976389d16 3 /** @{*/
mega64 146:03e976389d16 4 /* General C++ Object Thunking class
mega64 146:03e976389d16 5 *
mega64 146:03e976389d16 6 * - allows direct callbacks to non-static C++ class functions
mega64 146:03e976389d16 7 * - keeps track for the corresponding class instance
mega64 146:03e976389d16 8 * - supports an optional context parameter for the called function
mega64 146:03e976389d16 9 * - ideally suited for class object receiving interrupts (NVIC_SetVector)
mega64 146:03e976389d16 10 *
mega64 146:03e976389d16 11 * Copyright (c) 2014-2015 ARM Limited
mega64 146:03e976389d16 12 *
mega64 146:03e976389d16 13 * Licensed under the Apache License, Version 2.0 (the "License");
mega64 146:03e976389d16 14 * you may not use this file except in compliance with the License.
mega64 146:03e976389d16 15 * You may obtain a copy of the License at
mega64 146:03e976389d16 16 *
mega64 146:03e976389d16 17 * http://www.apache.org/licenses/LICENSE-2.0
mega64 146:03e976389d16 18 *
mega64 146:03e976389d16 19 * Unless required by applicable law or agreed to in writing, software
mega64 146:03e976389d16 20 * distributed under the License is distributed on an "AS IS" BASIS,
mega64 146:03e976389d16 21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mega64 146:03e976389d16 22 * See the License for the specific language governing permissions and
mega64 146:03e976389d16 23 * limitations under the License.
mega64 146:03e976389d16 24 */
mega64 146:03e976389d16 25
mega64 146:03e976389d16 26 /* General C++ Object Thunking class
mega64 146:03e976389d16 27 *
mega64 146:03e976389d16 28 * - allows direct callbacks to non-static C++ class functions
mega64 146:03e976389d16 29 * - keeps track for the corresponding class instance
mega64 146:03e976389d16 30 * - supports an optional context parameter for the called function
mega64 146:03e976389d16 31 * - ideally suited for class object receiving interrupts (NVIC_SetVector)
mega64 146:03e976389d16 32 */
mega64 146:03e976389d16 33
mega64 146:03e976389d16 34 #ifndef __CTHUNK_H__
mega64 146:03e976389d16 35 #define __CTHUNK_H__
mega64 146:03e976389d16 36
mega64 146:03e976389d16 37 #define CTHUNK_ADDRESS 1
mega64 146:03e976389d16 38 #define CTHUNK_VARIABLES volatile uint32_t code[2]
mega64 146:03e976389d16 39
mega64 146:03e976389d16 40 #if (defined(__CORTEX_M3) || defined(__CORTEX_M4) || defined(__CORTEX_M7) || defined(__CORTEX_A9))
mega64 146:03e976389d16 41 /**
mega64 146:03e976389d16 42 * CTHUNK disassembly for Cortex-M3/M4/M7/A9 (thumb2):
mega64 146:03e976389d16 43 * * adr r0, #4
mega64 146:03e976389d16 44 * * ldm r0, {r0, r1, r2, pc}
mega64 146:03e976389d16 45 *
mega64 146:03e976389d16 46 * This instruction loads the arguments for the static thunking function to r0-r2, and
mega64 146:03e976389d16 47 * branches to that function by loading its address into PC.
mega64 146:03e976389d16 48 *
mega64 146:03e976389d16 49 * This is safe for both regular calling and interrupt calling, since it only touches scratch registers
mega64 146:03e976389d16 50 * which should be saved by the caller, and are automatically saved as part of the IRQ context switch.
mega64 146:03e976389d16 51 */
mega64 146:03e976389d16 52 #define CTHUNK_ASSIGMENT do { \
mega64 146:03e976389d16 53 m_thunk.code[0] = 0xE890A001; \
mega64 146:03e976389d16 54 m_thunk.code[1] = 0x00008007; \
mega64 146:03e976389d16 55 } while (0)
mega64 146:03e976389d16 56
mega64 146:03e976389d16 57 #elif (defined(__CORTEX_M0PLUS) || defined(__CORTEX_M0))
mega64 146:03e976389d16 58 /*
mega64 146:03e976389d16 59 * CTHUNK disassembly for Cortex M0/M0+ (thumb):
mega64 146:03e976389d16 60 * * adr r0, #4
mega64 146:03e976389d16 61 * * ldm r0, {r0, r1, r2, r3}
mega64 146:03e976389d16 62 * * bx r3
mega64 146:03e976389d16 63 */
mega64 146:03e976389d16 64 #define CTHUNK_ASSIGMENT do { \
mega64 146:03e976389d16 65 m_thunk.code[0] = 0xC80FA001; \
mega64 146:03e976389d16 66 m_thunk.code[1] = 0x00004718; \
mega64 146:03e976389d16 67 } while (0)
mega64 146:03e976389d16 68
mega64 146:03e976389d16 69 #else
mega64 146:03e976389d16 70 #error "Target is not currently suported."
mega64 146:03e976389d16 71 #endif
mega64 146:03e976389d16 72
mega64 146:03e976389d16 73 /* IRQ/Exception compatible thunk entry function */
mega64 146:03e976389d16 74 typedef void (*CThunkEntry)(void);
mega64 146:03e976389d16 75
mega64 146:03e976389d16 76 /**
mega64 146:03e976389d16 77 * Class for created a pointer with data bound to it
mega64 146:03e976389d16 78 *
mega64 146:03e976389d16 79 * @Note Synchronization level: Not protected
mega64 146:03e976389d16 80 */
mega64 146:03e976389d16 81 template<class T>
mega64 146:03e976389d16 82 class CThunk
mega64 146:03e976389d16 83 {
mega64 146:03e976389d16 84 public:
mega64 146:03e976389d16 85 typedef void (T::*CCallbackSimple)(void);
mega64 146:03e976389d16 86 typedef void (T::*CCallback)(void* context);
mega64 146:03e976389d16 87
mega64 146:03e976389d16 88 inline CThunk(T *instance)
mega64 146:03e976389d16 89 {
mega64 146:03e976389d16 90 init(instance, NULL, NULL);
mega64 146:03e976389d16 91 }
mega64 146:03e976389d16 92
mega64 146:03e976389d16 93 inline CThunk(T *instance, CCallback callback)
mega64 146:03e976389d16 94 {
mega64 146:03e976389d16 95 init(instance, callback, NULL);
mega64 146:03e976389d16 96 }
mega64 146:03e976389d16 97
mega64 146:03e976389d16 98 ~CThunk() {
mega64 146:03e976389d16 99
mega64 146:03e976389d16 100 }
mega64 146:03e976389d16 101
mega64 146:03e976389d16 102 inline CThunk(T *instance, CCallbackSimple callback)
mega64 146:03e976389d16 103 {
mega64 146:03e976389d16 104 init(instance, (CCallback)callback, NULL);
mega64 146:03e976389d16 105 }
mega64 146:03e976389d16 106
mega64 146:03e976389d16 107 inline CThunk(T &instance, CCallback callback)
mega64 146:03e976389d16 108 {
mega64 146:03e976389d16 109 init(instance, callback, NULL);
mega64 146:03e976389d16 110 }
mega64 146:03e976389d16 111
mega64 146:03e976389d16 112 inline CThunk(T &instance, CCallbackSimple callback)
mega64 146:03e976389d16 113 {
mega64 146:03e976389d16 114 init(instance, (CCallback)callback, NULL);
mega64 146:03e976389d16 115 }
mega64 146:03e976389d16 116
mega64 146:03e976389d16 117 inline CThunk(T &instance, CCallback callback, void* context)
mega64 146:03e976389d16 118 {
mega64 146:03e976389d16 119 init(instance, callback, context);
mega64 146:03e976389d16 120 }
mega64 146:03e976389d16 121
mega64 146:03e976389d16 122 inline void callback(CCallback callback)
mega64 146:03e976389d16 123 {
mega64 146:03e976389d16 124 m_callback = callback;
mega64 146:03e976389d16 125 }
mega64 146:03e976389d16 126
mega64 146:03e976389d16 127 inline void callback(CCallbackSimple callback)
mega64 146:03e976389d16 128 {
mega64 146:03e976389d16 129 m_callback = (CCallback)callback;
mega64 146:03e976389d16 130 }
mega64 146:03e976389d16 131
mega64 146:03e976389d16 132 inline void context(void* context)
mega64 146:03e976389d16 133 {
mega64 146:03e976389d16 134 m_thunk.context = (uint32_t)context;
mega64 146:03e976389d16 135 }
mega64 146:03e976389d16 136
mega64 146:03e976389d16 137 inline void context(uint32_t context)
mega64 146:03e976389d16 138 {
mega64 146:03e976389d16 139 m_thunk.context = context;
mega64 146:03e976389d16 140 }
mega64 146:03e976389d16 141
mega64 146:03e976389d16 142 inline uint32_t entry(void)
mega64 146:03e976389d16 143 {
mega64 146:03e976389d16 144 return (((uint32_t)&m_thunk)|CTHUNK_ADDRESS);
mega64 146:03e976389d16 145 }
mega64 146:03e976389d16 146
mega64 146:03e976389d16 147 /* get thunk entry point for connecting rhunk to an IRQ table */
mega64 146:03e976389d16 148 inline operator CThunkEntry(void)
mega64 146:03e976389d16 149 {
mega64 146:03e976389d16 150 return (CThunkEntry)entry();
mega64 146:03e976389d16 151 }
mega64 146:03e976389d16 152
mega64 146:03e976389d16 153 /* get thunk entry point for connecting rhunk to an IRQ table */
mega64 146:03e976389d16 154 inline operator uint32_t(void)
mega64 146:03e976389d16 155 {
mega64 146:03e976389d16 156 return entry();
mega64 146:03e976389d16 157 }
mega64 146:03e976389d16 158
mega64 146:03e976389d16 159 /* simple test function */
mega64 146:03e976389d16 160 inline void call(void)
mega64 146:03e976389d16 161 {
mega64 146:03e976389d16 162 (((CThunkEntry)(entry()))());
mega64 146:03e976389d16 163 }
mega64 146:03e976389d16 164
mega64 146:03e976389d16 165 private:
mega64 146:03e976389d16 166 T* m_instance;
mega64 146:03e976389d16 167 volatile CCallback m_callback;
mega64 146:03e976389d16 168
mega64 146:03e976389d16 169 // TODO: this needs proper fix, to refactor toolchain header file and all its use
mega64 146:03e976389d16 170 // PACKED there is not defined properly for IAR
mega64 146:03e976389d16 171 #if defined (__ICCARM__)
mega64 146:03e976389d16 172 typedef __packed struct
mega64 146:03e976389d16 173 {
mega64 146:03e976389d16 174 CTHUNK_VARIABLES;
mega64 146:03e976389d16 175 volatile uint32_t instance;
mega64 146:03e976389d16 176 volatile uint32_t context;
mega64 146:03e976389d16 177 volatile uint32_t callback;
mega64 146:03e976389d16 178 volatile uint32_t trampoline;
mega64 146:03e976389d16 179 } CThunkTrampoline;
mega64 146:03e976389d16 180 #else
mega64 146:03e976389d16 181 typedef struct
mega64 146:03e976389d16 182 {
mega64 146:03e976389d16 183 CTHUNK_VARIABLES;
mega64 146:03e976389d16 184 volatile uint32_t instance;
mega64 146:03e976389d16 185 volatile uint32_t context;
mega64 146:03e976389d16 186 volatile uint32_t callback;
mega64 146:03e976389d16 187 volatile uint32_t trampoline;
mega64 146:03e976389d16 188 } __attribute__((__packed__)) CThunkTrampoline;
mega64 146:03e976389d16 189 #endif
mega64 146:03e976389d16 190
mega64 146:03e976389d16 191 static void trampoline(T* instance, void* context, CCallback* callback)
mega64 146:03e976389d16 192 {
mega64 146:03e976389d16 193 if(instance && *callback) {
mega64 146:03e976389d16 194 (static_cast<T*>(instance)->**callback)(context);
mega64 146:03e976389d16 195 }
mega64 146:03e976389d16 196 }
mega64 146:03e976389d16 197
mega64 146:03e976389d16 198 volatile CThunkTrampoline m_thunk;
mega64 146:03e976389d16 199
mega64 146:03e976389d16 200 inline void init(T *instance, CCallback callback, void* context)
mega64 146:03e976389d16 201 {
mega64 146:03e976389d16 202 /* remember callback - need to add this level of redirection
mega64 146:03e976389d16 203 as pointer size for member functions differs between platforms */
mega64 146:03e976389d16 204 m_callback = callback;
mega64 146:03e976389d16 205
mega64 146:03e976389d16 206 /* populate thunking trampoline */
mega64 146:03e976389d16 207 CTHUNK_ASSIGMENT;
mega64 146:03e976389d16 208 m_thunk.context = (uint32_t)context;
mega64 146:03e976389d16 209 m_thunk.instance = (uint32_t)instance;
mega64 146:03e976389d16 210 m_thunk.callback = (uint32_t)&m_callback;
mega64 146:03e976389d16 211 m_thunk.trampoline = (uint32_t)&trampoline;
mega64 146:03e976389d16 212
mega64 146:03e976389d16 213 #if defined(__CORTEX_A9)
mega64 146:03e976389d16 214 /* Data cache clean */
mega64 146:03e976389d16 215 /* Cache control */
mega64 146:03e976389d16 216 {
mega64 146:03e976389d16 217 uint32_t start_addr = (uint32_t)&m_thunk & 0xFFFFFFE0;
mega64 146:03e976389d16 218 uint32_t end_addr = (uint32_t)&m_thunk + sizeof(m_thunk);
mega64 146:03e976389d16 219 uint32_t addr;
mega64 146:03e976389d16 220
mega64 146:03e976389d16 221 /* Data cache clean and invalid */
mega64 146:03e976389d16 222 for (addr = start_addr; addr < end_addr; addr += 0x20) {
mega64 146:03e976389d16 223 __v7_clean_inv_dcache_mva((void *)addr);
mega64 146:03e976389d16 224 }
mega64 146:03e976389d16 225 /* Instruction cache invalid */
mega64 146:03e976389d16 226 __v7_inv_icache_all();
mega64 146:03e976389d16 227 __ca9u_inv_tlb_all();
mega64 146:03e976389d16 228 __v7_inv_btac();
mega64 146:03e976389d16 229 }
mega64 146:03e976389d16 230 #endif
mega64 146:03e976389d16 231 #if defined(__CORTEX_M7)
mega64 146:03e976389d16 232 /* Data cache clean and invalid */
mega64 146:03e976389d16 233 SCB_CleanInvalidateDCache();
mega64 146:03e976389d16 234
mega64 146:03e976389d16 235 /* Instruction cache invalid */
mega64 146:03e976389d16 236 SCB_InvalidateICache();
mega64 146:03e976389d16 237 #endif
mega64 146:03e976389d16 238 __ISB();
mega64 146:03e976389d16 239 __DSB();
mega64 146:03e976389d16 240 }
mega64 146:03e976389d16 241 };
mega64 146:03e976389d16 242
mega64 146:03e976389d16 243 #endif/*__CTHUNK_H__*/
mega64 146:03e976389d16 244
mega64 146:03e976389d16 245 /** @}*/