/***************************************************************************//** * @file flash_api.c ******************************************************************************* * @section License * Copyright 2017 Silicon Laboratories, Inc. http://www.silabs.com ******************************************************************************* * * SPDX-License-Identifier: Apache-2.0 * * 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 "device.h" #if DEVICE_FLASH #include "flash_api.h" #include "em_msc.h" /** Initialize the flash peripheral and the flash_t object * * @param obj The flash object * @return 0 for success, -1 for error */ int32_t flash_init(flash_t *obj) { (void)obj; MSC_Init(); return 0; } /** Uninitialize the flash peripheral and the flash_t object * * @param obj The flash object * @return 0 for success, -1 for error */ int32_t flash_free(flash_t *obj) { (void)obj; MSC_Deinit(); return 0; } /** Erase one sector starting at defined address * * The address should be at sector boundary. This function does not do any check for address alignments * @param obj The flash object * @param address The sector starting address * @return 0 for success, -1 for error */ int32_t flash_erase_sector(flash_t *obj, uint32_t address) { (void)obj; MSC_Status_TypeDef mscStatus = MSC_ErasePage((uint32_t *)address); return (mscStatus == mscReturnOk) ? 0 : -1; } /** Program one page starting at defined address * * The page should be at page boundary, should not cross multiple sectors. * This function does not do any check for address alignments or if size is aligned to a page size. * @param obj The flash object * @param address The sector starting address * @param data The data buffer to be programmed * @param size The number of bytes to program * @return 0 for success, -1 for error */ int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data, uint32_t size) { (void)obj; MSC_Status_TypeDef mscStatus = MSC_WriteWord((uint32_t *)address, data, size); return (mscStatus == mscReturnOk) ? 0 : -1; } /** Get sector size * * @param obj The flash object * @param address The sector starting address * @return The size of a sector */ uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address) { (void)obj; (void)address; #if FLASH_BASE > 0 if (address < FLASH_BASE || address >= FLASH_BASE + FLASH_SIZE) { // Address outside of flash -- invalid sector return MBED_FLASH_INVALID_SIZE; } #else if (address >= FLASH_BASE + FLASH_SIZE) { // Address outside of flash -- invalid sector return MBED_FLASH_INVALID_SIZE; } #endif return FLASH_PAGE_SIZE; } /** Get page size * * The page size defines the writable page size * @param obj The flash object * @return The size of a page */ uint32_t flash_get_page_size(const flash_t *obj) { (void)obj; return sizeof(uint32_t); } /** Get start address for the flash region * * @param obj The flash object * @return The start address for the flash region */ uint32_t flash_get_start_address(const flash_t *obj) { (void)obj; return FLASH_BASE; } /** Get the flash region size * * @param obj The flash object * @return The flash region size */ uint32_t flash_get_size(const flash_t *obj) { (void)obj; return FLASH_SIZE; } /** Get the flash erase value * * @param obj The flash object * @return The flash erase value */ uint8_t flash_get_erase_value(const flash_t *obj) { (void)obj; return 0xFF; } #endif // DEVICE_FLASH