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 * Copyright (c) 2006-2016 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 "hal_tick.h"
mega64 146:03e976389d16 17
mega64 146:03e976389d16 18 // A 16-bit timer is used
mega64 146:03e976389d16 19 #if TIM_MST_16BIT
mega64 146:03e976389d16 20
mega64 146:03e976389d16 21 #define DEBUG_TICK 0 // Set to 1 to toggle a pin (see below which pin) at each tick
mega64 146:03e976389d16 22
mega64 146:03e976389d16 23 extern TIM_HandleTypeDef TimMasterHandle;
mega64 146:03e976389d16 24
mega64 146:03e976389d16 25 extern volatile uint32_t SlaveCounter;
mega64 146:03e976389d16 26 extern volatile uint32_t oc_int_part;
mega64 146:03e976389d16 27 extern volatile uint16_t oc_rem_part;
mega64 146:03e976389d16 28 extern volatile uint8_t tim_it_update;
mega64 146:03e976389d16 29 extern volatile uint32_t tim_it_counter;
mega64 146:03e976389d16 30
mega64 146:03e976389d16 31 volatile uint32_t PreviousVal = 0;
mega64 146:03e976389d16 32
mega64 146:03e976389d16 33 void us_ticker_irq_handler(void);
mega64 146:03e976389d16 34 void set_compare(uint16_t count);
mega64 146:03e976389d16 35
mega64 146:03e976389d16 36 #if defined(TARGET_STM32F0)
mega64 146:03e976389d16 37 void timer_update_irq_handler(void) {
mega64 146:03e976389d16 38 #else
mega64 146:03e976389d16 39 void timer_irq_handler(void)
mega64 146:03e976389d16 40 {
mega64 146:03e976389d16 41 #endif
mega64 146:03e976389d16 42 uint16_t cnt_val = TIM_MST->CNT;
mega64 146:03e976389d16 43 TimMasterHandle.Instance = TIM_MST;
mega64 146:03e976389d16 44
mega64 146:03e976389d16 45 // Clear Update interrupt flag
mega64 146:03e976389d16 46 if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_UPDATE) == SET) {
mega64 146:03e976389d16 47 if (__HAL_TIM_GET_IT_SOURCE(&TimMasterHandle, TIM_IT_UPDATE) == SET) {
mega64 146:03e976389d16 48 __HAL_TIM_CLEAR_IT(&TimMasterHandle, TIM_IT_UPDATE);
mega64 146:03e976389d16 49 SlaveCounter++;
mega64 146:03e976389d16 50 tim_it_counter = cnt_val + (uint32_t)(SlaveCounter << 16);
mega64 146:03e976389d16 51 tim_it_update = 1;
mega64 146:03e976389d16 52 }
mega64 146:03e976389d16 53 }
mega64 146:03e976389d16 54
mega64 146:03e976389d16 55 #if defined(TARGET_STM32F0)
mega64 146:03e976389d16 56 } // end timer_update_irq_handler function
mega64 146:03e976389d16 57 // Used for mbed timeout (channel 1) and HAL tick (channel 2)
mega64 146:03e976389d16 58 void timer_oc_irq_handler(void)
mega64 146:03e976389d16 59 {
mega64 146:03e976389d16 60 uint16_t cnt_val = TIM_MST->CNT;
mega64 146:03e976389d16 61 TimMasterHandle.Instance = TIM_MST;
mega64 146:03e976389d16 62 #endif
mega64 146:03e976389d16 63
mega64 146:03e976389d16 64 // Channel 1 for mbed timeout
mega64 146:03e976389d16 65 if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_CC1) == SET) {
mega64 146:03e976389d16 66 if (__HAL_TIM_GET_IT_SOURCE(&TimMasterHandle, TIM_IT_CC1) == SET) {
mega64 146:03e976389d16 67 __HAL_TIM_CLEAR_IT(&TimMasterHandle, TIM_IT_CC1);
mega64 146:03e976389d16 68 if (oc_rem_part > 0) {
mega64 146:03e976389d16 69 set_compare(oc_rem_part); // Finish the remaining time left
mega64 146:03e976389d16 70 oc_rem_part = 0;
mega64 146:03e976389d16 71 } else {
mega64 146:03e976389d16 72 if (oc_int_part > 0) {
mega64 146:03e976389d16 73 set_compare(0xFFFF);
mega64 146:03e976389d16 74 oc_rem_part = cnt_val; // To finish the counter loop the next time
mega64 146:03e976389d16 75 oc_int_part--;
mega64 146:03e976389d16 76 } else {
mega64 146:03e976389d16 77 us_ticker_irq_handler();
mega64 146:03e976389d16 78 }
mega64 146:03e976389d16 79 }
mega64 146:03e976389d16 80 }
mega64 146:03e976389d16 81 }
mega64 146:03e976389d16 82
mega64 146:03e976389d16 83 // Channel 2 for HAL tick
mega64 146:03e976389d16 84 if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_CC2) == SET) {
mega64 146:03e976389d16 85 if (__HAL_TIM_GET_IT_SOURCE(&TimMasterHandle, TIM_IT_CC2) == SET) {
mega64 146:03e976389d16 86 __HAL_TIM_CLEAR_IT(&TimMasterHandle, TIM_IT_CC2);
mega64 146:03e976389d16 87 uint32_t val = __HAL_TIM_GetCounter(&TimMasterHandle);
mega64 146:03e976389d16 88 if ((val - PreviousVal) >= HAL_TICK_DELAY) {
mega64 146:03e976389d16 89 // Increment HAL variable
mega64 146:03e976389d16 90 HAL_IncTick();
mega64 146:03e976389d16 91 // Prepare next interrupt
mega64 146:03e976389d16 92 __HAL_TIM_SetCompare(&TimMasterHandle, TIM_CHANNEL_2, val + HAL_TICK_DELAY);
mega64 146:03e976389d16 93 PreviousVal = val;
mega64 146:03e976389d16 94 #if DEBUG_TICK > 0
mega64 146:03e976389d16 95 HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_6);
mega64 146:03e976389d16 96 #endif
mega64 146:03e976389d16 97 }
mega64 146:03e976389d16 98 }
mega64 146:03e976389d16 99 }
mega64 146:03e976389d16 100 }
mega64 146:03e976389d16 101
mega64 146:03e976389d16 102 // Reconfigure the HAL tick using a standard timer instead of systick.
mega64 146:03e976389d16 103 HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
mega64 146:03e976389d16 104 {
mega64 146:03e976389d16 105 // Enable timer clock
mega64 146:03e976389d16 106 TIM_MST_RCC;
mega64 146:03e976389d16 107
mega64 146:03e976389d16 108 // Reset timer
mega64 146:03e976389d16 109 TIM_MST_RESET_ON;
mega64 146:03e976389d16 110 TIM_MST_RESET_OFF;
mega64 146:03e976389d16 111
mega64 146:03e976389d16 112 // Update the SystemCoreClock variable
mega64 146:03e976389d16 113 SystemCoreClockUpdate();
mega64 146:03e976389d16 114
mega64 146:03e976389d16 115 // Configure time base
mega64 146:03e976389d16 116 TimMasterHandle.Instance = TIM_MST;
mega64 146:03e976389d16 117 TimMasterHandle.Init.Period = 0xFFFF;
mega64 146:03e976389d16 118 TimMasterHandle.Init.Prescaler = (uint32_t)(SystemCoreClock / 1000000) - 1; // 1 us tick
mega64 146:03e976389d16 119 TimMasterHandle.Init.ClockDivision = 0;
mega64 146:03e976389d16 120 TimMasterHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
mega64 146:03e976389d16 121 #ifdef TARGET_STM32F0
mega64 146:03e976389d16 122 TimMasterHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
mega64 146:03e976389d16 123 #endif
mega64 146:03e976389d16 124 HAL_TIM_Base_Init(&TimMasterHandle);
mega64 146:03e976389d16 125
mega64 146:03e976389d16 126 // Configure output compare channel 1 for mbed timeout (enabled later when used)
mega64 146:03e976389d16 127 HAL_TIM_OC_Start(&TimMasterHandle, TIM_CHANNEL_1);
mega64 146:03e976389d16 128
mega64 146:03e976389d16 129 // Configure output compare channel 2 for HAL tick
mega64 146:03e976389d16 130 HAL_TIM_OC_Start(&TimMasterHandle, TIM_CHANNEL_2);
mega64 146:03e976389d16 131 PreviousVal = __HAL_TIM_GetCounter(&TimMasterHandle);
mega64 146:03e976389d16 132 __HAL_TIM_SetCompare(&TimMasterHandle, TIM_CHANNEL_2, PreviousVal + HAL_TICK_DELAY);
mega64 146:03e976389d16 133
mega64 146:03e976389d16 134 // Configure interrupts
mega64 146:03e976389d16 135 // Update interrupt used for 32-bit counter
mega64 146:03e976389d16 136 // Output compare channel 1 interrupt for mbed timeout
mega64 146:03e976389d16 137 // Output compare channel 2 interrupt for HAL tick
mega64 146:03e976389d16 138 #if defined(TARGET_STM32F0)
mega64 146:03e976389d16 139 NVIC_SetVector(TIM_MST_UP_IRQ, (uint32_t)timer_update_irq_handler);
mega64 146:03e976389d16 140 NVIC_EnableIRQ(TIM_MST_UP_IRQ);
mega64 146:03e976389d16 141 NVIC_SetPriority(TIM_MST_UP_IRQ, 0);
mega64 146:03e976389d16 142 NVIC_SetVector(TIM_MST_OC_IRQ, (uint32_t)timer_oc_irq_handler);
mega64 146:03e976389d16 143 NVIC_EnableIRQ(TIM_MST_OC_IRQ);
mega64 146:03e976389d16 144 NVIC_SetPriority(TIM_MST_OC_IRQ, 1);
mega64 146:03e976389d16 145 #else
mega64 146:03e976389d16 146 NVIC_SetVector(TIM_MST_IRQ, (uint32_t)timer_irq_handler);
mega64 146:03e976389d16 147 NVIC_EnableIRQ(TIM_MST_IRQ);
mega64 146:03e976389d16 148 #endif
mega64 146:03e976389d16 149
mega64 146:03e976389d16 150 // Enable interrupts
mega64 146:03e976389d16 151 __HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_UPDATE); // For 32-bit counter
mega64 146:03e976389d16 152 __HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_CC2); // For HAL tick
mega64 146:03e976389d16 153
mega64 146:03e976389d16 154 // Enable timer
mega64 146:03e976389d16 155 HAL_TIM_Base_Start(&TimMasterHandle);
mega64 146:03e976389d16 156
mega64 146:03e976389d16 157 #if DEBUG_TICK > 0
mega64 146:03e976389d16 158 __GPIOB_CLK_ENABLE();
mega64 146:03e976389d16 159 GPIO_InitTypeDef GPIO_InitStruct;
mega64 146:03e976389d16 160 GPIO_InitStruct.Pin = GPIO_PIN_6;
mega64 146:03e976389d16 161 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
mega64 146:03e976389d16 162 GPIO_InitStruct.Pull = GPIO_PULLUP;
mega64 146:03e976389d16 163 GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
mega64 146:03e976389d16 164 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
mega64 146:03e976389d16 165 #endif
mega64 146:03e976389d16 166
mega64 146:03e976389d16 167 return HAL_OK;
mega64 146:03e976389d16 168 }
mega64 146:03e976389d16 169
mega64 146:03e976389d16 170 void HAL_SuspendTick(void)
mega64 146:03e976389d16 171 {
mega64 146:03e976389d16 172 TimMasterHandle.Instance = TIM_MST;
mega64 146:03e976389d16 173 __HAL_TIM_DISABLE_IT(&TimMasterHandle, TIM_IT_CC2);
mega64 146:03e976389d16 174 }
mega64 146:03e976389d16 175
mega64 146:03e976389d16 176 void HAL_ResumeTick(void)
mega64 146:03e976389d16 177 {
mega64 146:03e976389d16 178 TimMasterHandle.Instance = TIM_MST;
mega64 146:03e976389d16 179 __HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_CC2);
mega64 146:03e976389d16 180 }
mega64 146:03e976389d16 181
mega64 146:03e976389d16 182 #endif // TIM_MST_16BIT