You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ut...@apache.org on 2018/09/18 10:04:32 UTC

[mynewt-core] 02/04: [STM32] Initial L0 support

This is an automated email from the ASF dual-hosted git repository.

utzig pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git

commit c2d1dc0ceb9807ec6bf309d35fe8ee901732faaf
Author: Fabio Utzig <ut...@apache.org>
AuthorDate: Wed Jul 18 09:29:59 2018 -0300

    [STM32] Initial L0 support
---
 hw/mcu/stm/stm32l0xx/include/mcu/cmsis_nvic.h      |  29 +++
 hw/mcu/stm/stm32l0xx/include/mcu/cortex_m0.h       |  35 ++++
 hw/mcu/stm/stm32l0xx/include/mcu/mcu.h             |  46 +++++
 hw/mcu/stm/stm32l0xx/include/mcu/stm32_hal.h       |  87 +++++++++
 hw/mcu/stm/stm32l0xx/include/mcu/stm32l0_bsp.h     |  58 ++++++
 .../stm32l0xx/include/mcu/stm32l0xx_mynewt_hal.h   |  66 +++++++
 hw/mcu/stm/stm32l0xx/pkg.yml                       |  39 ++++
 hw/mcu/stm/stm32l0xx/src/hal_flash.c               | 187 ++++++++++++++++++
 hw/mcu/stm/stm32l0xx/src/hal_reset_cause.c         |  49 +++++
 hw/mcu/stm/stm32l0xx/src/hal_timer_freq.c          |  75 ++++++++
 hw/mcu/stm/stm32l0xx/stm32l072.ld                  | 209 +++++++++++++++++++++
 hw/mcu/stm/stm32l0xx/syscfg.yml                    |  68 +++++++
 12 files changed, 948 insertions(+)

diff --git a/hw/mcu/stm/stm32l0xx/include/mcu/cmsis_nvic.h b/hw/mcu/stm/stm32l0xx/include/mcu/cmsis_nvic.h
new file mode 100644
index 0000000..8b62258
--- /dev/null
+++ b/hw/mcu/stm/stm32l0xx/include/mcu/cmsis_nvic.h
@@ -0,0 +1,29 @@
+/* mbed Microcontroller Library - cmsis_nvic
+ * Copyright (c) 2009-2011 ARM Limited. All rights reserved.
+ *
+ * CMSIS-style functionality to support dynamic vectors
+ */
+
+#ifndef MBED_CMSIS_NVIC_H
+#define MBED_CMSIS_NVIC_H
+
+#include <stdint.h>
+
+#define NVIC_NUM_VECTORS      (16 + 32)   // CORE + MCU Peripherals
+#define NVIC_USER_IRQ_OFFSET  16
+
+#include "stm32l0xx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void NVIC_Relocate(void);
+void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector);
+uint32_t NVIC_GetVector(IRQn_Type IRQn);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hw/mcu/stm/stm32l0xx/include/mcu/cortex_m0.h b/hw/mcu/stm/stm32l0xx/include/mcu/cortex_m0.h
new file mode 100644
index 0000000..98e482d
--- /dev/null
+++ b/hw/mcu/stm/stm32l0xx/include/mcu/cortex_m0.h
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef __MCU_CORTEX_M0_H__
+#define __MCU_CORTEX_M0_H__
+
+#include "stm32l0xx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define OS_TICKS_PER_SEC    (1000)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MCU_CORTEX_M0_H__ */
diff --git a/hw/mcu/stm/stm32l0xx/include/mcu/mcu.h b/hw/mcu/stm/stm32l0xx/include/mcu/mcu.h
new file mode 100644
index 0000000..f468816
--- /dev/null
+++ b/hw/mcu/stm/stm32l0xx/include/mcu/mcu.h
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef __MCU_MCU_H_
+#define __MCU_MCU_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SVC_IRQ_NUMBER SVC_IRQn
+
+/*
+ * Defines for naming GPIOs.
+ */
+#define MCU_GPIO_PORTA(pin)	((0 * 16) + (pin))
+#define MCU_GPIO_PORTB(pin)	((1 * 16) + (pin))
+#define MCU_GPIO_PORTC(pin)	((2 * 16) + (pin))
+#define MCU_GPIO_PORTD(pin)	((3 * 16) + (pin))
+#define MCU_GPIO_PORTE(pin)	((4 * 16) + (pin))
+#define MCU_GPIO_PORTF(pin)	((5 * 16) + (pin))
+#define MCU_GPIO_PORTG(pin)	((6 * 16) + (pin))
+#define MCU_GPIO_PORTH(pin)	((7 * 16) + (pin))
+#define MCU_GPIO_PORTI(pin)	((8 * 16) + (pin))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MCU_MCU_H_ */
diff --git a/hw/mcu/stm/stm32l0xx/include/mcu/stm32_hal.h b/hw/mcu/stm/stm32l0xx/include/mcu/stm32_hal.h
new file mode 100644
index 0000000..5e895c3
--- /dev/null
+++ b/hw/mcu/stm/stm32l0xx/include/mcu/stm32_hal.h
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef STM32_HAL_H
+#define STM32_HAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <mcu/cortex_m0.h>
+
+#include "stm32l0xx_hal.h"
+#include "stm32l0xx_hal_def.h"
+
+#include "stm32l0xx_mynewt_hal.h"
+
+/* hal_watchdog */
+#include "stm32l0xx_hal_iwdg.h"
+#define STM32_HAL_WATCHDOG_CUSTOM_INIT(x)           \
+    do {                                            \
+        (x)->Init.Window = IWDG_WINDOW_DISABLE;     \
+    } while (0)
+
+/* hal_system_start */
+    /* FIXME */
+#define STM32_HAL_FLASH_REMAP()
+#if 0
+#define STM32_HAL_FLASH_REMAP()                  \
+    do {                                         \
+        SYSCFG->MEMRMP = 0;                      \
+        __DSB();                                 \
+    } while (0)
+#endif
+
+/* hal_spi */
+#include "stm32l0xx.h"
+#include "stm32l0xx_hal_dma.h"
+#include "stm32l0xx_hal_spi.h"
+#include "stm32l0xx_hal_gpio.h"
+#include "stm32l0xx_hal_gpio_ex.h"
+#include "stm32l0xx_hal_rcc.h"
+
+struct stm32_hal_spi_cfg {
+    int ss_pin;                     /* for slave mode */
+    int sck_pin;
+    int miso_pin;
+    int mosi_pin;
+    int irq_prio;
+};
+
+/* hal_i2c */
+#include "stm32l0xx_hal_i2c.h"
+#include "mcu/stm32l0xx_mynewt_hal.h"
+
+/* hal_uart */
+#include "stm32l0xx_hal_uart.h"
+#include "mcu/stm32l0_bsp.h"
+
+/* hal_timer */
+#include "stm32l0xx_hal_tim.h"
+#include "stm32l0xx_ll_bus.h"
+#include "stm32l0xx_ll_tim.h"
+
+#define STM32_HAL_TIMER_MAX     (3)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32_HAL_H */
diff --git a/hw/mcu/stm/stm32l0xx/include/mcu/stm32l0_bsp.h b/hw/mcu/stm/stm32l0xx/include/mcu/stm32l0_bsp.h
new file mode 100644
index 0000000..00a10f0
--- /dev/null
+++ b/hw/mcu/stm/stm32l0xx/include/mcu/stm32l0_bsp.h
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef __MCU_STM32L0_BSP_H_
+#define __MCU_STM32L0_BSP_H_
+
+#include <hal/hal_gpio.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * BSP specific UART settings.
+ */
+struct stm32_uart_cfg {
+    USART_TypeDef *suc_uart;            /* UART dev registers */
+    volatile uint32_t *suc_rcc_reg;     /* RCC register to modify */
+    uint32_t suc_rcc_dev;               /* RCC device ID */
+    int8_t suc_pin_tx;                  /* pins for IO */
+    int8_t suc_pin_rx;
+    int8_t suc_pin_rts;
+    int8_t suc_pin_cts;
+    uint8_t suc_pin_af;                 /* AF selection for this */
+    IRQn_Type suc_irqn;                 /* NVIC IRQn */
+};
+
+/*
+ * Internal API for stm32l0xx mcu specific code.
+ */
+int hal_gpio_init_af(int pin, uint8_t af_type, enum hal_gpio_pull pull, uint8_t
+od);
+
+struct hal_flash;
+extern struct hal_flash stm32l0_flash_dev;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MCU_STM32L0_BSP_H_ */
diff --git a/hw/mcu/stm/stm32l0xx/include/mcu/stm32l0xx_mynewt_hal.h b/hw/mcu/stm/stm32l0xx/include/mcu/stm32l0xx_mynewt_hal.h
new file mode 100644
index 0000000..75a7bef
--- /dev/null
+++ b/hw/mcu/stm/stm32l0xx/include/mcu/stm32l0xx_mynewt_hal.h
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef __MCU_STM32L0_MYNEWT_HAL_H
+#define __MCU_STM32L0_MYNEWT_HAL_H
+
+#include "stm32l0xx.h"
+#include "stm32l0xx_hal_dma.h"
+#include "stm32l0xx_hal_gpio.h"
+#include "stm32l0xx_hal_i2c.h"
+#include "stm32l0xx_hal_spi.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Helper functions to enable/disable interrupts. */
+#define __HAL_DISABLE_INTERRUPTS(x)                     \
+    do {                                                \
+        x = __get_PRIMASK();                            \
+        __disable_irq();                                \
+    } while(0);
+
+#define __HAL_ENABLE_INTERRUPTS(x)                      \
+    do {                                                \
+        if (!x) {                                       \
+            __enable_irq();                             \
+        }                                               \
+    } while(0);
+
+
+int hal_gpio_init_stm(int pin, GPIO_InitTypeDef *cfg);
+int hal_gpio_deinit_stm(int pin, GPIO_InitTypeDef *cfg);
+
+struct stm32_hal_i2c_cfg {
+    I2C_TypeDef *hic_i2c;
+    volatile uint32_t *hic_rcc_reg;     /* RCC register to modify */
+    uint32_t hic_rcc_dev;               /* RCC device ID */
+    uint8_t hic_pin_sda;
+    uint8_t hic_pin_scl;
+    uint8_t hic_pin_af;
+    uint8_t hic_10bit;
+    uint32_t hic_timingr;               /* TIMINGR register */
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MCU_STM32L0_MYNEWT_HAL_H */
diff --git a/hw/mcu/stm/stm32l0xx/pkg.yml b/hw/mcu/stm/stm32l0xx/pkg.yml
new file mode 100644
index 0000000..c417e13
--- /dev/null
+++ b/hw/mcu/stm/stm32l0xx/pkg.yml
@@ -0,0 +1,39 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: hw/mcu/stm/stm32l0xx
+pkg.description: MCU definition for STM32L0 ARM Cortex-M0 chips.
+pkg.author: "Apache Mynewt <de...@mynewt.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+    - stm32
+    - stm32l0
+
+pkg.type: sdk
+
+pkg.ign_files:
+    - ".*template.*"
+
+pkg.ign_dirs:
+    - "Device"
+
+pkg.deps:
+    - hw/hal
+    - hw/mcu/stm/stm32_common
+    - hw/cmsis-core
diff --git a/hw/mcu/stm/stm32l0xx/src/hal_flash.c b/hw/mcu/stm/stm32l0xx/src/hal_flash.c
new file mode 100644
index 0000000..453c25a
--- /dev/null
+++ b/hw/mcu/stm/stm32l0xx/src/hal_flash.c
@@ -0,0 +1,187 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <string.h>
+#include "stm32l0xx_hal_def.h"
+#include "stm32l0xx_hal_rcc.h"
+#include "stm32l0xx_hal_flash.h"
+#include "stm32l0xx_hal_flash_ex.h"
+#include "hal/hal_flash_int.h"
+#include "hal/hal_watchdog.h"
+
+static int stm32l0_flash_read(const struct hal_flash *dev, uint32_t address,
+        void *dst, uint32_t num_bytes);
+static int stm32l0_flash_write(const struct hal_flash *dev, uint32_t address,
+        const void *src, uint32_t num_bytes);
+static int stm32l0_flash_erase_sector(const struct hal_flash *dev,
+        uint32_t sector_address);
+static int stm32l0_flash_sector_info(const struct hal_flash *dev, int idx,
+        uint32_t *address, uint32_t *sz);
+static int stm32l0_flash_init(const struct hal_flash *dev);
+
+static const struct hal_flash_funcs stm32l0_flash_funcs = {
+    .hff_read = stm32l0_flash_read,
+    .hff_write = stm32l0_flash_write,
+    .hff_erase_sector = stm32l0_flash_erase_sector,
+    .hff_sector_info = stm32l0_flash_sector_info,
+    .hff_init = stm32l0_flash_init,
+};
+
+#define _FLASH_SIZE              (192 * 1024)
+/*
+ * NOTE: the actual page size if 128 bytes, but that would mean an
+ * enormous amount of pages, so here make it look like 1K.
+ */
+#define _FLASH_SECTOR_SIZE       1024
+#define _FLASH_PAGES_PER_SECTOR  8
+
+const struct hal_flash stm32l0_flash_dev = {
+    .hf_itf = &stm32l0_flash_funcs,
+    .hf_base_addr = 0x08000000,
+    .hf_size = _FLASH_SIZE,
+    .hf_sector_cnt = _FLASH_SIZE / _FLASH_SECTOR_SIZE,
+    /* FIXME: 2 also ok? */
+    .hf_align = 4,
+    .hf_erased_val = 0,
+};
+
+static int
+stm32l0_flash_read(const struct hal_flash *dev, uint32_t address, void *dst,
+        uint32_t num_bytes)
+{
+    memcpy(dst, (void *)address, num_bytes);
+    return 0;
+}
+
+static int
+stm32l0_flash_write(const struct hal_flash *dev, uint32_t address,
+        const void *src, uint32_t num_bytes)
+{
+    uint64_t val;
+    uint8_t align;
+    uint32_t i;
+    int rc;
+    uint32_t num_words;
+
+    if (!num_bytes) {
+        return -1;
+    }
+
+    align = dev->hf_align;
+    num_words = ((num_bytes - 1) / align) + 1;
+
+    /* clear previous errors */
+    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP |
+                    FLASH_FLAG_ENDHV      |
+                    FLASH_FLAG_READY      |
+                    FLASH_FLAG_WRPERR     |
+                    FLASH_FLAG_PGAERR     |
+                    FLASH_FLAG_SIZERR     |
+                    FLASH_FLAG_OPTVERR    |
+                    FLASH_FLAG_RDERR      |
+                    FLASH_FLAG_FWWERR     |
+                    FLASH_FLAG_NOTZEROERR);
+
+    for (i = 0; i < num_words; i++) {
+        //__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGSERR);
+
+        if (num_bytes < align) {
+            memcpy(&val, &((uint8_t *)src)[i * align], num_bytes);
+            memset((uint32_t *)&val + num_bytes, 0, align - num_bytes);
+        } else {
+            memcpy(&val, &((uint8_t *)src)[i * align], align);
+        }
+
+        rc = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, val);
+        if (rc != HAL_OK) {
+            return rc;
+        }
+
+        address += align;
+
+        /* underflowing is ok here... */
+        num_bytes -= align;
+
+        /*
+         * Long writes take excessive time, and stall the idle thread, so
+         * tickling the watchdog here to avoid resetting during writes...
+         */
+        if (!(i % 32)) {
+            hal_watchdog_tickle();
+        }
+    }
+
+    return 0;
+}
+
+static int
+stm32l0_flash_erase_sector(const struct hal_flash *dev, uint32_t sector_address)
+{
+    FLASH_EraseInitTypeDef eraseinit;
+    uint32_t PageError;
+    HAL_StatusTypeDef rc;
+
+    (void)PageError;
+
+    if (!(sector_address & (_FLASH_SECTOR_SIZE - 1))) {
+        /* FIXME: why is an err flag set? */
+
+        /* Clear status of previous operation. */
+        __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP |
+                        FLASH_FLAG_ENDHV      |
+                        FLASH_FLAG_READY      |
+                        FLASH_FLAG_WRPERR     |
+                        FLASH_FLAG_PGAERR     |
+                        FLASH_FLAG_SIZERR     |
+                        FLASH_FLAG_OPTVERR    |
+                        FLASH_FLAG_RDERR      |
+                        FLASH_FLAG_FWWERR     |
+                        FLASH_FLAG_NOTZEROERR);
+
+        eraseinit.TypeErase = FLASH_TYPEERASE_PAGES;
+        eraseinit.PageAddress = sector_address;
+        eraseinit.NbPages = _FLASH_PAGES_PER_SECTOR;
+        rc = HAL_FLASHEx_Erase(&eraseinit, &PageError);
+        if (rc == HAL_OK) {
+            return 0;
+        }
+    }
+
+    return -1;
+}
+
+static int
+stm32l0_flash_sector_info(const struct hal_flash *dev, int idx,
+        uint32_t *address, uint32_t *sz)
+{
+    *address = dev->hf_base_addr + _FLASH_SECTOR_SIZE * idx;
+    *sz = _FLASH_SECTOR_SIZE;
+    return 0;
+}
+
+static int
+stm32l0_flash_init(const struct hal_flash *dev)
+{
+    //__HAL_FLASH_BUFFER_CACHE_DISABLE();
+    //__HAL_FLASH_PREREAD_BUFFER_ENABLE();
+    //__HAL_FLASH_PREFETCH_BUFFER_ENABLE();
+    __HAL_RCC_MIF_CLK_ENABLE();
+    HAL_FLASH_Unlock();
+    return 0;
+}
diff --git a/hw/mcu/stm/stm32l0xx/src/hal_reset_cause.c b/hw/mcu/stm/stm32l0xx/src/hal_reset_cause.c
new file mode 100644
index 0000000..b9d3074
--- /dev/null
+++ b/hw/mcu/stm/stm32l0xx/src/hal_reset_cause.c
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#include <hal/hal_system.h>
+
+#include "stm32l0xx_hal_def.h"
+
+enum hal_reset_reason
+hal_reset_cause(void)
+{
+    static enum hal_reset_reason reason;
+    uint32_t reg;
+
+    if (reason) {
+        return reason;
+    }
+
+    reg = RCC->CSR;
+
+    if (reg & RCC_CSR_WWDGRSTF) {
+        reason = HAL_RESET_WATCHDOG;
+    } else if (reg & RCC_CSR_SFTRSTF) {
+        reason = HAL_RESET_SOFT;
+    } else if (reg & RCC_CSR_PINRSTF) {
+        reason = HAL_RESET_PIN;
+    } else if (reg & RCC_CSR_LPWRRSTF) {
+        /* For L0xx this is low-power reset */
+        reason = HAL_RESET_BROWNOUT;
+    } else {
+        reason = HAL_RESET_POR;
+    }
+    RCC->CSR |= RCC_CSR_RMVF;
+    return reason;
+}
diff --git a/hw/mcu/stm/stm32l0xx/src/hal_timer_freq.c b/hw/mcu/stm/stm32l0xx/src/hal_timer_freq.c
new file mode 100644
index 0000000..de07772
--- /dev/null
+++ b/hw/mcu/stm/stm32l0xx/src/hal_timer_freq.c
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <inttypes.h>
+#include <assert.h>
+
+#include "os/mynewt.h"
+
+#include <hal/hal_timer.h>
+#include "mcu/stm32_hal.h"
+#include "stm32_common/stm32_hal.h"
+
+
+/*
+ * Generic implementation for determining the frequency
+ * of a timer.
+ */
+
+uint32_t
+stm32_hal_timer_get_freq(void *regs)
+{
+    RCC_ClkInitTypeDef clocks;
+    uint32_t fl;
+    uint32_t freq;
+
+    HAL_RCC_GetClockConfig(&clocks, &fl);
+
+    /*
+     * Assuming RCC_DCKCFGR->TIMPRE is 0.
+     * There's just APB2 timers here.
+     */
+    switch ((uintptr_t)regs) {
+#ifdef TIM21
+    case (uintptr_t)TIM21:
+#endif
+#ifdef TIM23
+    case (uintptr_t)TIM22:
+#endif
+        freq = HAL_RCC_GetPCLK2Freq();
+        if (clocks.APB2CLKDivider) {
+            freq *= 2;
+        }
+        break;
+#ifdef TIM2
+    case (uintptr_t)TIM2:
+#endif
+#ifdef TIM3
+    case (uintptr_t)TIM3:
+#endif
+        freq = HAL_RCC_GetPCLK1Freq();
+        if (clocks.APB1CLKDivider) {
+            freq *= 2;
+        }
+        break;
+    default:
+        return 0;
+    }
+    return freq;
+}
diff --git a/hw/mcu/stm/stm32l0xx/stm32l072.ld b/hw/mcu/stm/stm32l0xx/stm32l072.ld
new file mode 100644
index 0000000..eb22247
--- /dev/null
+++ b/hw/mcu/stm/stm32l0xx/stm32l072.ld
@@ -0,0 +1,209 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/* Linker script to place sections and symbol values. Should be used together
+ * with other linker script that defines memory regions FLASH and RAM.
+ * It references following symbols, which must be defined in code:
+ *   Reset_Handler : Entry of reset handler
+ *
+ * It defines following symbols, which code can use without definition:
+ *   __exidx_start
+ *   __exidx_end
+ *   __etext
+ *   __data_start__
+ *   __preinit_array_start
+ *   __preinit_array_end
+ *   __init_array_start
+ *   __init_array_end
+ *   __fini_array_start
+ *   __fini_array_end
+ *   __data_end__
+ *   __bss_start__
+ *   __bss_end__
+ *   __end__
+ *   end
+ *   __HeapBase
+ *   __HeapLimit
+ *   __StackLimit
+ *   __StackTop
+ *   __stack
+ *   __coredata_start__
+ *   __coredata_end__
+ *   __corebss_start__
+ *   __corebss_end__
+ *   __ecoredata
+ *   __ecorebss
+ */
+ENTRY(Reset_Handler)
+
+_estack = 0x20005000;
+
+SECTIONS
+{
+    /* Reserve space at the start of the image for the header. */
+    .imghdr (NOLOAD):
+    {
+        . = . + _imghdr_size;
+    } > FLASH
+
+    .text :
+    {
+        . = ALIGN(4);
+        __isr_vector_start = .;
+        KEEP(*(.isr_vector))
+        __isr_vector_end = .;
+        *(.text*)
+
+        KEEP(*(.init))
+        KEEP(*(.fini))
+
+        /* .ctors */
+        *crtbegin.o(.ctors)
+        *crtbegin?.o(.ctors)
+        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
+        *(SORT(.ctors.*))
+        *(.ctors)
+
+        /* .dtors */
+        *crtbegin.o(.dtors)
+        *crtbegin?.o(.dtors)
+        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
+        *(SORT(.dtors.*))
+        *(.dtors)
+
+        *(.rodata*)
+
+        KEEP(*(.eh_frame*))
+    } > FLASH
+
+    .ARM.extab :
+    {
+        *(.ARM.extab* .gnu.linkonce.armextab.*)
+    } > FLASH
+
+    __exidx_start = .;
+    .ARM.exidx :
+    {
+        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+    } > FLASH
+
+    __exidx_end = .;
+
+    __etext = .;
+
+    .vector_relocation :
+    {
+        . = ALIGN(4);
+        __vector_tbl_reloc__ = .;
+        . = . + (__isr_vector_end - __isr_vector_start);
+    } > RAM
+
+    .coredata :
+    {
+        . = ALIGN(4);
+        __coredata_start__ = .;
+        *(.data.core)
+        __coredata_end__ = .;
+    } > RAM AT > FLASH
+
+    __ecoredata = __etext + SIZEOF(.coredata);
+
+    _sidata = LOADADDR(.data);
+
+    .data :
+    {
+        . = ALIGN(4);
+        _sdata = .;
+        __data_start__ = _sdata;
+        *(vtable)
+        *(.data*)
+
+        /* preinit data */
+        PROVIDE_HIDDEN (__preinit_array_start = .);
+        KEEP(*(.preinit_array))
+        PROVIDE_HIDDEN (__preinit_array_end = .);
+
+        . = ALIGN(4);
+        /* init data */
+        PROVIDE_HIDDEN (__init_array_start = .);
+        KEEP(*(SORT(.init_array.*)))
+        KEEP(*(.init_array))
+        PROVIDE_HIDDEN (__init_array_end = .);
+
+
+        . = ALIGN(4);
+        /* finit data */
+        PROVIDE_HIDDEN (__fini_array_start = .);
+        KEEP(*(SORT(.fini_array.*)))
+        KEEP(*(.fini_array))
+        PROVIDE_HIDDEN (__fini_array_end = .);
+
+        KEEP(*(.jcr*))
+        . = ALIGN(4);
+        /* All data end */
+        _edata = .;
+        __data_end__ = _edata;
+
+    } > RAM AT > FLASH
+
+    .corebss (NOLOAD):
+    {
+        . = ALIGN(4);
+        __corebss_start__ = .;
+        *(.bss.core)
+        . = ALIGN(4);
+        __corebss_end__ = .;
+        *(.corebss*)
+        *(.bss.core.nz)
+        . = ALIGN(4);
+        __ecorebss = .;
+    } > RAM
+
+    .bss :
+    {
+        . = ALIGN(4);
+        _sbss = .;
+        __bss_start__ = _sbss;
+        *(.bss*)
+        *(COMMON)
+        . = ALIGN(4);
+        _ebss = .;
+        __bss_end__ = _ebss;
+    } > RAM
+
+    . = ALIGN(8);
+    __HeapBase = .;
+    __HeapLimit = ORIGIN(RAM) + LENGTH(RAM);
+
+    _ram_start = ORIGIN(RAM);
+
+    /* .stack_dummy section doesn't contains any symbols. It is only
+     * used for linker to calculate size of stack sections, and assign
+     * values to stack symbols later */
+    .stack_dummy (COPY):
+    {
+        *(.stack*)
+    } > RAM
+
+    /* Set stack top to end of RAM; stack limit is bottom of stack */
+    __StackTop = ORIGIN(RAM) + LENGTH(RAM);
+    __StackLimit = __StackTop - SIZEOF(.stack_dummy);
+    PROVIDE(__stack = __StackTop);
+}
+
diff --git a/hw/mcu/stm/stm32l0xx/syscfg.yml b/hw/mcu/stm/stm32l0xx/syscfg.yml
new file mode 100644
index 0000000..fe215e6
--- /dev/null
+++ b/hw/mcu/stm/stm32l0xx/syscfg.yml
@@ -0,0 +1,68 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+# Package: hw/mcu/stm32l0xx
+
+syscfg.defs:
+    I2C_0:
+        description: 'I2C (TWI) interface 0'
+        value:  0
+
+    MCU_FLASH_MIN_WRITE_SIZE:
+        description: >
+            Specifies the required alignment for internal flash writes.
+            Used internally by the newt tool.
+        value: 4
+
+    MCU_STM32L0:
+        description: MCUs are of STM32L0xx family
+        value: 1
+
+    STM32_HAL_SPI_HAS_FIFO:
+        description: This MCU has a SPI without FIFO
+        value: 0
+
+    STM32_HAL_I2C_HAS_CLOCKSPEED:
+        description: This MCU's I2C has a clock speed register
+        value: 0
+
+    STM32_HAL_UART_HAS_SR:
+        description: This MCU's UART uses SR register for status.
+        value: 0
+
+    SPI_0_MASTER:
+        description: 'SPI 0 master'
+        value:  0
+        restrictions:
+            - "!SPI_0_SLAVE"
+    SPI_0_SLAVE:
+        description: 'SPI 0 slave'
+        value:  0
+        restrictions:
+            - "!SPI_0_MASTER"
+
+    SPI_1_MASTER:
+        description: 'SPI 1 master'
+        value:  0
+        restrictions:
+            - "!SPI_1_SLAVE"
+    SPI_1_SLAVE:
+        description: 'SPI 1 slave'
+        value:  0
+        restrictions:
+            - "!SPI_1_MASTER"