mbed library sources

Dependents:   Encrypted my_mbed lklk CyaSSL_DTLS_Cellular ... more

Superseded

This library was superseded by mbed-dev - https://os.mbed.com/users/mbed_official/code/mbed-dev/.

Development branch of the mbed library sources. This library is kept in synch with the latest changes from the mbed SDK and it is not guaranteed to work.

If you are looking for a stable and tested release, please import one of the official mbed library releases:

Import librarymbed

The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.

Files at this revision

API Documentation at this revision

Comitter:
mbed_official
Date:
Tue Apr 22 16:00:06 2014 +0100
Parent:
165:46e3636d4af7
Child:
167:d5744491c362
Commit message:
Synchronized with git revision a519f94f35c3993310499623be5c28f74b80485c

Full URL: https://github.com/mbedmicro/mbed/commit/a519f94f35c3993310499623be5c28f74b80485c/

[NUCLEO_F030R8] Many improvements added

Changed in this revision

targets/cmsis/TARGET_STM/TARGET_NUCLEO_F030R8/stm32f0xx.h Show annotated file Show diff for this revision Revisions of this file
targets/cmsis/TARGET_STM/TARGET_NUCLEO_F030R8/system_stm32f0xx.c Show annotated file Show diff for this revision Revisions of this file
targets/cmsis/TARGET_STM/TARGET_NUCLEO_F030R8/system_stm32f0xx.h Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/analogin_api.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/i2c_api.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/mbed_overrides.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/port_api.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/pwmout_api.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/rtc_api.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/serial_api.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/sleep.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/spi_api.c Show annotated file Show diff for this revision Revisions of this file
--- a/targets/cmsis/TARGET_STM/TARGET_NUCLEO_F030R8/stm32f0xx.h	Tue Apr 22 15:00:07 2014 +0100
+++ b/targets/cmsis/TARGET_STM/TARGET_NUCLEO_F030R8/stm32f0xx.h	Tue Apr 22 16:00:06 2014 +0100
@@ -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 */
 
 /**
--- a/targets/cmsis/TARGET_STM/TARGET_NUCLEO_F030R8/system_stm32f0xx.c	Tue Apr 22 15:00:07 2014 +0100
+++ b/targets/cmsis/TARGET_STM/TARGET_NUCLEO_F030R8/system_stm32f0xx.c	Tue Apr 22 16:00:06 2014 +0100
@@ -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
-  *-----------------------------------------------------------------------------
-  *        HCLK(Hz)                               | 8000000
-  *-----------------------------------------------------------------------------
-  *        AHB Prescaler                          | 1
+  * 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)  |
   *-----------------------------------------------------------------------------
-  *        APB Prescaler                          | 1
-  *-----------------------------------------------------------------------------
-  *        HSE Frequency(Hz)                      | NA
-  *----------------------------------------------------------------------------
-  *        PLLMUL                                 | NA
+  * SYSCLK(MHz)                        | 48                     | 48
   *-----------------------------------------------------------------------------
-  *        PREDIV                                 | NA
+  * AHBCLK (MHz)                       | 48                     | 48
   *-----------------------------------------------------------------------------
-  *        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 @@
   * @{
   */
 
-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 @@
 
   /* Disable all interrupts */
   RCC->CIR = 0x00000000;
-
-  /* Configure the System clock frequency, AHB/APBx prescalers and Flash settings */
-  SetSysClock();
 }
 
 /**
@@ -277,30 +273,155 @@
 }
 
 /**
-  * @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;
+
+    /* Enable Prefetch Buffer and set Flash Latency */
+    FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY; 
+
+    /* 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)
+    {
+    }
 
-     /* HCLK = SYSCLK / 1 */
-     RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
+    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;
 
-     /* PCLK = HCLK / 1 */
-     RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE_DIV1;
+  /* 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
 }
 
 /**
--- a/targets/cmsis/TARGET_STM/TARGET_NUCLEO_F030R8/system_stm32f0xx.h	Tue Apr 22 15:00:07 2014 +0100
+++ b/targets/cmsis/TARGET_STM/TARGET_NUCLEO_F030R8/system_stm32f0xx.h	Tue Apr 22 16:00:06 2014 +0100
@@ -94,6 +94,8 @@
   
 extern void SystemInit(void);
 extern void SystemCoreClockUpdate(void);
+extern void SetSysClock(void);
+
 /**
   * @}
   */
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/analogin_api.c	Tue Apr 22 15:00:07 2014 +0100
+++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/analogin_api.c	Tue Apr 22 16:00:06 2014 +0100
@@ -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
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/i2c_api.c	Tue Apr 22 15:00:07 2014 +0100
+++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/i2c_api.c	Tue Apr 22 16:00:06 2014 +0100
@@ -86,31 +86,59 @@
 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);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/mbed_overrides.c	Tue Apr 22 16:00:06 2014 +0100
@@ -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();
+}
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/port_api.c	Tue Apr 22 15:00:07 2014 +0100
+++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/port_api.c	Tue Apr 22 16:00:06 2014 +0100
@@ -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, ...)
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/pwmout_api.c	Tue Apr 22 15:00:07 2014 +0100
+++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/pwmout_api.c	Tue Apr 22 16:00:06 2014 +0100
@@ -29,6 +29,8 @@
  */
 #include "pwmout_api.h"
 
+#if DEVICE_PWMOUT
+
 #include "cmsis.h"
 #include "pinmap.h"
 #include "error.h"
@@ -214,3 +216,5 @@
     float value = (float)us / (float)obj->period;
     pwmout_write(obj, value);
 }
+
+#endif
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/rtc_api.c	Tue Apr 22 15:00:07 2014 +0100
+++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/rtc_api.c	Tue Apr 22 16:00:06 2014 +0100
@@ -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
+
+    // Reset back up registers
+    RCC_BackupResetCmd(ENABLE);
+    RCC_BackupResetCmd(DISABLE);
+  
+    // Enable LSE clock
+    RCC_LSEConfig(RCC_LSE_ON);
 
-    // Note: the LSI is used as RTC source clock
-    // The RTC Clock may vary due to LSI frequency dispersion.  
-   
-    RCC_LSICmd(ENABLE); // Enable LSI
-  
-    while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET) {} // Wait until ready
-    
-    RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); // Select LSI as RTC Clock Source
+    // 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 @@
     RTC_SetTime(RTC_Format_BIN, &timeStruct);    
     PWR_BackupAccessCmd(DISABLE); // Disable access to RTC
 }
+
+#endif
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/serial_api.c	Tue Apr 22 15:00:07 2014 +0100
+++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/serial_api.c	Tue Apr 22 16:00:06 2014 +0100
@@ -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_clear(serial_t *obj) {
 }
+
+#endif
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/sleep.c	Tue Apr 22 15:00:07 2014 +0100
+++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/sleep.c	Tue Apr 22 16:00:06 2014 +0100
@@ -28,6 +28,9 @@
  *******************************************************************************
  */
 #include "sleep_api.h"
+
+#if DEVICE_SLEEP
+
 #include "cmsis.h"
 
 void sleep(void)
@@ -51,4 +54,9 @@
     
     // 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
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/spi_api.c	Tue Apr 22 15:00:07 2014 +0100
+++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/spi_api.c	Tue Apr 22 16:00:06 2014 +0100
@@ -173,26 +173,31 @@
 }
 
 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 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_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) {