diff --git a/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/TOOLCHAIN_ARM_MICRO/stm32l151rc.sct b/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/TOOLCHAIN_ARM_MICRO/stm32l151rc.sct index 141eb4a827f..f189ccc6264 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/TOOLCHAIN_ARM_MICRO/stm32l151rc.sct +++ b/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/TOOLCHAIN_ARM_MICRO/stm32l151rc.sct @@ -1,3 +1,4 @@ +#! armcc -E ; Scatter-Loading Description File ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Copyright (c) 2015, STMicroelectronics @@ -27,10 +28,19 @@ ; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +#if !defined(MBED_APP_START) + #define MBED_APP_START 0x08000000 +#endif + +#if !defined(MBED_APP_SIZE) + #define MBED_APP_SIZE 0x40000 +#endif + + ; STM32L151RC: 256KB FLASH + 32KB SRAM -LR_IROM1 0x08000000 0x40000 { ; load region size_region +LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region - ER_IROM1 0x08000000 0x40000 { ; load address = execution address + ER_IROM1 MBED_APP_START MBED_APP_SIZE { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) diff --git a/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/TOOLCHAIN_ARM_STD/stm32l151rc.sct b/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/TOOLCHAIN_ARM_STD/stm32l151rc.sct index 141eb4a827f..f189ccc6264 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/TOOLCHAIN_ARM_STD/stm32l151rc.sct +++ b/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/TOOLCHAIN_ARM_STD/stm32l151rc.sct @@ -1,3 +1,4 @@ +#! armcc -E ; Scatter-Loading Description File ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Copyright (c) 2015, STMicroelectronics @@ -27,10 +28,19 @@ ; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +#if !defined(MBED_APP_START) + #define MBED_APP_START 0x08000000 +#endif + +#if !defined(MBED_APP_SIZE) + #define MBED_APP_SIZE 0x40000 +#endif + + ; STM32L151RC: 256KB FLASH + 32KB SRAM -LR_IROM1 0x08000000 0x40000 { ; load region size_region +LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region - ER_IROM1 0x08000000 0x40000 { ; load address = execution address + ER_IROM1 MBED_APP_START MBED_APP_SIZE { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) diff --git a/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/TOOLCHAIN_GCC_ARM/STM32L151XC.ld b/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/TOOLCHAIN_GCC_ARM/STM32L151XC.ld index af8cddd4a14..17d63638e65 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/TOOLCHAIN_GCC_ARM/STM32L151XC.ld +++ b/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/TOOLCHAIN_GCC_ARM/STM32L151XC.ld @@ -1,11 +1,17 @@ /* Linker script to configure memory regions. */ +#if !defined(MBED_APP_START) + #define MBED_APP_START 0x08000000 +#endif +#if !defined(MBED_APP_SIZE) + #define MBED_APP_SIZE 256k +#endif MEMORY { /* 256KB FLASH, 32KB RAM, Reserve up till 0x13C. There are 0x73 vectors = 292 * bytes (0x124) in RAM. But all GCC scripts seem to require BootRAM @0x138 */ - FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 256k + FLASH (rx) : ORIGIN = MBED_APP_START, LENGTH = MBED_APP_SIZE RAM (rwx) : ORIGIN = 0x2000013C, LENGTH = 0x8000-0x13C } diff --git a/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/TOOLCHAIN_IAR/stm32l152xc.icf b/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/TOOLCHAIN_IAR/stm32l152xc.icf index aed878fb05b..ebf7478802d 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/TOOLCHAIN_IAR/stm32l152xc.icf +++ b/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/TOOLCHAIN_IAR/stm32l152xc.icf @@ -1,7 +1,9 @@ +if (!isdefinedsymbol(MBED_APP_START)) { define symbol MBED_APP_START = 0x08000000; } +if (!isdefinedsymbol(MBED_APP_SIZE)) { define symbol MBED_APP_SIZE = 0x40000; } /* [ROM = 256kb = 0x40000] */ -define symbol __intvec_start__ = 0x08000000; -define symbol __region_ROM_start__ = 0x08000000; -define symbol __region_ROM_end__ = 0x0803FFFF; +define symbol __intvec_start__ = MBED_APP_START; +define symbol __region_ROM_start__ = MBED_APP_START; +define symbol __region_ROM_end__ = MBED_APP_START + MBED_APP_SIZE - 1; /* [RAM = 32kb = 0x8000] Vector table dynamic copy: 73 vectors = 292 bytes (0x124) to be reserved in RAM */ define symbol __NVIC_start__ = 0x20000000; diff --git a/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/system_stm32l1xx.c b/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/system_stm32l1xx.c index b54d115c2f2..2ad62cd9df1 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/system_stm32l1xx.c +++ b/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/system_stm32l1xx.c @@ -203,11 +203,25 @@ void SystemInit (void) #ifdef DATA_IN_ExtSRAM SystemInit_ExtMemCtl(); #endif /* DATA_IN_ExtSRAM */ - + + +#if defined(__ICCARM__) + #pragma section=".intvec" + #define FLASH_VTOR_BASE ((uint32_t)__section_begin(".intvec")) +#elif defined(__CC_ARM) + extern uint32_t Load$$LR$$LR_IROM1$$Base[]; + #define FLASH_VTOR_BASE ((uint32_t)Load$$LR$$LR_IROM1$$Base) +#elif defined(__GNUC__) + extern uint32_t g_pfnVectors[]; + #define FLASH_VTOR_BASE ((uint32_t)g_pfnVectors) +#else + #error "Flash vector address not set for this toolchain" +#endif + #ifdef VECT_TAB_SRAM SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */ #else - SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */ + SCB->VTOR = FLASH_VTOR_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */ #endif } diff --git a/targets/TARGET_STM/TARGET_STM32L1/common_objects.h b/targets/TARGET_STM/TARGET_STM32L1/common_objects.h index ef2e65c75ee..844e0f5b25b 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/common_objects.h +++ b/targets/TARGET_STM/TARGET_STM32L1/common_objects.h @@ -110,6 +110,11 @@ struct i2c_s { #endif }; +struct flash_s { + /* nothing to be stored for now */ + uint32_t dummy; +}; + struct dac_s { DACName dac; PinName pin; diff --git a/targets/TARGET_STM/TARGET_STM32L1/flash_api.c b/targets/TARGET_STM/TARGET_STM32L1/flash_api.c new file mode 100644 index 00000000000..86572e619d4 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32L1/flash_api.c @@ -0,0 +1,143 @@ +/* mbed Microcontroller Library + * Copyright (c) 2017 ARM Limited + * + * Licensed 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 "flash_api.h" +#include "mbed_critical.h" + +#if DEVICE_FLASH +#include "mbed_assert.h" +#include "cmsis.h" + +/* L1 targets embed 16 pages sectors */ +#define NUM_PAGES_IN_SECTOR 16 + +int32_t flash_init(flash_t *obj) +{ + /* Unlock the Flash to enable the flash control register access *************/ + HAL_FLASH_Unlock(); + return 0; +} + +int32_t flash_free(flash_t *obj) +{ + /* Lock the Flash to disable the flash control register access (recommended + * to protect the FLASH memory against possible unwanted operation) *********/ + HAL_FLASH_Lock(); + return 0; +} + +int32_t flash_erase_sector(flash_t *obj, uint32_t address) +{ + uint32_t FirstPage = 0; + uint32_t PAGEError = 0; + FLASH_EraseInitTypeDef EraseInitStruct; + + if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) { + + return -1; + } + + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR | FLASH_FLAG_EOP | FLASH_FLAG_PGAERR | FLASH_FLAG_WRPERR); + /* MBED HAL erases 1 sector at a time */ + /* Fill EraseInit structure*/ + EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES; + EraseInitStruct.PageAddress = address; + EraseInitStruct.NbPages = NUM_PAGES_IN_SECTOR; + + /* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache, + you have to make sure that these data are rewritten before they are accessed during code + execution. If this cannot be done safely, it is recommended to flush the caches by setting the + DCRST and ICRST bits in the FLASH_CR register. */ + + if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK) { + return -1; + } else { + return 0; + } +} + +int32_t flash_program_page(flash_t *obj, uint32_t address, + const uint8_t *data, uint32_t size) +{ + uint32_t StartAddress = 0; + + if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) { + return -1; + } + + if ((size % 4) != 0) { + /* L1 flash devices can only be programmed 32bits/4 bytes at a time */ + return -1; + } + + /* Program the user Flash area word by word */ + StartAddress = address; + + /* HW needs an aligned address to program flash, which data + * parameters doesn't ensure */ + if ((uint32_t) data % 4 != 0) { + volatile uint32_t data32; + while (address < (StartAddress + size)) { + for (uint8_t i =0; i < 4; i++) { + *(((uint8_t *) &data32) + i) = *(data + i); + } + + if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, data32) == HAL_OK) { + address = address + 4; + data = data + 4; + } else { + return -1; + } + } + } else { /* case where data is aligned, so let's avoid any copy */ + while (address < (StartAddress + size)) { + if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, *((uint32_t*) data)) == HAL_OK) { + address = address + 4; + data = data + 4; + } else { + return -1; + } + } + } + + return 0; +} + +uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address) +{ + if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) { + return MBED_FLASH_INVALID_SIZE; + } else { + return (NUM_PAGES_IN_SECTOR * FLASH_PAGE_SIZE); + } +} + +uint32_t flash_get_page_size(const flash_t *obj) +{ + return FLASH_PAGE_SIZE; +} + +uint32_t flash_get_start_address(const flash_t *obj) +{ + return FLASH_BASE; +} + +uint32_t flash_get_size(const flash_t *obj) +{ + return FLASH_SIZE; +} + +#endif diff --git a/targets/targets.json b/targets/targets.json index fee2445374a..e6f491b32ec 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -1408,9 +1408,10 @@ "default_toolchain": "ARM", "extra_labels_add": ["STM32L1", "STM32L151CC"], "supported_toolchains": ["ARM", "GCC_ARM", "IAR"], - "device_has_add": ["ANALOGOUT"], + "device_has_add": ["ANALOGOUT", "FLASH"], "release_versions": ["5"], - "device_name": "STM32L151CC" + "device_name": "STM32L151CC", + "bootloader_supported": true }, "MOTE_L152RC": { "inherits": ["FAMILY_STM32"],