mbed library sources

Fork of mbed-src by mbed official

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) {