diff --git a/TESTS/mbed_drivers/flashiap/main.cpp b/TESTS/mbed_drivers/flashiap/main.cpp new file mode 100644 index 00000000000..19c94bedd76 --- /dev/null +++ b/TESTS/mbed_drivers/flashiap/main.cpp @@ -0,0 +1,201 @@ + +/* 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. + */ + +#if !DEVICE_FLASH + #error [NOT_SUPPORTED] Flash API not supported for this target +#endif + +#include "utest/utest.h" +#include "unity/unity.h" +#include "greentea-client/test_env.h" + +#include "mbed.h" + +using namespace utest::v1; + +void flashiap_init_test() +{ + FlashIAP flash_device; + uint32_t ret = flash_device.init(); + TEST_ASSERT_EQUAL_INT32(ret, 0); + ret = flash_device.deinit(); + TEST_ASSERT_EQUAL_INT32(ret, 0); +} + +void flashiap_program_test() +{ + FlashIAP flash_device; + uint32_t ret = flash_device.init(); + TEST_ASSERT_EQUAL_INT32(ret, 0); + + // get the last sector size (flash size - 1) + uint32_t sector_size = flash_device.get_sector_size(flash_device.get_flash_start() + flash_device.get_flash_size() - 1UL); + TEST_ASSERT_NOT_EQUAL(sector_size, 0); + const uint8_t test_value = 0xCE; + uint8_t *data = new uint8_t[sector_size]; + for (uint32_t i = 0; i < sector_size; i++) { + data[i] = test_value; + } + + // the one before the last page in the system + uint32_t address = (flash_device.get_flash_start() + flash_device.get_flash_size()) - (sector_size); + TEST_ASSERT_TRUE(address != 0UL); + ret = flash_device.erase(address, sector_size); + TEST_ASSERT_EQUAL_INT32(ret, 0); + + ret = flash_device.program(data, address, sector_size); + TEST_ASSERT_EQUAL_INT32(ret, 0); + + uint8_t *data_flashed = new uint8_t[sector_size]; + ret = flash_device.read(data_flashed, address, sector_size); + TEST_ASSERT_EQUAL_INT32(ret, 0); + TEST_ASSERT_EQUAL_UINT8_ARRAY(data, data_flashed, sector_size); + delete[] data; + delete[] data_flashed; + + ret = flash_device.deinit(); + TEST_ASSERT_EQUAL_INT32(ret, 0); +} + +void flashiap_write_test() +{ + FlashIAP flash_device; + uint32_t ret = flash_device.init(); + TEST_ASSERT_EQUAL_INT32(ret, 0); + + // get the last sector size + uint32_t sector_size = flash_device.get_sector_size(flash_device.get_flash_start() + flash_device.get_flash_size() - 1UL); + TEST_ASSERT_NOT_EQUAL(sector_size, 0); + const uint8_t test_value = 0xCE; + uint8_t *data = new uint8_t[sector_size]; + for (uint32_t i = 0; i < sector_size; i++) { + data[i] = test_value; + } + + // the one before the last page in the system + uint32_t address = (flash_device.get_flash_start() + flash_device.get_flash_size()) - (sector_size); + TEST_ASSERT_TRUE(address != 0UL); + ret = flash_device.write(data, address, sector_size); + TEST_ASSERT_EQUAL_INT32(ret, 0); + + uint8_t *data_flashed = new uint8_t[sector_size]; + ret = flash_device.read(data_flashed, address, sector_size); + TEST_ASSERT_EQUAL_INT32(ret, 0); + TEST_ASSERT_EQUAL_UINT8_ARRAY(data, data_flashed, sector_size); + delete[] data; + delete[] data_flashed; + + ret = flash_device.deinit(); + TEST_ASSERT_EQUAL_INT32(ret, 0); +} + +void flashiap_program_error_test() +{ + FlashIAP flash_device; + uint32_t ret = flash_device.init(); + TEST_ASSERT_EQUAL_INT32(ret, 0); + + // get the last sector size (flash size - 1) + uint32_t sector_size = flash_device.get_sector_size(flash_device.get_flash_start() + flash_device.get_flash_size() - 1UL); + TEST_ASSERT_NOT_EQUAL(sector_size, 0); + const uint8_t test_value = 0xCE; + uint8_t *data = new uint8_t[sector_size]; + for (uint32_t i = 0; i < sector_size; i++) { + data[i] = test_value; + } + + // the one before the last page in the system + uint32_t address = (flash_device.get_flash_start() + flash_device.get_flash_size()) - (sector_size); + TEST_ASSERT_TRUE(address != 0UL); + + // unaligned address + address += 1; + ret = flash_device.erase(address, sector_size); + TEST_ASSERT_EQUAL_INT32(ret, -1); + ret = flash_device.program(data, address, sector_size); + TEST_ASSERT_EQUAL_INT32(ret, -1); + + // unaligned sector size + sector_size += 1; + ret = flash_device.program(data, address, sector_size); + TEST_ASSERT_EQUAL_INT32(ret, -1); + + delete[] data; + + ret = flash_device.deinit(); + TEST_ASSERT_EQUAL_INT32(ret, 0); +} + +void flashiap_write_error_test() +{ + FlashIAP flash_device; + uint32_t ret = flash_device.init(); + TEST_ASSERT_EQUAL_INT32(ret, 0); + + // get the last sector size + uint32_t sector_size = flash_device.get_sector_size(flash_device.get_flash_start() + flash_device.get_flash_size() - 1UL); + TEST_ASSERT_NOT_EQUAL(sector_size, 0); + const uint8_t test_value = 0xCE; + uint8_t *data = new uint8_t[sector_size]; + for (uint32_t i = 0; i < sector_size; i++) { + data[i] = test_value; + } + + // the one before the last page in the system + uint32_t address = (flash_device.get_flash_start() + flash_device.get_flash_size()) - (sector_size); + TEST_ASSERT_TRUE(address != 0UL); + + // unaligned address + address += 1; + ret = flash_device.write(data, address, sector_size); + TEST_ASSERT_EQUAL_INT32(ret, -1); + + // unaligned sector size + address -= 1; + sector_size += 1; + ret = flash_device.write(data, address, sector_size); + TEST_ASSERT_EQUAL_INT32(ret, -1); + + delete[] data; + + ret = flash_device.deinit(); + TEST_ASSERT_EQUAL_INT32(ret, 0); +} + +utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) { + greentea_case_failure_abort_handler(source, reason); + return STATUS_CONTINUE; +} + +Case cases[] = { + Case("FlashIAP - init", flashiap_init_test, greentea_failure_handler), + Case("FlashIAP - program", flashiap_program_test, greentea_failure_handler), + Case("FlashIAP - write", flashiap_write_test, greentea_failure_handler), + Case("FlashIAP - program errors", flashiap_program_error_test, greentea_failure_handler), + Case("FlashIAP - write errors", flashiap_write_error_test, greentea_failure_handler), +}; + +utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(20, "default_auto"); + return greentea_test_setup_handler(number_of_cases); +} + +Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); + +int main() { + Harness::run(specification); +} diff --git a/TESTS/mbed_hal/flash/functional_tests/main.cpp b/TESTS/mbed_hal/flash/functional_tests/main.cpp new file mode 100644 index 00000000000..320ba1255fc --- /dev/null +++ b/TESTS/mbed_hal/flash/functional_tests/main.cpp @@ -0,0 +1,190 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 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. + */ + +#if !DEVICE_FLASH + #error [NOT_SUPPORTED] Flash API not supported for this target +#endif + +#include "utest/utest.h" +#include "unity/unity.h" +#include "greentea-client/test_env.h" + +#include "mbed.h" +#include "flash_api.h" +#include "flash_data.h" + +using namespace utest::v1; + +/* + return values to be checked are documented at: + http://arm-software.github.io/CMSIS_5/Pack/html/algorithmFunc.html#Verify +*/ + +#ifndef ALIGN_DOWN +#define ALIGN_DOWN(x, a) ((x)& ~((a) - 1)) +#endif + +void flash_init_test() +{ + flash_t test_flash; + int32_t ret = flash_init(&test_flash); + TEST_ASSERT_EQUAL_INT32(ret, 0); + ret = flash_free(&test_flash); + TEST_ASSERT_EQUAL_INT32(ret, 0); +} + +// Erase sector, write one page, erase sector and write new data +void flash_program_page_test() +{ + flash_t test_flash; + int32_t ret = flash_init(&test_flash); + TEST_ASSERT_EQUAL_INT32(ret, 0); + + uint32_t test_size = flash_get_page_size(&test_flash); + uint8_t *data = new uint8_t[test_size]; + for (uint32_t i = 0; i < test_size; i++) { + data[i] = 0xCE; + } + + // the one before the last page in the system + uint32_t address = flash_get_start_address(&test_flash) + flash_get_size(&test_flash) - (2*test_size); + + // sector size might not be same as page size + uint32_t erase_sector_boundary = ALIGN_DOWN(address, flash_get_sector_size(&test_flash, address)); + ret = flash_erase_sector(&test_flash, erase_sector_boundary); + TEST_ASSERT_EQUAL_INT32(ret, 0); + + ret = flash_program_page(&test_flash, address, data, test_size); + TEST_ASSERT_EQUAL_INT32(ret, 0); + uint8_t *data_flashed = (uint8_t *)address; + TEST_ASSERT_EQUAL_UINT8_ARRAY(data, data_flashed, test_size); + + // sector size might not be same as page size + erase_sector_boundary = ALIGN_DOWN(address, flash_get_sector_size(&test_flash, address)); + ret = flash_erase_sector(&test_flash, erase_sector_boundary); + TEST_ASSERT_EQUAL_INT32(ret, 0); + + // write another data to be certain we are re-flashing + for (uint32_t i = 0; i < test_size; i++) { + data[i] = 0xAC; + } + ret = flash_program_page(&test_flash, address, data, test_size); + TEST_ASSERT_EQUAL_INT32(ret, 0); + TEST_ASSERT_EQUAL_UINT8_ARRAY(data, data_flashed, test_size); + + ret = flash_free(&test_flash); + TEST_ASSERT_EQUAL_INT32(ret, 0); + delete[] data; +} + +void flash_erase_sector_test() +{ + flash_t test_flash; + int32_t ret = flash_init(&test_flash); + TEST_ASSERT_EQUAL_INT32(ret, 0); + + uint32_t sector_size = 0x1000; + uint32_t address = flash_get_start_address(&test_flash) + flash_get_size(&test_flash) - (4*sector_size); + // sector size might not be same as page size + uint32_t erase_sector_boundary = ALIGN_DOWN(address, flash_get_sector_size(&test_flash, address)); + ret = flash_erase_sector(&test_flash, erase_sector_boundary); + TEST_ASSERT_EQUAL_INT32(ret, 0); + + ret = flash_free(&test_flash); + TEST_ASSERT_EQUAL_INT32(ret, 0); +} + +void flash_erase_sector_error_test() +{ + flash_t test_flash; + int32_t ret = flash_init(&test_flash); + TEST_ASSERT_EQUAL_INT32(ret, 0); + + // most common sector size to get an sector address + uint32_t sector_size = 0x1000; + uint32_t address = flash_get_start_address(&test_flash) + flash_get_size(&test_flash) - (4*sector_size); + uint32_t erase_sector_boundary = ALIGN_DOWN(address, flash_get_sector_size(&test_flash, address)); + + // unaligned address + erase_sector_boundary += 1; + ret = flash_erase_sector(&test_flash, erase_sector_boundary); + TEST_ASSERT_EQUAL_INT32(ret, -1); + + ret = flash_free(&test_flash); + TEST_ASSERT_EQUAL_INT32(ret, 0); +} + +void flash_program_page_error_test() +{ + flash_t test_flash; + int32_t ret = flash_init(&test_flash); + TEST_ASSERT_EQUAL_INT32(ret, 0); + + + uint32_t test_size = flash_get_page_size(&test_flash); + // the one before the last page in the system + uint32_t address = flash_get_start_address(&test_flash) + flash_get_size(&test_flash) - (2*test_size); + + // sector size might not be same as page size + uint32_t erase_sector_boundary = ALIGN_DOWN(address, flash_get_sector_size(&test_flash, address)); + ret = flash_erase_sector(&test_flash, erase_sector_boundary); + TEST_ASSERT_EQUAL_INT32(ret, 0); + + // we store the current data, and verify later they have not changed + uint8_t *data = new uint8_t[test_size]; + uint8_t *previous_data = new uint8_t[test_size]; + uint8_t *current_data = (uint8_t *)address; + for (uint32_t i = 0; i < test_size; i++) { + previous_data[i] = *current_data; + data[i] = 0xCE; + current_data++; + } + + address += 1UL; + ret = flash_program_page(&test_flash, address, data, test_size); + TEST_ASSERT_EQUAL_INT32(ret, -1); + TEST_ASSERT_EQUAL_UINT8_ARRAY(previous_data, current_data, test_size); + + ret = flash_free(&test_flash); + TEST_ASSERT_EQUAL_INT32(ret, 0); + delete[] data; + delete[] previous_data; +} + +utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) { + greentea_case_failure_abort_handler(source, reason); + return STATUS_CONTINUE; +} + +Case cases[] = { + Case("Flash - init", flash_init_test, greentea_failure_handler), + Case("Flash - erase sector", flash_erase_sector_test, greentea_failure_handler), + Case("Flash - program page", flash_program_page_test, greentea_failure_handler), + Case("Flash - erase sector errors", flash_erase_sector_error_test, greentea_failure_handler), + Case("Flash - program page errors", flash_program_page_error_test, greentea_failure_handler), + +}; + +utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(20, "default_auto"); + return greentea_test_setup_handler(number_of_cases); +} + +Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); + +int main() { + Harness::run(specification); +} diff --git a/drivers/FlashIAP.cpp b/drivers/FlashIAP.cpp new file mode 100644 index 00000000000..c9b73f042ed --- /dev/null +++ b/drivers/FlashIAP.cpp @@ -0,0 +1,180 @@ +/* mbed Microcontroller Library + * Copyright (c) 2017 ARM Limited + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include "FlashIAP.h" +#include "mbed_assert.h" + + +#ifdef DEVICE_FLASH + +namespace mbed { + +SingletonPtr FlashIAP::_mutex; + +static inline bool is_aligned(uint32_t number, uint32_t alignment) +{ + if ((number % alignment) != 0) { + return false; + } else { + return true; + } +} + +FlashIAP::FlashIAP() +{ + +} + +FlashIAP::~FlashIAP() +{ + +} + +int FlashIAP::init() +{ + int ret = 0; + _mutex->lock(); + if (flash_init(&_flash)) { + ret = -1; + } + _mutex->unlock(); + return ret; +} + +int FlashIAP::deinit() +{ + int ret = 0; + _mutex->lock(); + if (flash_free(&_flash)) { + ret = -1; + } + _mutex->unlock(); + return ret; +} + + +int FlashIAP::read(void *buffer, uint32_t addr, uint32_t size) +{ + _mutex->lock(); + memcpy(buffer, (const void *)addr, size); + _mutex->unlock(); + return 0; +} + +int FlashIAP::program(const void *buffer, uint32_t addr, uint32_t size) +{ + uint32_t page_size = get_page_size(); + uint32_t current_sector_size = flash_get_sector_size(&_flash, addr); + // addr and size should be aligned to page size, and multiple of page size + // page program should not cross sector boundaries + if ((is_aligned(addr, page_size) == false) || + (is_aligned(size, page_size) == false) || + (size < page_size) || + (((addr % current_sector_size) + size) > current_sector_size)) { + return -1; + } + + int ret = 0; + _mutex->lock(); + if (flash_program_page(&_flash, addr, (const uint8_t *)buffer, size)) { + ret = -1; + } + _mutex->unlock(); + return ret; +} + +int FlashIAP::write(const void *buffer, uint32_t addr, uint32_t size) +{ + int ret = 0; + // erase will lock + if (erase(addr, size) != 0) { + return -1; + } + _mutex->lock(); + ret = program(buffer, addr, size); + _mutex->unlock(); + return ret; +} + +bool FlashIAP::is_aligned_to_sector(uint32_t addr, uint32_t size) +{ + uint32_t current_sector_size = flash_get_sector_size(&_flash, addr); + if ((is_aligned(size, current_sector_size) == false) || + (is_aligned(addr, current_sector_size) == false)) { + return false; + } else { + return true; + } +} + +int FlashIAP::erase(uint32_t addr, uint32_t size) +{ + uint32_t current_sector_size = 0UL; + + if (is_aligned_to_sector(addr, size) == false) { + return -1; + } + + int32_t ret = 0; + _mutex->lock(); + while (size) { + ret = flash_erase_sector(&_flash, addr); + if (ret != 0) { + ret = -1; + break; + } + current_sector_size = flash_get_sector_size(&_flash, addr); + if (is_aligned_to_sector(addr, size) == false) { + ret = -1; + break; + } + size -= current_sector_size; + addr += current_sector_size; + } + _mutex->unlock(); + return ret; +} + +uint32_t FlashIAP::get_page_size() const +{ + return flash_get_page_size(&_flash); +} + +uint32_t FlashIAP::get_sector_size(uint32_t addr) const +{ + return flash_get_sector_size(&_flash, addr); +} + +uint32_t FlashIAP::get_flash_start() const +{ + return flash_get_start_address(&_flash); +} + +uint32_t FlashIAP::get_flash_size() const +{ + return flash_get_size(&_flash); +} + +} + +#endif diff --git a/drivers/FlashIAP.h b/drivers/FlashIAP.h new file mode 100644 index 00000000000..18c856eff2c --- /dev/null +++ b/drivers/FlashIAP.h @@ -0,0 +1,148 @@ +/* mbed Microcontroller Library + * Copyright (c) 2017 ARM Limited + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef MBED_FLASHIAP_H +#define MBED_FLASHIAP_H + +#ifdef DEVICE_FLASH + +#include "flash_api.h" +#include "platform/SingletonPtr.h" +#include "platform/PlatformMutex.h" + +namespace mbed { + +/** \addtogroup drivers */ +/** @{*/ + +/** Flash IAP driver. It invokes flash HAL functions. + * + * Note Synchronization level: Thread safe + */ +class FlashIAP { +public: + FlashIAP(); + ~FlashIAP(); + + /** Initialize a flash IAP device + * + * Should be called once per lifetime of the object. + * @return 0 on success or a negative error code on failure + */ + int init(); + + /** Deinitialize a flash IAP device + * + * @return 0 on success or a negative error code on failure + */ + int deinit(); + + /** Read data from a flash device. + * + * This method invokes memcpy - reads number of bytes from the address + * + * @param buffer Buffer to write to + * @param addr Flash address to begin reading from + * @param size Size to read in bytes + * @return 0 on success, negative error code on failure + */ + int read(void *buffer, uint32_t addr, uint32_t size); + + /** Write data at defined flash address + * + * A write is equivalent to an erase followed by a program. + * + * @param buffer Buffer of data to be written + * @param addr Address of a page to begin writing to + * @param size Size to write in bytes, must be a multiple of program and sector sizes + * @return 0 on success, negative error code on failure + */ + int write(const void *buffer, uint32_t addr, uint32_t size); + + /** Program data to pages + * + * The sectors must have been erased prior to being programmed + * + * @param buffer Buffer of data to be written + * @param addr Address of a page to begin writing to, must be a multiple of program and sector sizes + * @param size Size to write in bytes, must be a multiple of program and sector sizes + * @return 0 on success, negative error code on failure + */ + int program(const void *buffer, uint32_t addr, uint32_t size); + + /** Erase sectors + * + * The state of an erased sector is undefined until it has been programmed + * + * @param addr Address of a sector to begin erasing, must be a multiple of the sector size + * @param size Size to erase in bytes, must be a multiple of the sector size + * @return 0 on success, negative error code on failure + */ + int erase(uint32_t addr, uint32_t size); + + /** Get the sector size at the defined address + * + * Sector size might differ at address ranges. + * An example <0-0x1000, sector size=1024; 0x10000-0x20000, size=2048> + * + * @return Size of a sector in bytes + */ + uint32_t get_sector_size(uint32_t addr) const; + + /** Get the flash start address + * + * @return Flash start address + */ + uint32_t get_flash_start() const; + + /** Get the flash size + * + * @return Flash size + */ + uint32_t get_flash_size() const; + + /** Get the program page size + * + * @return Size of a program page in bytes + */ + uint32_t get_page_size() const; + +private: + + /** Check if address and size are aligned to a sector + * + * @param number Number that should be aligned + * @param alignment Defined alignment for a number to be checked + * @return true on success, false on failure + */ + bool is_aligned_to_sector(uint32_t addr, uint32_t size); + + flash_t _flash; + static SingletonPtr _mutex; +}; + +} /* namespace mbed */ + +#endif /* DEVICE_FLASH */ + +#endif /* MBED_FLASHIAP_H */ + +/** @}*/ diff --git a/hal/TARGET_FLASH_CMSIS_ALGO/flash_common_algo.c b/hal/TARGET_FLASH_CMSIS_ALGO/flash_common_algo.c new file mode 100644 index 00000000000..b3dc03bdc7c --- /dev/null +++ b/hal/TARGET_FLASH_CMSIS_ALGO/flash_common_algo.c @@ -0,0 +1,172 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 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 "flash_data.h" +#include "critical.h" + +#define MBED_FLASH_ALGO_ERASE 1UL +#define MBED_FLASH_ALGO_PROGRAM 2UL + +extern uint32_t SystemCoreClock; + +/* + This binary blob (thumb code) sets r9 (static base) as the code we are jumping to + is PIC (position independent code). + + These are the instructions (r0 is a pointer to arg_t): + push {r5, lr, r4} + mov r5, r9 + push {r5} + ldr r5, [r0, #20] + ldr r3, [r0, #16] + mov r9, r3 + ldr r3, [r0, #12] + ldr r2, [r0, #8] + ldr r1, [r0, #4] + ldr r0, [r0, #0] + blx r5 + pop {r5} + mov r9, r5 + pop {r4-r5, pc} + bx r14 +*/ +static uint32_t jump_to_flash_algo[] = { + 0x464DB530, + 0x6945B420, + 0x46996903, + 0x688268C3, + 0x68006841, + 0xBC2047A8, + 0xBD3046A9 +}; + +static uint32_t get_sector_index(const flash_t *obj, uint32_t address) +{ + // check where address belongs to + size_t sector_index = 0; + size_t sectors_count = sizeof(obj->target_config->sectors) / sizeof(sector_info_t); + for (; sector_index < sectors_count; sector_index++) { + if ((address > obj->target_config->sectors[sector_index].start) && + (address < (obj->target_config->sectors[sector_index].start +obj->target_config->sectors[sector_index].size))) { + break; + } + } + return sector_index; +} + +// should be called within critical section +static int32_t flash_algo_init(flash_t *obj, uint32_t address, uint32_t function) +{ + args_t arguments = { + .r0 = address, + .r1 = SystemCoreClock, + .r2 = function, + .r3 = 0, + .r9 = (uint32_t)obj->flash_algo->algo_blob + obj->flash_algo->static_base, + .pc = (uint32_t)obj->flash_algo->algo_blob + obj->flash_algo->init + }; + return ((flash_algo_jump_t)(((uint32_t)&jump_to_flash_algo) | 1))(&arguments); +} + +// should be called within critical section +static int32_t flash_algo_uninit(flash_t *obj, uint32_t address, uint32_t function) +{ + args_t arguments = { + .r0 = address, + .r1 = SystemCoreClock, + .r2 = function, + .r3 = 0, + .r9 = (uint32_t)obj->flash_algo->algo_blob + obj->flash_algo->static_base, + .pc = (uint32_t)obj->flash_algo->algo_blob + obj->flash_algo->uninit + }; + return ((flash_algo_jump_t)(((uint32_t)&jump_to_flash_algo) | 1))(&arguments); +} + + +int32_t flash_init(flash_t *obj) +{ + flash_set_target_config(obj); + return 0; +} + +int32_t flash_free(flash_t *obj) +{ + return 0; +} + +int32_t flash_erase_sector(flash_t *obj, uint32_t address) +{ + core_util_critical_section_enter(); + flash_algo_init(obj, address, MBED_FLASH_ALGO_ERASE); + + args_t arguments = { + .r0 = address, + .r1 = 0, + .r2 = 0, + .r3 = 0, + .r9 = (uint32_t)obj->flash_algo->algo_blob + obj->flash_algo->static_base, + .pc = (uint32_t)obj->flash_algo->algo_blob + obj->flash_algo->erase_sector + }; + int32_t ret = ((flash_algo_jump_t)(((uint32_t)&jump_to_flash_algo) | 1))(&arguments); + + flash_algo_uninit(obj, address, MBED_FLASH_ALGO_ERASE); + core_util_critical_section_exit(); + return ret ? -1 : 0; +} + + +int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data, uint32_t size) +{ + core_util_critical_section_enter(); + flash_algo_init(obj, address, MBED_FLASH_ALGO_PROGRAM); + + args_t arguments = { + .r0 = address, + .r1 = size, + .r2 = (uint32_t)data, + .r3 = 0, + .r9 = (uint32_t)obj->flash_algo->algo_blob + obj->flash_algo->static_base, + .pc = (uint32_t)obj->flash_algo->algo_blob + obj->flash_algo->program_page + }; + int32_t ret = ((flash_algo_jump_t)(((uint32_t)&jump_to_flash_algo) | 1))(&arguments); + + flash_algo_uninit(obj, address, MBED_FLASH_ALGO_PROGRAM); + core_util_critical_section_exit(); + return ret ? -1 : 0; +} + + +uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address) +{ + uint32_t sector_index = get_sector_index(obj, address); + return obj->target_config->sectors[sector_index].size; +} + +uint32_t flash_get_page_size(const flash_t *obj) +{ + return obj->target_config->page_size; +} + +uint32_t flash_get_start_address(const flash_t *obj) +{ + return obj->target_config->flash_start; +} + +uint32_t flash_get_size(const flash_t *obj) +{ + return obj->target_config->flash_size; +} diff --git a/hal/TARGET_FLASH_CMSIS_ALGO/flash_data.h b/hal/TARGET_FLASH_CMSIS_ALGO/flash_data.h new file mode 100644 index 00000000000..e00e06d757e --- /dev/null +++ b/hal/TARGET_FLASH_CMSIS_ALGO/flash_data.h @@ -0,0 +1,84 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 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. + */ +#ifndef MBED_FLASH_DATA_H +#define MBED_FLASH_DATA_H + +// This file is automagically generated from flash-algo repository + +#include + +// Target flash algorithm structure +typedef struct { + const uint32_t init; + const uint32_t uninit; + const uint32_t erase_sector; + const uint32_t program_page; + const uint32_t static_base; + uint32_t *algo_blob; +} flash_algo_t; + +typedef struct { + const uint32_t start; + const uint32_t size; +} sector_info_t; + +typedef struct { + const uint32_t page_size; + const uint32_t flash_start; + const uint32_t flash_size; + const sector_info_t *sectors; +} flash_target_config_t; + +// Target flash configuration +struct flash_s { + const flash_target_config_t *target_config; + const flash_algo_t *flash_algo; +}; + +typedef struct { + uint32_t r0; + uint32_t r1; + uint32_t r2; + uint32_t r3; + uint32_t r9; + uint32_t pc; +} args_t; + +typedef int32_t (*flash_algo_jump_t)(args_t*); + +// prototypes for flash algo CMSIS API + +typedef int (*CMSIS_Algo_Function_Init)(unsigned long adr, unsigned long clk, unsigned long fnc); +typedef int (*CMSIS_Algo_Function_UnInit)(unsigned long fnc); +typedef int (*CMSIS_Algo_Function_EraseSector)(unsigned long adr); +typedef int (*CMSIS_Algo_Function_EraseChip)(void); +typedef int (*CMSIS_Algo_Function_ProgramPage)(unsigned long adr, unsigned long sz, unsigned char *buf); +typedef unsigned long (*CMSIS_Algo_Function_Verify)(unsigned long adr, unsigned long sz, unsigned char *buf); + +#ifdef __cplusplus +extern "C" { +#endif + +/* Set target configuration + */ +void flash_set_target_config(flash_t *obj); + +#ifdef __cplusplus +}; +#endif + + +#endif diff --git a/hal/flash_api.h b/hal/flash_api.h new file mode 100644 index 00000000000..cc1d5bb0474 --- /dev/null +++ b/hal/flash_api.h @@ -0,0 +1,117 @@ +/** \addtogroup hal */ +/** @{*/ + +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 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. + */ +#ifndef MBED_FLASH_API_H +#define MBED_FLASH_API_H + +#include "device.h" +#include + +#if DEVICE_FLASH + +typedef struct flash_s flash_t; + +#if TARGET_FLASH_CMSIS_ALGO +#include "flash_data.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup flash_hal Flash HAL API + * @{ + */ + +/** 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); + +/** 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); + +/** 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); + +/** 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 in bytes + * @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); + +/** 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); + +/** Get page size + * + * @param obj The flash object + * @param address The page starting address + * @return The size of a page + */ +uint32_t flash_get_page_size(const flash_t *obj); + +/** Get start address for the flash region + * + * @param obj The flash objects + * @return The start address for the flash region + */ +uint32_t flash_get_start_address(const flash_t *obj); + +/** Get the flash region size + * + * @param obj The flash objects + * @return The flash region size + */ +uint32_t flash_get_size(const flash_t *obj); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif + +#endif + +/** @}*/ diff --git a/mbed.h b/mbed.h index 0e71670a0d0..84c7a263c31 100644 --- a/mbed.h +++ b/mbed.h @@ -80,6 +80,7 @@ #include "drivers/Ethernet.h" #include "drivers/CAN.h" #include "drivers/RawSerial.h" +#include "drivers/FlashIAP.h" // mbed Internal components #include "drivers/Timer.h" diff --git a/targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL46Z/flash_api.c b/targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL46Z/flash_api.c new file mode 100644 index 00000000000..cf442a1f0ec --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL46Z/flash_api.c @@ -0,0 +1,100 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 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 "flash_data.h" +#include "critical.h" + +// This file is automagically generated + +// This is a flash algo binary blob. It is PIC (position independent code) that should be stored in RAM +static uint32_t FLASH_ALGO[] = { + 0xb5104935, 0x60084449, 0x21004834, 0x48356001, 0x44484a33, 0x22016002, 0x04926041, 0x02926082, + 0x220560c2, 0x61420692, 0x03122201, 0x46026182, 0x70113220, 0x62411e49, 0xf939f000, 0xd0002800, + 0xbd102001, 0x47702000, 0xb5084a27, 0x0349447a, 0x0c0a9200, 0x48234601, 0x44482300, 0xf9c4f000, + 0xd0002800, 0xbd082001, 0x491fb508, 0x481d4479, 0x44483920, 0xf8a1f000, 0xd10e2800, 0x4478481a, + 0x38324b1a, 0x9000447b, 0x22044816, 0x44484918, 0xf967f000, 0xd0002800, 0xbd082001, 0x4b12b510, + 0x4601447b, 0x2201480f, 0x02923b54, 0xf0004448, 0xbd10f8b6, 0x460cb538, 0x4479490b, 0x9100396e, + 0x48084601, 0x46224613, 0xf0004448, 0x2800f94a, 0x2001d000, 0x0000bd38, 0x00000004, 0x40048100, + 0x40020000, 0x00000008, 0x000000a5, 0x0000055c, 0x0000040c, 0x4604b570, 0x25006800, 0x061b7803, + 0x2370d5fc, 0x20007003, 0x0003e03a, 0xfa5df000, 0x0f0b070c, 0x1f1b1713, 0x2f2b2723, 0x68263633, + 0x71f37813, 0x6826e02a, 0x71b37853, 0x6826e026, 0x71737893, 0x6826e022, 0x713378d3, 0x6826e01e, + 0x72f37913, 0x6826e01a, 0x72b37953, 0x6826e016, 0x72737993, 0x6826e012, 0x723379d3, 0x6826e00e, + 0x73f37a13, 0x6826e00a, 0x73b37a53, 0x6826e006, 0x73737a93, 0x6826e002, 0x73337ad3, 0xb2c01c40, + 0xd9c24288, 0x20806821, 0xe0037008, 0x1c416a60, 0x4780d000, 0x78006820, 0xd5f70600, 0x78006820, + 0xd5010681, 0xe0062504, 0xd50106c1, 0xe0022508, 0xd00007c0, 0x46282510, 0xb508bd70, 0x2244460b, + 0x700a4669, 0x2100466a, 0xbd084798, 0x4614b538, 0xd002078a, 0x300120ff, 0x6842bd38, 0xd803428a, + 0x18d36883, 0xd80d428b, 0x428b68c3, 0x6902d803, 0x428a189a, 0x2002d801, 0x2201bd38, 0x05d21ac9, + 0xe0001889, 0x22081a89, 0x701a466b, 0x705a0c0a, 0x709a0a0a, 0x466a70d9, 0x47a02103, 0xb5ffbd38, + 0x4615b081, 0x27019a01, 0x26006852, 0x02bf1948, 0xd804428a, 0x689b9b01, 0x428318d3, 0x9a01d20f, + 0x428a68d2, 0x9b01d804, 0x18d3691b, 0xd2014283, 0xe0292602, 0x21011a88, 0x184405c9, 0x1a8ce000, + 0x46204639, 0xf904f000, 0xd0022900, 0x360126ff, 0x4639e01a, 0xf0004628, 0x2900f8fb, 0x2601d012, + 0x2009e012, 0x70084669, 0x70480c20, 0x70880a20, 0x9b0470cc, 0x2103466a, 0x47989801, 0xd1030006, + 0x19e41bed, 0xd1ec2d00, 0xb0054630, 0xb5f0bdf0, 0x24006801, 0x0612780a, 0x2270d5fc, 0x6802700a, + 0x71d12103, 0x22806801, 0x6803718a, 0x71592100, 0x23fc6805, 0x6803712b, 0x680373d9, 0x6802701a, + 0x061b7813, 0x7a55d5fc, 0x07177a12, 0x0f3f2201, 0x10560412, 0xf000003b, 0x0910f968, 0x0b0d0b0b, + 0x0b0b0b0b, 0x090d0b0b, 0x0e090b0b, 0xe0026102, 0xe0006101, 0x072a6106, 0x00130f12, 0xf955f000, + 0x0c090910, 0x1815120f, 0x091f1d1b, 0x09090909, 0x61c10a09, 0xbdf04620, 0x03092101, 0x2101e7f9, + 0xe7f602c9, 0x02892101, 0x2101e7f3, 0xe7f00249, 0x310121ff, 0x2180e7ed, 0x2140e7eb, 0x2120e7e9, + 0xb5fee7e7, 0x46074616, 0x2000461d, 0x078b198a, 0x20ffd002, 0xbdfe3001, 0xd00107b3, 0xbdfe2001, + 0x428b687b, 0x68bcd803, 0x4294191c, 0x68fbd20d, 0xd803428b, 0x191c693c, 0xd2014294, 0xbdfe2002, + 0x1ac92201, 0x188c05d2, 0x1acce01b, 0x2006e019, 0x70084669, 0x70480c20, 0x70880a20, 0x78e870cc, + 0x78a87108, 0x78687148, 0x78287188, 0x9b0871c8, 0x2107466a, 0x47984638, 0xd1e02800, 0x1f361d24, + 0x2e001d2d, 0xbdfed1e3, 0x4615b5fe, 0x68424604, 0x184000a8, 0x428a461e, 0x68a3d803, 0x428b18d3, + 0x68e3d808, 0xd803428b, 0x19db6927, 0xd801428b, 0xbdfe2002, 0xd8054282, 0x18d368a3, 0xd3014283, + 0xe00a1a8f, 0x428268e2, 0x6923d903, 0x428318d3, 0x1a88d3ee, 0x05c92101, 0x21041847, 0xf0004638, + 0x2900f817, 0x20ffd002, 0xbdfe3001, 0x46692001, 0x0c387008, 0x0a387048, 0x70cf7088, 0x71080a28, + 0x718e714d, 0x466a9b08, 0x46202106, 0xbdfe4798, 0x09032200, 0xd32c428b, 0x428b0a03, 0x2300d311, + 0xe04e469c, 0x430b4603, 0x2200d43c, 0x428b0843, 0x0903d331, 0xd31c428b, 0x428b0a03, 0x4694d301, + 0x09c3e03f, 0xd301428b, 0x1ac001cb, 0x09834152, 0xd301428b, 0x1ac0018b, 0x09434152, 0xd301428b, + 0x1ac0014b, 0x09034152, 0xd301428b, 0x1ac0010b, 0x08c34152, 0xd301428b, 0x1ac000cb, 0x08834152, + 0xd301428b, 0x1ac0008b, 0x08434152, 0xd301428b, 0x1ac0004b, 0x1a414152, 0x4601d200, 0x46104152, + 0xe05d4770, 0xd0000fca, 0x10034249, 0x4240d300, 0x22004053, 0x0903469c, 0xd32d428b, 0x428b0a03, + 0x22fcd312, 0xba120189, 0x428b0a03, 0x0189d30c, 0x428b1192, 0x0189d308, 0x428b1192, 0x0189d304, + 0x1192d03a, 0x0989e000, 0x428b09c3, 0x01cbd301, 0x41521ac0, 0x428b0983, 0x018bd301, 0x41521ac0, + 0x428b0943, 0x014bd301, 0x41521ac0, 0x428b0903, 0x010bd301, 0x41521ac0, 0x428b08c3, 0x00cbd301, + 0x41521ac0, 0x428b0883, 0x008bd301, 0x41521ac0, 0x0843d2d9, 0xd301428b, 0x1ac0004b, 0x1a414152, + 0x4601d200, 0x41524663, 0x4610105b, 0x4240d301, 0xd5002b00, 0x47704249, 0x105b4663, 0x4240d300, + 0x2000b501, 0x46c046c0, 0xb430bd02, 0x1e644674, 0x1c647825, 0xd20042ab, 0x5d63461d, 0x18e3005b, + 0x4718bc30, 0xfffffffe, 0xffffffff, 0xfffffffe, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 +}; + +static const flash_algo_t flash_algo_config = { + .init = 0x1, + .uninit = 0x45, + .erase_sector = 0x9d, + .program_page = 0xb5, + .static_base = 0x5f0, + .algo_blob = FLASH_ALGO, +}; + +static const sector_info_t sectors_info[] = { + {0x0, 0x400}, +}; + +static const flash_target_config_t flash_target_config = { + .page_size = 0x100, + .flash_start = 0x0, + .flash_size = 0x40000, + .sectors = sectors_info, +}; + +void flash_set_target_config(flash_t *obj) +{ + obj->flash_algo = &flash_algo_config; + obj->target_config = &flash_target_config; +} diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/flash_api.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/flash_api.c new file mode 100644 index 00000000000..5bdbb79dfa4 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/flash_api.c @@ -0,0 +1,86 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 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 "flash_data.h" +#include "critical.h" + +// This file is automagically generated + +// This is a flash algo binary blob. It is PIC (position independent code) that should be stored in RAM +static uint32_t FLASH_ALGO[] = { + 0xb5104938, 0x60084449, 0xf24c4837, 0x81c15120, 0x1128f64d, 0x880181c1, 0x0101f021, 0x48348001, + 0x44484932, 0x1280f44f, 0x21006001, 0x1201e9c0, 0x52a0f04f, 0xf44f6142, 0x61824280, 0x1020f880, + 0x62411e49, 0xf939f000, 0xd0002800, 0xbd102001, 0x47702000, 0x4a27b508, 0x9200447a, 0x02cff3c1, + 0x48234601, 0x44482300, 0xf92cf000, 0xd0002800, 0xbd082001, 0x491fb508, 0x481d4479, 0x44483920, + 0xf89ff000, 0xd10f2800, 0x4478481a, 0x38324b1a, 0x9000447b, 0x22084816, 0x6181f44f, 0xf0004448, + 0x2800f959, 0x2001d000, 0x4b12bd08, 0x4601447b, 0x3b54480f, 0x5280f44f, 0xf0004448, 0xb508b8b6, + 0x1dc94613, 0x0207f021, 0x4479490a, 0x91003972, 0x48074601, 0xf0004448, 0x2800f93d, 0x2001d000, + 0x0000bd08, 0x00000004, 0x40052000, 0x40020000, 0x00000008, 0x000000a1, 0x0000037c, 0x4604b570, + 0x25006800, 0x061b7803, 0x2370d5fc, 0x20007003, 0x280ce03a, 0xe8dfd236, 0x0a06f000, 0x1a16120e, + 0x2a26221e, 0x6826322e, 0x71f37813, 0x6826e02a, 0x71b37853, 0x6826e026, 0x71737893, 0x6826e022, + 0x713378d3, 0x6826e01e, 0x72f37913, 0x6826e01a, 0x72b37953, 0x6826e016, 0x72737993, 0x6826e012, + 0x723379d3, 0x6826e00e, 0x73f37a13, 0x6826e00a, 0x73b37a53, 0x6826e006, 0x73737a93, 0x6826e002, + 0x73337ad3, 0xb2c01c40, 0xd9c24288, 0x20806821, 0xe0037008, 0x1c416a60, 0x4780d000, 0x78006820, + 0xd5f70600, 0x78006820, 0xd5010681, 0xe0062504, 0xd50106c1, 0xe0022508, 0xd00007c0, 0x46282510, + 0xb508bd70, 0x460b2244, 0x2000f88d, 0x2100466a, 0xbd084798, 0x4614b538, 0xd002070a, 0x7080f44f, + 0x6843bd38, 0xd803428b, 0x441a6882, 0xd80c428a, 0x428b68c3, 0x6902d803, 0x428a441a, 0x2002d801, + 0x1ac9bd38, 0x0100f501, 0x1ac9e000, 0xf88d2208, 0x0c0a2000, 0x2001f88d, 0xf88d0a0a, 0xf88d2002, + 0x466a1003, 0x47a02103, 0xe92dbd38, 0x460745f8, 0x46164698, 0x2000687b, 0x428b198a, 0x68bcd803, + 0x4294441c, 0x68fbd20e, 0xd803428b, 0x441c693c, 0xd2024294, 0xe8bd2002, 0x1acc85f8, 0x0400f504, + 0xe0022500, 0xf44f1acc, 0xfbb45580, 0xfb05f1f5, 0xb1114111, 0x7080f44f, 0xfbb6e7ed, 0xfb05f1f5, + 0xb1a96111, 0xe7e62001, 0xa000f88d, 0xf88d0c20, 0x0a200001, 0x0002f88d, 0x4003f88d, 0x2103466a, + 0x46434638, 0x28004798, 0x1b76d1d5, 0xe001442c, 0x0a09f04f, 0xd1e72e00, 0x4601e7cd, 0x61082000, + 0x477061c8, 0x41fce92d, 0x9d086846, 0x1402eb01, 0xd803428e, 0x44376887, 0xd80a428f, 0x428f68c7, + 0xf8d0d804, 0x4467c010, 0xd802428f, 0xe8bd2002, 0x42a681fc, 0x6887d805, 0x42a74437, 0x1b89d301, + 0x68c6e009, 0xd90342a6, 0x44376907, 0xd3ed42a7, 0xf5011b89, 0x24100100, 0xf6f4fbb1, 0x1416fb04, + 0xf44fb114, 0xe7e27080, 0xf88d2401, 0x0c0c4000, 0x4001f88d, 0xf88d0a0c, 0xf88d4002, 0x0a111003, + 0x1004f88d, 0x2005f88d, 0x3006f88d, 0x2106466a, 0xe7cc47a8, 0x43fee92d, 0x46074616, 0x2000461c, + 0xf8dd198a, 0x074b8028, 0xf44fd003, 0xe8bd7080, 0x077383fe, 0x2001d001, 0x687be7f9, 0xd803428b, + 0x441d68bd, 0xd20c4295, 0x428b68fb, 0x693dd803, 0x4295441d, 0x2002d201, 0x1acde7e9, 0x0500f505, + 0x1acde02e, 0x2007e02c, 0x0000f88d, 0xf88d0c28, 0x0a280001, 0x0002f88d, 0x5003f88d, 0xf88d78e0, + 0x78a00004, 0x0005f88d, 0xf88d7860, 0x78200006, 0x0007f88d, 0xf88d79e0, 0x79a00008, 0x0009f88d, + 0xf88d7960, 0x7920000a, 0x000bf88d, 0x210b466a, 0x46434638, 0x28004798, 0x3508d1b9, 0x34083e08, + 0xd1d02e00, 0x0000e7b3, 0xfffffffe, 0x00000000, 0xffffffff, 0xfffffffe, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000 +}; + +static const flash_algo_t flash_algo_config = { + .init = 0x1UL, + .uninit = 0x51, + .erase_sector = 0xab, + .program_page = 0xbf, + .static_base = 0x418, + .algo_blob = FLASH_ALGO, +}; + +static const sector_info_t sectors_info[] = { + {0x0, 0x1000}, +}; + +static const flash_target_config_t flash_target_config = { + .page_size = 0x200, + .flash_start = 0x0, + .flash_size = 0x100000, + .sectors = sectors_info, +}; + +void flash_set_target_config(flash_t *obj) +{ + obj->flash_algo = &flash_algo_config; + obj->target_config = &flash_target_config; +} diff --git a/targets/targets.json b/targets/targets.json index a17911c9ef0..c0d94a007c5 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -448,12 +448,12 @@ "KL46Z": { "supported_form_factors": ["ARDUINO"], "core": "Cortex-M0+", - "extra_labels": ["Freescale", "KLXX"], + "extra_labels": ["Freescale", "KLXX", "FLASH_CMSIS_ALGO"], "is_disk_virtual": true, "supported_toolchains": ["GCC_ARM", "ARM", "IAR"], "inherits": ["Target"], "detect_code": ["0220"], - "device_has": ["ANALOGIN", "ANALOGOUT", "ERROR_RED", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SEMIHOST", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], + "device_has": ["ANALOGIN", "ANALOGOUT", "ERROR_RED", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SEMIHOST", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES", "FLASH"], "release_versions": ["2", "5"], "device_name": "MKL46Z256xxx4" }, @@ -573,12 +573,12 @@ "supported_form_factors": ["ARDUINO"], "core": "Cortex-M4F", "supported_toolchains": ["ARM", "GCC_ARM", "IAR"], - "extra_labels": ["Freescale", "MCUXpresso_MCUS", "KSDK2_MCUS", "FRDM", "KPSDK_MCUS", "KPSDK_CODE", "MCU_K64F"], + "extra_labels": ["Freescale", "MCUXpresso_MCUS", "KSDK2_MCUS", "FRDM", "KPSDK_MCUS", "KPSDK_CODE", "MCU_K64F", "FLASH_CMSIS_ALGO"], "is_disk_virtual": true, "macros": ["CPU_MK64FN1M0VMD12", "FSL_RTOS_MBED"], "inherits": ["Target"], "detect_code": ["0240"], - "device_has": ["ANALOGIN", "ANALOGOUT", "ERROR_RED", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPI_ASYNCH", "SPISLAVE", "STDIO_MESSAGES", "STORAGE", "TRNG"], + "device_has": ["ANALOGIN", "ANALOGOUT", "ERROR_RED", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPI_ASYNCH", "SPISLAVE", "STDIO_MESSAGES", "STORAGE", "TRNG", "FLASH"], "features": ["LWIP", "STORAGE"], "release_versions": ["2", "5"], "device_name": "MK64FN1M0xxx12" @@ -587,22 +587,22 @@ "inherits": ["Target"], "core": "Cortex-M4F", "supported_toolchains": ["ARM", "GCC_ARM"], - "extra_labels": ["Freescale", "MCUXpresso_MCUS", "KSDK2_MCUS", "KPSDK_MCUS", "KPSDK_CODE", "MCU_K64F"], + "extra_labels": ["Freescale", "MCUXpresso_MCUS", "KSDK2_MCUS", "KPSDK_MCUS", "KPSDK_CODE", "MCU_K64F", "FLASH_CMSIS_ALGO"], "is_disk_virtual": true, "macros": ["CPU_MK64FN1M0VMD12", "FSL_RTOS_MBED", "TARGET_K64F"], - "device_has": ["I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPI_ASYNCH", "SPISLAVE", "STDIO_MESSAGES"], + "device_has": ["I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPI_ASYNCH", "SPISLAVE", "STDIO_MESSAGES", "FLASH"], "device_name": "MK64FN1M0xxx12" }, "HEXIWEAR": { "inherits": ["Target"], "core": "Cortex-M4F", - "extra_labels": ["Freescale", "MCUXpresso_MCUS", "KSDK2_MCUS", "MCU_K64F"], + "extra_labels": ["Freescale", "MCUXpresso_MCUS", "KSDK2_MCUS", "MCU_K64F", "FLASH_CMSIS_ALGO"], "supported_toolchains": ["ARM", "GCC_ARM", "IAR"], "macros": ["CPU_MK64FN1M0VMD12", "FSL_RTOS_MBED", "TARGET_K64F"], "is_disk_virtual": true, "default_toolchain": "ARM", "detect_code": ["0214"], - "device_has": ["ANALOGIN", "ANALOGOUT", "ERROR_RED", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPI_ASYNCH", "SPISLAVE", "STDIO_MESSAGES", "TRNG"], + "device_has": ["ANALOGIN", "ANALOGOUT", "ERROR_RED", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPI_ASYNCH", "SPISLAVE", "STDIO_MESSAGES", "TRNG", "FLASH"], "default_lib": "std", "release_versions": ["2", "5"], "device_name": "MK64FN1M0xxx12"