diff --git a/cpu/stm32f1/cpu.c b/cpu/stm32f1/cpu.c
index e30ef52e079ae21db322b74a18a7a1c1055fe07c..99b24be5c0e9fd3489f98ff4a49215ba3e5787de 100644
--- a/cpu/stm32f1/cpu.c
+++ b/cpu/stm32f1/cpu.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2013 INRIA
  * Copyright (C) 2014 Freie Universität Berlin
+ * Copyright (C) 2016 TriaGnoSys GmbH
  *
  * This file is subject to the terms and conditions of the GNU Lesser General
  * Public License v2.1. See the file LICENSE in the top level directory for more
@@ -19,6 +20,7 @@
  * @author      Thomas Eichinger <thomas.eichinger@fu-berlin.de>
  * @author      Hauke Petersen <hauke.petersen@fu-berlin.de>
  * @author      Nick van IJzendoorn <nijzendoorn@engineering-spirit.nl>
+ * @author      Víctor Ariño <victor.arino@zii.aero>
  *
  * @}
  */
@@ -26,9 +28,19 @@
 #include "cpu.h"
 #include "periph_conf.h"
 
-/* Check the source to be used for the PLL */
+/* See if we want to use the PLL */
+#if defined(CLOCK_PLL_DIV) || defined(CLOCK_PLL_MUL)
+#define CLOCK_USE_PLL              1
+#else
+#define CLOCK_USE_PLL              0
+#endif
+
+/* Check the source to be used and parameters */
 #if defined(CLOCK_HSI) && defined(CLOCK_HSE)
 #error "Only provide one of two CLOCK_HSI/CLOCK_HSE"
+#elif (CLOCK_USE_PLL == 1) && (!defined(CLOCK_PLL_MUL) || !defined(CLOCK_PLL_DIV))
+#error "When using PLL both CLOCK_PLL_DIV and CLOCK_PLL_MUL must be provided"
+
 #elif CLOCK_HSI
 #define CLOCK_CR_SOURCE            RCC_CR_HSION
 #define CLOCK_CR_SOURCE_RDY        RCC_CR_HSIRDY
@@ -36,8 +48,11 @@
 #define CLOCK_PLL_SOURCE           0
 #define CLOCK_DISABLE_HSI          0
 
-#if (CLOCK_PLL_DIV != 1)
-#error "HSI clock cannot be divided"
+#if (CLOCK_USE_PLL == 0)
+#define CLOCK_CFGR_SW              RCC_CFGR_SW_HSI
+#define CLOCK_CFGR_SW_RDY          RCC_CFGR_SWS_HSI
+#elif (CLOCK_PLL_DIV != 2)
+#error "CLOCK_PLL_DIV can only be 2 for the HSI"
 #endif
 
 #elif CLOCK_HSE
@@ -46,11 +61,14 @@
 #define CLOCK_PLL_SOURCE           RCC_CFGR_PLLSRC
 #define CLOCK_DISABLE_HSI          1
 
-#if (CLOCK_PLL_DIV == 2)
+#if (CLOCK_USE_PLL == 0)
+#define CLOCK_CFGR_SW              RCC_CFGR_SW_HSE
+#define CLOCK_CFGR_SW_RDY          RCC_CFGR_SWS_HSE
+#elif (CLOCK_PLL_DIV == 2)
 #define CLOCK_PLL_DIVMSK           RCC_CFGR_PLLXTPRE
 #elif (CLOCK_PLL_DIV == 1)
 #define CLOCK_PLL_DIVMSK           0
-#else
+#elif defined(CLOCK_PLL_DIV)
 #error "HSE divider must be 1 or 2"
 #endif
 
@@ -58,11 +76,15 @@
 #error "Please provide CLOCK_HSI or CLOCK_HSE in boards/NAME/includes/perhip_cpu.h"
 #endif
 
+#if (CLOCK_USE_PLL == 1)
+#define CLOCK_CFGR_SW              RCC_CFGR_SW_PLL
+#define CLOCK_CFGR_SW_RDY          RCC_CFGR_SWS_PLL
 #if CLOCK_PLL_MUL > 16
 #error "PLL multiplier cannot exceed 16 times"
 #elif CLOCK_PLL_MUL < 2
 #error "PLL multiplier cannot be set to 1 or lower"
 #endif
+#endif
 
 static void clk_init(void);
 
@@ -110,18 +132,21 @@ static void clk_init(void)
     RCC->CFGR |= (uint32_t)CLOCK_APB2_DIV;
     /* PCLK1 = HCLK */
     RCC->CFGR |= (uint32_t)CLOCK_APB1_DIV;
+
+#if (CLOCK_USE_PLL == 1)
     /*  PLL configuration: PLLCLK = CLOCK_SOURCE / PLL_DIV * PLL_MUL */
-    RCC->CFGR &= ~((uint32_t)(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
     RCC->CFGR |= (uint32_t)(CLOCK_PLL_SOURCE | CLOCK_PLL_DIVMSK | ((CLOCK_PLL_MUL - 2) << 18));
     /* 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 */
+#endif
+
+    /* Select the system clock source */
     RCC->CFGR &= ~((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) != RCC_CFGR_SWS_PLL) {}
+    RCC->CFGR |= (uint32_t)CLOCK_CFGR_SW;
+    /* Wait till selected system clock source is ready */
+    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != CLOCK_CFGR_SW_RDY) {}
 
 #if CLOCK_DISABLE_HSI
     RCC->CR &= ~(RCC_CR_HSION);
diff --git a/cpu/stm32f1/lpm_arch.c b/cpu/stm32f1/lpm_arch.c
index e41810c880b95e4129febbd1475d0498f9467c44..fe329cb5622ce0cd63d71ad3b37c499b5462629c 100644
--- a/cpu/stm32f1/lpm_arch.c
+++ b/cpu/stm32f1/lpm_arch.c
@@ -1,6 +1,5 @@
 /*
- * Copyright (C) 2013 INRIA
- * Copyright (C) 2014 Freie Universität Berlin
+ * Copyright (C) 2015 Engineering-Spirit
  *
  * This file is subject to the terms and conditions of the GNU Lesser General
  * Public License v2.1. See the file LICENSE in the top level directory for more
@@ -12,45 +11,88 @@
  * @{
  *
  * @file
- * @brief       Implementation of the kernel's lpm interface
+ * @brief       Implementation of the kernels power management interface
  *
- * @author      Alaeddine Weslati <alaeddine.weslati@inria.fr>
- * @author      Hauke Petersen <hauke.petersen@fu-berlin.de>
+ * @author      Nick v. IJzendoorn <nijzndoorn@engineering-spirit.nl>
  *
  * @}
  */
 
+#include "cpu.h"
 #include "arch/lpm_arch.h"
 
+static enum lpm_mode current_mode = LPM_UNKNOWN;
+
 void lpm_arch_init(void)
 {
-    /* TODO */
+    current_mode = LPM_ON;
 }
 
 enum lpm_mode lpm_arch_set(enum lpm_mode target)
 {
-    (void) target;
-    /* TODO */
-    return 0;
+    enum lpm_mode last_mode = current_mode;
+
+    switch (target) {
+        case LPM_ON:                    /* STM Run mode */
+            current_mode = LPM_ON;
+            break;
+        case LPM_IDLE:                  /* STM Sleep mode */
+            current_mode = LPM_IDLE;
+            /* Reset SLEEPDEEP bit of system control block */
+            SCB->SCR &= ~(SCB_SCR_SLEEPDEEP_Msk);
+            /* Enter sleep mode */
+            __WFI();
+            break;
+        case LPM_SLEEP:                 /* STM Stop mode */
+            current_mode = LPM_SLEEP;
+            /* Clear PDDS and LPDS bits to enter stop mode on */
+            /* deepsleep with voltage regulator on */
+            PWR->CR &= ~(PWR_CR_PDDS | PWR_CR_LPDS);
+            /* Set SLEEPDEEP bit of system control block */
+            SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
+            /* Enter stop mode */
+            __WFI();
+            break;
+        case LPM_POWERDOWN:             /* STM Standby mode */
+            /* Fall-through */
+        case LPM_OFF:                   /* STM Standby mode */
+            current_mode = LPM_POWERDOWN;
+            /* Set PDDS to enter standby mode on deepsleep and clear flags */
+            PWR->CR |= (PWR_CR_PDDS | PWR_CR_CWUF | PWR_CR_CSBF);
+            /* Enable WKUP pin to use for wakeup from standby mode */
+            PWR->CSR |= PWR_CSR_EWUP;
+            /* Set SLEEPDEEP bit of system control block */
+            SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
+#if defined ( __CC_ARM   )
+            /* Ensure that store operations are completed */
+            __force_stores();
+#endif
+            /* Enter standby mode */
+            __WFI();
+            break;
+        default:
+            break;
+    }
+
+    return last_mode;
 }
 
 enum lpm_mode lpm_arch_get(void)
 {
-    /* TODO */
-    return 0;
+    return current_mode;
 }
 
 void lpm_arch_awake(void)
 {
-    /* TODO */
+    if (current_mode == LPM_SLEEP) {
+        /* After stop mode, the clock system needs to be reconfigured */
+        cpu_init();
+    }
+    current_mode = LPM_ON;
 }
 
-void lpm_arch_begin_awake(void)
-{
-    /* TODO */
-}
+/** Not provided */
+inline void lpm_arch_begin_awake(void) { }
 
-void lpm_arch_end_awake(void)
-{
-    /* TODO */
-}
+/** Not provided */
+inline void lpm_arch_end_awake(void) { }