diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_F030R8/stm32f0xx.h b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_F030R8/stm32f0xx.h index e0d005eb59..249af8a0b6 100644 --- a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_F030R8/stm32f0xx.h +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_F030R8/stm32f0xx.h @@ -137,7 +137,7 @@ Timeout value */ #if !defined (HSE_STARTUP_TIMEOUT) -#define HSE_STARTUP_TIMEOUT ((uint16_t)0x5000) /*!< Time out for HSE start up */ +#define HSE_STARTUP_TIMEOUT ((uint16_t)1000) /*!< Time out for HSE start up */ #endif /* HSE_STARTUP_TIMEOUT */ /** diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_F030R8/system_stm32f0xx.c b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_F030R8/system_stm32f0xx.c index 4b65d8b2c8..41d25f3234 100644 --- a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_F030R8/system_stm32f0xx.c +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_F030R8/system_stm32f0xx.c @@ -40,27 +40,17 @@ * value to your own configuration. * * 5. This file configures the system clock as follows: - *============================================================================= - *============================================================================= - * System Clock source | HSI *----------------------------------------------------------------------------- - * SYSCLK(Hz) | 8000000 + * System clock source | 1- PLL_HSE_EXTC | 3- PLL_HSI + * | (external 8 MHz clock) | (internal 8 MHz) + * | 2- PLL_HSE_XTAL | + * | (external 8 MHz xtal) | *----------------------------------------------------------------------------- - * HCLK(Hz) | 8000000 + * SYSCLK(MHz) | 48 | 48 *----------------------------------------------------------------------------- - * AHB Prescaler | 1 + * AHBCLK (MHz) | 48 | 48 *----------------------------------------------------------------------------- - * APB Prescaler | 1 - *----------------------------------------------------------------------------- - * HSE Frequency(Hz) | NA - *---------------------------------------------------------------------------- - * PLLMUL | NA - *----------------------------------------------------------------------------- - * PREDIV | NA - *----------------------------------------------------------------------------- - * Flash Latency(WS) | 0 - *----------------------------------------------------------------------------- - * Prefetch Buffer | ON + * APBCLK (MHz) | 48 | 48 *----------------------------------------------------------------------------- ****************************************************************************** * @attention @@ -129,6 +119,10 @@ * @{ */ +/* Select the clock sources (other than HSI) to start with (0=OFF, 1=ON) */ +#define USE_PLL_HSE_EXTC (1) /* Use external clock */ +#define USE_PLL_HSE_XTAL (1) /* Use external xtal */ + /** * @} */ @@ -136,7 +130,8 @@ /** @addtogroup STM32F0xx_System_Private_Variables * @{ */ -uint32_t SystemCoreClock = 8000000; + +uint32_t SystemCoreClock = 48000000; __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; /** @@ -147,7 +142,11 @@ __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9} * @{ */ -static void SetSysClock(void); +#if (USE_PLL_HSE_XTAL != 0) || (USE_PLL_HSE_EXTC != 0) +uint8_t SetSysClock_PLL_HSE(uint8_t bypass); +#endif + +uint8_t SetSysClock_PLL_HSI(void); /** * @} @@ -192,9 +191,6 @@ void SystemInit (void) /* Disable all interrupts */ RCC->CIR = 0x00000000; - - /* Configure the System clock frequency, AHB/APBx prescalers and Flash settings */ - SetSysClock(); } /** @@ -277,30 +273,155 @@ void SystemCoreClockUpdate (void) } /** - * @brief Configures the System clock frequency, AHB/APBx prescalers and Flash - * settings. - * @note This function should be called only once the RCC clock configuration - * is reset to the default reset state (done in SystemInit() function). + * @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers. * @param None * @retval None */ -static void SetSysClock(void) +void SetSysClock(void) { + /* 1- Try to start with HSE and external clock */ +#if USE_PLL_HSE_EXTC != 0 + if (SetSysClock_PLL_HSE(1) == 0) +#endif + { + /* 2- If fail try to start with HSE and external xtal */ + #if USE_PLL_HSE_XTAL != 0 + if (SetSysClock_PLL_HSE(0) == 0) + #endif + { + /* 3- If fail start with HSI clock */ + if (SetSysClock_PLL_HSI() == 0) + { + while(1) + { + // [TODO] Put something here to tell the user that a problem occured... + } + } + } + } + + // Output clock on MCO pin (PA8) for debugging purpose + /* + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; + GPIO_Init(GPIOA, &GPIO_InitStructure); + GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_0); + // Output clock on MCO pin + // Warning: only RCC_MCOPrescaler_1 is available on STM32F030x8 devices + RCC_MCOConfig(RCC_MCOSource_SYSCLK, RCC_MCOPrescaler_1); + */ +} + +#if (USE_PLL_HSE_XTAL != 0) || (USE_PLL_HSE_EXTC != 0) /******************************************************************************/ -/* HSI used as System clock source */ +/* PLL (clocked by HSE) used as System clock source */ /******************************************************************************/ +uint8_t SetSysClock_PLL_HSE(uint8_t bypass) +{ + __IO uint32_t StartUpCounter = 0; + __IO uint32_t HSEStatus = 0; - /* At this stage the HSI is already enabled and used as System clock source */ + /* Bypass HSE: can be done only if HSE is OFF */ + RCC->CR &= ((uint32_t)~RCC_CR_HSEON); /* To be sure HSE is OFF */ + if (bypass != 0) + { + RCC->CR |= ((uint32_t)RCC_CR_HSEBYP); + } + else + { + RCC->CR &= ((uint32_t)~RCC_CR_HSEBYP); + } + + /* Enable HSE */ + RCC->CR |= ((uint32_t)RCC_CR_HSEON); + + /* Wait till HSE is ready */ + do + { + HSEStatus = RCC->CR & RCC_CR_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); - /* Enable Prefetch Buffer and Flash 0 wait state */ - FLASH->ACR = FLASH_ACR_PRFTBE; + /* Check if HSE has started correctly */ + if ((RCC->CR & RCC_CR_HSERDY) != RESET) + { + /* Enable Prefetch Buffer */ + FLASH->ACR |= FLASH_ACR_PRFTBE; - /* HCLK = SYSCLK / 1 */ - RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; + /* Enable Prefetch Buffer and set Flash Latency */ + FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY; - /* PCLK = HCLK / 1 */ - RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE_DIV1; + /* PLL configuration + PLLCLK = 48 MHz (xtal 8 MHz * 6) */ + RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); + RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLMULL6 + | RCC_CFGR_HPRE_DIV1 /* HCLK = 48 MHz */ + | RCC_CFGR_PPRE_DIV1); /* PCLK = 48 MHz */ + + /* Enable PLL */ + RCC->CR |= RCC_CR_PLLON; + /* Wait till PLL is ready */ + while((RCC->CR & RCC_CR_PLLRDY) == 0) + { + } + + /* Select PLL as system clock source */ + RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); + RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; + + /* Wait till PLL is used as system clock source */ + while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL) + { + } + + return 1; // OK + } + else + { + return 0; // FAIL + } +} +#endif + +/******************************************************************************/ +/* PLL (clocked by HSI) used as System clock source */ +/******************************************************************************/ +uint8_t SetSysClock_PLL_HSI(void) +{ + /* Enable Prefetch Buffer and set Flash Latency */ + FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY; + + /* PLL configuration + PLLCLK = 48 MHz ((HSI 8 MHz / 2) * 12) */ + RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); + RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSI_Div2 | RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLMULL12 + | RCC_CFGR_HPRE_DIV1 /* HCLK = 48 MHz */ + | RCC_CFGR_PPRE_DIV1); /* PCLK = 48 MHz */ + + /* Enable PLL */ + RCC->CR |= RCC_CR_PLLON; + + /* Wait till PLL is ready */ + while((RCC->CR & RCC_CR_PLLRDY) == 0) + { + } + + /* Select PLL as system clock source */ + RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); + RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; + + /* Wait till PLL is used as system clock source */ + while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL) + { + } + + return 1; // OK } /** diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_F030R8/system_stm32f0xx.h b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_F030R8/system_stm32f0xx.h index 78d9460404..36b2445353 100644 --- a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_F030R8/system_stm32f0xx.h +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_F030R8/system_stm32f0xx.h @@ -94,6 +94,8 @@ extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Cloc extern void SystemInit(void); extern void SystemCoreClockUpdate(void); +extern void SetSysClock(void); + /** * @} */ diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/analogin_api.c b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/analogin_api.c index 82700338f4..8c68293d06 100644 --- a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/analogin_api.c +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/analogin_api.c @@ -26,13 +26,13 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "analogin_api.h" -#include "wait_api.h" #if DEVICE_ANALOGIN #include "cmsis.h" #include "pinmap.h" #include "error.h" +#include "wait_api.h" static const PinMap PinMap_ADC[] = { {PA_0, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN0 diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/i2c_api.c b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/i2c_api.c index 913a704c2e..a69e6fd66e 100644 --- a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/i2c_api.c +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/i2c_api.c @@ -86,31 +86,59 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) { void i2c_frequency(i2c_t *obj, int hz) { I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); I2C_InitTypeDef I2C_InitStructure; + uint32_t tim = 0; + + // Disable the Fast Mode Plus capability + RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); // Enable SYSCFG clock + SYSCFG_I2CFastModePlusConfig(SYSCFG_I2CFastModePlus_I2C1, DISABLE); + SYSCFG_I2CFastModePlusConfig(SYSCFG_I2CFastModePlus_I2C2, DISABLE); - // Values calculated with I2C_Timing_Configuration_V1.0.1.xls file (see AN4235) - // with Rise time = 100ns and Fall time = 10ns + /* + Values calculated with I2C_Timing_Configuration_V1.0.1.xls file (see AN4235) + * Standard mode (up to 100 kHz) + * Fast Mode (up to 400 kHz) + * Fast Mode Plus (up to 1 MHz) + Below values obtained with: + - I2C clock source = 8 MHz (HSI clock per default) + - Analog filter delay = ON + - Digital filter coefficient = 0 + - Rise time = 100 ns + - Fall time = 10ns + */ switch (hz) { case 100000: - I2C_InitStructure.I2C_Timing = 0x00201D2B; // Standard mode + tim = 0x00201D2B; // Standard mode break; case 200000: - I2C_InitStructure.I2C_Timing = 0x0010021E; // Fast mode + tim = 0x0010021E; // Fast Mode break; case 400000: - I2C_InitStructure.I2C_Timing = 0x0010020A; // Fast mode + tim = 0x0010020A; // Fast Mode + break; + case 1000000: + tim = 0x00100001; // Fast Mode Plus + // Enable the Fast Mode Plus capability + if (obj->i2c == I2C_1) { + SYSCFG_I2CFastModePlusConfig(SYSCFG_I2CFastModePlus_I2C1, ENABLE); + } + if (obj->i2c == I2C_2) { + SYSCFG_I2CFastModePlusConfig(SYSCFG_I2CFastModePlus_I2C2, ENABLE); + } break; default: - error("Only 100kHz, 200kHz and 400kHz I2C frequencies are supported."); + error("Only 100kHz, 200kHz, 400kHz and 1MHz I2C frequencies are supported."); break; } // I2C configuration + I2C_DeInit(i2c); I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable; I2C_InitStructure.I2C_DigitalFilter = 0x00; I2C_InitStructure.I2C_OwnAddress1 = 0x00; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; + I2C_InitStructure.I2C_Timing = tim; I2C_Init(i2c, &I2C_InitStructure); I2C_Cmd(i2c, ENABLE); diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/mbed_overrides.c b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/mbed_overrides.c new file mode 100644 index 0000000000..428930beba --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/mbed_overrides.c @@ -0,0 +1,38 @@ +/* mbed Microcontroller Library + * Copyright (c) 2014, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "stm32f0xx.h" + +// This function is called after RAM initialization and before main. +void mbed_sdk_init() { + /* Configure the System clock source, PLL Multiplier and Divider factors, + AHB/APBx prescalers and Flash settings */ + SetSysClock(); + + // Update the SystemCoreClock variable. + SystemCoreClockUpdate(); +} diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/port_api.c b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/port_api.c index 7ac6b29095..3549b81e33 100644 --- a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/port_api.c +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/port_api.c @@ -28,12 +28,13 @@ ******************************************************************************* */ #include "port_api.h" + +#if DEVICE_PORTIN || DEVICE_PORTOUT + #include "pinmap.h" #include "gpio_api.h" #include "error.h" -#if DEVICE_PORTIN || DEVICE_PORTOUT - extern uint32_t Set_GPIO_Clock(uint32_t port_idx); // high nibble = port number (0=A, 1=B, 2=C, 3=D, 4=E, 5=F, ...) diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/pwmout_api.c b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/pwmout_api.c index 562a54c185..6b6da8dccf 100644 --- a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/pwmout_api.c +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/pwmout_api.c @@ -29,6 +29,8 @@ */ #include "pwmout_api.h" +#if DEVICE_PWMOUT + #include "cmsis.h" #include "pinmap.h" #include "error.h" @@ -214,3 +216,5 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us) { float value = (float)us / (float)obj->period; pwmout_write(obj, value); } + +#endif diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/rtc_api.c b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/rtc_api.c index 351df098aa..4792ba8004 100644 --- a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/rtc_api.c +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/rtc_api.c @@ -29,35 +29,63 @@ */ #include "rtc_api.h" +#if DEVICE_RTC + +#include "wait_api.h" + +#define LSE_STARTUP_TIMEOUT ((uint16_t)500) // delay in ms + static int rtc_inited = 0; void rtc_init(void) { + uint32_t StartUpCounter = 0; + uint32_t LSEStatus = 0; + uint32_t rtc_freq = 0; + RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); // Enable PWR clock - PWR_BackupAccessCmd(ENABLE); // Enable access to RTC + PWR_BackupAccessCmd(ENABLE); // Enable access to Backup domain - // Note: the LSI is used as RTC source clock - // The RTC Clock may vary due to LSI frequency dispersion. - - RCC_LSICmd(ENABLE); // Enable LSI + // Reset back up registers + RCC_BackupResetCmd(ENABLE); + RCC_BackupResetCmd(DISABLE); - while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET) {} // Wait until ready - - RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); // Select LSI as RTC Clock Source + // Enable LSE clock + RCC_LSEConfig(RCC_LSE_ON); + + // Wait till LSE is ready + do { + LSEStatus = RCC_GetFlagStatus(RCC_FLAG_LSERDY); + wait_ms(1); + StartUpCounter++; + } while((LSEStatus == 0) && (StartUpCounter <= LSE_STARTUP_TIMEOUT)); + + if (StartUpCounter > LSE_STARTUP_TIMEOUT) { + // The LSE has not started, use LSI instead. + // The RTC Clock may vary due to LSI frequency dispersion. + RCC_LSEConfig(RCC_LSE_OFF); + RCC_LSICmd(ENABLE); // Enable LSI + while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET) {} // Wait until ready + RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); // Select the RTC Clock Source + rtc_freq = 40000; // [TODO] To be measured precisely using a timer input capture + } + else { + // The LSE has correctly started + RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); // Select the RTC Clock Source + rtc_freq = LSE_VALUE; + } RCC_RTCCLKCmd(ENABLE); // Enable RTC Clock RTC_WaitForSynchro(); // Wait for RTC registers synchronization - uint32_t lsi_freq = 40000; // *** TODO** To be measured precisely using a timer input capture - RTC_InitTypeDef RTC_InitStructure; RTC_InitStructure.RTC_AsynchPrediv = 127; - RTC_InitStructure.RTC_SynchPrediv = (lsi_freq / 128) - 1; + RTC_InitStructure.RTC_SynchPrediv = (rtc_freq / 128) - 1; RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24; RTC_Init(&RTC_InitStructure); - PWR_BackupAccessCmd(DISABLE); // Disable access to RTC + PWR_BackupAccessCmd(DISABLE); // Disable access to Backup domain rtc_inited = 1; } @@ -135,3 +163,5 @@ void rtc_write(time_t t) { RTC_SetTime(RTC_Format_BIN, &timeStruct); PWR_BackupAccessCmd(DISABLE); // Disable access to RTC } + +#endif diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/serial_api.c b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/serial_api.c index d6472838ed..63027e8c04 100644 --- a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/serial_api.c +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/serial_api.c @@ -28,6 +28,9 @@ ******************************************************************************* */ #include "serial_api.h" + +#if DEVICE_SERIAL + #include "cmsis.h" #include "pinmap.h" #include "error.h" @@ -281,3 +284,5 @@ void serial_break_set(serial_t *obj) { void serial_break_clear(serial_t *obj) { } + +#endif diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/sleep.c b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/sleep.c index 2399412e6f..d18f7c06cb 100644 --- a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/sleep.c +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/sleep.c @@ -28,6 +28,9 @@ ******************************************************************************* */ #include "sleep_api.h" + +#if DEVICE_SLEEP + #include "cmsis.h" void sleep(void) @@ -51,4 +54,9 @@ void deepsleep(void) // Request to enter STOP mode with regulator in low power mode PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI); + + // After wake-up from STOP reconfigure the PLL + SetSysClock(); } + +#endif diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/spi_api.c b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/spi_api.c index 42cbc4c897..2bc6e3ed04 100644 --- a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/spi_api.c +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/spi_api.c @@ -173,26 +173,31 @@ void spi_format(spi_t *obj, int bits, int mode, int slave) { } void spi_frequency(spi_t *obj, int hz) { - // Get SPI clock frequency - uint32_t PCLK = SystemCoreClock; - - // Choose the baud rate divisor (between 2 and 256) - uint32_t divisor = PCLK / hz; - - // Find the nearest power-of-2 - divisor = (divisor > 0 ? divisor-1 : 0); - divisor |= divisor >> 1; - divisor |= divisor >> 2; - divisor |= divisor >> 4; - divisor |= divisor >> 8; - divisor |= divisor >> 16; - divisor++; - - uint32_t baud_rate = __builtin_ffs(divisor) - 2; - - // Save new value - obj->br_presc = ((baud_rate > 7) ? (7 << 3) : (baud_rate << 3)); - + // Note: The frequencies are obtained with SPI clock = 48 MHz (APB1 & APB2 clocks) + if (hz < 300000) { + obj->br_presc = SPI_BaudRatePrescaler_256; // 188 kHz + } + else if ((hz >= 300000) && (hz < 700000)) { + obj->br_presc = SPI_BaudRatePrescaler_128; // 375 kHz + } + else if ((hz >= 700000) && (hz < 1000000)) { + obj->br_presc = SPI_BaudRatePrescaler_64; // 750 kHz + } + else if ((hz >= 1000000) && (hz < 3000000)) { + obj->br_presc = SPI_BaudRatePrescaler_32; // 1.5 MHz + } + else if ((hz >= 3000000) && (hz < 6000000)) { + obj->br_presc = SPI_BaudRatePrescaler_16; // 3 MHz + } + else if ((hz >= 6000000) && (hz < 12000000)) { + obj->br_presc = SPI_BaudRatePrescaler_8; // 6 MHz + } + else if ((hz >= 12000000) && (hz < 24000000)) { + obj->br_presc = SPI_BaudRatePrescaler_4; // 12 MHz + } + else { // >= 24000000 + obj->br_presc = SPI_BaudRatePrescaler_2; // 24 MHz + } init_spi(obj); } @@ -215,19 +220,23 @@ static inline int ssp_writeable(spi_t *obj) { static inline void ssp_write(spi_t *obj, int value) { SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); while (!ssp_writeable(obj)); - if(obj->bits == SPI_DataSize_8b) // 8 bit mode - SPI_SendData8(spi, (uint8_t)value); - else - SPI_I2S_SendData16(spi, (uint16_t)value); + if (obj->bits == SPI_DataSize_8b) { + SPI_SendData8(spi, (uint8_t)value); + } + else { // 16-bit + SPI_I2S_SendData16(spi, (uint16_t)value); + } } static inline int ssp_read(spi_t *obj) { SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); while (!ssp_readable(obj)); - if(obj->bits == SPI_DataSize_8b) // 8 bit mode - return (int)SPI_ReceiveData8(spi); - else // 16 bit mode - return (int)SPI_I2S_ReceiveData16(spi); + if (obj->bits == SPI_DataSize_8b) { + return (int)SPI_ReceiveData8(spi); + } + else { // 16-bit + return (int)SPI_I2S_ReceiveData16(spi); + } } static inline int ssp_busy(spi_t *obj) { @@ -248,19 +257,23 @@ int spi_slave_receive(spi_t *obj) { int spi_slave_read(spi_t *obj) { SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - if(obj->bits == SPI_DataSize_8b) // 8 bit mode - return (int)SPI_ReceiveData8(spi); - else - return (int)SPI_I2S_ReceiveData16(spi); + if (obj->bits == SPI_DataSize_8b) { + return (int)SPI_ReceiveData8(spi); + } + else { // 16-bit + return (int)SPI_I2S_ReceiveData16(spi); + } } void spi_slave_write(spi_t *obj, int value) { SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); - while (!ssp_writeable(obj)); - if(obj->bits == SPI_DataSize_8b) // 8 bit mode - SPI_SendData8(spi, (uint8_t)value); - else - SPI_I2S_SendData16(spi, (uint16_t)value); + while (!ssp_writeable(obj)); + if (obj->bits == SPI_DataSize_8b) { + SPI_SendData8(spi, (uint8_t)value); + } + else { // 16-bit + SPI_I2S_SendData16(spi, (uint16_t)value); + } } int spi_busy(spi_t *obj) {