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 Mar 16 06:15:53 2017 +0000
Revision:
146:03e976389d16
fully rebuild, now based on mbed-dev v160

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mega64 146:03e976389d16 1 /* mbed Microcontroller Library
mega64 146:03e976389d16 2 *******************************************************************************
mega64 146:03e976389d16 3 * Copyright (c) 2014, STMicroelectronics
mega64 146:03e976389d16 4 * All rights reserved.
mega64 146:03e976389d16 5 *
mega64 146:03e976389d16 6 * Redistribution and use in source and binary forms, with or without
mega64 146:03e976389d16 7 * modification, are permitted provided that the following conditions are met:
mega64 146:03e976389d16 8 *
mega64 146:03e976389d16 9 * 1. Redistributions of source code must retain the above copyright notice,
mega64 146:03e976389d16 10 * this list of conditions and the following disclaimer.
mega64 146:03e976389d16 11 * 2. Redistributions in binary form must reproduce the above copyright notice,
mega64 146:03e976389d16 12 * this list of conditions and the following disclaimer in the documentation
mega64 146:03e976389d16 13 * and/or other materials provided with the distribution.
mega64 146:03e976389d16 14 * 3. Neither the name of STMicroelectronics nor the names of its contributors
mega64 146:03e976389d16 15 * may be used to endorse or promote products derived from this software
mega64 146:03e976389d16 16 * without specific prior written permission.
mega64 146:03e976389d16 17 *
mega64 146:03e976389d16 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
mega64 146:03e976389d16 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
mega64 146:03e976389d16 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
mega64 146:03e976389d16 21 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
mega64 146:03e976389d16 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
mega64 146:03e976389d16 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
mega64 146:03e976389d16 24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
mega64 146:03e976389d16 25 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
mega64 146:03e976389d16 26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
mega64 146:03e976389d16 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
mega64 146:03e976389d16 28 *******************************************************************************
mega64 146:03e976389d16 29 */
mega64 146:03e976389d16 30 #include <stddef.h>
mega64 146:03e976389d16 31 #include "cmsis.h"
mega64 146:03e976389d16 32 #include "gpio_irq_api.h"
mega64 146:03e976389d16 33 #include "pinmap.h"
mega64 146:03e976389d16 34 #include "mbed_error.h"
mega64 146:03e976389d16 35 #include "gpio_irq_device.h"
mega64 146:03e976389d16 36
mega64 146:03e976389d16 37 #define EDGE_NONE (0)
mega64 146:03e976389d16 38 #define EDGE_RISE (1)
mega64 146:03e976389d16 39 #define EDGE_FALL (2)
mega64 146:03e976389d16 40 #define EDGE_BOTH (3)
mega64 146:03e976389d16 41
mega64 146:03e976389d16 42
mega64 146:03e976389d16 43 typedef struct gpio_channel {
mega64 146:03e976389d16 44 uint32_t pin_mask; // bitmask representing which pins are configured for receiving interrupts
mega64 146:03e976389d16 45 uint32_t channel_ids[MAX_PIN_LINE]; // mbed "gpio_irq_t gpio_irq" field of instance
mega64 146:03e976389d16 46 GPIO_TypeDef* channel_gpio[MAX_PIN_LINE]; // base address of gpio port group
mega64 146:03e976389d16 47 uint32_t channel_pin[MAX_PIN_LINE]; // pin number in port group
mega64 146:03e976389d16 48 } gpio_channel_t;
mega64 146:03e976389d16 49
mega64 146:03e976389d16 50 static gpio_irq_handler irq_handler;
mega64 146:03e976389d16 51
mega64 146:03e976389d16 52 static gpio_channel_t channels[CHANNEL_NUM] = {
mega64 146:03e976389d16 53 #ifdef EXTI_IRQ0_NUM_LINES
mega64 146:03e976389d16 54 {.pin_mask = 0},
mega64 146:03e976389d16 55 #endif
mega64 146:03e976389d16 56 #ifdef EXTI_IRQ1_NUM_LINES
mega64 146:03e976389d16 57 {.pin_mask = 0},
mega64 146:03e976389d16 58 #endif
mega64 146:03e976389d16 59 #ifdef EXTI_IRQ2_NUM_LINES
mega64 146:03e976389d16 60 {.pin_mask = 0},
mega64 146:03e976389d16 61 #endif
mega64 146:03e976389d16 62 #ifdef EXTI_IRQ3_NUM_LINES
mega64 146:03e976389d16 63 {.pin_mask = 0},
mega64 146:03e976389d16 64 #endif
mega64 146:03e976389d16 65 #ifdef EXTI_IRQ4_NUM_LINES
mega64 146:03e976389d16 66 {.pin_mask = 0},
mega64 146:03e976389d16 67 #endif
mega64 146:03e976389d16 68 #ifdef EXTI_IRQ5_NUM_LINES
mega64 146:03e976389d16 69 {.pin_mask = 0},
mega64 146:03e976389d16 70 #endif
mega64 146:03e976389d16 71 #ifdef EXTI_IRQ6_NUM_LINES
mega64 146:03e976389d16 72 {.pin_mask = 0}
mega64 146:03e976389d16 73 #endif
mega64 146:03e976389d16 74 };
mega64 146:03e976389d16 75
mega64 146:03e976389d16 76 static void handle_interrupt_in(uint32_t irq_index, uint32_t max_num_pin_line)
mega64 146:03e976389d16 77 {
mega64 146:03e976389d16 78 gpio_channel_t *gpio_channel = &channels[irq_index];
mega64 146:03e976389d16 79 uint32_t gpio_idx;
mega64 146:03e976389d16 80
mega64 146:03e976389d16 81 for (gpio_idx = 0; gpio_idx < max_num_pin_line; gpio_idx++) {
mega64 146:03e976389d16 82 uint32_t current_mask = (1 << gpio_idx);
mega64 146:03e976389d16 83
mega64 146:03e976389d16 84 if (gpio_channel->pin_mask & current_mask) {
mega64 146:03e976389d16 85 // Retrieve the gpio and pin that generate the irq
mega64 146:03e976389d16 86 GPIO_TypeDef *gpio = (GPIO_TypeDef *)(gpio_channel->channel_gpio[gpio_idx]);
mega64 146:03e976389d16 87 uint32_t pin = (uint32_t)(1 << (gpio_channel->channel_pin[gpio_idx]));
mega64 146:03e976389d16 88
mega64 146:03e976389d16 89 // Clear interrupt flag
mega64 146:03e976389d16 90 if (__HAL_GPIO_EXTI_GET_FLAG(pin) != RESET) {
mega64 146:03e976389d16 91 __HAL_GPIO_EXTI_CLEAR_FLAG(pin);
mega64 146:03e976389d16 92
mega64 146:03e976389d16 93 if (gpio_channel->channel_ids[gpio_idx] == 0)
mega64 146:03e976389d16 94 continue;
mega64 146:03e976389d16 95
mega64 146:03e976389d16 96 // Check which edge has generated the irq
mega64 146:03e976389d16 97 if ((gpio->IDR & pin) == 0) {
mega64 146:03e976389d16 98 irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_FALL);
mega64 146:03e976389d16 99 } else {
mega64 146:03e976389d16 100 irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_RISE);
mega64 146:03e976389d16 101 }
mega64 146:03e976389d16 102 }
mega64 146:03e976389d16 103 }
mega64 146:03e976389d16 104 }
mega64 146:03e976389d16 105 }
mega64 146:03e976389d16 106
mega64 146:03e976389d16 107
mega64 146:03e976389d16 108 #ifdef EXTI_IRQ0_NUM_LINES
mega64 146:03e976389d16 109 // EXTI line 0
mega64 146:03e976389d16 110 static void gpio_irq0(void)
mega64 146:03e976389d16 111 {
mega64 146:03e976389d16 112 handle_interrupt_in(0, EXTI_IRQ0_NUM_LINES);
mega64 146:03e976389d16 113 }
mega64 146:03e976389d16 114 #endif
mega64 146:03e976389d16 115 #ifdef EXTI_IRQ1_NUM_LINES
mega64 146:03e976389d16 116 // EXTI line 1
mega64 146:03e976389d16 117 static void gpio_irq1(void)
mega64 146:03e976389d16 118 {
mega64 146:03e976389d16 119 handle_interrupt_in(1, EXTI_IRQ1_NUM_LINES);
mega64 146:03e976389d16 120 }
mega64 146:03e976389d16 121 #endif
mega64 146:03e976389d16 122 #ifdef EXTI_IRQ2_NUM_LINES
mega64 146:03e976389d16 123 // EXTI line 2
mega64 146:03e976389d16 124 static void gpio_irq2(void)
mega64 146:03e976389d16 125 {
mega64 146:03e976389d16 126 handle_interrupt_in(2, EXTI_IRQ2_NUM_LINES);
mega64 146:03e976389d16 127 }
mega64 146:03e976389d16 128 #endif
mega64 146:03e976389d16 129 #ifdef EXTI_IRQ3_NUM_LINES
mega64 146:03e976389d16 130 // EXTI line 3
mega64 146:03e976389d16 131 static void gpio_irq3(void)
mega64 146:03e976389d16 132 {
mega64 146:03e976389d16 133 handle_interrupt_in(3, EXTI_IRQ3_NUM_LINES);
mega64 146:03e976389d16 134 }
mega64 146:03e976389d16 135 #endif
mega64 146:03e976389d16 136 #ifdef EXTI_IRQ4_NUM_LINES
mega64 146:03e976389d16 137 // EXTI line 4
mega64 146:03e976389d16 138 static void gpio_irq4(void)
mega64 146:03e976389d16 139 {
mega64 146:03e976389d16 140 handle_interrupt_in(4, EXTI_IRQ4_NUM_LINES);
mega64 146:03e976389d16 141 }
mega64 146:03e976389d16 142 #endif
mega64 146:03e976389d16 143 #ifdef EXTI_IRQ5_NUM_LINES
mega64 146:03e976389d16 144 // EXTI lines 5 to 9
mega64 146:03e976389d16 145 static void gpio_irq5(void)
mega64 146:03e976389d16 146 {
mega64 146:03e976389d16 147 handle_interrupt_in(5, EXTI_IRQ5_NUM_LINES);
mega64 146:03e976389d16 148 }
mega64 146:03e976389d16 149 #endif
mega64 146:03e976389d16 150 #ifdef EXTI_IRQ6_NUM_LINES
mega64 146:03e976389d16 151 // EXTI lines 10 to 15
mega64 146:03e976389d16 152 static void gpio_irq6(void)
mega64 146:03e976389d16 153 {
mega64 146:03e976389d16 154 handle_interrupt_in(6, EXTI_IRQ6_NUM_LINES);
mega64 146:03e976389d16 155 }
mega64 146:03e976389d16 156 #endif
mega64 146:03e976389d16 157
mega64 146:03e976389d16 158 extern GPIO_TypeDef *Set_GPIO_Clock(uint32_t port_idx);
mega64 146:03e976389d16 159 extern void pin_function_gpiomode(PinName pin, uint32_t gpiomode);
mega64 146:03e976389d16 160
mega64 146:03e976389d16 161 int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id)
mega64 146:03e976389d16 162 {
mega64 146:03e976389d16 163 uint32_t vector = 0;
mega64 146:03e976389d16 164 uint32_t irq_index;
mega64 146:03e976389d16 165 gpio_channel_t *gpio_channel;
mega64 146:03e976389d16 166 uint32_t gpio_idx;
mega64 146:03e976389d16 167
mega64 146:03e976389d16 168 if (pin == NC) return -1;
mega64 146:03e976389d16 169
mega64 146:03e976389d16 170 /* Enable SYSCFG Clock */
mega64 146:03e976389d16 171 __HAL_RCC_SYSCFG_CLK_ENABLE();
mega64 146:03e976389d16 172
mega64 146:03e976389d16 173 uint32_t port_index = STM_PORT(pin);
mega64 146:03e976389d16 174 uint32_t pin_index = STM_PIN(pin);
mega64 146:03e976389d16 175 irq_index = pin_lines_desc[pin_index].irq_index;
mega64 146:03e976389d16 176
mega64 146:03e976389d16 177 switch (irq_index) {
mega64 146:03e976389d16 178 #ifdef EXTI_IRQ0_NUM_LINES
mega64 146:03e976389d16 179 case 0:
mega64 146:03e976389d16 180 vector = (uint32_t)&gpio_irq0;
mega64 146:03e976389d16 181 break;
mega64 146:03e976389d16 182 #endif
mega64 146:03e976389d16 183 #ifdef EXTI_IRQ1_NUM_LINES
mega64 146:03e976389d16 184 case 1:
mega64 146:03e976389d16 185 vector = (uint32_t)&gpio_irq1;
mega64 146:03e976389d16 186 break;
mega64 146:03e976389d16 187 #endif
mega64 146:03e976389d16 188 #ifdef EXTI_IRQ2_NUM_LINES
mega64 146:03e976389d16 189 case 2:
mega64 146:03e976389d16 190 vector = (uint32_t)&gpio_irq2;
mega64 146:03e976389d16 191 break;
mega64 146:03e976389d16 192 #endif
mega64 146:03e976389d16 193 #ifdef EXTI_IRQ3_NUM_LINES
mega64 146:03e976389d16 194 case 3:
mega64 146:03e976389d16 195 vector = (uint32_t)&gpio_irq3;
mega64 146:03e976389d16 196 break;
mega64 146:03e976389d16 197 #endif
mega64 146:03e976389d16 198 #ifdef EXTI_IRQ4_NUM_LINES
mega64 146:03e976389d16 199 case 4:
mega64 146:03e976389d16 200 vector = (uint32_t)&gpio_irq4;
mega64 146:03e976389d16 201 break;
mega64 146:03e976389d16 202 #endif
mega64 146:03e976389d16 203 #ifdef EXTI_IRQ5_NUM_LINES
mega64 146:03e976389d16 204 case 5:
mega64 146:03e976389d16 205 vector = (uint32_t)&gpio_irq5;
mega64 146:03e976389d16 206 break;
mega64 146:03e976389d16 207 #endif
mega64 146:03e976389d16 208 #ifdef EXTI_IRQ6_NUM_LINES
mega64 146:03e976389d16 209 case 6:
mega64 146:03e976389d16 210 vector = (uint32_t)&gpio_irq6;
mega64 146:03e976389d16 211 break;
mega64 146:03e976389d16 212 #endif
mega64 146:03e976389d16 213 default:
mega64 146:03e976389d16 214 error("InterruptIn error: pin not supported.\n");
mega64 146:03e976389d16 215 return -1;
mega64 146:03e976389d16 216 }
mega64 146:03e976389d16 217
mega64 146:03e976389d16 218 // Enable GPIO clock
mega64 146:03e976389d16 219 GPIO_TypeDef *gpio_add = Set_GPIO_Clock(port_index);
mega64 146:03e976389d16 220
mega64 146:03e976389d16 221 // Save informations for future use
mega64 146:03e976389d16 222 obj->irq_n = pin_lines_desc[pin_index].irq_n;
mega64 146:03e976389d16 223 obj->irq_index = pin_lines_desc[pin_index].irq_index;
mega64 146:03e976389d16 224 obj->event = EDGE_NONE;
mega64 146:03e976389d16 225 obj->pin = pin;
mega64 146:03e976389d16 226
mega64 146:03e976389d16 227 gpio_channel = &channels[irq_index];
mega64 146:03e976389d16 228 gpio_idx = pin_lines_desc[pin_index].gpio_idx;
mega64 146:03e976389d16 229 gpio_channel->pin_mask |= (1 << gpio_idx);
mega64 146:03e976389d16 230 gpio_channel->channel_ids[gpio_idx] = id;
mega64 146:03e976389d16 231 gpio_channel->channel_gpio[gpio_idx] = gpio_add;
mega64 146:03e976389d16 232 gpio_channel->channel_pin[gpio_idx] = pin_index;
mega64 146:03e976389d16 233
mega64 146:03e976389d16 234 irq_handler = handler;
mega64 146:03e976389d16 235
mega64 146:03e976389d16 236 // Enable EXTI interrupt
mega64 146:03e976389d16 237 NVIC_SetVector(obj->irq_n, vector);
mega64 146:03e976389d16 238 gpio_irq_enable(obj);
mega64 146:03e976389d16 239
mega64 146:03e976389d16 240 return 0;
mega64 146:03e976389d16 241 }
mega64 146:03e976389d16 242
mega64 146:03e976389d16 243 void gpio_irq_free(gpio_irq_t *obj)
mega64 146:03e976389d16 244 {
mega64 146:03e976389d16 245 uint32_t gpio_idx = pin_lines_desc[STM_PIN(obj->pin)].gpio_idx;
mega64 146:03e976389d16 246 gpio_channel_t *gpio_channel = &channels[obj->irq_index];
mega64 146:03e976389d16 247
mega64 146:03e976389d16 248 gpio_irq_disable(obj);
mega64 146:03e976389d16 249 gpio_channel->pin_mask &= ~(1 << gpio_idx);
mega64 146:03e976389d16 250 gpio_channel->channel_ids[gpio_idx] = 0;
mega64 146:03e976389d16 251 gpio_channel->channel_gpio[gpio_idx] = 0;
mega64 146:03e976389d16 252 gpio_channel->channel_pin[gpio_idx] = 0;
mega64 146:03e976389d16 253 }
mega64 146:03e976389d16 254
mega64 146:03e976389d16 255 void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
mega64 146:03e976389d16 256 {
mega64 146:03e976389d16 257 if (event == IRQ_RISE) {
mega64 146:03e976389d16 258 if (enable) {
mega64 146:03e976389d16 259 LL_EXTI_EnableRisingTrig_0_31(1 << STM_PIN(obj->pin));
mega64 146:03e976389d16 260 } else {
mega64 146:03e976389d16 261 LL_EXTI_DisableRisingTrig_0_31(1 << STM_PIN(obj->pin));
mega64 146:03e976389d16 262 }
mega64 146:03e976389d16 263 }
mega64 146:03e976389d16 264 if (event == IRQ_FALL) {
mega64 146:03e976389d16 265 if (enable) {
mega64 146:03e976389d16 266 LL_EXTI_EnableFallingTrig_0_31(1 << STM_PIN(obj->pin));
mega64 146:03e976389d16 267 } else {
mega64 146:03e976389d16 268 LL_EXTI_DisableFallingTrig_0_31(1 << STM_PIN(obj->pin));
mega64 146:03e976389d16 269 }
mega64 146:03e976389d16 270 }
mega64 146:03e976389d16 271 }
mega64 146:03e976389d16 272
mega64 146:03e976389d16 273 void gpio_irq_enable(gpio_irq_t *obj)
mega64 146:03e976389d16 274 {
mega64 146:03e976389d16 275 uint32_t temp = 0;
mega64 146:03e976389d16 276 uint32_t port_index = STM_PORT(obj->pin);
mega64 146:03e976389d16 277 uint32_t pin_index = STM_PIN(obj->pin);
mega64 146:03e976389d16 278
mega64 146:03e976389d16 279 /* Select Source */
mega64 146:03e976389d16 280 temp = SYSCFG->EXTICR[pin_index >> 2];
mega64 146:03e976389d16 281 CLEAR_BIT(temp, (0x0FU) << (4U * (pin_index & 0x03U)));
mega64 146:03e976389d16 282 SET_BIT(temp, port_index << (4U * (pin_index & 0x03U)));
mega64 146:03e976389d16 283 SYSCFG->EXTICR[pin_index >> 2] = temp;
mega64 146:03e976389d16 284
mega64 146:03e976389d16 285 LL_EXTI_EnableIT_0_31(1 << pin_index);
mega64 146:03e976389d16 286
mega64 146:03e976389d16 287 NVIC_EnableIRQ(obj->irq_n);
mega64 146:03e976389d16 288 }
mega64 146:03e976389d16 289
mega64 146:03e976389d16 290 void gpio_irq_disable(gpio_irq_t *obj)
mega64 146:03e976389d16 291 {
mega64 146:03e976389d16 292 /* Clear EXTI line configuration */
mega64 146:03e976389d16 293 LL_EXTI_DisableIT_0_31(1 << STM_PIN(obj->pin));
mega64 146:03e976389d16 294 NVIC_DisableIRQ(obj->irq_n);
mega64 146:03e976389d16 295 NVIC_ClearPendingIRQ(obj->irq_n);
mega64 146:03e976389d16 296 obj->event = EDGE_NONE;
mega64 146:03e976389d16 297 }