diff --git a/.gitignore b/.gitignore index 8d94e38c87..79c9c6cfae 100644 --- a/.gitignore +++ b/.gitignore @@ -75,3 +75,5 @@ cscope.* *.swp *~ +# Visual Studio Code +.vscode/ diff --git a/TESTS/events/queue/main.cpp b/TESTS/events/queue/main.cpp index bdb58b6eda..e1b77b9972 100644 --- a/TESTS/events/queue/main.cpp +++ b/TESTS/events/queue/main.cpp @@ -70,7 +70,7 @@ SIMPLE_POSTS_TEST(0) void time_func(Timer *t, int ms) { - TEST_ASSERT_INT_WITHIN(2, ms, t->read_ms()); + TEST_ASSERT_INT_WITHIN(5, ms, t->read_ms()); t->reset(); } @@ -210,7 +210,7 @@ void event_class_helper_test() { void event_inference_test() { counter = 0; - EventQueue queue (2048); + EventQueue queue(2048); queue.event(count5, 1, 1, 1, 1, 1).post(); queue.event(count5, 1, 1, 1, 1).post(1); @@ -219,9 +219,16 @@ void event_inference_test() { queue.event(count5, 1).post(1, 1, 1, 1); queue.event(count5).post(1, 1, 1, 1, 1); + queue.event(callback(count5), 1, 1, 1, 1, 1).post(); + queue.event(callback(count5), 1, 1, 1, 1).post(1); + queue.event(callback(count5), 1, 1, 1).post(1, 1); + queue.event(callback(count5), 1, 1).post(1, 1, 1); + queue.event(callback(count5), 1).post(1, 1, 1, 1); + queue.event(callback(count5)).post(1, 1, 1, 1, 1); + queue.dispatch(0); - TEST_ASSERT_EQUAL(counter, 30); + TEST_ASSERT_EQUAL(counter, 60); } diff --git a/TESTS/events/timing/main.cpp b/TESTS/events/timing/main.cpp new file mode 100644 index 0000000000..aa361d8dd2 --- /dev/null +++ b/TESTS/events/timing/main.cpp @@ -0,0 +1,122 @@ +#include "mbed_events.h" +#include "mbed.h" +#include "rtos.h" +#include "greentea-client/test_env.h" +#include "unity.h" +#include "utest.h" +#include +#include + +using namespace utest::v1; + + +// Test delay +#ifndef TEST_EVENTS_TIMING_TIME +#define TEST_EVENTS_TIMING_TIME 20000 +#endif + +#ifndef TEST_EVENTS_TIMING_MEAN +#define TEST_EVENTS_TIMING_MEAN 25 +#endif + +#ifndef M_PI +#define M_PI 3.14159265358979323846264338327950288 +#endif + +// Random number generation to skew timing values +float gauss(float mu, float sigma) { + float x = (float)rand() / ((float)RAND_MAX+1); + float y = (float)rand() / ((float)RAND_MAX+1); + float x2pi = x*2.0*M_PI; + float g2rad = sqrt(-2.0 * log(1.0-y)); + float z = cos(x2pi) * g2rad; + return mu + z*sigma; +} + +float chisq(float sigma) { + return pow(gauss(0, sqrt(sigma)), 2); +} + + +Timer timer; +DigitalOut led(LED1); + +equeue_sema_t sema; + +// Timer timing test +void timer_timing_test() { + timer.reset(); + timer.start(); + int prev = timer.read_us(); + + while (prev < TEST_EVENTS_TIMING_TIME*1000) { + int next = timer.read_us(); + if (next < prev) { + printf("backwards drift %d -> %d (%08x -> %08x)\r\n", + prev, next, prev, next); + } + TEST_ASSERT(next >= prev); + prev = next; + } +} + +// equeue tick timing test +void tick_timing_test() { + unsigned start = equeue_tick(); + int prev = 0; + + while (prev < TEST_EVENTS_TIMING_TIME) { + int next = equeue_tick() - start; + if (next < prev) { + printf("backwards drift %d -> %d (%08x -> %08x)\r\n", + prev, next, prev, next); + } + TEST_ASSERT(next >= prev); + prev = next; + } +} + +// equeue semaphore timing test +void semaphore_timing_test() { + srand(0); + timer.reset(); + timer.start(); + + int err = equeue_sema_create(&sema); + TEST_ASSERT_EQUAL(0, err); + + while (timer.read_ms() < TEST_EVENTS_TIMING_TIME) { + int delay = chisq(TEST_EVENTS_TIMING_MEAN); + + int start = timer.read_us(); + equeue_sema_wait(&sema, delay); + int taken = timer.read_us() - start; + + printf("delay %dms => error %dus\r\n", delay, abs(1000*delay - taken)); + TEST_ASSERT_INT_WITHIN(5000, taken, delay * 1000); + + led = !led; + } + + equeue_sema_destroy(&sema); +} + + +// Test setup +utest::v1::status_t test_setup(const size_t number_of_cases) { + GREENTEA_SETUP((number_of_cases+1)*TEST_EVENTS_TIMING_TIME, "default_auto"); + return verbose_test_setup_handler(number_of_cases); +} + +const Case cases[] = { + Case("Testing accuracy of timer", timer_timing_test), + Case("Testing accuracy of equeue tick", tick_timing_test), + Case("Testing accuracy of equeue semaphore", semaphore_timing_test), +}; + +Specification specification(test_setup, cases); + +int main() { + return !Harness::run(specification); +} + diff --git a/TESTS/mbed_drivers/flashiap/main.cpp b/TESTS/mbed_drivers/flashiap/main.cpp new file mode 100644 index 0000000000..78d9b902f3 --- /dev/null +++ b/TESTS/mbed_drivers/flashiap/main.cpp @@ -0,0 +1,137 @@ + +/* 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(0, ret); + ret = flash_device.deinit(); + TEST_ASSERT_EQUAL_INT32(0, ret); +} + +void flashiap_program_test() +{ + FlashIAP flash_device; + uint32_t ret = flash_device.init(); + TEST_ASSERT_EQUAL_INT32(0, ret); + + // 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); + uint32_t page_size = flash_device.get_page_size(); + TEST_ASSERT_NOT_EQUAL(0, sector_size); + TEST_ASSERT_NOT_EQUAL(0, page_size); + TEST_ASSERT_TRUE(sector_size % page_size == 0); + const uint8_t test_value = 0xCE; + uint8_t *data = new uint8_t[page_size]; + for (uint32_t i = 0; i < page_size; i++) { + data[i] = test_value; + } + + // the one before the last sector 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(0, ret); + + + for (uint32_t i = 0; i < sector_size / page_size; i++) { + uint32_t page_addr = address + i * page_size; + ret = flash_device.program(data, page_addr, page_size); + TEST_ASSERT_EQUAL_INT32(0, ret); + } + + uint8_t *data_flashed = new uint8_t[page_size]; + for (uint32_t i = 0; i < sector_size / page_size; i++) { + uint32_t page_addr = address + i * page_size; + ret = flash_device.read(data_flashed, page_addr, page_size); + TEST_ASSERT_EQUAL_INT32(0, ret); + TEST_ASSERT_EQUAL_UINT8_ARRAY(data, data_flashed, page_size); + } + delete[] data; + delete[] data_flashed; + + ret = flash_device.deinit(); + TEST_ASSERT_EQUAL_INT32(0, ret); +} + +void flashiap_program_error_test() +{ + FlashIAP flash_device; + uint32_t ret = flash_device.init(); + TEST_ASSERT_EQUAL_INT32(0, ret); + + // 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); + uint32_t page_size = flash_device.get_page_size(); + TEST_ASSERT_NOT_EQUAL(0, sector_size); + TEST_ASSERT_NOT_EQUAL(0, page_size); + TEST_ASSERT_TRUE(sector_size % page_size == 0); + const uint8_t test_value = 0xCE; + uint8_t *data = new uint8_t[page_size]; + for (uint32_t i = 0; i < page_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 + ret = flash_device.erase(address + 1, sector_size); + TEST_ASSERT_EQUAL_INT32(-1, ret); + ret = flash_device.program(data, address + 1, page_size); + TEST_ASSERT_EQUAL_INT32(-1, ret); + + // unaligned page size + ret = flash_device.program(data, address, page_size + 1); + TEST_ASSERT_EQUAL_INT32(-1, ret); + + delete[] data; + + ret = flash_device.deinit(); + TEST_ASSERT_EQUAL_INT32(0, ret); +} + +Case cases[] = { + Case("FlashIAP - init", flashiap_init_test), + Case("FlashIAP - program", flashiap_program_test), + Case("FlashIAP - program errors", flashiap_program_error_test), +}; + +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 0000000000..c8bb7fdd10 --- /dev/null +++ b/TESTS/mbed_hal/flash/functional_tests/main.cpp @@ -0,0 +1,244 @@ +/* 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" +#include "flash_api.h" +#include "flash_data.h" + +using namespace utest::v1; + +#define TEST_CYCLES 1000000 +#define ALLOWED_DRIFT_PPM 1000 //0.1% + +/* + 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 + +static int timer_diff_start; + +static void erase_range(flash_t *flash, uint32_t addr, uint32_t size) +{ + while (size > 0) { + uint32_t sector_size = flash_get_sector_size(flash, addr); + TEST_ASSERT_NOT_EQUAL(0, sector_size); + int32_t ret = flash_erase_sector(flash, addr); + TEST_ASSERT_EQUAL_INT32(0, ret); + size = size > sector_size ? size - sector_size : 0; + } +} + +static int time_cpu_cycles(uint32_t cycles) +{ + Timer timer; + timer.start(); + + int timer_start = timer.read_us(); + + volatile uint32_t delay = (volatile uint32_t)cycles; + while (delay--); + + int timer_end = timer.read_us(); + + timer.stop(); + return timer_end - timer_start; +} + +void flash_init_test() +{ + timer_diff_start = time_cpu_cycles(TEST_CYCLES); + + flash_t test_flash; + int32_t ret = flash_init(&test_flash); + TEST_ASSERT_EQUAL_INT32(0, ret); + ret = flash_free(&test_flash); + TEST_ASSERT_EQUAL_INT32(0, ret); +} + +void flash_mapping_alignment_test() +{ + flash_t test_flash; + int32_t ret = flash_init(&test_flash); + TEST_ASSERT_EQUAL_INT32(0, ret); + + const uint32_t page_size = flash_get_page_size(&test_flash); + const uint32_t flash_start = flash_get_start_address(&test_flash); + const uint32_t flash_size = flash_get_size(&test_flash); + TEST_ASSERT_TRUE(page_size != 0UL); + + uint32_t sector_size = flash_get_sector_size(&test_flash, flash_start); + for (uint32_t offset = 0; offset < flash_size; offset += sector_size) { + const uint32_t sector_start = flash_start + offset; + sector_size = flash_get_sector_size(&test_flash, sector_start); + const uint32_t sector_end = sector_start + sector_size - 1; + const uint32_t end_sector_size = flash_get_sector_size(&test_flash, sector_end); + + // Sector size must be a valid value + TEST_ASSERT_NOT_EQUAL(MBED_FLASH_INVALID_SIZE, sector_size); + // Sector size must be greater than zero + TEST_ASSERT_NOT_EQUAL(0, sector_size); + // All flash sectors must be a multiple of page size + TEST_ASSERT_EQUAL(0, sector_size % page_size); + // Sector address must be a multiple of sector size + TEST_ASSERT_EQUAL(0, sector_start % sector_size); + // All address in a sector must return the same sector size + TEST_ASSERT_EQUAL(sector_size, end_sector_size); + + } + + // Make sure unmapped flash is reported correctly + TEST_ASSERT_EQUAL(MBED_FLASH_INVALID_SIZE, flash_get_sector_size(&test_flash, flash_start - 1)); + TEST_ASSERT_EQUAL(MBED_FLASH_INVALID_SIZE, flash_get_sector_size(&test_flash, flash_start + flash_size)); + + ret = flash_free(&test_flash); + TEST_ASSERT_EQUAL_INT32(0, ret); +} + +void flash_erase_sector_test() +{ + flash_t test_flash; + int32_t ret = flash_init(&test_flash); + TEST_ASSERT_EQUAL_INT32(0, ret); + + uint32_t addr_after_last = flash_get_start_address(&test_flash) + flash_get_size(&test_flash); + uint32_t last_sector_size = flash_get_sector_size(&test_flash, addr_after_last - 1); + uint32_t last_sector = addr_after_last - last_sector_size; + TEST_ASSERT_EQUAL_INT32(0, last_sector % last_sector_size); + ret = flash_erase_sector(&test_flash, last_sector); + TEST_ASSERT_EQUAL_INT32(0, ret); + + ret = flash_free(&test_flash); + TEST_ASSERT_EQUAL_INT32(0, ret); +} + +// 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(0, ret); + + 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(0, ret); + + ret = flash_program_page(&test_flash, address, data, test_size); + TEST_ASSERT_EQUAL_INT32(0, ret); + 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(0, ret); + + // 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(0, ret); + TEST_ASSERT_EQUAL_UINT8_ARRAY(data, data_flashed, test_size); + + ret = flash_free(&test_flash); + TEST_ASSERT_EQUAL_INT32(0, ret); + delete[] data; +} + +// make sure programming works with an unaligned data buffer +void flash_buffer_alignment_test() +{ + flash_t test_flash; + int32_t ret = flash_init(&test_flash); + TEST_ASSERT_EQUAL_INT32(0, ret); + + const uint32_t page_size = flash_get_page_size(&test_flash); + const uint32_t buf_size = page_size + 4; + uint8_t *data = new uint8_t[buf_size]; + for (uint32_t i = 0; i < buf_size; i++) { + data[i] = i & 0xFF; + } + + // use the last four pages for the alignment test + const uint32_t flash_end = flash_get_start_address(&test_flash) + flash_get_size(&test_flash); + const uint32_t test_addr = flash_end - page_size * 4; + const uint32_t erase_sector_boundary = ALIGN_DOWN(test_addr, flash_get_sector_size(&test_flash, test_addr)); + erase_range(&test_flash, erase_sector_boundary, flash_end - erase_sector_boundary); + + // make sure page program works with an unaligned data buffer + for (uint32_t i = 0; i < 4; i++) { + const uint32_t addr = test_addr + i * page_size; + ret = flash_program_page(&test_flash, addr, data + i, page_size); + TEST_ASSERT_EQUAL_INT32(0, ret); + uint8_t *data_flashed = (uint8_t *)addr; + TEST_ASSERT_EQUAL_UINT8_ARRAY(data + i, data_flashed, page_size); + } + + ret = flash_free(&test_flash); + TEST_ASSERT_EQUAL_INT32(0, ret); + delete[] data; +} + +// check the execution speed at the start and end of the test to make sure +// cache settings weren't changed +void flash_clock_and_cache_test() +{ + const int timer_diff_end = time_cpu_cycles(TEST_CYCLES); + const int acceptable_range = timer_diff_start / (1000000 / ALLOWED_DRIFT_PPM); + TEST_ASSERT_UINT32_WITHIN(acceptable_range, timer_diff_start, timer_diff_end); +} + +Case cases[] = { + Case("Flash - init", flash_init_test), + Case("Flash - mapping alignment", flash_mapping_alignment_test), + Case("Flash - erase sector", flash_erase_sector_test), + Case("Flash - program page", flash_program_page_test), + Case("Flash - buffer alignment test", flash_buffer_alignment_test), + Case("Flash - clock and cache test", flash_clock_and_cache_test), +}; + +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/mbedmicro-rtos-mbed/mutex/main.cpp b/TESTS/mbedmicro-rtos-mbed/mutex/main.cpp index 5026f0534b..6fa2efaec3 100644 --- a/TESTS/mbedmicro-rtos-mbed/mutex/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/mutex/main.cpp @@ -1,54 +1,31 @@ #include "mbed.h" #include "greentea-client/test_env.h" +#include "unity.h" +#include "utest.h" #include "rtos.h" #if defined(MBED_RTOS_SINGLE_THREAD) #error [NOT_SUPPORTED] test not supported #endif -#define THREAD_DELAY 50 -#define SIGNALS_TO_EMIT 100 +using namespace utest::v1; /* * The stack size is defined in cmsis_os.h mainly dependent on the underlying toolchain and * the C standard library. For GCC, ARM_STD and IAR it is defined with a size of 2048 bytes * and for ARM_MICRO 512. Because of reduce RAM size some targets need a reduced stacksize. */ -#if defined(TARGET_STM32F334R8) && defined(TOOLCHAIN_IAR) - #define STACK_SIZE DEFAULT_STACK_SIZE/4 -#elif defined(TARGET_STM32F070RB) - #define STACK_SIZE DEFAULT_STACK_SIZE/2 -#elif defined(TARGET_STM32F072RB) - #define STACK_SIZE DEFAULT_STACK_SIZE/2 -#elif defined(TARGET_STM32F302R8) && defined(TOOLCHAIN_IAR) - #define STACK_SIZE DEFAULT_STACK_SIZE/2 -#elif defined(TARGET_STM32F303K8) && defined(TOOLCHAIN_IAR) - #define STACK_SIZE DEFAULT_STACK_SIZE/2 -#elif defined(TARGET_STM32L073RZ) - #define STACK_SIZE DEFAULT_STACK_SIZE/2 -#elif (defined(TARGET_EFM32HG_STK3400)) && !defined(TOOLCHAIN_ARM_MICRO) - #define STACK_SIZE 512 -#elif (defined(TARGET_EFM32LG_STK3600) || defined(TARGET_EFM32WG_STK3800) || defined(TARGET_EFM32PG_STK3401)) && !defined(TOOLCHAIN_ARM_MICRO) - #define STACK_SIZE 768 -#elif (defined(TARGET_EFM32GG_STK3700)) && !defined(TOOLCHAIN_ARM_MICRO) - #define STACK_SIZE 1536 -#elif (defined(TARGET_EFR32)) && !defined(TOOLCHAIN_ARM_MICRO) - #define STACK_SIZE 768 -#elif defined(TARGET_MCU_NRF51822) || defined(TARGET_MCU_NRF52832) - #define STACK_SIZE 1024 -#elif defined(TARGET_XDOT_L151CC) - #define STACK_SIZE 1024 -#else - #define STACK_SIZE DEFAULT_STACK_SIZE -#endif +#define TEST_STACK_SIZE 512 -void print_char(char c = '*') { - printf("%c", c); - fflush(stdout); -} +#define TEST_ONE_SEC_MS (1000) +#define TEST_HALF_SEC_MS (500) +#define TEST_HALF_SEC_US (500000) +#define TEST_ONE_MS_US (1000) + +#define THREAD_DELAY 50 +#define SIGNALS_TO_EMIT 100 Mutex stdio_mutex; -DigitalOut led(LED1); volatile int change_counter = 0; volatile bool changing_counter = false; @@ -57,23 +34,20 @@ volatile bool mutex_defect = false; bool manipulate_protected_zone(const int thread_delay) { bool result = true; - stdio_mutex.lock(); // LOCK + osStatus stat = stdio_mutex.lock(); + TEST_ASSERT_EQUAL(stat, osOK); if (changing_counter == true) { - // 'e' stands for error. If changing_counter is true access is not exclusively - print_char('e'); result = false; mutex_defect = true; } changing_counter = true; - // Some action on protected - led = !led; change_counter++; - print_char('.'); Thread::wait(thread_delay); changing_counter = false; - stdio_mutex.unlock(); // UNLOCK + stat = stdio_mutex.unlock(); + TEST_ASSERT_EQUAL(stat, osOK); return result; } @@ -83,14 +57,14 @@ void test_thread(int const *thread_delay) { } } -int main() { - GREENTEA_SETUP(20, "default_auto"); - +void test_multiple_threads(void) +{ const int t1_delay = THREAD_DELAY * 1; const int t2_delay = THREAD_DELAY * 2; const int t3_delay = THREAD_DELAY * 3; - Thread t2(osPriorityNormal, STACK_SIZE); - Thread t3(osPriorityNormal, STACK_SIZE); + + Thread t2(osPriorityNormal, TEST_STACK_SIZE); + Thread t3(osPriorityNormal, TEST_STACK_SIZE); t2.start(callback(test_thread, &t2_delay)); t3.start(callback(test_thread, &t3_delay)); @@ -99,6 +73,7 @@ int main() { // Thread 1 action Thread::wait(t1_delay); manipulate_protected_zone(t1_delay); + if (change_counter >= SIGNALS_TO_EMIT or mutex_defect == true) { t2.terminate(); t3.terminate(); @@ -106,7 +81,154 @@ int main() { } } - fflush(stdout); - GREENTEA_TESTSUITE_RESULT(!mutex_defect); - return 0; + TEST_ASSERT_EQUAL(mutex_defect, false); +} + +void test_dual_thread_nolock_lock_thread(Mutex *mutex) +{ + bool stat_b = mutex->trylock(); + TEST_ASSERT_EQUAL(stat_b, true); + + osStatus stat = mutex->unlock(); + TEST_ASSERT_EQUAL(stat, osOK); +} + +void test_dual_thread_nolock_trylock_thread(Mutex *mutex) +{ + bool stat_b = mutex->trylock(); + TEST_ASSERT_EQUAL(stat_b, true); + + osStatus stat = mutex->unlock(); + TEST_ASSERT_EQUAL(stat, osOK); +} + +template +void test_dual_thread_nolock(void) +{ + Mutex mutex; + Thread thread; + + thread.start(callback(F, &mutex)); + + wait_us(TEST_HALF_SEC_MS); +} + +void test_dual_thread_lock_unlock_thread(Mutex *mutex) +{ + osStatus stat = mutex->lock(osWaitForever); + TEST_ASSERT_EQUAL(stat, osOK); +} + +void test_dual_thread_lock_unlock(void) +{ + Mutex mutex; + osStatus stat; + Thread thread(osPriorityNormal, TEST_STACK_SIZE); + + stat = mutex.lock(); + TEST_ASSERT_EQUAL(stat, osOK); + + thread.start(callback(test_dual_thread_lock_unlock_thread, &mutex)); + + stat = mutex.unlock(); + TEST_ASSERT_EQUAL(stat, osOK); + + wait_us(TEST_HALF_SEC_MS); +} + +void test_dual_thread_lock_trylock_thread(Mutex *mutex) +{ + bool stat = mutex->trylock(); + TEST_ASSERT_EQUAL(stat, false); +} + +void test_dual_thread_lock_lock_thread(Mutex *mutex) +{ + uint32_t start = us_ticker_read(); + + osStatus stat = mutex->lock(TEST_HALF_SEC_MS); + TEST_ASSERT_EQUAL(stat, osEventTimeout); + TEST_ASSERT_UINT32_WITHIN(TEST_ONE_MS_US, TEST_HALF_SEC_US, us_ticker_read() - start); +} + +template +void test_dual_thread_lock(void) +{ + Mutex mutex; + osStatus stat; + Thread thread(osPriorityNormal, TEST_STACK_SIZE); + + stat = mutex.lock(); + TEST_ASSERT_EQUAL(stat, osOK); + + thread.start(callback(F, &mutex)); + + wait_us(TEST_ONE_SEC_MS); + + stat = mutex.unlock(); + TEST_ASSERT_EQUAL(stat, osOK); +} + +void test_single_thread_lock_recursive(void) +{ + Mutex mutex; + osStatus stat; + + stat = mutex.lock(); + TEST_ASSERT_EQUAL(stat, osOK); + + stat = mutex.lock(); + TEST_ASSERT_EQUAL(stat, osOK); + + stat = mutex.unlock(); + TEST_ASSERT_EQUAL(stat, osOK); + + stat = mutex.unlock(); + TEST_ASSERT_EQUAL(stat, osOK); +} + +void test_single_thread_trylock(void) +{ + Mutex mutex; + + bool stat_b = mutex.trylock(); + TEST_ASSERT_EQUAL(stat_b, true); + + osStatus stat = mutex.unlock(); + TEST_ASSERT_EQUAL(stat, osOK); +} + +void test_single_thread_lock(void) +{ + Mutex mutex; + osStatus stat; + + stat = mutex.lock(); + TEST_ASSERT_EQUAL(stat, osOK); + + stat = mutex.unlock(); + TEST_ASSERT_EQUAL(stat, osOK); +} + +utest::v1::status_t test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(15, "default_auto"); + return verbose_test_setup_handler(number_of_cases); +} + +Case cases[] = { + Case("Test single thread lock", test_single_thread_lock), + Case("Test single thread trylock", test_single_thread_trylock), + Case("Test single thread lock recursive", test_single_thread_lock_recursive), + Case("Test dual thread lock locked", test_dual_thread_lock), + Case("Test dual thread trylock locked", test_dual_thread_lock), + Case("Test dual thread lock unlock", test_dual_thread_lock_unlock), + Case("Test dual thread second thread lock", test_dual_thread_nolock), + Case("Test dual thread second thread trylock", test_dual_thread_nolock), + Case("Test multiple thread", test_multiple_threads), +}; + +Specification specification(test_setup, cases); + +int main() { + return !Harness::run(specification); } diff --git a/docs/exporters.md b/docs/exporters.md deleted file mode 100644 index a4c29712b7..0000000000 --- a/docs/exporters.md +++ /dev/null @@ -1,65 +0,0 @@ -# About the exporters - -The mbed exporters are used to export your code to various 3rd party tools and IDEs. Each exporter implements a `generate` function that produces an IDE specific project file. Exporters benefit from [mbed build tools](https://github.com/ARMmbed/mbed-os/blob/master/docs/BUILDING.md#build-mbed-sdk-library-from-sources). However, instead of using your source and [config data](https://github.com/ARMmbed/mbed-os/blob/master/docs/config_system.md) to create an executable, we use that information to populate an IDE project file that will be configured to build, flash, and debug your code. You can find exporter implementations [here](https://github.com/ARMmbed/mbed-os/tree/master/tools/export). - -## mbed-cli command - -`mbed export -m [target] -i [IDE]` - -# Adding export support for a target - -If you have added new target to the mbed SDK, exporting will allow users to transition from mbed source code to the offline development environment of their choice. This functionality activates the use of your device for larger number of users. - -## Eclipse and Make - -Eclipse project export utilizes a generated Makefile for building. Other than target configuration within the [config system](https://github.com/ARMmbed/mbed-os/blob/master/docs/mbed_targets.md) for mbed build system support, there is no additional work to provide Make export. - -### Available mbed-cli commands - -`mbed export -m [target] -i [make_gcc_arm, make_iar, make_armc5, eclipse_gcc_arm, eclipse_iar, eclipse_armc5]` - -## UVision and IAR - -### CMSIS Packs - -UVision and IAR both utilize [CMSIS packs](http://www.keil.com/pack/doc/CMSIS/Pack/html/index.html) to find target information necessary to create a valid project file. - -We utilize the tool [ArmPackManager](https://github.com/ARMmbed/mbed-os/tree/master/tools/arm_pack_manager) to scrape [MDK5 Software Packs](https://www.keil.com/dd2/Pack/) for target information. This is achieved by parsing [http://www.keil.com/pack/index.idx](http://sadevicepacksprod.blob.core.windows.net/idxfile/index.idx). The relevant information in the [PDSC (Pack Description)](http://www.keil.com/pack/doc/CMSIS/Pack/html/_pack_format.html) retrieved from each URL in the index is stored in [index.json](https://github.com/ARMmbed/mbed-os/blob/master/tools/arm_pack_manager/index.json). A `.pdsc` file typically describes a family of devices. Each device is uniquely identified by its [device name](https://github.com/ARMmbed/mbed-os/blob/master/docs/mbed_targets.md#device_name). Thus, this name makes a natural key to associate a device with its information in `index.json`. - -#### What's in a device name? -There is no reliable way to map an mbed alias like [NUCLEO_F030R8](https://github.com/ARMmbed/mbed-os/blob/master/targets/targets.json#L603) to its unique identifier, [STM32F030R8](https://github.com/ARMmbed/mbed-os/blob/master/targets/targets.json#L615), as it is listed in a CMSIS pack (and subsequently `index.json`). So, we added a [device name](https://github.com/ARMmbed/mbed-os/blob/master/docs/mbed_targets.md#device_name) field in `targets.json`. **This field is required for IAR or UVision exporter support**. - -#### Code Usage -http://www.keil.com/pack/Keil.Kinetis_K20_DFP.pdsc is the PDSC that contains TEENSY_31 device (MK20DX256xxx7). It has been parsed by ArmPackManager and stored in `index.json`. The device information begins on line 156: -```xml - - - - - - - - - - - - - -``` - -##### Uvision -The dname (device name) field on line 156 directly corresponds to that in the Uvision5 IDE target selection window. [`tools/export/uvision/uvision.tmpl`](https://github.com/ARMmbed/mbed-os/blob/master/tools/export/uvision/uvision.tmpl#L15), uses target information from these packs is used to generate valid Uvision5 projects. If the device name is not found, we use a generic ARM CPU target in Uvision5. - -##### IAR -[`tools/export/iar/iar_definitions.json`](https://github.com/ARMmbed/mbed-os/blob/master/tools/export/iar/iar_definitions.json) utilizes this device name to store information necessary to set the target in an IAR project. - -##### Updating index.json -You can regenerate `index.json` to contain a newly made CMSIS pack with the following command: - -`mbed export -i [IDE] --update-packs` - -You should include the changes to `index.json` in your PR that adds support for the new target. - - - - diff --git a/drivers/FlashIAP.cpp b/drivers/FlashIAP.cpp new file mode 100644 index 0000000000..7c3d93a7b8 --- /dev/null +++ b/drivers/FlashIAP.cpp @@ -0,0 +1,167 @@ +/* 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) || + !is_aligned(size, page_size) || + (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; +} + +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) || + !is_aligned(addr, current_sector_size)) { + 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)) { + 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)) { + 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 0000000000..fcb376dd5f --- /dev/null +++ b/drivers/FlashIAP.h @@ -0,0 +1,138 @@ +/* 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); + + /** 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> + * + * @param addr Address of or inside the sector to query + * @return Size of a sector in bytes or MBED_FLASH_INVALID_SIZE if not mapped + */ + 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 addr Address of block to check for alignment + * @param size Size of block to check for alignment + * @return true if the block is sector aligned, false otherwise + */ + 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/drivers/InterruptIn.cpp b/drivers/InterruptIn.cpp index 2ea3ec507b..f555d4bdf8 100644 --- a/drivers/InterruptIn.cpp +++ b/drivers/InterruptIn.cpp @@ -27,8 +27,8 @@ InterruptIn::InterruptIn(PinName pin) : gpio(), _fall() { // No lock needed in the constructor - _rise.attach(donothing); - _fall.attach(donothing); + _rise = donothing; + _fall = donothing; gpio_irq_init(&gpio_irq, pin, (&InterruptIn::_irq_handler), (uint32_t)this); gpio_init_in(&gpio, pin); @@ -53,10 +53,10 @@ void InterruptIn::mode(PinMode pull) { void InterruptIn::rise(Callback func) { core_util_critical_section_enter(); if (func) { - _rise.attach(func); + _rise = func; gpio_irq_set(&gpio_irq, IRQ_RISE, 1); } else { - _rise.attach(donothing); + _rise = donothing; gpio_irq_set(&gpio_irq, IRQ_RISE, 0); } core_util_critical_section_exit(); @@ -65,10 +65,10 @@ void InterruptIn::rise(Callback func) { void InterruptIn::fall(Callback func) { core_util_critical_section_enter(); if (func) { - _fall.attach(func); + _fall = func; gpio_irq_set(&gpio_irq, IRQ_FALL, 1); } else { - _fall.attach(donothing); + _fall = donothing; gpio_irq_set(&gpio_irq, IRQ_FALL, 0); } core_util_critical_section_exit(); @@ -77,8 +77,8 @@ void InterruptIn::fall(Callback func) { void InterruptIn::_irq_handler(uint32_t id, gpio_irq_event event) { InterruptIn *handler = (InterruptIn*)id; switch (event) { - case IRQ_RISE: handler->_rise.call(); break; - case IRQ_FALL: handler->_fall.call(); break; + case IRQ_RISE: handler->_rise(); break; + case IRQ_FALL: handler->_fall(); break; case IRQ_NONE: break; } } diff --git a/drivers/SerialBase.cpp b/drivers/SerialBase.cpp index 3e6fede641..1a7110f752 100644 --- a/drivers/SerialBase.cpp +++ b/drivers/SerialBase.cpp @@ -32,7 +32,7 @@ SerialBase::SerialBase(PinName tx, PinName rx, int baud) : // No lock needed in the constructor for (size_t i = 0; i < sizeof _irq / sizeof _irq[0]; i++) { - _irq[i].attach(donothing); + _irq[i] = donothing; } serial_init(&_serial, tx, rx); @@ -73,10 +73,10 @@ void SerialBase::attach(Callback func, IrqType type) { // Disable interrupts when attaching interrupt handler core_util_critical_section_enter(); if (func) { - _irq[type].attach(func); + _irq[type] = func; serial_irq_set(&_serial, (SerialIrq)type, 1); } else { - _irq[type].attach(donothing); + _irq[type] = donothing; serial_irq_set(&_serial, (SerialIrq)type, 0); } core_util_critical_section_exit(); @@ -85,7 +85,7 @@ void SerialBase::attach(Callback func, IrqType type) { void SerialBase::_irq_handler(uint32_t id, SerialIrq irq_type) { SerialBase *handler = (SerialBase*)id; - handler->_irq[irq_type].call(); + handler->_irq[irq_type](); } int SerialBase::_base_getc() { diff --git a/drivers/Ticker.cpp b/drivers/Ticker.cpp index 93a9d1be9a..f497c3a9fc 100644 --- a/drivers/Ticker.cpp +++ b/drivers/Ticker.cpp @@ -25,7 +25,7 @@ namespace mbed { void Ticker::detach() { core_util_critical_section_enter(); remove(); - _function.attach(0); + _function = 0; core_util_critical_section_exit(); } @@ -39,7 +39,7 @@ void Ticker::setup(timestamp_t t) { void Ticker::handler() { insert(event.timestamp + _delay); - _function.call(); + _function(); } } // namespace mbed diff --git a/drivers/Ticker.h b/drivers/Ticker.h index a219331c39..15c171c2cb 100644 --- a/drivers/Ticker.h +++ b/drivers/Ticker.h @@ -101,7 +101,7 @@ public: * @param t the time between calls in micro-seconds */ void attach_us(Callback func, timestamp_t t) { - _function.attach(func); + _function = func; setup(t); } diff --git a/events/Event.h b/events/Event.h index db4b0d76bf..7c4132af90 100644 --- a/events/Event.h +++ b/events/Event.h @@ -45,7 +45,10 @@ public: * * @param q Event queue to dispatch on * @param f Function to execute when the event is dispatched - * @param a0..a4 Arguments to pass to the callback + * @param c0..c4 Arguments to bind to the callback, these arguments are + * allocated on an irq-safe allocator from the event queue's + * memory pool. Must be type-compatible with b0..b4, the + * arguments to the underlying callback. */ template Event(EventQueue *q, F f) { @@ -438,7 +441,10 @@ public: * * @param q Event queue to dispatch on * @param f Function to execute when the event is dispatched - * @param a0..a4 Arguments to pass to the callback + * @param c0..c4 Arguments to bind to the callback, these arguments are + * allocated on an irq-safe allocator from the event queue's + * memory pool. Must be type-compatible with b0..b4, the + * arguments to the underlying callback. */ template Event(EventQueue *q, F f) { @@ -831,7 +837,10 @@ public: * * @param q Event queue to dispatch on * @param f Function to execute when the event is dispatched - * @param a0..a4 Arguments to pass to the callback + * @param c0..c4 Arguments to bind to the callback, these arguments are + * allocated on an irq-safe allocator from the event queue's + * memory pool. Must be type-compatible with b0..b4, the + * arguments to the underlying callback. */ template Event(EventQueue *q, F f) { @@ -1224,7 +1233,10 @@ public: * * @param q Event queue to dispatch on * @param f Function to execute when the event is dispatched - * @param a0..a4 Arguments to pass to the callback + * @param c0..c4 Arguments to bind to the callback, these arguments are + * allocated on an irq-safe allocator from the event queue's + * memory pool. Must be type-compatible with b0..b4, the + * arguments to the underlying callback. */ template Event(EventQueue *q, F f) { @@ -1617,7 +1629,10 @@ public: * * @param q Event queue to dispatch on * @param f Function to execute when the event is dispatched - * @param a0..a4 Arguments to pass to the callback + * @param c0..c4 Arguments to bind to the callback, these arguments are + * allocated on an irq-safe allocator from the event queue's + * memory pool. Must be type-compatible with b0..b4, the + * arguments to the underlying callback. */ template Event(EventQueue *q, F f) { @@ -2010,7 +2025,10 @@ public: * * @param q Event queue to dispatch on * @param f Function to execute when the event is dispatched - * @param a0..a4 Arguments to pass to the callback + * @param c0..c4 Arguments to bind to the callback, these arguments are + * allocated on an irq-safe allocator from the event queue's + * memory pool. Must be type-compatible with b0..b4, the + * arguments to the underlying callback. */ template Event(EventQueue *q, F f) { @@ -2417,6 +2435,11 @@ Event EventQueue::event(const volatile T *obj, R (T::*method)() const vo return Event(this, mbed::callback(obj, method)); } +template +Event EventQueue::event(mbed::Callback cb) { + return Event(this, cb); +} + template Event EventQueue::event(R (*func)(B0), C0 c0) { return Event(this, func, c0); @@ -2442,6 +2465,11 @@ Event EventQueue::event(const volatile T *obj, R (T::*method)(B0) const return Event(this, mbed::callback(obj, method), c0); } +template +Event EventQueue::event(mbed::Callback cb, C0 c0) { + return Event(this, cb, c0); +} + template Event EventQueue::event(R (*func)(B0, B1), C0 c0, C1 c1) { return Event(this, func, c0, c1); @@ -2467,6 +2495,11 @@ Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1) co return Event(this, mbed::callback(obj, method), c0, c1); } +template +Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1) { + return Event(this, cb, c0, c1); +} + template Event EventQueue::event(R (*func)(B0, B1, B2), C0 c0, C1 c1, C2 c2) { return Event(this, func, c0, c1, c2); @@ -2492,6 +2525,11 @@ Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, B2 return Event(this, mbed::callback(obj, method), c0, c1, c2); } +template +Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1, C2 c2) { + return Event(this, cb, c0, c1, c2); +} + template Event EventQueue::event(R (*func)(B0, B1, B2, B3), C0 c0, C1 c1, C2 c2, C3 c3) { return Event(this, func, c0, c1, c2, c3); @@ -2517,6 +2555,11 @@ Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, B2 return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); } +template +Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1, C2 c2, C3 c3) { + return Event(this, cb, c0, c1, c2, c3); +} + template Event EventQueue::event(R (*func)(B0, B1, B2, B3, B4), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { return Event(this, func, c0, c1, c2, c3, c4); @@ -2542,6 +2585,11 @@ Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, B2 return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); } +template +Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + return Event(this, cb, c0, c1, c2, c3, c4); +} + template Event EventQueue::event(R (*func)(A0)) { return Event(this, func); @@ -2567,6 +2615,11 @@ Event EventQueue::event(const volatile T *obj, R (T::*method)(A0) cons return Event(this, mbed::callback(obj, method)); } +template +Event EventQueue::event(mbed::Callback cb) { + return Event(this, cb); +} + template Event EventQueue::event(R (*func)(B0, A0), C0 c0) { return Event(this, func, c0); @@ -2592,6 +2645,11 @@ Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, A0) return Event(this, mbed::callback(obj, method), c0); } +template +Event EventQueue::event(mbed::Callback cb, C0 c0) { + return Event(this, cb, c0); +} + template Event EventQueue::event(R (*func)(B0, B1, A0), C0 c0, C1 c1) { return Event(this, func, c0, c1); @@ -2617,6 +2675,11 @@ Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, return Event(this, mbed::callback(obj, method), c0, c1); } +template +Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1) { + return Event(this, cb, c0, c1); +} + template Event EventQueue::event(R (*func)(B0, B1, B2, A0), C0 c0, C1 c1, C2 c2) { return Event(this, func, c0, c1, c2); @@ -2642,6 +2705,11 @@ Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, return Event(this, mbed::callback(obj, method), c0, c1, c2); } +template +Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1, C2 c2) { + return Event(this, cb, c0, c1, c2); +} + template Event EventQueue::event(R (*func)(B0, B1, B2, B3, A0), C0 c0, C1 c1, C2 c2, C3 c3) { return Event(this, func, c0, c1, c2, c3); @@ -2667,6 +2735,11 @@ Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); } +template +Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1, C2 c2, C3 c3) { + return Event(this, cb, c0, c1, c2, c3); +} + template Event EventQueue::event(R (*func)(B0, B1, B2, B3, B4, A0), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { return Event(this, func, c0, c1, c2, c3, c4); @@ -2692,6 +2765,11 @@ Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); } +template +Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + return Event(this, cb, c0, c1, c2, c3, c4); +} + template Event EventQueue::event(R (*func)(A0, A1)) { return Event(this, func); @@ -2717,6 +2795,11 @@ Event EventQueue::event(const volatile T *obj, R (T::*method)(A0, return Event(this, mbed::callback(obj, method)); } +template +Event EventQueue::event(mbed::Callback cb) { + return Event(this, cb); +} + template Event EventQueue::event(R (*func)(B0, A0, A1), C0 c0) { return Event(this, func, c0); @@ -2742,6 +2825,11 @@ Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, return Event(this, mbed::callback(obj, method), c0); } +template +Event EventQueue::event(mbed::Callback cb, C0 c0) { + return Event(this, cb, c0); +} + template Event EventQueue::event(R (*func)(B0, B1, A0, A1), C0 c0, C1 c1) { return Event(this, func, c0, c1); @@ -2767,6 +2855,11 @@ Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, return Event(this, mbed::callback(obj, method), c0, c1); } +template +Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1) { + return Event(this, cb, c0, c1); +} + template Event EventQueue::event(R (*func)(B0, B1, B2, A0, A1), C0 c0, C1 c1, C2 c2) { return Event(this, func, c0, c1, c2); @@ -2792,6 +2885,11 @@ Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, return Event(this, mbed::callback(obj, method), c0, c1, c2); } +template +Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1, C2 c2) { + return Event(this, cb, c0, c1, c2); +} + template Event EventQueue::event(R (*func)(B0, B1, B2, B3, A0, A1), C0 c0, C1 c1, C2 c2, C3 c3) { return Event(this, func, c0, c1, c2, c3); @@ -2817,6 +2915,11 @@ Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); } +template +Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1, C2 c2, C3 c3) { + return Event(this, cb, c0, c1, c2, c3); +} + template Event EventQueue::event(R (*func)(B0, B1, B2, B3, B4, A0, A1), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { return Event(this, func, c0, c1, c2, c3, c4); @@ -2842,6 +2945,11 @@ Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); } +template +Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + return Event(this, cb, c0, c1, c2, c3, c4); +} + template Event EventQueue::event(R (*func)(A0, A1, A2)) { return Event(this, func); @@ -2867,6 +2975,11 @@ Event EventQueue::event(const volatile T *obj, R (T::*method)( return Event(this, mbed::callback(obj, method)); } +template +Event EventQueue::event(mbed::Callback cb) { + return Event(this, cb); +} + template Event EventQueue::event(R (*func)(B0, A0, A1, A2), C0 c0) { return Event(this, func, c0); @@ -2892,6 +3005,11 @@ Event EventQueue::event(const volatile T *obj, R (T::*method)( return Event(this, mbed::callback(obj, method), c0); } +template +Event EventQueue::event(mbed::Callback cb, C0 c0) { + return Event(this, cb, c0); +} + template Event EventQueue::event(R (*func)(B0, B1, A0, A1, A2), C0 c0, C1 c1) { return Event(this, func, c0, c1); @@ -2917,6 +3035,11 @@ Event EventQueue::event(const volatile T *obj, R (T::*method)( return Event(this, mbed::callback(obj, method), c0, c1); } +template +Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1) { + return Event(this, cb, c0, c1); +} + template Event EventQueue::event(R (*func)(B0, B1, B2, A0, A1, A2), C0 c0, C1 c1, C2 c2) { return Event(this, func, c0, c1, c2); @@ -2942,6 +3065,11 @@ Event EventQueue::event(const volatile T *obj, R (T::*method)( return Event(this, mbed::callback(obj, method), c0, c1, c2); } +template +Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1, C2 c2) { + return Event(this, cb, c0, c1, c2); +} + template Event EventQueue::event(R (*func)(B0, B1, B2, B3, A0, A1, A2), C0 c0, C1 c1, C2 c2, C3 c3) { return Event(this, func, c0, c1, c2, c3); @@ -2967,6 +3095,11 @@ Event EventQueue::event(const volatile T *obj, R (T::*method)( return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); } +template +Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1, C2 c2, C3 c3) { + return Event(this, cb, c0, c1, c2, c3); +} + template Event EventQueue::event(R (*func)(B0, B1, B2, B3, B4, A0, A1, A2), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { return Event(this, func, c0, c1, c2, c3, c4); @@ -2992,6 +3125,11 @@ Event EventQueue::event(const volatile T *obj, R (T::*method)( return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); } +template +Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + return Event(this, cb, c0, c1, c2, c3, c4); +} + template Event EventQueue::event(R (*func)(A0, A1, A2, A3)) { return Event(this, func); @@ -3017,6 +3155,11 @@ Event EventQueue::event(const volatile T *obj, R (T::*meth return Event(this, mbed::callback(obj, method)); } +template +Event EventQueue::event(mbed::Callback cb) { + return Event(this, cb); +} + template Event EventQueue::event(R (*func)(B0, A0, A1, A2, A3), C0 c0) { return Event(this, func, c0); @@ -3042,6 +3185,11 @@ Event EventQueue::event(const volatile T *obj, R (T::*meth return Event(this, mbed::callback(obj, method), c0); } +template +Event EventQueue::event(mbed::Callback cb, C0 c0) { + return Event(this, cb, c0); +} + template Event EventQueue::event(R (*func)(B0, B1, A0, A1, A2, A3), C0 c0, C1 c1) { return Event(this, func, c0, c1); @@ -3067,6 +3215,11 @@ Event EventQueue::event(const volatile T *obj, R (T::*meth return Event(this, mbed::callback(obj, method), c0, c1); } +template +Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1) { + return Event(this, cb, c0, c1); +} + template Event EventQueue::event(R (*func)(B0, B1, B2, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2) { return Event(this, func, c0, c1, c2); @@ -3092,6 +3245,11 @@ Event EventQueue::event(const volatile T *obj, R (T::*meth return Event(this, mbed::callback(obj, method), c0, c1, c2); } +template +Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1, C2 c2) { + return Event(this, cb, c0, c1, c2); +} + template Event EventQueue::event(R (*func)(B0, B1, B2, B3, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2, C3 c3) { return Event(this, func, c0, c1, c2, c3); @@ -3117,6 +3275,11 @@ Event EventQueue::event(const volatile T *obj, R (T::*meth return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); } +template +Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1, C2 c2, C3 c3) { + return Event(this, cb, c0, c1, c2, c3); +} + template Event EventQueue::event(R (*func)(B0, B1, B2, B3, B4, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { return Event(this, func, c0, c1, c2, c3, c4); @@ -3142,6 +3305,11 @@ Event EventQueue::event(const volatile T *obj, R (T::*meth return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); } +template +Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + return Event(this, cb, c0, c1, c2, c3, c4); +} + template Event EventQueue::event(R (*func)(A0, A1, A2, A3, A4)) { return Event(this, func); @@ -3167,6 +3335,11 @@ Event EventQueue::event(const volatile T *obj, R (T::* return Event(this, mbed::callback(obj, method)); } +template +Event EventQueue::event(mbed::Callback cb) { + return Event(this, cb); +} + template Event EventQueue::event(R (*func)(B0, A0, A1, A2, A3, A4), C0 c0) { return Event(this, func, c0); @@ -3192,6 +3365,11 @@ Event EventQueue::event(const volatile T *obj, R (T::* return Event(this, mbed::callback(obj, method), c0); } +template +Event EventQueue::event(mbed::Callback cb, C0 c0) { + return Event(this, cb, c0); +} + template Event EventQueue::event(R (*func)(B0, B1, A0, A1, A2, A3, A4), C0 c0, C1 c1) { return Event(this, func, c0, c1); @@ -3217,6 +3395,11 @@ Event EventQueue::event(const volatile T *obj, R (T::* return Event(this, mbed::callback(obj, method), c0, c1); } +template +Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1) { + return Event(this, cb, c0, c1); +} + template Event EventQueue::event(R (*func)(B0, B1, B2, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2) { return Event(this, func, c0, c1, c2); @@ -3242,6 +3425,11 @@ Event EventQueue::event(const volatile T *obj, R (T::* return Event(this, mbed::callback(obj, method), c0, c1, c2); } +template +Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1, C2 c2) { + return Event(this, cb, c0, c1, c2); +} + template Event EventQueue::event(R (*func)(B0, B1, B2, B3, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2, C3 c3) { return Event(this, func, c0, c1, c2, c3); @@ -3267,6 +3455,11 @@ Event EventQueue::event(const volatile T *obj, R (T::* return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); } +template +Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1, C2 c2, C3 c3) { + return Event(this, cb, c0, c1, c2, c3); +} + template Event EventQueue::event(R (*func)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { return Event(this, func, c0, c1, c2, c3, c4); @@ -3292,6 +3485,11 @@ Event EventQueue::event(const volatile T *obj, R (T::* return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); } +template +Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + return Event(this, cb, c0, c1, c2, c3, c4); +} + } #endif diff --git a/events/EventQueue.h b/events/EventQueue.h index cf1ae22488..f87872fd5f 100644 --- a/events/EventQueue.h +++ b/events/EventQueue.h @@ -944,7 +944,10 @@ public: * context of the event queue's dispatch loop once posted. * * @param f Function to execute when the event is dispatched - * @param a0..a4 Arguments to pass to the callback + * @param c0..c4 Arguments to bind to the callback, these arguments are + * allocated on an irq-safe allocator from the event queue's + * memory pool. Must be type-compatible with b0..b4, the + * arguments to the underlying callback. * @return Event that will dispatch on the specific queue */ template @@ -974,6 +977,12 @@ public: template Event event(const volatile T *obj, R (T::*method)() const volatile); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1004,6 +1013,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(B0) const volatile, C0 c0); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb, C0 c0); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1034,6 +1049,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(B0, B1) const volatile, C0 c0, C1 c1); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb, C0 c0, C1 c1); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1064,6 +1085,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(B0, B1, B2) const volatile, C0 c0, C1 c1, C2 c2); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb, C0 c0, C1 c1, C2 c2); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1094,6 +1121,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(B0, B1, B2, B3) const volatile, C0 c0, C1 c1, C2 c2, C3 c3); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb, C0 c0, C1 c1, C2 c2, C3 c3); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1124,6 +1157,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4) const volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1154,6 +1193,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(A0) const volatile); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1184,6 +1229,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(B0, A0) const volatile, C0 c0); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb, C0 c0); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1214,6 +1265,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(B0, B1, A0) const volatile, C0 c0, C1 c1); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb, C0 c0, C1 c1); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1244,6 +1301,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(B0, B1, B2, A0) const volatile, C0 c0, C1 c1, C2 c2); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb, C0 c0, C1 c1, C2 c2); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1274,6 +1337,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0) const volatile, C0 c0, C1 c1, C2 c2, C3 c3); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb, C0 c0, C1 c1, C2 c2, C3 c3); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1304,6 +1373,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0) const volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1334,6 +1409,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(A0, A1) const volatile); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1364,6 +1445,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(B0, A0, A1) const volatile, C0 c0); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb, C0 c0); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1394,6 +1481,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(B0, B1, A0, A1) const volatile, C0 c0, C1 c1); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb, C0 c0, C1 c1); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1424,6 +1517,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1) const volatile, C0 c0, C1 c1, C2 c2); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb, C0 c0, C1 c1, C2 c2); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1454,6 +1553,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1) const volatile, C0 c0, C1 c1, C2 c2, C3 c3); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb, C0 c0, C1 c1, C2 c2, C3 c3); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1484,6 +1589,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1) const volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1514,6 +1625,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(A0, A1, A2) const volatile); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1544,6 +1661,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(B0, A0, A1, A2) const volatile, C0 c0); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb, C0 c0); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1574,6 +1697,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2) const volatile, C0 c0, C1 c1); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb, C0 c0, C1 c1); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1604,6 +1733,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2) const volatile, C0 c0, C1 c1, C2 c2); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb, C0 c0, C1 c1, C2 c2); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1634,6 +1769,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2) const volatile, C0 c0, C1 c1, C2 c2, C3 c3); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb, C0 c0, C1 c1, C2 c2, C3 c3); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1664,6 +1805,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2) const volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1694,6 +1841,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(A0, A1, A2, A3) const volatile); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1724,6 +1877,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(B0, A0, A1, A2, A3) const volatile, C0 c0); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb, C0 c0); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1754,6 +1913,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3) const volatile, C0 c0, C1 c1); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb, C0 c0, C1 c1); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1784,6 +1949,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3) const volatile, C0 c0, C1 c1, C2 c2); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb, C0 c0, C1 c1, C2 c2); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1814,6 +1985,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3) const volatile, C0 c0, C1 c1, C2 c2, C3 c3); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb, C0 c0, C1 c1, C2 c2, C3 c3); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1844,6 +2021,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3) const volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1874,6 +2057,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(A0, A1, A2, A3, A4) const volatile); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1904,6 +2093,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(B0, A0, A1, A2, A3, A4) const volatile, C0 c0); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb, C0 c0); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1934,6 +2129,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3, A4) const volatile, C0 c0, C1 c1); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb, C0 c0, C1 c1); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1964,6 +2165,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3, A4) const volatile, C0 c0, C1 c1, C2 c2); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb, C0 c0, C1 c1, C2 c2); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -1994,6 +2201,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3, A4) const volatile, C0 c0, C1 c1, C2 c2, C3 c3); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb, C0 c0, C1 c1, C2 c2, C3 c3); + /** Creates an event bound to the event queue * @see EventQueue::event */ @@ -2024,6 +2237,12 @@ public: template Event event(const volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4) const volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(mbed::Callback cb, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + protected: template friend class Event; diff --git a/events/equeue/equeue_mbed.cpp b/events/equeue/equeue_mbed.cpp index 9f1ce484de..5c72b38dea 100644 --- a/events/equeue/equeue_mbed.cpp +++ b/events/equeue/equeue_mbed.cpp @@ -26,15 +26,15 @@ // Ticker operations static bool equeue_tick_inited = false; -static unsigned equeue_minutes = 0; +static volatile unsigned equeue_minutes = 0; static unsigned equeue_timer[ (sizeof(Timer)+sizeof(unsigned)-1)/sizeof(unsigned)]; static unsigned equeue_ticker[ (sizeof(Ticker)+sizeof(unsigned)-1)/sizeof(unsigned)]; static void equeue_tick_update() { + equeue_minutes += reinterpret_cast(equeue_timer)->read_ms(); reinterpret_cast(equeue_timer)->reset(); - equeue_minutes += 1; } static void equeue_tick_init() { @@ -48,7 +48,7 @@ static void equeue_tick_init() { equeue_minutes = 0; reinterpret_cast(equeue_timer)->start(); reinterpret_cast(equeue_ticker) - ->attach_us(equeue_tick_update, (1 << 16)*1000); + ->attach_us(equeue_tick_update, 1000 << 16); equeue_tick_inited = true; } @@ -58,8 +58,15 @@ unsigned equeue_tick() { equeue_tick_init(); } - unsigned equeue_ms = reinterpret_cast(equeue_timer)->read_ms(); - return (equeue_minutes << 16) + equeue_ms; + unsigned minutes; + unsigned ms; + + do { + minutes = equeue_minutes; + ms = reinterpret_cast(equeue_timer)->read_ms(); + } while (minutes != equeue_minutes); + + return minutes + ms; } diff --git a/features/FEATURE_LWIP/TESTS/mbedmicro-net/host_tests/udp_shotgun.py b/features/FEATURE_LWIP/TESTS/mbedmicro-net/host_tests/udp_shotgun.py index 41de6c0ad0..cdf18f963b 100644 --- a/features/FEATURE_LWIP/TESTS/mbedmicro-net/host_tests/udp_shotgun.py +++ b/features/FEATURE_LWIP/TESTS/mbedmicro-net/host_tests/udp_shotgun.py @@ -20,6 +20,7 @@ import socket import json import random import itertools +import time from sys import stdout from threading import Thread from SocketServer import BaseRequestHandler, UDPServer @@ -42,6 +43,9 @@ class UDPEchoClientHandler(BaseRequestHandler): data = ''.join(map(chr, data)) sock.sendto(data, self.client_address) + # Sleep a tiny bit to compensate for local network + time.sleep(0.01) + class UDPEchoClientTest(BaseHostTest): def __init__(self): diff --git a/features/FEATURE_LWIP/lwip-interface/lwip_stack.c b/features/FEATURE_LWIP/lwip-interface/lwip_stack.c index eecdc0c8a2..22c6d7cf1f 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwip_stack.c +++ b/features/FEATURE_LWIP/lwip-interface/lwip_stack.c @@ -87,6 +87,11 @@ static void mbed_lwip_arena_dealloc(struct lwip_socket *s) static void mbed_lwip_socket_callback(struct netconn *nc, enum netconn_evt eh, u16_t len) { + // Filter send minus events + if (eh == NETCONN_EVT_SENDMINUS && nc->state == NETCONN_WRITE) { + return; + } + sys_prot_t prot = sys_arch_protect(); for (int i = 0; i < MEMP_NUM_NETCONN; i++) { diff --git a/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_ethernet_host.ar b/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_ethernet_host.ar index ef189b631b..11fcaae29b 100644 Binary files a/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_ethernet_host.ar and b/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_ethernet_host.ar differ diff --git a/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_ethernet_host.ar b/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_ethernet_host.ar index f6b57254a5..6c2b9de10e 100644 Binary files a/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_ethernet_host.ar and b/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_ethernet_host.ar differ diff --git a/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_ethernet_host.ar b/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_ethernet_host.ar index f6b57254a5..6c2b9de10e 100644 Binary files a/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_ethernet_host.ar and b/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_ethernet_host.ar differ diff --git a/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_ethernet_host.a b/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_ethernet_host.a index 7e2f74f62e..8728622992 100644 Binary files a/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_ethernet_host.a and b/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_ethernet_host.a differ diff --git a/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_ethernet_host.a b/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_ethernet_host.a index ce9fb9966c..0dc7129377 100644 Binary files a/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_ethernet_host.a and b/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_ethernet_host.a differ diff --git a/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_ethernet_host.a b/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_ethernet_host.a index ce9fb9966c..0dc7129377 100644 Binary files a/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_ethernet_host.a and b/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_ethernet_host.a differ diff --git a/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_ethernet_host.a b/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_ethernet_host.a index 07df41cf84..8a77a92af7 100644 Binary files a/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_ethernet_host.a and b/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_ethernet_host.a differ diff --git a/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_ethernet_host.a b/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_ethernet_host.a index b1c3bd18d4..f365c568c6 100644 Binary files a/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_ethernet_host.a and b/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_ethernet_host.a differ diff --git a/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_ethernet_host.a b/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_ethernet_host.a index b1c3bd18d4..f365c568c6 100644 Binary files a/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_ethernet_host.a and b/features/nanostack/FEATURE_ETHERNET_HOST/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_ethernet_host.a differ diff --git a/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_lowpan_border_router.ar b/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_lowpan_border_router.ar old mode 100755 new mode 100644 index d7dec0f572..868ad25fcc Binary files a/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_lowpan_border_router.ar and b/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_lowpan_border_router.ar differ diff --git a/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_lowpan_border_router.ar b/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_lowpan_border_router.ar old mode 100755 new mode 100644 index 68530cb729..50026ea69c Binary files a/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_lowpan_border_router.ar and b/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_lowpan_border_router.ar differ diff --git a/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_lowpan_border_router.ar b/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_lowpan_border_router.ar old mode 100755 new mode 100644 index 68530cb729..50026ea69c Binary files a/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_lowpan_border_router.ar and b/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_lowpan_border_router.ar differ diff --git a/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_lowpan_border_router.a b/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_lowpan_border_router.a old mode 100755 new mode 100644 index f555ad50db..e06ba6c839 Binary files a/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_lowpan_border_router.a and b/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_lowpan_border_router.a differ diff --git a/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_border_router.a b/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_border_router.a old mode 100755 new mode 100644 index bdc90e5078..bba9eaef4d Binary files a/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_border_router.a and b/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_border_router.a differ diff --git a/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_border_router.a b/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_border_router.a old mode 100755 new mode 100644 index bdc90e5078..bba9eaef4d Binary files a/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_border_router.a and b/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_border_router.a differ diff --git a/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_lowpan_border_router.a b/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_lowpan_border_router.a old mode 100755 new mode 100644 index 64c1ab6335..999329f66e Binary files a/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_lowpan_border_router.a and b/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_lowpan_border_router.a differ diff --git a/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_lowpan_border_router.a b/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_lowpan_border_router.a old mode 100755 new mode 100644 index b6ffed778c..72c38c42fc Binary files a/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_lowpan_border_router.a and b/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_lowpan_border_router.a differ diff --git a/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_lowpan_border_router.a b/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_lowpan_border_router.a old mode 100755 new mode 100644 index b6ffed778c..72c38c42fc Binary files a/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_lowpan_border_router.a and b/features/nanostack/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_lowpan_border_router.a differ diff --git a/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_lowpan_host.ar b/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_lowpan_host.ar old mode 100755 new mode 100644 index b52b83611f..73930b8d9e Binary files a/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_lowpan_host.ar and b/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_lowpan_host.ar differ diff --git a/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_lowpan_host.ar b/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_lowpan_host.ar old mode 100755 new mode 100644 index dab67dd9fd..a1a5b5d2c1 Binary files a/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_lowpan_host.ar and b/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_lowpan_host.ar differ diff --git a/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_lowpan_host.ar b/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_lowpan_host.ar old mode 100755 new mode 100644 index dab67dd9fd..a1a5b5d2c1 Binary files a/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_lowpan_host.ar and b/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_lowpan_host.ar differ diff --git a/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_lowpan_host.a b/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_lowpan_host.a old mode 100755 new mode 100644 index 062bff06d8..da5ab7d0c0 Binary files a/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_lowpan_host.a and b/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_lowpan_host.a differ diff --git a/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_host.a b/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_host.a old mode 100755 new mode 100644 index e11a2b7187..effa4503d3 Binary files a/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_host.a and b/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_host.a differ diff --git a/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_host.a b/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_host.a old mode 100755 new mode 100644 index e11a2b7187..effa4503d3 Binary files a/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_host.a and b/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_host.a differ diff --git a/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_lowpan_host.a b/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_lowpan_host.a old mode 100755 new mode 100644 index 24080c7d3a..9a179d0671 Binary files a/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_lowpan_host.a and b/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_lowpan_host.a differ diff --git a/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_lowpan_host.a b/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_lowpan_host.a old mode 100755 new mode 100644 index 9d331b9fe5..3ca8e32cc3 Binary files a/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_lowpan_host.a and b/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_lowpan_host.a differ diff --git a/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_lowpan_host.a b/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_lowpan_host.a old mode 100755 new mode 100644 index 9d331b9fe5..3ca8e32cc3 Binary files a/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_lowpan_host.a and b/features/nanostack/FEATURE_LOWPAN_HOST/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_lowpan_host.a differ diff --git a/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_lowpan_router.ar b/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_lowpan_router.ar old mode 100755 new mode 100644 index c0e19cd07a..60ba464234 Binary files a/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_lowpan_router.ar and b/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_lowpan_router.ar differ diff --git a/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_lowpan_router.ar b/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_lowpan_router.ar old mode 100755 new mode 100644 index 9554800c99..b5ae02ba96 Binary files a/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_lowpan_router.ar and b/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_lowpan_router.ar differ diff --git a/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_lowpan_router.ar b/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_lowpan_router.ar old mode 100755 new mode 100644 index 9554800c99..b5ae02ba96 Binary files a/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_lowpan_router.ar and b/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_lowpan_router.ar differ diff --git a/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_lowpan_router.a b/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_lowpan_router.a old mode 100755 new mode 100644 index 25799d3af8..dacc9b074e Binary files a/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_lowpan_router.a and b/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_lowpan_router.a differ diff --git a/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_router.a b/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_router.a old mode 100755 new mode 100644 index b469e72576..b13d56b71d Binary files a/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_router.a and b/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_router.a differ diff --git a/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_router.a b/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_router.a old mode 100755 new mode 100644 index b469e72576..b13d56b71d Binary files a/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_router.a and b/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_router.a differ diff --git a/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_lowpan_router.a b/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_lowpan_router.a old mode 100755 new mode 100644 index 12be904ee0..f3fee65f35 Binary files a/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_lowpan_router.a and b/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_lowpan_router.a differ diff --git a/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_lowpan_router.a b/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_lowpan_router.a old mode 100755 new mode 100644 index 9d216ebd63..04af103f7c Binary files a/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_lowpan_router.a and b/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_lowpan_router.a differ diff --git a/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_lowpan_router.a b/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_lowpan_router.a old mode 100755 new mode 100644 index 9d216ebd63..04af103f7c Binary files a/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_lowpan_router.a and b/features/nanostack/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_lowpan_router.a differ diff --git a/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackInterface.cpp b/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackInterface.cpp index f688e94469..0f93b1f62d 100644 --- a/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackInterface.cpp +++ b/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackInterface.cpp @@ -17,11 +17,13 @@ #include "mbed.h" #include "rtos.h" #include "NanostackInterface.h" +#include "NanostackLockGuard.h" #include "ns_address.h" #include "nsdynmemLIB.h" #include "eventOS_scheduler.h" #include "randLIB.h" +#include "ip6string.h" #include "mesh_system.h" // from inside mbed-mesh-api #include "socket_api.h" @@ -33,28 +35,25 @@ #define TRACE_GROUP "nsif" #define NS_INTERFACE_SOCKETS_MAX 16 //same as NanoStack SOCKET_MAX -#define NANOSTACK_SOCKET_UDP 17 // same as nanostack SOCKET_UDP -#define NANOSTACK_SOCKET_TCP 6 // same as nanostack SOCKET_TCP #define MALLOC ns_dyn_mem_alloc #define FREE ns_dyn_mem_free +// Socket state progressions: +// UDP: UNOPENED -> DATAGRAM +// TCP client: UNOPENED -> OPENED -> CONNECTING -> STREAM -> CLOSED +// TCP server: UNOPENED -> OPENED -> LISTENING +// TCP accept: UNOPENED -> STREAM -> CLOSED enum socket_mode_t { SOCKET_MODE_UNOPENED, // No socket ID + SOCKET_MODE_DATAGRAM, // Socket is datagram type SOCKET_MODE_OPENED, // Socket ID but no assigned use yet SOCKET_MODE_CONNECTING, // Socket is connecting but not open yet - SOCKET_MODE_DATAGRAM, // Socket is bound to a port and listening for datagrams SOCKET_MODE_STREAM, // Socket has an open stream SOCKET_MODE_CLOSED, // Socket is closed and resources are freed + SOCKET_MODE_LISTENING, // Socket is listening for connections }; -class NanostackBuffer { -public: - NanostackBuffer *next; /*mode); + + int temp_socket = socket_accept(socket_id, addr, socket_callback); + if (temp_socket < 0) { + tr_error("NanostackSocket::accept() failed"); + return temp_socket; + } + if (!accepted_socket->attach(temp_socket)) { + return -1; + } + accepted_socket->mode = SOCKET_MODE_STREAM; + return temp_socket; +} + +bool NanostackSocket::attach(int8_t temp_socket) +{ + nanostack_assert_locked(); if (temp_socket >= NS_INTERFACE_SOCKETS_MAX) { MBED_ASSERT(false); return false; @@ -181,9 +208,7 @@ bool NanostackSocket::open(void) } socket_id = temp_socket; socket_tbl[socket_id] = this; - mode = SOCKET_MODE_OPENED; return true; - } void NanostackSocket::close() @@ -201,26 +226,10 @@ void NanostackSocket::close() MBED_ASSERT(SOCKET_MODE_UNOPENED == mode); } - data_free_all(); - mode = SOCKET_MODE_CLOSED; signal_event(); } -bool NanostackSocket::is_bound() -{ - return SOCKET_MODE_DATAGRAM == mode; -} - -void NanostackSocket::set_bound() -{ - nanostack_assert_locked(); - MBED_ASSERT(SOCKET_MODE_OPENED == mode); - if (SOCKET_UDP == proto) { - mode = SOCKET_MODE_DATAGRAM; - } -} - bool NanostackSocket::is_connecting() { return SOCKET_MODE_CONNECTING == mode; @@ -235,6 +244,11 @@ void NanostackSocket::set_connecting(ns_address_t *addr) mode = SOCKET_MODE_CONNECTING; } +bool NanostackSocket::is_connected() +{ + return SOCKET_MODE_STREAM == mode; +} + void NanostackSocket::set_connected() { nanostack_assert_locked(); @@ -243,6 +257,19 @@ void NanostackSocket::set_connected() mode = SOCKET_MODE_STREAM; } +bool NanostackSocket::is_listening() +{ + return SOCKET_MODE_LISTENING == mode; +} + +void NanostackSocket::set_listening() +{ + nanostack_assert_locked(); + MBED_ASSERT(SOCKET_MODE_OPENED == mode); + + mode = SOCKET_MODE_LISTENING; +} + void NanostackSocket::signal_event() { nanostack_assert_locked(); @@ -267,151 +294,54 @@ void NanostackSocket::socket_callback(void *cb) { tr_debug("SOCKET_DATA, sock=%d, bytes=%d", sock_cb->socket_id, sock_cb->d_len); socket->event_data(sock_cb); break; - case SOCKET_BIND_DONE: - tr_debug("SOCKET_BIND_DONE"); - socket->event_bind_done(sock_cb); + case SOCKET_CONNECT_DONE: + tr_debug("SOCKET_CONNECT_DONE"); + socket->event_connect_done(sock_cb); break; - case SOCKET_BIND_FAIL: - tr_debug("SOCKET_BIND_FAIL"); + case SOCKET_CONNECT_FAIL: + tr_debug("SOCKET_CONNECT_FAIL"); + socket->event_connect_fail(sock_cb); break; - case SOCKET_BIND_AUTH_FAIL: - tr_debug("SOCKET_BIND_AUTH_FAIL"); + case SOCKET_CONNECT_AUTH_FAIL: + tr_debug("SOCKET_CONNECT_AUTH_FAIL"); break; case SOCKET_INCOMING_CONNECTION: tr_debug("SOCKET_INCOMING_CONNECTION"); + socket->event_incoming_connection(sock_cb); break; case SOCKET_TX_FAIL: tr_debug("SOCKET_TX_FAIL"); + socket->event_tx_fail(sock_cb); break; case SOCKET_CONNECT_CLOSED: tr_debug("SOCKET_CONNECT_CLOSED"); - socket->event_connnect_closed(sock_cb); + socket->event_connect_closed(sock_cb); break; case SOCKET_CONNECTION_RESET: tr_debug("SOCKET_CONNECTION_RESET"); + socket->event_connection_reset(sock_cb); break; case SOCKET_NO_ROUTE: tr_debug("SOCKET_NO_ROUTE"); + socket->event_tx_fail(sock_cb); break; case SOCKET_TX_DONE: - tr_debug("SOCKET_TX_DONE, %d bytes sent", sock_cb->d_len); socket->event_tx_done(sock_cb); break; + case SOCKET_NO_RAM: + tr_debug("SOCKET_NO_RAM"); + socket->event_tx_fail(sock_cb); + break; + case SOCKET_CONNECTION_PROBLEM: + tr_debug("SOCKET_CONNECTION_PROBLEM"); + break; default: - // SOCKET_NO_RAM, error case for SOCKET_TX_DONE break; } } -bool NanostackSocket::data_available() -{ - nanostack_assert_locked(); - MBED_ASSERT((SOCKET_MODE_DATAGRAM == mode) || - (SOCKET_MODE_CONNECTING == mode) || - (SOCKET_MODE_STREAM == mode)); - - return (NULL == rxBufChain) ? false : true; -} - -size_t NanostackSocket::data_copy_and_free(void *dest, size_t len, - SocketAddress *address, bool stream) -{ - nanostack_assert_locked(); - MBED_ASSERT((SOCKET_MODE_DATAGRAM == mode) || - (mode == SOCKET_MODE_STREAM)); - - NanostackBuffer *data_buf = rxBufChain; - if (NULL == data_buf) { - // No data - return 0; - } - - if (address) { - convert_ns_addr_to_mbed(address, &data_buf->ns_address); - } - - size_t copy_size = (len > data_buf->length) ? data_buf->length : len; - memcpy(dest, data_buf->payload, copy_size); - - if (stream && (copy_size < data_buf->length)) { - // Update the size in the buffer - size_t new_buf_size = data_buf->length - copy_size; - memmove(data_buf->payload, data_buf->payload + copy_size, new_buf_size); - data_buf->length = new_buf_size; - } else { - // Entire packet used so free it - rxBufChain = data_buf->next; - FREE(data_buf); - } - - return copy_size; -} - -void NanostackSocket::data_free_all(void) -{ - nanostack_assert_locked(); - // No mode requirement - - NanostackBuffer *buffer = rxBufChain; - rxBufChain = NULL; - while (buffer != NULL) { - NanostackBuffer *next_buffer = buffer->next; - FREE(buffer); - buffer = next_buffer; - } -} - -void NanostackSocket::data_attach(NanostackBuffer *data_buf) -{ - nanostack_assert_locked(); - MBED_ASSERT((SOCKET_MODE_DATAGRAM == mode) || - (SOCKET_MODE_STREAM == mode)); - - // Add to linked list - tr_debug("data_attach socket=%p", this); - if (NULL == rxBufChain) { - rxBufChain = data_buf; - } else { - NanostackBuffer *buf_tmp = rxBufChain; - while (NULL != buf_tmp->next) { - buf_tmp = buf_tmp->next; - } - buf_tmp->next = data_buf; - } - signal_event(); -} - void NanostackSocket::event_data(socket_callback_t *sock_cb) -{ - nanostack_assert_locked(); - MBED_ASSERT((SOCKET_MODE_DATAGRAM == mode) || - (SOCKET_MODE_STREAM == mode)); - - // Allocate buffer - NanostackBuffer *recv_buff = (NanostackBuffer *) MALLOC( - sizeof(NanostackBuffer) + sock_cb->d_len); - if (NULL == recv_buff) { - tr_error("alloc failed!"); - return; - } - recv_buff->next = NULL; - - // Write data to buffer - int16_t length = socket_read(sock_cb->socket_id, - &recv_buff->ns_address, recv_buff->payload, - sock_cb->d_len); - if (length < 0) { - tr_error("socket_read failed!"); - FREE(recv_buff); - return; - } - recv_buff->length = length; - - data_attach(recv_buff); -} - -void NanostackSocket::event_tx_done(socket_callback_t *sock_cb) { nanostack_assert_locked(); MBED_ASSERT((SOCKET_MODE_STREAM == mode) || @@ -420,7 +350,22 @@ void NanostackSocket::event_tx_done(socket_callback_t *sock_cb) signal_event(); } -void NanostackSocket::event_bind_done(socket_callback_t *sock_cb) +void NanostackSocket::event_tx_done(socket_callback_t *sock_cb) +{ + nanostack_assert_locked(); + MBED_ASSERT((SOCKET_MODE_STREAM == mode) || + (SOCKET_MODE_DATAGRAM == mode)); + + if (mode == SOCKET_MODE_DATAGRAM) { + tr_debug("SOCKET_TX_DONE, %d bytes sent", sock_cb->d_len); + } else if (mode == SOCKET_MODE_STREAM) { + tr_debug("SOCKET_TX_DONE, %d bytes remaining", sock_cb->d_len); + } + + signal_event(); +} + +void NanostackSocket::event_connect_done(socket_callback_t *sock_cb) { nanostack_assert_locked(); MBED_ASSERT(SOCKET_MODE_CONNECTING == mode); @@ -429,7 +374,50 @@ void NanostackSocket::event_bind_done(socket_callback_t *sock_cb) signal_event(); } -void NanostackSocket::event_connnect_closed(socket_callback_t *sock_cb) +void NanostackSocket::event_connect_fail(socket_callback_t *sock_cb) +{ + nanostack_assert_locked(); + MBED_ASSERT(mode == SOCKET_MODE_CONNECTING); + close(); +} + +void NanostackSocket::event_incoming_connection(socket_callback_t *sock_cb) +{ + nanostack_assert_locked(); + MBED_ASSERT(mode == SOCKET_MODE_LISTENING); + signal_event(); +} + +void NanostackSocket::event_connect_closed(socket_callback_t *sock_cb) +{ + nanostack_assert_locked(); + + // Can happen if we have an orderly close() + // Might never happen as we have not implemented shutdown() in abstraction layer. + MBED_ASSERT(mode == SOCKET_MODE_STREAM); + close(); +} + +void NanostackSocket::event_tx_fail(socket_callback_t *sock_cb) +{ + nanostack_assert_locked(); + + switch (mode) { + case SOCKET_MODE_CONNECTING: + case SOCKET_MODE_STREAM: + // TX_FAIL is fatal for stream sockets + close(); + break; + case SOCKET_MODE_DATAGRAM: + // TX_FAIL is non-fatal for datagram sockets + break; + default: + MBED_ASSERT(false); + break; + } +} + +void NanostackSocket::event_connection_reset(socket_callback_t *sock_cb) { nanostack_assert_locked(); @@ -439,28 +427,34 @@ void NanostackSocket::event_connnect_closed(socket_callback_t *sock_cb) close(); } -NanostackInterface * NanostackInterface::_ns_interface; +NanostackInterface *NanostackInterface::_ns_interface; -NanostackInterface * NanostackInterface::get_stack() +NanostackInterface *NanostackInterface::get_stack() { - nanostack_lock(); + NanostackLockGuard lock; if (NULL == _ns_interface) { _ns_interface = new NanostackInterface(); } - nanostack_unlock(); - return _ns_interface; } - const char * NanostackInterface::get_ip_address() { + NanostackLockGuard lock; + + for (int if_id = 1; if_id <= 127; if_id++) { + uint8_t address[16]; + int ret = arm_net_address_get(if_id, ADDR_IPV6_GP, address); + if (ret == 0) { + ip6tos(address, text_ip_address); + return text_ip_address; + } + } // Must result a valid IPv6 address // For gethostbyname() to detect IP version. - static const char localhost[] = "::"; - return localhost; + return "::"; } nsapi_error_t NanostackInterface::socket_open(void **handle, nsapi_protocol_t protocol) @@ -481,31 +475,28 @@ nsapi_error_t NanostackInterface::socket_open(void **handle, nsapi_protocol_t pr } *handle = (void*)NULL; - nanostack_lock(); + NanostackLockGuard lock; NanostackSocket * socket = new NanostackSocket(ns_proto); - if (NULL == socket) { - nanostack_unlock(); + if (socket == NULL) { tr_debug("socket_open() ret=%i", NSAPI_ERROR_NO_MEMORY); return NSAPI_ERROR_NO_MEMORY; } if (!socket->open()) { delete socket; - nanostack_unlock(); tr_debug("socket_open() ret=%i", NSAPI_ERROR_DEVICE_ERROR); return NSAPI_ERROR_DEVICE_ERROR; } *handle = (void*)socket; - nanostack_unlock(); - tr_debug("socket_open() socket=%p, sock_id=%d, ret=0", socket, socket->socket_id); - return 0; + return NSAPI_ERROR_OK; } nsapi_error_t NanostackInterface::socket_close(void *handle) { + NanostackLockGuard lock; // Validate parameters NanostackSocket * socket = static_cast(handle); if (NULL == handle) { @@ -514,105 +505,138 @@ nsapi_error_t NanostackInterface::socket_close(void *handle) } tr_debug("socket_close(socket=%p) sock_id=%d", socket, socket->socket_id); - nanostack_lock(); - delete socket; - nanostack_unlock(); - return 0; } -nsapi_size_or_error_t NanostackInterface::socket_sendto(void *handle, const SocketAddress &address, const void *data, nsapi_size_t size) +nsapi_size_or_error_t NanostackInterface::do_sendto(void *handle, const ns_address_t *address, const void *data, nsapi_size_t size) { // Validate parameters NanostackSocket * socket = static_cast(handle); - if (NULL == handle) { + if (handle == NULL) { MBED_ASSERT(false); return NSAPI_ERROR_NO_SOCKET; } - if (address.get_ip_version() != NSAPI_IPv6) { - return NSAPI_ERROR_UNSUPPORTED; - } - - nanostack_lock(); - nsapi_size_or_error_t ret; - if (socket->closed()) { + + NanostackLockGuard lock; + + if (socket->closed() || (!address && !socket->is_connected())) { ret = NSAPI_ERROR_NO_CONNECTION; - } else if (NANOSTACK_SOCKET_TCP == socket->proto) { - tr_error("socket_sendto() not supported with SOCKET_STREAM!"); - ret = NSAPI_ERROR_UNSUPPORTED; - } else { - ns_address_t ns_address; - convert_mbed_addr_to_ns(&ns_address, &address); - if (!socket->is_bound()) { - socket->set_bound(); - } - int8_t send_to_status = ::socket_sendto(socket->socket_id, &ns_address, - (uint8_t *)data, size); - /* - * \return 0 on success. - * \return -1 invalid socket id. - * \return -2 Socket memory allocation fail. - * \return -3 TCP state not established. - * \return -4 Socket tx process busy. - * \return -5 TLS authentication not ready. - * \return -6 Packet too short. - * */ - if (-4 == send_to_status) { - ret = NSAPI_ERROR_WOULD_BLOCK; - } else if (0 != send_to_status) { - tr_error("socket_sendto: error=%d", send_to_status); - ret = NSAPI_ERROR_DEVICE_ERROR; - } else { - ret = size; - } + goto out; } - nanostack_unlock(); + if (address && socket->proto == SOCKET_TCP) { + tr_error("socket_sendto() not supported with TCP!"); + ret = NSAPI_ERROR_IS_CONNECTED; + goto out; + } + int retcode; +#if 0 + retcode = ::socket_sendto(socket->socket_id, address, + data, size); +#else + // Use sendmsg purely to get the new return style + // of returning data written rather than 0 on success, + // which means TCP can do partial writes. (Sadly, + // it's the only call which takes flags so we can + // leave the NS_MSG_LEGACY0 flag clear). + ns_msghdr_t msg; + ns_iovec_t iov; + iov.iov_base = const_cast(data); + iov.iov_len = size; + msg.msg_name = const_cast(address); + msg.msg_namelen = address ? sizeof *address : 0; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = NULL; + msg.msg_controllen = 0; + retcode = ::socket_sendmsg(socket->socket_id, &msg, 0); +#endif + + /* + * \return length if entire amount written (which could be 0) + * \return value >0 and socket_id, ret); return ret; } +nsapi_size_or_error_t NanostackInterface::socket_sendto(void *handle, const SocketAddress &address, const void *data, nsapi_size_t size) +{ + if (address.get_ip_version() != NSAPI_IPv6) { + return NSAPI_ERROR_UNSUPPORTED; + } + + ns_address_t ns_address; + convert_mbed_addr_to_ns(&ns_address, &address); + /*No lock gaurd needed here as do_sendto() will handle locks.*/ + return do_sendto(handle, &ns_address, data, size); +} + nsapi_size_or_error_t NanostackInterface::socket_recvfrom(void *handle, SocketAddress *address, void *buffer, nsapi_size_t size) { // Validate parameters - NanostackSocket * socket = static_cast(handle); - if (NULL == handle) { + NanostackSocket *socket = static_cast(handle); + if (handle == NULL) { MBED_ASSERT(false); return NSAPI_ERROR_NO_SOCKET; } - if (NULL == buffer) { - MBED_ASSERT(false); - return NSAPI_ERROR_PARAMETER; - } - if (0 == size) { - MBED_ASSERT(false); - return NSAPI_ERROR_PARAMETER; - } - - nanostack_lock(); nsapi_size_or_error_t ret; + + NanostackLockGuard lock; + if (socket->closed()) { ret = NSAPI_ERROR_NO_CONNECTION; - } else if (NANOSTACK_SOCKET_TCP == socket->proto) { - tr_error("recv_from() not supported with SOCKET_STREAM!"); - ret = NSAPI_ERROR_UNSUPPORTED; - } else if (!socket->data_available()) { - ret = NSAPI_ERROR_WOULD_BLOCK; - } else { - ret = socket->data_copy_and_free(buffer, size, address, false); + goto out; } - nanostack_unlock(); + ns_address_t ns_address; - tr_debug("socket_recvfrom(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret); + int retcode; + retcode = ::socket_recvfrom(socket->socket_id, buffer, size, 0, &ns_address); + + if (retcode == NS_EWOULDBLOCK) { + ret = NSAPI_ERROR_WOULD_BLOCK; + } else if (retcode < 0) { + ret = NSAPI_ERROR_PARAMETER; + } else { + ret = retcode; + if (address != NULL) { + convert_ns_addr_to_mbed(address, &ns_address); + } + } + +out: + if (address) { + tr_debug("socket_recvfrom(socket=%p) sock_id=%d, ret=%i, addr=[%s]:%i", socket, socket->socket_id, ret, + trace_ipv6(address->get_ip_bytes()), address->get_port()); + } else { + tr_debug("socket_recv(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret); + } return ret; } @@ -620,8 +644,8 @@ nsapi_size_or_error_t NanostackInterface::socket_recvfrom(void *handle, SocketAd nsapi_error_t NanostackInterface::socket_bind(void *handle, const SocketAddress &address) { // Validate parameters - NanostackSocket * socket = static_cast(handle); - if (NULL == handle) { + NanostackSocket *socket = static_cast(handle); + if (handle == NULL) { MBED_ASSERT(false); return NSAPI_ERROR_NO_SOCKET; } @@ -638,68 +662,139 @@ nsapi_error_t NanostackInterface::socket_bind(void *handle, const SocketAddress return NSAPI_ERROR_UNSUPPORTED; } - nanostack_lock(); + NanostackLockGuard lock; ns_address_t ns_address; ns_address.type = ADDRESS_IPV6; memcpy(ns_address.address, addr_field, sizeof ns_address.address); ns_address.identifier = address.get_port(); - nsapi_error_t ret = NSAPI_ERROR_DEVICE_ERROR; - if (0 == ::socket_bind(socket->socket_id, &ns_address)) { - socket->set_bound(); - ret = 0; + nsapi_error_t ret; + int retcode = ::socket_bind(socket->socket_id, &ns_address); + + if (retcode == 0) { + ret = NSAPI_ERROR_OK; + } else { + ret = NSAPI_ERROR_PARAMETER; } - nanostack_unlock(); - - tr_debug("socket_bind(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret); + tr_debug("socket_bind(socket=%p) sock_id=%d, retcode=%i, ret=%i", socket, socket->socket_id, retcode, ret); return ret; } nsapi_error_t NanostackInterface::setsockopt(void *handle, int level, int optname, const void *optval, unsigned optlen) { - return NSAPI_ERROR_UNSUPPORTED; + NanostackSocket *socket = static_cast(handle); + if (handle == NULL) { + MBED_ASSERT(false); + return NSAPI_ERROR_NO_SOCKET; + } + + nsapi_error_t ret; + + NanostackLockGuard lock; + + if (::socket_setsockopt(socket->socket_id, level, optname, optval, optlen) == 0) { + ret = NSAPI_ERROR_OK; + } else { + ret = NSAPI_ERROR_PARAMETER; + } + + return ret; } nsapi_error_t NanostackInterface::getsockopt(void *handle, int level, int optname, void *optval, unsigned *optlen) { - return NSAPI_ERROR_UNSUPPORTED; + NanostackSocket *socket = static_cast(handle); + if (handle == NULL) { + MBED_ASSERT(false); + return NSAPI_ERROR_NO_SOCKET; + } + + nsapi_error_t ret; + + NanostackLockGuard lock; + + uint16_t optlen16 = *optlen; + if (::socket_getsockopt(socket->socket_id, level, optname, optval, &optlen16) == 0) { + ret = NSAPI_ERROR_OK; + *optlen = optlen16; + } else { + ret = NSAPI_ERROR_PARAMETER; + } + + return ret; } nsapi_error_t NanostackInterface::socket_listen(void *handle, int backlog) { - return NSAPI_ERROR_UNSUPPORTED; + //Check if socket exists + NanostackSocket *socket = static_cast(handle); + if (handle == NULL) { + MBED_ASSERT(false); + return NSAPI_ERROR_NO_SOCKET; + } + + nsapi_error_t ret = NSAPI_ERROR_OK; + + NanostackLockGuard lock; + + if(::socket_listen(socket->socket_id, backlog) < 0) { + ret = NSAPI_ERROR_PARAMETER; + } else { + socket->set_listening(); + } + + return ret; } nsapi_error_t NanostackInterface::socket_connect(void *handle, const SocketAddress &addr) { // Validate parameters - NanostackSocket * socket = static_cast(handle); - if (NULL == handle) { + NanostackSocket *socket = static_cast(handle); + nsapi_error_t ret; + if (handle == NULL) { MBED_ASSERT(false); return NSAPI_ERROR_NO_SOCKET; } + NanostackLockGuard lock; + if (addr.get_ip_version() != NSAPI_IPv6) { - return NSAPI_ERROR_UNSUPPORTED; + ret = NSAPI_ERROR_UNSUPPORTED; + goto out; } - nanostack_lock(); + if (socket->closed()) { + ret = NSAPI_ERROR_NO_CONNECTION; + goto out; + } + + if (socket->is_connecting()) { + ret = NSAPI_ERROR_ALREADY; + goto out; + } + + if (socket->is_connected()) { + ret = NSAPI_ERROR_IS_CONNECTED; + goto out; + } - nsapi_error_t ret; ns_address_t ns_addr; - int random_port = socket->is_bound() ? 0 : 1; + convert_mbed_addr_to_ns(&ns_addr, &addr); - if (0 == ::socket_connect(socket->socket_id, &ns_addr, random_port)) { - socket->set_connecting(&ns_addr); - ret = 0; + if (::socket_connect(socket->socket_id, &ns_addr, 0) == 0) { + if (socket->proto == SOCKET_TCP) { + socket->set_connecting(&ns_addr); + ret = NSAPI_ERROR_IN_PROGRESS; + } else { + ret = NSAPI_ERROR_OK; + } } else { ret = NSAPI_ERROR_DEVICE_ERROR; } - nanostack_unlock(); - +out: tr_debug("socket_connect(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret); return ret; @@ -707,95 +802,77 @@ nsapi_error_t NanostackInterface::socket_connect(void *handle, const SocketAddre nsapi_error_t NanostackInterface::socket_accept(void *server, void **handle, SocketAddress *address) { - return NSAPI_ERROR_UNSUPPORTED; -} + NanostackSocket * socket = static_cast(server); + NanostackSocket *accepted_sock = NULL; + nsapi_error_t ret; -nsapi_size_or_error_t NanostackInterface::socket_send(void *handle, const void *p, nsapi_size_t size) -{ - // Validate parameters - NanostackSocket * socket = static_cast(handle); - if (NULL == handle) { + if (handle == NULL) { MBED_ASSERT(false); return NSAPI_ERROR_NO_SOCKET; } - nanostack_lock(); + NanostackLockGuard lock; - nsapi_size_or_error_t ret; - if (socket->closed()) { - ret = NSAPI_ERROR_NO_CONNECTION; - } else if (socket->is_connecting()) { - ret = NSAPI_ERROR_WOULD_BLOCK; - } else { - ret = ::socket_sendto(socket->socket_id, &socket->ns_address, (uint8_t*)p, size); - /* - * \return 0 on success. - * \return -1 invalid socket id. - * \return -2 Socket memory allocation fail. - * \return -3 TCP state not established. - * \return -4 Socket tx process busy. - * \return -5 TLS authentication not ready. - * \return -6 Packet too short. - * */ - if (-4 == ret) { - ret = NSAPI_ERROR_WOULD_BLOCK; - } else if (ret != 0) { - tr_warning("socket_sendto ret %i, socket_id %i", ret, socket->socket_id); - ret = NSAPI_ERROR_DEVICE_ERROR; - } else { - ret = size; - } + if (!socket->is_listening()) { + ret = NSAPI_ERROR_PARAMETER; + goto out; } - nanostack_unlock(); + accepted_sock = new NanostackSocket(socket->proto); + if (accepted_sock == NULL) { + ret = NSAPI_ERROR_NO_MEMORY; + goto out; + } - tr_debug("socket_send(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret); + ns_address_t ns_addr; + int retcode; + retcode = socket->accept(accepted_sock, &ns_addr); + if (retcode < 0) { + delete accepted_sock; + if (retcode == NS_EWOULDBLOCK) { + ret = NSAPI_ERROR_WOULD_BLOCK; + } else { + ret = NSAPI_ERROR_DEVICE_ERROR; + } + goto out; + } + ret = NSAPI_ERROR_OK; + + if (address) { + convert_ns_addr_to_mbed(address, &ns_addr); + } + + *handle = accepted_sock; + +out: + tr_debug("socket_accept() socket=%p, sock_id=%d, ret=%i", accepted_sock, accepted_sock ? accepted_sock->socket_id : -1, ret); return ret; } +nsapi_size_or_error_t NanostackInterface::socket_send(void *handle, const void *data, nsapi_size_t size) +{ + return do_sendto(handle, NULL, data, size); +} + nsapi_size_or_error_t NanostackInterface::socket_recv(void *handle, void *data, nsapi_size_t size) { - // Validate parameters - NanostackSocket * socket = static_cast(handle); - if (NULL == handle) { - MBED_ASSERT(false); - return NSAPI_ERROR_NO_SOCKET; - } - - nanostack_lock(); - - nsapi_size_or_error_t ret; - if (socket->closed()) { - ret = NSAPI_ERROR_NO_CONNECTION; - } else if (socket->data_available()) { - ret = socket->data_copy_and_free(data, size, NULL, true); - } else { - ret = NSAPI_ERROR_WOULD_BLOCK; - } - - nanostack_unlock(); - - tr_debug("socket_recv(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret); - - return ret; + return socket_recvfrom(handle, NULL, data, size); } void NanostackInterface::socket_attach(void *handle, void (*callback)(void *), void *id) { // Validate parameters NanostackSocket * socket = static_cast(handle); - if (NULL == handle) { + if (handle == NULL) { MBED_ASSERT(false); return; } - nanostack_lock(); + NanostackLockGuard lock; socket->callback = callback; socket->callback_data = id; - nanostack_unlock(); - tr_debug("socket_attach(socket=%p) sock_id=%d", socket, socket->socket_id); } diff --git a/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackInterface.h b/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackInterface.h index 359e4a4758..8c5b611267 100644 --- a/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackInterface.h +++ b/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackInterface.h @@ -26,6 +26,8 @@ #include "NanostackEthernetInterface.h" #include "MeshInterfaceNanostack.h" +struct ns_address; + class NanostackInterface : public NetworkStack { public: static NanostackInterface *get_stack(); @@ -229,6 +231,8 @@ protected: virtual nsapi_error_t getsockopt(void *handle, int level, int optname, void *optval, unsigned *optlen); private: + nsapi_size_or_error_t do_sendto(void *handle, const struct ns_address *address, const void *data, nsapi_size_t size); + char text_ip_address[40]; static NanostackInterface * _ns_interface; }; diff --git a/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackLockGuard.h b/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackLockGuard.h new file mode 100644 index 0000000000..5bfd9409f2 --- /dev/null +++ b/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackLockGuard.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2017 ARM Limited. All rights reserved. + * 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. + */ + +#ifndef NANOSTACK_LOCK_GUARD_H_ +#define NANOSTACK_LOCK_GUARD_H_ + +#include "eventOS_scheduler.h" + +/** + * RAII style Nanostack mutex acquisition. + * Mutex is held until object leaves scope. + */ + +class NanostackLockGuard { +public: + NanostackLockGuard() { + eventOS_scheduler_mutex_wait(); + } + + ~NanostackLockGuard() { + eventOS_scheduler_mutex_release(); + } + +private: + NanostackLockGuard(const NanostackLockGuard&); + NanostackLockGuard& operator=(const NanostackLockGuard&); +}; + +#endif /* NANOSTACK_LOCK_GUARD_H_ */ diff --git a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/docs/11_API_sockets.md b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/docs/11_API_sockets.md index ffbc38fc3c..16ccb61fef 100644 --- a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/docs/11_API_sockets.md +++ b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/docs/11_API_sockets.md @@ -82,16 +82,17 @@ Member|Description Event type|Description ----------|----------- `SOCKET_DATA`|Data received. -`SOCKET_BIND_DONE`|TCP connection ready. -`SOCKET_BIND_FAIL`|TCP connection failed. -`SOCKET_BIND_AUTH_FAIL`|TCP connection authentication failed. +`SOCKET_CONNECT_DONE`|TCP connection ready. +`SOCKET_CONNECT_FAIL`|TCP connection failed. +`SOCKET_CONNECT_AUTH_FAIL`|TCP connection authentication failed. `SOCKET_INCOMING_CONNECTION`|TCP connection state change from listen to establishment. `SOCKET_TX_FAIL`|Socket data send failed. `SOCKET_CONNECT_CLOSED`|TCP connection closed. `SOCKET_CONNECTION_RESET`|TCP connection reset. `SOCKET_NO_ROUTER`|No route available to destination. -`SOCKET_TX_DONE`|Last socket TX process done, in TCP case whole TCP process is ready. +`SOCKET_TX_DONE`|TX process done (one per datagram, or if stream will be called each time some data acknowledged) `SOCKET_NO_RAM `|If no RAM is present. +`SOCKET_CONNECTION_PROBLEM`|If TCP is suffering a connection problem (a soft event, it continues to retry). An example parsing socket event: @@ -102,7 +103,7 @@ An example parsing socket event: static uint8_t rx_buffer[APP_SOCK_RX_SIZE]; void main_receive -( +(SOCKET_NO_ROUTER void *cb ) { @@ -248,6 +249,31 @@ Parameter|Description
-6 bind2addrsel is not supported on this type of socket.
+### How to connect a socket + +To connect a socket to a remote host: + +``` +int8_t socket_connect +( + int8_t socket, + ns_address_t *address, + uint8_t randomly_take_src_numbers +) +``` + +Parameter|Description +---------|----------- +`socket`|The socket ID, which is used to connect to the remote host. +`address`|A pointer to an address_t structure that contains the address of the remote host. +`randomly_take_src_numbers`|Value 1 indicates that a randomly selected source port number is used. + +
+
Return value
+
0 Valid request.
+
-1 Fail.
+
+ ### How to read data from a socket To read received data from a socket: @@ -300,9 +326,9 @@ _Table 3-24_ describes the possible response events when the outcome of the func Response Event|Socket Type|Description --------------|-----------|----------- -`SOCKET_TX_DONE`|TCP/UDP|UDP link layer TX ready/TCP TX process ready by TCP _Acknowledgement_ (ACK). -`SOCKET_TX_FAIL`|UDP|UDP link layer TX fails. -`SOCKET_CONNECTION_RESET`|TCP|TX process fails and connection closed. +`SOCKET_TX_DONE`|TCP/UDP|UDP: link layer TX ready (d_len = length of datagram). TCP: some data acknowledged (d_len = unacknowledged data remaining in send queue). +`SOCKET_TX_FAIL`|TCP/UDP|UDP: link layer TX fails. TCP: transmit timeout (no ACKs) and connection closed. +`SOCKET_CONNECTION_RESET`|TCP|Either the peer reset the connection or there was a protocol error. Connection closed. To transmit data on an unconnected socket: @@ -364,7 +390,7 @@ The TCP socket configuration API offers three function calls, as shown in _Table Function|Description --------|----------- `socket_listen()`|Set socket to the listen state. -`socket_connect()`|Connect socket to a host. +`socket_accept()`|Accepts an incoming TCP connection. `socket_shutdown()`|Shut down socket connection. To set a TCP socket into the listen state: @@ -380,47 +406,50 @@ int8_t socket_listen Parameter|Description ---------|----------- `socket`|The socket ID that is to be set to the listen state. -`backlog`|The pending connections queue size. (Not yet implemented). +`backlog`|The pending connections queue size.
Return value
0 Valid request.
-
Note: This does not imply that the state of the socket has been successfully changed.
-1 Fail.
-To connect a socket to a remote host: +For connecting a socket, please refer to the section above [How to connect a socket](#how-to-connect-a-socket). + +There are three possible responses from the stack for `socket_connect( )`: + +- `SOCKET_CONNECT_DONE` + - TCP handshake ready. + +- `SOCKET_CONNECT_FAIL` + - TCP handshake fail - connection actively refused or protocol error. + +- `SOCKET_TX_FAIL` + - TCP handshake fail - timed out. + +For accepting an incoming TCP connection, use `socket_accept()` function. ``` -int8_t socket_connect +int8_t socket_accept() ( - int8_t socket, - ns_address_t *address, - uint8_t randomly_take_src_numbers + int8_t listen_socket_id, + ns_address_t *addr, + void (*passed_fptr) (void *) ) ``` Parameter|Description ---------|----------- -`socket`|The socket ID, which is used to connect to the remote host. -`address`|A pointer to an address_t structure that contains the address of the remote host. -`randomly_take_src_numbers`|Value 1 indicates that a randomly selected source port number is used. +`listen_socket_id`|The socket ID of the listening socket. +`addr`|Pointer to the address structure where you wish to save the address +`passed_fptr`|A function pointer to a function that is called whenever a data frame is received to the new socket
Return value
-
0 Valid request.
-
Note:This does not imply that the state of the socket has been successfully changed.
+
0 or greter than zero, i.e., id for the new socket.
-1 Fail.
-There are two possible responses from the stack for `socket_connect( )`: - -- `SOCKET_BIND_DONE` - - TCP handshake ready. - -- `SOCKET_CONNECT_FAIL_CLOSED` - - TCP handshake fail. - To shut down a TCP connection: ``` diff --git a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/docs/16_API_porting.md b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/docs/16_API_porting.md index c37e7ed898..7ab23ea911 100644 --- a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/docs/16_API_porting.md +++ b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/docs/16_API_porting.md @@ -59,7 +59,9 @@ initializing. ![NanostackRfPhy](img/NanostackRfPhy.png) -Applications use only `LoWPANNDInterface` or `ThreadInterface` directly to set up the network and provide a driver. Rest of the classes provide an abstration between Nanostack and Socket layers of mbed OS. +Applications use only `LoWPANNDInterface`, `ThreadInterface` or `NanostackEthernetInterface` +directly to set up the network and provide a driver. Rest of the classes provide an abstration +between Nanostack and Socket layers of mbed OS. See [NanostackRfPhy.h](https://github.com/ARMmbed/mbed-os/blob/master/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackRfPhy.h) for an up-to-date header file and API. diff --git a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/NanostackRfPhy.plantuml.txt b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/NanostackRfPhy.plantuml.txt index b8a0a776b2..0428954f6e 100644 --- a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/NanostackRfPhy.plantuml.txt +++ b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/NanostackRfPhy.plantuml.txt @@ -1,28 +1,66 @@ @startuml -class NanostackRfPhy { - +int8_t rf_register() - +int8_t rf_register() - +void get_mac_address(uint8_t *mac) - +void set_mac_address(uint8_t *mac) +package "mbed OS Socket abstraction" { + abstract class MeshInterface -|> NetworkInterface + + interface NetworkInterface { + +connect(); + +disconnect(); + +NetworkStack *get_stack(); + } + + interface NetworkStack } -class MeshInterfaceNanostack { +package "Nanostack PHY driver interface" { + interface NanostackPhy { + +int8_t phy_register() + +void get_mac_address(uint8_t *mac) + +void set_mac_address(uint8_t *mac) + } + NanostackPhy <|-- abstract class NanostackRfPhy + NanostackPhy <|-- abstract class NanostackEthernetPhy } -MeshInterfaceNanostack o-- NanostackRfPhy -MeshInterfaceNanostack o-- AbstractMesh -MeshInterfaceNanostack o-- NanostackInterface -class MeshInterface { +package "mesh API internals" { + class NanostackInterface { + {static} +NanostackInterface *get_stack() + #socket_open() + #socket_close() + #socket_bind() + #socket_listen() + #socket_connect() + #socket_accept() + #socket_send() + #socket_recv() + #socket_sendto() + #socket_recvfrom() + #socket_attach() + #setsockopt() + #getsockopt() + } + NetworkStack <|-- NanostackInterface + + abstract class MeshInterfaceNanostack { + +initialize(NanostackPhy *phy) + +connect() + +disconnect() + #NetworkStack *get_stack(void) + } + MeshInterface <|-- MeshInterfaceNanostack + NanostackPhy --o MeshInterfaceNanostack + MeshInterfaceNanostack -left-> NanostackInterface : get_stack() } -NanostackInterface --|> NetworkStack -MeshInterfaceNanostack --|> MeshInterface -MeshInterface --|> NetworkInterface -LoWPANNDInterface --|> MeshInterfaceNanostack -ThreadInterface --|> MeshInterfaceNanostack +package "mbed-mesh-api" { + MeshInterfaceNanostack <|-- LoWPANNDInterface + MeshInterfaceNanostack <|-- ThreadInterface + MeshInterfaceNanostack <|-- NanostackEthernetInterface +} -AbstractMesh --|> AbstractNetworkInterface -class AbstractNetworkInterface -@enduml \ No newline at end of file +hide empty members +hide empty attributes +hide empty fields + +@enduml diff --git a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/NanostackRfPhy.png b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/NanostackRfPhy.png index 1c392994a4..9a794b5cbd 100644 Binary files a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/NanostackRfPhy.png and b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/NanostackRfPhy.png differ diff --git a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/mbedOS_sockets.plantumlt.txt b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/mbedOS_sockets.plantumlt.txt new file mode 100644 index 0000000000..26f40b95ef --- /dev/null +++ b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/mbedOS_sockets.plantumlt.txt @@ -0,0 +1,28 @@ +@startuml + +package "mbed OS Socket abstraction" { + interface NetworkStack + NetworkStack -o Socket + abstract class Socket + Socket <|-- UDPSocket + Socket <|-- TCPSocket + Socket <|-- TCPServer +} + +interface NetworkInterface +NetworkInterface --> NetworkStack : get_stack() +EthernetInterface --|> NetworkInterface +CellularInterface --|> NetworkInterface + +package "mbed-mesh-api" { + abstract class MeshInterfaceNanostack <|-- LoWPANNDInterface + MeshInterfaceNanostack <|-- ThreadInterface + MeshInterfaceNanostack --|> NetworkInterface +} + + +hide empty members +hide empty attributes +hide empty fields + +@enduml diff --git a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/mbedOS_sockets.png b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/mbedOS_sockets.png index 2a04be8015..9416663d42 100644 Binary files a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/mbedOS_sockets.png and b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/mbedOS_sockets.png differ diff --git a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/node_to_server.png b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/node_to_server.png index 51af6c6a0e..4a3e4b590c 100644 Binary files a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/node_to_server.png and b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/node_to_server.png differ diff --git a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/docs/thread_APIs.md b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/docs/thread_APIs.md index e4687f4300..e67305d201 100644 --- a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/docs/thread_APIs.md +++ b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/docs/thread_APIs.md @@ -380,14 +380,37 @@ Parameter|Description ### Collecting Thread management information -The function `thread_management_info_get()` is used to collect Thread management related information from the Leader Router. +#### Fetching Thread Management Information + +The function `thread_management_get()` is used to collect Thread management related information from the any device in the Thread network. Parameter|Description -----------|----------- `instance_id`|Instance ID of the management session. -`fields_ptr`|A pointer to management fields from which the information is fetched. -`field_count`|Number of fields in the field pointer array. -`cb_ptr`|A pointer to `management_get_response_cb` callback function. +`dst_addr` |Destination address; the address of a remote device from whome it is desirable to fetch management information. If however, the address is not provided, a request is sent to the leader of the network for this purpose. If a native commissioner is used, the request for management information is sent to the border router. +`uri_ptr` |The ASCII string for the URI. This string identifies the CoAP URI for the desired resource. For example, `/c/mg` identifies the management get information resource. +`fields_ptr`|A pointer to management fields; a set of TLVs. A list of such TLVs can be found in `thread_meshcop_lib.h`. +`field_count`|Number of fields in the field pointer array (set of TLVs). +`cb_ptr`|A pointer to `management_get_response_cb` callback function carrying the result of the operation. + +
+
Response
+
0, success.
+
<0, failure.
+
+ +#### Setting up Thread Management Information + +The function `thread_management_set()` is used to set up Thread management related information to any device in the Thread network. + +Parameter|Description +-----------|----------- +`instance_id`|Instance ID of the management session. +`dst_addr` |Destination address; the address of a remote device where it is desired to set up management information. If however, the address is not provided, a request is sent to the leader of the network for this purpose. If a native commissioner is used, the request for setting up management information is sent to the border router. +`uri_ptr` |The ASCII string for the URI. This string identifies the CoAP URI for the desired resource. For example, `/c/ms` identifies the management set information resource. +`data_ptr`|A pointer to the desired set of TLVs. +`field_count`|Number of fields in the field pointer array (set of TLVs). +`cb_ptr`|A pointer to `management_get_response_cb` callback function carrying the result of the operation.
Response
diff --git a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/ethernet_mac_api.h b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/ethernet_mac_api.h index ef8ee78944..bc5114f17a 100644 --- a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/ethernet_mac_api.h +++ b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/ethernet_mac_api.h @@ -79,21 +79,21 @@ extern int8_t ethernet_mac_destroy(eth_mac_api_t *mac_api); * @param api API to handle the request * @param data Data containing request parameters */ -typedef void data_request(const eth_mac_api_t* api, const eth_data_req_t *data); +typedef void eth_mac_data_request(const eth_mac_api_t* api, const eth_data_req_t *data); /** * @brief data_confirm confirm is called as a response to data_request * @param api The API which handled the request * @param data Data containing confirm parameters */ -typedef void data_confirm(const eth_mac_api_t* api, const eth_data_conf_t *data ); +typedef void eth_mac_data_confirm(const eth_mac_api_t* api, const eth_data_conf_t *data ); /** * @brief data_indication Data indication is called when MAC layer has received data * @param api The API which handled the response * @param data Data containing indication parameters */ -typedef void data_indication(const eth_mac_api_t* api, const eth_data_ind_t *data ); +typedef void eth_mac_data_indication(const eth_mac_api_t* api, const eth_data_ind_t *data ); /** * @brief Set 48 bit address from MAC @@ -119,15 +119,15 @@ typedef int8_t eth_mac_mac48_address_get(const eth_mac_api_t* api, uint8_t *mac4 * @param parent_id Upper layer identifier * @return 0 if success; -1 if api is NULL or not found */ -typedef int8_t eth_mac_api_initialize(eth_mac_api_t *api, data_confirm *conf_cb, - data_indication *ind_cb, uint8_t parent_id); +typedef int8_t eth_mac_api_initialize(eth_mac_api_t *api, eth_mac_data_confirm *conf_cb, + eth_mac_data_indication *ind_cb, uint8_t parent_id); struct eth_mac_api_s { eth_mac_api_initialize *mac_initialize; - data_request *data_req; - data_confirm *data_conf_cb; - data_indication *data_ind_cb; + eth_mac_data_request *data_req; + eth_mac_data_confirm *data_conf_cb; + eth_mac_data_indication *data_ind_cb; eth_mac_mac48_address_set *mac48_set; eth_mac_mac48_address_get *mac48_get; @@ -141,3 +141,4 @@ struct eth_mac_api_s { #endif #endif // ETHERNET_MAC_API_H + diff --git a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/mlme.h b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/mlme.h index 6943dd887f..8433f9d1e8 100644 --- a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/mlme.h +++ b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/mlme.h @@ -249,7 +249,7 @@ typedef enum { macAutoRequestKeyIndex = 0x7b, /*>The index of the key used for automatic data*/ macDefaultKeySource = 0x7c, /*>Default key source*/ //NON standard extension - macLoadBalancingBeaconTxPeriod = 0xfd, /*> Set Beacon periodic Tx interval.Value size uint16_t in seconds, Use 0 to disable */ + macLoadBalancingBeaconTx = 0xfd, /*> Trig Beacon from load balance module periodic */ macLoadBalancingAcceptAnyBeacon = 0xfe, /*>Beacon accept state control from other network. Value size bool, data true=Enable, false=disable .*/ macThreadForceLongAddressForBeacon = 0xff /*>Thread standard force beacon source address for extended 64-bit*/ } mlme_attr_t; diff --git a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_fhss.h b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_fhss.h index 6e05fc585f..1d3e406254 100644 --- a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_fhss.h +++ b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_fhss.h @@ -21,7 +21,7 @@ #ifndef NET_FHSS_H_ #define NET_FHSS_H_ -#include +#include "ns_types.h" #ifndef RPL_SYNCHRONIZATION_INSTANCE_ID #define RPL_SYNCHRONIZATION_INSTANCE_ID 1 @@ -56,6 +56,7 @@ typedef struct int (*fhss_timer_start)(uint32_t, void (*fhss_timer_callback)(int8_t, uint16_t), int8_t); int (*fhss_timer_stop)(void); uint32_t (*fhss_get_remaining_slots)(void); + uint32_t (*fhss_get_timestamp)(void); int (*fhss_time_measure_start)(void); uint32_t (*fhss_time_measure_read)(void); int (*fhss_time_measure_stop)(void); @@ -120,9 +121,10 @@ extern int8_t arm_fhss_disable(int8_t interface_id); extern int8_t arm_fhss_set_tuning_params(int8_t interface_id, const fhss_platform_tuning_params_s *fhss_tuning_params); #else -#define arm_fhss_enable(interface_id, fhss_platform_functions,fhss_configuration) (int8_t) -1 -#define arm_fhss_disable(interface_id) (int8_t) -1 -#define arm_fhss_set_tuning_params(interface_id, fhss_tuning_params) (int8_t) -1 +NS_DUMMY_DEFINITIONS_OK +#define arm_fhss_enable(interface_id, fhss_platform_functions,fhss_configuration) (-1) +#define arm_fhss_disable(interface_id) (-1) +#define arm_fhss_set_tuning_params(interface_id, fhss_tuning_params) (-1) #endif #endif /* NET_FHSS_H_ */ diff --git a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_interface.h b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_interface.h index cc2d769cb6..3a8b3eb19a 100644 --- a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_interface.h +++ b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_interface.h @@ -81,16 +81,16 @@ typedef enum arm_library_event_type_e { /** Data received. */ #define SOCKET_DATA (0 << 4) /** TCP connection ready. */ -#define SOCKET_BIND_DONE (1 << 4) +#define SOCKET_CONNECT_DONE (1 << 4) /** TCP connection failure. */ -#define SOCKET_BIND_FAIL (2 << 4) +#define SOCKET_CONNECT_FAIL (2 << 4) /** TCP connection authentication failed. */ -#define SOCKET_BIND_AUTH_FAIL (3 << 4) -/** TCP incoming connection attempt to listening socket */ +#define SOCKET_CONNECT_AUTH_FAIL (3 << 4) +/** TCP incoming connection on listening socket */ #define SOCKET_INCOMING_CONNECTION (4 << 4) /** Socket data send failure. */ #define SOCKET_TX_FAIL (5 << 4) -/** TCP connection closed. */ +/** TCP connection closed (received their FIN and ACK of our FIN). */ #define SOCKET_CONNECT_CLOSED (6 << 4) /** TCP connection reset */ #define SOCKET_CONNECTION_RESET (7 << 4) @@ -100,6 +100,13 @@ typedef enum arm_library_event_type_e { #define SOCKET_TX_DONE (9 << 4) /** Out of memory failure. */ #define SOCKET_NO_RAM (10 << 4) +/** TCP connection problem indication (RFC 1122 R1) */ +#define SOCKET_CONNECTION_PROBLEM (11 << 4) + +/* Backwards compatibility */ +#define SOCKET_BIND_DONE SOCKET_CONNECT_DONE +#define SOCKET_BIND_FAIL SOCKET_CONNECT_FAIL +#define SOCKET_BIND_AUTH_FAIL SOCKET_CONNECT_AUTH_FAIL /*! * \enum net_security_t @@ -992,6 +999,23 @@ void arm_print_neigh_cache(void); */ void arm_print_neigh_cache2(void (*print_fn)(const char *fmt, ...)); +/** + * \brief Print PCB list + * + * Prints Protocol Control Block list to the command line + */ +void arm_print_protocols(void); + +/** + * \brief Print PCB list + * + * Prints Protocol Control Block list using the given printf style function + * + * \param print_fn pointer to a printf style output function + * \param sep column separator character + */ +void arm_print_protocols2(void (*print_fn)(const char *fmt, ...), char sep); + /** * \brief Get the library version information. * diff --git a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_load_balance_api.h b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_load_balance_api.h new file mode 100644 index 0000000000..274fd8c37f --- /dev/null +++ b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_load_balance_api.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2016 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: LicenseRef-PBL + * + * Licensed under the Permissive Binary License, Version 1.0 (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.mbed.com/licenses/PBL-1.0 + * + * See the License for the specific language governing permissions and limitations under the License. + * + */ + +/** + * \file net_load_balance_api.h + * \brief 6Lowpan network load balance control API. + */ + +#ifndef NET_LOAD_BALANCE_API_H_ +#define NET_LOAD_BALANCE_API_H_ + +#include "ns_types.h" + +/** + * \brief load_balance_network_switch_notify this function will be called by load balance when it have detected better network to switch + * \param interface id + * + * \return true Network switching can be performed immediately + * \return false means that load balance will ask at a later time for network switching, if a better network is still available at that time + */ +typedef bool net_load_balance_network_switch_notify(int8_t interface_id); + +/** + * \brief Set user callback for accept network switch. + * \param network_switch_notify user callback + */ +void net_load_balance_network_switch_cb_set(net_load_balance_network_switch_notify *network_switch_notify); + +/** + * \brief Create and enable load balance to selected interface. + * \param interface_id interface id + * \param enable_periodic_beacon_interval Set True when want activate load balance periodic beacon, false will work only properly with fhss system + * + * \return 0 Enable ok + * \return -1 unknown Interface or parameter error + * \return -2 Out of memory + * \return -3 Load balance already configured to this interface + */ +int8_t net_load_balance_create(int8_t interface_id, bool enable_periodic_beacon_interval); + +/** + * \brief Disable and delete load balansing from interface + * \param interface_id interface id + * + * \return 0 Process ok + * \return -1 unknown Interface + */ +int8_t net_load_balance_delete(int8_t interface_id); + +/** + * \brief Set Load balance threshold min and max + * + * Nework switch will work next diff_priority >= randLIB_get_random_in_range(threshold_min, threshold_max) --> switch network if true + * For border router Disable Network compare set threshold_min and threshold_max to 0. + * \param threshold_min min value define random minimal value for compare + * \param threshold_max max value for define random max value for compare + * + * \return 0 process ok -1 Unknown interface id + */ +int8_t net_load_balance_threshold_set(int8_t interface_id, uint8_t threshold_min, uint8_t threshold_max); + +/** + * \brief Set Load balance expected device count and enable automatic network load level update + * + * This feature is just for RPL DoDAG root device! + * + * \param interface_id interface id + * \param expected_device_count Device count which will set max load level. If count is not expected_device_count % 8 it not zero function update number up to reach that.It is not hard limit it define max DoDAG preference + * + * \return 0 process ok -1 Unknown interface id -2 Out of memory + */ +int8_t net_load_balance_load_level_update_enable(int8_t interface_id, uint16_t expected_device_count); + +/** + * \brief Disable automatic network load level update + * + * \param interface_id interface id + * + * \return 0 process ok -1 Unknown interface id + */ +int8_t net_load_balance_load_level_update_disable(int8_t interface_id); + +/** + * \brief Set network probability percent when new network is better than threshold max + * + * \param interface_id interface id + * \param max_p is percent probability to switch network. Default is 40%. Accepted values are [1,100] recommend values are 15-50. + * + * \return 0 process ok -1 Unknown interface id or parameter fail + */ +int8_t net_load_balance_set_max_probability(int8_t interface_id , uint8_t max_p); + + +#endif /* NET_LOAD_BALANCE_API_H_ */ diff --git a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_test_api.h b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_test_api.h new file mode 100644 index 0000000000..b0c0375bc3 --- /dev/null +++ b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_test_api.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: LicenseRef-PBL + * + * Licensed under the Permissive Binary License, Version 1.0 (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.mbed.com/licenses/PBL-1.0 + * + * See the License for the specific language governing permissions and limitations under the License. + * + */ + +/** + * \file net_ipv6_api.h + * \brief IPv6 configuration API. + */ + +#ifndef NET_TEST_API_H_ +#define NET_TEST_API_H_ + +#include "ns_types.h" + +/** + * \brief Makes TCP protocol drop given number of packets from a particular state (TX side, tcp_down()). + * + * Testing API for TCP retransmission mechanism after a packet is dropped in a particular state. + * + * \param state Particular TCP state - Identified by its number from 1-11. Numbering is from the SNMP MIB - RFC 4022. + * \param count No. of packets to be dropped + * \return 0 OK + * \return <0 If request can't be fulfilled, i.e., Not test environment. + */ +int8_t arm_nwk_test_tcp_drop_tx(int state, uint8_t count); + +/** + * \brief Makes TCP protocol drop given number of packets from a particular state (RX side, tcp_up()). + * + * Testing API for TCP to drop received packets. + * + * \param state Particular TCP state - Identified by its number from 1-11. Numbering is from the SNMP MIB - RFC 4022. + * \param count No. of packets to be dropped + * \return 0 OK + * \return <0 If request can't be fulfilled, i.e., Not test environment. + */ +int8_t arm_nwk_test_tcp_drop_rx(int state, uint8_t count); + +/** + * \brief Resets drop counters. + * + * Testing API for TCP reset any packet drop counters. + */ +void arm_nwk_test_tcp_drop_reset(void); + +#endif //NET_TEST_API_H_ diff --git a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_thread_test.h b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_thread_test.h index 910793463c..a49cafb655 100644 --- a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_thread_test.h +++ b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_thread_test.h @@ -220,6 +220,16 @@ int thread_test_version_set(int8_t interface_id, uint8_t version); */ int thread_test_router_selection_jitter_set(int8_t interface_id, uint32_t jitter); +/** + * \brief Sets the thread MIN_DELAY_TIMER default value. + * + * \param interface_id Network Interface + * \param delay_timer_value delay timer value in seconds used in leader + * + * \return 0, OK + * \return <0 Error + */ +int thread_test_min_delay_timer_set(int8_t interface_id, uint32_t delay_timer_value); /** * \brief Increment Thread key sequence counter * diff --git a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/ns_address.h b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/ns_address.h index 5ddc9b285e..5ab483fb6c 100644 --- a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/ns_address.h +++ b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/ns_address.h @@ -37,7 +37,7 @@ typedef enum address_type_t { */ typedef struct ns_address { address_type_t type; /**< Address type. */ - uint8_t address[16]; /**< Addresss. */ + uint8_t address[16]; /**< Address. */ uint16_t identifier; /**< TCP/UDP port number. */ } ns_address_t; diff --git a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/platform/arm_hal_phy.h b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/platform/arm_hal_phy.h index 788f5cc158..34432a5ba4 100644 --- a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/platform/arm_hal_phy.h +++ b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/platform/arm_hal_phy.h @@ -52,6 +52,7 @@ typedef enum { PHY_EXTENSION_READ_CHANNEL_ENERGY, /**< RF interface ED scan energy read. */ PHY_EXTENSION_READ_LINK_STATUS, /**< Net library could read link status. */ PHY_EXTENSION_CONVERT_SIGNAL_INFO, /**< Convert signal info. */ + PHY_EXTENSION_ACCEPT_ANY_BEACON, /**< Set boolean true or false for accept beacon from other Pan-ID than configured. Default value should be false */ } phy_extension_type_e; /** Address types */ diff --git a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/socket_api.h b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/socket_api.h index e11fc6119d..8023d52a6b 100644 --- a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/socket_api.h +++ b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/socket_api.h @@ -24,20 +24,23 @@ extern "C" { * \section socket-com Common socket API * - socket_open(), A function to open a socket. * - socket_close(), A function to close a socket. + * - socket_connect(), A function to connect to a remote peer. + * - socket_bind(), A function to bind a local address or port or both. + * - socket_getpeername(), A function to get remote address and port of a connected socket. + * - socket_getsockname(), A function to get local address and port of a bound socket. * * \section socket-read Socket read API at callback * - socket_read(), A function to read received data buffer from a socket. * - socket_recvmsg(), A function to read received data buffer from a socket to Posix defined message structure - * - socket_read_session_address(), A function to read session info for a TCP event. * * \section socket-tx Socket TX API * - socket_send(), A function to write data buffer to a socket. * - socket_sendto(), A function to write data to a specific destination in the socket. - * - socket_senmsg(), A function which support socket_send and socket_sendto functionality which supports ancillary data + * - socket_sendmsg(), A function which support socket_send and socket_sendto functionality which supports ancillary data * * \section sock-connect TCP socket connection handle * - socket_listen(), A function to set the socket to listening mode. - * - socket_connect(), A function to connect to a remote peer. + * - socket_accept(), A function to accept an incoming connection. * - socket_shutdown(), A function to shut down a connection. * * Sockets are a common abstraction model for network communication and are used in most operating systems. @@ -98,13 +101,17 @@ extern "C" { * | :------------------------: | :---: | :-----------------------------------------------------------------: | * | SOCKET_EVENT_MASK | 0xF0 | NC Socket event mask. | * | SOCKET_DATA | 0x00 | Data received, read data length available in d_len field. | - * | SOCKET_BIND_DONE | 0x10 | TCP connection ready. | + * | SOCKET_CONNECT_DONE | 0x10 | TCP connection ready. | + * | SOCKET_CONNECT_FAIL | 0x20 | TCP connection failed. | + * | SOCKET_INCOMING_CONNECTION | 0x40 | TCP incoming connection on listening socket. | * | SOCKET_TX_FAIL | 0x50 | Socket data send failed. | * | SOCKET_CONNECT_CLOSED | 0x60 | TCP connection closed. | * | SOCKET_CONNECTION_RESET | 0x70 | TCP connection reset. | * | SOCKET_NO_ROUTER | 0x80 | No route available to destination. | - * | SOCKET_TX_DONE | 0x90 | Last socket TX process done, in TCP, whole TCP process is ready. | + * | SOCKET_TX_DONE | 0x90 | UDP: link layer TX ready (d_len = length of datagram). | + * | | | TCP: some data acknowledged (d_len = data remaining in send queue) | * | SOCKET_NO_RAM | 0xA0 | No RAM available. | + * | SOCKET_CONNECTION_PROBLEM | 0xB0 | TCP connection is retrying. | * * * \section socket-tcp How to use TCP sockets: @@ -112,28 +119,26 @@ extern "C" { * | API | Socket Type | Description | * | :---------------------------: | :-----------: | :------------------------------------------------------------: | * | socket_open() | Server/Client | Open socket to specific or dynamic port number. | - * | socket_shutdown() | Client | Shut down opened TCP connection. | + * | socket_shutdown() | Server/Client | Shut down opened TCP connection. | * | socket_listen() | Server | Set server port to listen state. | + * | socket_accept() | Server | Accept a connection to a listening socket as a new socket. | * | socket_connect() | Client | Connect client socket to specific destination. | - * | socket_close() | Server/Client | Closes the TCP Socket. | - * | socket_send() | Client | Send data to session based destination. | - * | socket_sendto() | Server/Client | Send data to specific destination. | - * | socket_read_session_address() | Server/Client | Read socket TCP session address and port information. | + * | socket_close() | Server/Client | Closes the TCP Socket. | + * | socket_send() | Server/Client | Send data to peer. | + * | socket_recv() | Server/Client | Receive data from peer. | * * When the TCP socket is opened it is in closed state. It must be set either to listen or to connect state before it can be used to receive or transmit data. * * A socket can be set to listen mode with the socket_listen() function. After the call, the socket can accept an incoming connection from a remote host. - * The listen mode closes the connection automatically after server timeout or when the client or application closes the connection manually by socket_shutdown() function. * * A TCP socket can be connected to a remote host with socket_connect() with correct arguments. After the function call, a (non-blocking) application must wait for the socket event to confirm the successful state change of the socket. - * After the successful state change, data can be sent using socket_send() by client and socket_send() by server. - * The connection can be shut down with socket_shutdown() function or by server timeout. + * After the successful state change, data can be sent using socket_send(). + * The connection can be shut down in either direction with socket_shutdown() function - shutting down write signals end-of-data to the peer. * * \section socket-udpicmp How to use UDP and RAW socket: * * A UDP socket is ready to receive and send data immediately after a successful call of socket_open() and a NET_READY event is received. * Data can be transmitted with the socket_sendto() function. An ICMP socket works with same function call. - * */ #include "ns_address.h" @@ -199,7 +204,7 @@ typedef struct ns_msghdr { uint_fast16_t msg_iovlen; /**< Data vector count in msg_iov */ void *msg_control; /**< Ancillary data list of ns_cmsghdr_t pointer */ uint_fast16_t msg_controllen; /**< Ancillary data length */ - int flags; /**< Flags for received messages */ + int msg_flags; /**< Flags for received messages */ } ns_msghdr_t; /*! @@ -212,8 +217,15 @@ typedef struct ns_cmsghdr { uint8_t cmsg_type; /**< Protocol Specific types for example SOCKET_IPV6_PKTINFO, */ } ns_cmsghdr_t; +/** \name Error values + * \anchor ERROR_CODES + */ +///@{ +/** No data currently available to read, or insufficient queue space for write */ +#define NS_EWOULDBLOCK (-100) +///@} -/** \name socket_recvmsg() message error flags. +/** \name socket_recvfrom() or socket_recvmsg() flags. * \anchor MSG_HEADER_FLAGS */ ///@{ @@ -221,6 +233,10 @@ typedef struct ns_cmsghdr { #define NS_MSG_TRUNC 1 /** Indicates that given ancillary data buffer was smaller than enabled at socket msg->msg_controllen define proper writed data lengths. */ #define NS_MSG_CTRUNC 2 +/** Can be passed as an input flag to socket_recvfrom() to not consume data */ +#define NS_MSG_PEEK 4 +/** \deprecated Can be passed as an input flag to get legacy returns of zero - used by socket_read() and socket_sendto() */ +#define NS_MSG_LEGACY0 0x4000 ///@} /*! * \struct ns_in6_pktinfo_t @@ -231,15 +247,22 @@ typedef struct ns_in6_pktinfo { int8_t ipi6_ifindex; /**< send/recv interface index */ } ns_in6_pktinfo_t; + +/** \privatesection Alignment macros for control message headers +* \anchor CMSG_ALIGN_FLAGS +*/ +///@{ +/** Base header alignment size */ #define CMSG_HEADER_ALIGN sizeof(long) - +/** Base data alignment size */ #define CMSG_DATA_ALIGN CMSG_HEADER_ALIGN - +/** Returns control message alignment size for data or header based upon alignment base */ #ifndef NS_ALIGN_SIZE #define NS_ALIGN_SIZE(length, aligment_base) \ ((length + (aligment_base -1 )) & ~(aligment_base -1)) #endif - +///@} +/// \publicsection /** * \brief Parse first control message header from message ancillary data. * @@ -327,7 +350,7 @@ int8_t socket_close(int8_t socket); * \brief A function to set a socket to listening mode. * * \param socket The socket ID. - * \param backlog The pending connections queue size. (Not yet implemented). + * \param backlog The pending connections queue size. * \return 0 on success. * \return -1 on failure. */ @@ -336,13 +359,12 @@ int8_t socket_listen(int8_t socket, uint8_t backlog); /** * \brief A function to accept a new connection on an socket. * - * NOT YET IMPLEMENTED - PLACEHOLDER FOR FUTURE TCP CHANGES - * * \param socket_id The socket ID of the listening socket. * \param addr Either NULL pointer or pointer to structure where the remote address of the connecting host is copied. * \param passed_fptr A function pointer to a function that is called whenever a data frame is received to the new socket. * \return 0 or greater on success; return value is the new socket ID. * \return -1 on failure. + * \return NS_EWOULDBLOCK if no pending connections. */ int8_t socket_accept(int8_t socket_id, ns_address_t *addr, void (*passed_fptr)(void *)); @@ -367,11 +389,14 @@ int8_t socket_connect(int8_t socket, ns_address_t *address, uint8_t randomly_tak /** * \brief Bind socket to address. * - * Used by the application to bind a socket to a port and/or an address. Binding can - * be done only once. The port or address cannot be changed after binding. + * Used by the application to bind a socket to a port and/or an address. Binding of each + * of address and port can only be done once. + * + * If address is ns_in6addr_any, the address binding is not changed. If port is 0, + * the port binding is not changed. * * \param socket Socket ID of the socket to bind. - * \param address Address structure containing the port and address to bind. + * \param address Address structure containing the port and/or address to bind. * * \return 0 on success. * \return -1 if the given address is NULL. @@ -386,6 +411,7 @@ int8_t socket_bind(int8_t socket, const ns_address_t *address); /** * \brief Bind a local address to a socket based on the destination address and * the address selection preferences. + * * Binding happens to the same address that socket_connect() would bind to. * Reference: RFC5014 IPv6 Socket API for Source Address Selection. * @@ -417,70 +443,119 @@ int8_t socket_bind2addrsel(int8_t socket, const ns_address_t *dst_address); * * \return 0 on success. * \return -1 if the given socket ID is not found, if the socket type is wrong or TCP layer returns a failure. - * \return -2 if no active TCP session was found. + * \return -2 if socket is not connected. */ int8_t socket_shutdown(int8_t socket, uint8_t how); /** - * \brief Send data via a connected TCP socket by client. + * \brief Send data via a connected socket by client. * * Note: The socket connection must be ready before using this function. * The stack uses automatically the address of the remote connected host as the destination address for the packet. * + * This call is equivalent to socket_sendto() with address set to NULL - see + * that call for more details. + * * \param socket The socket ID. * \param buffer A pointer to data. * \param length Data length. - * - * \return 0 done - * \return -1 Invalid socket ID. - * \return -2 Socket memory allocation fail. - * \return -3 TCP state not established or address scope not defined . - * \return -4 Socket TX process busy or unknown interface. - * \return -5 Socket not connected - * \return -6 Packet too short (ICMP raw socket error). */ -int8_t socket_send(int8_t socket, uint8_t *buffer, uint16_t length); +int16_t socket_send(int8_t socket, const void *buffer, uint16_t length); /** * \brief A function to read received data buffer from a socket. + * \deprecated * - * Used by the application to get data from a socket. This method must be called once - * from a socket callback when handling event SOCKET_DATA. If the received data does not fit - * in the buffer provided the excess data bytes are discarded. + * Used by the application to get data from a socket. See socket_recvfrom() + * for more details. + * + * This is equivalent to socket_recvfrom, except that it passes the + * flag NS_MSG_LEGACY0, which modifies the return behaviour for zero data. * * \param socket The socket ID. * \param src_addr A pointer to a structure where the sender's address is stored. + * May be NULL if not required. * \param buffer A pointer to an array where the read data is written to. * \param length The maximum length of the allocated buffer. * - * \return greater than 0 indicates the length of the data copied to buffer. - * \return 0 if no data is available to read. + * \return >0 indicates the length of the data copied to buffer. + * \return 0 if no data was read (includes zero-length datagram, + * end of stream and no data currently available) * \return -1 invalid input parameters. */ int16_t socket_read(int8_t socket, ns_address_t *src_addr, uint8_t *buffer, uint16_t length); /** - * \brief A function to read received message with ancillary data from a socket. + * \brief A function to read received data buffer from a socket, * - * Used by the application to get data from a socket. This method must be called once - * from a socket callback when handling event SOCKET_DATA. If the received data does not fit - * in the buffer provided the excess data bytes are discarded. + * Equivalent to socket_recvfrom with src_address set to NULL. * - * Ancillary data must request by socket_setsockopt(). + * \param socket The socket ID. + * \param buffer A pointer to an array where the read data is written to. + * \param length The maximum length of the allocated buffer. + * \param flags Flags for read call * - * msg->msg_controllen is updated to indicate actual length of ancillary data output + * \return as for socket_recvfrom + */ +int16_t socket_recv(int8_t socket, void *buffer, uint16_t length, int flags); + +/** + * \brief A function to read received data buffer from a socket + * + * Used by the application to get data from a socket. + * + * This has two modes of operation. + * + * 1) For non-stream sockets, if the receive queue is disabled (set to 0 via + * SOCKET_SO_RCVBUF), which is the non-stream default and original Nanostack + * behaviour, then applications receive exactly one SOCKET_DATA callback per + * datagram, indicating that datagram's length. They must make 1 read call + * in that callback, and they will be given the data. If not read, the + * datagram is discarded on return from the callback. + * + * 2) Otherwise - stream sockets or SOCKET_SO_RCVBUF non-zero - behaviour is + * akin to traditional BSD. SOCKET_DATA callbacks occur when new data arrives, + * and read calls can be made any time. Data will be queued to an extent + * determined by the receive buffer size. The length in the data callback + * is the total amount of data in the receive queue - possibly multiple + * datagrams. + * + * \param socket The socket ID. + * \param buffer A pointer to an array where the read data is written to. + * \param length The maximum length of the allocated buffer. + * \param flags Flags for read call + * \param src_addr A pointer to a structure where the sender's address is stored. + * May be NULL if not required. * * The returned length is normally the length of data actually written to the buffer; if * NS_MSG_TRUNC is set in flags, then for non-stream sockets, the actual datagram length is * returned instead, which may be larger than the buffer size. * + * Return values assume flag NS_MSG_LEGACY0 is not set - if it is set, they are + * as per socket_read(). + * + * \return >0 indicates the length of the data copied to buffer (or original datagram size) + * \return 0 if end of stream or zero-length datagram + * \return -1 invalid input parameters. + * \return NS_EWOULDBLOCK if no data is currently available + */ +int16_t socket_recvfrom(int8_t socket, void *buffer, uint16_t length, int flags, ns_address_t *src_addr); + +/** + * \brief A function to read received message with ancillary data from a socket. + * + * Used by the application to get data from a socket. See socket_recvfrom for + * details of the two delivery mechanisms. + * + * Ancillary data must request by socket_setsockopt(). + * + * msg->msg_controllen is updated to indicate actual length of ancillary data output + * * \param socket The socket ID. * \param msg A pointer to a structure where messages is stored with or without ancillary data * \param flags A flags for message read. * - * \return greater than 0 indicates the length of the data. - * \return 0 if no data is available to read. - * \return -1 invalid input parameters. + * \return as for socket_recvfrom */ int16_t socket_recvmsg(int8_t socket, ns_msghdr_t *msg, int flags); @@ -489,20 +564,28 @@ int16_t socket_recvmsg(int8_t socket, ns_msghdr_t *msg, int flags); * * Used by the application to send data. * + * The return of 0 on success is unconventional, and obtained by passing + * NS_MSG_LEGACY0 to socket_sendmsg internally - to get conventional + * return values, you can use socket_sendmsg() instead. + * * \param socket The socket ID. * \param address A pointer to the destination address information. * \param buffer A pointer to data to be sent. * \param length Length of the data to be sent. * - * \return 0 on success. + * \return 0 On success (whole packet queued) + * \return NS_EWOULDBLOCK if nothing written due to lack of queue space. + * + * Error returns: + * * \return -1 Invalid socket ID. * \return -2 Socket memory allocation fail. * \return -3 TCP state not established or address scope not defined . - * \return -4 Socket TX process busy or unknown interface. + * \return -4 Unknown interface. * \return -5 Socket not connected * \return -6 Packet too short (ICMP raw socket error). */ -int8_t socket_sendto(int8_t socket, ns_address_t *address, uint8_t *buffer, uint16_t length); +int16_t socket_sendto(int8_t socket, const ns_address_t *address, const void *buffer, uint16_t length); /** * \brief A function to send UDP, TCP or raw ICMP data via the socket with or without ancillary data or destination address. @@ -511,7 +594,7 @@ int8_t socket_sendto(int8_t socket, ns_address_t *address, uint8_t *buffer, uint * * \param socket The socket ID. * \param msg A pointer to the Message header which include address, payload and ancillary data. - * \param flags A flags for message send for future usage (not supported yet) + * \param flags A flags for message send (eg NS_MSG_LEGACY0) * * Messages destination address is defined by msg->msg_name which must be ns_address_t. If msg->msg_nme is NULL socket select connected address * @@ -519,34 +602,56 @@ int8_t socket_sendto(int8_t socket, ns_address_t *address, uint8_t *buffer, uint * * Supported ancillary data for send defined by msg->msg_control and msg->msg_controllen. * - * msg->flags and flags is ignored + * msg->msg_flags is unused, and need not be initialised. * - * \return 0 on success. - * \return -1 Invalid socket ID or message structure. + * The following main return values assume flag NS_MSG_LEGACY0 is not set - + * if it is set, they are as per socket_sendto(). + * + * \return length if entire amount written (which could be 0) + * \return value >0 and 0. Can be NULL which only searches for the length. + * \ [OUT] Pointer to previous TLV found + * + * \return The length of the TLV data found and found_tlv updated to point beginning of value field. 0 if TLV is not found. + */ +uint16_t thread_meshcop_tlv_find_next(uint8_t* tlv_ba, uint16_t tlv_ba_length, uint8_t tlv_id, uint8_t** found_tlv); + /** * Read 1 byte length TLV. * diff --git a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/whiteboard_api.h b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/whiteboard_api.h index caab82f9f1..bb8c4e3a81 100644 --- a/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/whiteboard_api.h +++ b/features/nanostack/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/whiteboard_api.h @@ -43,6 +43,15 @@ typedef struct whiteboard_entry_t { * \return A pointer to whiteboard_entry_t structure. */ extern whiteboard_entry_t *whiteboard_get(whiteboard_entry_t *cur); + +/** + * @brief Whiteboard_set_device_hard_limit Sets the absolut limit of child devices this device can handle. + * This is very useful in situations, where 1 GW drops from network and causes it's children + * to join other GW networks. This might cause other GWs to run out of memory. + * @param limit Absolute maximum amount of devices allowed to join. Default value=0 means unlimited (as long as there is memory) + */ +extern void whiteboard_set_device_hard_limit(uint16_t limit); + #ifdef __cplusplus } #endif diff --git a/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_nanostack_full.ar b/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_nanostack_full.ar old mode 100755 new mode 100644 index 9510d96fe7..3d755949a7 Binary files a/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_nanostack_full.ar and b/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_nanostack_full.ar differ diff --git a/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_nanostack_full.ar b/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_nanostack_full.ar old mode 100755 new mode 100644 index 9cf32606c3..4516ff0665 Binary files a/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_nanostack_full.ar and b/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_nanostack_full.ar differ diff --git a/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_nanostack_full.ar b/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_nanostack_full.ar old mode 100755 new mode 100644 index 9cf32606c3..4516ff0665 Binary files a/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_nanostack_full.ar and b/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_nanostack_full.ar differ diff --git a/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_nanostack_full.a b/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_nanostack_full.a old mode 100755 new mode 100644 index 3e185429bf..09558f8036 Binary files a/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_nanostack_full.a and b/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_nanostack_full.a differ diff --git a/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_nanostack_full.a b/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_nanostack_full.a old mode 100755 new mode 100644 index 17fcef0a0a..c8f4433fa2 Binary files a/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_nanostack_full.a and b/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_nanostack_full.a differ diff --git a/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_nanostack_full.a b/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_nanostack_full.a old mode 100755 new mode 100644 index 17fcef0a0a..c8f4433fa2 Binary files a/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_nanostack_full.a and b/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_nanostack_full.a differ diff --git a/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_nanostack_full.a b/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_nanostack_full.a old mode 100755 new mode 100644 index 37ba392dd8..75857b38bd Binary files a/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_nanostack_full.a and b/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_nanostack_full.a differ diff --git a/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_nanostack_full.a b/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_nanostack_full.a old mode 100755 new mode 100644 index 3f148da850..673c42beb8 Binary files a/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_nanostack_full.a and b/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_nanostack_full.a differ diff --git a/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_nanostack_full.a b/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_nanostack_full.a old mode 100755 new mode 100644 index 3f148da850..673c42beb8 Binary files a/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_nanostack_full.a and b/features/nanostack/FEATURE_NANOSTACK_FULL/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_nanostack_full.a differ diff --git a/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_thread_border_router.ar b/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_thread_border_router.ar old mode 100755 new mode 100644 index 518f9f44ba..f84486c908 Binary files a/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_thread_border_router.ar and b/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_thread_border_router.ar differ diff --git a/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_thread_border_router.ar b/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_thread_border_router.ar old mode 100755 new mode 100644 index 10d9f78524..bbe5d82858 Binary files a/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_thread_border_router.ar and b/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_thread_border_router.ar differ diff --git a/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_thread_border_router.ar b/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_thread_border_router.ar old mode 100755 new mode 100644 index 10d9f78524..bbe5d82858 Binary files a/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_thread_border_router.ar and b/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_thread_border_router.ar differ diff --git a/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_thread_border_router.a b/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_thread_border_router.a old mode 100755 new mode 100644 index 60fdef2f26..9068bf10f8 Binary files a/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_thread_border_router.a and b/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_thread_border_router.a differ diff --git a/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_border_router.a b/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_border_router.a old mode 100755 new mode 100644 index a1fbd2ac05..537c417a17 Binary files a/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_border_router.a and b/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_border_router.a differ diff --git a/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_border_router.a b/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_border_router.a old mode 100755 new mode 100644 index a1fbd2ac05..537c417a17 Binary files a/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_border_router.a and b/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_border_router.a differ diff --git a/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_thread_border_router.a b/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_thread_border_router.a old mode 100755 new mode 100644 index 47f897b513..a75c831fbe Binary files a/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_thread_border_router.a and b/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_thread_border_router.a differ diff --git a/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_thread_border_router.a b/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_thread_border_router.a old mode 100755 new mode 100644 index bf5bdb8057..4b9a76b3df Binary files a/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_thread_border_router.a and b/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_thread_border_router.a differ diff --git a/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_thread_border_router.a b/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_thread_border_router.a old mode 100755 new mode 100644 index bf5bdb8057..4b9a76b3df Binary files a/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_thread_border_router.a and b/features/nanostack/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_thread_border_router.a differ diff --git a/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_thread_end_device.ar b/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_thread_end_device.ar old mode 100755 new mode 100644 index b57626a5e3..8a3d6f2528 Binary files a/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_thread_end_device.ar and b/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_thread_end_device.ar differ diff --git a/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_thread_end_device.ar b/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_thread_end_device.ar old mode 100755 new mode 100644 index 016136c943..97240916d2 Binary files a/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_thread_end_device.ar and b/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_thread_end_device.ar differ diff --git a/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_thread_end_device.ar b/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_thread_end_device.ar old mode 100755 new mode 100644 index 016136c943..97240916d2 Binary files a/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_thread_end_device.ar and b/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_thread_end_device.ar differ diff --git a/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_thread_end_device.a b/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_thread_end_device.a old mode 100755 new mode 100644 index ec8f46ef69..45cb0bafa5 Binary files a/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_thread_end_device.a and b/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_thread_end_device.a differ diff --git a/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_end_device.a b/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_end_device.a old mode 100755 new mode 100644 index 42a372f0b0..ca865e567b Binary files a/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_end_device.a and b/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_end_device.a differ diff --git a/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_end_device.a b/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_end_device.a old mode 100755 new mode 100644 index 42a372f0b0..ca865e567b Binary files a/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_end_device.a and b/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_end_device.a differ diff --git a/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_thread_end_device.a b/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_thread_end_device.a old mode 100755 new mode 100644 index 8b7f198812..aec8686a0a Binary files a/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_thread_end_device.a and b/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_thread_end_device.a differ diff --git a/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_thread_end_device.a b/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_thread_end_device.a old mode 100755 new mode 100644 index 389c65e02b..27e6e6bef4 Binary files a/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_thread_end_device.a and b/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_thread_end_device.a differ diff --git a/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_thread_end_device.a b/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_thread_end_device.a old mode 100755 new mode 100644 index 389c65e02b..27e6e6bef4 Binary files a/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_thread_end_device.a and b/features/nanostack/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_thread_end_device.a differ diff --git a/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_thread_router.ar b/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_thread_router.ar old mode 100755 new mode 100644 index d42d222639..adacf26040 Binary files a/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_thread_router.ar and b/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_thread_router.ar differ diff --git a/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_thread_router.ar b/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_thread_router.ar old mode 100755 new mode 100644 index 1f2ad36bc4..9f7e72cfd1 Binary files a/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_thread_router.ar and b/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_ARM/TARGET_M3/libnanostack_armcc_Cortex-M3_thread_router.ar differ diff --git a/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_thread_router.ar b/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_thread_router.ar old mode 100755 new mode 100644 index 1f2ad36bc4..9f7e72cfd1 Binary files a/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_thread_router.ar and b/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_thread_router.ar differ diff --git a/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_thread_router.a b/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_thread_router.a old mode 100755 new mode 100644 index 84b6dfccd1..a4356eaf82 Binary files a/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_thread_router.a and b/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_thread_router.a differ diff --git a/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_router.a b/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_router.a old mode 100755 new mode 100644 index 4ad1ad96b3..8c92b6b8c4 Binary files a/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_router.a and b/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_GCC/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_router.a differ diff --git a/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_router.a b/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_router.a old mode 100755 new mode 100644 index 4ad1ad96b3..8c92b6b8c4 Binary files a/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_router.a and b/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_router.a differ diff --git a/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_thread_router.a b/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_thread_router.a old mode 100755 new mode 100644 index 05f0c0e5cc..5b0a43972f Binary files a/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_thread_router.a and b/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_thread_router.a differ diff --git a/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_thread_router.a b/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_thread_router.a old mode 100755 new mode 100644 index 887ada3579..abe04acd4e Binary files a/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_thread_router.a and b/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_IAR/TARGET_M3/libnanostack_iccarm_Cortex-M3_thread_router.a differ diff --git a/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_thread_router.a b/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_thread_router.a old mode 100755 new mode 100644 index 887ada3579..abe04acd4e Binary files a/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_thread_router.a and b/features/nanostack/FEATURE_THREAD_ROUTER/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_thread_router.a differ diff --git a/features/netsocket/Socket.cpp b/features/netsocket/Socket.cpp index e96f8a2924..fd50083bc7 100644 --- a/features/netsocket/Socket.cpp +++ b/features/netsocket/Socket.cpp @@ -42,7 +42,7 @@ nsapi_error_t Socket::open(NetworkStack *stack) } _socket = socket; - _event.attach(this, &Socket::event); + _event = callback(this, &Socket::event); _stack->socket_attach(_socket, Callback::thunk, &_event); _lock.unlock(); @@ -149,11 +149,14 @@ nsapi_error_t Socket::getsockopt(int level, int optname, void *optval, unsigned } -void Socket::attach(Callback callback) +void Socket::sigio(Callback callback) { _lock.lock(); - _callback = callback; - _lock.unlock(); } + +void Socket::attach(Callback callback) +{ + sigio(callback); +} diff --git a/features/netsocket/Socket.h b/features/netsocket/Socket.h index 00716611a7..3482349f94 100644 --- a/features/netsocket/Socket.h +++ b/features/netsocket/Socket.h @@ -163,22 +163,30 @@ public: * The callback may be called in an interrupt context and should not * perform expensive operations such as recv/send calls. * + * Note! This is not intended as a replacement for a poll or attach-like + * asynchronous api, but rather as a building block for constructing + * such functionality. The exact timing of when the registered function + * is called is not guaranteed and susceptible to change. + * * @param func Function to call on state change */ + void sigio(mbed::Callback func); + + /** Register a callback on state change of the socket + * + * @see Socket::sigio + * @deprecated + * The behaviour of Socket::attach differs from other attach functions in + * mbed OS and has been known to cause confusion. Replaced by Socket::sigio. + */ + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "The behaviour of Socket::attach differs from other attach functions in " + "mbed OS and has been known to cause confusion. Replaced by Socket::sigio.") void attach(mbed::Callback func); /** Register a callback on state change of the socket * - * The specified callback will be called on state changes such as when - * the socket can recv/send/accept successfully and on when an error - * occurs. The callback may also be called spuriously without reason. - * - * The callback may be called in an interrupt context and should not - * perform expensive operations such as recv/send calls. - * - * @param obj Pointer to object to call method on - * @param method Method to call on state change - * + * @see Socket::sigio * @deprecated * The attach function does not support cv-qualifiers. Replaced by * attach(callback(obj, method)). diff --git a/features/unsupported/USBDevice/USBDevice/TARGET_STM/USBHAL_STM32F769NI.h b/features/unsupported/USBDevice/USBDevice/TARGET_STM/USBHAL_STM32F769NI.h index 4ef5c58c00..f2bfa7a102 100644 --- a/features/unsupported/USBDevice/USBDevice/TARGET_STM/USBHAL_STM32F769NI.h +++ b/features/unsupported/USBDevice/USBDevice/TARGET_STM/USBHAL_STM32F769NI.h @@ -135,7 +135,7 @@ USBHAL::USBHAL(void) { /* bulk/int 64 bytes in FS */ HAL_PCDEx_SetTxFiFo(&hpcd, 0, (MAX_PACKET_SIZE_EP0/4)+1); /* bulk/int bytes in FS */ - HAL_PCDEx_SetTxFiFo(&hpcd, 1, (MAX_PACKET_SIZE_EP1/4)); + HAL_PCDEx_SetTxFiFo(&hpcd, 1, (MAX_PACKET_SIZE_EP1/4)+1); HAL_PCDEx_SetTxFiFo(&hpcd, 2, (MAX_PACKET_SIZE_EP2/4)); /* ISOchronous */ HAL_PCDEx_SetTxFiFo(&hpcd, 3, (MAX_PACKET_SIZE_EP3/4)); diff --git a/features/unsupported/USBDevice/USBDevice/TARGET_STM/USBHAL_STM32L476VG.h b/features/unsupported/USBDevice/USBDevice/TARGET_STM/USBHAL_STM32L476VG.h index e313b2529b..b08bce8b40 100644 --- a/features/unsupported/USBDevice/USBDevice/TARGET_STM/USBHAL_STM32L476VG.h +++ b/features/unsupported/USBDevice/USBDevice/TARGET_STM/USBHAL_STM32L476VG.h @@ -131,7 +131,7 @@ USBHAL::USBHAL(void) { /* bulk/int 64 bytes in FS */ HAL_PCDEx_SetTxFiFo(&hpcd, 0, (MAX_PACKET_SIZE_EP0/4)+1); /* bulk/int bytes in FS */ - HAL_PCDEx_SetTxFiFo(&hpcd, 1, (MAX_PACKET_SIZE_EP1/4)); + HAL_PCDEx_SetTxFiFo(&hpcd, 1, (MAX_PACKET_SIZE_EP1/4)+1); HAL_PCDEx_SetTxFiFo(&hpcd, 2, (MAX_PACKET_SIZE_EP2/4)); /* ISOchronous */ HAL_PCDEx_SetTxFiFo(&hpcd, 3, (MAX_PACKET_SIZE_EP3/4)); diff --git a/features/unsupported/USBDevice/USBDevice/TARGET_STM/USBHAL_STM_144_64pins.h b/features/unsupported/USBDevice/USBDevice/TARGET_STM/USBHAL_STM_144_64pins.h index 15fad1af0a..a9d3760448 100644 --- a/features/unsupported/USBDevice/USBDevice/TARGET_STM/USBHAL_STM_144_64pins.h +++ b/features/unsupported/USBDevice/USBDevice/TARGET_STM/USBHAL_STM_144_64pins.h @@ -121,7 +121,7 @@ USBHAL::USBHAL(void) { /* bulk/int 64 bytes in FS */ HAL_PCDEx_SetTxFiFo(&hpcd, 0, (MAX_PACKET_SIZE_EP0/4)+1); /* bulk/int bytes in FS */ - HAL_PCDEx_SetTxFiFo(&hpcd, 1, (MAX_PACKET_SIZE_EP1/4)); + HAL_PCDEx_SetTxFiFo(&hpcd, 1, (MAX_PACKET_SIZE_EP1/4)+1); HAL_PCDEx_SetTxFiFo(&hpcd, 2, (MAX_PACKET_SIZE_EP2/4)); /* ISOchronous */ HAL_PCDEx_SetTxFiFo(&hpcd, 3, (MAX_PACKET_SIZE_EP3/4)); diff --git a/features/unsupported/USBDevice/USBHID/USBHID.cpp b/features/unsupported/USBDevice/USBHID/USBHID.cpp index 571421d823..9ace4c992e 100644 --- a/features/unsupported/USBDevice/USBHID/USBHID.cpp +++ b/features/unsupported/USBDevice/USBHID/USBHID.cpp @@ -199,20 +199,23 @@ uint8_t * USBHID::stringIproductDesc() { uint8_t * USBHID::reportDesc() { static uint8_t reportDescriptor[] = { - 0x06, LSB(0xFFAB), MSB(0xFFAB), - 0x0A, LSB(0x0200), MSB(0x0200), - 0xA1, 0x01, // Collection 0x01 - 0x75, 0x08, // report size = 8 bits - 0x15, 0x00, // logical minimum = 0 - 0x26, 0xFF, 0x00, // logical maximum = 255 - 0x95, input_length, // report count - 0x09, 0x01, // usage - 0x81, 0x02, // Input (array) - 0x95, output_length,// report count - 0x09, 0x02, // usage - 0x91, 0x02, // Output (array) - 0xC0 // end collection + USAGE_PAGE(2), LSB(0xFFAB), MSB(0xFFAB), + USAGE(2), LSB(0x0200), MSB(0x0200), + COLLECTION(1), 0x01, // Collection (Application) + REPORT_SIZE(1), 0x08, // 8 bits + LOGICAL_MINIMUM(1), 0x00, + LOGICAL_MAXIMUM(1), 0xFF, + + REPORT_COUNT(1), input_length, + USAGE(1), 0x01, + INPUT(1), 0x02, // Data, Var, Abs + + REPORT_COUNT(1), output_length, + USAGE(1), 0x02, + OUTPUT(1), 0x02, // Data, Var, Abs + + END_COLLECTION(0), }; reportLength = sizeof(reportDescriptor); return reportDescriptor; @@ -226,51 +229,51 @@ uint8_t * USBHID::reportDesc() { uint8_t * USBHID::configurationDesc() { static uint8_t configurationDescriptor[] = { - CONFIGURATION_DESCRIPTOR_LENGTH,// bLength - CONFIGURATION_DESCRIPTOR, // bDescriptorType - LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB) - MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB) - 0x01, // bNumInterfaces - DEFAULT_CONFIGURATION, // bConfigurationValue - 0x00, // iConfiguration - C_RESERVED | C_SELF_POWERED, // bmAttributes - C_POWER(0), // bMaxPower + CONFIGURATION_DESCRIPTOR_LENGTH, // bLength + CONFIGURATION_DESCRIPTOR, // bDescriptorType + LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB) + MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB) + 0x01, // bNumInterfaces + DEFAULT_CONFIGURATION, // bConfigurationValue + 0x00, // iConfiguration + C_RESERVED | C_SELF_POWERED, // bmAttributes + C_POWER(0), // bMaxPower - INTERFACE_DESCRIPTOR_LENGTH, // bLength - INTERFACE_DESCRIPTOR, // bDescriptorType - 0x00, // bInterfaceNumber - 0x00, // bAlternateSetting - 0x02, // bNumEndpoints - HID_CLASS, // bInterfaceClass - HID_SUBCLASS_NONE, // bInterfaceSubClass - HID_PROTOCOL_NONE, // bInterfaceProtocol - 0x00, // iInterface + INTERFACE_DESCRIPTOR_LENGTH, // bLength + INTERFACE_DESCRIPTOR, // bDescriptorType + 0x00, // bInterfaceNumber + 0x00, // bAlternateSetting + 0x02, // bNumEndpoints + HID_CLASS, // bInterfaceClass + HID_SUBCLASS_NONE, // bInterfaceSubClass + HID_PROTOCOL_NONE, // bInterfaceProtocol + 0x00, // iInterface - HID_DESCRIPTOR_LENGTH, // bLength - HID_DESCRIPTOR, // bDescriptorType - LSB(HID_VERSION_1_11), // bcdHID (LSB) - MSB(HID_VERSION_1_11), // bcdHID (MSB) - 0x00, // bCountryCode - 0x01, // bNumDescriptors - REPORT_DESCRIPTOR, // bDescriptorType - (uint8_t)(LSB(this->reportDescLength())), // wDescriptorLength (LSB) - (uint8_t)(MSB(this->reportDescLength())), // wDescriptorLength (MSB) + HID_DESCRIPTOR_LENGTH, // bLength + HID_DESCRIPTOR, // bDescriptorType + LSB(HID_VERSION_1_11), // bcdHID (LSB) + MSB(HID_VERSION_1_11), // bcdHID (MSB) + 0x00, // bCountryCode + 0x01, // bNumDescriptors + REPORT_DESCRIPTOR, // bDescriptorType + (uint8_t)(LSB(reportDescLength())), // wDescriptorLength (LSB) + (uint8_t)(MSB(reportDescLength())), // wDescriptorLength (MSB) - ENDPOINT_DESCRIPTOR_LENGTH, // bLength - ENDPOINT_DESCRIPTOR, // bDescriptorType - PHY_TO_DESC(EPINT_IN), // bEndpointAddress - E_INTERRUPT, // bmAttributes - LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB) - MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB) - 1, // bInterval (milliseconds) + ENDPOINT_DESCRIPTOR_LENGTH, // bLength + ENDPOINT_DESCRIPTOR, // bDescriptorType + PHY_TO_DESC(EPINT_IN), // bEndpointAddress + E_INTERRUPT, // bmAttributes + LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB) + MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB) + 1, // bInterval (milliseconds) - ENDPOINT_DESCRIPTOR_LENGTH, // bLength - ENDPOINT_DESCRIPTOR, // bDescriptorType - PHY_TO_DESC(EPINT_OUT), // bEndpointAddress - E_INTERRUPT, // bmAttributes - LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB) - MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB) - 1, // bInterval (milliseconds) + ENDPOINT_DESCRIPTOR_LENGTH, // bLength + ENDPOINT_DESCRIPTOR, // bDescriptorType + PHY_TO_DESC(EPINT_OUT), // bEndpointAddress + E_INTERRUPT, // bmAttributes + LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB) + MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB) + 1, // bInterval (milliseconds) }; return configurationDescriptor; } diff --git a/features/unsupported/USBDevice/USBHID/USBHID_Types.h b/features/unsupported/USBDevice/USBHID/USBHID_Types.h index b8b181bedd..0a8e802329 100644 --- a/features/unsupported/USBDevice/USBHID/USBHID_Types.h +++ b/features/unsupported/USBDevice/USBHID/USBHID_Types.h @@ -25,9 +25,12 @@ #define HID_VERSION_1_11 (0x0111) /* HID Class */ -#define HID_CLASS (3) -#define HID_SUBCLASS_NONE (0) -#define HID_PROTOCOL_NONE (0) +#define HID_CLASS (3) +#define HID_SUBCLASS_NONE (0) +#define HID_SUBCLASS_BOOT (1) +#define HID_PROTOCOL_NONE (0) +#define HID_PROTOCOL_KEYBOARD (1) +#define HID_PROTOCOL_MOUSE (2) /* Descriptors */ #define HID_DESCRIPTOR (33) diff --git a/features/unsupported/USBDevice/USBHID/USBKeyboard.cpp b/features/unsupported/USBDevice/USBHID/USBKeyboard.cpp index df4ca4798b..3f02dd3182 100644 --- a/features/unsupported/USBDevice/USBHID/USBKeyboard.cpp +++ b/features/unsupported/USBDevice/USBHID/USBKeyboard.cpp @@ -503,51 +503,51 @@ bool USBKeyboard::mediaControl(MEDIA_KEY key) { uint8_t * USBKeyboard::configurationDesc() { static uint8_t configurationDescriptor[] = { - CONFIGURATION_DESCRIPTOR_LENGTH,// bLength - CONFIGURATION_DESCRIPTOR, // bDescriptorType - LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB) - MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB) - 0x01, // bNumInterfaces - DEFAULT_CONFIGURATION, // bConfigurationValue - 0x00, // iConfiguration - C_RESERVED | C_SELF_POWERED, // bmAttributes - C_POWER(0), // bMaxPowerHello World from Mbed + CONFIGURATION_DESCRIPTOR_LENGTH, // bLength + CONFIGURATION_DESCRIPTOR, // bDescriptorType + LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB) + MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB) + 0x01, // bNumInterfaces + DEFAULT_CONFIGURATION, // bConfigurationValue + 0x00, // iConfiguration + C_RESERVED | C_SELF_POWERED, // bmAttributes + C_POWER(0), // bMaxPower - INTERFACE_DESCRIPTOR_LENGTH, // bLength - INTERFACE_DESCRIPTOR, // bDescriptorType - 0x00, // bInterfaceNumber - 0x00, // bAlternateSetting - 0x02, // bNumEndpoints - HID_CLASS, // bInterfaceClass - 1, // bInterfaceSubClass - 1, // bInterfaceProtocol (keyboard) - 0x00, // iInterface + INTERFACE_DESCRIPTOR_LENGTH, // bLength + INTERFACE_DESCRIPTOR, // bDescriptorType + 0x00, // bInterfaceNumber + 0x00, // bAlternateSetting + 0x02, // bNumEndpoints + HID_CLASS, // bInterfaceClass + HID_SUBCLASS_BOOT, // bInterfaceSubClass + HID_PROTOCOL_KEYBOARD, // bInterfaceProtocol + 0x00, // iInterface - HID_DESCRIPTOR_LENGTH, // bLength - HID_DESCRIPTOR, // bDescriptorType - LSB(HID_VERSION_1_11), // bcdHID (LSB) - MSB(HID_VERSION_1_11), // bcdHID (MSB) - 0x00, // bCountryCode - 0x01, // bNumDescriptors - REPORT_DESCRIPTOR, // bDescriptorType - (uint8_t)(LSB(reportDescLength())), // wDescriptorLength (LSB) - (uint8_t)(MSB(reportDescLength())), // wDescriptorLength (MSB) + HID_DESCRIPTOR_LENGTH, // bLength + HID_DESCRIPTOR, // bDescriptorType + LSB(HID_VERSION_1_11), // bcdHID (LSB) + MSB(HID_VERSION_1_11), // bcdHID (MSB) + 0x00, // bCountryCode + 0x01, // bNumDescriptors + REPORT_DESCRIPTOR, // bDescriptorType + (uint8_t)(LSB(reportDescLength())), // wDescriptorLength (LSB) + (uint8_t)(MSB(reportDescLength())), // wDescriptorLength (MSB) - ENDPOINT_DESCRIPTOR_LENGTH, // bLength - ENDPOINT_DESCRIPTOR, // bDescriptorType - PHY_TO_DESC(EPINT_IN), // bEndpointAddress - E_INTERRUPT, // bmAttributes - LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB) - MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB) - 1, // bInterval (milliseconds) + ENDPOINT_DESCRIPTOR_LENGTH, // bLength + ENDPOINT_DESCRIPTOR, // bDescriptorType + PHY_TO_DESC(EPINT_IN), // bEndpointAddress + E_INTERRUPT, // bmAttributes + LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB) + MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB) + 1, // bInterval (milliseconds) - ENDPOINT_DESCRIPTOR_LENGTH, // bLength - ENDPOINT_DESCRIPTOR, // bDescriptorType - PHY_TO_DESC(EPINT_OUT), // bEndpointAddress - E_INTERRUPT, // bmAttributes - LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB) - MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB) - 1, // bInterval (milliseconds) + ENDPOINT_DESCRIPTOR_LENGTH, // bLength + ENDPOINT_DESCRIPTOR, // bDescriptorType + PHY_TO_DESC(EPINT_OUT), // bEndpointAddress + E_INTERRUPT, // bmAttributes + LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB) + MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB) + 1, // bInterval (milliseconds) }; return configurationDescriptor; } diff --git a/features/unsupported/USBDevice/USBHID/USBMouse.cpp b/features/unsupported/USBDevice/USBHID/USBMouse.cpp index 980e679091..ac3016cae0 100644 --- a/features/unsupported/USBDevice/USBHID/USBMouse.cpp +++ b/features/unsupported/USBDevice/USBHID/USBMouse.cpp @@ -142,7 +142,6 @@ uint8_t * USBMouse::reportDesc() { return reportDescriptor; } else if (mouse_type == ABS_MOUSE) { static uint8_t reportDescriptor[] = { - USAGE_PAGE(1), 0x01, // Generic Desktop USAGE(1), 0x02, // Mouse COLLECTION(1), 0x01, // Application @@ -195,51 +194,51 @@ uint8_t * USBMouse::reportDesc() { uint8_t * USBMouse::configurationDesc() { static uint8_t configurationDescriptor[] = { - CONFIGURATION_DESCRIPTOR_LENGTH,// bLength - CONFIGURATION_DESCRIPTOR, // bDescriptorType - LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB) - MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB) - 0x01, // bNumInterfaces - DEFAULT_CONFIGURATION, // bConfigurationValue - 0x00, // iConfiguration - C_RESERVED | C_SELF_POWERED, // bmAttributes - C_POWER(0), // bMaxPowerHello World from Mbed + CONFIGURATION_DESCRIPTOR_LENGTH, // bLength + CONFIGURATION_DESCRIPTOR, // bDescriptorType + LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB) + MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB) + 0x01, // bNumInterfaces + DEFAULT_CONFIGURATION, // bConfigurationValue + 0x00, // iConfiguration + C_RESERVED | C_SELF_POWERED, // bmAttributes + C_POWER(0), // bMaxPower - INTERFACE_DESCRIPTOR_LENGTH, // bLength - INTERFACE_DESCRIPTOR, // bDescriptorType - 0x00, // bInterfaceNumber - 0x00, // bAlternateSetting - 0x02, // bNumEndpoints - HID_CLASS, // bInterfaceClass - 1, // bInterfaceSubClass - 2, // bInterfaceProtocol (mouse) - 0x00, // iInterface + INTERFACE_DESCRIPTOR_LENGTH, // bLength + INTERFACE_DESCRIPTOR, // bDescriptorType + 0x00, // bInterfaceNumber + 0x00, // bAlternateSetting + 0x02, // bNumEndpoints + HID_CLASS, // bInterfaceClass + HID_SUBCLASS_BOOT, // bInterfaceSubClass + HID_PROTOCOL_MOUSE, // bInterfaceProtocol + 0x00, // iInterface - HID_DESCRIPTOR_LENGTH, // bLength - HID_DESCRIPTOR, // bDescriptorType - LSB(HID_VERSION_1_11), // bcdHID (LSB) - MSB(HID_VERSION_1_11), // bcdHID (MSB) - 0x00, // bCountryCode - 0x01, // bNumDescriptors - REPORT_DESCRIPTOR, // bDescriptorType - (uint8_t)(LSB(reportDescLength())), // wDescriptorLength (LSB) - (uint8_t)(MSB(reportDescLength())), // wDescriptorLength (MSB) + HID_DESCRIPTOR_LENGTH, // bLength + HID_DESCRIPTOR, // bDescriptorType + LSB(HID_VERSION_1_11), // bcdHID (LSB) + MSB(HID_VERSION_1_11), // bcdHID (MSB) + 0x00, // bCountryCode + 0x01, // bNumDescriptors + REPORT_DESCRIPTOR, // bDescriptorType + (uint8_t)(LSB(reportDescLength())), // wDescriptorLength (LSB) + (uint8_t)(MSB(reportDescLength())), // wDescriptorLength (MSB) - ENDPOINT_DESCRIPTOR_LENGTH, // bLength - ENDPOINT_DESCRIPTOR, // bDescriptorType - PHY_TO_DESC(EPINT_IN), // bEndpointAddress - E_INTERRUPT, // bmAttributes - LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB) - MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB) - 1, // bInterval (milliseconds) + ENDPOINT_DESCRIPTOR_LENGTH, // bLength + ENDPOINT_DESCRIPTOR, // bDescriptorType + PHY_TO_DESC(EPINT_IN), // bEndpointAddress + E_INTERRUPT, // bmAttributes + LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB) + MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB) + 1, // bInterval (milliseconds) - ENDPOINT_DESCRIPTOR_LENGTH, // bLength - ENDPOINT_DESCRIPTOR, // bDescriptorType - PHY_TO_DESC(EPINT_OUT), // bEndpointAddress - E_INTERRUPT, // bmAttributes - LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB) - MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB) - 1, // bInterval (milliseconds) + ENDPOINT_DESCRIPTOR_LENGTH, // bLength + ENDPOINT_DESCRIPTOR, // bDescriptorType + PHY_TO_DESC(EPINT_OUT), // bEndpointAddress + E_INTERRUPT, // bmAttributes + LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB) + MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB) + 1, // bInterval (milliseconds) }; return configurationDescriptor; } 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 0000000000..05c6660716 --- /dev/null +++ b/hal/TARGET_FLASH_CMSIS_ALGO/flash_common_algo.c @@ -0,0 +1,169 @@ +/* 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 "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 +}; + +// 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) +{ + const sector_info_t *sectors = obj->target_config->sectors; + + if (address >= obj->target_config->flash_start + obj->target_config->flash_size) { + return MBED_FLASH_INVALID_SIZE; + } + + int sector_index = obj->target_config->sector_info_count - 1; + for (; sector_index >= 0; sector_index--) { + if (address >= sectors[sector_index].start) { + return sectors[sector_index].size; + } + } + return MBED_FLASH_INVALID_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 0000000000..e905ad22a3 --- /dev/null +++ b/hal/TARGET_FLASH_CMSIS_ALGO/flash_data.h @@ -0,0 +1,83 @@ +/* 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. + */ +#ifndef MBED_FLASH_DATA_H +#define MBED_FLASH_DATA_H + +#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; + const uint32_t sector_info_count; +} 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 0000000000..1320ec37fc --- /dev/null +++ b/hal/flash_api.h @@ -0,0 +1,119 @@ +/** \addtogroup hal */ +/** @{*/ + +/* 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. + */ +#ifndef MBED_FLASH_API_H +#define MBED_FLASH_API_H + +#include "device.h" +#include + +#if DEVICE_FLASH + +#define MBED_FLASH_INVALID_SIZE 0xFFFFFFFF + +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 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); + +/** 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 object + * @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 object + * @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 0e71670a0d..587bfca9e1 100644 --- a/mbed.h +++ b/mbed.h @@ -49,6 +49,7 @@ #include "platform/toolchain.h" #include "platform/platform.h" +#include "platform/mbed_application.h" // Useful C libraries #include @@ -80,6 +81,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/platform/Callback.h b/platform/Callback.h index c888acbd3f..5a12e1020a 100644 --- a/platform/Callback.h +++ b/platform/Callback.h @@ -268,7 +268,11 @@ public: /** Attach a static function * @param func Static function to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(R (*func)()) { this->~Callback(); new (this) Callback(func); @@ -276,7 +280,11 @@ public: /** Attach a Callback * @param func The Callback to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(const Callback &func) { this->~Callback(); new (this) Callback(func); @@ -285,8 +293,12 @@ public: /** Attach a member function * @param obj Pointer to object to invoke member function on * @param method Member function to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(U *obj, R (T::*method)()) { this->~Callback(); new (this) Callback(obj, method); @@ -295,8 +307,12 @@ public: /** Attach a member function * @param obj Pointer to object to invoke member function on * @param method Member function to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(const U *obj, R (T::*method)() const) { this->~Callback(); new (this) Callback(obj, method); @@ -305,8 +321,12 @@ public: /** Attach a member function * @param obj Pointer to object to invoke member function on * @param method Member function to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(volatile U *obj, R (T::*method)() volatile) { this->~Callback(); new (this) Callback(obj, method); @@ -315,8 +335,12 @@ public: /** Attach a member function * @param obj Pointer to object to invoke member function on * @param method Member function to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(const volatile U *obj, R (T::*method)() const volatile) { this->~Callback(); new (this) Callback(obj, method); @@ -325,8 +349,12 @@ public: /** Attach a static function with a bound pointer * @param func Static function to attach * @param arg Pointer argument to function + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(R (*func)(T*), U *arg) { this->~Callback(); new (this) Callback(func, arg); @@ -335,8 +363,12 @@ public: /** Attach a static function with a bound pointer * @param func Static function to attach * @param arg Pointer argument to function + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(R (*func)(const T*), const U *arg) { this->~Callback(); new (this) Callback(func, arg); @@ -345,8 +377,12 @@ public: /** Attach a static function with a bound pointer * @param func Static function to attach * @param arg Pointer argument to function + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(R (*func)(volatile T*), volatile U *arg) { this->~Callback(); new (this) Callback(func, arg); @@ -355,8 +391,12 @@ public: /** Attach a static function with a bound pointer * @param func Static function to attach * @param arg Pointer argument to function + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(R (*func)(const volatile T*), const volatile U *arg) { this->~Callback(); new (this) Callback(func, arg); @@ -365,8 +405,12 @@ public: /** Attach a function object * @param func Function object to attach * @note The function object is limited to a single word of storage + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(F f, typename detail::enable_if< detail::is_type::value && sizeof(F) <= sizeof(uintptr_t) @@ -378,8 +422,12 @@ public: /** Attach a function object * @param func Function object to attach * @note The function object is limited to a single word of storage + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(const F f, typename detail::enable_if< detail::is_type::value && sizeof(F) <= sizeof(uintptr_t) @@ -391,8 +439,12 @@ public: /** Attach a function object * @param func Function object to attach * @note The function object is limited to a single word of storage + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(volatile F f, typename detail::enable_if< detail::is_type::value && sizeof(F) <= sizeof(uintptr_t) @@ -404,8 +456,12 @@ public: /** Attach a function object * @param func Function object to attach * @note The function object is limited to a single word of storage + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(const volatile F f, typename detail::enable_if< detail::is_type::value && sizeof(F) <= sizeof(uintptr_t) @@ -807,7 +863,11 @@ public: /** Attach a static function * @param func Static function to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(R (*func)(A0)) { this->~Callback(); new (this) Callback(func); @@ -815,7 +875,11 @@ public: /** Attach a Callback * @param func The Callback to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(const Callback &func) { this->~Callback(); new (this) Callback(func); @@ -824,8 +888,12 @@ public: /** Attach a member function * @param obj Pointer to object to invoke member function on * @param method Member function to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(U *obj, R (T::*method)(A0)) { this->~Callback(); new (this) Callback(obj, method); @@ -834,8 +902,12 @@ public: /** Attach a member function * @param obj Pointer to object to invoke member function on * @param method Member function to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(const U *obj, R (T::*method)(A0) const) { this->~Callback(); new (this) Callback(obj, method); @@ -844,8 +916,12 @@ public: /** Attach a member function * @param obj Pointer to object to invoke member function on * @param method Member function to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(volatile U *obj, R (T::*method)(A0) volatile) { this->~Callback(); new (this) Callback(obj, method); @@ -854,8 +930,12 @@ public: /** Attach a member function * @param obj Pointer to object to invoke member function on * @param method Member function to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(const volatile U *obj, R (T::*method)(A0) const volatile) { this->~Callback(); new (this) Callback(obj, method); @@ -864,8 +944,12 @@ public: /** Attach a static function with a bound pointer * @param func Static function to attach * @param arg Pointer argument to function + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(R (*func)(T*, A0), U *arg) { this->~Callback(); new (this) Callback(func, arg); @@ -874,8 +958,12 @@ public: /** Attach a static function with a bound pointer * @param func Static function to attach * @param arg Pointer argument to function + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(R (*func)(const T*, A0), const U *arg) { this->~Callback(); new (this) Callback(func, arg); @@ -884,8 +972,12 @@ public: /** Attach a static function with a bound pointer * @param func Static function to attach * @param arg Pointer argument to function + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(R (*func)(volatile T*, A0), volatile U *arg) { this->~Callback(); new (this) Callback(func, arg); @@ -894,8 +986,12 @@ public: /** Attach a static function with a bound pointer * @param func Static function to attach * @param arg Pointer argument to function + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(R (*func)(const volatile T*, A0), const volatile U *arg) { this->~Callback(); new (this) Callback(func, arg); @@ -904,8 +1000,12 @@ public: /** Attach a function object * @param func Function object to attach * @note The function object is limited to a single word of storage + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(F f, typename detail::enable_if< detail::is_type::value && sizeof(F) <= sizeof(uintptr_t) @@ -917,8 +1017,12 @@ public: /** Attach a function object * @param func Function object to attach * @note The function object is limited to a single word of storage + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(const F f, typename detail::enable_if< detail::is_type::value && sizeof(F) <= sizeof(uintptr_t) @@ -930,8 +1034,12 @@ public: /** Attach a function object * @param func Function object to attach * @note The function object is limited to a single word of storage + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(volatile F f, typename detail::enable_if< detail::is_type::value && sizeof(F) <= sizeof(uintptr_t) @@ -943,8 +1051,12 @@ public: /** Attach a function object * @param func Function object to attach * @note The function object is limited to a single word of storage + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(const volatile F f, typename detail::enable_if< detail::is_type::value && sizeof(F) <= sizeof(uintptr_t) @@ -1346,7 +1458,11 @@ public: /** Attach a static function * @param func Static function to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(R (*func)(A0, A1)) { this->~Callback(); new (this) Callback(func); @@ -1354,7 +1470,11 @@ public: /** Attach a Callback * @param func The Callback to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(const Callback &func) { this->~Callback(); new (this) Callback(func); @@ -1363,8 +1483,12 @@ public: /** Attach a member function * @param obj Pointer to object to invoke member function on * @param method Member function to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(U *obj, R (T::*method)(A0, A1)) { this->~Callback(); new (this) Callback(obj, method); @@ -1373,8 +1497,12 @@ public: /** Attach a member function * @param obj Pointer to object to invoke member function on * @param method Member function to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(const U *obj, R (T::*method)(A0, A1) const) { this->~Callback(); new (this) Callback(obj, method); @@ -1383,8 +1511,12 @@ public: /** Attach a member function * @param obj Pointer to object to invoke member function on * @param method Member function to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(volatile U *obj, R (T::*method)(A0, A1) volatile) { this->~Callback(); new (this) Callback(obj, method); @@ -1393,8 +1525,12 @@ public: /** Attach a member function * @param obj Pointer to object to invoke member function on * @param method Member function to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(const volatile U *obj, R (T::*method)(A0, A1) const volatile) { this->~Callback(); new (this) Callback(obj, method); @@ -1403,8 +1539,12 @@ public: /** Attach a static function with a bound pointer * @param func Static function to attach * @param arg Pointer argument to function + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(R (*func)(T*, A0, A1), U *arg) { this->~Callback(); new (this) Callback(func, arg); @@ -1413,8 +1553,12 @@ public: /** Attach a static function with a bound pointer * @param func Static function to attach * @param arg Pointer argument to function + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(R (*func)(const T*, A0, A1), const U *arg) { this->~Callback(); new (this) Callback(func, arg); @@ -1423,8 +1567,12 @@ public: /** Attach a static function with a bound pointer * @param func Static function to attach * @param arg Pointer argument to function + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(R (*func)(volatile T*, A0, A1), volatile U *arg) { this->~Callback(); new (this) Callback(func, arg); @@ -1433,8 +1581,12 @@ public: /** Attach a static function with a bound pointer * @param func Static function to attach * @param arg Pointer argument to function + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(R (*func)(const volatile T*, A0, A1), const volatile U *arg) { this->~Callback(); new (this) Callback(func, arg); @@ -1443,8 +1595,12 @@ public: /** Attach a function object * @param func Function object to attach * @note The function object is limited to a single word of storage + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(F f, typename detail::enable_if< detail::is_type::value && sizeof(F) <= sizeof(uintptr_t) @@ -1456,8 +1612,12 @@ public: /** Attach a function object * @param func Function object to attach * @note The function object is limited to a single word of storage + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(const F f, typename detail::enable_if< detail::is_type::value && sizeof(F) <= sizeof(uintptr_t) @@ -1469,8 +1629,12 @@ public: /** Attach a function object * @param func Function object to attach * @note The function object is limited to a single word of storage + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(volatile F f, typename detail::enable_if< detail::is_type::value && sizeof(F) <= sizeof(uintptr_t) @@ -1482,8 +1646,12 @@ public: /** Attach a function object * @param func Function object to attach * @note The function object is limited to a single word of storage + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(const volatile F f, typename detail::enable_if< detail::is_type::value && sizeof(F) <= sizeof(uintptr_t) @@ -1885,7 +2053,11 @@ public: /** Attach a static function * @param func Static function to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(R (*func)(A0, A1, A2)) { this->~Callback(); new (this) Callback(func); @@ -1893,7 +2065,11 @@ public: /** Attach a Callback * @param func The Callback to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(const Callback &func) { this->~Callback(); new (this) Callback(func); @@ -1902,8 +2078,12 @@ public: /** Attach a member function * @param obj Pointer to object to invoke member function on * @param method Member function to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(U *obj, R (T::*method)(A0, A1, A2)) { this->~Callback(); new (this) Callback(obj, method); @@ -1912,8 +2092,12 @@ public: /** Attach a member function * @param obj Pointer to object to invoke member function on * @param method Member function to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(const U *obj, R (T::*method)(A0, A1, A2) const) { this->~Callback(); new (this) Callback(obj, method); @@ -1922,8 +2106,12 @@ public: /** Attach a member function * @param obj Pointer to object to invoke member function on * @param method Member function to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(volatile U *obj, R (T::*method)(A0, A1, A2) volatile) { this->~Callback(); new (this) Callback(obj, method); @@ -1932,8 +2120,12 @@ public: /** Attach a member function * @param obj Pointer to object to invoke member function on * @param method Member function to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(const volatile U *obj, R (T::*method)(A0, A1, A2) const volatile) { this->~Callback(); new (this) Callback(obj, method); @@ -1942,8 +2134,12 @@ public: /** Attach a static function with a bound pointer * @param func Static function to attach * @param arg Pointer argument to function + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(R (*func)(T*, A0, A1, A2), U *arg) { this->~Callback(); new (this) Callback(func, arg); @@ -1952,8 +2148,12 @@ public: /** Attach a static function with a bound pointer * @param func Static function to attach * @param arg Pointer argument to function + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(R (*func)(const T*, A0, A1, A2), const U *arg) { this->~Callback(); new (this) Callback(func, arg); @@ -1962,8 +2162,12 @@ public: /** Attach a static function with a bound pointer * @param func Static function to attach * @param arg Pointer argument to function + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(R (*func)(volatile T*, A0, A1, A2), volatile U *arg) { this->~Callback(); new (this) Callback(func, arg); @@ -1972,8 +2176,12 @@ public: /** Attach a static function with a bound pointer * @param func Static function to attach * @param arg Pointer argument to function + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(R (*func)(const volatile T*, A0, A1, A2), const volatile U *arg) { this->~Callback(); new (this) Callback(func, arg); @@ -1982,8 +2190,12 @@ public: /** Attach a function object * @param func Function object to attach * @note The function object is limited to a single word of storage + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(F f, typename detail::enable_if< detail::is_type::value && sizeof(F) <= sizeof(uintptr_t) @@ -1995,8 +2207,12 @@ public: /** Attach a function object * @param func Function object to attach * @note The function object is limited to a single word of storage + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(const F f, typename detail::enable_if< detail::is_type::value && sizeof(F) <= sizeof(uintptr_t) @@ -2008,8 +2224,12 @@ public: /** Attach a function object * @param func Function object to attach * @note The function object is limited to a single word of storage + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(volatile F f, typename detail::enable_if< detail::is_type::value && sizeof(F) <= sizeof(uintptr_t) @@ -2021,8 +2241,12 @@ public: /** Attach a function object * @param func Function object to attach * @note The function object is limited to a single word of storage + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(const volatile F f, typename detail::enable_if< detail::is_type::value && sizeof(F) <= sizeof(uintptr_t) @@ -2424,7 +2648,11 @@ public: /** Attach a static function * @param func Static function to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(R (*func)(A0, A1, A2, A3)) { this->~Callback(); new (this) Callback(func); @@ -2432,7 +2660,11 @@ public: /** Attach a Callback * @param func The Callback to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(const Callback &func) { this->~Callback(); new (this) Callback(func); @@ -2441,8 +2673,12 @@ public: /** Attach a member function * @param obj Pointer to object to invoke member function on * @param method Member function to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(U *obj, R (T::*method)(A0, A1, A2, A3)) { this->~Callback(); new (this) Callback(obj, method); @@ -2451,8 +2687,12 @@ public: /** Attach a member function * @param obj Pointer to object to invoke member function on * @param method Member function to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(const U *obj, R (T::*method)(A0, A1, A2, A3) const) { this->~Callback(); new (this) Callback(obj, method); @@ -2461,8 +2701,12 @@ public: /** Attach a member function * @param obj Pointer to object to invoke member function on * @param method Member function to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(volatile U *obj, R (T::*method)(A0, A1, A2, A3) volatile) { this->~Callback(); new (this) Callback(obj, method); @@ -2471,8 +2715,12 @@ public: /** Attach a member function * @param obj Pointer to object to invoke member function on * @param method Member function to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(const volatile U *obj, R (T::*method)(A0, A1, A2, A3) const volatile) { this->~Callback(); new (this) Callback(obj, method); @@ -2481,8 +2729,12 @@ public: /** Attach a static function with a bound pointer * @param func Static function to attach * @param arg Pointer argument to function + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(R (*func)(T*, A0, A1, A2, A3), U *arg) { this->~Callback(); new (this) Callback(func, arg); @@ -2491,8 +2743,12 @@ public: /** Attach a static function with a bound pointer * @param func Static function to attach * @param arg Pointer argument to function + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(R (*func)(const T*, A0, A1, A2, A3), const U *arg) { this->~Callback(); new (this) Callback(func, arg); @@ -2501,8 +2757,12 @@ public: /** Attach a static function with a bound pointer * @param func Static function to attach * @param arg Pointer argument to function + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(R (*func)(volatile T*, A0, A1, A2, A3), volatile U *arg) { this->~Callback(); new (this) Callback(func, arg); @@ -2511,8 +2771,12 @@ public: /** Attach a static function with a bound pointer * @param func Static function to attach * @param arg Pointer argument to function + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(R (*func)(const volatile T*, A0, A1, A2, A3), const volatile U *arg) { this->~Callback(); new (this) Callback(func, arg); @@ -2521,8 +2785,12 @@ public: /** Attach a function object * @param func Function object to attach * @note The function object is limited to a single word of storage + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(F f, typename detail::enable_if< detail::is_type::value && sizeof(F) <= sizeof(uintptr_t) @@ -2534,8 +2802,12 @@ public: /** Attach a function object * @param func Function object to attach * @note The function object is limited to a single word of storage + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(const F f, typename detail::enable_if< detail::is_type::value && sizeof(F) <= sizeof(uintptr_t) @@ -2547,8 +2819,12 @@ public: /** Attach a function object * @param func Function object to attach * @note The function object is limited to a single word of storage + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(volatile F f, typename detail::enable_if< detail::is_type::value && sizeof(F) <= sizeof(uintptr_t) @@ -2560,8 +2836,12 @@ public: /** Attach a function object * @param func Function object to attach * @note The function object is limited to a single word of storage + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(const volatile F f, typename detail::enable_if< detail::is_type::value && sizeof(F) <= sizeof(uintptr_t) @@ -2963,7 +3243,11 @@ public: /** Attach a static function * @param func Static function to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(R (*func)(A0, A1, A2, A3, A4)) { this->~Callback(); new (this) Callback(func); @@ -2971,7 +3255,11 @@ public: /** Attach a Callback * @param func The Callback to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(const Callback &func) { this->~Callback(); new (this) Callback(func); @@ -2980,8 +3268,12 @@ public: /** Attach a member function * @param obj Pointer to object to invoke member function on * @param method Member function to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(U *obj, R (T::*method)(A0, A1, A2, A3, A4)) { this->~Callback(); new (this) Callback(obj, method); @@ -2990,8 +3282,12 @@ public: /** Attach a member function * @param obj Pointer to object to invoke member function on * @param method Member function to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(const U *obj, R (T::*method)(A0, A1, A2, A3, A4) const) { this->~Callback(); new (this) Callback(obj, method); @@ -3000,8 +3296,12 @@ public: /** Attach a member function * @param obj Pointer to object to invoke member function on * @param method Member function to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(volatile U *obj, R (T::*method)(A0, A1, A2, A3, A4) volatile) { this->~Callback(); new (this) Callback(obj, method); @@ -3010,8 +3310,12 @@ public: /** Attach a member function * @param obj Pointer to object to invoke member function on * @param method Member function to attach + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(const volatile U *obj, R (T::*method)(A0, A1, A2, A3, A4) const volatile) { this->~Callback(); new (this) Callback(obj, method); @@ -3020,8 +3324,12 @@ public: /** Attach a static function with a bound pointer * @param func Static function to attach * @param arg Pointer argument to function + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(R (*func)(T*, A0, A1, A2, A3, A4), U *arg) { this->~Callback(); new (this) Callback(func, arg); @@ -3030,8 +3338,12 @@ public: /** Attach a static function with a bound pointer * @param func Static function to attach * @param arg Pointer argument to function + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(R (*func)(const T*, A0, A1, A2, A3, A4), const U *arg) { this->~Callback(); new (this) Callback(func, arg); @@ -3040,8 +3352,12 @@ public: /** Attach a static function with a bound pointer * @param func Static function to attach * @param arg Pointer argument to function + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(R (*func)(volatile T*, A0, A1, A2, A3, A4), volatile U *arg) { this->~Callback(); new (this) Callback(func, arg); @@ -3050,8 +3366,12 @@ public: /** Attach a static function with a bound pointer * @param func Static function to attach * @param arg Pointer argument to function + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(R (*func)(const volatile T*, A0, A1, A2, A3, A4), const volatile U *arg) { this->~Callback(); new (this) Callback(func, arg); @@ -3060,8 +3380,12 @@ public: /** Attach a function object * @param func Function object to attach * @note The function object is limited to a single word of storage + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(F f, typename detail::enable_if< detail::is_type::value && sizeof(F) <= sizeof(uintptr_t) @@ -3073,8 +3397,12 @@ public: /** Attach a function object * @param func Function object to attach * @note The function object is limited to a single word of storage + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(const F f, typename detail::enable_if< detail::is_type::value && sizeof(F) <= sizeof(uintptr_t) @@ -3086,8 +3414,12 @@ public: /** Attach a function object * @param func Function object to attach * @note The function object is limited to a single word of storage + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(volatile F f, typename detail::enable_if< detail::is_type::value && sizeof(F) <= sizeof(uintptr_t) @@ -3099,8 +3431,12 @@ public: /** Attach a function object * @param func Function object to attach * @note The function object is limited to a single word of storage + * @deprecated + * Replaced by simple assignment 'Callback cb = func' */ template + MBED_DEPRECATED_SINCE("mbed-os-5.4", + "Replaced by simple assignment 'Callback cb = func") void attach(const volatile F f, typename detail::enable_if< detail::is_type::value && sizeof(F) <= sizeof(uintptr_t) diff --git a/platform/mbed_application.c b/platform/mbed_application.c new file mode 100644 index 0000000000..ff3e2db3f5 --- /dev/null +++ b/platform/mbed_application.c @@ -0,0 +1,127 @@ +/* mbed Microcontroller Library + * Copyright (c) 2017-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 +#include +#include "device.h" +#include "platform/mbed_application.h" + +#if MBED_APPLICATION_SUPPORT + +static void powerdown_nvic(void); +static void powerdown_scb(uint32_t vtor); +static void start_new_application(void *sp, void *pc); + +void mbed_start_application(uintptr_t address) +{ + void *sp; + void *pc; + + // Interrupts are re-enabled in start_new_application + __disable_irq(); + + SysTick->CTRL = 0x00000000; + powerdown_nvic(); + powerdown_scb(address); + + sp = *((void**)address + 0); + pc = *((void**)address + 1); + start_new_application(sp, pc); +} + +static void powerdown_nvic() +{ + int isr_count; + int i; + int j; + + isr_count = (SCnSCB->ICTR & SCnSCB_ICTR_INTLINESNUM_Msk) >> SCnSCB_ICTR_INTLINESNUM_Pos; + for (i = 0; i < isr_count; i++) { + NVIC->ICER[i] = 0xFFFFFFFF; + NVIC->ICPR[i] = 0xFFFFFFFF; + for (j = 0; j < 8; j++) { + NVIC->IP[i * 8 + j] = 0x00000000; + } + } +} + +static void powerdown_scb(uint32_t vtor) +{ + int i; + + // SCB->CPUID - Read only CPU ID register + SCB->ICSR = SCB_ICSR_PENDSVCLR_Msk | SCB_ICSR_PENDSTCLR_Msk; + SCB->VTOR = vtor; + SCB->AIRCR = 0x05FA | 0x0000; + SCB->SCR = 0x00000000; + // SCB->CCR - Implementation defined value + for (i = 0; i < 12; i++) { +#if defined(__CORTEX_M7) + SCB->SHPR[i] = 0x00; +#else + SCB->SHP[i] = 0x00; +#endif + } + SCB->SHCSR = 0x00000000; + SCB->CFSR = 0xFFFFFFFF; + SCB->HFSR = SCB_HFSR_DEBUGEVT_Msk | SCB_HFSR_FORCED_Msk | SCB_HFSR_VECTTBL_Msk; + SCB->DFSR = SCB_DFSR_EXTERNAL_Msk | SCB_DFSR_VCATCH_Msk | + SCB_DFSR_DWTTRAP_Msk | SCB_DFSR_BKPT_Msk | SCB_DFSR_HALTED_Msk; + // SCB->MMFAR - Implementation defined value + // SCB->BFAR - Implementation defined value + // SCB->AFSR - Implementation defined value + // SCB->PFR - Read only processor feature register + // SCB->DFR - Read only debug feature registers + // SCB->ADR - Read only auxiliary feature registers + // SCB->MMFR - Read only memory model feature registers + // SCB->ISAR - Read only instruction set attribute registers + // SCB->CPACR - Implementation defined value +} + +#if defined (__CC_ARM) + +__asm static void start_new_application(void *sp, void *pc) +{ + MOV R2, #0 + MSR CONTROL, R2 // Switch to main stack + MOV SP, R0 + MSR PRIMASK, R2 // Enable interrupts + BX R1 +} + +#elif defined (__GNUC__) || defined (__ICCARM__) + +void start_new_application(void *sp, void *pc) +{ + __asm volatile ( + "mov r2, #0 \n" + "msr control, r2 \n" // Switch to main stack + "mov sp, %0 \n" + "msr primask, r2 \n" // Enable interrupts + "bx %1 \n" + : + : "l" (sp), "l" (pc) + : "r2", "cc", "memory" + ); +} + +#else + +#error "Unsupported toolchain" + +#endif + +#endif /* MBED_APPLICATION_SUPPORT */ diff --git a/platform/mbed_application.h b/platform/mbed_application.h new file mode 100644 index 0000000000..6ee0bfd07d --- /dev/null +++ b/platform/mbed_application.h @@ -0,0 +1,50 @@ + +/** \addtogroup platform */ +/** @{*/ +/* mbed Microcontroller Library + * Copyright (c) 2017-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. + */ +#ifndef MBED_APPLICATION_H +#define MBED_APPLICATION_H + +#include + +#define MBED_APPLICATION_SUPPORT (defined(__CORTEX_M3) || defined(__CORTEX_M4) || defined(__CORTEX_M7)) +#if MBED_APPLICATION_SUPPORT +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Start the application at the given address. This function does + * not return. It is the applications responsibility for flushing to + * or powering down external components such as filesystems or + * socket connections before calling this function. For Cortex-M + * devices this function powers down generic system components such as + * the NVIC and set the vector table to that of the new image followed + * by jumping to the reset handler of the new image. + * + * @param address Starting address of next application to run + */ +void mbed_start_application(uintptr_t address); + +#ifdef __cplusplus +} +#endif +#endif + +#endif + +/** @}*/ diff --git a/platform/mbed_board.c b/platform/mbed_board.c index cbd67fad11..efa5f50f7d 100644 --- a/platform/mbed_board.c +++ b/platform/mbed_board.c @@ -75,16 +75,31 @@ void mbed_error_printf(const char* format, ...) { void mbed_error_vfprintf(const char * format, va_list arg) { #if DEVICE_SERIAL + +#if MBED_CONF_PLATFORM_STDIO_CONVERT_NEWLINES + char stdio_out_prev; +#endif + core_util_critical_section_enter(); char buffer[128]; int size = vsprintf(buffer, format, arg); if (size > 0) { if (!stdio_uart_inited) { - serial_init(&stdio_uart, STDIO_UART_TX, STDIO_UART_RX); + serial_init(&stdio_uart, STDIO_UART_TX, STDIO_UART_RX); } - for (int i = 0; i < size; i++) { +#if MBED_CONF_PLATFORM_STDIO_CONVERT_NEWLINES + for (unsigned int i = 0; i < size; i++) { + if (buffer[i] == '\n' && stdio_out_prev != '\r') { + serial_putc(&stdio_uart, '\r'); + } + serial_putc(&stdio_uart, buffer[i]); + stdio_out_prev = buffer[i]; + } +#else + for (unsigned int i = 0; i < size; i++) { serial_putc(&stdio_uart, buffer[i]); } +#endif } core_util_critical_section_exit(); #endif 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 0000000000..40414b0e2c --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL46Z/flash_api.c @@ -0,0 +1,101 @@ +/* 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 "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, + .sector_info_count = sizeof(sectors_info) / sizeof(sector_info_t) +}; + +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_KL27Z/spi_api.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/spi_api.c index 34affdc05e..c478db2485 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/spi_api.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/spi_api.c @@ -65,7 +65,7 @@ void spi_format(spi_t *obj, int bits, int mode, int slave) spi_master_config_t master_config; spi_slave_config_t slave_config; - if ((bits != 8) || (bits != 16)) { + if ((bits != 8) && (bits != 16)) { error("Only 8bits and 16bits SPI supported"); return; } diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/spi_api.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/spi_api.c index 34affdc05e..c478db2485 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/spi_api.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/spi_api.c @@ -65,7 +65,7 @@ void spi_format(spi_t *obj, int bits, int mode, int slave) spi_master_config_t master_config; spi_slave_config_t slave_config; - if ((bits != 8) || (bits != 16)) { + if ((bits != 8) && (bits != 16)) { error("Only 8bits and 16bits SPI supported"); return; } diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/TOOLCHAIN_ARM_STD/MK64FN1M0xxx12.sct b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/TOOLCHAIN_ARM_STD/MK64FN1M0xxx12.sct index edc93bb7ba..66557d071c 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/TOOLCHAIN_ARM_STD/MK64FN1M0xxx12.sct +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/TOOLCHAIN_ARM_STD/MK64FN1M0xxx12.sct @@ -60,14 +60,22 @@ #define __ram_vector_table_size__ 0x00000000 #endif -#define m_interrupts_start 0x00000000 +#if !defined(MBED_APP_START) + #define MBED_APP_START 0 +#endif + +#if !defined(MBED_APP_SIZE) + #define MBED_APP_SIZE 0x100000 +#endif + +#define m_interrupts_start MBED_APP_START #define m_interrupts_size 0x00000400 -#define m_flash_config_start 0x00000400 +#define m_flash_config_start MBED_APP_START + 0x400 #define m_flash_config_size 0x00000010 -#define m_text_start 0x00000410 -#define m_text_size 0x000FFBF0 +#define m_text_start MBED_APP_START + 0x410 +#define m_text_size MBED_APP_SIZE - 0x410 #define m_interrupts_ram_start 0x1FFF0000 #define m_interrupts_ram_size __ram_vector_table_size__ diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/TOOLCHAIN_GCC_ARM/MK64FN1M0xxx12.ld b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/TOOLCHAIN_GCC_ARM/MK64FN1M0xxx12.ld index 6fbe890f0c..327e9de61b 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/TOOLCHAIN_GCC_ARM/MK64FN1M0xxx12.ld +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/TOOLCHAIN_GCC_ARM/MK64FN1M0xxx12.ld @@ -63,6 +63,14 @@ __stack_size__ = 0x400; * heap and the page heap in uVisor applications. */ __heap_size__ = 0x6000; +#if !defined(MBED_APP_START) + #define MBED_APP_START 0 +#endif + +#if !defined(MBED_APP_SIZE) + #define MBED_APP_SIZE 0x100000 +#endif + HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x0400; STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400; M_VECTOR_RAM_SIZE = DEFINED(__ram_vector_table__) ? 0x0400 : 0x0; @@ -70,9 +78,9 @@ M_VECTOR_RAM_SIZE = DEFINED(__ram_vector_table__) ? 0x0400 : 0x0; /* Specify the memory areas */ MEMORY { - m_interrupts (RX) : ORIGIN = 0x00000000, LENGTH = 0x00000400 - m_flash_config (RX) : ORIGIN = 0x00000400, LENGTH = 0x00000010 - m_text (RX) : ORIGIN = 0x00000410, LENGTH = 0x000FFBF0 + m_interrupts (RX) : ORIGIN = MBED_APP_START, LENGTH = 0x400 + m_flash_config (RX) : ORIGIN = MBED_APP_START + 0x400, LENGTH = 0x10 + m_text (RX) : ORIGIN = MBED_APP_START + 0x410, LENGTH = MBED_APP_SIZE - 0x410 m_data (RW) : ORIGIN = 0x1FFF0000, LENGTH = 0x00010000 m_data_2 (RW) : ORIGIN = 0x20000000, LENGTH = 0x00030000 } diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/TOOLCHAIN_IAR/MK64FN1M0xxx12.icf b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/TOOLCHAIN_IAR/MK64FN1M0xxx12.icf index 86aa20f4ce..3f32a84320 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/TOOLCHAIN_IAR/MK64FN1M0xxx12.icf +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/TOOLCHAIN_IAR/MK64FN1M0xxx12.icf @@ -53,17 +53,25 @@ define symbol __ram_vector_table__ = 1; define symbol __stack_size__=0x8000; define symbol __heap_size__=0x10000; +if (!isdefinedsymbol(MBED_APP_START)) { + define symbol MBED_APP_START = 0; +} + +if (!isdefinedsymbol(MBED_APP_SIZE)) { + define symbol MBED_APP_SIZE = 0x100000; +} + define symbol __ram_vector_table_size__ = isdefinedsymbol(__ram_vector_table__) ? 0x00000400 : 0; define symbol __ram_vector_table_offset__ = isdefinedsymbol(__ram_vector_table__) ? 0x000003FF : 0; -define symbol m_interrupts_start = 0x00000000; -define symbol m_interrupts_end = 0x000003FF; +define symbol m_interrupts_start = MBED_APP_START; +define symbol m_interrupts_end = MBED_APP_START + 0x3FF; -define symbol m_flash_config_start = 0x00000400; -define symbol m_flash_config_end = 0x0000040F; +define symbol m_flash_config_start = MBED_APP_START + 0x400; +define symbol m_flash_config_end = MBED_APP_START + 0x40F; -define symbol m_text_start = 0x00000410; -define symbol m_text_end = 0x000FFFFF; +define symbol m_text_start = MBED_APP_START + 0x410; +define symbol m_text_end = MBED_APP_START + MBED_APP_SIZE - 1; define symbol m_interrupts_ram_start = 0x1FFF0000; define symbol m_interrupts_ram_end = 0x1FFF0000 + __ram_vector_table_offset__; 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 0000000000..d495281a96 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/flash_api.c @@ -0,0 +1,87 @@ +/* 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 "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 = 0x1, + .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, + .sector_info_count = sizeof(sectors_info) / sizeof(sector_info_t) +}; + +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_NORDIC/TARGET_NRF5/i2c_api.c b/targets/TARGET_NORDIC/TARGET_NRF5/i2c_api.c index 548aeebe9d..66063b4c49 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5/i2c_api.c +++ b/targets/TARGET_NORDIC/TARGET_NRF5/i2c_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 Nordic Semiconductor ASA + * Copyright (c) 2017 Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -43,8 +43,17 @@ #include "mbed_assert.h" #include "mbed_error.h" -#include "nrf_drv_twi.h" +#include "nrf_twi.h" +#include "nrf_drv_common.h" +#include "nrf_drv_config.h" #include "app_util_platform.h" +#include "nrf_gpio.h" +#include "nrf_delay.h" + +// An arbitrary value used as the counter in loops waiting for given event +// (e.g. STOPPED), needed to avoid infinite loops (and not involve any timers +// or tickers). +#define TIMEOUT_VALUE 1000 #if DEVICE_I2C_ASYNCH #define TWI_IDX(obj) ((obj)->i2c.twi_idx) @@ -54,59 +63,36 @@ #define TWI_INFO(obj) (&m_twi_info[TWI_IDX(obj)]) typedef struct { - bool initialized; - nrf_drv_twi_config_t config; - volatile bool transfer_finished; + bool initialized; + uint32_t pselsda; + uint32_t pselscl; + nrf_twi_frequency_t frequency; + bool start_twi; - #if DEVICE_I2C_ASYNCH - volatile uint32_t events; - void (*handler)(void); - uint32_t event_mask; - #endif +#if DEVICE_I2C_ASYNCH + volatile bool active; + uint8_t const *tx; + size_t tx_length; + uint8_t *rx; + size_t rx_length; + bool stop; + + volatile uint32_t events; + void (*handler)(void); + uint32_t evt_mask; +#endif // DEVICE_I2C_ASYNCH } twi_info_t; static twi_info_t m_twi_info[TWI_COUNT]; -static nrf_drv_twi_t const m_twi_instances[TWI_COUNT] = { +static NRF_TWI_Type * const m_twi_instances[TWI_COUNT] = { #if TWI0_ENABLED - NRF_DRV_TWI_INSTANCE(0), + NRF_TWI0, #endif #if TWI1_ENABLED - NRF_DRV_TWI_INSTANCE(1), + NRF_TWI1, #endif }; -static void twi_event_handler(nrf_drv_twi_evt_t const *event, void *context) -{ - twi_info_t * twi_info = TWI_INFO((i2c_t *)context); - twi_info->transfer_finished = true; - -#if DEVICE_I2C_ASYNCH - switch (event->type) { - case NRF_DRV_TWI_EVT_DONE: - twi_info->events |= I2C_EVENT_TRANSFER_COMPLETE; - break; - - case NRF_DRV_TWI_EVT_ADDRESS_NACK: - twi_info->events |= I2C_EVENT_ERROR_NO_SLAVE; - break; - - case NRF_DRV_TWI_EVT_DATA_NACK: - twi_info->events |= I2C_EVENT_ERROR; - break; - } - - if (twi_info->handler) { - twi_info->handler(); - } -#endif // DEVICE_I2C_ASYNCH -} - -static uint8_t twi_address(int i2c_address) -{ - // The TWI driver requires 7-bit slave address (without R/W bit). - return (i2c_address >> 1); -} - void SPI0_TWI0_IRQHandler(void); void SPI1_TWI1_IRQHandler(void); @@ -123,207 +109,580 @@ static const peripheral_handler_desc_t twi_handlers[TWI_COUNT] = SPI1_TWI1_IRQn, (uint32_t) SPI1_TWI1_IRQHandler } - #endif + #endif }; +#ifdef NRF51 + #define TWI_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#elif defined(NRF52) + #define TWI_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST +#endif + + +#if DEVICE_I2C_ASYNCH +static void start_asynch_rx(twi_info_t *twi_info, NRF_TWI_Type *twi) +{ + if (twi_info->rx_length == 1 && twi_info->stop) { + nrf_twi_shorts_set(twi, NRF_TWI_SHORT_BB_STOP_MASK); + } else { + nrf_twi_shorts_set(twi, NRF_TWI_SHORT_BB_SUSPEND_MASK); + } + nrf_twi_task_trigger(twi, NRF_TWI_TASK_STARTRX); +} + +static void twi_irq_handler(uint8_t instance_idx) +{ + twi_info_t *twi_info = &m_twi_info[instance_idx]; + + NRF_TWI_Type *twi = m_twi_instances[instance_idx]; + if (nrf_twi_event_check(twi, NRF_TWI_EVENT_ERROR)) { + nrf_twi_event_clear(twi, NRF_TWI_EVENT_ERROR); + + // In case of an error, force STOP. + // The current transfer may be suspended (if it is RX), so it must be + // resumed before the STOP task is triggered. + nrf_twi_task_trigger(twi, NRF_TWI_TASK_RESUME); + nrf_twi_task_trigger(twi, NRF_TWI_TASK_STOP); + + uint32_t errorsrc = nrf_twi_errorsrc_get_and_clear(twi); + twi_info->events |= I2C_EVENT_ERROR; + if (errorsrc & NRF_TWI_ERROR_ADDRESS_NACK) { + twi_info->events |= I2C_EVENT_ERROR_NO_SLAVE; + } + if (errorsrc & NRF_TWI_ERROR_DATA_NACK) { + twi_info->events |= I2C_EVENT_TRANSFER_EARLY_NACK; + } + } + + bool finished = false; + + if (nrf_twi_event_check(twi, NRF_TWI_EVENT_TXDSENT)) { + nrf_twi_event_clear(twi, NRF_TWI_EVENT_TXDSENT); + + MBED_ASSERT(twi_info->tx_length > 0); + --(twi_info->tx_length); + // Send next byte if there is still something to be sent. + if (twi_info->tx_length > 0) { + nrf_twi_txd_set(twi, *(twi_info->tx)); + ++(twi_info->tx); + // It TX is done, start RX if requested. + } else if (twi_info->rx_length > 0) { + start_asynch_rx(twi_info, twi); + // If there is nothing more to do, finalize the transfer. + } else { + if (twi_info->stop) { + nrf_twi_task_trigger(twi, NRF_TWI_TASK_STOP); + } else { + nrf_twi_task_trigger(twi, NRF_TWI_TASK_SUSPEND); + finished = true; + } + twi_info->events |= I2C_EVENT_TRANSFER_COMPLETE; + } + } + + if (nrf_twi_event_check(twi, NRF_TWI_EVENT_RXDREADY)) { + nrf_twi_event_clear(twi, NRF_TWI_EVENT_RXDREADY); + + MBED_ASSERT(twi_info->rx_length > 0); + *(twi_info->rx) = nrf_twi_rxd_get(twi); + ++(twi_info->rx); + --(twi_info->rx_length); + + if (twi_info->rx_length > 0) { + // If more bytes should be received, resume the transfer + // (in case the stop condition should be generated after the next + // byte, change the shortcuts configuration first). + if (twi_info->rx_length == 1 && twi_info->stop) { + nrf_twi_shorts_set(twi, NRF_TWI_SHORT_BB_STOP_MASK); + } + nrf_twi_task_trigger(twi, NRF_TWI_TASK_RESUME); + } else { + // If all requested bytes were received, finalize the transfer. + finished = true; + twi_info->events |= I2C_EVENT_TRANSFER_COMPLETE; + } + } + + if (finished || + nrf_twi_event_check(twi, NRF_TWI_EVENT_STOPPED) || + (nrf_twi_int_enable_check(twi, NRF_TWI_INT_SUSPENDED_MASK) && + nrf_twi_event_check(twi, NRF_TWI_EVENT_SUSPENDED))) { + // There is no need to clear the STOPPED and SUSPENDED events here, + // they will no longer generate the interrupt - see below. + + nrf_twi_shorts_set(twi, 0); + // Disable all interrupt sources. + nrf_twi_int_disable(twi, UINT32_MAX); + twi_info->active = false; + + if (twi_info->handler) { + twi_info->handler(); + } + } +} + +#if TWI0_ENABLED +static void irq_handler_twi0(void) +{ + twi_irq_handler(TWI0_INSTANCE_INDEX); +} +#endif +#if TWI1_ENABLED +static void irq_handler_twi1(void) +{ + twi_irq_handler(TWI1_INSTANCE_INDEX); +} +#endif +static nrf_drv_irq_handler_t const m_twi_irq_handlers[TWI_COUNT] = +{ +#if TWI0_ENABLED + irq_handler_twi0, +#endif +#if TWI1_ENABLED + irq_handler_twi1, +#endif +}; +#endif // DEVICE_I2C_ASYNCH + + +static void configure_twi_pin(uint32_t pin, nrf_gpio_pin_dir_t dir) +{ + nrf_gpio_cfg(pin, + dir, + NRF_GPIO_PIN_INPUT_CONNECT, + NRF_GPIO_PIN_PULLUP, + NRF_GPIO_PIN_S0D1, + NRF_GPIO_PIN_NOSENSE); +} + +static void twi_clear_bus(twi_info_t *twi_info) +{ + // Try to set SDA high, and check if no slave tries to drive it low. + nrf_gpio_pin_set(twi_info->pselsda); + configure_twi_pin(twi_info->pselsda, NRF_GPIO_PIN_DIR_OUTPUT); + // In case SDA is low, make up to 9 cycles on SCL line to help the slave + // that pulls SDA low release it. + if (!nrf_gpio_pin_read(twi_info->pselsda)) { + nrf_gpio_pin_set(twi_info->pselscl); + configure_twi_pin(twi_info->pselscl, NRF_GPIO_PIN_DIR_OUTPUT); + nrf_delay_us(4); + + for (int i = 0; i < 9; i++) { + if (nrf_gpio_pin_read(twi_info->pselsda)) { + break; + } + nrf_gpio_pin_clear(twi_info->pselscl); + nrf_delay_us(4); + nrf_gpio_pin_set(twi_info->pselscl); + nrf_delay_us(4); + } + + // Finally, generate STOP condition to put the bus into initial state. + nrf_gpio_pin_clear(twi_info->pselsda); + nrf_delay_us(4); + nrf_gpio_pin_set(twi_info->pselsda); + } +} void i2c_init(i2c_t *obj, PinName sda, PinName scl) { int i; for (i = 0; i < TWI_COUNT; ++i) { if (m_twi_info[i].initialized && - m_twi_info[i].config.sda == (uint32_t)sda && - m_twi_info[i].config.scl == (uint32_t)scl) { + m_twi_info[i].pselsda == (uint32_t)sda && + m_twi_info[i].pselscl == (uint32_t)scl) { TWI_IDX(obj) = i; - TWI_INFO(obj)->config.frequency = NRF_TWI_FREQ_100K; + TWI_INFO(obj)->frequency = NRF_TWI_FREQ_100K; i2c_reset(obj); return; } } - nrf_drv_twi_config_t const config = { - .scl = scl, - .sda = sda, - .frequency = NRF_TWI_FREQ_100K, -#ifdef NRF51 - .interrupt_priority = APP_IRQ_PRIORITY_LOW -#elif defined(NRF52) - .interrupt_priority = APP_IRQ_PRIORITY_LOWEST -#endif - - }; - for (i = 0; i < TWI_COUNT; ++i) { if (!m_twi_info[i].initialized) { + TWI_IDX(obj) = i; + twi_info_t *twi_info = TWI_INFO(obj); + twi_info->initialized = true; + twi_info->pselsda = (uint32_t)sda; + twi_info->pselscl = (uint32_t)scl; + twi_info->frequency = NRF_TWI_FREQ_100K; + twi_info->start_twi = false; +#if DEVICE_I2C_ASYNCH + twi_info->active = false; +#endif + + twi_clear_bus(twi_info); + + configure_twi_pin(twi_info->pselsda, NRF_GPIO_PIN_DIR_INPUT); + configure_twi_pin(twi_info->pselscl, NRF_GPIO_PIN_DIR_INPUT); + + i2c_reset(obj); + +#if DEVICE_I2C_ASYNCH + nrf_drv_common_per_res_acquire(m_twi_instances[i], + m_twi_irq_handlers[i]); NVIC_SetVector(twi_handlers[i].IRQn, twi_handlers[i].vector); + nrf_drv_common_irq_enable(twi_handlers[i].IRQn, TWI_IRQ_PRIORITY); +#endif - nrf_drv_twi_t const *twi = &m_twi_instances[i]; - ret_code_t ret_code = - nrf_drv_twi_init(twi, &config, twi_event_handler, obj); - if (ret_code == NRF_SUCCESS) { - TWI_IDX(obj) = i; - TWI_INFO(obj)->initialized = true; - TWI_INFO(obj)->config = config; - - nrf_drv_twi_enable(twi); - return; - } + return; } } - // No available peripheral error("No available I2C peripheral\r\n"); } void i2c_reset(i2c_t *obj) { twi_info_t *twi_info = TWI_INFO(obj); - nrf_drv_twi_t const *twi = &m_twi_instances[TWI_IDX(obj)]; + NRF_TWI_Type *twi = m_twi_instances[TWI_IDX(obj)]; - nrf_drv_twi_uninit(twi); - nrf_drv_twi_init(twi, &twi_info->config, twi_event_handler, obj); - nrf_drv_twi_enable(twi); + nrf_twi_disable(twi); + nrf_twi_pins_set(twi, twi_info->pselscl, twi_info->pselsda); + nrf_twi_frequency_set(twi, twi_info->frequency); + nrf_twi_enable(twi); } int i2c_start(i2c_t *obj) { - (void)obj; + twi_info_t *twi_info = TWI_INFO(obj); +#if DEVICE_I2C_ASYNCH + if (twi_info->active) { + return I2C_ERROR_BUS_BUSY; + } +#endif + twi_info->start_twi = true; - return -1; // Not implemented. + return 0; } int i2c_stop(i2c_t *obj) { - (void)obj; + NRF_TWI_Type *twi = m_twi_instances[TWI_IDX(obj)]; - return -1; // Not implemented. + // The current transfer may be suspended (if it is RX), so it must be + // resumed before the STOP task is triggered. + nrf_twi_task_trigger(twi, NRF_TWI_TASK_RESUME); + nrf_twi_task_trigger(twi, NRF_TWI_TASK_STOP); + uint32_t remaining_time = TIMEOUT_VALUE; + do { + if (nrf_twi_event_check(twi, NRF_TWI_EVENT_STOPPED)) { + return 0; + } + } while (--remaining_time); + + return 1; } void i2c_frequency(i2c_t *obj, int hz) { twi_info_t *twi_info = TWI_INFO(obj); - nrf_drv_twi_t const *twi = &m_twi_instances[TWI_IDX(obj)]; + NRF_TWI_Type *twi = m_twi_instances[TWI_IDX(obj)]; if (hz < 250000) { - twi_info->config.frequency = NRF_TWI_FREQ_100K; + twi_info->frequency = NRF_TWI_FREQ_100K; } else if (hz < 400000) { - twi_info->config.frequency = NRF_TWI_FREQ_250K; + twi_info->frequency = NRF_TWI_FREQ_250K; } else { - twi_info->config.frequency = NRF_TWI_FREQ_400K; + twi_info->frequency = NRF_TWI_FREQ_400K; } - nrf_twi_frequency_set(twi->reg.p_twi, twi_info->config.frequency); + nrf_twi_frequency_set(twi, twi_info->frequency); +} + +static uint8_t twi_address(int i2c_address) +{ + // The TWI peripheral requires 7-bit slave address (without R/W bit). + return (i2c_address >> 1); +} + +static void start_twi_read(NRF_TWI_Type *twi, int address) +{ + nrf_twi_event_clear(twi, NRF_TWI_EVENT_STOPPED); + nrf_twi_event_clear(twi, NRF_TWI_EVENT_RXDREADY); + nrf_twi_event_clear(twi, NRF_TWI_EVENT_ERROR); + (void)nrf_twi_errorsrc_get_and_clear(twi); + + nrf_twi_shorts_set(twi, NRF_TWI_SHORT_BB_SUSPEND_MASK); + + nrf_twi_address_set(twi, twi_address(address)); + nrf_twi_task_trigger(twi, NRF_TWI_TASK_RESUME); + nrf_twi_task_trigger(twi, NRF_TWI_TASK_STARTRX); } int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { - (void)stop; + // Zero-length RX transfers are not supported. Such transfers cannot + // be easily achieved with TWI peripheral (some dirty tricks would be + // required for this), and they are actually useless (TX can be used + // to check if the address is acknowledged by a slave). + MBED_ASSERT(length > 0); twi_info_t *twi_info = TWI_INFO(obj); - nrf_drv_twi_t const *twi = &m_twi_instances[TWI_IDX(obj)]; - - twi_info->transfer_finished = false; - ret_code_t ret_code = nrf_drv_twi_rx(twi, twi_address(address), - (uint8_t *)data, length); - if (ret_code != NRF_SUCCESS) { - return 0; +#if DEVICE_I2C_ASYNCH + if (twi_info->active) { + return I2C_ERROR_BUS_BUSY; } - while (!twi_info->transfer_finished) {} - return nrf_drv_twi_data_count_get(twi); +#endif + twi_info->start_twi = false; + + NRF_TWI_Type *twi = m_twi_instances[TWI_IDX(obj)]; + start_twi_read(twi, address); + + int result = length; + while (length > 0) { + int byte_read_result = i2c_byte_read(obj, (stop && length == 1)); + if (byte_read_result < 0) { + // When an error occurs, return the number of bytes that have been + // received successfully. + result -= length; + // Force STOP condition. + stop = 1; + break; + } + *data++ = (uint8_t)byte_read_result; + --length; + } + + if (stop) { + (void)i2c_stop(obj); + } + + return result; +} + +static uint8_t twi_byte_write(NRF_TWI_Type *twi, uint8_t data) +{ + nrf_twi_event_clear(twi, NRF_TWI_EVENT_TXDSENT); + nrf_twi_event_clear(twi, NRF_TWI_EVENT_ERROR); + + nrf_twi_txd_set(twi, data); + uint32_t remaining_time = TIMEOUT_VALUE; + do { + if (nrf_twi_event_check(twi, NRF_TWI_EVENT_TXDSENT)) { + nrf_twi_event_clear(twi, NRF_TWI_EVENT_TXDSENT); + return 1; // ACK received + } + if (nrf_twi_event_check(twi, NRF_TWI_EVENT_ERROR)) { + nrf_twi_event_clear(twi, NRF_TWI_EVENT_ERROR); + return 0; // some error occurred + } + } while (--remaining_time); + + return 2; // timeout; +} + +static void start_twi_write(NRF_TWI_Type *twi, int address) +{ + nrf_twi_event_clear(twi, NRF_TWI_EVENT_STOPPED); + nrf_twi_event_clear(twi, NRF_TWI_EVENT_TXDSENT); + nrf_twi_event_clear(twi, NRF_TWI_EVENT_ERROR); + (void)nrf_twi_errorsrc_get_and_clear(twi); + + nrf_twi_shorts_set(twi, 0); + + nrf_twi_address_set(twi, twi_address(address)); + nrf_twi_task_trigger(twi, NRF_TWI_TASK_RESUME); + nrf_twi_task_trigger(twi, NRF_TWI_TASK_STARTTX); } int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { twi_info_t *twi_info = TWI_INFO(obj); - nrf_drv_twi_t const *twi = &m_twi_instances[TWI_IDX(obj)]; - - twi_info->transfer_finished = false; - ret_code_t ret_code = nrf_drv_twi_tx(twi, twi_address(address), - (uint8_t const *)data, length, (stop == 0)); - if (ret_code != NRF_SUCCESS) { - return 0; +#if DEVICE_I2C_ASYNCH + if (twi_info->active) { + return I2C_ERROR_BUS_BUSY; } - while (!twi_info->transfer_finished) {} - return nrf_drv_twi_data_count_get(twi); +#endif + twi_info->start_twi = false; + + NRF_TWI_Type *twi = m_twi_instances[TWI_IDX(obj)]; + start_twi_write(twi, address); + + // Special case - transaction with no data. + // It can be used to check if a slave acknowledges the address. + if (length == 0) { + nrf_twi_event_t event; + if (stop) { + event = NRF_TWI_EVENT_STOPPED; + nrf_twi_task_trigger(twi, NRF_TWI_TASK_STOP); + } else { + event = NRF_TWI_EVENT_SUSPENDED; + nrf_twi_event_clear(twi, event); + nrf_twi_task_trigger(twi, NRF_TWI_TASK_SUSPEND); + } + uint32_t remaining_time = TIMEOUT_VALUE; + do { + if (nrf_twi_event_check(twi, event)) { + break; + } + } while (--remaining_time); + + uint32_t errorsrc = nrf_twi_errorsrc_get_and_clear(twi); + if (errorsrc & NRF_TWI_ERROR_ADDRESS_NACK) { + if (!stop) { + i2c_stop(obj); + } + return I2C_ERROR_NO_SLAVE; + } + + return (remaining_time ? 0 : I2C_ERROR_BUS_BUSY); + } + + int result = length; + do { + uint8_t byte_write_result = twi_byte_write(twi, (uint8_t)*data++); + if (byte_write_result != 1) { + if (byte_write_result == 0) { + // Check what kind of error has been signaled by TWI. + uint32_t errorsrc = nrf_twi_errorsrc_get_and_clear(twi); + if (errorsrc & NRF_TWI_ERROR_ADDRESS_NACK) { + result = I2C_ERROR_NO_SLAVE; + } else { + // Some other error - return the number of bytes that + // have been sent successfully. + result -= length; + } + } else { + result = I2C_ERROR_BUS_BUSY; + } + // Force STOP condition. + stop = 1; + break; + } + --length; + } while (length > 0); + + if (stop) { + (void)i2c_stop(obj); + } + + return result; } int i2c_byte_read(i2c_t *obj, int last) { - (void)obj; - (void)last; + NRF_TWI_Type *twi = m_twi_instances[TWI_IDX(obj)]; - return -1; // Not implemented. + if (last) { + nrf_twi_shorts_set(twi, NRF_TWI_SHORT_BB_STOP_MASK); + } + nrf_twi_task_trigger(twi, NRF_TWI_TASK_RESUME); + + uint32_t remaining_time = TIMEOUT_VALUE; + do { + if (nrf_twi_event_check(twi, NRF_TWI_EVENT_RXDREADY)) { + nrf_twi_event_clear(twi, NRF_TWI_EVENT_RXDREADY); + return nrf_twi_rxd_get(twi); + } + if (nrf_twi_event_check(twi, NRF_TWI_EVENT_ERROR)) { + nrf_twi_event_clear(twi, NRF_TWI_EVENT_ERROR); + return I2C_ERROR_NO_SLAVE; + } + } while (--remaining_time); + + return I2C_ERROR_BUS_BUSY; } int i2c_byte_write(i2c_t *obj, int data) { - (void)obj; - (void)data; + NRF_TWI_Type *twi = m_twi_instances[TWI_IDX(obj)]; + twi_info_t *twi_info = TWI_INFO(obj); + if (twi_info->start_twi) { + twi_info->start_twi = false; - return -1; // Not implemented. + if (data & 1) { + start_twi_read(twi, data); + } else { + start_twi_write(twi, data); + } + return 1; + } else { + nrf_twi_task_trigger(twi, NRF_TWI_TASK_RESUME); + // 0 - TWI signaled error (NAK is the only possibility here) + // 1 - ACK received + // 2 - timeout (clock stretched for too long?) + return twi_byte_write(twi, (uint8_t)data); + } } #if DEVICE_I2C_ASYNCH - void i2c_transfer_asynch(i2c_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length, uint32_t address, uint32_t stop, uint32_t handler, uint32_t event, DMAUsage hint) { - (void)stop; (void)hint; - if (i2c_active(obj)) { - return; - } - if ((tx_length == 0) && (rx_length == 0)) { - return; - } - twi_info_t *twi_info = TWI_INFO(obj); - twi_info->events = 0; - twi_info->handler = (void (*)(void))handler; - twi_info->event_mask = event; + if (twi_info->active) { + return; + } + twi_info->active = true; + twi_info->events = 0; + twi_info->handler = (void (*)(void))handler; + twi_info->evt_mask = event; + twi_info->tx_length = tx_length; + twi_info->tx = tx; + twi_info->rx_length = rx_length; + twi_info->rx = rx; + twi_info->stop = stop; - uint8_t twi_addr = twi_address(address); - nrf_drv_twi_t const *twi = &m_twi_instances[TWI_IDX(obj)]; + NRF_TWI_Type *twi = m_twi_instances[TWI_IDX(obj)]; - if ((tx_length > 0) && (rx_length == 0)) { - nrf_drv_twi_xfer_desc_t const xfer = - NRF_DRV_TWI_XFER_DESC_TX(twi_addr, (uint8_t *)tx, tx_length); - nrf_drv_twi_xfer(twi, &xfer, - stop ? 0 : NRF_DRV_TWI_FLAG_TX_NO_STOP); - } - else if ((tx_length == 0) && (rx_length > 0)) { - nrf_drv_twi_xfer_desc_t const xfer = - NRF_DRV_TWI_XFER_DESC_RX(twi_addr, rx, rx_length); - nrf_drv_twi_xfer(twi, &xfer, 0); - } - else if ((tx_length > 0) && (rx_length > 0)) { - nrf_drv_twi_xfer_desc_t const xfer = - NRF_DRV_TWI_XFER_DESC_TXRX(twi_addr, - (uint8_t *)tx, tx_length, rx, rx_length); - nrf_drv_twi_xfer(twi, &xfer, 0); + nrf_twi_event_clear(twi, NRF_TWI_EVENT_TXDSENT); + nrf_twi_event_clear(twi, NRF_TWI_EVENT_RXDREADY); + nrf_twi_event_clear(twi, NRF_TWI_EVENT_STOPPED); + nrf_twi_event_clear(twi, NRF_TWI_EVENT_SUSPENDED); + nrf_twi_event_clear(twi, NRF_TWI_EVENT_ERROR); + (void)nrf_twi_errorsrc_get_and_clear(twi); + + nrf_twi_address_set(twi, twi_address(address)); + nrf_twi_task_trigger(twi, NRF_TWI_TASK_RESUME); + // TX only, or TX + RX (after a repeated start). + if (tx_length > 0) { + nrf_twi_task_trigger(twi, NRF_TWI_TASK_STARTTX); + nrf_twi_txd_set(twi, *(twi_info->tx)); + ++(twi_info->tx); + // RX only. + } else if (rx_length > 0) { + start_asynch_rx(twi_info, twi); + // Both 'tx_length' and 'rx_length' are 0 - this case may be used + // to test if the slave is presentand ready for transfer (by just + // sending the address and checking if it is acknowledged). + } else { + nrf_twi_task_trigger(twi, NRF_TWI_TASK_STARTTX); + if (stop) { + nrf_twi_task_trigger(twi, NRF_TWI_TASK_STOP); + } else { + nrf_twi_task_trigger(twi, NRF_TWI_TASK_SUSPEND); + nrf_twi_int_enable(twi, NRF_TWI_INT_SUSPENDED_MASK); + } + twi_info->events |= I2C_EVENT_TRANSFER_COMPLETE; } + + nrf_twi_int_enable(twi, NRF_TWI_INT_TXDSENT_MASK | + NRF_TWI_INT_RXDREADY_MASK | + NRF_TWI_INT_STOPPED_MASK | + NRF_TWI_INT_ERROR_MASK); } uint32_t i2c_irq_handler_asynch(i2c_t *obj) { twi_info_t *twi_info = TWI_INFO(obj); - return (twi_info->events & twi_info->event_mask); + return (twi_info->events & twi_info->evt_mask); } uint8_t i2c_active(i2c_t *obj) { - nrf_drv_twi_t const *twi = &m_twi_instances[TWI_IDX(obj)]; - return nrf_drv_twi_is_busy(twi); + twi_info_t *twi_info = TWI_INFO(obj); + return twi_info->active; } void i2c_abort_asynch(i2c_t *obj) { i2c_reset(obj); } - #endif // DEVICE_I2C_ASYNCH #endif // DEVICE_I2C diff --git a/targets/TARGET_NORDIC/TARGET_NRF5/sdk/drivers_nrf/twi_master/nrf_drv_twi.c b/targets/TARGET_NORDIC/TARGET_NRF5/sdk/drivers_nrf/twi_master/nrf_drv_twi.c deleted file mode 100644 index a70c39e73d..0000000000 --- a/targets/TARGET_NORDIC/TARGET_NRF5/sdk/drivers_nrf/twi_master/nrf_drv_twi.c +++ /dev/null @@ -1,1005 +0,0 @@ -/* - * Copyright (c) 2015 Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list - * of conditions and the following disclaimer. - * - * 2. Redistributions in binary form, except as embedded into a Nordic Semiconductor ASA - * integrated circuit in a product or a software update for such product, must reproduce - * the above copyright notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific prior - * written permission. - * - * 4. This software, with or without modification, must only be used with a - * Nordic Semiconductor ASA integrated circuit. - * - * 5. Any software provided in binary or object form under this license must not be reverse - * engineered, decompiled, modified and/or disassembled. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - - -#include "nrf_drv_twi.h" -#include "nrf_drv_common.h" -#include "nrf_gpio.h" -#include "nrf_assert.h" -#include "app_util_platform.h" -#include "nrf_delay.h" - -#include - -#define TWI0_IRQ_HANDLER SPI0_TWI0_IRQHandler -#define TWI1_IRQ_HANDLER SPI1_TWI1_IRQHandler - -#if (defined(TWIM_IN_USE) && defined(TWI_IN_USE)) - // TWIM and TWI combined - #define CODE_FOR_TWIM(code) if (p_instance->use_easy_dma) { code } - #define CODE_FOR_TWI(code) else { code } -#elif (defined(TWIM_IN_USE) && !defined(TWI_IN_USE)) - // TWIM only - #define CODE_FOR_TWIM(code) { code } - #define CODE_FOR_TWI(code) -#elif (!defined(TWIM_IN_USE) && defined(TWI_IN_USE)) - // TWI only - #define CODE_FOR_TWIM(code) - #define CODE_FOR_TWI(code) { code } -#else - #error "Wrong configuration." -#endif - -// All interrupt flags -#define DISABLE_ALL 0xFFFFFFFF - -#define SCL_PIN_CONF ((GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) \ - | (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) \ - | (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) \ - | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) \ - | (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos)) - -#define SDA_PIN_CONF SCL_PIN_CONF - -#define SCL_PIN_CONF_CLR ((GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) \ - | (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) \ - | (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) \ - | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) \ - | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos)) - -#define SDA_PIN_CONF_CLR SCL_PIN_CONF_CLR - -// Control block - driver instance local data. -typedef struct -{ - nrf_drv_twi_evt_handler_t handler; - void * p_context; - volatile uint32_t int_mask; - nrf_drv_twi_xfer_desc_t xfer_desc; - uint32_t flags; - uint8_t * p_curr_buf; - uint8_t curr_length; - bool curr_no_stop; - nrf_drv_state_t state; - bool error; - volatile bool busy; - bool repeated; - uint8_t bytes_transferred; -} twi_control_block_t; - -static twi_control_block_t m_cb[TWI_COUNT]; - -static nrf_drv_twi_config_t const m_default_config[TWI_COUNT] = { -#if TWI0_ENABLED - NRF_DRV_TWI_DEFAULT_CONFIG(0), -#endif -#if TWI1_ENABLED - NRF_DRV_TWI_DEFAULT_CONFIG(1), -#endif -}; - -#if PERIPHERAL_RESOURCE_SHARING_ENABLED - #define IRQ_HANDLER_NAME(n) irq_handler_for_instance_##n - #define IRQ_HANDLER(n) static void IRQ_HANDLER_NAME(n)(void) - - #if TWI0_ENABLED - IRQ_HANDLER(0); - #endif - #if TWI1_ENABLED - IRQ_HANDLER(1); - #endif - static nrf_drv_irq_handler_t const m_irq_handlers[TWI_COUNT] = { - #if TWI0_ENABLED - IRQ_HANDLER_NAME(0), - #endif - #if TWI1_ENABLED - IRQ_HANDLER_NAME(1), - #endif - }; -#else - #define IRQ_HANDLER(n) void SPI##n##_TWI##n##_IRQHandler(void) -#endif // PERIPHERAL_RESOURCE_SHARING_ENABLED - -static void twi_clear_bus(nrf_drv_twi_t const * const p_instance, - nrf_drv_twi_config_t const * p_config) -{ - NRF_GPIO->PIN_CNF[p_config->scl] = SCL_PIN_CONF; - NRF_GPIO->PIN_CNF[p_config->sda] = SDA_PIN_CONF; - - nrf_gpio_pin_set(p_config->scl); - nrf_gpio_pin_set(p_config->sda); - - NRF_GPIO->PIN_CNF[p_config->scl] = SCL_PIN_CONF_CLR; - NRF_GPIO->PIN_CNF[p_config->sda] = SDA_PIN_CONF_CLR; - - nrf_delay_us(4); - - for(int i = 0; i < 9; i++) - { - if (nrf_gpio_pin_read(p_config->sda)) - { - if(i == 0) - { - return; - } - else - { - break; - } - } - nrf_gpio_pin_clear(p_config->scl); - nrf_delay_us(4); - nrf_gpio_pin_set(p_config->scl); - nrf_delay_us(4); - } - nrf_gpio_pin_clear(p_config->sda); - nrf_delay_us(4); - nrf_gpio_pin_set(p_config->sda); -} - -ret_code_t nrf_drv_twi_init(nrf_drv_twi_t const * p_instance, - nrf_drv_twi_config_t const * p_config, - nrf_drv_twi_evt_handler_t event_handler, - void * p_context) -{ - twi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; - - if (p_cb->state != NRF_DRV_STATE_UNINITIALIZED) - { - return NRF_ERROR_INVALID_STATE; - } - - if (p_config == NULL) - { - p_config = &m_default_config[p_instance->drv_inst_idx]; - } - -#if PERIPHERAL_RESOURCE_SHARING_ENABLED - if (nrf_drv_common_per_res_acquire(p_instance->reg.p_twi, - m_irq_handlers[p_instance->drv_inst_idx]) != NRF_SUCCESS) - { - return NRF_ERROR_BUSY; - } -#endif // PERIPHERAL_RESOURCE_SHARING_ENABLED - - p_cb->handler = event_handler; - p_cb->p_context = p_context; - p_cb->int_mask = 0; - p_cb->repeated = false; - p_cb->busy = false; - - twi_clear_bus(p_instance, p_config); - - /* To secure correct signal levels on the pins used by the TWI - master when the system is in OFF mode, and when the TWI master is - disabled, these pins must be configured in the GPIO peripheral. - */ - NRF_GPIO->PIN_CNF[p_config->scl] = SCL_PIN_CONF; - NRF_GPIO->PIN_CNF[p_config->sda] = SDA_PIN_CONF; - - CODE_FOR_TWIM - ( - NRF_TWIM_Type * p_twim = p_instance->reg.p_twim; - nrf_twim_pins_set(p_twim, p_config->scl, p_config->sda); - nrf_twim_frequency_set(p_twim, - (nrf_twim_frequency_t)p_config->frequency); - ) - CODE_FOR_TWI - ( - NRF_TWI_Type * p_twi = p_instance->reg.p_twi; - nrf_twi_pins_set(p_twi, p_config->scl, p_config->sda); - nrf_twi_frequency_set(p_twi, - (nrf_twi_frequency_t)p_config->frequency); - ) - - if (p_cb->handler) - { - CODE_FOR_TWIM - ( - nrf_drv_common_irq_enable(nrf_drv_get_IRQn((void *)p_instance->reg.p_twim), - p_config->interrupt_priority); - ) - CODE_FOR_TWI - ( - nrf_drv_common_irq_enable(nrf_drv_get_IRQn((void *)p_instance->reg.p_twi), - p_config->interrupt_priority); - ) - } - - p_cb->state = NRF_DRV_STATE_INITIALIZED; - - return NRF_SUCCESS; -} - -void nrf_drv_twi_uninit(nrf_drv_twi_t const * p_instance) -{ - twi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; - ASSERT(p_cb->state != NRF_DRV_STATE_UNINITIALIZED); - - if (p_cb->handler) - { - CODE_FOR_TWIM - ( - nrf_drv_common_irq_disable(nrf_drv_get_IRQn((void *)p_instance->reg.p_twim)); - ) - CODE_FOR_TWI - ( - nrf_drv_common_irq_disable(nrf_drv_get_IRQn((void *)p_instance->reg.p_twi)); - ) - } - nrf_drv_twi_disable(p_instance); - -#if PERIPHERAL_RESOURCE_SHARING_ENABLED - nrf_drv_common_per_res_release(p_instance->reg.p_twi); -#endif - - p_cb->state = NRF_DRV_STATE_UNINITIALIZED; -} - -void nrf_drv_twi_enable(nrf_drv_twi_t const * p_instance) -{ - twi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; - ASSERT(p_cb->state == NRF_DRV_STATE_INITIALIZED); - - CODE_FOR_TWIM - ( - NRF_TWIM_Type * p_twim = p_instance->reg.p_twim; - - nrf_twim_enable(p_twim); - ) - CODE_FOR_TWI - ( - NRF_TWI_Type * p_twi = p_instance->reg.p_twi; - - nrf_twi_enable(p_twi); - ) - - p_cb->state = NRF_DRV_STATE_POWERED_ON; -} - -void nrf_drv_twi_disable(nrf_drv_twi_t const * p_instance) -{ - twi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; - ASSERT(p_cb->state != NRF_DRV_STATE_UNINITIALIZED); - - CODE_FOR_TWIM - ( - NRF_TWIM_Type * p_twim = p_instance->reg.p_twim; - p_cb->int_mask = 0; - nrf_twim_int_disable(p_twim, DISABLE_ALL); - nrf_twim_shorts_disable(p_twim, DISABLE_ALL); - nrf_twim_disable(p_twim); - ) - CODE_FOR_TWI - ( - NRF_TWI_Type * p_twi = p_instance->reg.p_twi; - nrf_twi_int_disable(p_twi, DISABLE_ALL); - nrf_twi_shorts_disable(p_twi, DISABLE_ALL); - nrf_twi_disable(p_twi); - ) - - p_cb->state = NRF_DRV_STATE_INITIALIZED; -} - -#ifdef TWI_IN_USE -static bool twi_send_byte(NRF_TWI_Type * p_twi, - uint8_t const * p_data, - uint8_t length, - uint8_t * p_bytes_transferred, - bool no_stop) -{ - if (*p_bytes_transferred < length) - { - nrf_twi_txd_set(p_twi, p_data[*p_bytes_transferred]); - ++(*p_bytes_transferred); - } - else - { - if (no_stop) - { - nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_SUSPEND); - return false; - } - else - { - nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_STOP); - } - } - return true; -} - -static void twi_receive_byte(NRF_TWI_Type * p_twi, - uint8_t * p_data, - uint8_t length, - uint8_t * p_bytes_transferred) -{ - if (*p_bytes_transferred < length) - { - p_data[*p_bytes_transferred] = nrf_twi_rxd_get(p_twi); - - ++(*p_bytes_transferred); - - if (*p_bytes_transferred == length-1) - { - nrf_twi_shorts_set(p_twi, NRF_TWI_SHORT_BB_STOP_MASK); - } - else if (*p_bytes_transferred == length) - { - return; - } - - nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_RESUME); - } -} - -static bool twi_transfer(NRF_TWI_Type * p_twi, - bool * p_error, - uint8_t * p_bytes_transferred, - uint8_t * p_data, - uint8_t length, - bool no_stop) -{ - bool do_stop_check; - - if ((*p_error == true) || (*p_bytes_transferred == length)) - { - do_stop_check = true; - } - else - { - do_stop_check = false; - } - - if (*p_error) - { - nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_ERROR); - nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_TXDSENT); - nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_RXDREADY); - } - else if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_ERROR)) - { - nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_ERROR); - nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_STOP); - *p_error = true; - } - else - { - if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_TXDSENT)) - { - nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_TXDSENT); - if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_ERROR)) - { - nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_ERROR); - nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_STOP); - *p_error = true; - } - else - { - if (!twi_send_byte(p_twi, p_data, length, p_bytes_transferred, no_stop)) - { - return false; - } - } - } - else if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_RXDREADY)) - { - nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_RXDREADY); - if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_ERROR)) - { - nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_ERROR); - nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_STOP); - *p_error = true; - } - else - { - twi_receive_byte(p_twi, p_data, length, p_bytes_transferred); - } - } - } - - if (do_stop_check && nrf_twi_event_check(p_twi, NRF_TWI_EVENT_STOPPED)) - { - nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_STOPPED); - return false; - } - - return true; -} - -static ret_code_t twi_tx_start_transfer(twi_control_block_t * p_cb, - NRF_TWI_Type * p_twi, - uint8_t const * p_data, - uint8_t length, - bool no_stop) -{ - ret_code_t ret_code = NRF_SUCCESS; - - nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_STOPPED); - nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_ERROR); - nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_TXDSENT); - nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_RXDREADY); - nrf_twi_shorts_set(p_twi, 0); - - p_cb->bytes_transferred = 0; - p_cb->error = false; - - // In case TWI is suspended resume its operation. - nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_RESUME); - nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_STARTTX); - - (void)twi_send_byte(p_twi, p_data, length, &p_cb->bytes_transferred, no_stop); - - if (p_cb->handler) - { - p_cb->int_mask = NRF_TWI_INT_STOPPED_MASK | - NRF_TWI_INT_ERROR_MASK | - NRF_TWI_INT_TXDSENT_MASK | - NRF_TWI_INT_RXDREADY_MASK; - nrf_twi_int_enable(p_twi, p_cb->int_mask); - } - else - { - while (twi_transfer(p_twi, &p_cb->error, &p_cb->bytes_transferred, (uint8_t *)p_data, length, no_stop)) - {} - - if (p_cb->error) - { - ret_code = NRF_ERROR_INTERNAL; - } - } - return ret_code; -} - -static ret_code_t twi_rx_start_transfer(twi_control_block_t * p_cb, - NRF_TWI_Type * p_twi, - uint8_t const * p_data, - uint8_t length) -{ - ret_code_t ret_code = NRF_SUCCESS; - - nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_STOPPED); - nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_ERROR); - nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_TXDSENT); - nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_RXDREADY); - - p_cb->bytes_transferred = 0; - p_cb->error = false; - - if (length == 1) - { - nrf_twi_shorts_set(p_twi, NRF_TWI_SHORT_BB_STOP_MASK); - } - else - { - nrf_twi_shorts_set(p_twi, NRF_TWI_SHORT_BB_SUSPEND_MASK); - } - // In case TWI is suspended resume its operation. - nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_RESUME); - nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_STARTRX); - - if (p_cb->handler) - { - p_cb->int_mask = NRF_TWI_INT_STOPPED_MASK | - NRF_TWI_INT_ERROR_MASK | - NRF_TWI_INT_TXDSENT_MASK | - NRF_TWI_INT_RXDREADY_MASK; - nrf_twi_int_enable(p_twi, p_cb->int_mask); - } - else - { - while (twi_transfer(p_twi, &p_cb->error, &p_cb->bytes_transferred, (uint8_t*)p_data, length, false)) - {} - - if (p_cb->error) - { - ret_code = NRF_ERROR_INTERNAL; - } - } - return ret_code; -} - -__STATIC_INLINE ret_code_t twi_xfer(twi_control_block_t * p_cb, - NRF_TWI_Type * p_twi, - nrf_drv_twi_xfer_desc_t const * p_xfer_desc, - uint32_t flags) -{ - ret_code_t ret = NRF_SUCCESS; - - /* Block TWI interrupts to ensure that function is not interrupted by TWI interrupt. */ - nrf_twi_int_disable(p_twi, DISABLE_ALL); - - if (p_cb->busy) - { - nrf_twi_int_enable(p_twi, p_cb->int_mask); - return NRF_ERROR_BUSY; - } - else - { - p_cb->busy = (NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER & flags) ? false : true; - } - - if (flags & NRF_DRV_TWI_FLAG_HOLD_XFER) - { - return NRF_ERROR_NOT_SUPPORTED; - } - - p_cb->flags = flags; - p_cb->xfer_desc = *p_xfer_desc; - p_cb->curr_length = p_xfer_desc->primary_length; - p_cb->p_curr_buf = p_xfer_desc->p_primary_buf; - nrf_twi_address_set(p_twi, p_xfer_desc->address); - - if (p_xfer_desc->type != NRF_DRV_TWI_XFER_RX) - { - p_cb->curr_no_stop = ((p_xfer_desc->type == NRF_DRV_TWI_XFER_TX) && - !(flags & NRF_DRV_TWI_FLAG_TX_NO_STOP)) ? false : true; - ret = twi_tx_start_transfer(p_cb, p_twi, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length, p_cb->curr_no_stop); - } - else - { - p_cb->curr_no_stop = false; - ret = twi_rx_start_transfer(p_cb, p_twi, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length); - } - if (p_cb->handler == NULL) - { - p_cb->busy = false; - } - return ret; -} -#endif - -#ifdef TWIM_IN_USE -__STATIC_INLINE void twim_list_enable_handle(NRF_TWIM_Type * p_twim, uint32_t flags) -{ - if (NRF_DRV_TWI_FLAG_TX_POSTINC & flags) - { - nrf_twim_tx_list_enable(p_twim); - } - else - { - nrf_twim_tx_list_disable(p_twim); - } - - if (NRF_DRV_TWI_FLAG_RX_POSTINC & flags) - { - nrf_twim_rx_list_enable(p_twim); - } - else - { - nrf_twim_rx_list_disable(p_twim); - } -#ifndef NRF52_PAN_46 -#endif -} -__STATIC_INLINE ret_code_t twim_xfer(twi_control_block_t * p_cb, - NRF_TWIM_Type * p_twim, - nrf_drv_twi_xfer_desc_t const * p_xfer_desc, - uint32_t flags) -{ - ret_code_t ret = NRF_SUCCESS; - nrf_twim_task_t start_task = NRF_TWIM_TASK_STARTTX; - nrf_twim_event_t evt_to_wait = NRF_TWIM_EVENT_STOPPED; - - if (!nrf_drv_is_in_RAM(p_xfer_desc->p_primary_buf)) - { - return NRF_ERROR_INVALID_ADDR; - } - /* Block TWI interrupts to ensure that function is not interrupted by TWI interrupt. */ - nrf_twim_int_disable(p_twim, DISABLE_ALL); - if (p_cb->busy) - { - nrf_twim_int_enable(p_twim, p_cb->int_mask); - return NRF_ERROR_BUSY; - } - else - { - - p_cb->busy = ((NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER & flags) || - (NRF_DRV_TWI_FLAG_REPEATED_XFER & flags)) ? false: true; - } - - p_cb->xfer_desc = *p_xfer_desc; - p_cb->repeated = (flags & NRF_DRV_TWI_FLAG_REPEATED_XFER) ? true : false; - nrf_twim_address_set(p_twim, p_xfer_desc->address); - - nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_STOPPED); - nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_ERROR); - - twim_list_enable_handle(p_twim, flags); - switch (p_xfer_desc->type) - { - case NRF_DRV_TWI_XFER_TXTX: - ASSERT(!(flags & NRF_DRV_TWI_FLAG_REPEATED_XFER)); - ASSERT(!(flags & NRF_DRV_TWI_FLAG_HOLD_XFER)); - ASSERT(!(flags & NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER)); - if (!nrf_drv_is_in_RAM(p_xfer_desc->p_secondary_buf)) - { - return NRF_ERROR_INVALID_ADDR; - } - nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_SUSPEND_MASK); - nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length); - nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED); - nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_LASTTX); - nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_SUSPENDED); - nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME); - nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STARTTX); - while(!nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_TXSTARTED)) - {} - nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED); - nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_secondary_buf, p_xfer_desc->secondary_length); - p_cb->int_mask = NRF_TWIM_INT_SUSPENDED_MASK | NRF_TWIM_INT_ERROR_MASK; - break; - case NRF_DRV_TWI_XFER_TXRX: - nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length); - nrf_twim_rx_buffer_set(p_twim, p_xfer_desc->p_secondary_buf, p_xfer_desc->secondary_length); - nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_STARTRX_MASK | - NRF_TWIM_SHORT_LASTRX_STOP_MASK); - p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK; - break; - case NRF_DRV_TWI_XFER_TX: - nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length); - if (NRF_DRV_TWI_FLAG_TX_NO_STOP & flags) - { - nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_SUSPEND_MASK); - p_cb->int_mask = NRF_TWIM_INT_SUSPENDED_MASK | NRF_TWIM_INT_ERROR_MASK; - nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_SUSPENDED); - evt_to_wait = NRF_TWIM_EVENT_SUSPENDED; - } - else - { - nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_STOP_MASK); - p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK; - } - nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME); - break; - case NRF_DRV_TWI_XFER_RX: - nrf_twim_rx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length); - nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTRX_STOP_MASK); - p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK; - start_task = NRF_TWIM_TASK_STARTRX; - nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME); - break; - default: - ret = NRF_ERROR_INVALID_PARAM; - break; - } - - if (!(flags & NRF_DRV_TWI_FLAG_HOLD_XFER) && (p_xfer_desc->type != NRF_DRV_TWI_XFER_TXTX)) - { - nrf_twim_task_trigger(p_twim, start_task); - } - - if (p_cb->handler) - { - if (flags & NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER) - { - p_cb->int_mask = NRF_TWIM_INT_ERROR_MASK; - } - nrf_twim_int_enable(p_twim, p_cb->int_mask); - } - else - { - while (!nrf_twim_event_check(p_twim, evt_to_wait)) - { - if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_ERROR)) - { - nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_ERROR); - nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME); - nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STOP); - evt_to_wait = NRF_TWIM_EVENT_STOPPED; - } - } - - uint32_t errorsrc = nrf_twim_errorsrc_get_and_clear(p_twim); - - p_cb->busy = false; - - if (errorsrc) - { - ret = NRF_ERROR_INTERNAL; - } - } - return ret; -} -#endif - -ret_code_t nrf_drv_twi_xfer(nrf_drv_twi_t const * p_instance, - nrf_drv_twi_xfer_desc_t const * p_xfer_desc, - uint32_t flags) -{ - ret_code_t ret = NRF_SUCCESS; - twi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; - - // TXRX and TXTX transfers are support only in non-blocking mode. - ASSERT( !((p_cb->handler == NULL) && (p_xfer_desc->type == NRF_DRV_TWI_XFER_TXRX))); - ASSERT( !((p_cb->handler == NULL) && (p_xfer_desc->type == NRF_DRV_TWI_XFER_TXTX))); - - CODE_FOR_TWIM - ( - ret = twim_xfer(p_cb, (NRF_TWIM_Type *)p_instance->reg.p_twim, p_xfer_desc, flags); - ) - CODE_FOR_TWI - ( - if ( (NRF_DRV_TWI_FLAG_TX_POSTINC | NRF_DRV_TWI_FLAG_RX_POSTINC) & flags) - { - return NRF_ERROR_NOT_SUPPORTED; - } - ret = twi_xfer(p_cb, (NRF_TWI_Type *)p_instance->reg.p_twi, p_xfer_desc, flags); - ) - return ret; -} - -bool nrf_drv_twi_is_busy(nrf_drv_twi_t const * p_instance) -{ - twi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; - return p_cb->busy; -} - -ret_code_t nrf_drv_twi_tx(nrf_drv_twi_t const * p_instance, - uint8_t address, - uint8_t const * p_data, - uint8_t length, - bool no_stop) -{ - nrf_drv_twi_xfer_desc_t xfer = NRF_DRV_TWI_XFER_DESC_TX(address, (uint8_t*)p_data, length); - - return nrf_drv_twi_xfer(p_instance, &xfer, no_stop ? NRF_DRV_TWI_FLAG_TX_NO_STOP : 0); -} - -ret_code_t nrf_drv_twi_rx(nrf_drv_twi_t const * p_instance, - uint8_t address, - uint8_t * p_data, - uint8_t length) -{ - nrf_drv_twi_xfer_desc_t xfer = NRF_DRV_TWI_XFER_DESC_RX(address, p_data, length); - return nrf_drv_twi_xfer(p_instance, &xfer, 0); -} - -uint32_t nrf_drv_twi_data_count_get(nrf_drv_twi_t const * const p_instance) -{ - CODE_FOR_TWIM - ( - ASSERT(false); - return 0; - ) - CODE_FOR_TWI - ( - return m_cb[p_instance->drv_inst_idx].bytes_transferred; - ) -} -uint32_t nrf_drv_twi_start_task_get(nrf_drv_twi_t const * p_instance, nrf_drv_twi_xfer_type_t xfer_type) -{ - CODE_FOR_TWIM - ( - return (uint32_t)nrf_twim_task_address_get(p_instance->reg.p_twim, - (xfer_type != NRF_DRV_TWI_XFER_RX) ? NRF_TWIM_TASK_STARTTX : NRF_TWIM_TASK_STARTRX); - ) - CODE_FOR_TWI - ( - return (uint32_t)nrf_twi_task_address_get(p_instance->reg.p_twi, - (xfer_type != NRF_DRV_TWI_XFER_RX) ? NRF_TWI_TASK_STARTTX : NRF_TWI_TASK_STARTRX); - ) -} - -uint32_t nrf_drv_twi_stopped_event_get(nrf_drv_twi_t const * p_instance) -{ - CODE_FOR_TWIM - ( - return (uint32_t)nrf_twim_event_address_get(p_instance->reg.p_twim, NRF_TWIM_EVENT_STOPPED); - ) - CODE_FOR_TWI - ( - return (uint32_t)nrf_twi_event_address_get(p_instance->reg.p_twi, NRF_TWI_EVENT_STOPPED); - ) -} - -#ifdef TWIM_IN_USE -static void irq_handler_twim(NRF_TWIM_Type * p_twim, twi_control_block_t * p_cb) -{ - ASSERT(p_cb->handler); - - if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_ERROR)) - { - nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_ERROR); - if (!nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_STOPPED)) - { - nrf_twim_int_disable(p_twim, p_cb->int_mask); - p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK; - nrf_twim_int_enable(p_twim, p_cb->int_mask); - - nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME); - nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STOP); - return; - } - } - - nrf_drv_twi_evt_t event; - - if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_STOPPED)) - { - nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_STOPPED); - event.xfer_desc = p_cb->xfer_desc; - if (p_cb->error) - { - - event.xfer_desc.primary_length = (p_cb->xfer_desc.type == NRF_DRV_TWI_XFER_RX) ? - (uint8_t)nrf_twim_rxd_amount_get(p_twim) : (uint8_t)nrf_twim_txd_amount_get(p_twim); - event.xfer_desc.secondary_length = (p_cb->xfer_desc.type == NRF_DRV_TWI_XFER_TXRX) ? - (uint8_t)nrf_twim_rxd_amount_get(p_twim) : (uint8_t)nrf_twim_txd_amount_get(p_twim); - - } - nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_LASTTX); - nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_LASTRX); - if (!p_cb->repeated || p_cb->error) - { - nrf_twim_shorts_set(p_twim, 0); - p_cb->int_mask = 0; - nrf_twim_int_disable(p_twim, DISABLE_ALL); - } - } - else - { - nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_SUSPENDED); - if (p_cb->xfer_desc.type == NRF_DRV_TWI_XFER_TX) - { - event.xfer_desc = p_cb->xfer_desc; - if (!p_cb->repeated) - { - nrf_twim_shorts_set(p_twim, 0); - p_cb->int_mask = 0; - nrf_twim_int_disable(p_twim, DISABLE_ALL); - } - } - else - { - nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_STOP_MASK); - p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK; - nrf_twim_int_disable(p_twim, DISABLE_ALL); - nrf_twim_int_enable(p_twim, p_cb->int_mask); - nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STARTTX); - nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME); - return; - } - } - - uint32_t errorsrc = nrf_twim_errorsrc_get_and_clear(p_twim); - if (errorsrc & NRF_TWIM_ERROR_ADDRESS_NACK) - { - event.type = NRF_DRV_TWI_EVT_ADDRESS_NACK; - } - else if (errorsrc & NRF_TWIM_ERROR_DATA_NACK) - { - event.type = NRF_DRV_TWI_EVT_DATA_NACK; - } - else - { - event.type = NRF_DRV_TWI_EVT_DONE; - } - - if (!p_cb->repeated) - { - p_cb->busy = false; - } - p_cb->handler(&event, p_cb->p_context); -} -#endif // TWIM_IN_USE - -#ifdef TWI_IN_USE -static void irq_handler_twi(NRF_TWI_Type * p_twi, twi_control_block_t * p_cb) -{ - ASSERT(p_cb->handler); - - if (twi_transfer(p_twi, &p_cb->error, &p_cb->bytes_transferred, p_cb->p_curr_buf, p_cb->curr_length, p_cb->curr_no_stop )) - { - return; - } - - if (!p_cb->error && - ((p_cb->xfer_desc.type == NRF_DRV_TWI_XFER_TXRX) || - (p_cb->xfer_desc.type == NRF_DRV_TWI_XFER_TXTX)) && - p_cb->p_curr_buf == p_cb->xfer_desc.p_primary_buf) - { - p_cb->p_curr_buf = p_cb->xfer_desc.p_secondary_buf; - p_cb->curr_length = p_cb->xfer_desc.secondary_length; - p_cb->curr_no_stop = (p_cb->flags & NRF_DRV_TWI_FLAG_TX_NO_STOP); - - if (p_cb->xfer_desc.type == NRF_DRV_TWI_XFER_TXTX) - { - (void)twi_tx_start_transfer(p_cb, p_twi, p_cb->p_curr_buf, p_cb->curr_length, p_cb->curr_no_stop); - } - else - { - (void)twi_rx_start_transfer(p_cb, p_twi, p_cb->p_curr_buf, p_cb->curr_length); - } - } - else - { - nrf_drv_twi_evt_t event; - event.xfer_desc = p_cb->xfer_desc; - - if (p_cb->error) - { - uint32_t errorsrc = nrf_twi_errorsrc_get_and_clear(p_twi); - if (errorsrc & NRF_TWI_ERROR_ADDRESS_NACK) - { - event.type = NRF_DRV_TWI_EVT_ADDRESS_NACK; - } - else if (errorsrc & NRF_TWI_ERROR_DATA_NACK) - { - event.type = NRF_DRV_TWI_EVT_DATA_NACK; - } - } - else - { - event.type = NRF_DRV_TWI_EVT_DONE; - } - - p_cb->busy = false; - - if (!(NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER & p_cb->flags)) - { - p_cb->handler(&event, p_cb->p_context); - } - } - -} -#endif // TWI_IN_USE - -#if TWI0_ENABLED -IRQ_HANDLER(0) -{ - #if (TWI0_USE_EASY_DMA == 1) && defined(NRF52) - irq_handler_twim(NRF_TWIM0, - #else - irq_handler_twi(NRF_TWI0, - #endif - &m_cb[TWI0_INSTANCE_INDEX]); -} -#endif // TWI0_ENABLED - -#if TWI1_ENABLED -IRQ_HANDLER(1) -{ - #if (TWI1_USE_EASY_DMA == 1) - irq_handler_twim(NRF_TWIM1, - #else - irq_handler_twi(NRF_TWI1, - #endif - &m_cb[TWI1_INSTANCE_INDEX]); -} -#endif // TWI1_ENABLED diff --git a/targets/TARGET_NORDIC/TARGET_NRF5/sdk/drivers_nrf/twi_master/nrf_drv_twi.h b/targets/TARGET_NORDIC/TARGET_NRF5/sdk/drivers_nrf/twi_master/nrf_drv_twi.h deleted file mode 100644 index 83f37ea4be..0000000000 --- a/targets/TARGET_NORDIC/TARGET_NRF5/sdk/drivers_nrf/twi_master/nrf_drv_twi.h +++ /dev/null @@ -1,421 +0,0 @@ -/* - * Copyright (c) 2015 Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list - * of conditions and the following disclaimer. - * - * 2. Redistributions in binary form, except as embedded into a Nordic Semiconductor ASA - * integrated circuit in a product or a software update for such product, must reproduce - * the above copyright notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific prior - * written permission. - * - * 4. This software, with or without modification, must only be used with a - * Nordic Semiconductor ASA integrated circuit. - * - * 5. Any software provided in binary or object form under this license must not be reverse - * engineered, decompiled, modified and/or disassembled. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - - -/** - * - * @defgroup nrf_twi Two-wire interface (TWI) - * @ingroup nrf_drivers - * @brief Two-wire interface (TWI) APIs. - * - * @defgroup nrf_twi_master TWI master HAL and driver - * @ingroup nrf_twi - * @brief TWI master APIs. - * @details The TWI and TWIM HALs provide basic APIs for accessing the registers of the TWI and TWIM peripherals, respectively. - * - * The TWI master driver provides APIs on a higher level. - * - */ - -#ifndef NRF_DRV_TWI_H__ -#define NRF_DRV_TWI_H__ - -#include "nordic_common.h" -#include "nrf_drv_config.h" - -// This set of macros makes it possible to exclude parts of code when one type -// of supported peripherals is not used. -#if ((TWI0_ENABLED == 1 && TWI0_USE_EASY_DMA == 1) || \ - (TWI1_ENABLED == 1 && TWI1_USE_EASY_DMA == 1)) - #define TWIM_IN_USE -#endif -#if ((TWI0_ENABLED == 1 && TWI0_USE_EASY_DMA != 1) || \ - (TWI1_ENABLED == 1 && TWI1_USE_EASY_DMA != 1)) - #define TWI_IN_USE -#endif - -#include "nrf_twi.h" -#ifdef TWIM_IN_USE - #include "nrf_twim.h" -#endif -#include "sdk_errors.h" - -#if defined(NRF52) - #define NRF_DRV_TWI_PERIPHERAL(id) \ - (CONCAT_3(TWI, id, _USE_EASY_DMA) == 1 ? \ - (void *)CONCAT_2(NRF_TWIM, id) \ - : (void *)CONCAT_2(NRF_TWI, id)) -#else - #define NRF_DRV_TWI_PERIPHERAL(id) (void *)CONCAT_2(NRF_TWI, id) -#endif - -/** - * @defgroup nrf_drv_twi TWI master driver - * @{ - * @ingroup nrf_twi_master - * @brief Multi-instance TWI master driver. - */ - -/** - * @brief Structure for the TWI master driver instance. - */ -typedef struct -{ - union - { -#ifdef TWIM_IN_USE - NRF_TWIM_Type * p_twim; ///< Pointer to a structure with TWIM registers. -#endif - NRF_TWI_Type * p_twi; ///< Pointer to a structure with TWI registers. - } reg; - uint8_t drv_inst_idx; ///< Driver instance index. - bool use_easy_dma; ///< True if the peripheral with EasyDMA (TWIM) shall be used. -} nrf_drv_twi_t; - -/** - * @brief Macro for creating a TWI master driver instance. - */ -#define NRF_DRV_TWI_INSTANCE(id) \ -{ \ - .reg = {NRF_DRV_TWI_PERIPHERAL(id)}, \ - .drv_inst_idx = CONCAT_3(TWI, id, _INSTANCE_INDEX), \ - .use_easy_dma = CONCAT_3(TWI, id, _USE_EASY_DMA) \ -} - -/** - * @brief Structure for the TWI master driver instance configuration. - */ -typedef struct -{ - uint32_t scl; ///< SCL pin number. - uint32_t sda; ///< SDA pin number. - nrf_twi_frequency_t frequency; ///< TWI frequency. - uint8_t interrupt_priority; ///< Interrupt priority. -} nrf_drv_twi_config_t; - -/** - * @brief TWI master driver instance default configuration. - */ -#define NRF_DRV_TWI_DEFAULT_CONFIG(id) \ -{ \ - .frequency = CONCAT_3(TWI, id, _CONFIG_FREQUENCY), \ - .scl = CONCAT_3(TWI, id, _CONFIG_SCL), \ - .sda = CONCAT_3(TWI, id, _CONFIG_SDA), \ - .interrupt_priority = CONCAT_3(TWI, id, _CONFIG_IRQ_PRIORITY) \ -} - -#define NRF_DRV_TWI_FLAG_TX_POSTINC (1UL << 0) /**< TX buffer address incremented after transfer. */ -#define NRF_DRV_TWI_FLAG_RX_POSTINC (1UL << 1) /**< RX buffer address incremented after transfer. */ -#define NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER (1UL << 2) /**< Interrupt after each transfer is suppressed, and the event handler is not called. */ -#define NRF_DRV_TWI_FLAG_HOLD_XFER (1UL << 3) /**< Set up the transfer but do not start it. */ -#define NRF_DRV_TWI_FLAG_REPEATED_XFER (1UL << 4) /**< Flag indicating that the transfer will be executed multiple times. */ -#define NRF_DRV_TWI_FLAG_TX_NO_STOP (1UL << 5) /**< Flag indicating that the TX transfer will not end with a stop condition. */ - -/** - * @brief TWI master driver event types. - */ -typedef enum -{ - NRF_DRV_TWI_EVT_DONE, ///< Transfer completed event. - NRF_DRV_TWI_EVT_ADDRESS_NACK, ///< Error event: NACK received after sending the address. - NRF_DRV_TWI_EVT_DATA_NACK ///< Error event: NACK received after sending a data byte. -} nrf_drv_twi_evt_type_t; - -/** - * @brief TWI master driver transfer types. - */ -typedef enum -{ - NRF_DRV_TWI_XFER_TX, ///< TX transfer. - NRF_DRV_TWI_XFER_RX, ///< RX transfer. - NRF_DRV_TWI_XFER_TXRX, ///< TX transfer followed by RX transfer with repeated start. - NRF_DRV_TWI_XFER_TXTX ///< TX transfer followed by TX transfer with repeated start. -} nrf_drv_twi_xfer_type_t; - -/** - * @brief Structure for a TWI transfer descriptor. - */ -typedef struct -{ - nrf_drv_twi_xfer_type_t type; ///< Type of transfer. - uint8_t address; ///< Slave address. - uint8_t primary_length; ///< Number of bytes transferred. - uint8_t secondary_length; ///< Number of bytes transferred. - uint8_t * p_primary_buf; ///< Pointer to transferred data. - uint8_t * p_secondary_buf; ///< Pointer to transferred data. -} nrf_drv_twi_xfer_desc_t; - - -/**@brief Macro for setting the TX transfer descriptor. */ -#define NRF_DRV_TWI_XFER_DESC_TX(addr, p_data, length) \ - { \ - .type = NRF_DRV_TWI_XFER_TX, \ - .address = addr, \ - .primary_length = length, \ - .p_primary_buf = p_data, \ - } - -/**@brief Macro for setting the RX transfer descriptor. */ -#define NRF_DRV_TWI_XFER_DESC_RX(addr, p_data, length) \ - { \ - .type = NRF_DRV_TWI_XFER_RX, \ - .address = addr, \ - .primary_length = length, \ - .p_primary_buf = p_data, \ - } - -/**@brief Macro for setting the TXRX transfer descriptor. */ -#define NRF_DRV_TWI_XFER_DESC_TXRX(addr, p_tx, tx_len, p_rx, rx_len) \ - { \ - .type = NRF_DRV_TWI_XFER_TXRX, \ - .address = addr, \ - .primary_length = tx_len, \ - .secondary_length = rx_len, \ - .p_primary_buf = p_tx, \ - .p_secondary_buf = p_rx, \ - } - -/**@brief Macro for setting the TXTX transfer descriptor. */ -#define NRF_DRV_TWI_XFER_DESC_TXTX(addr, p_tx, tx_len, p_tx2, tx_len2) \ - { \ - .type = NRF_DRV_TWI_XFER_TXTX, \ - .address = addr, \ - .primary_length = tx_len, \ - .secondary_length = tx_len2, \ - .p_primary_buf = p_tx, \ - .p_secondary_buf = p_tx2, \ - } - -/** - * @brief Structure for a TWI event. - */ -typedef struct -{ - nrf_drv_twi_evt_type_t type; ///< Event type. - nrf_drv_twi_xfer_desc_t xfer_desc; ///< Transfer details. -} nrf_drv_twi_evt_t; - -/** - * @brief TWI event handler prototype. - */ -typedef void (* nrf_drv_twi_evt_handler_t)(nrf_drv_twi_evt_t const * p_event, - void * p_context); - -/** - * @brief Function for initializing the TWI instance. - * - * @param[in] p_instance TWI instance. - * @param[in] p_config Initial configuration. If NULL, the default configuration is used. - * @param[in] event_handler Event handler provided by the user. If NULL, blocking mode is enabled. - * @param[in] p_context Context passed to event handler. - * - * @retval NRF_SUCCESS If initialization was successful. - * @retval NRF_ERROR_INVALID_STATE If the driver is in invalid state. - * @retval NRF_ERROR_BUSY If some other peripheral with the same - * instance ID is already in use. This is - * possible only if PERIPHERAL_RESOURCE_SHARING_ENABLED - * is set to a value other than zero. - */ -ret_code_t nrf_drv_twi_init(nrf_drv_twi_t const * p_instance, - nrf_drv_twi_config_t const * p_config, - nrf_drv_twi_evt_handler_t event_handler, - void * p_context); - -/** - * @brief Function for uninitializing the TWI instance. - * - * @param[in] p_instance TWI instance. - */ -void nrf_drv_twi_uninit(nrf_drv_twi_t const * p_instance); - -/** - * @brief Function for enabling the TWI instance. - * - * @param[in] p_instance TWI instance. - */ -void nrf_drv_twi_enable(nrf_drv_twi_t const * p_instance); - -/** - * @brief Function for disabling the TWI instance. - * - * @param[in] p_instance TWI instance. - */ -void nrf_drv_twi_disable(nrf_drv_twi_t const * p_instance); - -/** - * @brief Function for sending data to a TWI slave. - * - * The transmission will be stopped when an error occurs. If a transfer is ongoing, - * the function returns the error code @ref NRF_ERROR_BUSY. - * - * @param[in] p_instance TWI instance. - * @param[in] address Address of a specific slave device (only 7 LSB). - * @param[in] p_data Pointer to a transmit buffer. - * @param[in] length Number of bytes to send. - * @param[in] no_stop If set, the stop condition is not generated on the bus - * after the transfer has completed successfully (allowing - * for a repeated start in the next transfer). - * - * @retval NRF_SUCCESS If the procedure was successful. - * @retval NRF_ERROR_BUSY If the driver is not ready for a new transfer. - * @retval NRF_ERROR_INTERNAL If an error was detected by hardware. - */ -ret_code_t nrf_drv_twi_tx(nrf_drv_twi_t const * p_instance, - uint8_t address, - uint8_t const * p_data, - uint8_t length, - bool no_stop); - -/** - * @brief Function for reading data from a TWI slave. - * - * The transmission will be stopped when an error occurs. If a transfer is ongoing, - * the function returns the error code @ref NRF_ERROR_BUSY. - * - * @param[in] p_instance TWI instance. - * @param[in] address Address of a specific slave device (only 7 LSB). - * @param[in] p_data Pointer to a receive buffer. - * @param[in] length Number of bytes to be received. - * - * @retval NRF_SUCCESS If the procedure was successful. - * @retval NRF_ERROR_BUSY If the driver is not ready for a new transfer. - * @retval NRF_ERROR_INTERNAL If an error was detected by hardware. - */ -ret_code_t nrf_drv_twi_rx(nrf_drv_twi_t const * p_instance, - uint8_t address, - uint8_t * p_data, - uint8_t length); - -/** - * @brief Function for preparing a TWI transfer. - * - * The following transfer types can be configured (@ref nrf_drv_twi_xfer_desc_t::type): - * - @ref NRF_DRV_TWI_XFER_TXRX: Write operation followed by a read operation (without STOP condition in between). - * - @ref NRF_DRV_TWI_XFER_TXTX: Write operation followed by a write operation (without STOP condition in between). - * - @ref NRF_DRV_TWI_XFER_TX: Write operation (with or without STOP condition). - * - @ref NRF_DRV_TWI_XFER_RX: Read operation (with STOP condition). - * - * Additional options are provided using the flags parameter: - * - @ref NRF_DRV_TWI_FLAG_TX_POSTINC and @ref NRF_DRV_TWI_FLAG_RX_POSTINC: Post-incrementation of buffer addresses. Supported only by TWIM. - * - @ref NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER: No user event handler after transfer completion. In most cases, this also means no interrupt at the end of the transfer. - * - @ref NRF_DRV_TWI_FLAG_HOLD_XFER: Driver is not starting the transfer. Use this flag if the transfer is triggered externally by PPI. Supported only by TWIM. - * Use @ref nrf_drv_twi_start_task_get to get the address of the start task. - * - @ref NRF_DRV_TWI_FLAG_REPEATED_XFER: Prepare for repeated transfers. You can set up a number of transfers that will be triggered externally (for example by PPI). - * An example is a TXRX transfer with the options @ref NRF_DRV_TWI_FLAG_RX_POSTINC, @ref NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER, and @ref NRF_DRV_TWI_FLAG_REPEATED_XFER. - * After the transfer is set up, a set of transfers can be triggered by PPI that will read, for example, the same register of an - * external component and put it into a RAM buffer without any interrupts. @ref nrf_drv_twi_stopped_event_get can be used to get the - * address of the STOPPED event, which can be used to count the number of transfers. If @ref NRF_DRV_TWI_FLAG_REPEATED_XFER is used, - * the driver does not set the instance into busy state, so you must ensure that the next transfers are set up - * when TWIM is not active. Supported only by TWIM. - * - @ref NRF_DRV_TWI_FLAG_TX_NO_STOP: No stop condition after TX transfer. - * - * @note - * Some flag combinations are invalid: - * - @ref NRF_DRV_TWI_FLAG_TX_NO_STOP with @ref nrf_drv_twi_xfer_desc_t::type different than @ref NRF_DRV_TWI_XFER_TX - * - @ref NRF_DRV_TWI_FLAG_REPEATED_XFER with @ref nrf_drv_twi_xfer_desc_t::type set to @ref NRF_DRV_TWI_XFER_TXTX - * - * If @ref nrf_drv_twi_xfer_desc_t::type is set to @ref NRF_DRV_TWI_XFER_TX and the @ref NRF_DRV_TWI_FLAG_TX_NO_STOP and @ref NRF_DRV_TWI_FLAG_REPEATED_XFER - * flags are set, two tasks must be used to trigger a transfer: TASKS_RESUME followed by TASKS_STARTTX. If no stop condition is generated, - * TWIM is in SUSPENDED state. Therefore, it must be resumed before the transfer can be started. - * - * @note - * This function should be used only if the instance is configured to work in non-blocking mode. If the function is used in blocking mode, the driver asserts. - * @note If you are using this function with TWI, the only supported flag is @ref NRF_DRV_TWI_FLAG_TX_NO_STOP. All other flags require TWIM. - * - * @param[in] p_instance TWI instance. - * @param[in] p_xfer_desc Pointer to the transfer descriptor. - * @param[in] flags Transfer options (0 for default settings). - * - * @retval NRF_SUCCESS If the procedure was successful. - * @retval NRF_ERROR_BUSY If the driver is not ready for a new transfer. - * @retval NRF_ERROR_NOT_SUPPORTED If the provided parameters are not supported. - */ -ret_code_t nrf_drv_twi_xfer(nrf_drv_twi_t const * p_instance, - nrf_drv_twi_xfer_desc_t const * p_xfer_desc, - uint32_t flags); - -/** - * @brief Function for checking the TWI driver state. - * - * @param[in] p_instance TWI instance. - * - * @retval true If the TWI driver is currently busy performing a transfer. - * @retval false If the TWI driver is ready for a new transfer. - */ -bool nrf_drv_twi_is_busy(nrf_drv_twi_t const * p_instance); - -/** - * @brief Function for getting the transferred data count. - * - * This function provides valid results only in legacy mode. - * - * @param[in] p_instance TWI instance. - * - * @return Data count. - */ -uint32_t nrf_drv_twi_data_count_get(nrf_drv_twi_t const * const p_instance); - -/** - * @brief Function for returning the address of a TWI/TWIM start task. - * - * This function should be used if @ref nrf_drv_twi_xfer was called with the flag @ref NRF_DRV_TWI_FLAG_HOLD_XFER. - * In that case, the transfer is not started by the driver, but it must be started externally by PPI. - * - * @param[in] p_instance TWI instance. - * @param[in] xfer_type Transfer type used in the last call of the @ref nrf_drv_twi_xfer function. - * - * @return Start task address (TX or RX) depending on the value of xfer_type. - */ -uint32_t nrf_drv_twi_start_task_get(nrf_drv_twi_t const * p_instance, nrf_drv_twi_xfer_type_t xfer_type); - -/** - * @brief Function for returning the address of a STOPPED TWI/TWIM event. - * - * A STOPPED event can be used to detect the end of a transfer if the @ref NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER - * option is used. - * - * @param[in] p_instance TWI instance. - * - * @return STOPPED event address. - */ -uint32_t nrf_drv_twi_stopped_event_get(nrf_drv_twi_t const * p_instance); -/** - *@} - **/ - -#endif // NRF_DRV_TWI_H__ diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_ARM_MICRO/NUC472.sct b/targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_ARM_MICRO/TARGET_NU_XRAM_SUPPORTED/NUC472.sct similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_ARM_MICRO/NUC472.sct rename to targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_ARM_MICRO/TARGET_NU_XRAM_SUPPORTED/NUC472.sct diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_ARM_MICRO/TARGET_NU_XRAM_UNSUPPORTED/NUC472.sct b/targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_ARM_MICRO/TARGET_NU_XRAM_UNSUPPORTED/NUC472.sct new file mode 100644 index 0000000000..5b3d1bc55d --- /dev/null +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_ARM_MICRO/TARGET_NU_XRAM_UNSUPPORTED/NUC472.sct @@ -0,0 +1,29 @@ + +LR_IROM1 0x00000000 { + ER_IROM1 0x00000000 { ; load address = execution address + *(RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + } + + ;UVISOR AlignExpr(+0, 16) { ; 16 byte-aligned + ; uvisor-lib.a (+RW +ZI) + ;} + + ARM_LIB_STACK 0x20000000 EMPTY 0x800 { + } + + ER_IRAMVEC 0x20000800 EMPTY (4*(16 + 142)) { ; Reserve for vectors + } + + RW_IRAM1 AlignExpr(+0, 16) { ; 16 byte-aligned + .ANY (+RW +ZI) + } + + ; Extern SRAM for HEAP + ARM_LIB_HEAP AlignExpr(+0, 16) EMPTY (0x20000000 + 0x10000 - AlignExpr(ImageLimit(RW_IRAM1), 16)) { + } +} +ScatterAssert(LoadLimit(LR_IROM1) <= 0x00080000) ; 512 KB APROM +ScatterAssert(ImageLimit(RW_IRAM1) <= 0x20010000) ; 64 KB SRAM (internal) + diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_ARM_STD/NUC472.sct b/targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_ARM_STD/TARGET_NU_XRAM_SUPPORTED/NUC472.sct similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_ARM_STD/NUC472.sct rename to targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_ARM_STD/TARGET_NU_XRAM_SUPPORTED/NUC472.sct diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_ARM_STD/TARGET_NU_XRAM_UNSUPPORTED/NUC472.sct b/targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_ARM_STD/TARGET_NU_XRAM_UNSUPPORTED/NUC472.sct new file mode 100644 index 0000000000..5b3d1bc55d --- /dev/null +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_ARM_STD/TARGET_NU_XRAM_UNSUPPORTED/NUC472.sct @@ -0,0 +1,29 @@ + +LR_IROM1 0x00000000 { + ER_IROM1 0x00000000 { ; load address = execution address + *(RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + } + + ;UVISOR AlignExpr(+0, 16) { ; 16 byte-aligned + ; uvisor-lib.a (+RW +ZI) + ;} + + ARM_LIB_STACK 0x20000000 EMPTY 0x800 { + } + + ER_IRAMVEC 0x20000800 EMPTY (4*(16 + 142)) { ; Reserve for vectors + } + + RW_IRAM1 AlignExpr(+0, 16) { ; 16 byte-aligned + .ANY (+RW +ZI) + } + + ; Extern SRAM for HEAP + ARM_LIB_HEAP AlignExpr(+0, 16) EMPTY (0x20000000 + 0x10000 - AlignExpr(ImageLimit(RW_IRAM1), 16)) { + } +} +ScatterAssert(LoadLimit(LR_IROM1) <= 0x00080000) ; 512 KB APROM +ScatterAssert(ImageLimit(RW_IRAM1) <= 0x20010000) ; 64 KB SRAM (internal) + diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_GCC_ARM/NUC472.ld b/targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_GCC_ARM/TARGET_NU_XRAM_SUPPORTED/NUC472.ld similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_GCC_ARM/NUC472.ld rename to targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_GCC_ARM/TARGET_NU_XRAM_SUPPORTED/NUC472.ld diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_GCC_ARM/TARGET_NU_XRAM_UNSUPPORTED/NUC472.ld b/targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_GCC_ARM/TARGET_NU_XRAM_UNSUPPORTED/NUC472.ld new file mode 100644 index 0000000000..3440229f87 --- /dev/null +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_GCC_ARM/TARGET_NU_XRAM_UNSUPPORTED/NUC472.ld @@ -0,0 +1,268 @@ +/* + * Nuvoton NUC472 GCC linker script file + */ + +StackSize = 0x800; + +MEMORY +{ + + VECTORS (rx) : ORIGIN = 0x00000000, LENGTH = 0x00000400 + FLASH (rx) : ORIGIN = 0x00000400, LENGTH = 0x00080000 - 0x00000400 + RAM_INTERN (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00010000 - 0x00000000 +} + +/** + * Must match cmsis_nvic.h + */ +__vector_size = 4 * (16 + 142); + +/* 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 + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .isr_vector : + { + __vector_table = .; + KEEP(*(.vector_table)) + . = ALIGN(4); + } > VECTORS + + /* ensure that uvisor bss is at the beginning of memory */ + .uvisor.bss (NOLOAD): + { + . = ALIGN(32); + __uvisor_bss_start = .; + + /* protected uvisor main bss */ + . = ALIGN(32); + __uvisor_bss_main_start = .; + KEEP(*(.keep.uvisor.bss.main)) + . = ALIGN(32); + __uvisor_bss_main_end = .; + + /* protected uvisor secure boxes bss */ + . = ALIGN(32); + __uvisor_bss_boxes_start = .; + KEEP(*(.keep.uvisor.bss.boxes)) + . = ALIGN(32); + __uvisor_bss_boxes_end = .; + + /* Ensure log2(size) alignment of the uvisor region, to ensure that the region can be effectively protected by the MPU. */ + . = ALIGN(1 << LOG2CEIL(__uvisor_bss_boxes_end - __uvisor_bss_start)); + __uvisor_bss_end = .; + } > RAM_INTERN + + .text : + { + /* uVisor code and data */ + . = ALIGN(4); + __uvisor_main_start = .; + *(.uvisor.main) + __uvisor_main_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 + + .ARM.exidx : + { + __exidx_start = .; + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + __exidx_end = .; + } > FLASH + + /* .stack section doesn't contains any symbols. It is only + * used for linker to reserve space for the main stack section + * WARNING: .stack should come immediately after the last secure memory + * section. This provides stack overflow detection. */ + .stack (NOLOAD): + { + __StackLimit = .; + *(.stack*); + . += StackSize - (. - __StackLimit); + } > RAM_INTERN + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ADDR(.stack) + SIZEOF(.stack); + __StackLimit = ADDR(.stack); + PROVIDE(__stack = __StackTop); + + /* Relocate vector table in SRAM */ + .isr_vector.reloc (NOLOAD) : + { + . = ALIGN(1 << LOG2CEIL(__vector_size)); + PROVIDE(__start_vector_table__ = .); + . += __vector_size; + PROVIDE(__end_vector_table__ = .); + } > RAM_INTERN + + .data : + { + PROVIDE( __etext = LOADADDR(.data) ); + + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* 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 = .); + + /* All data end */ + . = ALIGN(32); + __data_end__ = .; + + } >RAM_INTERN AT>FLASH + + /* uvisor configuration data */ + .uvisor.secure : + { + . = ALIGN(32); + __uvisor_secure_start = .; + + /* uvisor secure boxes configuration tables */ + . = ALIGN(32); + __uvisor_cfgtbl_start = .; + KEEP(*(.keep.uvisor.cfgtbl)) + . = ALIGN(32); + __uvisor_cfgtbl_end = .; + + /* pointers to uvisor secure boxes configuration tables */ + /* note: no further alignment here, we need to have the exact list of pointers */ + __uvisor_cfgtbl_ptr_start = .; + KEEP(*(.keep.uvisor.cfgtbl_ptr_first)) + KEEP(*(.keep.uvisor.cfgtbl_ptr)) + __uvisor_cfgtbl_ptr_end = .; + + /* the following symbols are kept for backward compatibility and will be soon + * deprecated; applications actively using uVisor (__uvisor_mode == UVISOR_ENABLED) + * will need to use uVisor 0.8.x or above, or the security assertions will halt the + * system */ + /************************/ + __uvisor_data_src = .; + __uvisor_data_start = .; + __uvisor_data_end = .; + /************************/ + + . = ALIGN(32); + __uvisor_secure_end = .; + } >FLASH + + .uninitialized (NOLOAD): + { + . = ALIGN(32); + __uninitialized_start = .; + *(.uninitialized) + KEEP(*(.keep.uninitialized)) + . = ALIGN(32); + __uninitialized_end = .; + } > RAM_INTERN + + .bss.extern (NOLOAD): + { + __bss_extern_start__ = .; + /** + * Place large .bss* sections into external SRAM if internal SRAM is insufficient. + * Such memory arrangement requires initializing .bss.extern section to zero in startup file. Check startup fiile in cmsis-core-* for support or not. + */ + *lwip_*.o(.bss*) + *lwip_*.o(COMMON) + *mesh_system.o(.bss*) + __bss_extern_end__ = .; + } > RAM_INTERN + + .bss (NOLOAD): + { + __bss_start__ = .; + *(.bss*) + *(COMMON) + __bss_end__ = .; + } > RAM_INTERN + + .heap (NOLOAD): + { + __end__ = .; + end = __end__; + *(.heap*); + . += (ORIGIN(RAM_INTERN) + LENGTH(RAM_INTERN) - .); + __HeapLimit = .; + } > RAM_INTERN + PROVIDE(__heap_size = SIZEOF(.heap)); + PROVIDE(__mbed_sbrk_start = ADDR(.heap)); + PROVIDE(__mbed_krbs_start = ADDR(.heap) + SIZEOF(.heap)); + + /* Provide physical memory boundaries for uVisor. */ + __uvisor_flash_start = ORIGIN(VECTORS); + __uvisor_flash_end = ORIGIN(FLASH) + LENGTH(FLASH); + __uvisor_sram_start = ORIGIN(RAM_INTERN); + __uvisor_sram_end = ORIGIN(RAM_INTERN) + LENGTH(RAM_INTERN); +} diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_IAR/NUC472_442.icf b/targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_IAR/TARGET_NU_XRAM_SUPPORTED/NUC472_442.icf similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_IAR/NUC472_442.icf rename to targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_IAR/TARGET_NU_XRAM_SUPPORTED/NUC472_442.icf diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_IAR/TARGET_NU_XRAM_UNSUPPORTED/NUC472_442.icf b/targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_IAR/TARGET_NU_XRAM_UNSUPPORTED/NUC472_442.icf new file mode 100644 index 0000000000..e62e957908 --- /dev/null +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_IAR/TARGET_NU_XRAM_UNSUPPORTED/NUC472_442.icf @@ -0,0 +1,36 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x00000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x00000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x00080000; +define symbol __ICFEDIT_region_IRAM_start__ = 0x20000000; +define symbol __ICFEDIT_region_IRAM_end__ = 0x20010000; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x800; +define symbol __ICFEDIT_size_heap__ = 0x8000; +/**** End of ICF editor section. ###ICF###*/ + + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region IRAM_region = mem:[from __ICFEDIT_region_IRAM_start__ to __ICFEDIT_region_IRAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; +/* NOTE: Vector table base requires to be aligned to the power of vector table size. Give a safe value here. */ +define block IRAMVEC with alignment = 1024, size = 4 * (16 + 142) { }; + + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place at start of IRAM_region { block CSTACK }; +place in IRAM_region { block IRAMVEC }; +place in IRAM_region { readwrite }; +place in IRAM_region { block HEAP }; \ No newline at end of file diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/device/system_NUC472_442.c b/targets/TARGET_NUVOTON/TARGET_NUC472/device/system_NUC472_442.c index c1954ab405..56a5fb8cda 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/device/system_NUC472_442.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/device/system_NUC472_442.c @@ -19,7 +19,7 @@ uint32_t SystemCoreClock = __HSI; /*!< System Clock Frequency (Cor uint32_t CyclesPerUs = (__HSI / 1000000); /*!< Cycles per micro second */ uint32_t gau32ClkSrcTbl[] = {__HXT, __LXT, 0, __LIRC, 0, 0, 0, __HIRC}; /*!< System clock source table */ -#if defined TARGET_NUMAKER_PFM_NUC472 +#if defined TARGET_NU_XRAM_SUPPORTED static void nu_ebi_init(void); #endif @@ -113,13 +113,13 @@ void SystemInit (void) /*------------------------------------------------------------------------*/ #endif -#if defined TARGET_NUMAKER_PFM_NUC472 +#if defined TARGET_NU_XRAM_SUPPORTED // NOTE: C-runtime not initialized yet. Ensure no static memory (global variable) are accessed in this function. nu_ebi_init(); #endif } -#if defined TARGET_NUMAKER_PFM_NUC472 +#if defined TARGET_NU_XRAM_SUPPORTED void nu_ebi_init(void) { /* Enable IP clock */ diff --git a/targets/TARGET_ONSEMI/TARGET_NCS36510/i2c.h b/targets/TARGET_ONSEMI/TARGET_NCS36510/i2c.h index 15abc34edd..bcbafbe000 100644 --- a/targets/TARGET_ONSEMI/TARGET_NCS36510/i2c.h +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/i2c.h @@ -83,14 +83,18 @@ #define I2C_APB_CLK_DIVIDER_VAL_MASK 0x1FE0 /* Error check */ -#define I2C_UFL_CHECK (d->membase->STATUS.WORD & 0x80) -#define FIFO_OFL_CHECK (d->membase->STATUS.WORD & 0x10) -#define I2C_BUS_ERR_CHECK (d->membase->STATUS.WORD & 0x04) -#define RD_DATA_READY (d->membase->STATUS.WORD & 0x02) +#define I2C_UFL_CHECK (obj->membase->STATUS.WORD & 0x80) +#define I2C_FIFO_FULL (obj->membase->STATUS.WORD & 0x20) +#define FIFO_OFL_CHECK (obj->membase->STATUS.WORD & 0x10) +#define I2C_BUS_ERR_CHECK (obj->membase->STATUS.WORD & 0x04) +#define RD_DATA_READY (obj->membase->STATUS.WORD & 0x02) +#define I2C_FIFO_EMPTY (obj->membase->STATUS.WORD & 0x01) #define I2C_API_STATUS_SUCCESS 0 #define PAD_REG_ADRS_BYTE_SIZE 4 +#define SEND_COMMAND(cmd) while(!I2C_FIFO_EMPTY); wait_us(1); obj->membase->CMD_REG = cmd; + /** Init I2C device. * @details * Sets the necessary registers. The baud rate is set default to 100K @@ -154,4 +158,4 @@ extern int32_t fI2cReadB(i2c_t *d, char *buf, int len); */ extern int32_t fI2cWriteB(i2c_t *d, const char *buf, int len); -#endif /* I2C_H_ */ +#endif /* I2C_H_ */ \ No newline at end of file diff --git a/targets/TARGET_ONSEMI/TARGET_NCS36510/i2c_api.c b/targets/TARGET_ONSEMI/TARGET_NCS36510/i2c_api.c index 8b254c8c90..1e134581a3 100644 --- a/targets/TARGET_ONSEMI/TARGET_NCS36510/i2c_api.c +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/i2c_api.c @@ -31,6 +31,7 @@ #include "i2c.h" #include "i2c_api.h" +#include "wait_api.h" #define I2C_READ_WRITE_BIT_MASK 0xFE @@ -151,10 +152,10 @@ int i2c_byte_read(i2c_t *obj, int last) /* TODO return size can be uint8_t */ } if(last) { /* ACK */ - obj->membase->CMD_REG = I2C_CMD_WDAT0; + SEND_COMMAND(I2C_CMD_WDAT0); } else { /* No ACK */ - obj->membase->CMD_REG = I2C_CMD_WDAT1; + SEND_COMMAND(I2C_CMD_WDAT1); } return data; } @@ -168,8 +169,6 @@ int i2c_byte_write(i2c_t *obj, int data) return Count; } - obj->membase->CMD_REG = I2C_CMD_VRFY_ACK; /* Verify ACK */ - while(obj->membase->STATUS.WORD & I2C_STATUS_CMD_FIFO_OFL_BIT); /* Wait till command overflow ends */ if(obj->membase->STATUS.WORD & I2C_STATUS_BUS_ERR_BIT) { @@ -181,4 +180,4 @@ int i2c_byte_write(i2c_t *obj, int data) } } -#endif /* DEVICE_I2C */ +#endif /* DEVICE_I2C */ \ No newline at end of file diff --git a/targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_i2c.c b/targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_i2c.c index 784ea31bc1..f4cae19428 100644 --- a/targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_i2c.c +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_i2c.c @@ -60,6 +60,7 @@ */ #if DEVICE_I2C #include "i2c.h" +#include "wait_api.h" /* See i2c.h for details */ void fI2cInit(i2c_t *obj,PinName sda,PinName scl) @@ -135,7 +136,7 @@ void fI2cFrequency(i2c_t *obj, uint32_t hz) int32_t fI2cStart(i2c_t *obj) { /* Send start bit */ - obj->membase->CMD_REG = I2C_CMD_START; + SEND_COMMAND(I2C_CMD_START); return I2C_API_STATUS_SUCCESS; } @@ -143,7 +144,7 @@ int32_t fI2cStart(i2c_t *obj) int32_t fI2cStop(i2c_t *obj) { /* Send stop bit */ - obj->membase->CMD_REG = I2C_CMD_STOP; + SEND_COMMAND(I2C_CMD_STOP); if (obj->membase->STATUS.WORD & (I2C_STATUS_CMD_FIFO_FULL_BIT | I2C_STATUS_CMD_FIFO_OFL_BIT | I2C_STATUS_BUS_ERR_BIT)) { @@ -154,23 +155,26 @@ int32_t fI2cStop(i2c_t *obj) } /* See i2c.h for details */ -int32_t fI2cReadB(i2c_t *d, char *buf, int len) +int32_t fI2cReadB(i2c_t *obj, char *buf, int len) { int32_t read = 0; while (read < len) { /* Send read command */ - d->membase->CMD_REG = I2C_CMD_RDAT8; + SEND_COMMAND(I2C_CMD_RDAT8); while(!RD_DATA_READY) { if (I2C_BUS_ERR_CHECK) { /* Bus error occured */ return I2C_ERROR_BUS_BUSY; } } - buf[read++] = d->membase->RD_FIFO_REG; /**< Reading 'read FIFO register' will clear status register */ + buf[read++] = obj->membase->RD_FIFO_REG; /**< Reading 'read FIFO register' will clear status register */ if(!(read>=len)) { /* No ACK will be generated for the last read, upper level I2C protocol should generate */ - d->membase->CMD_REG=I2C_CMD_WDAT0; /* TODO based on requirement generate ACK or NACK Based on the requirement. */ + SEND_COMMAND(I2C_CMD_WDAT0); /* TODO based on requirement generate ACK or NACK Based on the requirement. */ + } else { + /* No ack */ + SEND_COMMAND(I2C_CMD_WDAT1); } /* check for FIFO underflow */ @@ -187,42 +191,49 @@ int32_t fI2cReadB(i2c_t *d, char *buf, int len) } /* See i2c.h for details */ -int32_t fI2cWriteB(i2c_t *d, const char *buf, int len) +int32_t fI2cWriteB(i2c_t *obj, const char *buf, int len) { int32_t write = 0; while (write < len) { /* Send write command */ - d->membase->CMD_REG = I2C_CMD_WDAT8; + SEND_COMMAND(I2C_CMD_WDAT8); + if(buf[write] == I2C_CMD_RDAT8) { /* SW work around to counter FSM issue. If the only command in the CMD FIFO is the WDAT8 command (data of 0x13) then as the command is read out (i.e. the FIFO goes empty), the WDAT8 command will be misinterpreted as a RDAT8 command by the data FSM; resulting in an I2C bus error (NACK instead of an ACK). */ /* Send 0x13 bit wise */ - d->membase->CMD_REG = I2C_CMD_WDAT0; - d->membase->CMD_REG = I2C_CMD_WDAT0; - d->membase->CMD_REG = I2C_CMD_WDAT0; - d->membase->CMD_REG = I2C_CMD_WDAT1; + SEND_COMMAND(I2C_CMD_WDAT0); - d->membase->CMD_REG = I2C_CMD_WDAT0; - d->membase->CMD_REG = I2C_CMD_WDAT0; - d->membase->CMD_REG = I2C_CMD_WDAT1; - d->membase->CMD_REG = I2C_CMD_WDAT1; + SEND_COMMAND(I2C_CMD_WDAT0); + + SEND_COMMAND(I2C_CMD_WDAT0); + + SEND_COMMAND(I2C_CMD_WDAT1); + + SEND_COMMAND(I2C_CMD_WDAT0); + + SEND_COMMAND(I2C_CMD_WDAT0); + + SEND_COMMAND(I2C_CMD_WDAT1); + + SEND_COMMAND(I2C_CMD_WDAT1); } else { /* Send data */ - d->membase->CMD_REG = buf[write++]; + SEND_COMMAND(buf[write++]); } - d->membase->CMD_REG = I2C_CMD_VRFY_ACK; /* TODO Verify ACK based on requirement, Do we need? */ - - while(FIFO_OFL_CHECK); /* Wait till command overflow ends */ + SEND_COMMAND(I2C_CMD_VRFY_ACK); /* TODO Verify ACK based on requirement, Do we need? */ if (I2C_BUS_ERR_CHECK) { /* Bus error */ return I2C_ERROR_BUS_BUSY; } + + while(FIFO_OFL_CHECK); /* Wait till command overflow ends */ } return write; } -#endif /* DEVICE_I2C */ +#endif /* DEVICE_I2C */ \ No newline at end of file diff --git a/targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_lp_ticker_api.c b/targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_lp_ticker_api.c index 9663cd66be..324dbb32f3 100644 --- a/targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_lp_ticker_api.c +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_lp_ticker_api.c @@ -34,12 +34,10 @@ #include "device.h" #if DEVICE_LOWPOWERTIMER -#include "sleep_api.h" #include "cmsis_nvic.h" #include "lp_ticker_api.h" #include "rtc.h" #include "rtc_map.h" -#include "sleep.h" /* Initialize the RTC for low power ticker */ void lp_ticker_init() diff --git a/targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_us_ticker_api.c b/targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_us_ticker_api.c index 8ba3759775..abed10ef06 100644 --- a/targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_us_ticker_api.c +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_us_ticker_api.c @@ -37,7 +37,7 @@ static int us_ticker_inited = 0; static void us_timer_init(void); -static uint32_t us_ticker_int_counter = 0; +static uint32_t us_ticker_target = 0; static volatile uint32_t msb_counter = 0; void us_ticker_init(void) @@ -168,20 +168,25 @@ extern void us_ticker_isr(void) /* Clear IRQ flag */ TIM1REG->CLEAR = 0; - /* If this is a longer timer it will take multiple full hw counter cycles */ - if (us_ticker_int_counter > 0) { - ticker_set(0xFFFF); - us_ticker_int_counter--; - } else { + int32_t delta = us_ticker_target - us_ticker_read(); + if (delta <= 0) { TIM1REG->CONTROL.BITS.ENABLE = False; us_ticker_irq_handler(); + } else { + // Clamp at max value of timer + if (delta > 0xFFFF) { + delta = 0xFFFF; + } + + ticker_set(delta); } } /* Set timer 1 ticker interrupt */ void us_ticker_set_interrupt(timestamp_t timestamp) { - int32_t delta = (uint32_t)timestamp - us_ticker_read(); + us_ticker_target = (uint32_t)timestamp; + int32_t delta = us_ticker_target - us_ticker_read(); if (delta <= 0) { /* This event was in the past */ @@ -195,10 +200,10 @@ void us_ticker_set_interrupt(timestamp_t timestamp) return; } - /* Calculate how much delta falls outside the 16-bit counter range. */ - /* You will have to perform a full timer overflow for each bit above */ - /* that range. */ - us_ticker_int_counter = (uint32_t)(delta >> 16); + // Clamp at max value of timer + if (delta > 0xFFFF) { + delta = 0xFFFF; + } ticker_set(delta); } diff --git a/targets/TARGET_RENESAS/TARGET_RZ_A1H/gpio_irq_api.c b/targets/TARGET_RENESAS/TARGET_RZ_A1H/gpio_irq_api.c index 71a9fe1cdb..a4d780bff2 100644 --- a/targets/TARGET_RENESAS/TARGET_RZ_A1H/gpio_irq_api.c +++ b/targets/TARGET_RENESAS/TARGET_RZ_A1H/gpio_irq_api.c @@ -166,7 +166,6 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32 InterruptHandlerRegister((IRQn_Type)(nIRQn_h+obj->ch), (void (*)(uint32_t))irq_tbl[obj->ch]); INTCICR1 &= ~(0x3 << shift); GIC_SetPriority((IRQn_Type)(nIRQn_h+obj->ch), 5); - GIC_EnableIRQ((IRQn_Type)(nIRQn_h+obj->ch)); obj->int_enable = 1; __enable_irq(); diff --git a/targets/TARGET_STM/PinNamesTypes.h b/targets/TARGET_STM/PinNamesTypes.h index b7033a4245..d51be1905a 100644 --- a/targets/TARGET_STM/PinNamesTypes.h +++ b/targets/TARGET_STM/PinNamesTypes.h @@ -36,54 +36,118 @@ extern "C" { #endif -#define STM_PIN_DATA(MODE, PUPD, AFNUM) ((int)(((MODE & 0x0F) << 0) |\ - ((PUPD & 0x07) << 4) |\ - ((AFNUM & 0x0F) << 7))) +/* STM PIN data as used in pin_function is coded on 32 bits as below + * [2:0] Function (like in MODER reg) : Input / Output / Alt / Analog + * [3] Output Push-Pull / Open Drain (as in OTYPER reg) + * [5:4] as in PUPDR reg: No Pull, Pull-up, Pull-Donc + * [7:6] Reserved for speed config (as in OSPEEDR), but not used yet + * [11:8] Alternate Num (as in AFRL/AFRG reg) + * [16:12] Channel (Analog/Timer specific) + * [17] Inverted (Analog/Timer specific) + * [18] Analog ADC control - Only valid for specific families + * [32:19] Reserved + */ -#define STM_PIN_DATA_EXT(MODE, PUPD, AFNUM, CHANNEL, INVERTED) ((int)(((MODE & 0x0F) << 0) |\ - ((PUPD & 0x07) << 4) |\ - ((AFNUM & 0x0F) << 7) |\ - ((CHANNEL & 0x1F) << 11) |\ - ((INVERTED & 0x01) << 16))) +#define STM_PIN_FUNCTION_MASK 0x07 +#define STM_PIN_FUNCTION_SHIFT 0 +#define STM_PIN_FUNCTION_BITS (STM_PIN_FUNCTION_MASK << STM_PIN_FUNCTION_SHIFT) -#define STM_PIN_MODE(X) (((X) >> 0) & 0x0F) -#define STM_PIN_PUPD(X) (((X) >> 4) & 0x07) -#define STM_PIN_AFNUM(X) (((X) >> 7) & 0x0F) -#define STM_PIN_CHANNEL(X) (((X) >> 11) & 0x1F) -#define STM_PIN_INVERTED(X) (((X) >> 16) & 0x01) +#define STM_PIN_OD_MASK 0x01 +#define STM_PIN_OD_SHIFT 3 +#define STM_PIN_OD_BITS (STM_PIN_OD_MASK << STM_PIN_OD_SHIFT) -#define STM_MODE_INPUT (0) -#define STM_MODE_OUTPUT_PP (1) -#define STM_MODE_OUTPUT_OD (2) -#define STM_MODE_AF_PP (3) -#define STM_MODE_AF_OD (4) -#define STM_MODE_ANALOG (5) -#define STM_MODE_IT_RISING (6) -#define STM_MODE_IT_FALLING (7) -#define STM_MODE_IT_RISING_FALLING (8) -#define STM_MODE_EVT_RISING (9) -#define STM_MODE_EVT_FALLING (10) -#define STM_MODE_EVT_RISING_FALLING (11) -#define STM_MODE_IT_EVT_RESET (12) -// The last mode is only valid for specific families, so we put it in the end -#define STM_MODE_ANALOG_ADC_CONTROL (13) +#define STM_PIN_PUPD_MASK 0x03 +#define STM_PIN_PUPD_SHIFT 4 +#define STM_PIN_PUPD_BITS (STM_PIN_PUPD_MASK << STM_PIN_PUPD_SHIFT) + +#define STM_PIN_SPEED_MASK 0x03 +#define STM_PIN_SPEED_SHIFT 6 +#define STM_PIN_SPEED_BITS (STM_PIN_SPEED_MASK << STM_PIN_SPEED_SHIFT) + +#define STM_PIN_AFNUM_MASK 0x0F +#define STM_PIN_AFNUM_SHIFT 8 +#define STM_PIN_AFNUM_BITS (STM_PIN_AFNUM_MASK << STM_PIN_AFNUM_SHIFT) + +#define STM_PIN_CHAN_MASK 0x1F +#define STM_PIN_CHAN_SHIFT 12 +#define STM_PIN_CHANNEL_BIT (STM_PIN_CHAN_MASK << STM_PIN_CHAN_SHIFT) + +#define STM_PIN_INV_MASK 0x01 +#define STM_PIN_INV_SHIFT 17 +#define STM_PIN_INV_BIT (STM_PIN_INV_MASK << STM_PIN_INV_SHIFT) + +#define STM_PIN_AN_CTRL_MASK 0x01 +#define STM_PIN_AN_CTRL_SHIFT 18 +#define STM_PIN_ANALOG_CONTROL_BIT (STM_PIN_AN_CTRL_MASK << STM_PIN_AN_CTRL_SHIFT) + +#define STM_PIN_FUNCTION(X) (((X) >> STM_PIN_FUNCTION_SHIFT) & STM_PIN_FUNCTION_MASK) +#define STM_PIN_OD(X) (((X) >> STM_PIN_OD_SHIFT) & STM_PIN_OD_MASK) +#define STM_PIN_PUPD(X) (((X) >> STM_PIN_PUPD_SHIFT) & STM_PIN_PUPD_MASK) +#define STM_PIN_SPEED(X) (((X) >> STM_PIN_SPEED_SHIFT) & STM_PIN_SPEED_MASK) +#define STM_PIN_AFNUM(X) (((X) >> STM_PIN_AFNUM_SHIFT) & STM_PIN_AFNUM_MASK) +#define STM_PIN_CHANNEL(X) (((X) >> STM_PIN_CHAN_SHIFT) & STM_PIN_CHAN_MASK) +#define STM_PIN_INVERTED(X) (((X) >> STM_PIN_INV_SHIFT) & STM_PIN_INV_MASK) +#define STM_PIN_ANALOG_CONTROL(X) (((X) >> STM_PIN_AN_CTRL_SHIFT) & STM_PIN_AN_CTRL_MASK) + +#define STM_PIN_DEFINE(FUNC_OD, PUPD, AFNUM) ((int)(FUNC_OD) |\ + ((PUPD & STM_PIN_PUPD_MASK) << STM_PIN_PUPD_SHIFT) |\ + ((AFNUM & STM_PIN_AFNUM_MASK) << STM_PIN_AFNUM_SHIFT)) + +#define STM_PIN_DEFINE_EXT(FUNC_OD, PUPD, AFNUM, CHAN, INV) \ + ((int)(FUNC_OD) |\ + ((PUPD & STM_PIN_PUPD_MASK) << STM_PIN_PUPD_SHIFT) |\ + ((AFNUM & STM_PIN_AFNUM_MASK) << STM_PIN_AFNUM_SHIFT) |\ + ((CHAN & STM_PIN_CHAN_MASK) << STM_PIN_CHAN_SHIFT) |\ + ((INV & STM_PIN_INV_MASK) << STM_PIN_INV_SHIFT)) + +/* + * MACROS to support the legacy definition of PIN formats + * The STM_MODE_ defines contain the function and the Push-pull/OpenDrain + * configuration (legacy inheritance). + */ +#define STM_PIN_DATA(FUNC_OD, PUPD, AFNUM) \ + STM_PIN_DEFINE(FUNC_OD, PUPD, AFNUM) +#define STM_PIN_DATA_EXT(FUNC_OD, PUPD, AFNUM, CHANNEL, INVERTED) \ + STM_PIN_DEFINE_EXT(FUNC_OD, PUPD, AFNUM, CHANNEL, INVERTED) + +typedef enum { + STM_PIN_INPUT = 0, + STM_PIN_OUTPUT = 1, + STM_PIN_ALTERNATE = 2, + STM_PIN_ANALOG = 3, +} StmPinFunction; + +#define STM_MODE_INPUT (STM_PIN_INPUT) +#define STM_MODE_OUTPUT_PP (STM_PIN_OUTPUT) +#define STM_MODE_OUTPUT_OD (STM_PIN_OUTPUT | STM_PIN_OD_BITS) +#define STM_MODE_AF_PP (STM_PIN_ALTERNATE) +#define STM_MODE_AF_OD (STM_PIN_ALTERNATE | STM_PIN_OD_BITS) +#define STM_MODE_ANALOG (STM_PIN_ANALOG) +#define STM_MODE_ANALOG_ADC_CONTROL (STM_PIN_ANALOG | STM_PIN_ANALOG_CONTROL_BIT) // High nibble = port number (0=A, 1=B, 2=C, 3=D, 4=E, 5=F, 6=G, 7=H) // Low nibble = pin number #define STM_PORT(X) (((uint32_t)(X) >> 4) & 0xF) #define STM_PIN(X) ((uint32_t)(X) & 0xF) +/* Defines to be used by application */ typedef enum { - PIN_INPUT, + PIN_INPUT = 0, PIN_OUTPUT } PinDirection; typedef enum { - PullNone = 0, - PullUp = 1, - PullDown = 2, - OpenDrain = 3, - PullDefault = PullNone + PullNone = 0, + PullUp = 1, + PullDown = 2, + OpenDrainPullUp = 3, + OpenDrainNoPull = 4, + OpenDrainPullDown = 5, + PushPullNoPull = PullNone, + PushPullPullUp = PullUp, + PushPullPullDown = PullDown, + OpenDrain = OpenDrainPullUp, + PullDefault = PullNone } PinMode; #ifdef __cplusplus @@ -91,3 +155,4 @@ typedef enum { #endif #endif + diff --git a/targets/TARGET_STM/TARGET_STM32F0/can_api.c b/targets/TARGET_STM/TARGET_STM32F0/can_api.c deleted file mode 100644 index 0f93832791..0000000000 --- a/targets/TARGET_STM/TARGET_STM32F0/can_api.c +++ /dev/null @@ -1,477 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-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 "can_api.h" - -#if DEVICE_CAN - -#include "cmsis.h" -#include "pinmap.h" -#include "PeripheralPins.h" -#include "mbed_error.h" -#include -#include - -#define CAN_NUM 1 -static CAN_HandleTypeDef CanHandle; -static uint32_t can_irq_ids[CAN_NUM] = {0}; -static can_irq_handler irq_handler; - -void can_init(can_t *obj, PinName rd, PinName td) -{ - CANName can_rd = (CANName)pinmap_peripheral(rd, PinMap_CAN_RD); - CANName can_td = (CANName)pinmap_peripheral(td, PinMap_CAN_TD); - obj->can = (CANName)pinmap_merge(can_rd, can_td); - MBED_ASSERT((int)obj->can != NC); - - if (obj->can == CAN_1) { - __HAL_RCC_CAN1_CLK_ENABLE(); - obj->index = 0; - } - - // Configure the CAN pins - pinmap_pinout(rd, PinMap_CAN_RD); - pinmap_pinout(td, PinMap_CAN_TD); - if (rd != NC) { - pin_mode(rd, PullUp); - } - if (td != NC) { - pin_mode(td, PullUp); - } - - CanHandle.Instance = (CAN_TypeDef *)(obj->can); - - CanHandle.Init.TTCM = DISABLE; - CanHandle.Init.ABOM = DISABLE; - CanHandle.Init.AWUM = DISABLE; - CanHandle.Init.NART = DISABLE; - CanHandle.Init.RFLM = DISABLE; - CanHandle.Init.TXFP = DISABLE; - CanHandle.Init.Mode = CAN_MODE_NORMAL; - CanHandle.Init.SJW = CAN_SJW_1TQ; - CanHandle.Init.BS1 = CAN_BS1_6TQ; - CanHandle.Init.BS2 = CAN_BS2_8TQ; - CanHandle.Init.Prescaler = 2; - - if (HAL_CAN_Init(&CanHandle) != HAL_OK) { - error("Cannot initialize CAN"); - } - // Set initial CAN frequency to 100kb/s - can_frequency(obj, 100000); - - can_filter(obj, 0, 0, CANStandard, 0); -} - -void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id) -{ - irq_handler = handler; - can_irq_ids[obj->index] = id; -} - -void can_irq_free(can_t *obj) -{ - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - can->IER &= ~(CAN_IT_FMP0 | CAN_IT_FMP1 | CAN_IT_TME | \ - CAN_IT_ERR | CAN_IT_EPV | CAN_IT_BOF); - can_irq_ids[obj->can] = 0; -} - -void can_free(can_t *obj) -{ - // Reset CAN and disable clock - if (obj->can == CAN_1) { - __HAL_RCC_CAN1_FORCE_RESET(); - __HAL_RCC_CAN1_RELEASE_RESET(); - __HAL_RCC_CAN1_CLK_DISABLE(); - } -} - -// The following table is used to program bit_timing. It is an adjustment of the sample -// point by synchronizing on the start-bit edge and resynchronizing on the following edges. -// This table has the sampling points as close to 75% as possible (most commonly used). -// The first value is TSEG1, the second TSEG2. -static const int timing_pts[23][2] = { - {0x0, 0x0}, // 2, 50% - {0x1, 0x0}, // 3, 67% - {0x2, 0x0}, // 4, 75% - {0x3, 0x0}, // 5, 80% - {0x3, 0x1}, // 6, 67% - {0x4, 0x1}, // 7, 71% - {0x5, 0x1}, // 8, 75% - {0x6, 0x1}, // 9, 78% - {0x6, 0x2}, // 10, 70% - {0x7, 0x2}, // 11, 73% - {0x8, 0x2}, // 12, 75% - {0x9, 0x2}, // 13, 77% - {0x9, 0x3}, // 14, 71% - {0xA, 0x3}, // 15, 73% - {0xB, 0x3}, // 16, 75% - {0xC, 0x3}, // 17, 76% - {0xD, 0x3}, // 18, 78% - {0xD, 0x4}, // 19, 74% - {0xE, 0x4}, // 20, 75% - {0xF, 0x4}, // 21, 76% - {0xF, 0x5}, // 22, 73% - {0xF, 0x6}, // 23, 70% - {0xF, 0x7}, // 24, 67% -}; - -static unsigned int can_speed(unsigned int pclk, unsigned int cclk, unsigned char psjw) -{ - uint32_t btr; - uint16_t brp = 0; - uint32_t calcbit; - uint32_t bitwidth; - int hit = 0; - int bits; - - bitwidth = (pclk / cclk); - - brp = bitwidth / 0x18; - while ((!hit) && (brp < bitwidth / 4)) { - brp++; - for (bits = 22; bits > 0; bits--) { - calcbit = (bits + 3) * (brp + 1); - if (calcbit == bitwidth) { - hit = 1; - break; - } - } - } - - if (hit) { - btr = ((timing_pts[bits][1] << 20) & 0x00700000) - | ((timing_pts[bits][0] << 16) & 0x000F0000) - | ((psjw << 24) & 0x0000C000) - | ((brp << 0) & 0x000003FF); - } else { - btr = 0xFFFFFFFF; - } - - return btr; - -} - -int can_frequency(can_t *obj, int f) -{ - int pclk = HAL_RCC_GetPCLK1Freq(); - int btr = can_speed(pclk, (unsigned int)f, 1); - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - if (btr > 0) { - can->MCR |= CAN_MCR_INRQ ; - while ((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { - } - can->BTR = btr; - can->MCR &= ~(uint32_t)CAN_MCR_INRQ; - while ((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { - } - return 1; - } else { - return 0; - } -} - -int can_write(can_t *obj, CAN_Message msg, int cc) -{ - uint32_t transmitmailbox = 5; - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - /* Select one empty transmit mailbox */ - if ((can->TSR&CAN_TSR_TME0) == CAN_TSR_TME0) { - transmitmailbox = 0; - } else if ((can->TSR&CAN_TSR_TME1) == CAN_TSR_TME1) { - transmitmailbox = 1; - } else if ((can->TSR&CAN_TSR_TME2) == CAN_TSR_TME2) { - transmitmailbox = 2; - } else { - transmitmailbox = CAN_TXSTATUS_NOMAILBOX; - } - - if (transmitmailbox != CAN_TXSTATUS_NOMAILBOX) { - can->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ; - if (!(msg.format)) { - can->sTxMailBox[transmitmailbox].TIR |= ((msg.id << 21) | msg.type); - } else { - can->sTxMailBox[transmitmailbox].TIR |= ((msg.id << 3) | CAN_ID_EXT | msg.type); - } - - /* Set up the DLC */ - can->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0; - can->sTxMailBox[transmitmailbox].TDTR |= (msg.len & (uint8_t)0x0000000F); - - /* Set up the data field */ - can->sTxMailBox[transmitmailbox].TDLR = (((uint32_t)msg.data[3] << 24) | - ((uint32_t)msg.data[2] << 16) | - ((uint32_t)msg.data[1] << 8) | - ((uint32_t)msg.data[0])); - can->sTxMailBox[transmitmailbox].TDHR = (((uint32_t)msg.data[7] << 24) | - ((uint32_t)msg.data[6] << 16) | - ((uint32_t)msg.data[5] << 8) | - ((uint32_t)msg.data[4])); - /* Request transmission */ - can->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ; - } - - return 1; -} - -int can_read(can_t *obj, CAN_Message *msg, int handle) -{ - //handle is the FIFO number - - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - // check FPM0 which holds the pending message count in FIFO 0 - // if no message is pending, return 0 - if ((can->RF0R & CAN_RF0R_FMP0) == 0) { - return 0; - } - - /* Get the Id */ - msg->format = (CANFormat)((uint8_t)0x04 & can->sFIFOMailBox[handle].RIR); - if (!msg->format) { - msg->id = (uint32_t)0x000007FF & (can->sFIFOMailBox[handle].RIR >> 21); - } else { - msg->id = (uint32_t)0x1FFFFFFF & (can->sFIFOMailBox[handle].RIR >> 3); - } - - msg->type = (CANType)((uint8_t)0x02 & can->sFIFOMailBox[handle].RIR); - /* Get the DLC */ - msg->len = (uint8_t)0x0F & can->sFIFOMailBox[handle].RDTR; -// /* Get the FMI */ -// msg->FMI = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDTR >> 8); - /* Get the data field */ - msg->data[0] = (uint8_t)0xFF & can->sFIFOMailBox[handle].RDLR; - msg->data[1] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDLR >> 8); - msg->data[2] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDLR >> 16); - msg->data[3] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDLR >> 24); - msg->data[4] = (uint8_t)0xFF & can->sFIFOMailBox[handle].RDHR; - msg->data[5] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDHR >> 8); - msg->data[6] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDHR >> 16); - msg->data[7] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDHR >> 24); - - /* Release the FIFO */ - if (handle == CAN_FIFO0) { - /* Release FIFO0 */ - can->RF0R |= CAN_RF0R_RFOM0; - } else { /* FIFONumber == CAN_FIFO1 */ - /* Release FIFO1 */ - can->RF1R |= CAN_RF1R_RFOM1; - } - - return 1; -} - -void can_reset(can_t *obj) -{ - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - can->MCR |= CAN_MCR_RESET; - can->ESR = 0x0; -} - -unsigned char can_rderror(can_t *obj) -{ - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - return (can->ESR >> 24) & 0xFF; -} - -unsigned char can_tderror(can_t *obj) -{ - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - return (can->ESR >> 16) & 0xFF; -} - -void can_monitor(can_t *obj, int silent) -{ - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - can->MCR |= CAN_MCR_INRQ ; - while((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { - } - if (silent) { - can->BTR |= ((uint32_t)1 << 31); - } else { - can->BTR &= ~((uint32_t)1 << 31); - } - can->MCR &= ~(uint32_t)CAN_MCR_INRQ; - while((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { - } -} - -int can_mode(can_t *obj, CanMode mode) -{ - int success = 0; - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - can->MCR |= CAN_MCR_INRQ ; - while ((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { - } - switch (mode) { - case MODE_NORMAL: - can->BTR &= ~(CAN_BTR_SILM | CAN_BTR_LBKM); - success = 1; - break; - case MODE_SILENT: - can->BTR |= CAN_BTR_SILM; - can->BTR &= ~CAN_BTR_LBKM; - success = 1; - break; - case MODE_TEST_GLOBAL: - case MODE_TEST_LOCAL: - can->BTR |= CAN_BTR_LBKM; - can->BTR &= ~CAN_BTR_SILM; - success = 1; - break; - case MODE_TEST_SILENT: - can->BTR |= (CAN_BTR_SILM | CAN_BTR_LBKM); - success = 1; - break; - default: - success = 0; - break; - } - can->MCR &= ~(uint32_t)CAN_MCR_INRQ; - while ((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { - } - return success; -} - -int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) -{ - int retval = 0; - - // filter for CANAny format cannot be configured for STM32 - if ((format == CANStandard) || (format == CANExtended)) { - CanHandle.Instance = (CAN_TypeDef *)(obj->can); - CAN_FilterConfTypeDef sFilterConfig; - sFilterConfig.FilterNumber = handle; - sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; - sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; - - if (format == CANStandard) { - sFilterConfig.FilterIdHigh = id << 5; - sFilterConfig.FilterIdLow = 0x0; - sFilterConfig.FilterMaskIdHigh = mask << 5; - sFilterConfig.FilterMaskIdLow = 0x0; // allows both remote and data frames - } else if (format == CANExtended) { - sFilterConfig.FilterIdHigh = id >> 13; // EXTID[28:13] - sFilterConfig.FilterIdLow = (0x00FF & (id << 3)) | (1 << 2); // EXTID[12:0] - sFilterConfig.FilterMaskIdHigh = mask >> 13; - sFilterConfig.FilterMaskIdLow = (0x00FF & (mask << 3)) | (1 << 2); - } - - sFilterConfig.FilterFIFOAssignment = 0; - sFilterConfig.FilterActivation = ENABLE; - sFilterConfig.BankNumber = 14 + handle; - - HAL_CAN_ConfigFilter(&CanHandle, &sFilterConfig); - retval = handle; - } - return retval; -} - -static void can_irq(CANName name, int id) -{ - uint32_t tmp1 = 0, tmp2 = 0, tmp3 = 0; - CanHandle.Instance = (CAN_TypeDef *)name; - - if (__HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_TME)) { - tmp1 = __HAL_CAN_TRANSMIT_STATUS(&CanHandle, CAN_TXMAILBOX_0); - tmp2 = __HAL_CAN_TRANSMIT_STATUS(&CanHandle, CAN_TXMAILBOX_1); - tmp3 = __HAL_CAN_TRANSMIT_STATUS(&CanHandle, CAN_TXMAILBOX_2); - if(tmp1 || tmp2 || tmp3) - { - irq_handler(can_irq_ids[id], IRQ_TX); - } - } - - tmp1 = __HAL_CAN_MSG_PENDING(&CanHandle, CAN_FIFO0); - tmp2 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_FMP0); - - if ((tmp1 != 0) && tmp2) { - irq_handler(can_irq_ids[id], IRQ_RX); - } - - tmp1 = __HAL_CAN_GET_FLAG(&CanHandle, CAN_FLAG_EPV); - tmp2 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_EPV); - tmp3 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_ERR); - - if (tmp1 && tmp2 && tmp3) { - irq_handler(can_irq_ids[id], IRQ_PASSIVE); - } - - tmp1 = __HAL_CAN_GET_FLAG(&CanHandle, CAN_FLAG_BOF); - tmp2 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_BOF); - tmp3 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_ERR); - if (tmp1 && tmp2 && tmp3) { - irq_handler(can_irq_ids[id], IRQ_BUS); - } - - tmp3 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_ERR); - if (tmp1 && tmp2 && tmp3) { - irq_handler(can_irq_ids[id], IRQ_ERROR); - } -} - -void CAN_IRQHandler(void) -{ - can_irq(CAN_1, 0); -} - -void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable) -{ - - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - IRQn_Type irq_n = (IRQn_Type)0; - uint32_t vector = 0; - uint32_t ier; - - if (obj->can == CAN_1) { - switch (type) { - case IRQ_RX: - ier = CAN_IT_FMP0; - break; - case IRQ_TX: - ier = CAN_IT_TME; - break; - case IRQ_ERROR: - ier = CAN_IT_ERR; - break; - case IRQ_PASSIVE: - ier = CAN_IT_EPV; - break; - case IRQ_BUS: - ier = CAN_IT_BOF; - break; - default: return; - } - irq_n = CEC_CAN_IRQn; - vector = (uint32_t)&CAN_IRQHandler; - } - - if (enable) { - can->IER |= ier; - } else { - can->IER &= ~ier; - } - - NVIC_SetVector(irq_n, vector); - NVIC_EnableIRQ(irq_n); -} - -#endif // DEVICE_CAN - diff --git a/targets/TARGET_STM/TARGET_STM32F0/can_device.h b/targets/TARGET_STM/TARGET_STM32F0/can_device.h new file mode 100644 index 0000000000..c0ab4bf66d --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F0/can_device.h @@ -0,0 +1,42 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-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. + */ +#ifndef MBED_CAN_DEVICE_H +#define MBED_CAN_DEVICE_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef DEVICE_CAN + +#define CAN_NUM 1 // Number of CAN peripherals present in the STM32 serie + +#define CAN1_IRQ_RX_IRQN CEC_CAN_IRQn +#define CAN1_IRQ_RX_VECT CAN_IRQHandler +#define CAN1_IRQ_TX_IRQN CEC_CAN_IRQn +#define CAN1_IRQ_TX_VECT CAN_IRQHandler +#define CAN1_IRQ_ERROR_IRQN CEC_CAN_IRQn +#define CAN1_IRQ_ERROR_VECT CAN_IRQHandler +#define CAN1_IRQ_PASSIVE_IRQN CEC_CAN_IRQn +#define CAN1_IRQ_PASSIVE_VECT CAN_IRQHandler +#define CAN1_IRQ_BUS_IRQN CEC_CAN_IRQn +#define CAN1_IRQ_BUS_VECT CAN_IRQHandler + +#endif // DEVICE_CAN + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32F0/gpio_irq_api.c b/targets/TARGET_STM/TARGET_STM32F0/gpio_irq_api.c deleted file mode 100644 index 127aae939d..0000000000 --- a/targets/TARGET_STM/TARGET_STM32F0/gpio_irq_api.c +++ /dev/null @@ -1,270 +0,0 @@ -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include -#include "cmsis.h" -#include "gpio_irq_api.h" -#include "pinmap.h" -#include "mbed_error.h" - -#define EDGE_NONE (0) -#define EDGE_RISE (1) -#define EDGE_FALL (2) -#define EDGE_BOTH (3) - -// Number of EXTI irq vectors (EXTI0_1, EXTI2_3, EXTI4_15) -#define CHANNEL_NUM (3) - -// Max pins for one line (max with EXTI4_15) -#define MAX_PIN_LINE (12) - -typedef struct gpio_channel { - uint32_t pin_mask; // bitmask representing which pins are configured for receiving interrupts - uint32_t channel_ids[MAX_PIN_LINE]; // mbed "gpio_irq_t gpio_irq" field of instance - uint32_t channel_gpio[MAX_PIN_LINE]; // base address of gpio port group - uint32_t channel_pin[MAX_PIN_LINE]; // pin number in port group -} gpio_channel_t; - -static gpio_channel_t channels[CHANNEL_NUM] = { - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0} -}; - -// Used to return the index for channels array. -static uint32_t pin_base_nr[16] = { - // EXTI0_1 - 0, // pin 0 - 1, // pin 1 - // EXTI2_3 - 0, // pin 2 - 1, // pin 3 - // EXTI4_15 - 0, // pin 4 - 1, // pin 5 - 2, // pin 6 - 3, // pin 7 - 4, // pin 8 - 5, // pin 9 - 6, // pin 10 - 7, // pin 11 - 8, // pin 12 - 9, // pin 13 - 10, // pin 14 - 11 // pin 15 -}; - -static gpio_irq_handler irq_handler; - -static void handle_interrupt_in(uint32_t irq_index, uint32_t max_num_pin_line) -{ - gpio_channel_t *gpio_channel = &channels[irq_index]; - uint32_t gpio_idx; - - for (gpio_idx = 0; gpio_idx < max_num_pin_line; gpio_idx++) { - uint32_t current_mask = (1 << gpio_idx); - - if (gpio_channel->pin_mask & current_mask) { - // Retrieve the gpio and pin that generate the irq - GPIO_TypeDef *gpio = (GPIO_TypeDef *)(gpio_channel->channel_gpio[gpio_idx]); - uint32_t pin = (uint32_t)(1 << (gpio_channel->channel_pin[gpio_idx])); - - // Clear interrupt flag - if (__HAL_GPIO_EXTI_GET_FLAG(pin) != RESET) { - __HAL_GPIO_EXTI_CLEAR_FLAG(pin); - - if (gpio_channel->channel_ids[gpio_idx] == 0) continue; - - // Check which edge has generated the irq - if ((gpio->IDR & pin) == 0) { - irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_FALL); - } else { - irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_RISE); - } - } - } - } -} - -// EXTI lines 0 to 1 -static void gpio_irq0(void) -{ - handle_interrupt_in(0, 2); -} - -// EXTI lines 2 to 3 -static void gpio_irq1(void) -{ - handle_interrupt_in(1, 2); -} - -// EXTI lines 4 to 15 -static void gpio_irq2(void) -{ - handle_interrupt_in(2, 12); -} - -extern uint32_t Set_GPIO_Clock(uint32_t port_idx); -extern void pin_function_gpiomode(PinName pin, uint32_t gpiomode); - -int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) -{ - IRQn_Type irq_n = (IRQn_Type)0; - uint32_t vector = 0; - uint32_t irq_index; - gpio_channel_t *gpio_channel; - uint32_t gpio_idx; - - if (pin == NC) return -1; - - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - - // Select irq number and interrupt routine - if ((pin_index == 0) || (pin_index == 1)) { - irq_n = EXTI0_1_IRQn; - vector = (uint32_t)&gpio_irq0; - irq_index = 0; - } else if ((pin_index == 2) || (pin_index == 3)) { - irq_n = EXTI2_3_IRQn; - vector = (uint32_t)&gpio_irq1; - irq_index = 1; - } else if ((pin_index > 3) && (pin_index < 16)) { - irq_n = EXTI4_15_IRQn; - vector = (uint32_t)&gpio_irq2; - irq_index = 2; - } else { - error("InterruptIn error: pin not supported.\n"); - return -1; - } - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - - // Configure GPIO - pin_function(pin, STM_PIN_DATA(STM_MODE_IT_FALLING, GPIO_NOPULL, 0)); - - // Enable EXTI interrupt - NVIC_SetVector(irq_n, vector); - NVIC_EnableIRQ(irq_n); - - // Save informations for future use - obj->irq_n = irq_n; - obj->irq_index = irq_index; - obj->event = EDGE_NONE; - obj->pin = pin; - - gpio_channel = &channels[irq_index]; - gpio_idx = pin_base_nr[pin_index]; - gpio_channel->pin_mask |= (1 << gpio_idx); - gpio_channel->channel_ids[gpio_idx] = id; - gpio_channel->channel_gpio[gpio_idx] = gpio_add; - gpio_channel->channel_pin[gpio_idx] = pin_index; - - irq_handler = handler; - - return 0; -} - -void gpio_irq_free(gpio_irq_t *obj) -{ - gpio_channel_t *gpio_channel = &channels[obj->irq_index]; - uint32_t pin_index = STM_PIN(obj->pin); - uint32_t gpio_addr = GPIOA_BASE + (GPIOB_BASE-GPIOA_BASE) * STM_PORT(obj->pin); - uint32_t gpio_idx = pin_base_nr[pin_index]; - - HAL_GPIO_DeInit((GPIO_TypeDef *)gpio_addr, (1<pin_mask &= ~(1 << gpio_idx); - gpio_channel->channel_ids[gpio_idx] = 0; - gpio_channel->channel_gpio[gpio_idx] = 0; - gpio_channel->channel_pin[gpio_idx] = 0; - - // Disable EXTI line, but don't change pull-up config - pin_function_gpiomode(obj->pin, STM_MODE_INPUT); - obj->event = EDGE_NONE; -} - -void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) -{ - uint32_t mode = STM_MODE_IT_EVT_RESET; - uint32_t pull = GPIO_NOPULL; - - if (enable) { - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or RISE - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or FALL - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } - } - } else { // Disable - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } else { // NONE or RISE - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } else { // NONE or FALL - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } - } - } - - pin_function_gpiomode(obj->pin, mode); -} - -void gpio_irq_enable(gpio_irq_t *obj) -{ - NVIC_EnableIRQ(obj->irq_n); -} - -void gpio_irq_disable(gpio_irq_t *obj) -{ - NVIC_DisableIRQ(obj->irq_n); - obj->event = EDGE_NONE; -} diff --git a/targets/TARGET_STM/TARGET_STM32F0/gpio_irq_device.c b/targets/TARGET_STM/TARGET_STM32F0/gpio_irq_device.c new file mode 100644 index 0000000000..542dc01b46 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F0/gpio_irq_device.c @@ -0,0 +1,55 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2017, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include "cmsis.h" +#include "gpio_irq_device.h" + +// Used to return the index for channels array. +const exti_lines_t pin_lines_desc[16] = { + // EXTI0_1 + {.gpio_idx = 0, .irq_index = 0, .irq_n = EXTI0_1_IRQn}, // pin 0 + {.gpio_idx = 1, .irq_index = 0, .irq_n = EXTI0_1_IRQn}, // pin 1 + // EXTI2_3 + {.gpio_idx = 0, .irq_index = 1, .irq_n = EXTI2_3_IRQn}, // pin 2 + {.gpio_idx = 1, .irq_index = 1, .irq_n = EXTI2_3_IRQn}, // pin 3 + // EXTI4_15 + {.gpio_idx = 0, .irq_index = 2, .irq_n = EXTI4_15_IRQn}, // pin 4 + {.gpio_idx = 1, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 5 + {.gpio_idx = 2, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 6 + {.gpio_idx = 3, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 7 + {.gpio_idx = 4, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 8 + {.gpio_idx = 5, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 9 + {.gpio_idx = 6, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 10 + {.gpio_idx = 7, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 11 + {.gpio_idx = 8, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 12 + {.gpio_idx = 9, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 13 + {.gpio_idx = 10, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 14 + {.gpio_idx = 11, .irq_index = 2, .irq_n = EXTI4_15_IRQn}// pin 15 +}; + diff --git a/targets/TARGET_STM/TARGET_STM32F0/gpio_irq_device.h b/targets/TARGET_STM/TARGET_STM32F0/gpio_irq_device.h new file mode 100644 index 0000000000..d5754f0da0 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F0/gpio_irq_device.h @@ -0,0 +1,62 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2017, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef MBED_GPIO_IRQ_DEVICE_H +#define MBED_GPIO_IRQ_DEVICE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stm32f0xx_ll_exti.h" + +// Number of EXTI irq vectors (EXTI0_1, EXTI2_3, EXTI4_15) +#define CHANNEL_NUM (3) + +#define EXTI_IRQ0_NUM_LINES 2 +#define EXTI_IRQ1_NUM_LINES 2 +#define EXTI_IRQ2_NUM_LINES 12 +// Max pins for one line (max with EXTI4_15) +#define MAX_PIN_LINE (EXTI_IRQ2_NUM_LINES) + +/* Structure to describe how the HW EXTI lines are defined in this HW */ +typedef struct exti_lines { + uint32_t gpio_idx; // an index entry for each EXIT line + uint32_t irq_index; // the IRQ index + IRQn_Type irq_n; // the corresponding EXTI IRQn +} exti_lines_t; + +// Used to return the index for channels array. +extern const exti_lines_t pin_lines_desc[]; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32F0/pin_device.h b/targets/TARGET_STM/TARGET_STM32F0/pin_device.h new file mode 100644 index 0000000000..158ad745b3 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F0/pin_device.h @@ -0,0 +1,69 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2016, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef MBED_PIN_DEVICE_H +#define MBED_PIN_DEVICE_H + +#include "cmsis.h" +#include "stm32f0xx_ll_gpio.h" + +extern const uint32_t ll_pin_defines[16]; + +/* Family specific implementations */ +static inline void stm_pin_DisconnectDebug(PinName pin) +{ + /* empty for now */ +} + +static inline void stm_pin_PullConfig(GPIO_TypeDef *gpio, uint32_t ll_pin, uint32_t pull_config) +{ + switch (pull_config) { + case GPIO_PULLUP: + LL_GPIO_SetPinPull(gpio, ll_pin, LL_GPIO_PULL_UP); + break; + case GPIO_PULLDOWN: + LL_GPIO_SetPinPull(gpio, ll_pin, LL_GPIO_PULL_DOWN); + break; + default: + LL_GPIO_SetPinPull(gpio, ll_pin, LL_GPIO_PULL_NO); + break; + } +} + +static inline void stm_pin_SetAFPin( GPIO_TypeDef *gpio, PinName pin, uint32_t afnum) +{ + uint32_t ll_pin = ll_pin_defines[STM_PIN(pin)]; + + if (STM_PIN(pin) > 7) + LL_GPIO_SetAFPin_8_15(gpio, ll_pin, afnum); + else + LL_GPIO_SetAFPin_0_7(gpio, ll_pin, afnum); +} + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32F0/pinmap.c b/targets/TARGET_STM/TARGET_STM32F0/pinmap.c deleted file mode 100644 index 791b8736bd..0000000000 --- a/targets/TARGET_STM/TARGET_STM32F0/pinmap.c +++ /dev/null @@ -1,157 +0,0 @@ -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "mbed_assert.h" -#include "pinmap.h" -#include "PortNames.h" -#include "mbed_error.h" - -// GPIO mode look-up table -static const uint32_t gpio_mode[13] = { - 0x00000000, // 0 = GPIO_MODE_INPUT - 0x00000001, // 1 = GPIO_MODE_OUTPUT_PP - 0x00000011, // 2 = GPIO_MODE_OUTPUT_OD - 0x00000002, // 3 = GPIO_MODE_AF_PP - 0x00000012, // 4 = GPIO_MODE_AF_OD - 0x00000003, // 5 = GPIO_MODE_ANALOG - 0x10110000, // 6 = GPIO_MODE_IT_RISING - 0x10210000, // 7 = GPIO_MODE_IT_FALLING - 0x10310000, // 8 = GPIO_MODE_IT_RISING_FALLING - 0x10120000, // 9 = GPIO_MODE_EVT_RISING - 0x10220000, // 10 = GPIO_MODE_EVT_FALLING - 0x10320000, // 11 = GPIO_MODE_EVT_RISING_FALLING - 0x10000000 // 12 = Reset IT and EVT (not in STM32Cube HAL) -}; - -// Enable GPIO clock and return GPIO base address -uint32_t Set_GPIO_Clock(uint32_t port_idx) { - uint32_t gpio_add = 0; - switch (port_idx) { - case PortA: - gpio_add = GPIOA_BASE; - __GPIOA_CLK_ENABLE(); - break; - case PortB: - gpio_add = GPIOB_BASE; - __GPIOB_CLK_ENABLE(); - break; -#if defined(GPIOC_BASE) - case PortC: - gpio_add = GPIOC_BASE; - __GPIOC_CLK_ENABLE(); - break; -#endif -#if defined(GPIOD_BASE) - case PortD: - gpio_add = GPIOD_BASE; - __GPIOD_CLK_ENABLE(); - break; -#endif -#if defined(GPIOF_BASE) - case PortF: - gpio_add = GPIOF_BASE; - __GPIOF_CLK_ENABLE(); - break; -#endif - default: - error("Pinmap error: wrong port number."); - break; - } - return gpio_add; -} - -/** - * Configure pin (mode, speed, output type and pull-up/pull-down) - */ -void pin_function(PinName pin, int data) { - MBED_ASSERT(pin != (PinName)NC); - - // Get the pin informations - uint32_t mode = STM_PIN_MODE(data); - uint32_t pupd = STM_PIN_PUPD(data); - uint32_t afnum = STM_PIN_AFNUM(data); - - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add; - - // Configure GPIO - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.Pin = (uint32_t)(1 << pin_index); - GPIO_InitStructure.Mode = gpio_mode[mode]; - GPIO_InitStructure.Pull = pupd; - GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; - GPIO_InitStructure.Alternate = afnum; - HAL_GPIO_Init(gpio, &GPIO_InitStructure); - - // [TODO] Disconnect SWDIO and SWCLK signals ? - // Warning: For debugging it is necessary to reconnect under reset if this is done. - //if ((pin == PA_13) || (pin == PA_14)) { - // - //} -} - -/** - * Configure pin pull-up/pull-down - */ -void pin_mode(PinName pin, PinMode mode) { - MBED_ASSERT(pin != (PinName)NC); - - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add; - - // Configure pull-up/pull-down resistors - uint32_t pupd = (uint32_t)mode; - if (pupd > 2) pupd = 0; // Open-drain = No pull-up/No pull-down - gpio->PUPDR &= (uint32_t)(~(GPIO_PUPDR_PUPDR0 << (pin_index * 2))); - gpio->PUPDR |= (uint32_t)(pupd << (pin_index * 2)); -} - -/* Internal function for setting the gpiomode/function - * without changing Pull mode - */ -void pin_function_gpiomode(PinName pin, uint32_t gpiomode) { - - /* Read current pull state from HW to avoid over-write*/ - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - GPIO_TypeDef *gpio = (GPIO_TypeDef *) Set_GPIO_Clock(port_index); - uint32_t temp = gpio->PUPDR; - uint32_t pull = (temp >> (pin_index * 2U)) & GPIO_PUPDR_PUPDR0; - - /* Then re-use global function for updating the mode part*/ - pin_function(pin, STM_PIN_DATA(gpiomode, pull, 0)); -} diff --git a/targets/TARGET_STM/TARGET_STM32F0/port_api.c b/targets/TARGET_STM/TARGET_STM32F0/port_api.c deleted file mode 100644 index e49e804cc8..0000000000 --- a/targets/TARGET_STM/TARGET_STM32F0/port_api.c +++ /dev/null @@ -1,97 +0,0 @@ -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2015, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "port_api.h" -#include "pinmap.h" -#include "gpio_api.h" -#include "mbed_error.h" - -#if DEVICE_PORTIN || DEVICE_PORTOUT - -extern uint32_t Set_GPIO_Clock(uint32_t port_idx); - -// high nibble = port number (0=A, 1=B, 2=C, 3=D, 4=E, 5=F, ...) -// low nibble = pin number -PinName port_pin(PortName port, int pin_n) { - return (PinName)(pin_n + (port << 4)); -} - -void port_init(port_t *obj, PortName port, int mask, PinDirection dir) { - uint32_t port_index = (uint32_t)port; - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add; - - // Fill PORT object structure for future use - obj->port = port; - obj->mask = mask; - obj->direction = dir; - obj->reg_in = &gpio->IDR; - obj->reg_out = &gpio->ODR; - - port_dir(obj, dir); -} - -void port_dir(port_t *obj, PinDirection dir) { - uint32_t i; - obj->direction = dir; - for (i = 0; i < 16; i++) { // Process all pins - if (obj->mask & (1 << i)) { // If the pin is used - if (dir == PIN_OUTPUT) { - pin_function(port_pin(obj->port, i), STM_PIN_DATA(STM_MODE_OUTPUT_PP, GPIO_NOPULL, 0)); - } else { // PIN_INPUT - pin_function(port_pin(obj->port, i), STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - } - } - } -} - -void port_mode(port_t *obj, PinMode mode) { - uint32_t i; - for (i = 0; i < 16; i++) { // Process all pins - if (obj->mask & (1 << i)) { // If the pin is used - pin_mode(port_pin(obj->port, i), mode); - } - } -} - -void port_write(port_t *obj, int value) { - *obj->reg_out = (*obj->reg_out & ~obj->mask) | (value & obj->mask); -} - -int port_read(port_t *obj) { - if (obj->direction == PIN_OUTPUT) { - return (*obj->reg_out & obj->mask); - } else { // PIN_INPUT - return (*obj->reg_in & obj->mask); - } -} - -#endif diff --git a/targets/TARGET_STM/TARGET_STM32F1/TARGET_BLUEPILL_F103C8/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32F1/TARGET_BLUEPILL_F103C8/PeripheralPins.c index ca5fcf9134..828a6265a6 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/TARGET_BLUEPILL_F103C8/PeripheralPins.c +++ b/targets/TARGET_STM/TARGET_STM32F1/TARGET_BLUEPILL_F103C8/PeripheralPins.c @@ -167,8 +167,8 @@ const PinMap PinMap_SPI_SSEL[] = { }; const PinMap PinMap_CAN_RD[] = { - {PA_11, CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, 0)}, - {PB_8 , CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, 1)}, + {PA_11, CAN_1, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)}, + {PB_8 , CAN_1, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 1)}, {NC, NC, 0} }; diff --git a/targets/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/PeripheralPins.c index dfa681fd89..5207de2d12 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/PeripheralPins.c +++ b/targets/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/PeripheralPins.c @@ -181,8 +181,8 @@ const PinMap PinMap_SPI_SSEL[] = { }; const PinMap PinMap_CAN_RD[] = { - {PA_11, CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, 0)}, - {PB_8 , CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, 10)}, // Remap CAN_RX to PB_8 + {PA_11, CAN_1, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)}, + {PB_8 , CAN_1, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 10)}, // Remap CAN_RX to PB_8 {NC, NC, 0} }; diff --git a/targets/TARGET_STM/TARGET_STM32F1/can_api.c b/targets/TARGET_STM/TARGET_STM32F1/can_api.c deleted file mode 100644 index cbcc9ca636..0000000000 --- a/targets/TARGET_STM/TARGET_STM32F1/can_api.c +++ /dev/null @@ -1,494 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-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 "can_api.h" - -#if DEVICE_CAN - -#include "cmsis.h" -#include "pinmap.h" -#include "PeripheralPins.h" -#include "mbed_error.h" -#include -#include - -#define CAN_NUM 1 -static CAN_HandleTypeDef CanHandle; -static uint32_t can_irq_ids[CAN_NUM] = {0}; -static can_irq_handler irq_handler; - -void can_init(can_t *obj, PinName rd, PinName td) -{ - CANName can_rd = (CANName)pinmap_peripheral(rd, PinMap_CAN_RD); - CANName can_td = (CANName)pinmap_peripheral(td, PinMap_CAN_TD); - obj->can = (CANName)pinmap_merge(can_rd, can_td); - MBED_ASSERT((int)obj->can != NC); - - if(obj->can == CAN_1) { - __HAL_RCC_CAN1_CLK_ENABLE(); - obj->index = 0; - } - - // Configure the CAN pins - pinmap_pinout(rd, PinMap_CAN_RD); - pinmap_pinout(td, PinMap_CAN_TD); - if (rd != NC) { - pin_mode(rd, PullUp); - } - if (td != NC) { - pin_mode(td, PullUp); - } - - CanHandle.Instance = (CAN_TypeDef *)(obj->can); - - CanHandle.Init.TTCM = DISABLE; - CanHandle.Init.ABOM = DISABLE; - CanHandle.Init.AWUM = DISABLE; - CanHandle.Init.NART = DISABLE; - CanHandle.Init.RFLM = DISABLE; - CanHandle.Init.TXFP = DISABLE; - CanHandle.Init.Mode = CAN_MODE_NORMAL; - CanHandle.Init.SJW = CAN_SJW_1TQ; - CanHandle.Init.BS1 = CAN_BS1_6TQ; - CanHandle.Init.BS2 = CAN_BS2_8TQ; - CanHandle.Init.Prescaler = 2; - - if (HAL_CAN_Init(&CanHandle) != HAL_OK) { - error("Cannot initialize CAN"); - } - // Set initial CAN frequency to 100kb/s - can_frequency(obj, 100000); - - can_filter(obj, 0, 0, CANStandard, 0); -} - -void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id) -{ - irq_handler = handler; - can_irq_ids[obj->index] = id; -} - -void can_irq_free(can_t *obj) -{ - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - can->IER &= ~(CAN_IT_FMP0 | CAN_IT_FMP1 | CAN_IT_TME | \ - CAN_IT_ERR | CAN_IT_EPV | CAN_IT_BOF); - can_irq_ids[obj->can] = 0; -} - -void can_free(can_t *obj) -{ - // Reset CAN and disable clock - if (obj->can == CAN_1) { - __HAL_RCC_CAN1_FORCE_RESET(); - __HAL_RCC_CAN1_RELEASE_RESET(); - __HAL_RCC_CAN1_CLK_DISABLE(); - } -} - -// The following table is used to program bit_timing. It is an adjustment of the sample -// point by synchronizing on the start-bit edge and resynchronizing on the following edges. -// This table has the sampling points as close to 75% as possible (most commonly used). -// The first value is TSEG1, the second TSEG2. -static const int timing_pts[23][2] = { - {0x0, 0x0}, // 2, 50% - {0x1, 0x0}, // 3, 67% - {0x2, 0x0}, // 4, 75% - {0x3, 0x0}, // 5, 80% - {0x3, 0x1}, // 6, 67% - {0x4, 0x1}, // 7, 71% - {0x5, 0x1}, // 8, 75% - {0x6, 0x1}, // 9, 78% - {0x6, 0x2}, // 10, 70% - {0x7, 0x2}, // 11, 73% - {0x8, 0x2}, // 12, 75% - {0x9, 0x2}, // 13, 77% - {0x9, 0x3}, // 14, 71% - {0xA, 0x3}, // 15, 73% - {0xB, 0x3}, // 16, 75% - {0xC, 0x3}, // 17, 76% - {0xD, 0x3}, // 18, 78% - {0xD, 0x4}, // 19, 74% - {0xE, 0x4}, // 20, 75% - {0xF, 0x4}, // 21, 76% - {0xF, 0x5}, // 22, 73% - {0xF, 0x6}, // 23, 70% - {0xF, 0x7}, // 24, 67% -}; - -static unsigned int can_speed(unsigned int pclk, unsigned int cclk, unsigned char psjw) -{ - uint32_t btr; - uint16_t brp = 0; - uint32_t calcbit; - uint32_t bitwidth; - int hit = 0; - int bits; - - bitwidth = (pclk / cclk); - - brp = bitwidth / 0x18; - while ((!hit) && (brp < bitwidth / 4)) { - brp++; - for (bits = 22; bits > 0; bits--) { - calcbit = (bits + 3) * (brp + 1); - if (calcbit == bitwidth) { - hit = 1; - break; - } - } - } - - if (hit) { - btr = ((timing_pts[bits][1] << 20) & 0x00700000) - | ((timing_pts[bits][0] << 16) & 0x000F0000) - | ((psjw << 24) & 0x0000C000) - | ((brp << 0) & 0x000003FF); - } else { - btr = 0xFFFFFFFF; - } - - return btr; - -} - -int can_frequency(can_t *obj, int f) -{ - int pclk = HAL_RCC_GetPCLK1Freq(); - int btr = can_speed(pclk, (unsigned int)f, 1); - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - if (btr > 0) { - can->MCR |= CAN_MCR_INRQ ; - while((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { - } - can->BTR = btr; - can->MCR &= ~(uint32_t)CAN_MCR_INRQ; - while((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { - } - return 1; - } else { - return 0; - } -} - -int can_write(can_t *obj, CAN_Message msg, int cc) -{ - uint32_t transmitmailbox = 5; - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - /* Select one empty transmit mailbox */ - if ((can->TSR&CAN_TSR_TME0) == CAN_TSR_TME0) { - transmitmailbox = 0; - } else if ((can->TSR&CAN_TSR_TME1) == CAN_TSR_TME1) { - transmitmailbox = 1; - } else if ((can->TSR&CAN_TSR_TME2) == CAN_TSR_TME2) { - transmitmailbox = 2; - } else { - transmitmailbox = CAN_TXSTATUS_NOMAILBOX; - } - - if (transmitmailbox != CAN_TXSTATUS_NOMAILBOX) { - can->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ; - if (!(msg.format)) - { - can->sTxMailBox[transmitmailbox].TIR |= ((msg.id << 21) | msg.type); - } - else - { - can->sTxMailBox[transmitmailbox].TIR |= ((msg.id << 3) | CAN_ID_EXT | msg.type); - } - - /* Set up the DLC */ - can->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0; - can->sTxMailBox[transmitmailbox].TDTR |= (msg.len & (uint8_t)0x0000000F); - - /* Set up the data field */ - can->sTxMailBox[transmitmailbox].TDLR = (((uint32_t)msg.data[3] << 24) | - ((uint32_t)msg.data[2] << 16) | - ((uint32_t)msg.data[1] << 8) | - ((uint32_t)msg.data[0])); - can->sTxMailBox[transmitmailbox].TDHR = (((uint32_t)msg.data[7] << 24) | - ((uint32_t)msg.data[6] << 16) | - ((uint32_t)msg.data[5] << 8) | - ((uint32_t)msg.data[4])); - /* Request transmission */ - can->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ; - } - - return 1; -} - -int can_read(can_t *obj, CAN_Message *msg, int handle) -{ - //handle is the FIFO number - - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - // check FPM0 which holds the pending message count in FIFO 0 - // if no message is pending, return 0 - if ((can->RF0R & CAN_RF0R_FMP0) == 0) { - return 0; - } - - /* Get the Id */ - msg->format = (CANFormat)((uint8_t)0x04 & can->sFIFOMailBox[handle].RIR); - if (!msg->format) { - msg->id = (uint32_t)0x000007FF & (can->sFIFOMailBox[handle].RIR >> 21); - } else { - msg->id = (uint32_t)0x1FFFFFFF & (can->sFIFOMailBox[handle].RIR >> 3); - } - - msg->type = (CANType)((uint8_t)0x02 & can->sFIFOMailBox[handle].RIR); - /* Get the DLC */ - msg->len = (uint8_t)0x0F & can->sFIFOMailBox[handle].RDTR; -// /* Get the FMI */ -// msg->FMI = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDTR >> 8); - /* Get the data field */ - msg->data[0] = (uint8_t)0xFF & can->sFIFOMailBox[handle].RDLR; - msg->data[1] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDLR >> 8); - msg->data[2] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDLR >> 16); - msg->data[3] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDLR >> 24); - msg->data[4] = (uint8_t)0xFF & can->sFIFOMailBox[handle].RDHR; - msg->data[5] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDHR >> 8); - msg->data[6] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDHR >> 16); - msg->data[7] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDHR >> 24); - - /* Release the FIFO */ - if(handle == CAN_FIFO0) { - /* Release FIFO0 */ - can->RF0R |= CAN_RF0R_RFOM0; - } else { /* FIFONumber == CAN_FIFO1 */ - /* Release FIFO1 */ - can->RF1R |= CAN_RF1R_RFOM1; - } - - return 1; -} - -void can_reset(can_t *obj) -{ - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - can->MCR |= CAN_MCR_RESET; - can->ESR = 0x0; -} - -unsigned char can_rderror(can_t *obj) -{ - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - return (can->ESR >> 24) & 0xFF; -} - -unsigned char can_tderror(can_t *obj) -{ - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - return (can->ESR >> 16) & 0xFF; -} - -void can_monitor(can_t *obj, int silent) -{ - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - can->MCR |= CAN_MCR_INRQ ; - while((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { - } - if (silent) { - can->BTR |= ((uint32_t)1 << 31); - } else { - can->BTR &= ~((uint32_t)1 << 31); - } - can->MCR &= ~(uint32_t)CAN_MCR_INRQ; - while((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { - } -} - -int can_mode(can_t *obj, CanMode mode) -{ - int success = 0; - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - can->MCR |= CAN_MCR_INRQ ; - while((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { - } - switch (mode) { - case MODE_NORMAL: - can->BTR &= ~(CAN_BTR_SILM | CAN_BTR_LBKM); - success = 1; - break; - case MODE_SILENT: - can->BTR |= CAN_BTR_SILM; - can->BTR &= ~CAN_BTR_LBKM; - success = 1; - break; - case MODE_TEST_GLOBAL: - case MODE_TEST_LOCAL: - can->BTR |= CAN_BTR_LBKM; - can->BTR &= ~CAN_BTR_SILM; - success = 1; - break; - case MODE_TEST_SILENT: - can->BTR |= (CAN_BTR_SILM | CAN_BTR_LBKM); - success = 1; - break; - default: - success = 0; - break; - } - can->MCR &= ~(uint32_t)CAN_MCR_INRQ; - while((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { - } - return success; -} - -int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) -{ - CanHandle.Instance = (CAN_TypeDef *)(obj->can); - CAN_FilterConfTypeDef sFilterConfig; - - sFilterConfig.FilterNumber = handle; - sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; - sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; - sFilterConfig.FilterIdHigh = (uint8_t) (id >> 8); - sFilterConfig.FilterIdLow = (uint8_t) id; - sFilterConfig.FilterMaskIdHigh = (uint8_t) (mask >> 8); - sFilterConfig.FilterMaskIdLow = (uint8_t) mask; - sFilterConfig.FilterFIFOAssignment = 0; - sFilterConfig.FilterActivation = ENABLE; - sFilterConfig.BankNumber = 14; - - HAL_CAN_ConfigFilter(&CanHandle, &sFilterConfig); - - return 0; -} - -static void can_irq(CANName name, int id) -{ - uint32_t tmp1 = 0, tmp2 = 0, tmp3 = 0; - CanHandle.Instance = (CAN_TypeDef *)name; - - if(__HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_TME)) { - tmp1 = __HAL_CAN_TRANSMIT_STATUS(&CanHandle, CAN_TXMAILBOX_0); - tmp2 = __HAL_CAN_TRANSMIT_STATUS(&CanHandle, CAN_TXMAILBOX_1); - tmp3 = __HAL_CAN_TRANSMIT_STATUS(&CanHandle, CAN_TXMAILBOX_2); - if (tmp1){ - __HAL_CAN_CLEAR_FLAG(&CanHandle, CAN_FLAG_RQCP0); - } - if (tmp2){ - __HAL_CAN_CLEAR_FLAG(&CanHandle, CAN_FLAG_RQCP1); - } - if (tmp3){ - __HAL_CAN_CLEAR_FLAG(&CanHandle, CAN_FLAG_RQCP2); - } - if(tmp1 || tmp2 || tmp3) - { - irq_handler(can_irq_ids[id], IRQ_TX); - } - } - - tmp1 = __HAL_CAN_MSG_PENDING(&CanHandle, CAN_FIFO0); - tmp2 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_FMP0); - - if((tmp1 != 0) && tmp2) { - irq_handler(can_irq_ids[id], IRQ_RX); - } - - tmp1 = __HAL_CAN_GET_FLAG(&CanHandle, CAN_FLAG_EPV); - tmp2 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_EPV); - tmp3 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_ERR); - - if(tmp1 && tmp2 && tmp3) { - irq_handler(can_irq_ids[id], IRQ_PASSIVE); - } - - tmp1 = __HAL_CAN_GET_FLAG(&CanHandle, CAN_FLAG_BOF); - tmp2 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_BOF); - tmp3 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_ERR); - if(tmp1 && tmp2 && tmp3) { - irq_handler(can_irq_ids[id], IRQ_BUS); - } - - tmp3 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_ERR); - if(tmp1 && tmp2 && tmp3) { - irq_handler(can_irq_ids[id], IRQ_ERROR); - } -} - -void CAN1_RX0_IRQHandler(void ) -{ - can_irq(CAN_1, 0); -} - -void CAN1_TX_IRQHandler(void) -{ - can_irq(CAN_1, 0); -} - -void CAN1_SCE_IRQHandler(void) -{ - can_irq(CAN_1, 0); -} - -void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable) -{ - - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - IRQn_Type irq_n = (IRQn_Type)0; - uint32_t vector = 0; - uint32_t ier; - - if(obj->can == CAN_1) { - switch (type) { - case IRQ_RX: - ier = CAN_IT_FMP0; - irq_n = CAN1_RX0_IRQn; - vector = (uint32_t)&CAN1_RX0_IRQHandler; - break; - case IRQ_TX: - ier = CAN_IT_TME; - irq_n = CAN1_TX_IRQn; - vector = (uint32_t)&CAN1_TX_IRQHandler; - break; - case IRQ_ERROR: - ier = CAN_IT_ERR; - irq_n = CAN1_SCE_IRQn; - vector = (uint32_t)&CAN1_SCE_IRQHandler; - break; - case IRQ_PASSIVE: - ier = CAN_IT_EPV; - irq_n = CAN1_SCE_IRQn; - vector = (uint32_t)&CAN1_SCE_IRQHandler; - break; - case IRQ_BUS: - ier = CAN_IT_BOF; - irq_n = CAN1_SCE_IRQn; - vector = (uint32_t)&CAN1_SCE_IRQHandler; - break; - default: return; - } - } - - if(enable) { - can->IER |= ier; - } else { - can->IER &= ~ier; - } - - NVIC_SetVector(irq_n, vector); - NVIC_EnableIRQ(irq_n); -} - -#endif // DEVICE_CAN - diff --git a/targets/TARGET_STM/TARGET_STM32F1/can_device.h b/targets/TARGET_STM/TARGET_STM32F1/can_device.h new file mode 100644 index 0000000000..d0e3ad0ce7 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F1/can_device.h @@ -0,0 +1,42 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-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. + */ +#ifndef MBED_CAN_DEVICE_H +#define MBED_CAN_DEVICE_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef DEVICE_CAN + +#define CAN_NUM 1 // Number of CAN peripherals present in the STM32 serie + +#define CAN1_IRQ_RX_IRQN CAN1_RX0_IRQn +#define CAN1_IRQ_RX_VECT CAN1_RX0_IRQHandler +#define CAN1_IRQ_TX_IRQN CAN1_TX_IRQn +#define CAN1_IRQ_TX_VECT CAN1_TX_IRQHandler +#define CAN1_IRQ_ERROR_IRQN CAN1_SCE_IRQn +#define CAN1_IRQ_ERROR_VECT CAN1_SCE_IRQHandler +#define CAN1_IRQ_PASSIVE_IRQN CAN1_SCE_IRQn +#define CAN1_IRQ_PASSIVE_VECT CAN1_SCE_IRQHandler +#define CAN1_IRQ_BUS_IRQN CAN1_SCE_IRQn +#define CAN1_IRQ_BUS_VECT CAN1_SCE_IRQHandler + +#endif // DEVICE_CAN + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32F1/gpio_irq_api.c b/targets/TARGET_STM/TARGET_STM32F1/gpio_irq_api.c deleted file mode 100644 index f8e4f7a5bc..0000000000 --- a/targets/TARGET_STM/TARGET_STM32F1/gpio_irq_api.c +++ /dev/null @@ -1,334 +0,0 @@ -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include -#include "cmsis.h" -#include "gpio_irq_api.h" -#include "pinmap.h" -#include "mbed_error.h" - -#define EDGE_NONE (0) -#define EDGE_RISE (1) -#define EDGE_FALL (2) -#define EDGE_BOTH (3) - -// Number of EXTI irq vectors (EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5_9, EXTI10_15) -#define CHANNEL_NUM (7) - -// Max pins for one line (max with EXTI10_15) -#define MAX_PIN_LINE (6) - -typedef struct gpio_channel { - uint32_t pin_mask; // bitmask representing which pins are configured for receiving interrupts - uint32_t channel_ids[MAX_PIN_LINE]; // mbed "gpio_irq_t gpio_irq" field of instance - uint32_t channel_gpio[MAX_PIN_LINE]; // base address of gpio port group - uint32_t channel_pin[MAX_PIN_LINE]; // pin number in port group -} gpio_channel_t; - -static gpio_channel_t channels[CHANNEL_NUM] = { - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0} -}; - -// Used to return the index for channels array. -static uint32_t pin_base_nr[16] = { - // EXTI0 - 0, // pin 0 - // EXTI1 - 0, // pin 1 - // EXTI2 - 0, // pin 2 - // EXTI3 - 0, // pin 3 - // EXTI4 - 0, // pin 4 - // EXTI5_9 - 0, // pin 5 - 1, // pin 6 - 2, // pin 7 - 3, // pin 8 - 4, // pin 9 - // EXTI10_15 - 0, // pin 10 - 1, // pin 11 - 2, // pin 12 - 3, // pin 13 - 4, // pin 14 - 5 // pin 15 -}; - -static gpio_irq_handler irq_handler; - -static void handle_interrupt_in(uint32_t irq_index, uint32_t max_num_pin_line) -{ - gpio_channel_t *gpio_channel = &channels[irq_index]; - uint32_t gpio_idx; - - for (gpio_idx = 0; gpio_idx < max_num_pin_line; gpio_idx++) { - uint32_t current_mask = (1 << gpio_idx); - - if (gpio_channel->pin_mask & current_mask) { - // Retrieve the gpio and pin that generate the irq - GPIO_TypeDef *gpio = (GPIO_TypeDef *)(gpio_channel->channel_gpio[gpio_idx]); - uint32_t pin = (uint32_t)(1 << (gpio_channel->channel_pin[gpio_idx])); - - // Clear interrupt flag - if (__HAL_GPIO_EXTI_GET_FLAG(pin) != RESET) { - __HAL_GPIO_EXTI_CLEAR_FLAG(pin); - - if (gpio_channel->channel_ids[gpio_idx] == 0) continue; - - // Check which edge has generated the irq - if ((gpio->IDR & pin) == 0) { - irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_FALL); - } else { - irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_RISE); - } - } - } - } -} - -// EXTI line 0 -static void gpio_irq0(void) -{ - handle_interrupt_in(0, 1); -} - -// EXTI line 1 -static void gpio_irq1(void) -{ - handle_interrupt_in(1, 1); -} - -// EXTI line 2 -static void gpio_irq2(void) -{ - handle_interrupt_in(2, 1); -} - -// EXTI line 3 -static void gpio_irq3(void) -{ - handle_interrupt_in(3, 1); -} - -// EXTI line 4 -static void gpio_irq4(void) -{ - handle_interrupt_in(4, 1); -} - -// EXTI lines 5 to 9 -static void gpio_irq5(void) -{ - handle_interrupt_in(5, 5); -} - -// EXTI lines 10 to 15 -static void gpio_irq6(void) -{ - handle_interrupt_in(6, 6); -} - -extern uint32_t Set_GPIO_Clock(uint32_t port_idx); -extern void pin_function_gpiomode(PinName pin, uint32_t gpiomode); - -int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) -{ - IRQn_Type irq_n = (IRQn_Type)0; - uint32_t vector = 0; - uint32_t irq_index; - gpio_channel_t *gpio_channel; - uint32_t gpio_idx; - - if (pin == NC) return -1; - - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - - // Select irq number and interrupt routine - switch (pin_index) { - case 0: - irq_n = EXTI0_IRQn; - vector = (uint32_t)&gpio_irq0; - irq_index = 0; - break; - case 1: - irq_n = EXTI1_IRQn; - vector = (uint32_t)&gpio_irq1; - irq_index = 1; - break; - case 2: - irq_n = EXTI2_IRQn; - vector = (uint32_t)&gpio_irq2; - irq_index = 2; - break; - case 3: - irq_n = EXTI3_IRQn; - vector = (uint32_t)&gpio_irq3; - irq_index = 3; - break; - case 4: - irq_n = EXTI4_IRQn; - vector = (uint32_t)&gpio_irq4; - irq_index = 4; - break; - case 5: - case 6: - case 7: - case 8: - case 9: - irq_n = EXTI9_5_IRQn; - vector = (uint32_t)&gpio_irq5; - irq_index = 5; - break; - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - irq_n = EXTI15_10_IRQn; - vector = (uint32_t)&gpio_irq6; - irq_index = 6; - break; - default: - error("InterruptIn error: pin not supported.\n"); - return -1; - } - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - - // Configure GPIO - pin_function(pin, STM_PIN_DATA(STM_MODE_IT_FALLING, GPIO_NOPULL, 0)); - - // Enable EXTI interrupt - NVIC_SetVector(irq_n, vector); - NVIC_EnableIRQ(irq_n); - - // Save informations for future use - obj->irq_n = irq_n; - obj->irq_index = irq_index; - obj->event = EDGE_NONE; - obj->pin = pin; - - gpio_channel = &channels[irq_index]; - gpio_idx = pin_base_nr[pin_index]; - gpio_channel->pin_mask |= (1 << gpio_idx); - gpio_channel->channel_ids[gpio_idx] = id; - gpio_channel->channel_gpio[gpio_idx] = gpio_add; - gpio_channel->channel_pin[gpio_idx] = pin_index; - - irq_handler = handler; - - return 0; -} - -void gpio_irq_free(gpio_irq_t *obj) -{ - gpio_channel_t *gpio_channel = &channels[obj->irq_index]; - uint32_t pin_index = STM_PIN(obj->pin); - uint32_t gpio_addr = GPIOA_BASE + (GPIOB_BASE-GPIOA_BASE) * STM_PORT(obj->pin); - uint32_t gpio_idx = pin_base_nr[pin_index]; - - HAL_GPIO_DeInit((GPIO_TypeDef *)gpio_addr, (1<pin_mask &= ~(1 << gpio_idx); - gpio_channel->channel_ids[gpio_idx] = 0; - gpio_channel->channel_gpio[gpio_idx] = 0; - gpio_channel->channel_pin[gpio_idx] = 0; - - // Disable EXTI line, but don't change pull-up config - pin_function_gpiomode(obj->pin, STM_MODE_INPUT); - obj->event = EDGE_NONE; -} - -void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) -{ - uint32_t mode = STM_MODE_IT_EVT_RESET; - - if (enable) { - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or RISE - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or FALL - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } - } - } else { // Disable - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } else { // NONE or RISE - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } else { // NONE or FALL - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } - } - } - - pin_function_gpiomode(obj->pin, mode); -} - -void gpio_irq_enable(gpio_irq_t *obj) -{ - NVIC_EnableIRQ(obj->irq_n); -} - -void gpio_irq_disable(gpio_irq_t *obj) -{ - NVIC_DisableIRQ(obj->irq_n); - obj->event = EDGE_NONE; -} diff --git a/targets/TARGET_STM/TARGET_STM32F1/gpio_irq_device.c b/targets/TARGET_STM/TARGET_STM32F1/gpio_irq_device.c new file mode 100644 index 0000000000..c6ed6be3ca --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F1/gpio_irq_device.c @@ -0,0 +1,59 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include "cmsis.h" +#include "gpio_irq_device.h" + +// Used to return the index for channels array. +const exti_lines_t pin_lines_desc[16] = { + // EXTI0 + {.gpio_idx = 0, .irq_index = 0, .irq_n = EXTI0_IRQn}, // pin 0 + // EXTI1 + {.gpio_idx = 0, .irq_index = 1, .irq_n = EXTI1_IRQn}, // pin 1 + // EXTI2 + {.gpio_idx = 0, .irq_index = 2, .irq_n = EXTI2_IRQn}, // pin 2 + // EXTI3 + {.gpio_idx = 0, .irq_index = 3, .irq_n = EXTI3_IRQn}, // pin 3 + // EXTI4 + {.gpio_idx = 0, .irq_index = 4, .irq_n = EXTI4_IRQn}, // pin 4 + // EXTI5_9 + {.gpio_idx = 0, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 5 + {.gpio_idx = 1, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 6 + {.gpio_idx = 2, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 7 + {.gpio_idx = 3, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 8 + {.gpio_idx = 4, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 9 + // EXTI10_15 + {.gpio_idx = 0, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 10 + {.gpio_idx = 1, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 11 + {.gpio_idx = 2, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 12 + {.gpio_idx = 3, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 13 + {.gpio_idx = 4, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 14 + {.gpio_idx = 5, .irq_index = 6, .irq_n = EXTI15_10_IRQn}// pin 15 +}; + diff --git a/targets/TARGET_STM/TARGET_STM32F1/gpio_irq_device.h b/targets/TARGET_STM/TARGET_STM32F1/gpio_irq_device.h new file mode 100644 index 0000000000..1833b7fdf0 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F1/gpio_irq_device.h @@ -0,0 +1,70 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2017, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef MBED_GPIO_IRQ_DEVICE_H +#define MBED_GPIO_IRQ_DEVICE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stm32f1xx_ll_exti.h" + +// Number of EXTI irq vectors (EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5_9, EXTI10_15) +#define CHANNEL_NUM (7) + +#define EXTI_IRQ0_NUM_LINES 1 +#define EXTI_IRQ1_NUM_LINES 1 +#define EXTI_IRQ2_NUM_LINES 1 +#define EXTI_IRQ3_NUM_LINES 1 +#define EXTI_IRQ4_NUM_LINES 1 +#define EXTI_IRQ5_NUM_LINES 5 +#define EXTI_IRQ6_NUM_LINES 6 + +// Max pins for one line (max with EXTI10_15) +#define MAX_PIN_LINE (EXTI_IRQ6_NUM_LINES) + +/* Structure to describe how the HW EXTI lines are defined in this HW */ +typedef struct exti_lines { + uint32_t gpio_idx; // an index entry for each EXIT line + uint32_t irq_index; // the IRQ index + IRQn_Type irq_n; // the corresponding EXTI IRQn +} exti_lines_t; + +// Used to return the index for channels array. +extern const exti_lines_t pin_lines_desc[]; + +/* In F1 family target, SYSCFG is named AFIO */ +#define SYSCFG AFIO + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32F1/pin_device.h b/targets/TARGET_STM/TARGET_STM32F1/pin_device.h new file mode 100644 index 0000000000..21f7008fa4 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F1/pin_device.h @@ -0,0 +1,119 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2016, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef MBED_PIN_DEVICE_H +#define MBED_PIN_DEVICE_H + +#include "cmsis.h" +#include "stm32f1xx_ll_gpio.h" + +extern const uint32_t ll_pin_defines[16]; + +static inline void stm_pin_DisconnectDebug(PinName pin) +{ + // Disconnect JTAG-DP + SW-DP signals. + // Warning: Need to reconnect under reset + if ((pin == PA_13) || (pin == PA_14)) { + __HAL_AFIO_REMAP_SWJ_DISABLE(); // JTAG-DP Disabled and SW-DP Disabled + } + if ((pin == PA_15) || (pin == PB_3) || (pin == PB_4)) { + __HAL_AFIO_REMAP_SWJ_NOJTAG(); // JTAG-DP Disabled and SW-DP enabled + } +} + +/* The AF selection of F1 family is specific compared to others */ +static inline void stm_pin_SetAFPin(GPIO_TypeDef *gpio, PinName pin, uint32_t afnum) +{ + // Enable AFIO clock + __HAL_RCC_AFIO_CLK_ENABLE(); + + if (afnum > 0) { + switch (afnum) { + case 1: // Remap SPI1 + __HAL_AFIO_REMAP_SPI1_ENABLE(); + break; + case 2: // Remap I2C1 + __HAL_AFIO_REMAP_I2C1_ENABLE(); + break; + case 3: // Remap USART1 + __HAL_AFIO_REMAP_USART1_ENABLE(); + break; + case 4: // Remap USART2 + __HAL_AFIO_REMAP_USART2_ENABLE(); + break; + case 5: // Partial Remap USART3 + __HAL_AFIO_REMAP_USART3_PARTIAL(); + break; + case 6: // Partial Remap TIM1 + __HAL_AFIO_REMAP_TIM1_PARTIAL(); + break; + case 7: // Partial Remap TIM3 + __HAL_AFIO_REMAP_TIM3_PARTIAL(); + break; + case 8: // Full Remap TIM2 + __HAL_AFIO_REMAP_TIM2_ENABLE(); + break; + case 9: // Full Remap TIM3 + __HAL_AFIO_REMAP_TIM3_ENABLE(); + break; +#if defined(AFIO_MAPR_CAN_REMAP_REMAP1) + case 10: // CAN_RX mapped to PB8, CAN_TX mapped to PB9 + __HAL_AFIO_REMAP_CAN1_2(); + break; +#endif + default: + break; + } + } +} + +static inline void stm_pin_PullConfig(GPIO_TypeDef *gpio, uint32_t ll_pin, uint32_t pull_config) +{ + uint32_t function = LL_GPIO_GetPinMode(gpio, ll_pin); + + switch (pull_config) { + case GPIO_PULLUP: + if (function == LL_GPIO_MODE_FLOATING) + LL_GPIO_SetPinMode(gpio, ll_pin, LL_GPIO_MODE_INPUT); + LL_GPIO_SetPinPull(gpio, ll_pin, LL_GPIO_PULL_UP); + break; + case GPIO_PULLDOWN: + if (function == LL_GPIO_MODE_FLOATING) + LL_GPIO_SetPinMode(gpio, ll_pin, LL_GPIO_MODE_INPUT); + LL_GPIO_SetPinPull(gpio, ll_pin, LL_GPIO_PULL_DOWN); + break; + default: + /* Input+NoPull = Floating for F1 family */ + if (function == LL_GPIO_MODE_INPUT) + LL_GPIO_SetPinMode(gpio, ll_pin, LL_GPIO_MODE_FLOATING); + break; + } +} + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32F1/pinmap.c b/targets/TARGET_STM/TARGET_STM32F1/pinmap.c deleted file mode 100644 index f608a1c38f..0000000000 --- a/targets/TARGET_STM/TARGET_STM32F1/pinmap.c +++ /dev/null @@ -1,252 +0,0 @@ -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "mbed_assert.h" -#include "pinmap.h" -#include "PortNames.h" -#include "mbed_error.h" - -// GPIO mode look-up table -// Warning: the elements order must be the same as the one defined in PinNames.h -static const uint32_t gpio_mode[13] = { - GPIO_MODE_INPUT, // 0 = STM_MODE_INPUT - GPIO_MODE_OUTPUT_PP, // 1 = STM_MODE_OUTPUT_PP - GPIO_MODE_OUTPUT_OD, // 2 = STM_MODE_OUTPUT_OD - GPIO_MODE_AF_PP, // 3 = STM_MODE_AF_PP - GPIO_MODE_AF_OD, // 4 = STM_MODE_AF_OD - GPIO_MODE_ANALOG, // 5 = STM_MODE_ANALOG - GPIO_MODE_IT_RISING, // 6 = STM_MODE_IT_RISING - GPIO_MODE_IT_FALLING, // 7 = STM_MODE_IT_FALLING - GPIO_MODE_IT_RISING_FALLING, // 8 = STM_MODE_IT_RISING_FALLING - GPIO_MODE_EVT_RISING, // 9 = STM_MODE_EVT_RISING - GPIO_MODE_EVT_FALLING, // 10 = STM_MODE_EVT_FALLING - GPIO_MODE_EVT_RISING_FALLING, // 11 = STM_MODE_EVT_RISING_FALLING - 0x10000000 // 12 = STM_MODE_IT_EVT_RESET (not in STM32Cube HAL) -}; - -// Enable GPIO clock and return GPIO base address -uint32_t Set_GPIO_Clock(uint32_t port_idx) -{ - uint32_t gpio_add = 0; - switch (port_idx) { - case PortA: - gpio_add = GPIOA_BASE; - __GPIOA_CLK_ENABLE(); - break; - case PortB: - gpio_add = GPIOB_BASE; - __GPIOB_CLK_ENABLE(); - break; - case PortC: - gpio_add = GPIOC_BASE; - __GPIOC_CLK_ENABLE(); - break; - case PortD: - gpio_add = GPIOD_BASE; - __GPIOD_CLK_ENABLE(); - break; - default: - error("Pinmap error: wrong port number."); - break; - } - return gpio_add; -} - -/** - * Configure pin (input, output, alternate function or analog) + output speed + AF - */ -void pin_function(PinName pin, int data) -{ - MBED_ASSERT(pin != (PinName)NC); - // Get the pin informations - uint32_t mode = STM_PIN_MODE(data); - uint32_t pupd = STM_PIN_PUPD(data); - uint32_t afnum = STM_PIN_AFNUM(data); - - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add; - - // Enable AFIO clock - __HAL_RCC_AFIO_CLK_ENABLE(); - - // Configure Alternate Function - // Warning: Must be done before the GPIO is initialized - if (afnum > 0) { - switch (afnum) { - case 1: // Remap SPI1 - __HAL_AFIO_REMAP_SPI1_ENABLE(); - break; - case 2: // Remap I2C1 - __HAL_AFIO_REMAP_I2C1_ENABLE(); - break; - case 3: // Remap USART1 - __HAL_AFIO_REMAP_USART1_ENABLE(); - break; - case 4: // Remap USART2 - __HAL_AFIO_REMAP_USART2_ENABLE(); - break; - case 5: // Partial Remap USART3 - __HAL_AFIO_REMAP_USART3_PARTIAL(); - break; - case 6: // Partial Remap TIM1 - __HAL_AFIO_REMAP_TIM1_PARTIAL(); - break; - case 7: // Partial Remap TIM3 - __HAL_AFIO_REMAP_TIM3_PARTIAL(); - break; - case 8: // Full Remap TIM2 - __HAL_AFIO_REMAP_TIM2_ENABLE(); - break; - case 9: // Full Remap TIM3 - __HAL_AFIO_REMAP_TIM3_ENABLE(); - break; - case 10: // CAN_RX mapped to PB8, CAN_TX mapped to PB9 - __HAL_AFIO_REMAP_CAN1_2(); - break; - default: - break; - } - } - - // Configure GPIO - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.Pin = (uint32_t)(1 << pin_index); - GPIO_InitStructure.Mode = gpio_mode[mode]; - GPIO_InitStructure.Pull = pupd; - GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; - HAL_GPIO_Init(gpio, &GPIO_InitStructure); - - // Disconnect JTAG-DP + SW-DP signals. - // Warning: Need to reconnect under reset - if ((pin == PA_13) || (pin == PA_14)) { - __HAL_AFIO_REMAP_SWJ_DISABLE(); // JTAG-DP Disabled and SW-DP Disabled - } - if ((pin == PA_15) || (pin == PB_3) || (pin == PB_4)) { - __HAL_AFIO_REMAP_SWJ_NOJTAG(); // JTAG-DP Disabled and SW-DP enabled - } -} - -/** - * Configure pin pull-up/pull-down - */ -void pin_mode(PinName pin, PinMode mode) -{ - MBED_ASSERT(pin != (PinName)NC); - - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add; - __IO uint32_t* gpio_reg_hl;//gpio register depends on bit index (high or low) - uint32_t shift; - - if (pin_index < 8) { - shift = (pin_index * 4); - gpio_reg_hl = &(gpio->CRL); - } else { - shift = (pin_index % 8) * 4; - gpio_reg_hl = &(gpio->CRH); - } - - // Configure open-drain and pull-up/down - switch (mode) { - case PullNone: - break; - case PullUp: - case PullDown: - // Set pull-up / pull-down for Input mode - if ((*gpio_reg_hl & (0x03 << shift)) == 0) { // MODE bits = Input mode - *gpio_reg_hl |= (0x08 << shift); // Set pull-up / pull-down - *gpio_reg_hl &= ~(0x04 << shift); // ENSURES GPIOx_CRL.CNFx.bit0 = 0 - } - // Now it's time to setup properly if pullup or pulldown. This is done in ODR register: - // set pull-up => bit=1, set pull-down => bit = 0 - if (mode == PullUp) { - gpio->ODR |= (0x01 << (pin_index)); // Set pull-up - } else { - gpio->ODR &= ~(0x01 << (pin_index)); // Set pull-down - } - break; - case OpenDrain: - // Set open-drain for Output mode (General Purpose or Alternate Function) - if ((*gpio_reg_hl & (0x03 << shift)) > 0) { // MODE bits = Output mode - *gpio_reg_hl |= (0x04 << shift); // Set open-drain - } - break; - default: - break; - } -} - -/* Internal function for setting the gpiomode/function - * without changing Pull mode - */ -void pin_function_gpiomode(PinName pin, uint32_t gpiomode) -{ - - /* Read current pull state from HW to avoid over-write*/ - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - GPIO_TypeDef *gpio = (GPIO_TypeDef *) Set_GPIO_Clock(port_index); - uint32_t pull = PullNone; - __IO uint32_t* gpio_reg_hl;//gpio register depends on bit index (high or low) - uint32_t shift; - - if (pin_index < 8) { - shift = (pin_index * 4); - gpio_reg_hl = &(gpio->CRL); - } else { - shift = (pin_index % 8) * 4; - gpio_reg_hl = &(gpio->CRH); - } - - /* Check if pull/pull down is active */ - if (!(*gpio_reg_hl & (0x03 << shift))) {// input - if((!!(*gpio_reg_hl & (0x08 << shift))) // pull-up / down - && (!(*gpio_reg_hl & (0x04 << shift)))) { // GPIOx_CRL.CNFx.bit0 = 0 - if (!!(gpio->ODR & (0x01 << pin_index))) { - pull = PullUp; - } else { - pull = PullDown; - } - } - } else { //output - if (!!(*gpio_reg_hl & (0x04 << shift))) { //open drain - pull = OpenDrain; - } - } - - /* Then re-use global function for updating the mode part*/ - pin_function(pin, STM_PIN_DATA(gpiomode, pull, 0)); -} diff --git a/targets/TARGET_STM/TARGET_STM32F1/port_api.c b/targets/TARGET_STM/TARGET_STM32F1/port_api.c deleted file mode 100644 index e982858665..0000000000 --- a/targets/TARGET_STM/TARGET_STM32F1/port_api.c +++ /dev/null @@ -1,103 +0,0 @@ -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "port_api.h" -#include "pinmap.h" -#include "gpio_api.h" -#include "mbed_error.h" - -#if DEVICE_PORTIN || DEVICE_PORTOUT - -extern uint32_t Set_GPIO_Clock(uint32_t port_idx); - -// high nibble = port number (0=A, 1=B, 2=C, 3=D, 4=E, 5=F, ...) -// low nibble = pin number -PinName port_pin(PortName port, int pin_n) -{ - return (PinName)(pin_n + (port << 4)); -} - -void port_init(port_t *obj, PortName port, int mask, PinDirection dir) -{ - uint32_t port_index = (uint32_t)port; - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add; - - // Fill PORT object structure for future use - obj->port = port; - obj->mask = mask; - obj->direction = dir; - obj->reg_in = &gpio->IDR; - obj->reg_out = &gpio->ODR; - - port_dir(obj, dir); -} - -void port_dir(port_t *obj, PinDirection dir) -{ - uint32_t i; - obj->direction = dir; - for (i = 0; i < 16; i++) { // Process all pins - if (obj->mask & (1 << i)) { // If the pin is used - if (dir == PIN_OUTPUT) { - pin_function(port_pin(obj->port, i), STM_PIN_DATA(STM_MODE_OUTPUT_PP, GPIO_NOPULL, 0)); - } else { // PIN_INPUT - pin_function(port_pin(obj->port, i), STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - } - } - } -} - -void port_mode(port_t *obj, PinMode mode) -{ - uint32_t i; - for (i = 0; i < 16; i++) { // Process all pins - if (obj->mask & (1 << i)) { // If the pin is used - pin_mode(port_pin(obj->port, i), mode); - } - } -} - -void port_write(port_t *obj, int value) -{ - *obj->reg_out = (*obj->reg_out & ~obj->mask) | (value & obj->mask); -} - -int port_read(port_t *obj) -{ - if (obj->direction == PIN_OUTPUT) { - return (*obj->reg_out & obj->mask); - } else { // PIN_INPUT - return (*obj->reg_in & obj->mask); - } -} - -#endif diff --git a/targets/TARGET_STM/TARGET_STM32F2/can_device.h b/targets/TARGET_STM/TARGET_STM32F2/can_device.h new file mode 100644 index 0000000000..8689988944 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F2/can_device.h @@ -0,0 +1,53 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-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. + */ +#ifndef MBED_CAN_DEVICE_H +#define MBED_CAN_DEVICE_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef DEVICE_CAN + +#define CAN_NUM 2 // Number of CAN peripherals present in the STM32 serie (1 or 2) + +#define CAN1_IRQ_RX_IRQN CAN1_RX0_IRQn +#define CAN1_IRQ_RX_VECT CAN1_RX0_IRQHandler +#define CAN1_IRQ_TX_IRQN CAN1_TX_IRQn +#define CAN1_IRQ_TX_VECT CAN1_TX_IRQHandler +#define CAN1_IRQ_ERROR_IRQN CAN1_SCE_IRQn +#define CAN1_IRQ_ERROR_VECT CAN1_SCE_IRQHandler +#define CAN1_IRQ_PASSIVE_IRQN CAN1_SCE_IRQn +#define CAN1_IRQ_PASSIVE_VECT CAN1_SCE_IRQHandler +#define CAN1_IRQ_BUS_IRQN CAN1_SCE_IRQn +#define CAN1_IRQ_BUS_VECT CAN1_SCE_IRQHandler + +#define CAN2_IRQ_RX_IRQN CAN2_RX0_IRQn +#define CAN2_IRQ_RX_VECT CAN2_RX0_IRQHandler +#define CAN2_IRQ_TX_IRQN CAN2_TX_IRQn +#define CAN2_IRQ_TX_VECT CAN2_TX_IRQHandler +#define CAN2_IRQ_ERROR_IRQN CAN2_SCE_IRQn +#define CAN2_IRQ_ERROR_VECT CAN2_SCE_IRQHandler +#define CAN2_IRQ_PASSIVE_IRQN CAN2_SCE_IRQn +#define CAN2_IRQ_PASSIVE_VECT CAN2_SCE_IRQHandler +#define CAN2_IRQ_BUS_IRQN CAN2_SCE_IRQn +#define CAN2_IRQ_BUS_VECT CAN2_SCE_IRQHandler + +#endif // DEVICE_CAN + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32F2/gpio_irq_api.c b/targets/TARGET_STM/TARGET_STM32F2/gpio_irq_api.c deleted file mode 100644 index c595b98ba6..0000000000 --- a/targets/TARGET_STM/TARGET_STM32F2/gpio_irq_api.c +++ /dev/null @@ -1,334 +0,0 @@ -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2016, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include -#include "cmsis.h" -#include "gpio_irq_api.h" -#include "pinmap.h" -#include "mbed_error.h" - -#define EDGE_NONE (0) -#define EDGE_RISE (1) -#define EDGE_FALL (2) -#define EDGE_BOTH (3) - -// Number of EXTI irq vectors (EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5_9, EXTI10_15) -#define CHANNEL_NUM (7) - -// Max pins for one line (max with EXTI10_15) -#define MAX_PIN_LINE (6) - -typedef struct gpio_channel { - uint32_t pin_mask; // bitmask representing which pins are configured for receiving interrupts - uint32_t channel_ids[MAX_PIN_LINE]; // mbed "gpio_irq_t gpio_irq" field of instance - uint32_t channel_gpio[MAX_PIN_LINE]; // base address of gpio port group - uint32_t channel_pin[MAX_PIN_LINE]; // pin number in port group -} gpio_channel_t; - -static gpio_channel_t channels[CHANNEL_NUM] = { - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0} -}; - -// Used to return the index for channels array. -static uint32_t pin_base_nr[16] = { - // EXTI0 - 0, // pin 0 - // EXTI1 - 0, // pin 1 - // EXTI2 - 0, // pin 2 - // EXTI3 - 0, // pin 3 - // EXTI4 - 0, // pin 4 - // EXTI5_9 - 0, // pin 5 - 1, // pin 6 - 2, // pin 7 - 3, // pin 8 - 4, // pin 9 - // EXTI10_15 - 0, // pin 10 - 1, // pin 11 - 2, // pin 12 - 3, // pin 13 - 4, // pin 14 - 5 // pin 15 -}; - -static gpio_irq_handler irq_handler; - -static void handle_interrupt_in(uint32_t irq_index, uint32_t max_num_pin_line) -{ - gpio_channel_t *gpio_channel = &channels[irq_index]; - uint32_t gpio_idx; - - for (gpio_idx = 0; gpio_idx < max_num_pin_line; gpio_idx++) { - uint32_t current_mask = (1 << gpio_idx); - - if (gpio_channel->pin_mask & current_mask) { - // Retrieve the gpio and pin that generate the irq - GPIO_TypeDef *gpio = (GPIO_TypeDef *)(gpio_channel->channel_gpio[gpio_idx]); - uint32_t pin = (uint32_t)(1 << (gpio_channel->channel_pin[gpio_idx])); - - // Clear interrupt flag - if (__HAL_GPIO_EXTI_GET_FLAG(pin) != RESET) { - __HAL_GPIO_EXTI_CLEAR_FLAG(pin); - - if (gpio_channel->channel_ids[gpio_idx] == 0) continue; - - // Check which edge has generated the irq - if ((gpio->IDR & pin) == 0) { - irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_FALL); - } else { - irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_RISE); - } - } - } - } -} - -// EXTI line 0 -static void gpio_irq0(void) -{ - handle_interrupt_in(0, 1); -} - -// EXTI line 1 -static void gpio_irq1(void) -{ - handle_interrupt_in(1, 1); -} - -// EXTI line 2 -static void gpio_irq2(void) -{ - handle_interrupt_in(2, 1); -} - -// EXTI line 3 -static void gpio_irq3(void) -{ - handle_interrupt_in(3, 1); -} - -// EXTI line 4 -static void gpio_irq4(void) -{ - handle_interrupt_in(4, 1); -} - -// EXTI lines 5 to 9 -static void gpio_irq5(void) -{ - handle_interrupt_in(5, 5); -} - -// EXTI lines 10 to 15 -static void gpio_irq6(void) -{ - handle_interrupt_in(6, 6); -} - -extern uint32_t Set_GPIO_Clock(uint32_t port_idx); -extern void pin_function_gpiomode(PinName pin, uint32_t gpiomode); - -int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) -{ - IRQn_Type irq_n = (IRQn_Type)0; - uint32_t vector = 0; - uint32_t irq_index; - gpio_channel_t *gpio_channel; - uint32_t gpio_idx; - - if (pin == NC) return -1; - - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - - // Select irq number and interrupt routine - switch (pin_index) { - case 0: - irq_n = EXTI0_IRQn; - vector = (uint32_t)&gpio_irq0; - irq_index = 0; - break; - case 1: - irq_n = EXTI1_IRQn; - vector = (uint32_t)&gpio_irq1; - irq_index = 1; - break; - case 2: - irq_n = EXTI2_IRQn; - vector = (uint32_t)&gpio_irq2; - irq_index = 2; - break; - case 3: - irq_n = EXTI3_IRQn; - vector = (uint32_t)&gpio_irq3; - irq_index = 3; - break; - case 4: - irq_n = EXTI4_IRQn; - vector = (uint32_t)&gpio_irq4; - irq_index = 4; - break; - case 5: - case 6: - case 7: - case 8: - case 9: - irq_n = EXTI9_5_IRQn; - vector = (uint32_t)&gpio_irq5; - irq_index = 5; - break; - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - irq_n = EXTI15_10_IRQn; - vector = (uint32_t)&gpio_irq6; - irq_index = 6; - break; - default: - error("InterruptIn error: pin not supported.\n"); - return -1; - } - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - - // Configure GPIO - pin_function(pin, STM_PIN_DATA(STM_MODE_IT_FALLING, GPIO_NOPULL, 0)); - - // Enable EXTI interrupt - NVIC_SetVector(irq_n, vector); - NVIC_EnableIRQ(irq_n); - - // Save informations for future use - obj->irq_n = irq_n; - obj->irq_index = irq_index; - obj->event = EDGE_NONE; - obj->pin = pin; - - gpio_channel = &channels[irq_index]; - gpio_idx = pin_base_nr[pin_index]; - gpio_channel->pin_mask |= (1 << gpio_idx); - gpio_channel->channel_ids[gpio_idx] = id; - gpio_channel->channel_gpio[gpio_idx] = gpio_add; - gpio_channel->channel_pin[gpio_idx] = pin_index; - - irq_handler = handler; - - return 0; -} - -void gpio_irq_free(gpio_irq_t *obj) -{ - gpio_channel_t *gpio_channel = &channels[obj->irq_index]; - uint32_t pin_index = STM_PIN(obj->pin); - uint32_t gpio_addr = GPIOA_BASE + (GPIOB_BASE-GPIOA_BASE) * STM_PORT(obj->pin); - uint32_t gpio_idx = pin_base_nr[pin_index]; - - HAL_GPIO_DeInit((GPIO_TypeDef *)gpio_addr, (1<pin_mask &= ~(1 << gpio_idx); - gpio_channel->channel_ids[gpio_idx] = 0; - gpio_channel->channel_gpio[gpio_idx] = 0; - gpio_channel->channel_pin[gpio_idx] = 0; - - // Disable EXTI line, but don't change pull-up config - pin_function_gpiomode(obj->pin, STM_MODE_INPUT); - obj->event = EDGE_NONE; -} - -void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) -{ - uint32_t mode = STM_MODE_IT_EVT_RESET; - - if (enable) { - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or RISE - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or FALL - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } - } - } else { // Disable - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } else { // NONE or RISE - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } else { // NONE or FALL - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } - } - } - - pin_function_gpiomode(obj->pin, mode); -} - -void gpio_irq_enable(gpio_irq_t *obj) -{ - NVIC_EnableIRQ(obj->irq_n); -} - -void gpio_irq_disable(gpio_irq_t *obj) -{ - NVIC_DisableIRQ(obj->irq_n); - obj->event = EDGE_NONE; -} diff --git a/targets/TARGET_STM/TARGET_STM32F2/gpio_irq_device.c b/targets/TARGET_STM/TARGET_STM32F2/gpio_irq_device.c new file mode 100644 index 0000000000..9f63aff054 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F2/gpio_irq_device.c @@ -0,0 +1,59 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2017, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include "cmsis.h" +#include "gpio_irq_device.h" + +// Used to return the index for channels array. +const exti_lines_t pin_lines_desc[16] = { + // EXTI0 + {.gpio_idx = 0, .irq_index = 0, .irq_n = EXTI0_IRQn}, // pin 0 + // EXTI1 + {.gpio_idx = 0, .irq_index = 1, .irq_n = EXTI1_IRQn}, // pin 1 + // EXTI2 + {.gpio_idx = 0, .irq_index = 2, .irq_n = EXTI2_IRQn}, // pin 2 + // EXTI3 + {.gpio_idx = 0, .irq_index = 3, .irq_n = EXTI3_IRQn}, // pin 3 + // EXTI4 + {.gpio_idx = 0, .irq_index = 4, .irq_n = EXTI4_IRQn}, // pin 4 + // EXTI5_9 + {.gpio_idx = 0, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 5 + {.gpio_idx = 1, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 6 + {.gpio_idx = 2, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 7 + {.gpio_idx = 3, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 8 + {.gpio_idx = 4, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 9 + // EXTI10_15 + {.gpio_idx = 0, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 10 + {.gpio_idx = 1, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 11 + {.gpio_idx = 2, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 12 + {.gpio_idx = 3, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 13 + {.gpio_idx = 4, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 14 + {.gpio_idx = 5, .irq_index = 6, .irq_n = EXTI15_10_IRQn}// pin 15 +}; + diff --git a/targets/TARGET_STM/TARGET_STM32F2/gpio_irq_device.h b/targets/TARGET_STM/TARGET_STM32F2/gpio_irq_device.h new file mode 100644 index 0000000000..7b7af71e74 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F2/gpio_irq_device.h @@ -0,0 +1,94 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2017, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef MBED_GPIO_IRQ_DEVICE_H +#define MBED_GPIO_IRQ_DEVICE_H + +#ifdef __cplusplus +extern "C" { +#endif + +// when LL is available, below include can be used +// #include "stm32f2xx_ll_exti.h" +// until then let's define locally the required functions +__STATIC_INLINE void LL_EXTI_EnableRisingTrig_0_31(uint32_t ExtiLine) +{ + SET_BIT(EXTI->RTSR, ExtiLine); +} +__STATIC_INLINE void LL_EXTI_DisableRisingTrig_0_31(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->RTSR, ExtiLine); +} +__STATIC_INLINE void LL_EXTI_EnableFallingTrig_0_31(uint32_t ExtiLine) +{ + SET_BIT(EXTI->FTSR, ExtiLine); +} +__STATIC_INLINE void LL_EXTI_DisableFallingTrig_0_31(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->FTSR, ExtiLine); +} +__STATIC_INLINE void LL_EXTI_EnableIT_0_31(uint32_t ExtiLine) +{ + SET_BIT(EXTI->IMR, ExtiLine); +} +__STATIC_INLINE void LL_EXTI_DisableIT_0_31(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->IMR, ExtiLine); +} +// Above lines shall be later defined in LL + +// Number of EXTI irq vectors (EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5_9, EXTI10_15) +#define CHANNEL_NUM (7) + +#define EXTI_IRQ0_NUM_LINES 1 +#define EXTI_IRQ1_NUM_LINES 1 +#define EXTI_IRQ2_NUM_LINES 1 +#define EXTI_IRQ3_NUM_LINES 1 +#define EXTI_IRQ4_NUM_LINES 1 +#define EXTI_IRQ5_NUM_LINES 5 +#define EXTI_IRQ6_NUM_LINES 6 + +// Max pins for one line (max with EXTI10_15) +#define MAX_PIN_LINE (EXTI_IRQ6_NUM_LINES) + +/* Structure to describe how the HW EXTI lines are defined in this HW */ +typedef struct exti_lines { + uint32_t gpio_idx; // an index entry for each EXIT line + uint32_t irq_index; // the IRQ index + IRQn_Type irq_n; // the corresponding EXTI IRQn +} exti_lines_t; + +// Used to return the index for channels array. +extern const exti_lines_t pin_lines_desc[]; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32F2/pin_device.h b/targets/TARGET_STM/TARGET_STM32F2/pin_device.h new file mode 100644 index 0000000000..38aca54c3c --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F2/pin_device.h @@ -0,0 +1,139 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2016, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef MBED_PIN_DEVICE_H +#define MBED_PIN_DEVICE_H + +#include "cmsis.h" + +// when LL is available, below include can be used +// #include "stm32f2xx_ll_gpio.h" +// until then let's define locally the required functions +#define LL_GPIO_PIN_0 GPIO_BSRR_BS0 /*!< Select pin 0 */ +#define LL_GPIO_PIN_1 GPIO_BSRR_BS1 /*!< Select pin 1 */ +#define LL_GPIO_PIN_2 GPIO_BSRR_BS2 /*!< Select pin 2 */ +#define LL_GPIO_PIN_3 GPIO_BSRR_BS3 /*!< Select pin 3 */ +#define LL_GPIO_PIN_4 GPIO_BSRR_BS4 /*!< Select pin 4 */ +#define LL_GPIO_PIN_5 GPIO_BSRR_BS5 /*!< Select pin 5 */ +#define LL_GPIO_PIN_6 GPIO_BSRR_BS6 /*!< Select pin 6 */ +#define LL_GPIO_PIN_7 GPIO_BSRR_BS7 /*!< Select pin 7 */ +#define LL_GPIO_PIN_8 GPIO_BSRR_BS8 /*!< Select pin 8 */ +#define LL_GPIO_PIN_9 GPIO_BSRR_BS9 /*!< Select pin 9 */ +#define LL_GPIO_PIN_10 GPIO_BSRR_BS10 /*!< Select pin 10 */ +#define LL_GPIO_PIN_11 GPIO_BSRR_BS11 /*!< Select pin 11 */ +#define LL_GPIO_PIN_12 GPIO_BSRR_BS12 /*!< Select pin 12 */ +#define LL_GPIO_PIN_13 GPIO_BSRR_BS13 /*!< Select pin 13 */ +#define LL_GPIO_PIN_14 GPIO_BSRR_BS14 /*!< Select pin 14 */ +#define LL_GPIO_PIN_15 GPIO_BSRR_BS15 /*!< Select pin 15 */ + +#define LL_GPIO_MODE_INPUT ((uint32_t)0x00000000U) /*!< Select input mode */ +#define LL_GPIO_MODE_OUTPUT GPIO_MODER_MODE0_0 /*!< Select output mode */ +#define LL_GPIO_MODE_ALTERNATE GPIO_MODER_MODE0_1 /*!< Select alternate function mode */ +#define LL_GPIO_MODE_ANALOG GPIO_MODER_MODE0 /*!< Select analog mode */ + +#define LL_GPIO_OUTPUT_PUSHPULL ((uint32_t)0x00000000U) /*!< Select push-pull as output type */ +#define LL_GPIO_OUTPUT_OPENDRAIN GPIO_OTYPER_OT0 /*!< Select open-drain as output type */ + +#define LL_GPIO_PULL_NO ((uint32_t)0x00000000U) /*!< Select I/O no pull */ +#define LL_GPIO_PULL_UP GPIO_PUPDR_PUPD0_0 /*!< Select I/O pull up */ +#define LL_GPIO_PULL_DOWN GPIO_PUPDR_PUPD0_1 /*!< Select I/O pull down */ + +#define LL_GPIO_SPEED_FREQ_LOW ((uint32_t)0x00000000U) /*!< Select I/O low output speed */ +#define LL_GPIO_SPEED_FREQ_MEDIUM GPIO_OSPEEDER_OSPEEDR0_0 /*!< Select I/O medium output speed */ +#define LL_GPIO_SPEED_FREQ_HIGH GPIO_OSPEEDER_OSPEEDR0_1 /*!< Select I/O fast output speed */ +#define LL_GPIO_SPEED_FREQ_VERY_HIGH GPIO_OSPEEDER_OSPEEDR0 /*!< Select I/O high output speed */ + +__STATIC_INLINE void LL_GPIO_SetAFPin_0_7(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Alternate) +{ + MODIFY_REG(GPIOx->AFR[0], (GPIO_AFRL_AFSEL0 << (POSITION_VAL(Pin) * 4U)), + (Alternate << (POSITION_VAL(Pin) * 4U))); +} + +__STATIC_INLINE void LL_GPIO_SetAFPin_8_15(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Alternate) +{ + MODIFY_REG(GPIOx->AFR[1], (GPIO_AFRH_AFSEL8 << (POSITION_VAL(Pin >> 8U) * 4U)), + (Alternate << (POSITION_VAL(Pin >> 8U) * 4U))); +} +__STATIC_INLINE void LL_GPIO_SetPinMode(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Mode) +{ + MODIFY_REG(GPIOx->MODER, (GPIO_MODER_MODE0 << (POSITION_VAL(Pin) * 2U)), (Mode << (POSITION_VAL(Pin) * 2U))); +} +__STATIC_INLINE uint32_t LL_GPIO_GetPinMode(GPIO_TypeDef *GPIOx, uint32_t Pin) +{ + return (uint32_t)(READ_BIT(GPIOx->MODER, ((Pin * Pin) * GPIO_MODER_MODER0)) / (Pin * Pin)); +} +__STATIC_INLINE void LL_GPIO_SetPinPull(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Pull) +{ + MODIFY_REG(GPIOx->PUPDR, (GPIO_PUPDR_PUPD0 << (POSITION_VAL(Pin) * 2U)), (Pull << (POSITION_VAL(Pin) * 2U))); +} +__STATIC_INLINE void LL_GPIO_SetPinOutputType(GPIO_TypeDef *GPIOx, uint32_t PinMask, uint32_t OutputType) +{ + MODIFY_REG(GPIOx->OTYPER, PinMask, (PinMask * OutputType)); +} +__STATIC_INLINE void LL_GPIO_SetPinSpeed(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Speed) +{ + MODIFY_REG(GPIOx->OSPEEDR, (GPIO_OSPEEDER_OSPEEDR0 << (POSITION_VAL(Pin) * 2U)), + (Speed << (POSITION_VAL(Pin) * 2U))); +} +// Above lines shall be defined in LL when available + +extern const uint32_t ll_pin_defines[16]; + +/* Family specific implementations */ +static inline void stm_pin_DisconnectDebug(PinName pin) +{ + /* empty for now */ +} + +static inline void stm_pin_PullConfig(GPIO_TypeDef *gpio, uint32_t ll_pin, uint32_t pull_config) +{ + switch (pull_config) { + case GPIO_PULLUP: + LL_GPIO_SetPinPull(gpio, ll_pin, LL_GPIO_PULL_UP); + break; + case GPIO_PULLDOWN: + LL_GPIO_SetPinPull(gpio, ll_pin, LL_GPIO_PULL_DOWN); + break; + default: + LL_GPIO_SetPinPull(gpio, ll_pin, LL_GPIO_PULL_NO); + break; + } +} + +static inline void stm_pin_SetAFPin( GPIO_TypeDef *gpio, PinName pin, uint32_t afnum) +{ + uint32_t ll_pin = ll_pin_defines[STM_PIN(pin)]; + + if (STM_PIN(pin) > 7) + LL_GPIO_SetAFPin_8_15(gpio, ll_pin, afnum); + else + LL_GPIO_SetAFPin_0_7(gpio, ll_pin, afnum); +} + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32F2/pinmap.c b/targets/TARGET_STM/TARGET_STM32F2/pinmap.c deleted file mode 100644 index fe415e7e8a..0000000000 --- a/targets/TARGET_STM/TARGET_STM32F2/pinmap.c +++ /dev/null @@ -1,197 +0,0 @@ -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2016, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "mbed_assert.h" -#include "pinmap.h" -#include "PortNames.h" -#include "mbed_error.h" - -// GPIO mode look-up table -static const uint32_t gpio_mode[13] = { - 0x00000000, // 0 = GPIO_MODE_INPUT - 0x00000001, // 1 = GPIO_MODE_OUTPUT_PP - 0x00000011, // 2 = GPIO_MODE_OUTPUT_OD - 0x00000002, // 3 = GPIO_MODE_AF_PP - 0x00000012, // 4 = GPIO_MODE_AF_OD - 0x00000003, // 5 = GPIO_MODE_ANALOG - 0x10110000, // 6 = GPIO_MODE_IT_RISING - 0x10210000, // 7 = GPIO_MODE_IT_FALLING - 0x10310000, // 8 = GPIO_MODE_IT_RISING_FALLING - 0x10120000, // 9 = GPIO_MODE_EVT_RISING - 0x10220000, // 10 = GPIO_MODE_EVT_FALLING - 0x10320000, // 11 = GPIO_MODE_EVT_RISING_FALLING - 0x10000000 // 12 = Reset GPIO_MODE_IT_EVT -}; - -// Enable GPIO clock and return GPIO base address -uint32_t Set_GPIO_Clock(uint32_t port_idx) -{ - uint32_t gpio_add = 0; - switch (port_idx) { - case PortA: - gpio_add = GPIOA_BASE; - __GPIOA_CLK_ENABLE(); - break; - case PortB: - gpio_add = GPIOB_BASE; - __GPIOB_CLK_ENABLE(); - break; - case PortC: - gpio_add = GPIOC_BASE; - __GPIOC_CLK_ENABLE(); - break; -#if defined GPIOD_BASE - case PortD: - gpio_add = GPIOD_BASE; - __GPIOD_CLK_ENABLE(); - break; -#endif -#if defined GPIOE_BASE - case PortE: - gpio_add = GPIOE_BASE; - __GPIOE_CLK_ENABLE(); - break; -#endif -#if defined GPIOF_BASE - case PortF: - gpio_add = GPIOF_BASE; - __GPIOF_CLK_ENABLE(); - break; -#endif -#if defined GPIOG_BASE - case PortG: - gpio_add = GPIOG_BASE; - __GPIOG_CLK_ENABLE(); - break; -#endif -#if defined GPIOH_BASE - case PortH: - gpio_add = GPIOH_BASE; - __GPIOH_CLK_ENABLE(); - break; -#endif -#if defined GPIOI_BASE - case PortI: - gpio_add = GPIOI_BASE; - __GPIOI_CLK_ENABLE(); - break; -#endif -#if defined GPIOJ_BASE - case PortJ: - gpio_add = GPIOJ_BASE; - __GPIOJ_CLK_ENABLE(); - break; -#endif -#if defined GPIOK_BASE - case PortK: - gpio_add = GPIOK_BASE; - __GPIOK_CLK_ENABLE(); - break; -#endif - default: - error("Pinmap error: wrong port number."); - break; - } - return gpio_add; -} - -/** - * Configure pin (mode, speed, output type and pull-up/pull-down) - */ -void pin_function(PinName pin, int data) -{ - MBED_ASSERT(pin != (PinName)NC); - // Get the pin informations - uint32_t mode = STM_PIN_MODE(data); - uint32_t pupd = STM_PIN_PUPD(data); - uint32_t afnum = STM_PIN_AFNUM(data); - - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add; - - // Configure GPIO - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.Pin = (uint32_t)(1 << pin_index); - GPIO_InitStructure.Mode = gpio_mode[mode]; - GPIO_InitStructure.Pull = pupd; - GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; - GPIO_InitStructure.Alternate = afnum; - HAL_GPIO_Init(gpio, &GPIO_InitStructure); - - // [TODO] Disconnect JTAG-DP + SW-DP signals. - // Warning: Need to reconnect under reset - //if ((pin == PA_13) || (pin == PA_14)) { - // - //} - //if ((pin == PA_15) || (pin == PB_3) || (pin == PB_4)) { - // - //} -} - -/** - * Configure pin pull-up/pull-down - */ -void pin_mode(PinName pin, PinMode mode) -{ - MBED_ASSERT(pin != (PinName)NC); - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add; - - // Configure pull-up/pull-down resistors - uint32_t pupd = (uint32_t)mode; - if (pupd > 2) { - pupd = 0; // Open-drain = No pull-up/No pull-down - } - gpio->PUPDR &= (uint32_t)(~(GPIO_PUPDR_PUPDR0 << (pin_index * 2))); - gpio->PUPDR |= (uint32_t)(pupd << (pin_index * 2)); -} - -/* Internal function for setting the gpiomode/function - * without changing Pull mode - */ -void pin_function_gpiomode(PinName pin, uint32_t gpiomode) { - - /* Read current pull state from HW to avoid over-write*/ - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - GPIO_TypeDef *gpio = (GPIO_TypeDef *) Set_GPIO_Clock(port_index); - uint32_t temp = gpio->PUPDR; - uint32_t pull = (temp >> (pin_index * 2U)) & GPIO_PUPDR_PUPDR0; - - /* Then re-use global function for updating the mode part*/ - pin_function(pin, STM_PIN_DATA(gpiomode, pull, 0)); -} diff --git a/targets/TARGET_STM/TARGET_STM32F3/can_api.c b/targets/TARGET_STM/TARGET_STM32F3/can_api.c deleted file mode 100644 index 15309dd170..0000000000 --- a/targets/TARGET_STM/TARGET_STM32F3/can_api.c +++ /dev/null @@ -1,485 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-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 "can_api.h" - -#if DEVICE_CAN - -#include "cmsis.h" -#include "pinmap.h" -#include "PeripheralPins.h" -#include "mbed_error.h" -#include -#include - -#define CAN_NUM 1 -static CAN_HandleTypeDef CanHandle; -static uint32_t can_irq_ids[CAN_NUM] = {0}; -static can_irq_handler irq_handler; - -void can_init(can_t *obj, PinName rd, PinName td) -{ - CANName can_rd = (CANName)pinmap_peripheral(rd, PinMap_CAN_RD); - CANName can_td = (CANName)pinmap_peripheral(td, PinMap_CAN_TD); - obj->can = (CANName)pinmap_merge(can_rd, can_td); - MBED_ASSERT((int)obj->can != NC); - - if(obj->can == CAN_1) { - __CAN_CLK_ENABLE(); - obj->index = 0; - } - - // Configure the CAN pins - pinmap_pinout(rd, PinMap_CAN_RD); - pinmap_pinout(td, PinMap_CAN_TD); - if (rd != NC) { - pin_mode(rd, PullUp); - } - if (td != NC) { - pin_mode(td, PullUp); - } - - CanHandle.Instance = (CAN_TypeDef *)(obj->can); - - CanHandle.Init.TTCM = DISABLE; - CanHandle.Init.ABOM = DISABLE; - CanHandle.Init.AWUM = DISABLE; - CanHandle.Init.NART = DISABLE; - CanHandle.Init.RFLM = DISABLE; - CanHandle.Init.TXFP = DISABLE; - CanHandle.Init.Mode = CAN_MODE_NORMAL; - CanHandle.Init.SJW = CAN_SJW_1TQ; - CanHandle.Init.BS1 = CAN_BS1_6TQ; - CanHandle.Init.BS2 = CAN_BS2_8TQ; - CanHandle.Init.Prescaler = 2; - - if (HAL_CAN_Init(&CanHandle) != HAL_OK) { - error("Cannot initialize CAN"); - } - // Set initial CAN frequency to 100kb/s - can_frequency(obj, 100000); - - can_filter(obj, 0, 0, CANStandard, 0); -} - -void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id) -{ - irq_handler = handler; - can_irq_ids[obj->index] = id; -} - -void can_irq_free(can_t *obj) -{ - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - can->IER &= ~(CAN_IT_FMP0 | CAN_IT_FMP1 | CAN_IT_TME | \ - CAN_IT_ERR | CAN_IT_EPV | CAN_IT_BOF); - can_irq_ids[obj->can] = 0; -} - -void can_free(can_t *obj) -{ - // Reset CAN and disable clock - if (obj->can == CAN_1) { - __CAN_FORCE_RESET(); - __CAN_RELEASE_RESET(); - __CAN_CLK_DISABLE(); - } -} - -// The following table is used to program bit_timing. It is an adjustment of the sample -// point by synchronizing on the start-bit edge and resynchronizing on the following edges. -// This table has the sampling points as close to 75% as possible (most commonly used). -// The first value is TSEG1, the second TSEG2. -static const int timing_pts[23][2] = { - {0x0, 0x0}, // 2, 50% - {0x1, 0x0}, // 3, 67% - {0x2, 0x0}, // 4, 75% - {0x3, 0x0}, // 5, 80% - {0x3, 0x1}, // 6, 67% - {0x4, 0x1}, // 7, 71% - {0x5, 0x1}, // 8, 75% - {0x6, 0x1}, // 9, 78% - {0x6, 0x2}, // 10, 70% - {0x7, 0x2}, // 11, 73% - {0x8, 0x2}, // 12, 75% - {0x9, 0x2}, // 13, 77% - {0x9, 0x3}, // 14, 71% - {0xA, 0x3}, // 15, 73% - {0xB, 0x3}, // 16, 75% - {0xC, 0x3}, // 17, 76% - {0xD, 0x3}, // 18, 78% - {0xD, 0x4}, // 19, 74% - {0xE, 0x4}, // 20, 75% - {0xF, 0x4}, // 21, 76% - {0xF, 0x5}, // 22, 73% - {0xF, 0x6}, // 23, 70% - {0xF, 0x7}, // 24, 67% -}; - -static unsigned int can_speed(unsigned int pclk, unsigned int cclk, unsigned char psjw) -{ - uint32_t btr; - uint16_t brp = 0; - uint32_t calcbit; - uint32_t bitwidth; - int hit = 0; - int bits; - - bitwidth = (pclk / cclk); - - brp = bitwidth / 0x18; - while ((!hit) && (brp < bitwidth / 4)) { - brp++; - for (bits = 22; bits > 0; bits--) { - calcbit = (bits + 3) * (brp + 1); - if (calcbit == bitwidth) { - hit = 1; - break; - } - } - } - - if (hit) { - btr = ((timing_pts[bits][1] << 20) & 0x00700000) - | ((timing_pts[bits][0] << 16) & 0x000F0000) - | ((psjw << 24) & 0x0000C000) - | ((brp << 0) & 0x000003FF); - } else { - btr = 0xFFFFFFFF; - } - - return btr; - -} - -int can_frequency(can_t *obj, int f) -{ - int pclk = HAL_RCC_GetPCLK1Freq(); - int btr = can_speed(pclk, (unsigned int)f, 1); - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - if (btr > 0) { - can->MCR |= CAN_MCR_INRQ ; - while((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { - } - can->BTR = btr; - can->MCR &= ~(uint32_t)CAN_MCR_INRQ; - while((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { - } - return 1; - } else { - return 0; - } -} - -int can_write(can_t *obj, CAN_Message msg, int cc) -{ - uint32_t transmitmailbox = 5; - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - /* Select one empty transmit mailbox */ - if ((can->TSR&CAN_TSR_TME0) == CAN_TSR_TME0) { - transmitmailbox = 0; - } else if ((can->TSR&CAN_TSR_TME1) == CAN_TSR_TME1) { - transmitmailbox = 1; - } else if ((can->TSR&CAN_TSR_TME2) == CAN_TSR_TME2) { - transmitmailbox = 2; - } else { - transmitmailbox = CAN_TXSTATUS_NOMAILBOX; - } - - if (transmitmailbox != CAN_TXSTATUS_NOMAILBOX) { - can->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ; - if (!(msg.format)) - { - can->sTxMailBox[transmitmailbox].TIR |= ((msg.id << 21) | msg.type); - } - else - { - can->sTxMailBox[transmitmailbox].TIR |= ((msg.id << 3) | CAN_ID_EXT | msg.type); - } - - /* Set up the DLC */ - can->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0; - can->sTxMailBox[transmitmailbox].TDTR |= (msg.len & (uint8_t)0x0000000F); - - /* Set up the data field */ - can->sTxMailBox[transmitmailbox].TDLR = (((uint32_t)msg.data[3] << 24) | - ((uint32_t)msg.data[2] << 16) | - ((uint32_t)msg.data[1] << 8) | - ((uint32_t)msg.data[0])); - can->sTxMailBox[transmitmailbox].TDHR = (((uint32_t)msg.data[7] << 24) | - ((uint32_t)msg.data[6] << 16) | - ((uint32_t)msg.data[5] << 8) | - ((uint32_t)msg.data[4])); - /* Request transmission */ - can->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ; - } - - return 1; -} - -int can_read(can_t *obj, CAN_Message *msg, int handle) -{ - //handle is the FIFO number - - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - // check FPM0 which holds the pending message count in FIFO 0 - // if no message is pending, return 0 - if ((can->RF0R & CAN_RF0R_FMP0) == 0) { - return 0; - } - - /* Get the Id */ - msg->format = (CANFormat)((uint8_t)0x04 & can->sFIFOMailBox[handle].RIR); - if (!msg->format) { - msg->id = (uint32_t)0x000007FF & (can->sFIFOMailBox[handle].RIR >> 21); - } else { - msg->id = (uint32_t)0x1FFFFFFF & (can->sFIFOMailBox[handle].RIR >> 3); - } - - msg->type = (CANType)((uint8_t)0x02 & can->sFIFOMailBox[handle].RIR); - /* Get the DLC */ - msg->len = (uint8_t)0x0F & can->sFIFOMailBox[handle].RDTR; -// /* Get the FMI */ -// msg->FMI = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDTR >> 8); - /* Get the data field */ - msg->data[0] = (uint8_t)0xFF & can->sFIFOMailBox[handle].RDLR; - msg->data[1] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDLR >> 8); - msg->data[2] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDLR >> 16); - msg->data[3] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDLR >> 24); - msg->data[4] = (uint8_t)0xFF & can->sFIFOMailBox[handle].RDHR; - msg->data[5] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDHR >> 8); - msg->data[6] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDHR >> 16); - msg->data[7] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDHR >> 24); - - /* Release the FIFO */ - if(handle == CAN_FIFO0) { - /* Release FIFO0 */ - can->RF0R |= CAN_RF0R_RFOM0; - } else { /* FIFONumber == CAN_FIFO1 */ - /* Release FIFO1 */ - can->RF1R |= CAN_RF1R_RFOM1; - } - - return 1; -} - -void can_reset(can_t *obj) -{ - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - can->MCR |= CAN_MCR_RESET; - can->ESR = 0x0; -} - -unsigned char can_rderror(can_t *obj) -{ - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - return (can->ESR >> 24) & 0xFF; -} - -unsigned char can_tderror(can_t *obj) -{ - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - return (can->ESR >> 16) & 0xFF; -} - -void can_monitor(can_t *obj, int silent) -{ - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - can->MCR |= CAN_MCR_INRQ ; - while((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { - } - if (silent) { - can->BTR |= ((uint32_t)1 << 31); - } else { - can->BTR &= ~((uint32_t)1 << 31); - } - can->MCR &= ~(uint32_t)CAN_MCR_INRQ; - while((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { - } -} - -int can_mode(can_t *obj, CanMode mode) -{ - int success = 0; - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - can->MCR |= CAN_MCR_INRQ ; - while((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { - } - switch (mode) { - case MODE_NORMAL: - can->BTR &= ~(CAN_BTR_SILM | CAN_BTR_LBKM); - success = 1; - break; - case MODE_SILENT: - can->BTR |= CAN_BTR_SILM; - can->BTR &= ~CAN_BTR_LBKM; - success = 1; - break; - case MODE_TEST_GLOBAL: - case MODE_TEST_LOCAL: - can->BTR |= CAN_BTR_LBKM; - can->BTR &= ~CAN_BTR_SILM; - success = 1; - break; - case MODE_TEST_SILENT: - can->BTR |= (CAN_BTR_SILM | CAN_BTR_LBKM); - success = 1; - break; - default: - success = 0; - break; - } - can->MCR &= ~(uint32_t)CAN_MCR_INRQ; - while((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { - } - return success; -} - -int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) -{ - CanHandle.Instance = (CAN_TypeDef *)(obj->can); - CAN_FilterConfTypeDef sFilterConfig; - - sFilterConfig.FilterNumber = handle; - sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; - sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; - sFilterConfig.FilterIdHigh = (uint8_t) (id >> 8); - sFilterConfig.FilterIdLow = (uint8_t) id; - sFilterConfig.FilterMaskIdHigh = (uint8_t) (mask >> 8); - sFilterConfig.FilterMaskIdLow = (uint8_t) mask; - sFilterConfig.FilterFIFOAssignment = 0; - sFilterConfig.FilterActivation = ENABLE; - sFilterConfig.BankNumber = 14 + handle; - - HAL_CAN_ConfigFilter(&CanHandle, &sFilterConfig); - - return 0; -} - -static void can_irq(CANName name, int id) -{ - uint32_t tmp1 = 0, tmp2 = 0, tmp3 = 0; - CanHandle.Instance = (CAN_TypeDef *)name; - - if(__HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_TME)) { - tmp1 = __HAL_CAN_TRANSMIT_STATUS(&CanHandle, CAN_TXMAILBOX_0); - tmp2 = __HAL_CAN_TRANSMIT_STATUS(&CanHandle, CAN_TXMAILBOX_1); - tmp3 = __HAL_CAN_TRANSMIT_STATUS(&CanHandle, CAN_TXMAILBOX_2); - if(tmp1 || tmp2 || tmp3) - { - irq_handler(can_irq_ids[id], IRQ_TX); - } - } - - tmp1 = __HAL_CAN_MSG_PENDING(&CanHandle, CAN_FIFO0); - tmp2 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_FMP0); - - if((tmp1 != 0) && tmp2) { - irq_handler(can_irq_ids[id], IRQ_RX); - } - - tmp1 = __HAL_CAN_GET_FLAG(&CanHandle, CAN_FLAG_EPV); - tmp2 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_EPV); - tmp3 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_ERR); - - if(tmp1 && tmp2 && tmp3) { - irq_handler(can_irq_ids[id], IRQ_PASSIVE); - } - - tmp1 = __HAL_CAN_GET_FLAG(&CanHandle, CAN_FLAG_BOF); - tmp2 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_BOF); - tmp3 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_ERR); - if(tmp1 && tmp2 && tmp3) { - irq_handler(can_irq_ids[id], IRQ_BUS); - } - - tmp3 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_ERR); - if(tmp1 && tmp2 && tmp3) { - irq_handler(can_irq_ids[id], IRQ_ERROR); - } -} - -void CAN_RX0_IRQHandler(void) -{ - can_irq(CAN_1, 0); -} - -void CAN_TX_IRQHandler(void) -{ - can_irq(CAN_1, 0); -} - -void CAN_SCE_IRQHandler(void) -{ - can_irq(CAN_1, 0); -} - -void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable) -{ - - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - IRQn_Type irq_n = (IRQn_Type)0; - uint32_t vector = 0; - uint32_t ier; - - if(obj->can == CAN_1) { - switch (type) { - case IRQ_RX: - ier = CAN_IT_FMP0; - irq_n = CAN_RX0_IRQn; - vector = (uint32_t)&CAN_RX0_IRQHandler; - break; - case IRQ_TX: - ier = CAN_IT_TME; - irq_n = CAN_TX_IRQn; - vector = (uint32_t)&CAN_TX_IRQHandler; - break; - case IRQ_ERROR: - ier = CAN_IT_ERR; - irq_n = CAN_SCE_IRQn; - vector = (uint32_t)&CAN_SCE_IRQHandler; - break; - case IRQ_PASSIVE: - ier = CAN_IT_EPV; - irq_n = CAN_SCE_IRQn; - vector = (uint32_t)&CAN_SCE_IRQHandler; - break; - case IRQ_BUS: - ier = CAN_IT_BOF; - irq_n = CAN_SCE_IRQn; - vector = (uint32_t)&CAN_SCE_IRQHandler; - break; - default: return; - } - } - - if(enable) { - can->IER |= ier; - } else { - can->IER &= ~ier; - } - - NVIC_SetVector(irq_n, vector); - NVIC_EnableIRQ(irq_n); -} - -#endif // DEVICE_CAN - diff --git a/targets/TARGET_STM/TARGET_STM32F3/can_device.h b/targets/TARGET_STM/TARGET_STM32F3/can_device.h new file mode 100644 index 0000000000..3337c51dc7 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F3/can_device.h @@ -0,0 +1,42 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-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. + */ +#ifndef MBED_CAN_DEVICE_H +#define MBED_CAN_DEVICE_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef DEVICE_CAN + +#define CAN_NUM 1 // Number of CAN peripherals present in the STM32 serie + +#define CAN1_IRQ_RX_IRQN CAN_RX0_IRQn +#define CAN1_IRQ_RX_VECT CAN_RX0_IRQHandler +#define CAN1_IRQ_TX_IRQN CAN_TX_IRQn +#define CAN1_IRQ_TX_VECT CAN_TX_IRQHandler +#define CAN1_IRQ_ERROR_IRQN CAN_SCE_IRQn +#define CAN1_IRQ_ERROR_VECT CAN_SCE_IRQHandler +#define CAN1_IRQ_PASSIVE_IRQN CAN_SCE_IRQn +#define CAN1_IRQ_PASSIVE_VECT CAN_SCE_IRQHandler +#define CAN1_IRQ_BUS_IRQN CAN_SCE_IRQn +#define CAN1_IRQ_BUS_VECT CAN_SCE_IRQHandler + +#endif // DEVICE_CAN + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32F3/gpio_irq_device.c b/targets/TARGET_STM/TARGET_STM32F3/gpio_irq_device.c new file mode 100644 index 0000000000..25a0569716 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F3/gpio_irq_device.c @@ -0,0 +1,59 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2017, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include "cmsis.h" +#include "gpio_irq_device.h" + +// Used to return the index for channels array. +const exti_lines_t pin_lines_desc[16] = { + // EXTI0 + {.gpio_idx = 0, .irq_index = 0, .irq_n = EXTI0_IRQn}, // pin 0 + // EXTI1 + {.gpio_idx = 0, .irq_index = 1, .irq_n = EXTI1_IRQn}, // pin 1 + // EXTI2 + {.gpio_idx = 0, .irq_index = 2, .irq_n = EXTI2_TSC_IRQn}, // pin 2 + // EXTI3 + {.gpio_idx = 0, .irq_index = 3, .irq_n = EXTI3_IRQn}, // pin 3 + // EXTI4 + {.gpio_idx = 0, .irq_index = 4, .irq_n = EXTI4_IRQn}, // pin 4 + // EXTI5_9 + {.gpio_idx = 0, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 5 + {.gpio_idx = 1, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 6 + {.gpio_idx = 2, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 7 + {.gpio_idx = 3, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 8 + {.gpio_idx = 4, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 9 + // EXTI10_15 + {.gpio_idx = 0, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 10 + {.gpio_idx = 1, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 11 + {.gpio_idx = 2, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 12 + {.gpio_idx = 3, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 13 + {.gpio_idx = 4, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 14 + {.gpio_idx = 5, .irq_index = 6, .irq_n = EXTI15_10_IRQn}// pin 15 +}; + diff --git a/targets/TARGET_STM/TARGET_STM32F3/gpio_irq_device.h b/targets/TARGET_STM/TARGET_STM32F3/gpio_irq_device.h new file mode 100644 index 0000000000..1fcbf2cc02 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F3/gpio_irq_device.h @@ -0,0 +1,67 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2017, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef MBED_GPIO_IRQ_DEVICE_H +#define MBED_GPIO_IRQ_DEVICE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stm32f3xx_ll_exti.h" + +// Number of EXTI irq vectors (EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5_9, EXTI10_15) +#define CHANNEL_NUM (7) + +#define EXTI_IRQ0_NUM_LINES 1 +#define EXTI_IRQ1_NUM_LINES 1 +#define EXTI_IRQ2_NUM_LINES 1 +#define EXTI_IRQ3_NUM_LINES 1 +#define EXTI_IRQ4_NUM_LINES 1 +#define EXTI_IRQ5_NUM_LINES 5 +#define EXTI_IRQ6_NUM_LINES 6 + +// Max pins for one line (max with EXTI10_15) +#define MAX_PIN_LINE (EXTI_IRQ6_NUM_LINES) + +/* Structure to describe how the HW EXTI lines are defined in this HW */ +typedef struct exti_lines { + uint32_t gpio_idx; // an index entry for each EXIT line + uint32_t irq_index; // the IRQ index + IRQn_Type irq_n; // the corresponding EXTI IRQn +} exti_lines_t; + +// Used to return the index for channels array. +extern const exti_lines_t pin_lines_desc[]; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32F3/pin_device.h b/targets/TARGET_STM/TARGET_STM32F3/pin_device.h new file mode 100644 index 0000000000..5d1325784e --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F3/pin_device.h @@ -0,0 +1,70 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2016, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef MBED_PIN_DEVICE_H +#define MBED_PIN_DEVICE_H + +#include "cmsis.h" + +#include "stm32f3xx_ll_gpio.h" + +extern const uint32_t ll_pin_defines[16]; + +/* Family specific implementations */ +static inline void stm_pin_DisconnectDebug(PinName pin) +{ + /* empty for now */ +} + +static inline void stm_pin_PullConfig(GPIO_TypeDef *gpio, uint32_t ll_pin, uint32_t pull_config) +{ + switch (pull_config) { + case GPIO_PULLUP: + LL_GPIO_SetPinPull(gpio, ll_pin, LL_GPIO_PULL_UP); + break; + case GPIO_PULLDOWN: + LL_GPIO_SetPinPull(gpio, ll_pin, LL_GPIO_PULL_DOWN); + break; + default: + LL_GPIO_SetPinPull(gpio, ll_pin, LL_GPIO_PULL_NO); + break; + } +} + +static inline void stm_pin_SetAFPin( GPIO_TypeDef *gpio, PinName pin, uint32_t afnum) +{ + uint32_t ll_pin = ll_pin_defines[STM_PIN(pin)]; + + if (STM_PIN(pin) > 7) + LL_GPIO_SetAFPin_8_15(gpio, ll_pin, afnum); + else + LL_GPIO_SetAFPin_0_7(gpio, ll_pin, afnum); +} + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32F3/pinmap.c b/targets/TARGET_STM/TARGET_STM32F3/pinmap.c deleted file mode 100644 index 47f46eace2..0000000000 --- a/targets/TARGET_STM/TARGET_STM32F3/pinmap.c +++ /dev/null @@ -1,195 +0,0 @@ -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "mbed_assert.h" -#include "pinmap.h" -#include "PortNames.h" -#include "mbed_error.h" - -// GPIO mode look-up table -// Warning: the elements order must be the same as the one defined in PinNames.h -static const uint32_t gpio_mode[13] = { - GPIO_MODE_INPUT, // 0 = STM_MODE_INPUT - GPIO_MODE_OUTPUT_PP, // 1 = STM_MODE_OUTPUT_PP - GPIO_MODE_OUTPUT_OD, // 2 = STM_MODE_OUTPUT_OD - GPIO_MODE_AF_PP, // 3 = STM_MODE_AF_PP - GPIO_MODE_AF_OD, // 4 = STM_MODE_AF_OD - GPIO_MODE_ANALOG, // 5 = STM_MODE_ANALOG - GPIO_MODE_IT_RISING, // 6 = STM_MODE_IT_RISING - GPIO_MODE_IT_FALLING, // 7 = STM_MODE_IT_FALLING - GPIO_MODE_IT_RISING_FALLING, // 8 = STM_MODE_IT_RISING_FALLING - GPIO_MODE_EVT_RISING, // 9 = STM_MODE_EVT_RISING - GPIO_MODE_EVT_FALLING, // 10 = STM_MODE_EVT_FALLING - GPIO_MODE_EVT_RISING_FALLING, // 11 = STM_MODE_EVT_RISING_FALLING - 0x10000000 // 12 = STM_MODE_IT_EVT_RESET (not in STM32Cube HAL) -}; - -// Enable GPIO clock and return GPIO base address -uint32_t Set_GPIO_Clock(uint32_t port_idx) -{ - uint32_t gpio_add = 0; - switch (port_idx) { - case PortA: - gpio_add = GPIOA_BASE; - __GPIOA_CLK_ENABLE(); - break; - case PortB: - gpio_add = GPIOB_BASE; - __GPIOB_CLK_ENABLE(); - break; - case PortC: - gpio_add = GPIOC_BASE; - __GPIOC_CLK_ENABLE(); - break; - case PortD: - gpio_add = GPIOD_BASE; - __GPIOD_CLK_ENABLE(); - break; -#if defined GPIOE_BASE - case PortE: - gpio_add = GPIOE_BASE; - __GPIOE_CLK_ENABLE(); - break; -#endif -#if defined GPIOF_BASE - case PortF: - gpio_add = GPIOF_BASE; - __GPIOF_CLK_ENABLE(); - break; -#endif -#if defined GPIOG_BASE - case PortG: - gpio_add = GPIOG_BASE; - __GPIOG_CLK_ENABLE(); - break; -#endif -#if defined GPIOH_BASE - case PortH: - gpio_add = GPIOH_BASE; - __GPIOH_CLK_ENABLE(); - break; -#endif -#if defined GPIOI_BASE - case PortI: - gpio_add = GPIOI_BASE; - __GPIOI_CLK_ENABLE(); - break; -#endif -#if defined GPIOJ_BASE - case PortJ: - gpio_add = GPIOJ_BASE; - __GPIOJ_CLK_ENABLE(); - break; -#endif -#if defined GPIOK_BASE - case PortK: - gpio_add = GPIOK_BASE; - __GPIOK_CLK_ENABLE(); - break; -#endif - - - default: - error("Pinmap error: wrong port number."); - break; - } - return gpio_add; -} - -/** - * Configure pin (mode, speed, output type and pull-up/pull-down) - */ -void pin_function(PinName pin, int data) -{ - MBED_ASSERT(pin != (PinName)NC); - // Get the pin informations - uint32_t mode = STM_PIN_MODE(data); - uint32_t pupd = STM_PIN_PUPD(data); - uint32_t afnum = STM_PIN_AFNUM(data); - - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add; - - // Configure GPIO - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.Pin = (uint32_t)(1 << pin_index); - GPIO_InitStructure.Mode = gpio_mode[mode]; - GPIO_InitStructure.Pull = pupd; - GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; - GPIO_InitStructure.Alternate = afnum; - HAL_GPIO_Init(gpio, &GPIO_InitStructure); - - // [TODO] Disconnect JTAG-DP + SW-DP signals. - // Warning: Need to reconnect under reset - //if ((pin == PA_13) || (pin == PA_14)) { - // - //} -} - -/** - * Configure pin pull-up/pull-down - */ -void pin_mode(PinName pin, PinMode mode) -{ - MBED_ASSERT(pin != (PinName)NC); - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add; - - // Configure pull-up/pull-down resistors - uint32_t pupd = (uint32_t)mode; - if (pupd > 2) { - pupd = 0; // Open-drain = No pull-up/No pull-down - } - gpio->PUPDR &= (uint32_t)(~(GPIO_PUPDR_PUPDR0 << (pin_index * 2))); - gpio->PUPDR |= (uint32_t)(pupd << (pin_index * 2)); -} - -/* Internal function for setting the gpiomode/function - * without changing Pull mode - */ -void pin_function_gpiomode(PinName pin, uint32_t gpiomode) { - - /* Read current pull state from HW to avoid over-write*/ - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - GPIO_TypeDef *gpio = (GPIO_TypeDef *) Set_GPIO_Clock(port_index); - uint32_t temp = gpio->PUPDR; - uint32_t pull = (temp >> (pin_index * 2U)) & GPIO_PUPDR_PUPDR0; - - /* Then re-use global function for updating the mode part*/ - pin_function(pin, STM_PIN_DATA(gpiomode, pull, 0)); -} diff --git a/targets/TARGET_STM/TARGET_STM32F3/port_api.c b/targets/TARGET_STM/TARGET_STM32F3/port_api.c deleted file mode 100644 index e982858665..0000000000 --- a/targets/TARGET_STM/TARGET_STM32F3/port_api.c +++ /dev/null @@ -1,103 +0,0 @@ -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "port_api.h" -#include "pinmap.h" -#include "gpio_api.h" -#include "mbed_error.h" - -#if DEVICE_PORTIN || DEVICE_PORTOUT - -extern uint32_t Set_GPIO_Clock(uint32_t port_idx); - -// high nibble = port number (0=A, 1=B, 2=C, 3=D, 4=E, 5=F, ...) -// low nibble = pin number -PinName port_pin(PortName port, int pin_n) -{ - return (PinName)(pin_n + (port << 4)); -} - -void port_init(port_t *obj, PortName port, int mask, PinDirection dir) -{ - uint32_t port_index = (uint32_t)port; - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add; - - // Fill PORT object structure for future use - obj->port = port; - obj->mask = mask; - obj->direction = dir; - obj->reg_in = &gpio->IDR; - obj->reg_out = &gpio->ODR; - - port_dir(obj, dir); -} - -void port_dir(port_t *obj, PinDirection dir) -{ - uint32_t i; - obj->direction = dir; - for (i = 0; i < 16; i++) { // Process all pins - if (obj->mask & (1 << i)) { // If the pin is used - if (dir == PIN_OUTPUT) { - pin_function(port_pin(obj->port, i), STM_PIN_DATA(STM_MODE_OUTPUT_PP, GPIO_NOPULL, 0)); - } else { // PIN_INPUT - pin_function(port_pin(obj->port, i), STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - } - } - } -} - -void port_mode(port_t *obj, PinMode mode) -{ - uint32_t i; - for (i = 0; i < 16; i++) { // Process all pins - if (obj->mask & (1 << i)) { // If the pin is used - pin_mode(port_pin(obj->port, i), mode); - } - } -} - -void port_write(port_t *obj, int value) -{ - *obj->reg_out = (*obj->reg_out & ~obj->mask) | (value & obj->mask); -} - -int port_read(port_t *obj) -{ - if (obj->direction == PIN_OUTPUT) { - return (*obj->reg_out & obj->mask); - } else { // PIN_INPUT - return (*obj->reg_in & obj->mask); - } -} - -#endif diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/TARGET_NUCLEO_F429ZI/system_stm32f4xx.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/TARGET_NUCLEO_F429ZI/system_stm32f4xx.c index 17c200221c..8394e8823e 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/TARGET_NUCLEO_F429ZI/system_stm32f4xx.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/TARGET_NUCLEO_F429ZI/system_stm32f4xx.c @@ -80,6 +80,7 @@ #include "stm32f4xx.h" #include "hal_tick.h" +#include "nvic_addr.h" #if !defined (HSE_VALUE) #define HSE_VALUE ((uint32_t)8000000) /*!< Default value of the External oscillator in Hz */ @@ -218,7 +219,7 @@ void SystemInit(void) #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 = NVIC_FLASH_VECTOR_ADDRESS; /* Vector Table Relocation in Internal FLASH */ #endif /* Configure the Cube driver */ diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_ARM_MICRO/stm32f429xx.sct b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_ARM_MICRO/stm32f429xx.sct index 40ba8dfc42..f6afa341de 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_ARM_MICRO/stm32f429xx.sct +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_ARM_MICRO/stm32f429xx.sct @@ -1,3 +1,4 @@ +#! armcc -E ; Scatter-Loading Description File ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Copyright (c) 2015, STMicroelectronics @@ -27,10 +28,18 @@ ; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; 2 MB FLASH (0x200000) + 256 KB SRAM (0x40000) -LR_IROM1 0x08000000 0x200000 { ; load region size_region +#if !defined(MBED_APP_START) + #define MBED_APP_START 0x08000000 +#endif - ER_IROM1 0x08000000 0x200000 { ; load address = execution address +#if !defined(MBED_APP_SIZE) + #define MBED_APP_SIZE 0x200000 +#endif + +; 2 MB FLASH (0x200000) + 256 KB SRAM (0x40000) +LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region + + 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_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_ARM_STD/stm32f429xx.sct b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_ARM_STD/stm32f429xx.sct index 646d1493bf..052738ec2a 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_ARM_STD/stm32f429xx.sct +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_ARM_STD/stm32f429xx.sct @@ -1,3 +1,4 @@ +#! armcc -E ; Scatter-Loading Description File ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Copyright (c) 2015, STMicroelectronics @@ -27,10 +28,18 @@ ; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; 2 MB FLASH (0x200000) + 192 KB SRAM (0x30000) -LR_IROM1 0x08000000 0x200000 { ; load region size_region +#if !defined(MBED_APP_START) + #define MBED_APP_START 0x08000000 +#endif - ER_IROM1 0x08000000 0x200000 { ; load address = execution address +#if !defined(MBED_APP_SIZE) + #define MBED_APP_SIZE 0x200000 +#endif + +; 2 MB FLASH (0x200000) + 192 KB SRAM (0x30000) +LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region + + 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_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_GCC_ARM/STM32F429xI.ld b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_GCC_ARM/STM32F429xI.ld index 1aa47a1ac9..fbb49574b0 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_GCC_ARM/STM32F429xI.ld +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_GCC_ARM/STM32F429xI.ld @@ -10,11 +10,19 @@ STACK_SIZE = 0x400; * heap and the page heap in uVisor applications. */ HEAP_SIZE = 0x6000; +#if !defined(MBED_APP_START) + #define MBED_APP_START 0x08000000 +#endif + +#if !defined(MBED_APP_SIZE) + #define MBED_APP_SIZE 2048k +#endif + /* Specify the memory areas */ MEMORY { - VECTORS (rx) : ORIGIN = 0x08000000, LENGTH = 0x400 - FLASH (rx) : ORIGIN = 0x08000400, LENGTH = 2048k - 0x400 + VECTORS (rx) : ORIGIN = MBED_APP_START, LENGTH = 0x400 + FLASH (rx) : ORIGIN = MBED_APP_START + 0x400, LENGTH = MBED_APP_SIZE - 0x400 CCM (rwx) : ORIGIN = 0x10000000, LENGTH = 64K RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 192k } diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_IAR/stm32f429xx_flash.icf b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_IAR/stm32f429xx_flash.icf index 6a59ff527c..b9efffd660 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_IAR/stm32f429xx_flash.icf +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/TOOLCHAIN_IAR/stm32f429xx_flash.icf @@ -1,11 +1,13 @@ /*###ICF### Section handled by ICF editor, don't touch! ****/ /*-Editor annotation file-*/ /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +if (!isdefinedsymbol(MBED_APP_START)) { define symbol MBED_APP_START = 0x08000000; } +if (!isdefinedsymbol(MBED_APP_SIZE)) { define symbol MBED_APP_SIZE = 0x200000; } /*-Specials-*/ -define symbol __ICFEDIT_intvec_start__ = 0x08000000; +define symbol __ICFEDIT_intvec_start__ = MBED_APP_START; /*-Memory Regions-*/ -define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; -define symbol __ICFEDIT_region_ROM_end__ = 0x081FFFFF; +define symbol __ICFEDIT_region_ROM_start__ = MBED_APP_START; +define symbol __ICFEDIT_region_ROM_end__ = MBED_APP_START + MBED_APP_SIZE - 1; define symbol __ICFEDIT_region_NVIC_start__ = 0x20000000; define symbol __ICFEDIT_region_NVIC_end__ = 0x200001AF; define symbol __ICFEDIT_region_RAM_start__ = 0x200001B0; diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/cmsis_nvic.c index 4a35e6e7f9..64aa174e4d 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/cmsis_nvic.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/cmsis_nvic.c @@ -29,9 +29,9 @@ ******************************************************************************* */ #include "cmsis_nvic.h" +#include "nvic_addr.h" #define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { uint32_t *vectors = (uint32_t *)SCB->VTOR; diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/flash_api.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/flash_api.c new file mode 100644 index 0000000000..9a79bc48f7 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/flash_api.c @@ -0,0 +1,74 @@ +/* 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 "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[] = { + 0xf3c04601, 0x28203007, 0x2204bf24, 0x1050eb02, 0x2810d205, 0x2203bf26, 0x1010eb02, 0xf4110880, + 0xbf181f80, 0x0010f040, 0x48714770, 0x6001496f, 0x60014970, 0x68014870, 0x01f0f041, 0x486f6001, + 0xf0106800, 0xd1080f20, 0xf245486d, 0x60015155, 0x60412106, 0x71fff640, 0x20006081, 0x49694770, + 0xf4206808, 0x600a52f8, 0x48676008, 0xf0416801, 0x60014100, 0x47702000, 0xc18cf8df, 0x0000f8dc, + 0x0004f040, 0x0000f8cc, 0x0000f8dc, 0x4000f440, 0x0000f8cc, 0x0000f8dc, 0x3080f440, 0x0000f8cc, + 0x0004f1ac, 0xf4116801, 0xbf1c3f80, 0x21aaf64a, 0xd0044a53, 0x68036011, 0x3f80f413, 0xf8dcd1fa, + 0xf0200000, 0xf8cc0004, 0xf8dc0000, 0xf4200000, 0xf8cc4000, 0x20000000, 0xf3c04770, 0x29203107, + 0x2204bf24, 0x1151eb02, 0x2910d205, 0x2203bf26, 0x1111eb02, 0xf4100889, 0xbf181f80, 0x0110f041, + 0x6802483d, 0x02f0f042, 0xf1006002, 0x22020c04, 0x2000f8cc, 0x2000f8dc, 0xea0323f8, 0x431101c1, + 0x1000f8cc, 0x1000f8dc, 0x3180f441, 0x1000f8cc, 0xf4116801, 0xbf1c3f80, 0x21aaf64a, 0xd0044a30, + 0x68036011, 0x3f80f413, 0xf8dcd1fa, 0xf0211000, 0xf8cc0102, 0x68011000, 0x0ff0f011, 0x2000bf04, + 0x68014770, 0x01f0f041, 0x20016001, 0x4b224770, 0x1cc9b430, 0xc000f8d3, 0x0103f031, 0x0cf0f04c, + 0xc000f8c3, 0x0404f103, 0x0c00f04f, 0xc000f8c4, 0xf240bf18, 0xd0252501, 0xc000f8d4, 0x0c05ea4c, + 0xc000f8c4, 0xc000f8d2, 0xc000f8c0, 0xc000f8d3, 0x3f80f41c, 0xf8d4d1fa, 0xf02cc000, 0xf8c40c01, + 0xf8d3c000, 0xf01cc000, 0xd0060ff0, 0xf0406818, 0x601800f0, 0x2001bc30, 0x1d004770, 0xf1021f09, + 0xd1d90204, 0x2000bc30, 0x00004770, 0x45670123, 0x40023c04, 0xcdef89ab, 0x40023c0c, 0x40023c14, + 0x40003000, 0x40023c00, 0x40023c10, 0x00000000 +}; + +static const flash_algo_t flash_algo_config = { + .init = 0x2b, + .uninit = 0x5f, + .erase_sector = 0xdb, + .program_page = 0x16f, + .static_base = 0x20c, + .algo_blob = FLASH_ALGO +}; + +static const sector_info_t sectors_info[] = { + {0x8000000, 0x4000}, + {0x8010000, 0x10000}, + {0x8020000, 0x20000}, + {0x8100000, 0x4000}, + {0x8110000, 0x10000}, + {0x8120000, 0x20000}, +}; + +static const flash_target_config_t flash_target_config = { + .page_size = 0x400, + .flash_start = 0x8000000, + .flash_size = 0x200000, + .sectors = sectors_info, + .sector_info_count = sizeof(sectors_info) / sizeof(sector_info_t) +}; + +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_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/nvic_addr.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/nvic_addr.h new file mode 100644 index 0000000000..307c99edd6 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/nvic_addr.h @@ -0,0 +1,40 @@ +/* mbed Microcontroller Library + * Copyright (c) 2017-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. + */ +#ifndef NVIC_ADDR_H +#define NVIC_ADDR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__ICCARM__) + #pragma section=".intvec" + #define NVIC_FLASH_VECTOR_ADDRESS ((uint32_t)__section_begin(".intvec")) +#elif defined(__CC_ARM) + extern uint32_t Load$$LR$$LR_IROM1$$Base[]; + #define NVIC_FLASH_VECTOR_ADDRESS ((uint32_t)Load$$LR$$LR_IROM1$$Base) +#elif defined(__GNUC__) + extern uint32_t g_pfnVectors[]; + #define NVIC_FLASH_VECTOR_ADDRESS ((uint32_t)g_pfnVectors) +#else + #error "Flash vector address not set for this toolchain" +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/system_init_pre.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/system_init_pre.c index bedfab07ad..790c2ae375 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/system_init_pre.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/system_init_pre.c @@ -15,6 +15,7 @@ * limitations under the License. */ #include "stm32f4xx.h" +#include "nvic_addr.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -37,6 +38,6 @@ void SystemInitPre(void) #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 = NVIC_FLASH_VECTOR_ADDRESS; /* Vector Table Relocation in Internal FLASH */ #endif } diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/TARGET_NUCLEO_F439ZI/system_stm32f4xx.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/TARGET_NUCLEO_F439ZI/system_stm32f4xx.c index 17c200221c..8394e8823e 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/TARGET_NUCLEO_F439ZI/system_stm32f4xx.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/TARGET_NUCLEO_F439ZI/system_stm32f4xx.c @@ -80,6 +80,7 @@ #include "stm32f4xx.h" #include "hal_tick.h" +#include "nvic_addr.h" #if !defined (HSE_VALUE) #define HSE_VALUE ((uint32_t)8000000) /*!< Default value of the External oscillator in Hz */ @@ -218,7 +219,7 @@ void SystemInit(void) #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 = NVIC_FLASH_VECTOR_ADDRESS; /* Vector Table Relocation in Internal FLASH */ #endif /* Configure the Cube driver */ diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/cmsis_nvic.c index 2da63fc9af..a1e0351aa1 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/cmsis_nvic.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/cmsis_nvic.c @@ -29,9 +29,9 @@ ******************************************************************************* */ #include "cmsis_nvic.h" +#include "nvic_addr.h" #define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { uint32_t *vectors = (uint32_t *)SCB->VTOR; diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/flash_api.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/flash_api.c new file mode 100644 index 0000000000..9a79bc48f7 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/flash_api.c @@ -0,0 +1,74 @@ +/* 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 "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[] = { + 0xf3c04601, 0x28203007, 0x2204bf24, 0x1050eb02, 0x2810d205, 0x2203bf26, 0x1010eb02, 0xf4110880, + 0xbf181f80, 0x0010f040, 0x48714770, 0x6001496f, 0x60014970, 0x68014870, 0x01f0f041, 0x486f6001, + 0xf0106800, 0xd1080f20, 0xf245486d, 0x60015155, 0x60412106, 0x71fff640, 0x20006081, 0x49694770, + 0xf4206808, 0x600a52f8, 0x48676008, 0xf0416801, 0x60014100, 0x47702000, 0xc18cf8df, 0x0000f8dc, + 0x0004f040, 0x0000f8cc, 0x0000f8dc, 0x4000f440, 0x0000f8cc, 0x0000f8dc, 0x3080f440, 0x0000f8cc, + 0x0004f1ac, 0xf4116801, 0xbf1c3f80, 0x21aaf64a, 0xd0044a53, 0x68036011, 0x3f80f413, 0xf8dcd1fa, + 0xf0200000, 0xf8cc0004, 0xf8dc0000, 0xf4200000, 0xf8cc4000, 0x20000000, 0xf3c04770, 0x29203107, + 0x2204bf24, 0x1151eb02, 0x2910d205, 0x2203bf26, 0x1111eb02, 0xf4100889, 0xbf181f80, 0x0110f041, + 0x6802483d, 0x02f0f042, 0xf1006002, 0x22020c04, 0x2000f8cc, 0x2000f8dc, 0xea0323f8, 0x431101c1, + 0x1000f8cc, 0x1000f8dc, 0x3180f441, 0x1000f8cc, 0xf4116801, 0xbf1c3f80, 0x21aaf64a, 0xd0044a30, + 0x68036011, 0x3f80f413, 0xf8dcd1fa, 0xf0211000, 0xf8cc0102, 0x68011000, 0x0ff0f011, 0x2000bf04, + 0x68014770, 0x01f0f041, 0x20016001, 0x4b224770, 0x1cc9b430, 0xc000f8d3, 0x0103f031, 0x0cf0f04c, + 0xc000f8c3, 0x0404f103, 0x0c00f04f, 0xc000f8c4, 0xf240bf18, 0xd0252501, 0xc000f8d4, 0x0c05ea4c, + 0xc000f8c4, 0xc000f8d2, 0xc000f8c0, 0xc000f8d3, 0x3f80f41c, 0xf8d4d1fa, 0xf02cc000, 0xf8c40c01, + 0xf8d3c000, 0xf01cc000, 0xd0060ff0, 0xf0406818, 0x601800f0, 0x2001bc30, 0x1d004770, 0xf1021f09, + 0xd1d90204, 0x2000bc30, 0x00004770, 0x45670123, 0x40023c04, 0xcdef89ab, 0x40023c0c, 0x40023c14, + 0x40003000, 0x40023c00, 0x40023c10, 0x00000000 +}; + +static const flash_algo_t flash_algo_config = { + .init = 0x2b, + .uninit = 0x5f, + .erase_sector = 0xdb, + .program_page = 0x16f, + .static_base = 0x20c, + .algo_blob = FLASH_ALGO +}; + +static const sector_info_t sectors_info[] = { + {0x8000000, 0x4000}, + {0x8010000, 0x10000}, + {0x8020000, 0x20000}, + {0x8100000, 0x4000}, + {0x8110000, 0x10000}, + {0x8120000, 0x20000}, +}; + +static const flash_target_config_t flash_target_config = { + .page_size = 0x400, + .flash_start = 0x8000000, + .flash_size = 0x200000, + .sectors = sectors_info, + .sector_info_count = sizeof(sectors_info) / sizeof(sector_info_t) +}; + +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_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/nvic_addr.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/nvic_addr.h new file mode 100644 index 0000000000..307c99edd6 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/nvic_addr.h @@ -0,0 +1,40 @@ +/* mbed Microcontroller Library + * Copyright (c) 2017-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. + */ +#ifndef NVIC_ADDR_H +#define NVIC_ADDR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__ICCARM__) + #pragma section=".intvec" + #define NVIC_FLASH_VECTOR_ADDRESS ((uint32_t)__section_begin(".intvec")) +#elif defined(__CC_ARM) + extern uint32_t Load$$LR$$LR_IROM1$$Base[]; + #define NVIC_FLASH_VECTOR_ADDRESS ((uint32_t)Load$$LR$$LR_IROM1$$Base) +#elif defined(__GNUC__) + extern uint32_t g_pfnVectors[]; + #define NVIC_FLASH_VECTOR_ADDRESS ((uint32_t)g_pfnVectors) +#else + #error "Flash vector address not set for this toolchain" +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/TOOLCHAIN_ARM_MICRO/stm32f439xx.sct b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/TOOLCHAIN_ARM_MICRO/stm32f439xx.sct index 68c246a768..8ad4e967ad 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/TOOLCHAIN_ARM_MICRO/stm32f439xx.sct +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/TOOLCHAIN_ARM_MICRO/stm32f439xx.sct @@ -1,3 +1,4 @@ +#! armcc -E ; Scatter-Loading Description File ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Copyright (c) 2014, STMicroelectronics @@ -27,10 +28,18 @@ ; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; STM32F439ZI: 2048 KB FLASH (0x200000) + 256 KB SRAM (0x30000 + 0x10000) -LR_IROM1 0x08000000 0x200000 { ; load region size_region +#if !defined(MBED_APP_START) + #define MBED_APP_START 0x08000000 +#endif - ER_IROM1 0x08000000 0x200000 { ; load address = execution address +#if !defined(MBED_APP_SIZE) + #define MBED_APP_SIZE 0x200000 +#endif + +; STM32F439ZI: 2048 KB FLASH (0x200000) + 256 KB SRAM (0x30000 + 0x10000) +LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region + + 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_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/TOOLCHAIN_ARM_STD/stm32f439xx.sct b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/TOOLCHAIN_ARM_STD/stm32f439xx.sct index 6b5cd4b0a1..b114905027 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/TOOLCHAIN_ARM_STD/stm32f439xx.sct +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/TOOLCHAIN_ARM_STD/stm32f439xx.sct @@ -1,3 +1,4 @@ +#! armcc -E ; Scatter-Loading Description File ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Copyright (c) 2015, STMicroelectronics @@ -27,10 +28,18 @@ ; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; 2 MB FLASH (0x200000) + 256 KB SRAM (0x30000 + 0x10000) -LR_IROM1 0x08000000 0x200000 { ; load region size_region +#if !defined(MBED_APP_START) + #define MBED_APP_START 0x08000000 +#endif - ER_IROM1 0x08000000 0x200000 { ; load address = execution address +#if !defined(MBED_APP_SIZE) + #define MBED_APP_SIZE 0x200000 +#endif + +; 2 MB FLASH (0x200000) + 256 KB SRAM (0x30000 + 0x10000) +LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region + + 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_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/TOOLCHAIN_GCC_ARM/STM32F439ZI.ld b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/TOOLCHAIN_GCC_ARM/STM32F439ZI.ld index 1ae1add65c..86820f2823 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/TOOLCHAIN_GCC_ARM/STM32F439ZI.ld +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/TOOLCHAIN_GCC_ARM/STM32F439ZI.ld @@ -1,7 +1,15 @@ +#if !defined(MBED_APP_START) + #define MBED_APP_START 0x08000000 +#endif + +#if !defined(MBED_APP_SIZE) + #define MBED_APP_SIZE 2048k +#endif + /* Linker script to configure memory regions. */ MEMORY { - FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048k + FLASH (rx) : ORIGIN = MBED_APP_START, LENGTH = MBED_APP_SIZE CCM (rwx) : ORIGIN = 0x10000000, LENGTH = 64K RAM (rwx) : ORIGIN = 0x200001AC, LENGTH = 192k - 0x1AC } diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/TOOLCHAIN_IAR/stm32f439xx_flash.icf b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/TOOLCHAIN_IAR/stm32f439xx_flash.icf index 6a59ff527c..b9efffd660 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/TOOLCHAIN_IAR/stm32f439xx_flash.icf +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/TOOLCHAIN_IAR/stm32f439xx_flash.icf @@ -1,11 +1,13 @@ /*###ICF### Section handled by ICF editor, don't touch! ****/ /*-Editor annotation file-*/ /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +if (!isdefinedsymbol(MBED_APP_START)) { define symbol MBED_APP_START = 0x08000000; } +if (!isdefinedsymbol(MBED_APP_SIZE)) { define symbol MBED_APP_SIZE = 0x200000; } /*-Specials-*/ -define symbol __ICFEDIT_intvec_start__ = 0x08000000; +define symbol __ICFEDIT_intvec_start__ = MBED_APP_START; /*-Memory Regions-*/ -define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; -define symbol __ICFEDIT_region_ROM_end__ = 0x081FFFFF; +define symbol __ICFEDIT_region_ROM_start__ = MBED_APP_START; +define symbol __ICFEDIT_region_ROM_end__ = MBED_APP_START + MBED_APP_SIZE - 1; define symbol __ICFEDIT_region_NVIC_start__ = 0x20000000; define symbol __ICFEDIT_region_NVIC_end__ = 0x200001AF; define symbol __ICFEDIT_region_RAM_start__ = 0x200001B0; diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/cmsis_nvic.c index 2da63fc9af..a1e0351aa1 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/cmsis_nvic.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/cmsis_nvic.c @@ -29,9 +29,9 @@ ******************************************************************************* */ #include "cmsis_nvic.h" +#include "nvic_addr.h" #define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { uint32_t *vectors = (uint32_t *)SCB->VTOR; diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/nvic_addr.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/nvic_addr.h new file mode 100644 index 0000000000..307c99edd6 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/nvic_addr.h @@ -0,0 +1,40 @@ +/* mbed Microcontroller Library + * Copyright (c) 2017-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. + */ +#ifndef NVIC_ADDR_H +#define NVIC_ADDR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__ICCARM__) + #pragma section=".intvec" + #define NVIC_FLASH_VECTOR_ADDRESS ((uint32_t)__section_begin(".intvec")) +#elif defined(__CC_ARM) + extern uint32_t Load$$LR$$LR_IROM1$$Base[]; + #define NVIC_FLASH_VECTOR_ADDRESS ((uint32_t)Load$$LR$$LR_IROM1$$Base) +#elif defined(__GNUC__) + extern uint32_t g_pfnVectors[]; + #define NVIC_FLASH_VECTOR_ADDRESS ((uint32_t)g_pfnVectors) +#else + #error "Flash vector address not set for this toolchain" +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/system_stm32f4xx.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/system_stm32f4xx.c index 3663e712f7..0e35d09260 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/system_stm32f4xx.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/system_stm32f4xx.c @@ -80,6 +80,7 @@ #include "stm32f4xx.h" #include "hal_tick.h" +#include "nvic_addr.h" #if !defined (HSE_VALUE) #define HSE_VALUE ((uint32_t)8000000) /*!< Default value of the External oscillator in Hz */ @@ -218,7 +219,7 @@ void SystemInit(void) #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 = NVIC_FLASH_VECTOR_ADDRESS; /* Vector Table Relocation in Internal FLASH */ #endif /* Configure the Cube driver */ diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/flash_api.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/flash_api.c new file mode 100644 index 0000000000..9a79bc48f7 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/flash_api.c @@ -0,0 +1,74 @@ +/* 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 "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[] = { + 0xf3c04601, 0x28203007, 0x2204bf24, 0x1050eb02, 0x2810d205, 0x2203bf26, 0x1010eb02, 0xf4110880, + 0xbf181f80, 0x0010f040, 0x48714770, 0x6001496f, 0x60014970, 0x68014870, 0x01f0f041, 0x486f6001, + 0xf0106800, 0xd1080f20, 0xf245486d, 0x60015155, 0x60412106, 0x71fff640, 0x20006081, 0x49694770, + 0xf4206808, 0x600a52f8, 0x48676008, 0xf0416801, 0x60014100, 0x47702000, 0xc18cf8df, 0x0000f8dc, + 0x0004f040, 0x0000f8cc, 0x0000f8dc, 0x4000f440, 0x0000f8cc, 0x0000f8dc, 0x3080f440, 0x0000f8cc, + 0x0004f1ac, 0xf4116801, 0xbf1c3f80, 0x21aaf64a, 0xd0044a53, 0x68036011, 0x3f80f413, 0xf8dcd1fa, + 0xf0200000, 0xf8cc0004, 0xf8dc0000, 0xf4200000, 0xf8cc4000, 0x20000000, 0xf3c04770, 0x29203107, + 0x2204bf24, 0x1151eb02, 0x2910d205, 0x2203bf26, 0x1111eb02, 0xf4100889, 0xbf181f80, 0x0110f041, + 0x6802483d, 0x02f0f042, 0xf1006002, 0x22020c04, 0x2000f8cc, 0x2000f8dc, 0xea0323f8, 0x431101c1, + 0x1000f8cc, 0x1000f8dc, 0x3180f441, 0x1000f8cc, 0xf4116801, 0xbf1c3f80, 0x21aaf64a, 0xd0044a30, + 0x68036011, 0x3f80f413, 0xf8dcd1fa, 0xf0211000, 0xf8cc0102, 0x68011000, 0x0ff0f011, 0x2000bf04, + 0x68014770, 0x01f0f041, 0x20016001, 0x4b224770, 0x1cc9b430, 0xc000f8d3, 0x0103f031, 0x0cf0f04c, + 0xc000f8c3, 0x0404f103, 0x0c00f04f, 0xc000f8c4, 0xf240bf18, 0xd0252501, 0xc000f8d4, 0x0c05ea4c, + 0xc000f8c4, 0xc000f8d2, 0xc000f8c0, 0xc000f8d3, 0x3f80f41c, 0xf8d4d1fa, 0xf02cc000, 0xf8c40c01, + 0xf8d3c000, 0xf01cc000, 0xd0060ff0, 0xf0406818, 0x601800f0, 0x2001bc30, 0x1d004770, 0xf1021f09, + 0xd1d90204, 0x2000bc30, 0x00004770, 0x45670123, 0x40023c04, 0xcdef89ab, 0x40023c0c, 0x40023c14, + 0x40003000, 0x40023c00, 0x40023c10, 0x00000000 +}; + +static const flash_algo_t flash_algo_config = { + .init = 0x2b, + .uninit = 0x5f, + .erase_sector = 0xdb, + .program_page = 0x16f, + .static_base = 0x20c, + .algo_blob = FLASH_ALGO +}; + +static const sector_info_t sectors_info[] = { + {0x8000000, 0x4000}, + {0x8010000, 0x10000}, + {0x8020000, 0x20000}, + {0x8100000, 0x4000}, + {0x8110000, 0x10000}, + {0x8120000, 0x20000}, +}; + +static const flash_target_config_t flash_target_config = { + .page_size = 0x400, + .flash_start = 0x8000000, + .flash_size = 0x200000, + .sectors = sectors_info, + .sector_info_count = sizeof(sectors_info) / sizeof(sector_info_t) +}; + +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_STM/TARGET_STM32F4/can_api.c b/targets/TARGET_STM/TARGET_STM32F4/can_api.c deleted file mode 100644 index dbadf01597..0000000000 --- a/targets/TARGET_STM/TARGET_STM32F4/can_api.c +++ /dev/null @@ -1,542 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-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 "can_api.h" - -#if DEVICE_CAN - -#include "cmsis.h" -#include "pinmap.h" -#include "PeripheralPins.h" -#include "mbed_error.h" -#include -#include - -#define CAN_NUM 2 -static CAN_HandleTypeDef CanHandle; -static uint32_t can_irq_ids[CAN_NUM] = {0}; -static can_irq_handler irq_handler; - -void can_init(can_t *obj, PinName rd, PinName td) -{ - uint32_t filter_number; - CANName can_rd = (CANName)pinmap_peripheral(rd, PinMap_CAN_RD); - CANName can_td = (CANName)pinmap_peripheral(td, PinMap_CAN_TD); - obj->can = (CANName)pinmap_merge(can_rd, can_td); - MBED_ASSERT((int)obj->can != NC); - - if(obj->can == CAN_1) { - __HAL_RCC_CAN1_CLK_ENABLE(); - obj->index = 0; - } else { - __HAL_RCC_CAN2_CLK_ENABLE(); - obj->index = 1; - } - - // Configure the CAN pins - pinmap_pinout(rd, PinMap_CAN_RD); - pinmap_pinout(td, PinMap_CAN_TD); - if (rd != NC) { - pin_mode(rd, PullUp); - } - if (td != NC) { - pin_mode(td, PullUp); - } - - CanHandle.Instance = (CAN_TypeDef *)(obj->can); - - CanHandle.Init.TTCM = DISABLE; - CanHandle.Init.ABOM = DISABLE; - CanHandle.Init.AWUM = DISABLE; - CanHandle.Init.NART = DISABLE; - CanHandle.Init.RFLM = DISABLE; - CanHandle.Init.TXFP = DISABLE; - CanHandle.Init.Mode = CAN_MODE_NORMAL; - CanHandle.Init.SJW = CAN_SJW_1TQ; - CanHandle.Init.BS1 = CAN_BS1_6TQ; - CanHandle.Init.BS2 = CAN_BS2_8TQ; - CanHandle.Init.Prescaler = 2; - - if (HAL_CAN_Init(&CanHandle) != HAL_OK) { - error("Cannot initialize CAN"); - } - - filter_number = (obj->can == CAN_1) ? 0 : 14; - - // Set initial CAN frequency to 100kb/s - can_frequency(obj, 100000); - - can_filter(obj, 0, 0, CANStandard, filter_number); -} - -void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id) -{ - irq_handler = handler; - can_irq_ids[obj->index] = id; -} - -void can_irq_free(can_t *obj) -{ - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - can->IER &= ~(CAN_IT_FMP0 | CAN_IT_FMP1 | CAN_IT_TME | \ - CAN_IT_ERR | CAN_IT_EPV | CAN_IT_BOF); - can_irq_ids[obj->can] = 0; -} - -void can_free(can_t *obj) -{ - // Reset CAN and disable clock - if (obj->can == CAN_1) { - __HAL_RCC_CAN1_FORCE_RESET(); - __HAL_RCC_CAN1_RELEASE_RESET(); - __HAL_RCC_CAN1_CLK_DISABLE(); - } - - if (obj->can == CAN_2) { - __HAL_RCC_CAN2_FORCE_RESET(); - __HAL_RCC_CAN2_RELEASE_RESET(); - __HAL_RCC_CAN2_CLK_DISABLE(); - } -} - -// The following table is used to program bit_timing. It is an adjustment of the sample -// point by synchronizing on the start-bit edge and resynchronizing on the following edges. -// This table has the sampling points as close to 75% as possible (most commonly used). -// The first value is TSEG1, the second TSEG2. -static const int timing_pts[23][2] = { - {0x0, 0x0}, // 2, 50% - {0x1, 0x0}, // 3, 67% - {0x2, 0x0}, // 4, 75% - {0x3, 0x0}, // 5, 80% - {0x3, 0x1}, // 6, 67% - {0x4, 0x1}, // 7, 71% - {0x5, 0x1}, // 8, 75% - {0x6, 0x1}, // 9, 78% - {0x6, 0x2}, // 10, 70% - {0x7, 0x2}, // 11, 73% - {0x8, 0x2}, // 12, 75% - {0x9, 0x2}, // 13, 77% - {0x9, 0x3}, // 14, 71% - {0xA, 0x3}, // 15, 73% - {0xB, 0x3}, // 16, 75% - {0xC, 0x3}, // 17, 76% - {0xD, 0x3}, // 18, 78% - {0xD, 0x4}, // 19, 74% - {0xE, 0x4}, // 20, 75% - {0xF, 0x4}, // 21, 76% - {0xF, 0x5}, // 22, 73% - {0xF, 0x6}, // 23, 70% - {0xF, 0x7}, // 24, 67% -}; - -static unsigned int can_speed(unsigned int pclk, unsigned int cclk, unsigned char psjw) -{ - uint32_t btr; - uint16_t brp = 0; - uint32_t calcbit; - uint32_t bitwidth; - int hit = 0; - int bits; - - bitwidth = (pclk / cclk); - - brp = bitwidth / 0x18; - while ((!hit) && (brp < bitwidth / 4)) { - brp++; - for (bits = 22; bits > 0; bits--) { - calcbit = (bits + 3) * (brp + 1); - if (calcbit == bitwidth) { - hit = 1; - break; - } - } - } - - if (hit) { - btr = ((timing_pts[bits][1] << 20) & 0x00700000) - | ((timing_pts[bits][0] << 16) & 0x000F0000) - | ((psjw << 24) & 0x0000C000) - | ((brp << 0) & 0x000003FF); - } else { - btr = 0xFFFFFFFF; - } - - return btr; - -} - -int can_frequency(can_t *obj, int f) -{ - int pclk = HAL_RCC_GetPCLK1Freq(); - int btr = can_speed(pclk, (unsigned int)f, 1); - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - if (btr > 0) { - can->MCR |= CAN_MCR_INRQ ; - while((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { - } - can->BTR = btr; - can->MCR &= ~(uint32_t)CAN_MCR_INRQ; - while((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { - } - return 1; - } else { - return 0; - } -} - -int can_write(can_t *obj, CAN_Message msg, int cc) -{ - uint32_t transmitmailbox = 5; - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - /* Select one empty transmit mailbox */ - if ((can->TSR&CAN_TSR_TME0) == CAN_TSR_TME0) { - transmitmailbox = 0; - } else if ((can->TSR&CAN_TSR_TME1) == CAN_TSR_TME1) { - transmitmailbox = 1; - } else if ((can->TSR&CAN_TSR_TME2) == CAN_TSR_TME2) { - transmitmailbox = 2; - } else { - transmitmailbox = CAN_TXSTATUS_NOMAILBOX; - } - - if (transmitmailbox != CAN_TXSTATUS_NOMAILBOX) { - can->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ; - if (!(msg.format)) - { - can->sTxMailBox[transmitmailbox].TIR |= ((msg.id << 21) | msg.type); - } - else - { - can->sTxMailBox[transmitmailbox].TIR |= ((msg.id << 3) | CAN_ID_EXT | msg.type); - } - - /* Set up the DLC */ - can->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0; - can->sTxMailBox[transmitmailbox].TDTR |= (msg.len & (uint8_t)0x0000000F); - - /* Set up the data field */ - can->sTxMailBox[transmitmailbox].TDLR = (((uint32_t)msg.data[3] << 24) | - ((uint32_t)msg.data[2] << 16) | - ((uint32_t)msg.data[1] << 8) | - ((uint32_t)msg.data[0])); - can->sTxMailBox[transmitmailbox].TDHR = (((uint32_t)msg.data[7] << 24) | - ((uint32_t)msg.data[6] << 16) | - ((uint32_t)msg.data[5] << 8) | - ((uint32_t)msg.data[4])); - /* Request transmission */ - can->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ; - } - - return 1; -} - -int can_read(can_t *obj, CAN_Message *msg, int handle) -{ - //handle is the FIFO number - - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - // check FPM0 which holds the pending message count in FIFO 0 - // if no message is pending, return 0 - if ((can->RF0R & CAN_RF0R_FMP0) == 0) { - return 0; - } - - /* Get the Id */ - msg->format = (CANFormat)((uint8_t)0x04 & can->sFIFOMailBox[handle].RIR); - if (!msg->format) { - msg->id = (uint32_t)0x000007FF & (can->sFIFOMailBox[handle].RIR >> 21); - } else { - msg->id = (uint32_t)0x1FFFFFFF & (can->sFIFOMailBox[handle].RIR >> 3); - } - - msg->type = (CANType)((uint8_t)0x02 & can->sFIFOMailBox[handle].RIR); - /* Get the DLC */ - msg->len = (uint8_t)0x0F & can->sFIFOMailBox[handle].RDTR; -// /* Get the FMI */ -// msg->FMI = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDTR >> 8); - /* Get the data field */ - msg->data[0] = (uint8_t)0xFF & can->sFIFOMailBox[handle].RDLR; - msg->data[1] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDLR >> 8); - msg->data[2] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDLR >> 16); - msg->data[3] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDLR >> 24); - msg->data[4] = (uint8_t)0xFF & can->sFIFOMailBox[handle].RDHR; - msg->data[5] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDHR >> 8); - msg->data[6] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDHR >> 16); - msg->data[7] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDHR >> 24); - - /* Release the FIFO */ - if(handle == CAN_FIFO0) { - /* Release FIFO0 */ - can->RF0R |= CAN_RF0R_RFOM0; - } else { /* FIFONumber == CAN_FIFO1 */ - /* Release FIFO1 */ - can->RF1R |= CAN_RF1R_RFOM1; - } - - return 1; -} - -void can_reset(can_t *obj) -{ - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - can->MCR |= CAN_MCR_RESET; - can->ESR = 0x0; -} - -unsigned char can_rderror(can_t *obj) -{ - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - return (can->ESR >> 24) & 0xFF; -} - -unsigned char can_tderror(can_t *obj) -{ - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - return (can->ESR >> 16) & 0xFF; -} - -void can_monitor(can_t *obj, int silent) -{ - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - can->MCR |= CAN_MCR_INRQ ; - while((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { - } - if (silent) { - can->BTR |= ((uint32_t)1 << 31); - } else { - can->BTR &= ~((uint32_t)1 << 31); - } - can->MCR &= ~(uint32_t)CAN_MCR_INRQ; - while((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { - } -} - -int can_mode(can_t *obj, CanMode mode) -{ - int success = 0; - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - can->MCR |= CAN_MCR_INRQ ; - while((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { - } - switch (mode) { - case MODE_NORMAL: - can->BTR &= ~(CAN_BTR_SILM | CAN_BTR_LBKM); - success = 1; - break; - case MODE_SILENT: - can->BTR |= CAN_BTR_SILM; - can->BTR &= ~CAN_BTR_LBKM; - success = 1; - break; - case MODE_TEST_GLOBAL: - case MODE_TEST_LOCAL: - can->BTR |= CAN_BTR_LBKM; - can->BTR &= ~CAN_BTR_SILM; - success = 1; - break; - case MODE_TEST_SILENT: - can->BTR |= (CAN_BTR_SILM | CAN_BTR_LBKM); - success = 1; - break; - default: - success = 0; - break; - } - can->MCR &= ~(uint32_t)CAN_MCR_INRQ; - while((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { - } - return success; -} - -int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) -{ - CanHandle.Instance = (CAN_TypeDef *)(obj->can); - CAN_FilterConfTypeDef sFilterConfig; - - sFilterConfig.FilterNumber = handle; - sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; - sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; - sFilterConfig.FilterIdHigh = (uint8_t) (id >> 8); - sFilterConfig.FilterIdLow = (uint8_t) id; - sFilterConfig.FilterMaskIdHigh = (uint8_t) (mask >> 8); - sFilterConfig.FilterMaskIdLow = (uint8_t) mask; - sFilterConfig.FilterFIFOAssignment = 0; - sFilterConfig.FilterActivation = ENABLE; - sFilterConfig.BankNumber = 14 + handle; - - HAL_CAN_ConfigFilter(&CanHandle, &sFilterConfig); - - return 0; -} - -static void can_irq(CANName name, int id) -{ - uint32_t tmp1 = 0, tmp2 = 0, tmp3 = 0; - CanHandle.Instance = (CAN_TypeDef *)name; - - if(__HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_TME)) { - tmp1 = __HAL_CAN_TRANSMIT_STATUS(&CanHandle, CAN_TXMAILBOX_0); - tmp2 = __HAL_CAN_TRANSMIT_STATUS(&CanHandle, CAN_TXMAILBOX_1); - tmp3 = __HAL_CAN_TRANSMIT_STATUS(&CanHandle, CAN_TXMAILBOX_2); - if(tmp1 || tmp2 || tmp3) - { - irq_handler(can_irq_ids[id], IRQ_TX); - } - } - - tmp1 = __HAL_CAN_MSG_PENDING(&CanHandle, CAN_FIFO0); - tmp2 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_FMP0); - - if((tmp1 != 0) && tmp2) { - irq_handler(can_irq_ids[id], IRQ_RX); - } - - tmp1 = __HAL_CAN_GET_FLAG(&CanHandle, CAN_FLAG_EPV); - tmp2 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_EPV); - tmp3 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_ERR); - - if(tmp1 && tmp2 && tmp3) { - irq_handler(can_irq_ids[id], IRQ_PASSIVE); - } - - tmp1 = __HAL_CAN_GET_FLAG(&CanHandle, CAN_FLAG_BOF); - tmp2 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_BOF); - tmp3 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_ERR); - if(tmp1 && tmp2 && tmp3) { - irq_handler(can_irq_ids[id], IRQ_BUS); - } - - tmp3 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_ERR); - if(tmp1 && tmp2 && tmp3) { - irq_handler(can_irq_ids[id], IRQ_ERROR); - } -} - -void CAN1_RX0_IRQHandler(void) -{ - can_irq(CAN_1, 0); -} - -void CAN1_TX_IRQHandler(void) -{ - can_irq(CAN_1, 0); -} - -void CAN1_SCE_IRQHandler(void) -{ - can_irq(CAN_1, 0); -} - -void CAN2_RX0_IRQHandler(void) -{ - can_irq(CAN_2, 1); -} - -void CAN2_TX_IRQHandler(void) -{ - can_irq(CAN_2, 1); -} - -void CAN2_SCE_IRQHandler(void) -{ - can_irq(CAN_2, 1); -} - -void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable) -{ - - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - IRQn_Type irq_n = (IRQn_Type)0; - uint32_t vector = 0; - uint32_t ier; - - if(obj->can == CAN_1) { - switch (type) { - case IRQ_RX: - ier = CAN_IT_FMP0; - irq_n = CAN1_RX0_IRQn; - vector = (uint32_t)&CAN1_RX0_IRQHandler; - break; - case IRQ_TX: - ier = CAN_IT_TME; - irq_n = CAN1_TX_IRQn; - vector = (uint32_t)&CAN1_TX_IRQHandler; - break; - case IRQ_ERROR: - ier = CAN_IT_ERR; - irq_n = CAN1_SCE_IRQn; - vector = (uint32_t)&CAN1_SCE_IRQHandler; - break; - case IRQ_PASSIVE: - ier = CAN_IT_EPV; - irq_n = CAN1_SCE_IRQn; - vector = (uint32_t)&CAN1_SCE_IRQHandler; - break; - case IRQ_BUS: - ier = CAN_IT_BOF; - irq_n = CAN1_SCE_IRQn; - vector = (uint32_t)&CAN1_SCE_IRQHandler; - break; - default: return; - } - } else { - switch (type) { - case IRQ_RX: - ier = CAN_IT_FMP0; - irq_n = CAN2_RX0_IRQn; - vector = (uint32_t)&CAN2_RX0_IRQHandler; - break; - case IRQ_TX: - ier = CAN_IT_TME; - irq_n = CAN2_TX_IRQn; - vector = (uint32_t)&CAN2_TX_IRQHandler; - break; - case IRQ_ERROR: - ier = CAN_IT_ERR; - irq_n = CAN2_SCE_IRQn; - vector = (uint32_t)&CAN2_SCE_IRQHandler; - break; - case IRQ_PASSIVE: - ier = CAN_IT_EPV; - irq_n = CAN2_SCE_IRQn; - vector = (uint32_t)&CAN2_SCE_IRQHandler; - break; - case IRQ_BUS: - ier = CAN_IT_BOF; - irq_n = CAN2_SCE_IRQn; - vector = (uint32_t)&CAN2_SCE_IRQHandler; - break; - default: return; - } - } - - if(enable) { - can->IER |= ier; - } else { - can->IER &= ~ier; - } - - NVIC_SetVector(irq_n, vector); - NVIC_EnableIRQ(irq_n); -} - -#endif // DEVICE_CAN - diff --git a/targets/TARGET_STM/TARGET_STM32F4/can_device.h b/targets/TARGET_STM/TARGET_STM32F4/can_device.h new file mode 100644 index 0000000000..8689988944 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F4/can_device.h @@ -0,0 +1,53 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-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. + */ +#ifndef MBED_CAN_DEVICE_H +#define MBED_CAN_DEVICE_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef DEVICE_CAN + +#define CAN_NUM 2 // Number of CAN peripherals present in the STM32 serie (1 or 2) + +#define CAN1_IRQ_RX_IRQN CAN1_RX0_IRQn +#define CAN1_IRQ_RX_VECT CAN1_RX0_IRQHandler +#define CAN1_IRQ_TX_IRQN CAN1_TX_IRQn +#define CAN1_IRQ_TX_VECT CAN1_TX_IRQHandler +#define CAN1_IRQ_ERROR_IRQN CAN1_SCE_IRQn +#define CAN1_IRQ_ERROR_VECT CAN1_SCE_IRQHandler +#define CAN1_IRQ_PASSIVE_IRQN CAN1_SCE_IRQn +#define CAN1_IRQ_PASSIVE_VECT CAN1_SCE_IRQHandler +#define CAN1_IRQ_BUS_IRQN CAN1_SCE_IRQn +#define CAN1_IRQ_BUS_VECT CAN1_SCE_IRQHandler + +#define CAN2_IRQ_RX_IRQN CAN2_RX0_IRQn +#define CAN2_IRQ_RX_VECT CAN2_RX0_IRQHandler +#define CAN2_IRQ_TX_IRQN CAN2_TX_IRQn +#define CAN2_IRQ_TX_VECT CAN2_TX_IRQHandler +#define CAN2_IRQ_ERROR_IRQN CAN2_SCE_IRQn +#define CAN2_IRQ_ERROR_VECT CAN2_SCE_IRQHandler +#define CAN2_IRQ_PASSIVE_IRQN CAN2_SCE_IRQn +#define CAN2_IRQ_PASSIVE_VECT CAN2_SCE_IRQHandler +#define CAN2_IRQ_BUS_IRQN CAN2_SCE_IRQn +#define CAN2_IRQ_BUS_VECT CAN2_SCE_IRQHandler + +#endif // DEVICE_CAN + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32F4/gpio_irq_api.c b/targets/TARGET_STM/TARGET_STM32F4/gpio_irq_api.c deleted file mode 100644 index c595b98ba6..0000000000 --- a/targets/TARGET_STM/TARGET_STM32F4/gpio_irq_api.c +++ /dev/null @@ -1,334 +0,0 @@ -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2016, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include -#include "cmsis.h" -#include "gpio_irq_api.h" -#include "pinmap.h" -#include "mbed_error.h" - -#define EDGE_NONE (0) -#define EDGE_RISE (1) -#define EDGE_FALL (2) -#define EDGE_BOTH (3) - -// Number of EXTI irq vectors (EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5_9, EXTI10_15) -#define CHANNEL_NUM (7) - -// Max pins for one line (max with EXTI10_15) -#define MAX_PIN_LINE (6) - -typedef struct gpio_channel { - uint32_t pin_mask; // bitmask representing which pins are configured for receiving interrupts - uint32_t channel_ids[MAX_PIN_LINE]; // mbed "gpio_irq_t gpio_irq" field of instance - uint32_t channel_gpio[MAX_PIN_LINE]; // base address of gpio port group - uint32_t channel_pin[MAX_PIN_LINE]; // pin number in port group -} gpio_channel_t; - -static gpio_channel_t channels[CHANNEL_NUM] = { - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0} -}; - -// Used to return the index for channels array. -static uint32_t pin_base_nr[16] = { - // EXTI0 - 0, // pin 0 - // EXTI1 - 0, // pin 1 - // EXTI2 - 0, // pin 2 - // EXTI3 - 0, // pin 3 - // EXTI4 - 0, // pin 4 - // EXTI5_9 - 0, // pin 5 - 1, // pin 6 - 2, // pin 7 - 3, // pin 8 - 4, // pin 9 - // EXTI10_15 - 0, // pin 10 - 1, // pin 11 - 2, // pin 12 - 3, // pin 13 - 4, // pin 14 - 5 // pin 15 -}; - -static gpio_irq_handler irq_handler; - -static void handle_interrupt_in(uint32_t irq_index, uint32_t max_num_pin_line) -{ - gpio_channel_t *gpio_channel = &channels[irq_index]; - uint32_t gpio_idx; - - for (gpio_idx = 0; gpio_idx < max_num_pin_line; gpio_idx++) { - uint32_t current_mask = (1 << gpio_idx); - - if (gpio_channel->pin_mask & current_mask) { - // Retrieve the gpio and pin that generate the irq - GPIO_TypeDef *gpio = (GPIO_TypeDef *)(gpio_channel->channel_gpio[gpio_idx]); - uint32_t pin = (uint32_t)(1 << (gpio_channel->channel_pin[gpio_idx])); - - // Clear interrupt flag - if (__HAL_GPIO_EXTI_GET_FLAG(pin) != RESET) { - __HAL_GPIO_EXTI_CLEAR_FLAG(pin); - - if (gpio_channel->channel_ids[gpio_idx] == 0) continue; - - // Check which edge has generated the irq - if ((gpio->IDR & pin) == 0) { - irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_FALL); - } else { - irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_RISE); - } - } - } - } -} - -// EXTI line 0 -static void gpio_irq0(void) -{ - handle_interrupt_in(0, 1); -} - -// EXTI line 1 -static void gpio_irq1(void) -{ - handle_interrupt_in(1, 1); -} - -// EXTI line 2 -static void gpio_irq2(void) -{ - handle_interrupt_in(2, 1); -} - -// EXTI line 3 -static void gpio_irq3(void) -{ - handle_interrupt_in(3, 1); -} - -// EXTI line 4 -static void gpio_irq4(void) -{ - handle_interrupt_in(4, 1); -} - -// EXTI lines 5 to 9 -static void gpio_irq5(void) -{ - handle_interrupt_in(5, 5); -} - -// EXTI lines 10 to 15 -static void gpio_irq6(void) -{ - handle_interrupt_in(6, 6); -} - -extern uint32_t Set_GPIO_Clock(uint32_t port_idx); -extern void pin_function_gpiomode(PinName pin, uint32_t gpiomode); - -int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) -{ - IRQn_Type irq_n = (IRQn_Type)0; - uint32_t vector = 0; - uint32_t irq_index; - gpio_channel_t *gpio_channel; - uint32_t gpio_idx; - - if (pin == NC) return -1; - - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - - // Select irq number and interrupt routine - switch (pin_index) { - case 0: - irq_n = EXTI0_IRQn; - vector = (uint32_t)&gpio_irq0; - irq_index = 0; - break; - case 1: - irq_n = EXTI1_IRQn; - vector = (uint32_t)&gpio_irq1; - irq_index = 1; - break; - case 2: - irq_n = EXTI2_IRQn; - vector = (uint32_t)&gpio_irq2; - irq_index = 2; - break; - case 3: - irq_n = EXTI3_IRQn; - vector = (uint32_t)&gpio_irq3; - irq_index = 3; - break; - case 4: - irq_n = EXTI4_IRQn; - vector = (uint32_t)&gpio_irq4; - irq_index = 4; - break; - case 5: - case 6: - case 7: - case 8: - case 9: - irq_n = EXTI9_5_IRQn; - vector = (uint32_t)&gpio_irq5; - irq_index = 5; - break; - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - irq_n = EXTI15_10_IRQn; - vector = (uint32_t)&gpio_irq6; - irq_index = 6; - break; - default: - error("InterruptIn error: pin not supported.\n"); - return -1; - } - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - - // Configure GPIO - pin_function(pin, STM_PIN_DATA(STM_MODE_IT_FALLING, GPIO_NOPULL, 0)); - - // Enable EXTI interrupt - NVIC_SetVector(irq_n, vector); - NVIC_EnableIRQ(irq_n); - - // Save informations for future use - obj->irq_n = irq_n; - obj->irq_index = irq_index; - obj->event = EDGE_NONE; - obj->pin = pin; - - gpio_channel = &channels[irq_index]; - gpio_idx = pin_base_nr[pin_index]; - gpio_channel->pin_mask |= (1 << gpio_idx); - gpio_channel->channel_ids[gpio_idx] = id; - gpio_channel->channel_gpio[gpio_idx] = gpio_add; - gpio_channel->channel_pin[gpio_idx] = pin_index; - - irq_handler = handler; - - return 0; -} - -void gpio_irq_free(gpio_irq_t *obj) -{ - gpio_channel_t *gpio_channel = &channels[obj->irq_index]; - uint32_t pin_index = STM_PIN(obj->pin); - uint32_t gpio_addr = GPIOA_BASE + (GPIOB_BASE-GPIOA_BASE) * STM_PORT(obj->pin); - uint32_t gpio_idx = pin_base_nr[pin_index]; - - HAL_GPIO_DeInit((GPIO_TypeDef *)gpio_addr, (1<pin_mask &= ~(1 << gpio_idx); - gpio_channel->channel_ids[gpio_idx] = 0; - gpio_channel->channel_gpio[gpio_idx] = 0; - gpio_channel->channel_pin[gpio_idx] = 0; - - // Disable EXTI line, but don't change pull-up config - pin_function_gpiomode(obj->pin, STM_MODE_INPUT); - obj->event = EDGE_NONE; -} - -void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) -{ - uint32_t mode = STM_MODE_IT_EVT_RESET; - - if (enable) { - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or RISE - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or FALL - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } - } - } else { // Disable - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } else { // NONE or RISE - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } else { // NONE or FALL - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } - } - } - - pin_function_gpiomode(obj->pin, mode); -} - -void gpio_irq_enable(gpio_irq_t *obj) -{ - NVIC_EnableIRQ(obj->irq_n); -} - -void gpio_irq_disable(gpio_irq_t *obj) -{ - NVIC_DisableIRQ(obj->irq_n); - obj->event = EDGE_NONE; -} diff --git a/targets/TARGET_STM/TARGET_STM32F4/gpio_irq_device.c b/targets/TARGET_STM/TARGET_STM32F4/gpio_irq_device.c new file mode 100644 index 0000000000..9f63aff054 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F4/gpio_irq_device.c @@ -0,0 +1,59 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2017, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include "cmsis.h" +#include "gpio_irq_device.h" + +// Used to return the index for channels array. +const exti_lines_t pin_lines_desc[16] = { + // EXTI0 + {.gpio_idx = 0, .irq_index = 0, .irq_n = EXTI0_IRQn}, // pin 0 + // EXTI1 + {.gpio_idx = 0, .irq_index = 1, .irq_n = EXTI1_IRQn}, // pin 1 + // EXTI2 + {.gpio_idx = 0, .irq_index = 2, .irq_n = EXTI2_IRQn}, // pin 2 + // EXTI3 + {.gpio_idx = 0, .irq_index = 3, .irq_n = EXTI3_IRQn}, // pin 3 + // EXTI4 + {.gpio_idx = 0, .irq_index = 4, .irq_n = EXTI4_IRQn}, // pin 4 + // EXTI5_9 + {.gpio_idx = 0, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 5 + {.gpio_idx = 1, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 6 + {.gpio_idx = 2, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 7 + {.gpio_idx = 3, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 8 + {.gpio_idx = 4, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 9 + // EXTI10_15 + {.gpio_idx = 0, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 10 + {.gpio_idx = 1, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 11 + {.gpio_idx = 2, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 12 + {.gpio_idx = 3, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 13 + {.gpio_idx = 4, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 14 + {.gpio_idx = 5, .irq_index = 6, .irq_n = EXTI15_10_IRQn}// pin 15 +}; + diff --git a/targets/TARGET_STM/TARGET_STM32F4/gpio_irq_device.h b/targets/TARGET_STM/TARGET_STM32F4/gpio_irq_device.h new file mode 100644 index 0000000000..6f8f1ad4c4 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F4/gpio_irq_device.h @@ -0,0 +1,94 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2017, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef MBED_GPIO_IRQ_DEVICE_H +#define MBED_GPIO_IRQ_DEVICE_H + +#ifdef __cplusplus +extern "C" { +#endif + +// when LL is available, below include can be used +// #include "stm32f4xx_ll_exti.h" +// until then let's define locally the required functions +__STATIC_INLINE void LL_EXTI_EnableRisingTrig_0_31(uint32_t ExtiLine) +{ + SET_BIT(EXTI->RTSR, ExtiLine); +} +__STATIC_INLINE void LL_EXTI_DisableRisingTrig_0_31(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->RTSR, ExtiLine); +} +__STATIC_INLINE void LL_EXTI_EnableFallingTrig_0_31(uint32_t ExtiLine) +{ + SET_BIT(EXTI->FTSR, ExtiLine); +} +__STATIC_INLINE void LL_EXTI_DisableFallingTrig_0_31(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->FTSR, ExtiLine); +} +__STATIC_INLINE void LL_EXTI_EnableIT_0_31(uint32_t ExtiLine) +{ + SET_BIT(EXTI->IMR, ExtiLine); +} +__STATIC_INLINE void LL_EXTI_DisableIT_0_31(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->IMR, ExtiLine); +} +// Above lines shall be later defined in LL + +// Number of EXTI irq vectors (EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5_9, EXTI10_15) +#define CHANNEL_NUM (7) + +#define EXTI_IRQ0_NUM_LINES 1 +#define EXTI_IRQ1_NUM_LINES 1 +#define EXTI_IRQ2_NUM_LINES 1 +#define EXTI_IRQ3_NUM_LINES 1 +#define EXTI_IRQ4_NUM_LINES 1 +#define EXTI_IRQ5_NUM_LINES 5 +#define EXTI_IRQ6_NUM_LINES 6 + +// Max pins for one line (max with EXTI10_15) +#define MAX_PIN_LINE (EXTI_IRQ6_NUM_LINES) + +/* Structure to describe how the HW EXTI lines are defined in this HW */ +typedef struct exti_lines { + uint32_t gpio_idx; // an index entry for each EXIT line + uint32_t irq_index; // the IRQ index + IRQn_Type irq_n; // the corresponding EXTI IRQn +} exti_lines_t; + +// Used to return the index for channels array. +extern const exti_lines_t pin_lines_desc[]; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32F4/pin_device.h b/targets/TARGET_STM/TARGET_STM32F4/pin_device.h new file mode 100644 index 0000000000..843580e4ef --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F4/pin_device.h @@ -0,0 +1,138 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2016, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef MBED_PIN_DEVICE_H +#define MBED_PIN_DEVICE_H + +#include "cmsis.h" + +// when LL is available, below include can be used +// #include "stm32f4xx_ll_gpio.h" +// until then let's define locally the required functions +#define LL_GPIO_PIN_0 GPIO_BSRR_BS_0 /*!< Select pin 0 */ +#define LL_GPIO_PIN_1 GPIO_BSRR_BS_1 /*!< Select pin 1 */ +#define LL_GPIO_PIN_2 GPIO_BSRR_BS_2 /*!< Select pin 2 */ +#define LL_GPIO_PIN_3 GPIO_BSRR_BS_3 /*!< Select pin 3 */ +#define LL_GPIO_PIN_4 GPIO_BSRR_BS_4 /*!< Select pin 4 */ +#define LL_GPIO_PIN_5 GPIO_BSRR_BS_5 /*!< Select pin 5 */ +#define LL_GPIO_PIN_6 GPIO_BSRR_BS_6 /*!< Select pin 6 */ +#define LL_GPIO_PIN_7 GPIO_BSRR_BS_7 /*!< Select pin 7 */ +#define LL_GPIO_PIN_8 GPIO_BSRR_BS_8 /*!< Select pin 8 */ +#define LL_GPIO_PIN_9 GPIO_BSRR_BS_9 /*!< Select pin 9 */ +#define LL_GPIO_PIN_10 GPIO_BSRR_BS_10 /*!< Select pin 10 */ +#define LL_GPIO_PIN_11 GPIO_BSRR_BS_11 /*!< Select pin 11 */ +#define LL_GPIO_PIN_12 GPIO_BSRR_BS_12 /*!< Select pin 12 */ +#define LL_GPIO_PIN_13 GPIO_BSRR_BS_13 /*!< Select pin 13 */ +#define LL_GPIO_PIN_14 GPIO_BSRR_BS_14 /*!< Select pin 14 */ +#define LL_GPIO_PIN_15 GPIO_BSRR_BS_15 /*!< Select pin 15 */ + +#define LL_GPIO_MODE_INPUT ((uint32_t)0x00000000U) /*!< Select input mode */ +#define LL_GPIO_MODE_OUTPUT GPIO_MODER_MODER0_0 /*!< Select output mode */ +#define LL_GPIO_MODE_ALTERNATE GPIO_MODER_MODER0_1 /*!< Select alternate function mode */ +#define LL_GPIO_MODE_ANALOG GPIO_MODER_MODER0 /*!< Select analog mode */ + +#define LL_GPIO_OUTPUT_PUSHPULL ((uint32_t)0x00000000U) /*!< Select push-pull as output type */ +#define LL_GPIO_OUTPUT_OPENDRAIN GPIO_OTYPER_OT_0 /*!< Select open-drain as output type */ + +#define LL_GPIO_PULL_NO ((uint32_t)0x00000000U) /*!< Select I/O no pull */ +#define LL_GPIO_PULL_UP GPIO_PUPDR_PUPDR0_0 /*!< Select I/O pull up */ +#define LL_GPIO_PULL_DOWN GPIO_PUPDR_PUPDR0_1 /*!< Select I/O pull down */ + +#define LL_GPIO_SPEED_FREQ_LOW ((uint32_t)0x00000000U) /*!< Select I/O low output speed */ +#define LL_GPIO_SPEED_FREQ_MEDIUM GPIO_OSPEEDER_OSPEEDR0_0 /*!< Select I/O medium output speed */ +#define LL_GPIO_SPEED_FREQ_HIGH GPIO_OSPEEDER_OSPEEDR0_1 /*!< Select I/O fast output speed */ +#define LL_GPIO_SPEED_FREQ_VERY_HIGH GPIO_OSPEEDER_OSPEEDR0 /*!< Select I/O high output speed */ + +__STATIC_INLINE void LL_GPIO_SetAFPin_0_7(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Alternate) +{ + MODIFY_REG(GPIOx->AFR[0], (0xFU << (POSITION_VAL(Pin) * 4U)), + (Alternate << (POSITION_VAL(Pin) * 4U))); +} +__STATIC_INLINE void LL_GPIO_SetAFPin_8_15(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Alternate) +{ + MODIFY_REG(GPIOx->AFR[1], (0xFU << (POSITION_VAL(Pin >> 8U) * 4U)), + (Alternate << (POSITION_VAL(Pin >> 8U) * 4U))); +} +__STATIC_INLINE void LL_GPIO_SetPinMode(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Mode) +{ + MODIFY_REG(GPIOx->MODER, (GPIO_MODER_MODER0 << (POSITION_VAL(Pin) * 2U)), (Mode << (POSITION_VAL(Pin) * 2U))); +} +__STATIC_INLINE uint32_t LL_GPIO_GetPinMode(GPIO_TypeDef *GPIOx, uint32_t Pin) +{ + return (uint32_t)(READ_BIT(GPIOx->MODER, ((Pin * Pin) * GPIO_MODER_MODER0)) / (Pin * Pin)); +} +__STATIC_INLINE void LL_GPIO_SetPinPull(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Pull) +{ + MODIFY_REG(GPIOx->PUPDR, (GPIO_PUPDR_PUPDR0 << (POSITION_VAL(Pin) * 2U)), (Pull << (POSITION_VAL(Pin) * 2U))); +} +__STATIC_INLINE void LL_GPIO_SetPinOutputType(GPIO_TypeDef *GPIOx, uint32_t PinMask, uint32_t OutputType) +{ + MODIFY_REG(GPIOx->OTYPER, PinMask, (PinMask * OutputType)); +} +__STATIC_INLINE void LL_GPIO_SetPinSpeed(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Speed) +{ + MODIFY_REG(GPIOx->OSPEEDR, (GPIO_OSPEEDER_OSPEEDR0 << (POSITION_VAL(Pin) * 2U)), + (Speed << (POSITION_VAL(Pin) * 2U))); +} +// Above lines shall be defined in LL when available + +extern const uint32_t ll_pin_defines[16]; + +/* Family specific implementations */ +static inline void stm_pin_DisconnectDebug(PinName pin) +{ + /* empty for now */ +} + +static inline void stm_pin_PullConfig(GPIO_TypeDef *gpio, uint32_t ll_pin, uint32_t pull_config) +{ + switch (pull_config) { + case GPIO_PULLUP: + LL_GPIO_SetPinPull(gpio, ll_pin, LL_GPIO_PULL_UP); + break; + case GPIO_PULLDOWN: + LL_GPIO_SetPinPull(gpio, ll_pin, LL_GPIO_PULL_DOWN); + break; + default: + LL_GPIO_SetPinPull(gpio, ll_pin, LL_GPIO_PULL_NO); + break; + } +} + +static inline void stm_pin_SetAFPin( GPIO_TypeDef *gpio, PinName pin, uint32_t afnum) +{ + uint32_t ll_pin = ll_pin_defines[STM_PIN(pin)]; + + if (STM_PIN(pin) > 7) + LL_GPIO_SetAFPin_8_15(gpio, ll_pin, afnum); + else + LL_GPIO_SetAFPin_0_7(gpio, ll_pin, afnum); +} + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32F4/pinmap.c b/targets/TARGET_STM/TARGET_STM32F4/pinmap.c deleted file mode 100644 index 7f9fe49f38..0000000000 --- a/targets/TARGET_STM/TARGET_STM32F4/pinmap.c +++ /dev/null @@ -1,197 +0,0 @@ -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2015, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "mbed_assert.h" -#include "pinmap.h" -#include "PortNames.h" -#include "mbed_error.h" - -// GPIO mode look-up table -static const uint32_t gpio_mode[13] = { - 0x00000000, // 0 = GPIO_MODE_INPUT - 0x00000001, // 1 = GPIO_MODE_OUTPUT_PP - 0x00000011, // 2 = GPIO_MODE_OUTPUT_OD - 0x00000002, // 3 = GPIO_MODE_AF_PP - 0x00000012, // 4 = GPIO_MODE_AF_OD - 0x00000003, // 5 = GPIO_MODE_ANALOG - 0x10110000, // 6 = GPIO_MODE_IT_RISING - 0x10210000, // 7 = GPIO_MODE_IT_FALLING - 0x10310000, // 8 = GPIO_MODE_IT_RISING_FALLING - 0x10120000, // 9 = GPIO_MODE_EVT_RISING - 0x10220000, // 10 = GPIO_MODE_EVT_FALLING - 0x10320000, // 11 = GPIO_MODE_EVT_RISING_FALLING - 0x10000000 // 12 = Reset GPIO_MODE_IT_EVT -}; - -// Enable GPIO clock and return GPIO base address -uint32_t Set_GPIO_Clock(uint32_t port_idx) -{ - uint32_t gpio_add = 0; - switch (port_idx) { - case PortA: - gpio_add = GPIOA_BASE; - __GPIOA_CLK_ENABLE(); - break; - case PortB: - gpio_add = GPIOB_BASE; - __GPIOB_CLK_ENABLE(); - break; - case PortC: - gpio_add = GPIOC_BASE; - __GPIOC_CLK_ENABLE(); - break; -#if defined GPIOD_BASE - case PortD: - gpio_add = GPIOD_BASE; - __GPIOD_CLK_ENABLE(); - break; -#endif -#if defined GPIOE_BASE - case PortE: - gpio_add = GPIOE_BASE; - __GPIOE_CLK_ENABLE(); - break; -#endif -#if defined GPIOF_BASE - case PortF: - gpio_add = GPIOF_BASE; - __GPIOF_CLK_ENABLE(); - break; -#endif -#if defined GPIOG_BASE - case PortG: - gpio_add = GPIOG_BASE; - __GPIOG_CLK_ENABLE(); - break; -#endif -#if defined GPIOH_BASE - case PortH: - gpio_add = GPIOH_BASE; - __GPIOH_CLK_ENABLE(); - break; -#endif -#if defined GPIOI_BASE - case PortI: - gpio_add = GPIOI_BASE; - __GPIOI_CLK_ENABLE(); - break; -#endif -#if defined GPIOJ_BASE - case PortJ: - gpio_add = GPIOJ_BASE; - __GPIOJ_CLK_ENABLE(); - break; -#endif -#if defined GPIOK_BASE - case PortK: - gpio_add = GPIOK_BASE; - __GPIOK_CLK_ENABLE(); - break; -#endif - default: - error("Pinmap error: wrong port number."); - break; - } - return gpio_add; -} - -/** - * Configure pin (mode, speed, output type and pull-up/pull-down) - */ -void pin_function(PinName pin, int data) -{ - MBED_ASSERT(pin != (PinName)NC); - // Get the pin informations - uint32_t mode = STM_PIN_MODE(data); - uint32_t pupd = STM_PIN_PUPD(data); - uint32_t afnum = STM_PIN_AFNUM(data); - - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add; - - // Configure GPIO - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.Pin = (uint32_t)(1 << pin_index); - GPIO_InitStructure.Mode = gpio_mode[mode]; - GPIO_InitStructure.Pull = pupd; - GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; - GPIO_InitStructure.Alternate = afnum; - HAL_GPIO_Init(gpio, &GPIO_InitStructure); - - // [TODO] Disconnect JTAG-DP + SW-DP signals. - // Warning: Need to reconnect under reset - //if ((pin == PA_13) || (pin == PA_14)) { - // - //} - //if ((pin == PA_15) || (pin == PB_3) || (pin == PB_4)) { - // - //} -} - -/** - * Configure pin pull-up/pull-down - */ -void pin_mode(PinName pin, PinMode mode) -{ - MBED_ASSERT(pin != (PinName)NC); - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add; - - // Configure pull-up/pull-down resistors - uint32_t pupd = (uint32_t)mode; - if (pupd > 2) { - pupd = 0; // Open-drain = No pull-up/No pull-down - } - gpio->PUPDR &= (uint32_t)(~(GPIO_PUPDR_PUPDR0 << (pin_index * 2))); - gpio->PUPDR |= (uint32_t)(pupd << (pin_index * 2)); -} - -/* Internal function for setting the gpiomode/function - * without changing Pull mode - */ -void pin_function_gpiomode(PinName pin, uint32_t gpiomode) { - - /* Read current pull state from HW to avoid over-write*/ - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - GPIO_TypeDef *gpio = (GPIO_TypeDef *) Set_GPIO_Clock(port_index); - uint32_t temp = gpio->PUPDR; - uint32_t pull = (temp >> (pin_index * 2U)) & GPIO_PUPDR_PUPDR0; - - /* Then re-use global function for updating the mode part*/ - pin_function(pin, STM_PIN_DATA(gpiomode, pull, 0)); -} diff --git a/targets/TARGET_STM/TARGET_STM32F4/port_api.c b/targets/TARGET_STM/TARGET_STM32F4/port_api.c deleted file mode 100644 index e982858665..0000000000 --- a/targets/TARGET_STM/TARGET_STM32F4/port_api.c +++ /dev/null @@ -1,103 +0,0 @@ -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "port_api.h" -#include "pinmap.h" -#include "gpio_api.h" -#include "mbed_error.h" - -#if DEVICE_PORTIN || DEVICE_PORTOUT - -extern uint32_t Set_GPIO_Clock(uint32_t port_idx); - -// high nibble = port number (0=A, 1=B, 2=C, 3=D, 4=E, 5=F, ...) -// low nibble = pin number -PinName port_pin(PortName port, int pin_n) -{ - return (PinName)(pin_n + (port << 4)); -} - -void port_init(port_t *obj, PortName port, int mask, PinDirection dir) -{ - uint32_t port_index = (uint32_t)port; - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add; - - // Fill PORT object structure for future use - obj->port = port; - obj->mask = mask; - obj->direction = dir; - obj->reg_in = &gpio->IDR; - obj->reg_out = &gpio->ODR; - - port_dir(obj, dir); -} - -void port_dir(port_t *obj, PinDirection dir) -{ - uint32_t i; - obj->direction = dir; - for (i = 0; i < 16; i++) { // Process all pins - if (obj->mask & (1 << i)) { // If the pin is used - if (dir == PIN_OUTPUT) { - pin_function(port_pin(obj->port, i), STM_PIN_DATA(STM_MODE_OUTPUT_PP, GPIO_NOPULL, 0)); - } else { // PIN_INPUT - pin_function(port_pin(obj->port, i), STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - } - } - } -} - -void port_mode(port_t *obj, PinMode mode) -{ - uint32_t i; - for (i = 0; i < 16; i++) { // Process all pins - if (obj->mask & (1 << i)) { // If the pin is used - pin_mode(port_pin(obj->port, i), mode); - } - } -} - -void port_write(port_t *obj, int value) -{ - *obj->reg_out = (*obj->reg_out & ~obj->mask) | (value & obj->mask); -} - -int port_read(port_t *obj) -{ - if (obj->direction == PIN_OUTPUT) { - return (*obj->reg_out & obj->mask); - } else { // PIN_INPUT - return (*obj->reg_in & obj->mask); - } -} - -#endif diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_DISCO_F746NG/system_stm32f7xx.c b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_DISCO_F746NG/system_stm32f7xx.c index fab899fb25..d3e86e4039 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_DISCO_F746NG/system_stm32f7xx.c +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_DISCO_F746NG/system_stm32f7xx.c @@ -83,7 +83,9 @@ HAL_StatusTypeDef HAL_Init(void); -#define HSE_VALUE ((uint32_t)25000000) /*!< Default value of the External oscillator in Hz */ +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ #if !defined (HSI_VALUE) #define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/ diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/TARGET_DISCO_F769NI/system_stm32f7xx.c b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/TARGET_DISCO_F769NI/system_stm32f7xx.c index c5d91fdaec..00e63dd9d5 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/TARGET_DISCO_F769NI/system_stm32f7xx.c +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/TARGET_DISCO_F769NI/system_stm32f7xx.c @@ -83,7 +83,9 @@ HAL_StatusTypeDef HAL_Init(void); -#define HSE_VALUE ((uint32_t)25000000) /*!< Default value of the External oscillator in Hz */ +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ #if !defined (HSI_VALUE) #define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/ diff --git a/targets/TARGET_STM/TARGET_STM32F7/can_api.c b/targets/TARGET_STM/TARGET_STM32F7/can_api.c deleted file mode 100644 index 73ddf859e5..0000000000 --- a/targets/TARGET_STM/TARGET_STM32F7/can_api.c +++ /dev/null @@ -1,542 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-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 "can_api.h" - -#if DEVICE_CAN - -#include "cmsis.h" -#include "pinmap.h" -#include "PeripheralPins.h" -#include "mbed_error.h" -#include -#include - -#define CAN_NUM 2 -static CAN_HandleTypeDef CanHandle; -static uint32_t can_irq_ids[CAN_NUM] = {0}; -static can_irq_handler irq_handler; - -void can_init(can_t *obj, PinName rd, PinName td) -{ - uint32_t filter_number; - CANName can_rd = (CANName)pinmap_peripheral(rd, PinMap_CAN_RD); - CANName can_td = (CANName)pinmap_peripheral(td, PinMap_CAN_TD); - obj->can = (CANName)pinmap_merge(can_rd, can_td); - MBED_ASSERT((int)obj->can != NC); - - if(obj->can == CAN_1) { - __HAL_RCC_CAN1_CLK_ENABLE(); - obj->index = 0; - } else { - __HAL_RCC_CAN2_CLK_ENABLE(); - obj->index = 1; - } - - // Configure the CAN pins - pinmap_pinout(rd, PinMap_CAN_RD); - pinmap_pinout(td, PinMap_CAN_TD); - if (rd != NC) { - pin_mode(rd, PullUp); - } - if (td != NC) { - pin_mode(td, PullUp); - } - - CanHandle.Instance = (CAN_TypeDef *)(obj->can); - - CanHandle.Init.TTCM = DISABLE; - CanHandle.Init.ABOM = DISABLE; - CanHandle.Init.AWUM = DISABLE; - CanHandle.Init.NART = DISABLE; - CanHandle.Init.RFLM = DISABLE; - CanHandle.Init.TXFP = DISABLE; - CanHandle.Init.Mode = CAN_MODE_NORMAL; - CanHandle.Init.SJW = CAN_SJW_1TQ; - CanHandle.Init.BS1 = CAN_BS1_6TQ; - CanHandle.Init.BS2 = CAN_BS2_8TQ; - CanHandle.Init.Prescaler = 2; - - if (HAL_CAN_Init(&CanHandle) != HAL_OK) { - error("Cannot initialize CAN"); - } - - filter_number = (obj->can == CAN_1) ? 0 : 14; - - // Set initial CAN frequency to 100kb/s - can_frequency(obj, 100000); - - can_filter(obj, 0, 0, CANStandard, filter_number); -} - -void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id) -{ - irq_handler = handler; - can_irq_ids[obj->index] = id; -} - -void can_irq_free(can_t *obj) -{ - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - can->IER &= ~(CAN_IT_FMP0 | CAN_IT_FMP1 | CAN_IT_TME | \ - CAN_IT_ERR | CAN_IT_EPV | CAN_IT_BOF); - can_irq_ids[obj->can] = 0; -} - -void can_free(can_t *obj) -{ - // Reset CAN and disable clock - if (obj->can == CAN_1) { - __HAL_RCC_CAN1_FORCE_RESET(); - __HAL_RCC_CAN1_RELEASE_RESET(); - __HAL_RCC_CAN1_CLK_DISABLE(); - } - - if (obj->can == CAN_2) { - __HAL_RCC_CAN2_FORCE_RESET(); - __HAL_RCC_CAN2_RELEASE_RESET(); - __HAL_RCC_CAN2_CLK_DISABLE(); - } -} - -// The following table is used to program bit_timing. It is an adjustment of the sample -// point by synchronizing on the start-bit edge and resynchronizing on the following edges. -// This table has the sampling points as close to 75% as possible (most commonly used). -// The first value is TSEG1, the second TSEG2. -static const int timing_pts[23][2] = { - {0x0, 0x0}, // 2, 50% - {0x1, 0x0}, // 3, 67% - {0x2, 0x0}, // 4, 75% - {0x3, 0x0}, // 5, 80% - {0x3, 0x1}, // 6, 67% - {0x4, 0x1}, // 7, 71% - {0x5, 0x1}, // 8, 75% - {0x6, 0x1}, // 9, 78% - {0x6, 0x2}, // 10, 70% - {0x7, 0x2}, // 11, 73% - {0x8, 0x2}, // 12, 75% - {0x9, 0x2}, // 13, 77% - {0x9, 0x3}, // 14, 71% - {0xA, 0x3}, // 15, 73% - {0xB, 0x3}, // 16, 75% - {0xC, 0x3}, // 17, 76% - {0xD, 0x3}, // 18, 78% - {0xD, 0x4}, // 19, 74% - {0xE, 0x4}, // 20, 75% - {0xF, 0x4}, // 21, 76% - {0xF, 0x5}, // 22, 73% - {0xF, 0x6}, // 23, 70% - {0xF, 0x7}, // 24, 67% -}; - -static unsigned int can_speed(unsigned int pclk, unsigned int cclk, unsigned char psjw) -{ - uint32_t btr; - uint16_t brp = 0; - uint32_t calcbit; - uint32_t bitwidth; - int hit = 0; - int bits; - - bitwidth = (pclk / cclk); - - brp = bitwidth / 0x18; - while ((!hit) && (brp < bitwidth / 4)) { - brp++; - for (bits = 22; bits > 0; bits--) { - calcbit = (bits + 3) * (brp + 1); - if (calcbit == bitwidth) { - hit = 1; - break; - } - } - } - - if (hit) { - btr = ((timing_pts[bits][1] << 20) & 0x00700000) - | ((timing_pts[bits][0] << 16) & 0x000F0000) - | ((psjw << 24) & 0x0000C000) - | ((brp << 0) & 0x000003FF); - } else { - btr = 0xFFFFFFFF; - } - - return btr; - -} - -int can_frequency(can_t *obj, int f) -{ - int pclk = HAL_RCC_GetPCLK1Freq(); - int btr = can_speed(pclk, (unsigned int)f, 1); - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - if (btr > 0) { - can->MCR |= CAN_MCR_INRQ ; - while((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { - } - can->BTR = btr; - can->MCR &= ~(uint32_t)CAN_MCR_INRQ; - while((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { - } - return 1; - } else { - return 0; - } -} - -int can_write(can_t *obj, CAN_Message msg, int cc) -{ - uint32_t transmitmailbox = 5; - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - /* Select one empty transmit mailbox */ - if ((can->TSR&CAN_TSR_TME0) == CAN_TSR_TME0) { - transmitmailbox = 0; - } else if ((can->TSR&CAN_TSR_TME1) == CAN_TSR_TME1) { - transmitmailbox = 1; - } else if ((can->TSR&CAN_TSR_TME2) == CAN_TSR_TME2) { - transmitmailbox = 2; - } else { - transmitmailbox = CAN_TXSTATUS_NOMAILBOX; - } - - if (transmitmailbox != CAN_TXSTATUS_NOMAILBOX) { - can->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ; - if (!(msg.format)) - { - can->sTxMailBox[transmitmailbox].TIR |= ((msg.id << 21) | msg.type); - } - else - { - can->sTxMailBox[transmitmailbox].TIR |= ((msg.id << 3) | CAN_ID_EXT | msg.type); - } - - /* Set up the DLC */ - can->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0; - can->sTxMailBox[transmitmailbox].TDTR |= (msg.len & (uint8_t)0x0000000F); - - /* Set up the data field */ - can->sTxMailBox[transmitmailbox].TDLR = (((uint32_t)msg.data[3] << 24) | - ((uint32_t)msg.data[2] << 16) | - ((uint32_t)msg.data[1] << 8) | - ((uint32_t)msg.data[0])); - can->sTxMailBox[transmitmailbox].TDHR = (((uint32_t)msg.data[7] << 24) | - ((uint32_t)msg.data[6] << 16) | - ((uint32_t)msg.data[5] << 8) | - ((uint32_t)msg.data[4])); - /* Request transmission */ - can->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ; - } - - return 1; -} - -int can_read(can_t *obj, CAN_Message *msg, int handle) -{ - //handle is the FIFO number - - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - // check FPM0 which holds the pending message count in FIFO 0 - // if no message is pending, return 0 - if ((can->RF0R & CAN_RF0R_FMP0) == 0) { - return 0; - } - - /* Get the Id */ - msg->format = (CANFormat)((uint8_t)0x04 & can->sFIFOMailBox[handle].RIR); - if (!msg->format) { - msg->id = (uint32_t)0x000007FF & (can->sFIFOMailBox[handle].RIR >> 21); - } else { - msg->id = (uint32_t)0x1FFFFFFF & (can->sFIFOMailBox[handle].RIR >> 3); - } - - msg->type = (CANType)((uint8_t)0x02 & can->sFIFOMailBox[handle].RIR); - /* Get the DLC */ - msg->len = (uint8_t)0x0F & can->sFIFOMailBox[handle].RDTR; -// /* Get the FMI */ -// msg->FMI = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDTR >> 8); - /* Get the data field */ - msg->data[0] = (uint8_t)0xFF & can->sFIFOMailBox[handle].RDLR; - msg->data[1] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDLR >> 8); - msg->data[2] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDLR >> 16); - msg->data[3] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDLR >> 24); - msg->data[4] = (uint8_t)0xFF & can->sFIFOMailBox[handle].RDHR; - msg->data[5] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDHR >> 8); - msg->data[6] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDHR >> 16); - msg->data[7] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDHR >> 24); - - /* Release the FIFO */ - if(handle == CAN_FIFO0) { - /* Release FIFO0 */ - can->RF0R |= CAN_RF0R_RFOM0; - } else { /* FIFONumber == CAN_FIFO1 */ - /* Release FIFO1 */ - can->RF1R |= CAN_RF1R_RFOM1; - } - - return 1; -} - -void can_reset(can_t *obj) -{ - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - can->MCR |= CAN_MCR_RESET; - can->ESR = 0x0; -} - -unsigned char can_rderror(can_t *obj) -{ - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - return (can->ESR >> 24) & 0xFF; -} - -unsigned char can_tderror(can_t *obj) -{ - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - return (can->ESR >> 16) & 0xFF; -} - -void can_monitor(can_t *obj, int silent) -{ - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - can->MCR |= CAN_MCR_INRQ ; - while((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { - } - if (silent) { - can->BTR |= ((uint32_t)1 << 31); - } else { - can->BTR &= ~((uint32_t)1 << 31); - } - can->MCR &= ~(uint32_t)CAN_MCR_INRQ; - while((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { - } -} - -int can_mode(can_t *obj, CanMode mode) -{ - int success = 0; - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - can->MCR |= CAN_MCR_INRQ ; - while((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { - } - switch (mode) { - case MODE_NORMAL: - can->BTR &= ~(CAN_BTR_SILM | CAN_BTR_LBKM); - success = 1; - break; - case MODE_SILENT: - can->BTR |= CAN_BTR_SILM; - can->BTR &= ~CAN_BTR_LBKM; - success = 1; - break; - case MODE_TEST_GLOBAL: - case MODE_TEST_LOCAL: - can->BTR |= CAN_BTR_LBKM; - can->BTR &= ~CAN_BTR_SILM; - success = 1; - break; - case MODE_TEST_SILENT: - can->BTR |= (CAN_BTR_SILM | CAN_BTR_LBKM); - success = 1; - break; - default: - success = 0; - break; - } - can->MCR &= ~(uint32_t)CAN_MCR_INRQ; - while((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { - } - return success; -} - -int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) -{ - CanHandle.Instance = (CAN_TypeDef *)(obj->can); - CAN_FilterConfTypeDef sFilterConfig; - - sFilterConfig.FilterNumber = handle; - sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; - sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; - sFilterConfig.FilterIdHigh = (uint8_t) (id >> 8); - sFilterConfig.FilterIdLow = (uint8_t) id; - sFilterConfig.FilterMaskIdHigh = (uint8_t) (mask >> 8); - sFilterConfig.FilterMaskIdLow = (uint8_t) mask; - sFilterConfig.FilterFIFOAssignment = 0; - sFilterConfig.FilterActivation = ENABLE; - sFilterConfig.BankNumber = 14; - - HAL_CAN_ConfigFilter(&CanHandle, &sFilterConfig); - - return 0; -} - -static void can_irq(CANName name, int id) -{ - uint32_t tmp1 = 0, tmp2 = 0, tmp3 = 0; - CanHandle.Instance = (CAN_TypeDef *)name; - - if(__HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_TME)) { - tmp1 = __HAL_CAN_TRANSMIT_STATUS(&CanHandle, CAN_TXMAILBOX_0); - tmp2 = __HAL_CAN_TRANSMIT_STATUS(&CanHandle, CAN_TXMAILBOX_1); - tmp3 = __HAL_CAN_TRANSMIT_STATUS(&CanHandle, CAN_TXMAILBOX_2); - if(tmp1 || tmp2 || tmp3) - { - irq_handler(can_irq_ids[id], IRQ_TX); - } - } - - tmp1 = __HAL_CAN_MSG_PENDING(&CanHandle, CAN_FIFO0); - tmp2 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_FMP0); - - if((tmp1 != 0) && tmp2) { - irq_handler(can_irq_ids[id], IRQ_RX); - } - - tmp1 = __HAL_CAN_GET_FLAG(&CanHandle, CAN_FLAG_EPV); - tmp2 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_EPV); - tmp3 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_ERR); - - if(tmp1 && tmp2 && tmp3) { - irq_handler(can_irq_ids[id], IRQ_PASSIVE); - } - - tmp1 = __HAL_CAN_GET_FLAG(&CanHandle, CAN_FLAG_BOF); - tmp2 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_BOF); - tmp3 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_ERR); - if(tmp1 && tmp2 && tmp3) { - irq_handler(can_irq_ids[id], IRQ_BUS); - } - - tmp3 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_ERR); - if(tmp1 && tmp2 && tmp3) { - irq_handler(can_irq_ids[id], IRQ_ERROR); - } -} - -void CAN1_RX0_IRQHandler(void) -{ - can_irq(CAN_1, 0); -} - -void CAN1_TX_IRQHandler(void) -{ - can_irq(CAN_1, 0); -} - -void CAN1_SCE_IRQHandler(void) -{ - can_irq(CAN_1, 0); -} - -void CAN2_RX0_IRQHandler(void) -{ - can_irq(CAN_2, 1); -} - -void CAN2_TX_IRQHandler(void) -{ - can_irq(CAN_2, 1); -} - -void CAN2_SCE_IRQHandler(void) -{ - can_irq(CAN_2, 1); -} - -void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable) -{ - - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - IRQn_Type irq_n = (IRQn_Type)0; - uint32_t vector = 0; - uint32_t ier; - - if(obj->can == CAN_1) { - switch (type) { - case IRQ_RX: - ier = CAN_IT_FMP0; - irq_n = CAN1_RX0_IRQn; - vector = (uint32_t)&CAN1_RX0_IRQHandler; - break; - case IRQ_TX: - ier = CAN_IT_TME; - irq_n = CAN1_TX_IRQn; - vector = (uint32_t)&CAN1_TX_IRQHandler; - break; - case IRQ_ERROR: - ier = CAN_IT_ERR; - irq_n = CAN1_SCE_IRQn; - vector = (uint32_t)&CAN1_SCE_IRQHandler; - break; - case IRQ_PASSIVE: - ier = CAN_IT_EPV; - irq_n = CAN1_SCE_IRQn; - vector = (uint32_t)&CAN1_SCE_IRQHandler; - break; - case IRQ_BUS: - ier = CAN_IT_BOF; - irq_n = CAN1_SCE_IRQn; - vector = (uint32_t)&CAN1_SCE_IRQHandler; - break; - default: return; - } - } else { - switch (type) { - case IRQ_RX: - ier = CAN_IT_FMP0; - irq_n = CAN2_RX0_IRQn; - vector = (uint32_t)&CAN2_RX0_IRQHandler; - break; - case IRQ_TX: - ier = CAN_IT_TME; - irq_n = CAN2_TX_IRQn; - vector = (uint32_t)&CAN2_TX_IRQHandler; - break; - case IRQ_ERROR: - ier = CAN_IT_ERR; - irq_n = CAN2_SCE_IRQn; - vector = (uint32_t)&CAN2_SCE_IRQHandler; - break; - case IRQ_PASSIVE: - ier = CAN_IT_EPV; - irq_n = CAN2_SCE_IRQn; - vector = (uint32_t)&CAN2_SCE_IRQHandler; - break; - case IRQ_BUS: - ier = CAN_IT_BOF; - irq_n = CAN2_SCE_IRQn; - vector = (uint32_t)&CAN2_SCE_IRQHandler; - break; - default: return; - } - } - - if(enable) { - can->IER |= ier; - } else { - can->IER &= ~ier; - } - - NVIC_SetVector(irq_n, vector); - NVIC_EnableIRQ(irq_n); -} - -#endif // DEVICE_CAN - diff --git a/targets/TARGET_STM/TARGET_STM32F7/can_device.h b/targets/TARGET_STM/TARGET_STM32F7/can_device.h new file mode 100644 index 0000000000..8689988944 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F7/can_device.h @@ -0,0 +1,53 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-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. + */ +#ifndef MBED_CAN_DEVICE_H +#define MBED_CAN_DEVICE_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef DEVICE_CAN + +#define CAN_NUM 2 // Number of CAN peripherals present in the STM32 serie (1 or 2) + +#define CAN1_IRQ_RX_IRQN CAN1_RX0_IRQn +#define CAN1_IRQ_RX_VECT CAN1_RX0_IRQHandler +#define CAN1_IRQ_TX_IRQN CAN1_TX_IRQn +#define CAN1_IRQ_TX_VECT CAN1_TX_IRQHandler +#define CAN1_IRQ_ERROR_IRQN CAN1_SCE_IRQn +#define CAN1_IRQ_ERROR_VECT CAN1_SCE_IRQHandler +#define CAN1_IRQ_PASSIVE_IRQN CAN1_SCE_IRQn +#define CAN1_IRQ_PASSIVE_VECT CAN1_SCE_IRQHandler +#define CAN1_IRQ_BUS_IRQN CAN1_SCE_IRQn +#define CAN1_IRQ_BUS_VECT CAN1_SCE_IRQHandler + +#define CAN2_IRQ_RX_IRQN CAN2_RX0_IRQn +#define CAN2_IRQ_RX_VECT CAN2_RX0_IRQHandler +#define CAN2_IRQ_TX_IRQN CAN2_TX_IRQn +#define CAN2_IRQ_TX_VECT CAN2_TX_IRQHandler +#define CAN2_IRQ_ERROR_IRQN CAN2_SCE_IRQn +#define CAN2_IRQ_ERROR_VECT CAN2_SCE_IRQHandler +#define CAN2_IRQ_PASSIVE_IRQN CAN2_SCE_IRQn +#define CAN2_IRQ_PASSIVE_VECT CAN2_SCE_IRQHandler +#define CAN2_IRQ_BUS_IRQN CAN2_SCE_IRQn +#define CAN2_IRQ_BUS_VECT CAN2_SCE_IRQHandler + +#endif // DEVICE_CAN + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32F7/device/stm32f7xx_hal_conf.h b/targets/TARGET_STM/TARGET_STM32F7/device/stm32f7xx_hal_conf.h index 9260ccee56..dd26352919 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/device/stm32f7xx_hal_conf.h +++ b/targets/TARGET_STM/TARGET_STM32F7/device/stm32f7xx_hal_conf.h @@ -103,9 +103,12 @@ * This value is used by the RCC HAL module to compute the system frequency * (when HSE is used as system clock source, directly or through the PLL). */ -#if !defined (HSE_VALUE) - #define HSE_VALUE 8000000U /*!< Value of the External oscillator in Hz */ -#endif /* HSE_VALUE */ +//#if !defined (HSE_VALUE) +#if defined(TARGET_DISCO_F746NG) || defined(TARGET_DISCO_F769NI) + #define HSE_VALUE 25000000U /*!< Value of the External oscillator in Hz */ +#else + #define HSE_VALUE 8000000U /*!< Default value of the External oscillator in Hz */ +#endif #if !defined (HSE_STARTUP_TIMEOUT) #define HSE_STARTUP_TIMEOUT 200U /*!< Time out for HSE start up, in ms */ diff --git a/targets/TARGET_STM/TARGET_STM32F7/gpio_irq_api.c b/targets/TARGET_STM/TARGET_STM32F7/gpio_irq_api.c deleted file mode 100644 index c595b98ba6..0000000000 --- a/targets/TARGET_STM/TARGET_STM32F7/gpio_irq_api.c +++ /dev/null @@ -1,334 +0,0 @@ -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2016, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include -#include "cmsis.h" -#include "gpio_irq_api.h" -#include "pinmap.h" -#include "mbed_error.h" - -#define EDGE_NONE (0) -#define EDGE_RISE (1) -#define EDGE_FALL (2) -#define EDGE_BOTH (3) - -// Number of EXTI irq vectors (EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5_9, EXTI10_15) -#define CHANNEL_NUM (7) - -// Max pins for one line (max with EXTI10_15) -#define MAX_PIN_LINE (6) - -typedef struct gpio_channel { - uint32_t pin_mask; // bitmask representing which pins are configured for receiving interrupts - uint32_t channel_ids[MAX_PIN_LINE]; // mbed "gpio_irq_t gpio_irq" field of instance - uint32_t channel_gpio[MAX_PIN_LINE]; // base address of gpio port group - uint32_t channel_pin[MAX_PIN_LINE]; // pin number in port group -} gpio_channel_t; - -static gpio_channel_t channels[CHANNEL_NUM] = { - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0} -}; - -// Used to return the index for channels array. -static uint32_t pin_base_nr[16] = { - // EXTI0 - 0, // pin 0 - // EXTI1 - 0, // pin 1 - // EXTI2 - 0, // pin 2 - // EXTI3 - 0, // pin 3 - // EXTI4 - 0, // pin 4 - // EXTI5_9 - 0, // pin 5 - 1, // pin 6 - 2, // pin 7 - 3, // pin 8 - 4, // pin 9 - // EXTI10_15 - 0, // pin 10 - 1, // pin 11 - 2, // pin 12 - 3, // pin 13 - 4, // pin 14 - 5 // pin 15 -}; - -static gpio_irq_handler irq_handler; - -static void handle_interrupt_in(uint32_t irq_index, uint32_t max_num_pin_line) -{ - gpio_channel_t *gpio_channel = &channels[irq_index]; - uint32_t gpio_idx; - - for (gpio_idx = 0; gpio_idx < max_num_pin_line; gpio_idx++) { - uint32_t current_mask = (1 << gpio_idx); - - if (gpio_channel->pin_mask & current_mask) { - // Retrieve the gpio and pin that generate the irq - GPIO_TypeDef *gpio = (GPIO_TypeDef *)(gpio_channel->channel_gpio[gpio_idx]); - uint32_t pin = (uint32_t)(1 << (gpio_channel->channel_pin[gpio_idx])); - - // Clear interrupt flag - if (__HAL_GPIO_EXTI_GET_FLAG(pin) != RESET) { - __HAL_GPIO_EXTI_CLEAR_FLAG(pin); - - if (gpio_channel->channel_ids[gpio_idx] == 0) continue; - - // Check which edge has generated the irq - if ((gpio->IDR & pin) == 0) { - irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_FALL); - } else { - irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_RISE); - } - } - } - } -} - -// EXTI line 0 -static void gpio_irq0(void) -{ - handle_interrupt_in(0, 1); -} - -// EXTI line 1 -static void gpio_irq1(void) -{ - handle_interrupt_in(1, 1); -} - -// EXTI line 2 -static void gpio_irq2(void) -{ - handle_interrupt_in(2, 1); -} - -// EXTI line 3 -static void gpio_irq3(void) -{ - handle_interrupt_in(3, 1); -} - -// EXTI line 4 -static void gpio_irq4(void) -{ - handle_interrupt_in(4, 1); -} - -// EXTI lines 5 to 9 -static void gpio_irq5(void) -{ - handle_interrupt_in(5, 5); -} - -// EXTI lines 10 to 15 -static void gpio_irq6(void) -{ - handle_interrupt_in(6, 6); -} - -extern uint32_t Set_GPIO_Clock(uint32_t port_idx); -extern void pin_function_gpiomode(PinName pin, uint32_t gpiomode); - -int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) -{ - IRQn_Type irq_n = (IRQn_Type)0; - uint32_t vector = 0; - uint32_t irq_index; - gpio_channel_t *gpio_channel; - uint32_t gpio_idx; - - if (pin == NC) return -1; - - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - - // Select irq number and interrupt routine - switch (pin_index) { - case 0: - irq_n = EXTI0_IRQn; - vector = (uint32_t)&gpio_irq0; - irq_index = 0; - break; - case 1: - irq_n = EXTI1_IRQn; - vector = (uint32_t)&gpio_irq1; - irq_index = 1; - break; - case 2: - irq_n = EXTI2_IRQn; - vector = (uint32_t)&gpio_irq2; - irq_index = 2; - break; - case 3: - irq_n = EXTI3_IRQn; - vector = (uint32_t)&gpio_irq3; - irq_index = 3; - break; - case 4: - irq_n = EXTI4_IRQn; - vector = (uint32_t)&gpio_irq4; - irq_index = 4; - break; - case 5: - case 6: - case 7: - case 8: - case 9: - irq_n = EXTI9_5_IRQn; - vector = (uint32_t)&gpio_irq5; - irq_index = 5; - break; - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - irq_n = EXTI15_10_IRQn; - vector = (uint32_t)&gpio_irq6; - irq_index = 6; - break; - default: - error("InterruptIn error: pin not supported.\n"); - return -1; - } - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - - // Configure GPIO - pin_function(pin, STM_PIN_DATA(STM_MODE_IT_FALLING, GPIO_NOPULL, 0)); - - // Enable EXTI interrupt - NVIC_SetVector(irq_n, vector); - NVIC_EnableIRQ(irq_n); - - // Save informations for future use - obj->irq_n = irq_n; - obj->irq_index = irq_index; - obj->event = EDGE_NONE; - obj->pin = pin; - - gpio_channel = &channels[irq_index]; - gpio_idx = pin_base_nr[pin_index]; - gpio_channel->pin_mask |= (1 << gpio_idx); - gpio_channel->channel_ids[gpio_idx] = id; - gpio_channel->channel_gpio[gpio_idx] = gpio_add; - gpio_channel->channel_pin[gpio_idx] = pin_index; - - irq_handler = handler; - - return 0; -} - -void gpio_irq_free(gpio_irq_t *obj) -{ - gpio_channel_t *gpio_channel = &channels[obj->irq_index]; - uint32_t pin_index = STM_PIN(obj->pin); - uint32_t gpio_addr = GPIOA_BASE + (GPIOB_BASE-GPIOA_BASE) * STM_PORT(obj->pin); - uint32_t gpio_idx = pin_base_nr[pin_index]; - - HAL_GPIO_DeInit((GPIO_TypeDef *)gpio_addr, (1<pin_mask &= ~(1 << gpio_idx); - gpio_channel->channel_ids[gpio_idx] = 0; - gpio_channel->channel_gpio[gpio_idx] = 0; - gpio_channel->channel_pin[gpio_idx] = 0; - - // Disable EXTI line, but don't change pull-up config - pin_function_gpiomode(obj->pin, STM_MODE_INPUT); - obj->event = EDGE_NONE; -} - -void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) -{ - uint32_t mode = STM_MODE_IT_EVT_RESET; - - if (enable) { - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or RISE - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or FALL - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } - } - } else { // Disable - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } else { // NONE or RISE - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } else { // NONE or FALL - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } - } - } - - pin_function_gpiomode(obj->pin, mode); -} - -void gpio_irq_enable(gpio_irq_t *obj) -{ - NVIC_EnableIRQ(obj->irq_n); -} - -void gpio_irq_disable(gpio_irq_t *obj) -{ - NVIC_DisableIRQ(obj->irq_n); - obj->event = EDGE_NONE; -} diff --git a/targets/TARGET_STM/TARGET_STM32F7/gpio_irq_device.c b/targets/TARGET_STM/TARGET_STM32F7/gpio_irq_device.c new file mode 100644 index 0000000000..9f63aff054 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F7/gpio_irq_device.c @@ -0,0 +1,59 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2017, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include "cmsis.h" +#include "gpio_irq_device.h" + +// Used to return the index for channels array. +const exti_lines_t pin_lines_desc[16] = { + // EXTI0 + {.gpio_idx = 0, .irq_index = 0, .irq_n = EXTI0_IRQn}, // pin 0 + // EXTI1 + {.gpio_idx = 0, .irq_index = 1, .irq_n = EXTI1_IRQn}, // pin 1 + // EXTI2 + {.gpio_idx = 0, .irq_index = 2, .irq_n = EXTI2_IRQn}, // pin 2 + // EXTI3 + {.gpio_idx = 0, .irq_index = 3, .irq_n = EXTI3_IRQn}, // pin 3 + // EXTI4 + {.gpio_idx = 0, .irq_index = 4, .irq_n = EXTI4_IRQn}, // pin 4 + // EXTI5_9 + {.gpio_idx = 0, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 5 + {.gpio_idx = 1, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 6 + {.gpio_idx = 2, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 7 + {.gpio_idx = 3, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 8 + {.gpio_idx = 4, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 9 + // EXTI10_15 + {.gpio_idx = 0, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 10 + {.gpio_idx = 1, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 11 + {.gpio_idx = 2, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 12 + {.gpio_idx = 3, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 13 + {.gpio_idx = 4, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 14 + {.gpio_idx = 5, .irq_index = 6, .irq_n = EXTI15_10_IRQn}// pin 15 +}; + diff --git a/targets/TARGET_STM/TARGET_STM32F7/gpio_irq_device.h b/targets/TARGET_STM/TARGET_STM32F7/gpio_irq_device.h new file mode 100644 index 0000000000..55f798e83f --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F7/gpio_irq_device.h @@ -0,0 +1,94 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2017, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef MBED_GPIO_IRQ_DEVICE_H +#define MBED_GPIO_IRQ_DEVICE_H + +#ifdef __cplusplus +extern "C" { +#endif + +// when LL is available, below include can be used +// #include "stm32f0xx_f7_exti.h" +// until then let's define locally the required functions +__STATIC_INLINE void LL_EXTI_EnableRisingTrig_0_31(uint32_t ExtiLine) +{ + SET_BIT(EXTI->RTSR, ExtiLine); +} +__STATIC_INLINE void LL_EXTI_DisableRisingTrig_0_31(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->RTSR, ExtiLine); +} +__STATIC_INLINE void LL_EXTI_EnableFallingTrig_0_31(uint32_t ExtiLine) +{ + SET_BIT(EXTI->FTSR, ExtiLine); +} +__STATIC_INLINE void LL_EXTI_DisableFallingTrig_0_31(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->FTSR, ExtiLine); +} +__STATIC_INLINE void LL_EXTI_EnableIT_0_31(uint32_t ExtiLine) +{ + SET_BIT(EXTI->IMR, ExtiLine); +} +__STATIC_INLINE void LL_EXTI_DisableIT_0_31(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->IMR, ExtiLine); +} +// Above lines shall be later defined in LL + +// Number of EXTI irq vectors (EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5_9, EXTI10_15) +#define CHANNEL_NUM (7) + +#define EXTI_IRQ0_NUM_LINES 1 +#define EXTI_IRQ1_NUM_LINES 1 +#define EXTI_IRQ2_NUM_LINES 1 +#define EXTI_IRQ3_NUM_LINES 1 +#define EXTI_IRQ4_NUM_LINES 1 +#define EXTI_IRQ5_NUM_LINES 5 +#define EXTI_IRQ6_NUM_LINES 6 + +// Max pins for one line (max with EXTI10_15) +#define MAX_PIN_LINE (EXTI_IRQ6_NUM_LINES) + +/* Structure to describe how the HW EXTI lines are defined in this HW */ +typedef struct exti_lines { + uint32_t gpio_idx; // an index entry for each EXIT line + uint32_t irq_index; // the IRQ index + IRQn_Type irq_n; // the corresponding EXTI IRQn +} exti_lines_t; + +// Used to return the index for channels array. +extern const exti_lines_t pin_lines_desc[]; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32F7/pin_device.h b/targets/TARGET_STM/TARGET_STM32F7/pin_device.h new file mode 100644 index 0000000000..6551d95483 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F7/pin_device.h @@ -0,0 +1,140 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2016, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef MBED_PIN_DEVICE_H +#define MBED_PIN_DEVICE_H + +#include "cmsis.h" + +// when LL is available, below include can be used +// #include "stm32f7xx_ll_gpio.h" +// until then let's define locally the required functions +#define LL_GPIO_PIN_0 GPIO_BSRR_BS_0 /*!< Select pin 0 */ +#define LL_GPIO_PIN_1 GPIO_BSRR_BS_1 /*!< Select pin 1 */ +#define LL_GPIO_PIN_2 GPIO_BSRR_BS_2 /*!< Select pin 2 */ +#define LL_GPIO_PIN_3 GPIO_BSRR_BS_3 /*!< Select pin 3 */ +#define LL_GPIO_PIN_4 GPIO_BSRR_BS_4 /*!< Select pin 4 */ +#define LL_GPIO_PIN_5 GPIO_BSRR_BS_5 /*!< Select pin 5 */ +#define LL_GPIO_PIN_6 GPIO_BSRR_BS_6 /*!< Select pin 6 */ +#define LL_GPIO_PIN_7 GPIO_BSRR_BS_7 /*!< Select pin 7 */ +#define LL_GPIO_PIN_8 GPIO_BSRR_BS_8 /*!< Select pin 8 */ +#define LL_GPIO_PIN_9 GPIO_BSRR_BS_9 /*!< Select pin 9 */ +#define LL_GPIO_PIN_10 GPIO_BSRR_BS_10 /*!< Select pin 10 */ +#define LL_GPIO_PIN_11 GPIO_BSRR_BS_11 /*!< Select pin 11 */ +#define LL_GPIO_PIN_12 GPIO_BSRR_BS_12 /*!< Select pin 12 */ +#define LL_GPIO_PIN_13 GPIO_BSRR_BS_13 /*!< Select pin 13 */ +#define LL_GPIO_PIN_14 GPIO_BSRR_BS_14 /*!< Select pin 14 */ +#define LL_GPIO_PIN_15 GPIO_BSRR_BS_15 /*!< Select pin 15 */ + +#define LL_GPIO_MODE_INPUT ((uint32_t)0x00000000U) /*!< Select input mode */ +#define LL_GPIO_MODE_OUTPUT GPIO_MODER_MODER0_0 /*!< Select output mode */ +#define LL_GPIO_MODE_ALTERNATE GPIO_MODER_MODER0_1 /*!< Select alternate function mode */ +#define LL_GPIO_MODE_ANALOG GPIO_MODER_MODER0 /*!< Select analog mode */ + +#define LL_GPIO_OUTPUT_PUSHPULL ((uint32_t)0x00000000U) /*!< Select push-pull as output type */ +#define LL_GPIO_OUTPUT_OPENDRAIN GPIO_OTYPER_OT_0 /*!< Select open-drain as output type */ + +#define LL_GPIO_PULL_NO ((uint32_t)0x00000000U) /*!< Select I/O no pull */ +#define LL_GPIO_PULL_UP GPIO_PUPDR_PUPDR0_0 /*!< Select I/O pull up */ +#define LL_GPIO_PULL_DOWN GPIO_PUPDR_PUPDR0_1 /*!< Select I/O pull down */ + +#define LL_GPIO_SPEED_FREQ_LOW ((uint32_t)0x00000000U) /*!< Select I/O low output speed */ +#define LL_GPIO_SPEED_FREQ_MEDIUM GPIO_OSPEEDER_OSPEEDR0_0 /*!< Select I/O medium output speed */ +#define LL_GPIO_SPEED_FREQ_HIGH GPIO_OSPEEDER_OSPEEDR0_1 /*!< Select I/O fast output speed */ +#define LL_GPIO_SPEED_FREQ_VERY_HIGH GPIO_OSPEEDER_OSPEEDR0 /*!< Select I/O high output speed */ + + +__STATIC_INLINE void LL_GPIO_SetAFPin_0_7(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Alternate) +{ + MODIFY_REG(GPIOx->AFR[0], (0xFU << (POSITION_VAL(Pin) * 4U)), + (Alternate << (POSITION_VAL(Pin) * 4U))); +} + +__STATIC_INLINE void LL_GPIO_SetAFPin_8_15(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Alternate) +{ + MODIFY_REG(GPIOx->AFR[1], (0xFU << (POSITION_VAL(Pin >> 8U) * 4U)), + (Alternate << (POSITION_VAL(Pin >> 8U) * 4U))); +} +__STATIC_INLINE void LL_GPIO_SetPinMode(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Mode) +{ + MODIFY_REG(GPIOx->MODER, (GPIO_MODER_MODER0 << (POSITION_VAL(Pin) * 2U)), (Mode << (POSITION_VAL(Pin) * 2U))); +} +__STATIC_INLINE uint32_t LL_GPIO_GetPinMode(GPIO_TypeDef *GPIOx, uint32_t Pin) +{ + return (uint32_t)(READ_BIT(GPIOx->MODER, ((Pin * Pin) * GPIO_MODER_MODER0)) / (Pin * Pin)); +} +__STATIC_INLINE void LL_GPIO_SetPinPull(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Pull) +{ + MODIFY_REG(GPIOx->PUPDR, (GPIO_PUPDR_PUPDR0 << (POSITION_VAL(Pin) * 2U)), (Pull << (POSITION_VAL(Pin) * 2U))); +} +__STATIC_INLINE void LL_GPIO_SetPinOutputType(GPIO_TypeDef *GPIOx, uint32_t PinMask, uint32_t OutputType) +{ + MODIFY_REG(GPIOx->OTYPER, PinMask, (PinMask * OutputType)); +} +__STATIC_INLINE void LL_GPIO_SetPinSpeed(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Speed) +{ + MODIFY_REG(GPIOx->OSPEEDR, (GPIO_OSPEEDER_OSPEEDR0 << (POSITION_VAL(Pin) * 2U)), + (Speed << (POSITION_VAL(Pin) * 2U))); +} +// Above lines shall be defined in LL when available + +extern const uint32_t ll_pin_defines[16]; + +/* Family specific implementations */ +static inline void stm_pin_DisconnectDebug(PinName pin) +{ + /* empty for now */ +} + +static inline void stm_pin_PullConfig(GPIO_TypeDef *gpio, uint32_t ll_pin, uint32_t pull_config) +{ + switch (pull_config) { + case GPIO_PULLUP: + LL_GPIO_SetPinPull(gpio, ll_pin, LL_GPIO_PULL_UP); + break; + case GPIO_PULLDOWN: + LL_GPIO_SetPinPull(gpio, ll_pin, LL_GPIO_PULL_DOWN); + break; + default: + LL_GPIO_SetPinPull(gpio, ll_pin, LL_GPIO_PULL_NO); + break; + } +} + +static inline void stm_pin_SetAFPin( GPIO_TypeDef *gpio, PinName pin, uint32_t afnum) +{ + uint32_t ll_pin = ll_pin_defines[STM_PIN(pin)]; + + if (STM_PIN(pin) > 7) + LL_GPIO_SetAFPin_8_15(gpio, ll_pin, afnum); + else + LL_GPIO_SetAFPin_0_7(gpio, ll_pin, afnum); +} + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32F7/pinmap.c b/targets/TARGET_STM/TARGET_STM32F7/pinmap.c deleted file mode 100644 index 62cb340294..0000000000 --- a/targets/TARGET_STM/TARGET_STM32F7/pinmap.c +++ /dev/null @@ -1,196 +0,0 @@ -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2015, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "mbed_assert.h" -#include "pinmap.h" -#include "PortNames.h" -#include "mbed_error.h" - -// GPIO mode look-up table -static const uint32_t gpio_mode[13] = { - 0x00000000, // 0 = GPIO_MODE_INPUT - 0x00000001, // 1 = GPIO_MODE_OUTPUT_PP - 0x00000011, // 2 = GPIO_MODE_OUTPUT_OD - 0x00000002, // 3 = GPIO_MODE_AF_PP - 0x00000012, // 4 = GPIO_MODE_AF_OD - 0x00000003, // 5 = GPIO_MODE_ANALOG - 0x10110000, // 6 = GPIO_MODE_IT_RISING - 0x10210000, // 7 = GPIO_MODE_IT_FALLING - 0x10310000, // 8 = GPIO_MODE_IT_RISING_FALLING - 0x10120000, // 9 = GPIO_MODE_EVT_RISING - 0x10220000, // 10 = GPIO_MODE_EVT_FALLING - 0x10320000, // 11 = GPIO_MODE_EVT_RISING_FALLING - 0x10000000 // 12 = Reset GPIO_MODE_IT_EVT -}; - -// Enable GPIO clock and return GPIO base address -uint32_t Set_GPIO_Clock(uint32_t port_idx) -{ - uint32_t gpio_add = 0; - switch (port_idx) { - case PortA: - gpio_add = GPIOA_BASE; - __GPIOA_CLK_ENABLE(); - break; - case PortB: - gpio_add = GPIOB_BASE; - __GPIOB_CLK_ENABLE(); - break; - case PortC: - gpio_add = GPIOC_BASE; - __GPIOC_CLK_ENABLE(); - break; -#if defined GPIOD_BASE - case PortD: - gpio_add = GPIOD_BASE; - __GPIOD_CLK_ENABLE(); - break; -#endif -#if defined GPIOE_BASE - case PortE: - gpio_add = GPIOE_BASE; - __GPIOE_CLK_ENABLE(); - break; -#endif -#if defined GPIOF_BASE - case PortF: - gpio_add = GPIOF_BASE; - __GPIOF_CLK_ENABLE(); - break; -#endif -#if defined GPIOG_BASE - case PortG: - gpio_add = GPIOG_BASE; - __GPIOG_CLK_ENABLE(); - break; -#endif -#if defined GPIOH_BASE - case PortH: - gpio_add = GPIOH_BASE; - __GPIOH_CLK_ENABLE(); - break; -#endif -#if defined GPIOI_BASE - case PortI: - gpio_add = GPIOI_BASE; - __GPIOI_CLK_ENABLE(); - break; -#endif -#if defined GPIOJ_BASE - case PortJ: - gpio_add = GPIOJ_BASE; - __GPIOJ_CLK_ENABLE(); - break; -#endif -#if defined GPIOK_BASE - case PortK: - gpio_add = GPIOK_BASE; - __GPIOK_CLK_ENABLE(); - break; -#endif - default: - error("Pinmap error: wrong port number."); - break; - } - return gpio_add; -} - -/** - * Configure pin (mode, speed, output type and pull-up/pull-down) - */ -void pin_function(PinName pin, int data) -{ - MBED_ASSERT(pin != (PinName)NC); - // Get the pin informations - uint32_t mode = STM_PIN_MODE(data); - uint32_t pupd = STM_PIN_PUPD(data); - uint32_t afnum = STM_PIN_AFNUM(data); - - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add; - - // Configure GPIO - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.Pin = (uint32_t)(1 << pin_index); - GPIO_InitStructure.Mode = gpio_mode[mode]; - GPIO_InitStructure.Pull = pupd; - GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; - GPIO_InitStructure.Alternate = afnum; - HAL_GPIO_Init(gpio, &GPIO_InitStructure); - - // [TODO] Disconnect JTAG-DP + SW-DP signals. - // Warning: Need to reconnect under reset - //if ((pin == PA_13) || (pin == PA_14)) { - // - //} - //if ((pin == PA_15) || (pin == PB_3) || (pin == PB_4)) { - // - //} -} - -/** - * Configure pin pull-up/pull-down - */ -void pin_mode(PinName pin, PinMode mode) -{ - MBED_ASSERT(pin != (PinName)NC); - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add; - - // Configure pull-up/pull-down resistors - uint32_t pupd = (uint32_t)mode; - if (pupd > 2) - pupd = 0; // Open-drain = No pull-up/No pull-down - gpio->PUPDR &= (uint32_t)(~(GPIO_PUPDR_PUPDR0 << (pin_index * 2))); - gpio->PUPDR |= (uint32_t)(pupd << (pin_index * 2)); -} - -/* Internal function for setting the gpiomode/function - * without changing Pull mode - */ -void pin_function_gpiomode(PinName pin, uint32_t gpiomode) { - - /* Read current pull state from HW to avoid over-write*/ - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - GPIO_TypeDef *gpio = (GPIO_TypeDef *) Set_GPIO_Clock(port_index); - uint32_t temp = gpio->PUPDR; - uint32_t pull = (temp >> (pin_index * 2U)) & GPIO_PUPDR_PUPDR0; - - /* Then re-use global function for updating the mode part*/ - pin_function(pin, STM_PIN_DATA(gpiomode, pull, 0)); -} diff --git a/targets/TARGET_STM/TARGET_STM32F7/port_api.c b/targets/TARGET_STM/TARGET_STM32F7/port_api.c deleted file mode 100644 index b8ee1ec927..0000000000 --- a/targets/TARGET_STM/TARGET_STM32F7/port_api.c +++ /dev/null @@ -1,103 +0,0 @@ -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2015, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "port_api.h" -#include "pinmap.h" -#include "gpio_api.h" -#include "mbed_error.h" - -#if DEVICE_PORTIN || DEVICE_PORTOUT - -extern uint32_t Set_GPIO_Clock(uint32_t port_idx); - -// high nibble = port number (0=A, 1=B, 2=C, 3=D, 4=E, 5=F, ...) -// low nibble = pin number -PinName port_pin(PortName port, int pin_n) -{ - return (PinName)(pin_n + (port << 4)); -} - -void port_init(port_t *obj, PortName port, int mask, PinDirection dir) -{ - uint32_t port_index = (uint32_t)port; - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add; - - // Fill PORT object structure for future use - obj->port = port; - obj->mask = mask; - obj->direction = dir; - obj->reg_in = &gpio->IDR; - obj->reg_out = &gpio->ODR; - - port_dir(obj, dir); -} - -void port_dir(port_t *obj, PinDirection dir) -{ - uint32_t i; - obj->direction = dir; - for (i = 0; i < 16; i++) { // Process all pins - if (obj->mask & (1 << i)) { // If the pin is used - if (dir == PIN_OUTPUT) { - pin_function(port_pin(obj->port, i), STM_PIN_DATA(STM_MODE_OUTPUT_PP, GPIO_NOPULL, 0)); - } else { // PIN_INPUT - pin_function(port_pin(obj->port, i), STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - } - } - } -} - -void port_mode(port_t *obj, PinMode mode) -{ - uint32_t i; - for (i = 0; i < 16; i++) { // Process all pins - if (obj->mask & (1 << i)) { // If the pin is used - pin_mode(port_pin(obj->port, i), mode); - } - } -} - -void port_write(port_t *obj, int value) -{ - *obj->reg_out = (*obj->reg_out & ~obj->mask) | (value & obj->mask); -} - -int port_read(port_t *obj) -{ - if (obj->direction == PIN_OUTPUT) { - return (*obj->reg_out & obj->mask); - } else { // PIN_INPUT - return (*obj->reg_in & obj->mask); - } -} - -#endif diff --git a/targets/TARGET_STM/TARGET_STM32L0/gpio_irq_api.c b/targets/TARGET_STM/TARGET_STM32L0/gpio_irq_api.c deleted file mode 100644 index 61fef17594..0000000000 --- a/targets/TARGET_STM/TARGET_STM32L0/gpio_irq_api.c +++ /dev/null @@ -1,269 +0,0 @@ -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2016, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include -#include "cmsis.h" -#include "gpio_irq_api.h" -#include "pinmap.h" -#include "mbed_error.h" - -#define EDGE_NONE (0) -#define EDGE_RISE (1) -#define EDGE_FALL (2) -#define EDGE_BOTH (3) - -// Number of EXTI irq vectors (EXTI0_1, EXTI2_3, EXTI4_15) -#define CHANNEL_NUM (3) - -// Max pins for one line (max with EXTI4_15) -#define MAX_PIN_LINE (12) - -typedef struct gpio_channel { - uint32_t pin_mask; // bitmask representing which pins are configured for receiving interrupts - uint32_t channel_ids[MAX_PIN_LINE]; // mbed "gpio_irq_t gpio_irq" field of instance - uint32_t channel_gpio[MAX_PIN_LINE]; // base address of gpio port group - uint32_t channel_pin[MAX_PIN_LINE]; // pin number in port group -} gpio_channel_t; - -static gpio_channel_t channels[CHANNEL_NUM] = { - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0} -}; - -// Used to return the index for channels array. -static uint32_t pin_base_nr[16] = { - // EXTI0_1 - 0, // pin 0 - 1, // pin 1 - // EXTI2_3 - 0, // pin 2 - 1, // pin 3 - // EXTI4_15 - 0, // pin 4 - 1, // pin 5 - 2, // pin 6 - 3, // pin 7 - 4, // pin 8 - 5, // pin 9 - 6, // pin 10 - 7, // pin 11 - 8, // pin 12 - 9, // pin 13 - 10, // pin 14 - 11 // pin 15 -}; - -static gpio_irq_handler irq_handler; - -static void handle_interrupt_in(uint32_t irq_index, uint32_t max_num_pin_line) -{ - gpio_channel_t *gpio_channel = &channels[irq_index]; - uint32_t gpio_idx; - - for (gpio_idx = 0; gpio_idx < max_num_pin_line; gpio_idx++) { - uint32_t current_mask = (1 << gpio_idx); - - if (gpio_channel->pin_mask & current_mask) { - // Retrieve the gpio and pin that generate the irq - GPIO_TypeDef *gpio = (GPIO_TypeDef *)(gpio_channel->channel_gpio[gpio_idx]); - uint32_t pin = (uint32_t)(1 << (gpio_channel->channel_pin[gpio_idx])); - - // Clear interrupt flag - if (__HAL_GPIO_EXTI_GET_FLAG(pin) != RESET) { - __HAL_GPIO_EXTI_CLEAR_FLAG(pin); - - if (gpio_channel->channel_ids[gpio_idx] == 0) continue; - - // Check which edge has generated the irq - if ((gpio->IDR & pin) == 0) { - irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_FALL); - } else { - irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_RISE); - } - } - } - } -} - -// EXTI lines 0 to 1 -static void gpio_irq0(void) -{ - handle_interrupt_in(0, 2); -} - -// EXTI lines 2 to 3 -static void gpio_irq1(void) -{ - handle_interrupt_in(1, 2); -} - -// EXTI lines 4 to 15 -static void gpio_irq2(void) -{ - handle_interrupt_in(2, 12); -} - -extern uint32_t Set_GPIO_Clock(uint32_t port_idx); -extern void pin_function_gpiomode(PinName pin, uint32_t gpiomode); - -int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) -{ - IRQn_Type irq_n = (IRQn_Type)0; - uint32_t vector = 0; - uint32_t irq_index; - gpio_channel_t *gpio_channel; - uint32_t gpio_idx; - - if (pin == NC) return -1; - - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - - // Select irq number and interrupt routine - if ((pin_index == 0) || (pin_index == 1)) { - irq_n = EXTI0_1_IRQn; - vector = (uint32_t)&gpio_irq0; - irq_index = 0; - } else if ((pin_index == 2) || (pin_index == 3)) { - irq_n = EXTI2_3_IRQn; - vector = (uint32_t)&gpio_irq1; - irq_index = 1; - } else if ((pin_index > 3) && (pin_index < 16)) { - irq_n = EXTI4_15_IRQn; - vector = (uint32_t)&gpio_irq2; - irq_index = 2; - } else { - error("InterruptIn error: pin not supported.\n"); - return -1; - } - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - - // Configure GPIO - pin_function(pin, STM_PIN_DATA(STM_MODE_IT_FALLING, GPIO_NOPULL, 0)); - - // Enable EXTI interrupt - NVIC_SetVector(irq_n, vector); - NVIC_EnableIRQ(irq_n); - - // Save informations for future use - obj->irq_n = irq_n; - obj->irq_index = irq_index; - obj->event = EDGE_NONE; - obj->pin = pin; - - gpio_channel = &channels[irq_index]; - gpio_idx = pin_base_nr[pin_index]; - gpio_channel->pin_mask |= (1 << gpio_idx); - gpio_channel->channel_ids[gpio_idx] = id; - gpio_channel->channel_gpio[gpio_idx] = gpio_add; - gpio_channel->channel_pin[gpio_idx] = pin_index; - - irq_handler = handler; - - return 0; -} - -void gpio_irq_free(gpio_irq_t *obj) -{ - gpio_channel_t *gpio_channel = &channels[obj->irq_index]; - uint32_t pin_index = STM_PIN(obj->pin); - uint32_t gpio_addr = GPIOA_BASE + (GPIOB_BASE-GPIOA_BASE) * STM_PORT(obj->pin); - uint32_t gpio_idx = pin_base_nr[pin_index]; - - HAL_GPIO_DeInit((GPIO_TypeDef *)gpio_addr, (1<pin_mask &= ~(1 << gpio_idx); - gpio_channel->channel_ids[gpio_idx] = 0; - gpio_channel->channel_gpio[gpio_idx] = 0; - gpio_channel->channel_pin[gpio_idx] = 0; - - // Disable EXTI line, but don't change pull-up config - pin_function_gpiomode(obj->pin, STM_MODE_INPUT); - obj->event = EDGE_NONE; -} - -void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) -{ - uint32_t mode = STM_MODE_IT_EVT_RESET; - - if (enable) { - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or RISE - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or FALL - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } - } - } else { // Disable - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } else { // NONE or RISE - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } else { // NONE or FALL - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } - } - } - - pin_function_gpiomode(obj->pin, mode); -} - -void gpio_irq_enable(gpio_irq_t *obj) -{ - NVIC_EnableIRQ(obj->irq_n); -} - -void gpio_irq_disable(gpio_irq_t *obj) -{ - NVIC_DisableIRQ(obj->irq_n); - obj->event = EDGE_NONE; -} diff --git a/targets/TARGET_STM/TARGET_STM32L0/gpio_irq_device.c b/targets/TARGET_STM/TARGET_STM32L0/gpio_irq_device.c new file mode 100644 index 0000000000..542dc01b46 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32L0/gpio_irq_device.c @@ -0,0 +1,55 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2017, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include "cmsis.h" +#include "gpio_irq_device.h" + +// Used to return the index for channels array. +const exti_lines_t pin_lines_desc[16] = { + // EXTI0_1 + {.gpio_idx = 0, .irq_index = 0, .irq_n = EXTI0_1_IRQn}, // pin 0 + {.gpio_idx = 1, .irq_index = 0, .irq_n = EXTI0_1_IRQn}, // pin 1 + // EXTI2_3 + {.gpio_idx = 0, .irq_index = 1, .irq_n = EXTI2_3_IRQn}, // pin 2 + {.gpio_idx = 1, .irq_index = 1, .irq_n = EXTI2_3_IRQn}, // pin 3 + // EXTI4_15 + {.gpio_idx = 0, .irq_index = 2, .irq_n = EXTI4_15_IRQn}, // pin 4 + {.gpio_idx = 1, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 5 + {.gpio_idx = 2, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 6 + {.gpio_idx = 3, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 7 + {.gpio_idx = 4, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 8 + {.gpio_idx = 5, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 9 + {.gpio_idx = 6, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 10 + {.gpio_idx = 7, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 11 + {.gpio_idx = 8, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 12 + {.gpio_idx = 9, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 13 + {.gpio_idx = 10, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 14 + {.gpio_idx = 11, .irq_index = 2, .irq_n = EXTI4_15_IRQn}// pin 15 +}; + diff --git a/targets/TARGET_STM/TARGET_STM32L0/gpio_irq_device.h b/targets/TARGET_STM/TARGET_STM32L0/gpio_irq_device.h new file mode 100644 index 0000000000..ceea0fc19b --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32L0/gpio_irq_device.h @@ -0,0 +1,63 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2017, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef MBED_GPIO_IRQ_DEVICE_H +#define MBED_GPIO_IRQ_DEVICE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stm32l0xx_ll_exti.h" + +// Number of EXTI irq vectors (EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5_9, EXTI10_15) +#define CHANNEL_NUM (3) + +#define EXTI_IRQ0_NUM_LINES 2 +#define EXTI_IRQ1_NUM_LINES 2 +#define EXTI_IRQ2_NUM_LINES 12 + +// Max pins for one line (max with EXTI10_15) +#define MAX_PIN_LINE (EXTI_IRQ2_NUM_LINES) + +/* Structure to describe how the HW EXTI lines are defined in this HW */ +typedef struct exti_lines { + uint32_t gpio_idx; // an index entry for each EXIT line + uint32_t irq_index; // the IRQ index + IRQn_Type irq_n; // the corresponding EXTI IRQn +} exti_lines_t; + +// Used to return the index for channels array. +extern const exti_lines_t pin_lines_desc[]; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32L0/pin_device.h b/targets/TARGET_STM/TARGET_STM32L0/pin_device.h new file mode 100644 index 0000000000..8e17d97c57 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32L0/pin_device.h @@ -0,0 +1,69 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2016, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef MBED_PIN_DEVICE_H +#define MBED_PIN_DEVICE_H + +#include "cmsis.h" +#include "stm32l0xx_ll_gpio.h" + +extern const uint32_t ll_pin_defines[16]; + +/* Family specific implementations */ +static inline void stm_pin_DisconnectDebug(PinName pin) +{ + /* empty for now */ +} + +static inline void stm_pin_PullConfig(GPIO_TypeDef *gpio, uint32_t ll_pin, uint32_t pull_config) +{ + switch (pull_config) { + case GPIO_PULLUP: + LL_GPIO_SetPinPull(gpio, ll_pin, LL_GPIO_PULL_UP); + break; + case GPIO_PULLDOWN: + LL_GPIO_SetPinPull(gpio, ll_pin, LL_GPIO_PULL_DOWN); + break; + default: + LL_GPIO_SetPinPull(gpio, ll_pin, LL_GPIO_PULL_NO); + break; + } +} + +static inline void stm_pin_SetAFPin( GPIO_TypeDef *gpio, PinName pin, uint32_t afnum) +{ + uint32_t ll_pin = ll_pin_defines[STM_PIN(pin)]; + + if (STM_PIN(pin) > 7) + LL_GPIO_SetAFPin_8_15(gpio, ll_pin, afnum); + else + LL_GPIO_SetAFPin_0_7(gpio, ll_pin, afnum); +} + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32L0/pinmap.c b/targets/TARGET_STM/TARGET_STM32L0/pinmap.c deleted file mode 100644 index b81a7c400d..0000000000 --- a/targets/TARGET_STM/TARGET_STM32L0/pinmap.c +++ /dev/null @@ -1,165 +0,0 @@ -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2015, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "mbed_assert.h" -#include "pinmap.h" -#include "PortNames.h" -#include "mbed_error.h" - -// GPIO mode look-up table -// Warning: order must be the same as the one defined in PinNames.h !!! -static const uint32_t gpio_mode[13] = { - 0x00000000, // 0 = GPIO_MODE_INPUT - 0x00000001, // 1 = GPIO_MODE_OUTPUT_PP - 0x00000011, // 2 = GPIO_MODE_OUTPUT_OD - 0x00000002, // 3 = GPIO_MODE_AF_PP - 0x00000012, // 4 = GPIO_MODE_AF_OD - 0x00000003, // 5 = GPIO_MODE_ANALOG - 0x10110000, // 6 = GPIO_MODE_IT_RISING - 0x10210000, // 7 = GPIO_MODE_IT_FALLING - 0x10310000, // 8 = GPIO_MODE_IT_RISING_FALLING - 0x10120000, // 9 = GPIO_MODE_EVT_RISING - 0x10220000, // 10 = GPIO_MODE_EVT_FALLING - 0x10320000, // 11 = GPIO_MODE_EVT_RISING_FALLING - 0x10000000 // 12 = Reset IT and EVT (not in STM32Cube HAL) -}; - -// Enable GPIO clock and return GPIO base address -uint32_t Set_GPIO_Clock(uint32_t port_idx) -{ - uint32_t gpio_add = 0; - switch (port_idx) { - case PortA: - gpio_add = GPIOA_BASE; - __GPIOA_CLK_ENABLE(); - break; - case PortB: - gpio_add = GPIOB_BASE; - __GPIOB_CLK_ENABLE(); - break; -#if defined(GPIOC_BASE) - case PortC: - gpio_add = GPIOC_BASE; - __GPIOC_CLK_ENABLE(); - break; -#endif -#if defined(GPIOD_BASE) - case PortD: - gpio_add = GPIOD_BASE; - __GPIOD_CLK_ENABLE(); - break; -#endif -#if defined(GPIOH_BASE) - case PortH: - gpio_add = GPIOH_BASE; - __GPIOH_CLK_ENABLE(); - break; -#endif - default: - error("Pinmap error: wrong port number."); - break; - } - return gpio_add; -} - -/** - * Configure pin (mode, speed, output type and pull-up/pull-down) - */ -void pin_function(PinName pin, int data) -{ - MBED_ASSERT(pin != (PinName)NC); - // Get the pin informations - uint32_t mode = STM_PIN_MODE(data); - uint32_t pupd = STM_PIN_PUPD(data); - uint32_t afnum = STM_PIN_AFNUM(data); - - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add; - - // Configure GPIO - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.Pin = (uint32_t)(1 << pin_index); - GPIO_InitStructure.Mode = gpio_mode[mode]; - GPIO_InitStructure.Pull = pupd; - GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; - GPIO_InitStructure.Alternate = afnum; - HAL_GPIO_Init(gpio, &GPIO_InitStructure); - - // [TODO] Disconnect JTAG-DP + SW-DP signals. - // Warning: Need to reconnect under reset - //if ((pin == PA_13) || (pin == PA_14)) { - // - //} - //if ((pin == PA_15) || (pin == PB_3) || (pin == PB_4)) { - // - //} -} - -/** - * Configure pin pull-up/pull-down - */ -void pin_mode(PinName pin, PinMode mode) -{ - MBED_ASSERT(pin != (PinName)NC); - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add; - - // Configure pull-up/pull-down resistors - uint32_t pupd = (uint32_t)mode; - if (pupd > 2) - { - pupd = 0; // Open-drain = No pull-up/No pull-down - } - gpio->PUPDR &= (uint32_t)(~(GPIO_PUPDR_PUPD0 << (pin_index * 2))); - gpio->PUPDR |= (uint32_t)(pupd << (pin_index * 2)); -} - -/* Internal function for setting the gpiomode/function - * without changing Pull mode - */ -void pin_function_gpiomode(PinName pin, uint32_t gpiomode) { - - /* Read current pull state from HW to avoid over-write*/ - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - GPIO_TypeDef *gpio = (GPIO_TypeDef *) Set_GPIO_Clock(port_index); - uint32_t temp = gpio->PUPDR; - uint32_t pull = (temp >> (pin_index * 2U)) & GPIO_PUPDR_PUPD0; - - /* Then re-use global function for updating the mode part*/ - pin_function(pin, STM_PIN_DATA(gpiomode, pull, 0)); -} diff --git a/targets/TARGET_STM/TARGET_STM32L0/port_api.c b/targets/TARGET_STM/TARGET_STM32L0/port_api.c deleted file mode 100644 index b8ee1ec927..0000000000 --- a/targets/TARGET_STM/TARGET_STM32L0/port_api.c +++ /dev/null @@ -1,103 +0,0 @@ -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2015, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "port_api.h" -#include "pinmap.h" -#include "gpio_api.h" -#include "mbed_error.h" - -#if DEVICE_PORTIN || DEVICE_PORTOUT - -extern uint32_t Set_GPIO_Clock(uint32_t port_idx); - -// high nibble = port number (0=A, 1=B, 2=C, 3=D, 4=E, 5=F, ...) -// low nibble = pin number -PinName port_pin(PortName port, int pin_n) -{ - return (PinName)(pin_n + (port << 4)); -} - -void port_init(port_t *obj, PortName port, int mask, PinDirection dir) -{ - uint32_t port_index = (uint32_t)port; - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add; - - // Fill PORT object structure for future use - obj->port = port; - obj->mask = mask; - obj->direction = dir; - obj->reg_in = &gpio->IDR; - obj->reg_out = &gpio->ODR; - - port_dir(obj, dir); -} - -void port_dir(port_t *obj, PinDirection dir) -{ - uint32_t i; - obj->direction = dir; - for (i = 0; i < 16; i++) { // Process all pins - if (obj->mask & (1 << i)) { // If the pin is used - if (dir == PIN_OUTPUT) { - pin_function(port_pin(obj->port, i), STM_PIN_DATA(STM_MODE_OUTPUT_PP, GPIO_NOPULL, 0)); - } else { // PIN_INPUT - pin_function(port_pin(obj->port, i), STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - } - } - } -} - -void port_mode(port_t *obj, PinMode mode) -{ - uint32_t i; - for (i = 0; i < 16; i++) { // Process all pins - if (obj->mask & (1 << i)) { // If the pin is used - pin_mode(port_pin(obj->port, i), mode); - } - } -} - -void port_write(port_t *obj, int value) -{ - *obj->reg_out = (*obj->reg_out & ~obj->mask) | (value & obj->mask); -} - -int port_read(port_t *obj) -{ - if (obj->direction == PIN_OUTPUT) { - return (*obj->reg_out & obj->mask); - } else { // PIN_INPUT - return (*obj->reg_in & obj->mask); - } -} - -#endif diff --git a/targets/TARGET_STM/TARGET_STM32L1/gpio_irq_api.c b/targets/TARGET_STM/TARGET_STM32L1/gpio_irq_api.c deleted file mode 100644 index c595b98ba6..0000000000 --- a/targets/TARGET_STM/TARGET_STM32L1/gpio_irq_api.c +++ /dev/null @@ -1,334 +0,0 @@ -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2016, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include -#include "cmsis.h" -#include "gpio_irq_api.h" -#include "pinmap.h" -#include "mbed_error.h" - -#define EDGE_NONE (0) -#define EDGE_RISE (1) -#define EDGE_FALL (2) -#define EDGE_BOTH (3) - -// Number of EXTI irq vectors (EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5_9, EXTI10_15) -#define CHANNEL_NUM (7) - -// Max pins for one line (max with EXTI10_15) -#define MAX_PIN_LINE (6) - -typedef struct gpio_channel { - uint32_t pin_mask; // bitmask representing which pins are configured for receiving interrupts - uint32_t channel_ids[MAX_PIN_LINE]; // mbed "gpio_irq_t gpio_irq" field of instance - uint32_t channel_gpio[MAX_PIN_LINE]; // base address of gpio port group - uint32_t channel_pin[MAX_PIN_LINE]; // pin number in port group -} gpio_channel_t; - -static gpio_channel_t channels[CHANNEL_NUM] = { - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0} -}; - -// Used to return the index for channels array. -static uint32_t pin_base_nr[16] = { - // EXTI0 - 0, // pin 0 - // EXTI1 - 0, // pin 1 - // EXTI2 - 0, // pin 2 - // EXTI3 - 0, // pin 3 - // EXTI4 - 0, // pin 4 - // EXTI5_9 - 0, // pin 5 - 1, // pin 6 - 2, // pin 7 - 3, // pin 8 - 4, // pin 9 - // EXTI10_15 - 0, // pin 10 - 1, // pin 11 - 2, // pin 12 - 3, // pin 13 - 4, // pin 14 - 5 // pin 15 -}; - -static gpio_irq_handler irq_handler; - -static void handle_interrupt_in(uint32_t irq_index, uint32_t max_num_pin_line) -{ - gpio_channel_t *gpio_channel = &channels[irq_index]; - uint32_t gpio_idx; - - for (gpio_idx = 0; gpio_idx < max_num_pin_line; gpio_idx++) { - uint32_t current_mask = (1 << gpio_idx); - - if (gpio_channel->pin_mask & current_mask) { - // Retrieve the gpio and pin that generate the irq - GPIO_TypeDef *gpio = (GPIO_TypeDef *)(gpio_channel->channel_gpio[gpio_idx]); - uint32_t pin = (uint32_t)(1 << (gpio_channel->channel_pin[gpio_idx])); - - // Clear interrupt flag - if (__HAL_GPIO_EXTI_GET_FLAG(pin) != RESET) { - __HAL_GPIO_EXTI_CLEAR_FLAG(pin); - - if (gpio_channel->channel_ids[gpio_idx] == 0) continue; - - // Check which edge has generated the irq - if ((gpio->IDR & pin) == 0) { - irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_FALL); - } else { - irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_RISE); - } - } - } - } -} - -// EXTI line 0 -static void gpio_irq0(void) -{ - handle_interrupt_in(0, 1); -} - -// EXTI line 1 -static void gpio_irq1(void) -{ - handle_interrupt_in(1, 1); -} - -// EXTI line 2 -static void gpio_irq2(void) -{ - handle_interrupt_in(2, 1); -} - -// EXTI line 3 -static void gpio_irq3(void) -{ - handle_interrupt_in(3, 1); -} - -// EXTI line 4 -static void gpio_irq4(void) -{ - handle_interrupt_in(4, 1); -} - -// EXTI lines 5 to 9 -static void gpio_irq5(void) -{ - handle_interrupt_in(5, 5); -} - -// EXTI lines 10 to 15 -static void gpio_irq6(void) -{ - handle_interrupt_in(6, 6); -} - -extern uint32_t Set_GPIO_Clock(uint32_t port_idx); -extern void pin_function_gpiomode(PinName pin, uint32_t gpiomode); - -int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) -{ - IRQn_Type irq_n = (IRQn_Type)0; - uint32_t vector = 0; - uint32_t irq_index; - gpio_channel_t *gpio_channel; - uint32_t gpio_idx; - - if (pin == NC) return -1; - - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - - // Select irq number and interrupt routine - switch (pin_index) { - case 0: - irq_n = EXTI0_IRQn; - vector = (uint32_t)&gpio_irq0; - irq_index = 0; - break; - case 1: - irq_n = EXTI1_IRQn; - vector = (uint32_t)&gpio_irq1; - irq_index = 1; - break; - case 2: - irq_n = EXTI2_IRQn; - vector = (uint32_t)&gpio_irq2; - irq_index = 2; - break; - case 3: - irq_n = EXTI3_IRQn; - vector = (uint32_t)&gpio_irq3; - irq_index = 3; - break; - case 4: - irq_n = EXTI4_IRQn; - vector = (uint32_t)&gpio_irq4; - irq_index = 4; - break; - case 5: - case 6: - case 7: - case 8: - case 9: - irq_n = EXTI9_5_IRQn; - vector = (uint32_t)&gpio_irq5; - irq_index = 5; - break; - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - irq_n = EXTI15_10_IRQn; - vector = (uint32_t)&gpio_irq6; - irq_index = 6; - break; - default: - error("InterruptIn error: pin not supported.\n"); - return -1; - } - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - - // Configure GPIO - pin_function(pin, STM_PIN_DATA(STM_MODE_IT_FALLING, GPIO_NOPULL, 0)); - - // Enable EXTI interrupt - NVIC_SetVector(irq_n, vector); - NVIC_EnableIRQ(irq_n); - - // Save informations for future use - obj->irq_n = irq_n; - obj->irq_index = irq_index; - obj->event = EDGE_NONE; - obj->pin = pin; - - gpio_channel = &channels[irq_index]; - gpio_idx = pin_base_nr[pin_index]; - gpio_channel->pin_mask |= (1 << gpio_idx); - gpio_channel->channel_ids[gpio_idx] = id; - gpio_channel->channel_gpio[gpio_idx] = gpio_add; - gpio_channel->channel_pin[gpio_idx] = pin_index; - - irq_handler = handler; - - return 0; -} - -void gpio_irq_free(gpio_irq_t *obj) -{ - gpio_channel_t *gpio_channel = &channels[obj->irq_index]; - uint32_t pin_index = STM_PIN(obj->pin); - uint32_t gpio_addr = GPIOA_BASE + (GPIOB_BASE-GPIOA_BASE) * STM_PORT(obj->pin); - uint32_t gpio_idx = pin_base_nr[pin_index]; - - HAL_GPIO_DeInit((GPIO_TypeDef *)gpio_addr, (1<pin_mask &= ~(1 << gpio_idx); - gpio_channel->channel_ids[gpio_idx] = 0; - gpio_channel->channel_gpio[gpio_idx] = 0; - gpio_channel->channel_pin[gpio_idx] = 0; - - // Disable EXTI line, but don't change pull-up config - pin_function_gpiomode(obj->pin, STM_MODE_INPUT); - obj->event = EDGE_NONE; -} - -void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) -{ - uint32_t mode = STM_MODE_IT_EVT_RESET; - - if (enable) { - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or RISE - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or FALL - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } - } - } else { // Disable - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } else { // NONE or RISE - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } else { // NONE or FALL - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } - } - } - - pin_function_gpiomode(obj->pin, mode); -} - -void gpio_irq_enable(gpio_irq_t *obj) -{ - NVIC_EnableIRQ(obj->irq_n); -} - -void gpio_irq_disable(gpio_irq_t *obj) -{ - NVIC_DisableIRQ(obj->irq_n); - obj->event = EDGE_NONE; -} diff --git a/targets/TARGET_STM/TARGET_STM32L1/gpio_irq_device.c b/targets/TARGET_STM/TARGET_STM32L1/gpio_irq_device.c new file mode 100644 index 0000000000..9f63aff054 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32L1/gpio_irq_device.c @@ -0,0 +1,59 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2017, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include "cmsis.h" +#include "gpio_irq_device.h" + +// Used to return the index for channels array. +const exti_lines_t pin_lines_desc[16] = { + // EXTI0 + {.gpio_idx = 0, .irq_index = 0, .irq_n = EXTI0_IRQn}, // pin 0 + // EXTI1 + {.gpio_idx = 0, .irq_index = 1, .irq_n = EXTI1_IRQn}, // pin 1 + // EXTI2 + {.gpio_idx = 0, .irq_index = 2, .irq_n = EXTI2_IRQn}, // pin 2 + // EXTI3 + {.gpio_idx = 0, .irq_index = 3, .irq_n = EXTI3_IRQn}, // pin 3 + // EXTI4 + {.gpio_idx = 0, .irq_index = 4, .irq_n = EXTI4_IRQn}, // pin 4 + // EXTI5_9 + {.gpio_idx = 0, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 5 + {.gpio_idx = 1, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 6 + {.gpio_idx = 2, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 7 + {.gpio_idx = 3, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 8 + {.gpio_idx = 4, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 9 + // EXTI10_15 + {.gpio_idx = 0, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 10 + {.gpio_idx = 1, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 11 + {.gpio_idx = 2, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 12 + {.gpio_idx = 3, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 13 + {.gpio_idx = 4, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 14 + {.gpio_idx = 5, .irq_index = 6, .irq_n = EXTI15_10_IRQn}// pin 15 +}; + diff --git a/targets/TARGET_STM/TARGET_STM32L1/gpio_irq_device.h b/targets/TARGET_STM/TARGET_STM32L1/gpio_irq_device.h new file mode 100644 index 0000000000..1ed0ecbc28 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32L1/gpio_irq_device.h @@ -0,0 +1,67 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2017, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef MBED_GPIO_IRQ_DEVICE_H +#define MBED_GPIO_IRQ_DEVICE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stm32l1xx_ll_exti.h" + +// Number of EXTI irq vectors (EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5_9, EXTI10_15) +#define CHANNEL_NUM (7) + +#define EXTI_IRQ0_NUM_LINES 1 +#define EXTI_IRQ1_NUM_LINES 1 +#define EXTI_IRQ2_NUM_LINES 1 +#define EXTI_IRQ3_NUM_LINES 1 +#define EXTI_IRQ4_NUM_LINES 1 +#define EXTI_IRQ5_NUM_LINES 5 +#define EXTI_IRQ6_NUM_LINES 6 + +// Max pins for one line (max with EXTI10_15) +#define MAX_PIN_LINE (EXTI_IRQ6_NUM_LINES) + +/* Structure to describe how the HW EXTI lines are defined in this HW */ +typedef struct exti_lines { + uint32_t gpio_idx; // an index entry for each EXIT line + uint32_t irq_index; // the IRQ index + IRQn_Type irq_n; // the corresponding EXTI IRQn +} exti_lines_t; + +// Used to return the index for channels array. +extern const exti_lines_t pin_lines_desc[]; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32L1/pin_device.h b/targets/TARGET_STM/TARGET_STM32L1/pin_device.h new file mode 100644 index 0000000000..d81e5a5e90 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32L1/pin_device.h @@ -0,0 +1,69 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2016, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef MBED_PIN_DEVICE_H +#define MBED_PIN_DEVICE_H + +#include "cmsis.h" +#include "stm32l1xx_ll_gpio.h" + +extern const uint32_t ll_pin_defines[16]; + +/* Family specific implementations */ +static inline void stm_pin_DisconnectDebug(PinName pin) +{ + /* empty for now */ +} + +static inline void stm_pin_PullConfig(GPIO_TypeDef *gpio, uint32_t ll_pin, uint32_t pull_config) +{ + switch (pull_config) { + case GPIO_PULLUP: + LL_GPIO_SetPinPull(gpio, ll_pin, LL_GPIO_PULL_UP); + break; + case GPIO_PULLDOWN: + LL_GPIO_SetPinPull(gpio, ll_pin, LL_GPIO_PULL_DOWN); + break; + default: + LL_GPIO_SetPinPull(gpio, ll_pin, LL_GPIO_PULL_NO); + break; + } +} + +static inline void stm_pin_SetAFPin( GPIO_TypeDef *gpio, PinName pin, uint32_t afnum) +{ + uint32_t ll_pin = ll_pin_defines[STM_PIN(pin)]; + + if (STM_PIN(pin) > 7) + LL_GPIO_SetAFPin_8_15(gpio, ll_pin, afnum); + else + LL_GPIO_SetAFPin_0_7(gpio, ll_pin, afnum); +} + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32L1/pinmap.c b/targets/TARGET_STM/TARGET_STM32L1/pinmap.c deleted file mode 100644 index cc5a164222..0000000000 --- a/targets/TARGET_STM/TARGET_STM32L1/pinmap.c +++ /dev/null @@ -1,158 +0,0 @@ -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "mbed_assert.h" -#include "pinmap.h" -#include "PortNames.h" -#include "mbed_error.h" - -// GPIO mode look-up table -static const uint32_t gpio_mode[13] = { - 0x00000000, // 0 = GPIO_MODE_INPUT - 0x00000001, // 1 = GPIO_MODE_OUTPUT_PP - 0x00000011, // 2 = GPIO_MODE_OUTPUT_OD - 0x00000002, // 3 = GPIO_MODE_AF_PP - 0x00000012, // 4 = GPIO_MODE_AF_OD - 0x00000003, // 5 = GPIO_MODE_ANALOG - 0x10110000, // 6 = GPIO_MODE_IT_RISING - 0x10210000, // 7 = GPIO_MODE_IT_FALLING - 0x10310000, // 8 = GPIO_MODE_IT_RISING_FALLING - 0x10120000, // 9 = GPIO_MODE_EVT_RISING - 0x10220000, // 10 = GPIO_MODE_EVT_FALLING - 0x10320000, // 11 = GPIO_MODE_EVT_RISING_FALLING - 0x10000000 // 12 = Reset IT and EVT (not in STM32Cube HAL) -}; - -// Enable GPIO clock and return GPIO base address -uint32_t Set_GPIO_Clock(uint32_t port_idx) -{ - uint32_t gpio_add = 0; - switch (port_idx) { - case PortA: - gpio_add = GPIOA_BASE; - __GPIOA_CLK_ENABLE(); - break; - case PortB: - gpio_add = GPIOB_BASE; - __GPIOB_CLK_ENABLE(); - break; - case PortC: - gpio_add = GPIOC_BASE; - __GPIOC_CLK_ENABLE(); - break; - case PortD: - gpio_add = GPIOD_BASE; - __GPIOD_CLK_ENABLE(); - break; - case PortH: - gpio_add = GPIOH_BASE; - __GPIOH_CLK_ENABLE(); - break; - default: - error("Pinmap error: wrong port number."); - break; - } - return gpio_add; -} - -/** - * Configure pin (mode, speed, output type and pull-up/pull-down) - */ -void pin_function(PinName pin, int data) -{ - MBED_ASSERT(pin != (PinName)NC); - // Get the pin informations - uint32_t mode = STM_PIN_MODE(data); - uint32_t pupd = STM_PIN_PUPD(data); - uint32_t afnum = STM_PIN_AFNUM(data); - - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add; - - // Configure GPIO - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.Pin = (uint32_t)(1 << pin_index); - GPIO_InitStructure.Mode = gpio_mode[mode]; - GPIO_InitStructure.Pull = pupd; - GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; - GPIO_InitStructure.Alternate = afnum; - HAL_GPIO_Init(gpio, &GPIO_InitStructure); - - // [TODO] Disconnect JTAG-DP + SW-DP signals. - // Warning: Need to reconnect under reset - //if ((pin == PA_13) || (pin == PA_14)) { - // - //} - //if ((pin == PA_15) || (pin == PB_3) || (pin == PB_4)) { - // - //} -} - -/** - * Configure pin pull-up/pull-down - */ -void pin_mode(PinName pin, PinMode mode) -{ - MBED_ASSERT(pin != (PinName)NC); - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add; - - // Configure pull-up/pull-down resistors - uint32_t pupd = (uint32_t)mode; - if (pupd > 2) - { - pupd = 0; // Open-drain = No pull-up/No pull-down - } - gpio->PUPDR &= (uint32_t)(~(GPIO_PUPDR_PUPDR0 << (pin_index * 2))); - gpio->PUPDR |= (uint32_t)(pupd << (pin_index * 2)); -} - -/* Internal function for setting the gpiomode/function - * without changing Pull mode - */ -void pin_function_gpiomode(PinName pin, uint32_t gpiomode) { - - /* Read current pull state from HW to avoid over-write*/ - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - GPIO_TypeDef *gpio = (GPIO_TypeDef *) Set_GPIO_Clock(port_index); - uint32_t temp = gpio->PUPDR; - uint32_t pull = (temp >> (pin_index * 2U)) & GPIO_PUPDR_PUPDR0; - - /* Then re-use global function for updating the mode part*/ - pin_function(pin, STM_PIN_DATA(gpiomode, pull, 0)); -} diff --git a/targets/TARGET_STM/TARGET_STM32L1/port_api.c b/targets/TARGET_STM/TARGET_STM32L1/port_api.c deleted file mode 100644 index e982858665..0000000000 --- a/targets/TARGET_STM/TARGET_STM32L1/port_api.c +++ /dev/null @@ -1,103 +0,0 @@ -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "port_api.h" -#include "pinmap.h" -#include "gpio_api.h" -#include "mbed_error.h" - -#if DEVICE_PORTIN || DEVICE_PORTOUT - -extern uint32_t Set_GPIO_Clock(uint32_t port_idx); - -// high nibble = port number (0=A, 1=B, 2=C, 3=D, 4=E, 5=F, ...) -// low nibble = pin number -PinName port_pin(PortName port, int pin_n) -{ - return (PinName)(pin_n + (port << 4)); -} - -void port_init(port_t *obj, PortName port, int mask, PinDirection dir) -{ - uint32_t port_index = (uint32_t)port; - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add; - - // Fill PORT object structure for future use - obj->port = port; - obj->mask = mask; - obj->direction = dir; - obj->reg_in = &gpio->IDR; - obj->reg_out = &gpio->ODR; - - port_dir(obj, dir); -} - -void port_dir(port_t *obj, PinDirection dir) -{ - uint32_t i; - obj->direction = dir; - for (i = 0; i < 16; i++) { // Process all pins - if (obj->mask & (1 << i)) { // If the pin is used - if (dir == PIN_OUTPUT) { - pin_function(port_pin(obj->port, i), STM_PIN_DATA(STM_MODE_OUTPUT_PP, GPIO_NOPULL, 0)); - } else { // PIN_INPUT - pin_function(port_pin(obj->port, i), STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - } - } - } -} - -void port_mode(port_t *obj, PinMode mode) -{ - uint32_t i; - for (i = 0; i < 16; i++) { // Process all pins - if (obj->mask & (1 << i)) { // If the pin is used - pin_mode(port_pin(obj->port, i), mode); - } - } -} - -void port_write(port_t *obj, int value) -{ - *obj->reg_out = (*obj->reg_out & ~obj->mask) | (value & obj->mask); -} - -int port_read(port_t *obj) -{ - if (obj->direction == PIN_OUTPUT) { - return (*obj->reg_out & obj->mask); - } else { // PIN_INPUT - return (*obj->reg_in & obj->mask); - } -} - -#endif diff --git a/targets/TARGET_STM/TARGET_STM32L4/can_api.c b/targets/TARGET_STM/TARGET_STM32L4/can_api.c deleted file mode 100644 index bf6ad70949..0000000000 --- a/targets/TARGET_STM/TARGET_STM32L4/can_api.c +++ /dev/null @@ -1,485 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-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 "can_api.h" - -#if DEVICE_CAN - -#include "cmsis.h" -#include "pinmap.h" -#include "PeripheralPins.h" -#include "mbed_error.h" -#include -#include - -#define CAN_NUM 1 -static CAN_HandleTypeDef CanHandle; -static uint32_t can_irq_ids[CAN_NUM] = {0}; -static can_irq_handler irq_handler; - -void can_init(can_t *obj, PinName rd, PinName td) -{ - CANName can_rd = (CANName)pinmap_peripheral(rd, PinMap_CAN_RD); - CANName can_td = (CANName)pinmap_peripheral(td, PinMap_CAN_TD); - obj->can = (CANName)pinmap_merge(can_rd, can_td); - MBED_ASSERT((int)obj->can != NC); - - if(obj->can == CAN_1) { - __CAN_CLK_ENABLE(); - obj->index = 0; - } - - // Configure the CAN pins - pinmap_pinout(rd, PinMap_CAN_RD); - pinmap_pinout(td, PinMap_CAN_TD); - if (rd != NC) { - pin_mode(rd, PullUp); - } - if (td != NC) { - pin_mode(td, PullUp); - } - - CanHandle.Instance = (CAN_TypeDef *)(obj->can); - - CanHandle.Init.TTCM = DISABLE; - CanHandle.Init.ABOM = DISABLE; - CanHandle.Init.AWUM = DISABLE; - CanHandle.Init.NART = DISABLE; - CanHandle.Init.RFLM = DISABLE; - CanHandle.Init.TXFP = DISABLE; - CanHandle.Init.Mode = CAN_MODE_NORMAL; - CanHandle.Init.SJW = CAN_SJW_1TQ; - CanHandle.Init.BS1 = CAN_BS1_6TQ; - CanHandle.Init.BS2 = CAN_BS2_8TQ; - CanHandle.Init.Prescaler = 2; - - if (HAL_CAN_Init(&CanHandle) != HAL_OK) { - error("Cannot initialize CAN"); - } - // Set initial CAN frequency to 100kb/s - can_frequency(obj, 100000); - - can_filter(obj, 0, 0, CANStandard, 0); -} - -void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id) -{ - irq_handler = handler; - can_irq_ids[obj->index] = id; -} - -void can_irq_free(can_t *obj) -{ - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - can->IER &= ~(CAN_IT_FMP0 | CAN_IT_FMP1 | CAN_IT_TME | \ - CAN_IT_ERR | CAN_IT_EPV | CAN_IT_BOF); - can_irq_ids[obj->can] = 0; -} - -void can_free(can_t *obj) -{ - // Reset CAN and disable clock - if (obj->can == CAN_1) { - __CAN_FORCE_RESET(); - __CAN_RELEASE_RESET(); - __CAN_CLK_DISABLE(); - } -} - -// The following table is used to program bit_timing. It is an adjustment of the sample -// point by synchronizing on the start-bit edge and resynchronizing on the following edges. -// This table has the sampling points as close to 75% as possible (most commonly used). -// The first value is TSEG1, the second TSEG2. -static const int timing_pts[23][2] = { - {0x0, 0x0}, // 2, 50% - {0x1, 0x0}, // 3, 67% - {0x2, 0x0}, // 4, 75% - {0x3, 0x0}, // 5, 80% - {0x3, 0x1}, // 6, 67% - {0x4, 0x1}, // 7, 71% - {0x5, 0x1}, // 8, 75% - {0x6, 0x1}, // 9, 78% - {0x6, 0x2}, // 10, 70% - {0x7, 0x2}, // 11, 73% - {0x8, 0x2}, // 12, 75% - {0x9, 0x2}, // 13, 77% - {0x9, 0x3}, // 14, 71% - {0xA, 0x3}, // 15, 73% - {0xB, 0x3}, // 16, 75% - {0xC, 0x3}, // 17, 76% - {0xD, 0x3}, // 18, 78% - {0xD, 0x4}, // 19, 74% - {0xE, 0x4}, // 20, 75% - {0xF, 0x4}, // 21, 76% - {0xF, 0x5}, // 22, 73% - {0xF, 0x6}, // 23, 70% - {0xF, 0x7}, // 24, 67% -}; - -static unsigned int can_speed(unsigned int pclk, unsigned int cclk, unsigned char psjw) -{ - uint32_t btr; - uint16_t brp = 0; - uint32_t calcbit; - uint32_t bitwidth; - int hit = 0; - int bits; - - bitwidth = (pclk / cclk); - - brp = bitwidth / 0x18; - while ((!hit) && (brp < bitwidth / 4)) { - brp++; - for (bits = 22; bits > 0; bits--) { - calcbit = (bits + 3) * (brp + 1); - if (calcbit == bitwidth) { - hit = 1; - break; - } - } - } - - if (hit) { - btr = ((timing_pts[bits][1] << 20) & 0x00700000) - | ((timing_pts[bits][0] << 16) & 0x000F0000) - | ((psjw << 24) & 0x0000C000) - | ((brp << 0) & 0x000003FF); - } else { - btr = 0xFFFFFFFF; - } - - return btr; - -} - -int can_frequency(can_t *obj, int f) -{ - int pclk = HAL_RCC_GetPCLK1Freq(); - int btr = can_speed(pclk, (unsigned int)f, 1); - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - if (btr > 0) { - can->MCR |= CAN_MCR_INRQ ; - while((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { - } - can->BTR = btr; - can->MCR &= ~(uint32_t)CAN_MCR_INRQ; - while((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { - } - return 1; - } else { - return 0; - } -} - -int can_write(can_t *obj, CAN_Message msg, int cc) -{ - uint32_t transmitmailbox = 5; - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - /* Select one empty transmit mailbox */ - if ((can->TSR&CAN_TSR_TME0) == CAN_TSR_TME0) { - transmitmailbox = 0; - } else if ((can->TSR&CAN_TSR_TME1) == CAN_TSR_TME1) { - transmitmailbox = 1; - } else if ((can->TSR&CAN_TSR_TME2) == CAN_TSR_TME2) { - transmitmailbox = 2; - } else { - transmitmailbox = CAN_TXSTATUS_NOMAILBOX; - } - - if (transmitmailbox != CAN_TXSTATUS_NOMAILBOX) { - can->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ; - if (!(msg.format)) - { - can->sTxMailBox[transmitmailbox].TIR |= ((msg.id << 21) | msg.type); - } - else - { - can->sTxMailBox[transmitmailbox].TIR |= ((msg.id << 3) | CAN_ID_EXT | msg.type); - } - - /* Set up the DLC */ - can->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0; - can->sTxMailBox[transmitmailbox].TDTR |= (msg.len & (uint8_t)0x0000000F); - - /* Set up the data field */ - can->sTxMailBox[transmitmailbox].TDLR = (((uint32_t)msg.data[3] << 24) | - ((uint32_t)msg.data[2] << 16) | - ((uint32_t)msg.data[1] << 8) | - ((uint32_t)msg.data[0])); - can->sTxMailBox[transmitmailbox].TDHR = (((uint32_t)msg.data[7] << 24) | - ((uint32_t)msg.data[6] << 16) | - ((uint32_t)msg.data[5] << 8) | - ((uint32_t)msg.data[4])); - /* Request transmission */ - can->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ; - } - - return 1; -} - -int can_read(can_t *obj, CAN_Message *msg, int handle) -{ - //handle is the FIFO number - - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - // check FPM0 which holds the pending message count in FIFO 0 - // if no message is pending, return 0 - if ((can->RF0R & CAN_RF0R_FMP0) == 0) { - return 0; - } - - /* Get the Id */ - msg->format = (CANFormat)((uint8_t)0x04 & can->sFIFOMailBox[handle].RIR); - if (!msg->format) { - msg->id = (uint32_t)0x000007FF & (can->sFIFOMailBox[handle].RIR >> 21); - } else { - msg->id = (uint32_t)0x1FFFFFFF & (can->sFIFOMailBox[handle].RIR >> 3); - } - - msg->type = (CANType)((uint8_t)0x02 & can->sFIFOMailBox[handle].RIR); - /* Get the DLC */ - msg->len = (uint8_t)0x0F & can->sFIFOMailBox[handle].RDTR; -// /* Get the FMI */ -// msg->FMI = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDTR >> 8); - /* Get the data field */ - msg->data[0] = (uint8_t)0xFF & can->sFIFOMailBox[handle].RDLR; - msg->data[1] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDLR >> 8); - msg->data[2] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDLR >> 16); - msg->data[3] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDLR >> 24); - msg->data[4] = (uint8_t)0xFF & can->sFIFOMailBox[handle].RDHR; - msg->data[5] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDHR >> 8); - msg->data[6] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDHR >> 16); - msg->data[7] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDHR >> 24); - - /* Release the FIFO */ - if(handle == CAN_FIFO0) { - /* Release FIFO0 */ - can->RF0R |= CAN_RF0R_RFOM0; - } else { /* FIFONumber == CAN_FIFO1 */ - /* Release FIFO1 */ - can->RF1R |= CAN_RF1R_RFOM1; - } - - return 1; -} - -void can_reset(can_t *obj) -{ - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - can->MCR |= CAN_MCR_RESET; - can->ESR = 0x0; -} - -unsigned char can_rderror(can_t *obj) -{ - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - return (can->ESR >> 24) & 0xFF; -} - -unsigned char can_tderror(can_t *obj) -{ - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - return (can->ESR >> 16) & 0xFF; -} - -void can_monitor(can_t *obj, int silent) -{ - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - can->MCR |= CAN_MCR_INRQ ; - while((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { - } - if (silent) { - can->BTR |= ((uint32_t)1 << 31); - } else { - can->BTR &= ~((uint32_t)1 << 31); - } - can->MCR &= ~(uint32_t)CAN_MCR_INRQ; - while((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { - } -} - -int can_mode(can_t *obj, CanMode mode) -{ - int success = 0; - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - can->MCR |= CAN_MCR_INRQ ; - while((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { - } - switch (mode) { - case MODE_NORMAL: - can->BTR &= ~(CAN_BTR_SILM | CAN_BTR_LBKM); - success = 1; - break; - case MODE_SILENT: - can->BTR |= CAN_BTR_SILM; - can->BTR &= ~CAN_BTR_LBKM; - success = 1; - break; - case MODE_TEST_GLOBAL: - case MODE_TEST_LOCAL: - can->BTR |= CAN_BTR_LBKM; - can->BTR &= ~CAN_BTR_SILM; - success = 1; - break; - case MODE_TEST_SILENT: - can->BTR |= (CAN_BTR_SILM | CAN_BTR_LBKM); - success = 1; - break; - default: - success = 0; - break; - } - can->MCR &= ~(uint32_t)CAN_MCR_INRQ; - while((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { - } - return success; -} - -int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) -{ - CanHandle.Instance = (CAN_TypeDef *)(obj->can); - CAN_FilterConfTypeDef sFilterConfig; - - sFilterConfig.FilterNumber = handle; - sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; - sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; - sFilterConfig.FilterIdHigh = (uint8_t) (id >> 8); - sFilterConfig.FilterIdLow = (uint8_t) id; - sFilterConfig.FilterMaskIdHigh = (uint8_t) (mask >> 8); - sFilterConfig.FilterMaskIdLow = (uint8_t) mask; - sFilterConfig.FilterFIFOAssignment = 0; - sFilterConfig.FilterActivation = ENABLE; - sFilterConfig.BankNumber = 14 + handle; - - HAL_CAN_ConfigFilter(&CanHandle, &sFilterConfig); - - return 0; -} - -static void can_irq(CANName name, int id) -{ - uint32_t tmp1 = 0, tmp2 = 0, tmp3 = 0; - CanHandle.Instance = (CAN_TypeDef *)name; - - if(__HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_TME)) { - tmp1 = __HAL_CAN_TRANSMIT_STATUS(&CanHandle, CAN_TXMAILBOX_0); - tmp2 = __HAL_CAN_TRANSMIT_STATUS(&CanHandle, CAN_TXMAILBOX_1); - tmp3 = __HAL_CAN_TRANSMIT_STATUS(&CanHandle, CAN_TXMAILBOX_2); - if(tmp1 || tmp2 || tmp3) - { - irq_handler(can_irq_ids[id], IRQ_TX); - } - } - - tmp1 = __HAL_CAN_MSG_PENDING(&CanHandle, CAN_FIFO0); - tmp2 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_FMP0); - - if((tmp1 != 0) && tmp2) { - irq_handler(can_irq_ids[id], IRQ_RX); - } - - tmp1 = __HAL_CAN_GET_FLAG(&CanHandle, CAN_FLAG_EPV); - tmp2 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_EPV); - tmp3 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_ERR); - - if(tmp1 && tmp2 && tmp3) { - irq_handler(can_irq_ids[id], IRQ_PASSIVE); - } - - tmp1 = __HAL_CAN_GET_FLAG(&CanHandle, CAN_FLAG_BOF); - tmp2 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_BOF); - tmp3 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_ERR); - if(tmp1 && tmp2 && tmp3) { - irq_handler(can_irq_ids[id], IRQ_BUS); - } - - tmp3 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_ERR); - if(tmp1 && tmp2 && tmp3) { - irq_handler(can_irq_ids[id], IRQ_ERROR); - } -} - -void CAN1_RX0_IRQHandler(void) -{ - can_irq(CAN_1, 0); -} - -void CAN1_TX_IRQHandler(void) -{ - can_irq(CAN_1, 0); -} - -void CAN1_SCE_IRQHandler(void) -{ - can_irq(CAN_1, 0); -} - -void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable) -{ - - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - IRQn_Type irq_n = (IRQn_Type)0; - uint32_t vector = 0; - uint32_t ier; - - if(obj->can == CAN_1) { - switch (type) { - case IRQ_RX: - ier = CAN_IT_FMP0; - irq_n = CAN1_RX0_IRQn; - vector = (uint32_t)&CAN1_RX0_IRQHandler; - break; - case IRQ_TX: - ier = CAN_IT_TME; - irq_n = CAN1_TX_IRQn; - vector = (uint32_t)&CAN1_TX_IRQHandler; - break; - case IRQ_ERROR: - ier = CAN_IT_ERR; - irq_n = CAN1_SCE_IRQn; - vector = (uint32_t)&CAN1_SCE_IRQHandler; - break; - case IRQ_PASSIVE: - ier = CAN_IT_EPV; - irq_n = CAN1_SCE_IRQn; - vector = (uint32_t)&CAN1_SCE_IRQHandler; - break; - case IRQ_BUS: - ier = CAN_IT_BOF; - irq_n = CAN1_SCE_IRQn; - vector = (uint32_t)&CAN1_SCE_IRQHandler; - break; - default: return; - } - } - - if(enable) { - can->IER |= ier; - } else { - can->IER &= ~ier; - } - - NVIC_SetVector(irq_n, vector); - NVIC_EnableIRQ(irq_n); -} - -#endif // DEVICE_CAN - diff --git a/targets/TARGET_STM/TARGET_STM32L4/can_device.h b/targets/TARGET_STM/TARGET_STM32L4/can_device.h new file mode 100644 index 0000000000..d0e3ad0ce7 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32L4/can_device.h @@ -0,0 +1,42 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-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. + */ +#ifndef MBED_CAN_DEVICE_H +#define MBED_CAN_DEVICE_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef DEVICE_CAN + +#define CAN_NUM 1 // Number of CAN peripherals present in the STM32 serie + +#define CAN1_IRQ_RX_IRQN CAN1_RX0_IRQn +#define CAN1_IRQ_RX_VECT CAN1_RX0_IRQHandler +#define CAN1_IRQ_TX_IRQN CAN1_TX_IRQn +#define CAN1_IRQ_TX_VECT CAN1_TX_IRQHandler +#define CAN1_IRQ_ERROR_IRQN CAN1_SCE_IRQn +#define CAN1_IRQ_ERROR_VECT CAN1_SCE_IRQHandler +#define CAN1_IRQ_PASSIVE_IRQN CAN1_SCE_IRQn +#define CAN1_IRQ_PASSIVE_VECT CAN1_SCE_IRQHandler +#define CAN1_IRQ_BUS_IRQN CAN1_SCE_IRQn +#define CAN1_IRQ_BUS_VECT CAN1_SCE_IRQHandler + +#endif // DEVICE_CAN + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_rtc_ex.c b/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_rtc_ex.c index 1a1b67c8d0..b543ee91ff 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_rtc_ex.c +++ b/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_rtc_ex.c @@ -1123,9 +1123,12 @@ HAL_StatusTypeDef HAL_RTCEx_SetWakeUpTimer_IT(RTC_HandleTypeDef *hrtc, uint32_t } } } - + /* Disable the Wake-Up timer */ __HAL_RTC_WAKEUPTIMER_DISABLE(hrtc); + /* Clear flag Wake-Up */ + __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(hrtc, RTC_FLAG_WUTF); + tickstart = HAL_GetTick(); /* Wait till RTC WUTWF flag is set and if Time out is reached exit */ diff --git a/targets/TARGET_STM/TARGET_STM32L4/gpio_irq_api.c b/targets/TARGET_STM/TARGET_STM32L4/gpio_irq_api.c deleted file mode 100644 index c595b98ba6..0000000000 --- a/targets/TARGET_STM/TARGET_STM32L4/gpio_irq_api.c +++ /dev/null @@ -1,334 +0,0 @@ -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2016, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include -#include "cmsis.h" -#include "gpio_irq_api.h" -#include "pinmap.h" -#include "mbed_error.h" - -#define EDGE_NONE (0) -#define EDGE_RISE (1) -#define EDGE_FALL (2) -#define EDGE_BOTH (3) - -// Number of EXTI irq vectors (EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5_9, EXTI10_15) -#define CHANNEL_NUM (7) - -// Max pins for one line (max with EXTI10_15) -#define MAX_PIN_LINE (6) - -typedef struct gpio_channel { - uint32_t pin_mask; // bitmask representing which pins are configured for receiving interrupts - uint32_t channel_ids[MAX_PIN_LINE]; // mbed "gpio_irq_t gpio_irq" field of instance - uint32_t channel_gpio[MAX_PIN_LINE]; // base address of gpio port group - uint32_t channel_pin[MAX_PIN_LINE]; // pin number in port group -} gpio_channel_t; - -static gpio_channel_t channels[CHANNEL_NUM] = { - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0} -}; - -// Used to return the index for channels array. -static uint32_t pin_base_nr[16] = { - // EXTI0 - 0, // pin 0 - // EXTI1 - 0, // pin 1 - // EXTI2 - 0, // pin 2 - // EXTI3 - 0, // pin 3 - // EXTI4 - 0, // pin 4 - // EXTI5_9 - 0, // pin 5 - 1, // pin 6 - 2, // pin 7 - 3, // pin 8 - 4, // pin 9 - // EXTI10_15 - 0, // pin 10 - 1, // pin 11 - 2, // pin 12 - 3, // pin 13 - 4, // pin 14 - 5 // pin 15 -}; - -static gpio_irq_handler irq_handler; - -static void handle_interrupt_in(uint32_t irq_index, uint32_t max_num_pin_line) -{ - gpio_channel_t *gpio_channel = &channels[irq_index]; - uint32_t gpio_idx; - - for (gpio_idx = 0; gpio_idx < max_num_pin_line; gpio_idx++) { - uint32_t current_mask = (1 << gpio_idx); - - if (gpio_channel->pin_mask & current_mask) { - // Retrieve the gpio and pin that generate the irq - GPIO_TypeDef *gpio = (GPIO_TypeDef *)(gpio_channel->channel_gpio[gpio_idx]); - uint32_t pin = (uint32_t)(1 << (gpio_channel->channel_pin[gpio_idx])); - - // Clear interrupt flag - if (__HAL_GPIO_EXTI_GET_FLAG(pin) != RESET) { - __HAL_GPIO_EXTI_CLEAR_FLAG(pin); - - if (gpio_channel->channel_ids[gpio_idx] == 0) continue; - - // Check which edge has generated the irq - if ((gpio->IDR & pin) == 0) { - irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_FALL); - } else { - irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_RISE); - } - } - } - } -} - -// EXTI line 0 -static void gpio_irq0(void) -{ - handle_interrupt_in(0, 1); -} - -// EXTI line 1 -static void gpio_irq1(void) -{ - handle_interrupt_in(1, 1); -} - -// EXTI line 2 -static void gpio_irq2(void) -{ - handle_interrupt_in(2, 1); -} - -// EXTI line 3 -static void gpio_irq3(void) -{ - handle_interrupt_in(3, 1); -} - -// EXTI line 4 -static void gpio_irq4(void) -{ - handle_interrupt_in(4, 1); -} - -// EXTI lines 5 to 9 -static void gpio_irq5(void) -{ - handle_interrupt_in(5, 5); -} - -// EXTI lines 10 to 15 -static void gpio_irq6(void) -{ - handle_interrupt_in(6, 6); -} - -extern uint32_t Set_GPIO_Clock(uint32_t port_idx); -extern void pin_function_gpiomode(PinName pin, uint32_t gpiomode); - -int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) -{ - IRQn_Type irq_n = (IRQn_Type)0; - uint32_t vector = 0; - uint32_t irq_index; - gpio_channel_t *gpio_channel; - uint32_t gpio_idx; - - if (pin == NC) return -1; - - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - - // Select irq number and interrupt routine - switch (pin_index) { - case 0: - irq_n = EXTI0_IRQn; - vector = (uint32_t)&gpio_irq0; - irq_index = 0; - break; - case 1: - irq_n = EXTI1_IRQn; - vector = (uint32_t)&gpio_irq1; - irq_index = 1; - break; - case 2: - irq_n = EXTI2_IRQn; - vector = (uint32_t)&gpio_irq2; - irq_index = 2; - break; - case 3: - irq_n = EXTI3_IRQn; - vector = (uint32_t)&gpio_irq3; - irq_index = 3; - break; - case 4: - irq_n = EXTI4_IRQn; - vector = (uint32_t)&gpio_irq4; - irq_index = 4; - break; - case 5: - case 6: - case 7: - case 8: - case 9: - irq_n = EXTI9_5_IRQn; - vector = (uint32_t)&gpio_irq5; - irq_index = 5; - break; - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - irq_n = EXTI15_10_IRQn; - vector = (uint32_t)&gpio_irq6; - irq_index = 6; - break; - default: - error("InterruptIn error: pin not supported.\n"); - return -1; - } - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - - // Configure GPIO - pin_function(pin, STM_PIN_DATA(STM_MODE_IT_FALLING, GPIO_NOPULL, 0)); - - // Enable EXTI interrupt - NVIC_SetVector(irq_n, vector); - NVIC_EnableIRQ(irq_n); - - // Save informations for future use - obj->irq_n = irq_n; - obj->irq_index = irq_index; - obj->event = EDGE_NONE; - obj->pin = pin; - - gpio_channel = &channels[irq_index]; - gpio_idx = pin_base_nr[pin_index]; - gpio_channel->pin_mask |= (1 << gpio_idx); - gpio_channel->channel_ids[gpio_idx] = id; - gpio_channel->channel_gpio[gpio_idx] = gpio_add; - gpio_channel->channel_pin[gpio_idx] = pin_index; - - irq_handler = handler; - - return 0; -} - -void gpio_irq_free(gpio_irq_t *obj) -{ - gpio_channel_t *gpio_channel = &channels[obj->irq_index]; - uint32_t pin_index = STM_PIN(obj->pin); - uint32_t gpio_addr = GPIOA_BASE + (GPIOB_BASE-GPIOA_BASE) * STM_PORT(obj->pin); - uint32_t gpio_idx = pin_base_nr[pin_index]; - - HAL_GPIO_DeInit((GPIO_TypeDef *)gpio_addr, (1<pin_mask &= ~(1 << gpio_idx); - gpio_channel->channel_ids[gpio_idx] = 0; - gpio_channel->channel_gpio[gpio_idx] = 0; - gpio_channel->channel_pin[gpio_idx] = 0; - - // Disable EXTI line, but don't change pull-up config - pin_function_gpiomode(obj->pin, STM_MODE_INPUT); - obj->event = EDGE_NONE; -} - -void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) -{ - uint32_t mode = STM_MODE_IT_EVT_RESET; - - if (enable) { - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or RISE - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or FALL - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } - } - } else { // Disable - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } else { // NONE or RISE - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } else { // NONE or FALL - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } - } - } - - pin_function_gpiomode(obj->pin, mode); -} - -void gpio_irq_enable(gpio_irq_t *obj) -{ - NVIC_EnableIRQ(obj->irq_n); -} - -void gpio_irq_disable(gpio_irq_t *obj) -{ - NVIC_DisableIRQ(obj->irq_n); - obj->event = EDGE_NONE; -} diff --git a/targets/TARGET_STM/TARGET_STM32L4/gpio_irq_device.c b/targets/TARGET_STM/TARGET_STM32L4/gpio_irq_device.c new file mode 100644 index 0000000000..9f63aff054 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32L4/gpio_irq_device.c @@ -0,0 +1,59 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2017, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include "cmsis.h" +#include "gpio_irq_device.h" + +// Used to return the index for channels array. +const exti_lines_t pin_lines_desc[16] = { + // EXTI0 + {.gpio_idx = 0, .irq_index = 0, .irq_n = EXTI0_IRQn}, // pin 0 + // EXTI1 + {.gpio_idx = 0, .irq_index = 1, .irq_n = EXTI1_IRQn}, // pin 1 + // EXTI2 + {.gpio_idx = 0, .irq_index = 2, .irq_n = EXTI2_IRQn}, // pin 2 + // EXTI3 + {.gpio_idx = 0, .irq_index = 3, .irq_n = EXTI3_IRQn}, // pin 3 + // EXTI4 + {.gpio_idx = 0, .irq_index = 4, .irq_n = EXTI4_IRQn}, // pin 4 + // EXTI5_9 + {.gpio_idx = 0, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 5 + {.gpio_idx = 1, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 6 + {.gpio_idx = 2, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 7 + {.gpio_idx = 3, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 8 + {.gpio_idx = 4, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 9 + // EXTI10_15 + {.gpio_idx = 0, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 10 + {.gpio_idx = 1, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 11 + {.gpio_idx = 2, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 12 + {.gpio_idx = 3, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 13 + {.gpio_idx = 4, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 14 + {.gpio_idx = 5, .irq_index = 6, .irq_n = EXTI15_10_IRQn}// pin 15 +}; + diff --git a/targets/TARGET_STM/TARGET_STM32L4/gpio_irq_device.h b/targets/TARGET_STM/TARGET_STM32L4/gpio_irq_device.h new file mode 100644 index 0000000000..339077445f --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32L4/gpio_irq_device.h @@ -0,0 +1,67 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2017, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef MBED_GPIO_IRQ_DEVICE_H +#define MBED_GPIO_IRQ_DEVICE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stm32l4xx_ll_exti.h" + +// Number of EXTI irq vectors (EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5_9, EXTI10_15) +#define CHANNEL_NUM (7) + +#define EXTI_IRQ0_NUM_LINES 1 +#define EXTI_IRQ1_NUM_LINES 1 +#define EXTI_IRQ2_NUM_LINES 1 +#define EXTI_IRQ3_NUM_LINES 1 +#define EXTI_IRQ4_NUM_LINES 1 +#define EXTI_IRQ5_NUM_LINES 5 +#define EXTI_IRQ6_NUM_LINES 6 + +// Max pins for one line (max with EXTI10_15) +#define MAX_PIN_LINE (EXTI_IRQ6_NUM_LINES) + +/* Structure to describe how the HW EXTI lines are defined in this HW */ +typedef struct exti_lines { + uint32_t gpio_idx; // an index entry for each EXIT line + uint32_t irq_index; // the IRQ index + IRQn_Type irq_n; // the corresponding EXTI IRQn +} exti_lines_t; + +// Used to return the index for channels array. +extern const exti_lines_t pin_lines_desc[]; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32L4/pin_device.h b/targets/TARGET_STM/TARGET_STM32L4/pin_device.h new file mode 100644 index 0000000000..b45c56d2ac --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32L4/pin_device.h @@ -0,0 +1,69 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2016, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef MBED_PIN_DEVICE_H +#define MBED_PIN_DEVICE_H + +#include "cmsis.h" +#include "stm32l4xx_ll_gpio.h" + +extern const uint32_t ll_pin_defines[16]; + +/* Family specific implementations */ +static inline void stm_pin_DisconnectDebug(PinName pin) +{ + /* empty for now */ +} + +static inline void stm_pin_PullConfig(GPIO_TypeDef *gpio, uint32_t ll_pin, uint32_t pull_config) +{ + switch (pull_config) { + case GPIO_PULLUP: + LL_GPIO_SetPinPull(gpio, ll_pin, LL_GPIO_PULL_UP); + break; + case GPIO_PULLDOWN: + LL_GPIO_SetPinPull(gpio, ll_pin, LL_GPIO_PULL_DOWN); + break; + default: + LL_GPIO_SetPinPull(gpio, ll_pin, LL_GPIO_PULL_NO); + break; + } +} + +static inline void stm_pin_SetAFPin( GPIO_TypeDef *gpio, PinName pin, uint32_t afnum) +{ + uint32_t ll_pin = ll_pin_defines[STM_PIN(pin)]; + + if (STM_PIN(pin) > 7) + LL_GPIO_SetAFPin_8_15(gpio, ll_pin, afnum); + else + LL_GPIO_SetAFPin_0_7(gpio, ll_pin, afnum); +} + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32L4/pinmap.c b/targets/TARGET_STM/TARGET_STM32L4/pinmap.c deleted file mode 100644 index f2a9f540d7..0000000000 --- a/targets/TARGET_STM/TARGET_STM32L4/pinmap.c +++ /dev/null @@ -1,167 +0,0 @@ -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2015, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "mbed_assert.h" -#include "pinmap.h" -#include "PortNames.h" -#include "mbed_error.h" - -// GPIO mode look-up table -// Warning: order must be the same as the one defined in PinNames.h !!! -static const uint32_t gpio_mode[14] = { - 0x00000000, // 0 = GPIO_MODE_INPUT - 0x00000001, // 1 = GPIO_MODE_OUTPUT_PP - 0x00000011, // 2 = GPIO_MODE_OUTPUT_OD - 0x00000002, // 3 = GPIO_MODE_AF_PP - 0x00000012, // 4 = GPIO_MODE_AF_OD - 0x00000003, // 5 = GPIO_MODE_ANALOG - 0x10110000, // 6 = GPIO_MODE_IT_RISING - 0x10210000, // 7 = GPIO_MODE_IT_FALLING - 0x10310000, // 8 = GPIO_MODE_IT_RISING_FALLING - 0x10120000, // 9 = GPIO_MODE_EVT_RISING - 0x10220000, // 10 = GPIO_MODE_EVT_FALLING - 0x10320000, // 11 = GPIO_MODE_EVT_RISING_FALLING - 0x10000000, // 12 = Reset IT and EVT (not in STM32Cube HAL) - 0x0000000B //13 = GPIO_MODE_ANALOG_ADC_CONTROL -}; - -// Enable GPIO clock and return GPIO base address -uint32_t Set_GPIO_Clock(uint32_t port_idx) -{ - uint32_t gpio_add = 0; - switch (port_idx) { - case PortA: - gpio_add = GPIOA_BASE; - __HAL_RCC_GPIOA_CLK_ENABLE(); - break; - case PortB: - gpio_add = GPIOB_BASE; - __HAL_RCC_GPIOB_CLK_ENABLE(); - break; - case PortC: - gpio_add = GPIOC_BASE; - __HAL_RCC_GPIOC_CLK_ENABLE(); - break; -#if defined(GPIOD_BASE) - case PortD: - gpio_add = GPIOD_BASE; - __HAL_RCC_GPIOD_CLK_ENABLE(); - break; -#endif -#if defined(GPIOE_BASE) - case PortE: - gpio_add = GPIOE_BASE; - __HAL_RCC_GPIOE_CLK_ENABLE(); - break; -#endif - case PortH: - gpio_add = GPIOH_BASE; - __HAL_RCC_GPIOH_CLK_ENABLE(); - break; - default: - error("Pinmap error: wrong port number\n"); - break; - } - return gpio_add; -} - -/** - * Configure pin (mode, speed, output type and pull-up/pull-down) - */ -void pin_function(PinName pin, int data) -{ - MBED_ASSERT(pin != (PinName)NC); - // Get the pin informations - uint32_t mode = STM_PIN_MODE(data); - uint32_t pupd = STM_PIN_PUPD(data); - uint32_t afnum = STM_PIN_AFNUM(data); - - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add; - - // Configure GPIO - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.Pin = (uint32_t)(1 << pin_index); - GPIO_InitStructure.Mode = gpio_mode[mode]; - GPIO_InitStructure.Pull = pupd; - GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; - GPIO_InitStructure.Alternate = afnum; - HAL_GPIO_Init(gpio, &GPIO_InitStructure); - - // [TODO] Disconnect JTAG-DP + SW-DP signals. - // Warning: Need to reconnect under reset - //if ((pin == PA_13) || (pin == PA_14)) { - // - //} - //if ((pin == PA_15) || (pin == PB_3) || (pin == PB_4)) { - // - //} -} - -/** - * Configure pin pull-up/pull-down - */ -void pin_mode(PinName pin, PinMode mode) -{ - MBED_ASSERT(pin != (PinName)NC); - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add; - - // Configure pull-up/pull-down resistors - uint32_t pupd = (uint32_t)mode; - if (pupd > 2) { - pupd = 0; // Open-drain = No pull-up/No pull-down - } - gpio->PUPDR &= (uint32_t)(~(GPIO_PUPDR_PUPDR0 << (pin_index * 2))); - gpio->PUPDR |= (uint32_t)(pupd << (pin_index * 2)); -} - -/* Internal function for setting the gpiomode/function - * without changing Pull mode - */ -void pin_function_gpiomode(PinName pin, uint32_t gpiomode) { - - /* Read current pull state from HW to avoid over-write*/ - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - GPIO_TypeDef *gpio = (GPIO_TypeDef *) Set_GPIO_Clock(port_index); - uint32_t temp = gpio->PUPDR; - uint32_t pull = (temp >> (pin_index * 2U)) & GPIO_PUPDR_PUPDR0; - - /* Then re-use global function for updating the mode part*/ - pin_function(pin, STM_PIN_DATA(gpiomode, pull, 0)); -} diff --git a/targets/TARGET_STM/TARGET_STM32L4/port_api.c b/targets/TARGET_STM/TARGET_STM32L4/port_api.c deleted file mode 100644 index b8ee1ec927..0000000000 --- a/targets/TARGET_STM/TARGET_STM32L4/port_api.c +++ /dev/null @@ -1,103 +0,0 @@ -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2015, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "port_api.h" -#include "pinmap.h" -#include "gpio_api.h" -#include "mbed_error.h" - -#if DEVICE_PORTIN || DEVICE_PORTOUT - -extern uint32_t Set_GPIO_Clock(uint32_t port_idx); - -// high nibble = port number (0=A, 1=B, 2=C, 3=D, 4=E, 5=F, ...) -// low nibble = pin number -PinName port_pin(PortName port, int pin_n) -{ - return (PinName)(pin_n + (port << 4)); -} - -void port_init(port_t *obj, PortName port, int mask, PinDirection dir) -{ - uint32_t port_index = (uint32_t)port; - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add; - - // Fill PORT object structure for future use - obj->port = port; - obj->mask = mask; - obj->direction = dir; - obj->reg_in = &gpio->IDR; - obj->reg_out = &gpio->ODR; - - port_dir(obj, dir); -} - -void port_dir(port_t *obj, PinDirection dir) -{ - uint32_t i; - obj->direction = dir; - for (i = 0; i < 16; i++) { // Process all pins - if (obj->mask & (1 << i)) { // If the pin is used - if (dir == PIN_OUTPUT) { - pin_function(port_pin(obj->port, i), STM_PIN_DATA(STM_MODE_OUTPUT_PP, GPIO_NOPULL, 0)); - } else { // PIN_INPUT - pin_function(port_pin(obj->port, i), STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - } - } - } -} - -void port_mode(port_t *obj, PinMode mode) -{ - uint32_t i; - for (i = 0; i < 16; i++) { // Process all pins - if (obj->mask & (1 << i)) { // If the pin is used - pin_mode(port_pin(obj->port, i), mode); - } - } -} - -void port_write(port_t *obj, int value) -{ - *obj->reg_out = (*obj->reg_out & ~obj->mask) | (value & obj->mask); -} - -int port_read(port_t *obj) -{ - if (obj->direction == PIN_OUTPUT) { - return (*obj->reg_out & obj->mask); - } else { // PIN_INPUT - return (*obj->reg_in & obj->mask); - } -} - -#endif diff --git a/targets/TARGET_STM/TARGET_STM32F2/can_api.c b/targets/TARGET_STM/can_api.c similarity index 78% rename from targets/TARGET_STM/TARGET_STM32F2/can_api.c rename to targets/TARGET_STM/can_api.c index d20e24011b..4c588e7250 100644 --- a/targets/TARGET_STM/TARGET_STM32F2/can_api.c +++ b/targets/TARGET_STM/can_api.c @@ -1,5 +1,5 @@ /* mbed Microcontroller Library - * Copyright (c) 2006-2016 ARM Limited + * Copyright (c) 2006-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. @@ -21,29 +21,35 @@ #include "pinmap.h" #include "PeripheralPins.h" #include "mbed_error.h" +#include "can_device.h" // Specific to STM32 serie #include #include -#define CAN_NUM 2 static CAN_HandleTypeDef CanHandle; static uint32_t can_irq_ids[CAN_NUM] = {0}; static can_irq_handler irq_handler; void can_init(can_t *obj, PinName rd, PinName td) { - uint32_t filter_number; CANName can_rd = (CANName)pinmap_peripheral(rd, PinMap_CAN_RD); CANName can_td = (CANName)pinmap_peripheral(td, PinMap_CAN_TD); + obj->can = (CANName)pinmap_merge(can_rd, can_td); MBED_ASSERT((int)obj->can != NC); if (obj->can == CAN_1) { __HAL_RCC_CAN1_CLK_ENABLE(); obj->index = 0; - } else { + } +#if defined(CAN2_BASE) && (CAN_NUM == 2) + else if (obj->can == CAN_2) { __HAL_RCC_CAN2_CLK_ENABLE(); obj->index = 1; } +#endif + else { + return; + } // Configure the CAN pins pinmap_pinout(rd, PinMap_CAN_RD); @@ -73,11 +79,10 @@ void can_init(can_t *obj, PinName rd, PinName td) error("Cannot initialize CAN"); } - filter_number = (obj->can == CAN_1) ? 0 : 14; - - // Set initial CAN frequency to 100kb/s + // Set initial CAN frequency to 100 kb/s can_frequency(obj, 100000); + uint32_t filter_number = (obj->can == CAN_1) ? 0 : 14; can_filter(obj, 0, 0, CANStandard, filter_number); } @@ -104,12 +109,13 @@ void can_free(can_t *obj) __HAL_RCC_CAN1_RELEASE_RESET(); __HAL_RCC_CAN1_CLK_DISABLE(); } - +#if defined(CAN2_BASE) && (CAN_NUM == 2) if (obj->can == CAN_2) { __HAL_RCC_CAN2_FORCE_RESET(); __HAL_RCC_CAN2_RELEASE_RESET(); __HAL_RCC_CAN2_CLK_DISABLE(); } +#endif } // The following table is used to program bit_timing. It is an adjustment of the sample @@ -265,8 +271,8 @@ int can_read(can_t *obj, CAN_Message *msg, int handle) msg->type = (CANType)((uint8_t)0x02 & can->sFIFOMailBox[handle].RIR); /* Get the DLC */ msg->len = (uint8_t)0x0F & can->sFIFOMailBox[handle].RDTR; -// /* Get the FMI */ -// msg->FMI = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDTR >> 8); + /* Get the FMI */ + // msg->FMI = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDTR >> 8); /* Get the data field */ msg->data[0] = (uint8_t)0xFF & can->sFIFOMailBox[handle].RDLR; msg->data[1] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDLR >> 8); @@ -292,7 +298,6 @@ int can_read(can_t *obj, CAN_Message *msg, int handle) void can_reset(can_t *obj) { CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - can->MCR |= CAN_MCR_RESET; can->ESR = 0x0; } @@ -316,11 +321,13 @@ void can_monitor(can_t *obj, int silent) can->MCR |= CAN_MCR_INRQ ; while ((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { } + if (silent) { can->BTR |= ((uint32_t)1 << 31); } else { can->BTR &= ~((uint32_t)1 << 31); } + can->MCR &= ~(uint32_t)CAN_MCR_INRQ; while ((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { } @@ -330,9 +337,11 @@ int can_mode(can_t *obj, CanMode mode) { int success = 0; CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); + can->MCR |= CAN_MCR_INRQ ; while ((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { } + switch (mode) { case MODE_NORMAL: can->BTR &= ~(CAN_BTR_SILM | CAN_BTR_LBKM); @@ -357,31 +366,46 @@ int can_mode(can_t *obj, CanMode mode) success = 0; break; } + can->MCR &= ~(uint32_t)CAN_MCR_INRQ; while ((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { } + return success; } -int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) +int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) { - CanHandle.Instance = (CAN_TypeDef *)(obj->can); - CAN_FilterConfTypeDef sFilterConfig; + int retval = 0; + + // filter for CANAny format cannot be configured for STM32 + if ((format == CANStandard) || (format == CANExtended)) { + CanHandle.Instance = (CAN_TypeDef *)(obj->can); + CAN_FilterConfTypeDef sFilterConfig; + sFilterConfig.FilterNumber = handle; + sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; + sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; - sFilterConfig.FilterNumber = handle; - sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; - sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; - sFilterConfig.FilterIdHigh = (uint8_t)(id >> 8); - sFilterConfig.FilterIdLow = (uint8_t) id; - sFilterConfig.FilterMaskIdHigh = (uint8_t)(mask >> 8); - sFilterConfig.FilterMaskIdLow = (uint8_t) mask; - sFilterConfig.FilterFIFOAssignment = 0; - sFilterConfig.FilterActivation = ENABLE; - sFilterConfig.BankNumber = 14 + handle; - - HAL_CAN_ConfigFilter(&CanHandle, &sFilterConfig); - - return 0; + if (format == CANStandard) { + sFilterConfig.FilterIdHigh = id << 5; + sFilterConfig.FilterIdLow = 0x0; + sFilterConfig.FilterMaskIdHigh = mask << 5; + sFilterConfig.FilterMaskIdLow = 0x0; // allows both remote and data frames + } else if (format == CANExtended) { + sFilterConfig.FilterIdHigh = id >> 13; // EXTID[28:13] + sFilterConfig.FilterIdLow = (0x00FF & (id << 3)) | (1 << 2); // EXTID[12:0] + sFilterConfig.FilterMaskIdHigh = mask >> 13; + sFilterConfig.FilterMaskIdLow = (0x00FF & (mask << 3)) | (1 << 2); + } + + sFilterConfig.FilterFIFOAssignment = 0; + sFilterConfig.FilterActivation = ENABLE; + sFilterConfig.BankNumber = 14 + handle; + + HAL_CAN_ConfigFilter(&CanHandle, &sFilterConfig); + retval = handle; + } + return retval; } static void can_irq(CANName name, int id) @@ -393,6 +417,15 @@ static void can_irq(CANName name, int id) tmp1 = __HAL_CAN_TRANSMIT_STATUS(&CanHandle, CAN_TXMAILBOX_0); tmp2 = __HAL_CAN_TRANSMIT_STATUS(&CanHandle, CAN_TXMAILBOX_1); tmp3 = __HAL_CAN_TRANSMIT_STATUS(&CanHandle, CAN_TXMAILBOX_2); + if (tmp1) { + __HAL_CAN_CLEAR_FLAG(&CanHandle, CAN_FLAG_RQCP0); + } + if (tmp2) { + __HAL_CAN_CLEAR_FLAG(&CanHandle, CAN_FLAG_RQCP1); + } + if (tmp3) { + __HAL_CAN_CLEAR_FLAG(&CanHandle, CAN_FLAG_RQCP2); + } if (tmp1 || tmp2 || tmp3) { irq_handler(can_irq_ids[id], IRQ_TX); } @@ -426,35 +459,42 @@ static void can_irq(CANName name, int id) } } -void CAN1_RX0_IRQHandler(void) -{ +#if defined(TARGET_STM32F0) +void CAN_IRQHandler(void) { can_irq(CAN_1, 0); } - -void CAN1_TX_IRQHandler(void) -{ +#elif defined(TARGET_STM32F3) +void CAN_RX0_IRQHandler(void) { can_irq(CAN_1, 0); } - -void CAN1_SCE_IRQHandler(void) -{ +void CAN_TX_IRQHandler(void) { can_irq(CAN_1, 0); } - -void CAN2_RX0_IRQHandler(void) -{ +void CAN_SCE_IRQHandler(void) { + can_irq(CAN_1, 0); +} +#else +void CAN1_RX0_IRQHandler(void) { + can_irq(CAN_1, 0); +} +void CAN1_TX_IRQHandler(void) { + can_irq(CAN_1, 0); +} +void CAN1_SCE_IRQHandler(void) { + can_irq(CAN_1, 0); +} +#if defined(CAN2_BASE) && (CAN_NUM == 2) +void CAN2_RX0_IRQHandler(void) { can_irq(CAN_2, 1); } - -void CAN2_TX_IRQHandler(void) -{ +void CAN2_TX_IRQHandler(void) { can_irq(CAN_2, 1); } - -void CAN2_SCE_IRQHandler(void) -{ +void CAN2_SCE_IRQHandler(void) { can_irq(CAN_2, 1); } +#endif // defined(CAN2_BASE) && (CAN_NUM == 2) +#endif // else void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable) { @@ -468,63 +508,69 @@ void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable) switch (type) { case IRQ_RX: ier = CAN_IT_FMP0; - irq_n = CAN1_RX0_IRQn; - vector = (uint32_t)&CAN1_RX0_IRQHandler; + irq_n = CAN1_IRQ_RX_IRQN; + vector = (uint32_t)&CAN1_IRQ_RX_VECT; break; case IRQ_TX: ier = CAN_IT_TME; - irq_n = CAN1_TX_IRQn; - vector = (uint32_t)&CAN1_TX_IRQHandler; + irq_n = CAN1_IRQ_TX_IRQN; + vector = (uint32_t)&CAN1_IRQ_TX_VECT; break; case IRQ_ERROR: ier = CAN_IT_ERR; - irq_n = CAN1_SCE_IRQn; - vector = (uint32_t)&CAN1_SCE_IRQHandler; + irq_n = CAN1_IRQ_ERROR_IRQN; + vector = (uint32_t)&CAN1_IRQ_ERROR_VECT; break; case IRQ_PASSIVE: ier = CAN_IT_EPV; - irq_n = CAN1_SCE_IRQn; - vector = (uint32_t)&CAN1_SCE_IRQHandler; + irq_n = CAN1_IRQ_PASSIVE_IRQN; + vector = (uint32_t)&CAN1_IRQ_PASSIVE_VECT; break; case IRQ_BUS: ier = CAN_IT_BOF; - irq_n = CAN1_SCE_IRQn; - vector = (uint32_t)&CAN1_SCE_IRQHandler; + irq_n = CAN1_IRQ_BUS_IRQN; + vector = (uint32_t)&CAN1_IRQ_BUS_VECT; break; default: return; } - } else { + } +#if defined(CAN2_BASE) && (CAN_NUM == 2) + else if (obj->can == CAN_2) { switch (type) { case IRQ_RX: ier = CAN_IT_FMP0; - irq_n = CAN2_RX0_IRQn; - vector = (uint32_t)&CAN2_RX0_IRQHandler; + irq_n = CAN2_IRQ_RX_IRQN; + vector = (uint32_t)&CAN2_IRQ_RX_VECT; break; case IRQ_TX: ier = CAN_IT_TME; - irq_n = CAN2_TX_IRQn; - vector = (uint32_t)&CAN2_TX_IRQHandler; + irq_n = CAN2_IRQ_TX_IRQN; + vector = (uint32_t)&CAN2_IRQ_TX_VECT; break; case IRQ_ERROR: ier = CAN_IT_ERR; - irq_n = CAN2_SCE_IRQn; - vector = (uint32_t)&CAN2_SCE_IRQHandler; + irq_n = CAN2_IRQ_ERROR_IRQN; + vector = (uint32_t)&CAN2_IRQ_ERROR_VECT; break; case IRQ_PASSIVE: ier = CAN_IT_EPV; - irq_n = CAN2_SCE_IRQn; - vector = (uint32_t)&CAN2_SCE_IRQHandler; + irq_n = CAN2_IRQ_PASSIVE_IRQN; + vector = (uint32_t)&CAN2_IRQ_PASSIVE_VECT; break; case IRQ_BUS: ier = CAN_IT_BOF; - irq_n = CAN2_SCE_IRQn; - vector = (uint32_t)&CAN2_SCE_IRQHandler; + irq_n = CAN2_IRQ_BUS_IRQN; + vector = (uint32_t)&CAN2_IRQ_BUS_VECT; break; default: return; } } +#endif + else { + return; + } if (enable) { can->IER |= ier; diff --git a/targets/TARGET_STM/gpio_api.c b/targets/TARGET_STM/gpio_api.c index 560350f13e..bbcf53fc4c 100644 --- a/targets/TARGET_STM/gpio_api.c +++ b/targets/TARGET_STM/gpio_api.c @@ -31,8 +31,82 @@ #include "gpio_api.h" #include "pinmap.h" #include "mbed_error.h" +#include "pin_device.h" -extern uint32_t Set_GPIO_Clock(uint32_t port_idx); +extern const uint32_t ll_pin_defines[16]; + +// Enable GPIO clock and return GPIO base address +GPIO_TypeDef *Set_GPIO_Clock(uint32_t port_idx) { + uint32_t gpio_add = 0; + switch (port_idx) { + case PortA: + gpio_add = GPIOA_BASE; + __GPIOA_CLK_ENABLE(); + break; + case PortB: + gpio_add = GPIOB_BASE; + __GPIOB_CLK_ENABLE(); + break; +#if defined(GPIOC_BASE) + case PortC: + gpio_add = GPIOC_BASE; + __GPIOC_CLK_ENABLE(); + break; +#endif +#if defined GPIOD_BASE + case PortD: + gpio_add = GPIOD_BASE; + __GPIOD_CLK_ENABLE(); + break; +#endif +#if defined GPIOE_BASE + case PortE: + gpio_add = GPIOE_BASE; + __GPIOE_CLK_ENABLE(); + break; +#endif +#if defined GPIOF_BASE + case PortF: + gpio_add = GPIOF_BASE; + __GPIOF_CLK_ENABLE(); + break; +#endif +#if defined GPIOG_BASE + case PortG: + gpio_add = GPIOG_BASE; + __GPIOG_CLK_ENABLE(); + break; +#endif +#if defined GPIOH_BASE + case PortH: + gpio_add = GPIOH_BASE; + __GPIOH_CLK_ENABLE(); + break; +#endif +#if defined GPIOI_BASE + case PortI: + gpio_add = GPIOI_BASE; + __GPIOI_CLK_ENABLE(); + break; +#endif +#if defined GPIOJ_BASE + case PortJ: + gpio_add = GPIOJ_BASE; + __GPIOJ_CLK_ENABLE(); + break; +#endif +#if defined GPIOK_BASE + case PortK: + gpio_add = GPIOK_BASE; + __GPIOK_CLK_ENABLE(); + break; +#endif + default: + error("Pinmap error: wrong port number."); + break; + } + return (GPIO_TypeDef *) gpio_add; +} uint32_t gpio_set(PinName pin) { MBED_ASSERT(pin != (PinName)NC); @@ -42,6 +116,7 @@ uint32_t gpio_set(PinName pin) { return (uint32_t)(1 << ((uint32_t)pin & 0xF)); // Return the pin mask } + void gpio_init(gpio_t *obj, PinName pin) { obj->pin = pin; if (pin == (PinName)NC) { @@ -51,11 +126,12 @@ void gpio_init(gpio_t *obj, PinName pin) { uint32_t port_index = STM_PORT(pin); // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add; + GPIO_TypeDef *gpio = Set_GPIO_Clock(port_index); // Fill GPIO object structure for future use obj->mask = gpio_set(pin); + obj->gpio = gpio; + obj->ll_pin = ll_pin_defines[STM_PIN(obj->pin)]; obj->reg_in = &gpio->IDR; obj->reg_set = &gpio->BSRR; #ifdef GPIO_IP_WITHOUT_BRR @@ -69,11 +145,11 @@ void gpio_mode(gpio_t *obj, PinMode mode) { pin_mode(obj->pin, mode); } -void gpio_dir(gpio_t *obj, PinDirection direction) { - MBED_ASSERT(obj->pin != (PinName)NC); - if (direction == PIN_OUTPUT) { - pin_function(obj->pin, STM_PIN_DATA(STM_MODE_OUTPUT_PP, GPIO_NOPULL, 0)); - } else { // PIN_INPUT - pin_function(obj->pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); +inline void gpio_dir(gpio_t *obj, PinDirection direction) { + if (direction == PIN_INPUT) { + LL_GPIO_SetPinMode(obj->gpio, obj->ll_pin, LL_GPIO_MODE_INPUT); + } else { + LL_GPIO_SetPinMode(obj->gpio, obj->ll_pin, LL_GPIO_MODE_OUTPUT); } } + diff --git a/targets/TARGET_STM/TARGET_STM32F3/gpio_irq_api.c b/targets/TARGET_STM/gpio_irq_api.c similarity index 60% rename from targets/TARGET_STM/TARGET_STM32F3/gpio_irq_api.c rename to targets/TARGET_STM/gpio_irq_api.c index 6b40b8836b..a507a00164 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/gpio_irq_api.c +++ b/targets/TARGET_STM/gpio_irq_api.c @@ -32,64 +32,47 @@ #include "gpio_irq_api.h" #include "pinmap.h" #include "mbed_error.h" +#include "gpio_irq_device.h" #define EDGE_NONE (0) #define EDGE_RISE (1) #define EDGE_FALL (2) #define EDGE_BOTH (3) -// Number of EXTI irq vectors (EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5_9, EXTI10_15) -#define CHANNEL_NUM (7) - -// Max pins for one line (max with EXTI10_15) -#define MAX_PIN_LINE (6) typedef struct gpio_channel { uint32_t pin_mask; // bitmask representing which pins are configured for receiving interrupts uint32_t channel_ids[MAX_PIN_LINE]; // mbed "gpio_irq_t gpio_irq" field of instance - uint32_t channel_gpio[MAX_PIN_LINE]; // base address of gpio port group + GPIO_TypeDef* channel_gpio[MAX_PIN_LINE]; // base address of gpio port group uint32_t channel_pin[MAX_PIN_LINE]; // pin number in port group } gpio_channel_t; -static gpio_channel_t channels[CHANNEL_NUM] = { - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0} -}; - -// Used to return the index for channels array. -static uint32_t pin_base_nr[16] = { - // EXTI0 - 0, // pin 0 - // EXTI1 - 0, // pin 1 - // EXTI2 - 0, // pin 2 - // EXTI3 - 0, // pin 3 - // EXTI4 - 0, // pin 4 - // EXTI5_9 - 0, // pin 5 - 1, // pin 6 - 2, // pin 7 - 3, // pin 8 - 4, // pin 9 - // EXTI10_15 - 0, // pin 10 - 1, // pin 11 - 2, // pin 12 - 3, // pin 13 - 4, // pin 14 - 5 // pin 15 -}; - static gpio_irq_handler irq_handler; +static gpio_channel_t channels[CHANNEL_NUM] = { +#ifdef EXTI_IRQ0_NUM_LINES + {.pin_mask = 0}, +#endif +#ifdef EXTI_IRQ1_NUM_LINES + {.pin_mask = 0}, +#endif +#ifdef EXTI_IRQ2_NUM_LINES + {.pin_mask = 0}, +#endif +#ifdef EXTI_IRQ3_NUM_LINES + {.pin_mask = 0}, +#endif +#ifdef EXTI_IRQ4_NUM_LINES + {.pin_mask = 0}, +#endif +#ifdef EXTI_IRQ5_NUM_LINES + {.pin_mask = 0}, +#endif +#ifdef EXTI_IRQ6_NUM_LINES + {.pin_mask = 0} +#endif +}; + static void handle_interrupt_in(uint32_t irq_index, uint32_t max_num_pin_line) { gpio_channel_t *gpio_channel = &channels[irq_index]; @@ -107,12 +90,13 @@ static void handle_interrupt_in(uint32_t irq_index, uint32_t max_num_pin_line) if (__HAL_GPIO_EXTI_GET_FLAG(pin) != RESET) { __HAL_GPIO_EXTI_CLEAR_FLAG(pin); - if (gpio_channel->channel_ids[gpio_idx] == 0) continue; + if (gpio_channel->channel_ids[gpio_idx] == 0) + continue; // Check which edge has generated the irq if ((gpio->IDR & pin) == 0) { irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_FALL); - } else { + } else { irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_RISE); } } @@ -120,54 +104,62 @@ static void handle_interrupt_in(uint32_t irq_index, uint32_t max_num_pin_line) } } + +#ifdef EXTI_IRQ0_NUM_LINES // EXTI line 0 static void gpio_irq0(void) { - handle_interrupt_in(0, 1); + handle_interrupt_in(0, EXTI_IRQ0_NUM_LINES); } - +#endif +#ifdef EXTI_IRQ1_NUM_LINES // EXTI line 1 static void gpio_irq1(void) { - handle_interrupt_in(1, 1); + handle_interrupt_in(1, EXTI_IRQ1_NUM_LINES); } - +#endif +#ifdef EXTI_IRQ2_NUM_LINES // EXTI line 2 static void gpio_irq2(void) { - handle_interrupt_in(2, 1); + handle_interrupt_in(2, EXTI_IRQ2_NUM_LINES); } - +#endif +#ifdef EXTI_IRQ3_NUM_LINES // EXTI line 3 static void gpio_irq3(void) { - handle_interrupt_in(3, 1); + handle_interrupt_in(3, EXTI_IRQ3_NUM_LINES); } - +#endif +#ifdef EXTI_IRQ4_NUM_LINES // EXTI line 4 static void gpio_irq4(void) { - handle_interrupt_in(4, 1); + handle_interrupt_in(4, EXTI_IRQ4_NUM_LINES); } - +#endif +#ifdef EXTI_IRQ5_NUM_LINES // EXTI lines 5 to 9 static void gpio_irq5(void) { - handle_interrupt_in(5, 5); + handle_interrupt_in(5, EXTI_IRQ5_NUM_LINES); } - +#endif +#ifdef EXTI_IRQ6_NUM_LINES // EXTI lines 10 to 15 static void gpio_irq6(void) { - handle_interrupt_in(6, 6); + handle_interrupt_in(6, EXTI_IRQ6_NUM_LINES); } +#endif -extern uint32_t Set_GPIO_Clock(uint32_t port_idx); +extern GPIO_TypeDef *Set_GPIO_Clock(uint32_t port_idx); extern void pin_function_gpiomode(PinName pin, uint32_t gpiomode); int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) { - IRQn_Type irq_n = (IRQn_Type)0; uint32_t vector = 0; uint32_t irq_index; gpio_channel_t *gpio_channel; @@ -175,78 +167,65 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32 if (pin == NC) return -1; - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); + /* Enable SYSCFG Clock */ + __HAL_RCC_SYSCFG_CLK_ENABLE(); - // Select irq number and interrupt routine - switch (pin_index) { + uint32_t port_index = STM_PORT(pin); + uint32_t pin_index = STM_PIN(pin); + irq_index = pin_lines_desc[pin_index].irq_index; + + switch (irq_index) { +#ifdef EXTI_IRQ0_NUM_LINES case 0: - irq_n = EXTI0_IRQn; vector = (uint32_t)&gpio_irq0; - irq_index = 0; break; +#endif +#ifdef EXTI_IRQ1_NUM_LINES case 1: - irq_n = EXTI1_IRQn; vector = (uint32_t)&gpio_irq1; - irq_index = 1; break; +#endif +#ifdef EXTI_IRQ2_NUM_LINES case 2: - irq_n = EXTI2_TSC_IRQn; vector = (uint32_t)&gpio_irq2; - irq_index = 2; break; +#endif +#ifdef EXTI_IRQ3_NUM_LINES case 3: - irq_n = EXTI3_IRQn; vector = (uint32_t)&gpio_irq3; - irq_index = 3; break; +#endif +#ifdef EXTI_IRQ4_NUM_LINES case 4: - irq_n = EXTI4_IRQn; vector = (uint32_t)&gpio_irq4; - irq_index = 4; break; +#endif +#ifdef EXTI_IRQ5_NUM_LINES case 5: - case 6: - case 7: - case 8: - case 9: - irq_n = EXTI9_5_IRQn; vector = (uint32_t)&gpio_irq5; - irq_index = 5; break; - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - irq_n = EXTI15_10_IRQn; +#endif +#ifdef EXTI_IRQ6_NUM_LINES + case 6: vector = (uint32_t)&gpio_irq6; - irq_index = 6; break; +#endif default: error("InterruptIn error: pin not supported.\n"); return -1; } // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - - // Configure GPIO - pin_function(pin, STM_PIN_DATA(STM_MODE_IT_FALLING, GPIO_NOPULL, 0)); - - // Enable EXTI interrupt - NVIC_SetVector(irq_n, vector); - NVIC_EnableIRQ(irq_n); + GPIO_TypeDef *gpio_add = Set_GPIO_Clock(port_index); // Save informations for future use - obj->irq_n = irq_n; - obj->irq_index = irq_index; + obj->irq_n = pin_lines_desc[pin_index].irq_n; + obj->irq_index = pin_lines_desc[pin_index].irq_index; obj->event = EDGE_NONE; obj->pin = pin; gpio_channel = &channels[irq_index]; - gpio_idx = pin_base_nr[pin_index]; + gpio_idx = pin_lines_desc[pin_index].gpio_idx; gpio_channel->pin_mask |= (1 << gpio_idx); gpio_channel->channel_ids[gpio_idx] = id; gpio_channel->channel_gpio[gpio_idx] = gpio_add; @@ -254,81 +233,65 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32 irq_handler = handler; + // Enable EXTI interrupt + NVIC_SetVector(obj->irq_n, vector); + gpio_irq_enable(obj); + return 0; } void gpio_irq_free(gpio_irq_t *obj) { + uint32_t gpio_idx = pin_lines_desc[STM_PIN(obj->pin)].gpio_idx; gpio_channel_t *gpio_channel = &channels[obj->irq_index]; - uint32_t pin_index = STM_PIN(obj->pin); - uint32_t gpio_addr = GPIOA_BASE + (GPIOB_BASE-GPIOA_BASE) * STM_PORT(obj->pin); - uint32_t gpio_idx = pin_base_nr[pin_index]; - - HAL_GPIO_DeInit((GPIO_TypeDef *)gpio_addr, (1<pin_mask &= ~(1 << gpio_idx); gpio_channel->channel_ids[gpio_idx] = 0; gpio_channel->channel_gpio[gpio_idx] = 0; gpio_channel->channel_pin[gpio_idx] = 0; - - // Disable EXTI line, but don't change pull-up config - pin_function_gpiomode(obj->pin, STM_MODE_INPUT); - obj->event = EDGE_NONE; } void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) { - uint32_t mode = STM_MODE_INPUT; - - if (enable) { - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or RISE - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or FALL - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } - } - } else { // Disable - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } else { // NONE or RISE - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } else { // NONE or FALL - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } + if (event == IRQ_RISE) { + if (enable) { + LL_EXTI_EnableRisingTrig_0_31(1 << STM_PIN(obj->pin)); + } else { + LL_EXTI_DisableRisingTrig_0_31(1 << STM_PIN(obj->pin)); + } + } + if (event == IRQ_FALL) { + if (enable) { + LL_EXTI_EnableFallingTrig_0_31(1 << STM_PIN(obj->pin)); + } else { + LL_EXTI_DisableFallingTrig_0_31(1 << STM_PIN(obj->pin)); } } - - pin_function_gpiomode(obj->pin, mode); } void gpio_irq_enable(gpio_irq_t *obj) { + uint32_t temp = 0; + uint32_t port_index = STM_PORT(obj->pin); + uint32_t pin_index = STM_PIN(obj->pin); + + /* Select Source */ + temp = SYSCFG->EXTICR[pin_index >> 2]; + CLEAR_BIT(temp, (0x0FU) << (4U * (pin_index & 0x03U))); + SET_BIT(temp, port_index << (4U * (pin_index & 0x03U))); + SYSCFG->EXTICR[pin_index >> 2] = temp; + + LL_EXTI_EnableIT_0_31(1 << pin_index); + NVIC_EnableIRQ(obj->irq_n); } void gpio_irq_disable(gpio_irq_t *obj) { + /* Clear EXTI line configuration */ + LL_EXTI_DisableIT_0_31(1 << STM_PIN(obj->pin)); NVIC_DisableIRQ(obj->irq_n); + NVIC_ClearPendingIRQ(obj->irq_n); obj->event = EDGE_NONE; } diff --git a/targets/TARGET_STM/gpio_object.h b/targets/TARGET_STM/gpio_object.h index c80c7b9964..b4285cc766 100644 --- a/targets/TARGET_STM/gpio_object.h +++ b/targets/TARGET_STM/gpio_object.h @@ -46,16 +46,17 @@ extern "C" { * if BRR does not exist, family shall define GPIO_DOES_NOT_HAVE_BRR */ typedef struct { - PinName pin; uint32_t mask; __IO uint32_t *reg_in; __IO uint32_t *reg_set; __IO uint32_t *reg_clr; + PinName pin; + GPIO_TypeDef *gpio; + uint32_t ll_pin; } gpio_t; static inline void gpio_write(gpio_t *obj, int value) { - MBED_ASSERT(obj->pin != (PinName)NC); if (value) { *obj->reg_set = obj->mask; } else { @@ -69,7 +70,6 @@ static inline void gpio_write(gpio_t *obj, int value) static inline int gpio_read(gpio_t *obj) { - MBED_ASSERT(obj->pin != (PinName)NC); return ((*obj->reg_in & obj->mask) ? 1 : 0); } @@ -78,6 +78,7 @@ static inline int gpio_is_connected(const gpio_t *obj) return obj->pin != (PinName)NC; } + #ifdef __cplusplus } #endif diff --git a/targets/TARGET_STM/i2c_api.c b/targets/TARGET_STM/i2c_api.c index 2559a46b52..ae64810315 100644 --- a/targets/TARGET_STM/i2c_api.c +++ b/targets/TARGET_STM/i2c_api.c @@ -276,8 +276,8 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) { // Configure I2C pins pinmap_pinout(sda, PinMap_I2C_SDA); pinmap_pinout(scl, PinMap_I2C_SCL); - pin_mode(sda, PullUp); - pin_mode(scl, PullUp); + pin_mode(sda, OpenDrainPullUp); + pin_mode(scl, OpenDrainPullUp); obj_s->event_i2cIRQ = I2C1_EV_IRQn; obj_s->error_i2cIRQ = I2C1_ER_IRQn; } @@ -290,8 +290,8 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) { // Configure I2C pins pinmap_pinout(sda, PinMap_I2C_SDA); pinmap_pinout(scl, PinMap_I2C_SCL); - pin_mode(sda, PullUp); - pin_mode(scl, PullUp); + pin_mode(sda, OpenDrainPullUp); + pin_mode(scl, OpenDrainPullUp); obj_s->event_i2cIRQ = I2C2_EV_IRQn; obj_s->error_i2cIRQ = I2C2_ER_IRQn; } @@ -304,8 +304,8 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) { // Configure I2C pins pinmap_pinout(sda, PinMap_I2C_SDA); pinmap_pinout(scl, PinMap_I2C_SCL); - pin_mode(sda, PullUp); - pin_mode(scl, PullUp); + pin_mode(sda, OpenDrainPullUp); + pin_mode(scl, OpenDrainPullUp); obj_s->event_i2cIRQ = I2C3_EV_IRQn; obj_s->error_i2cIRQ = I2C3_ER_IRQn; } @@ -318,8 +318,8 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) { // Configure I2C pins pinmap_pinout(sda, PinMap_I2C_SDA); pinmap_pinout(scl, PinMap_I2C_SCL); - pin_mode(sda, PullUp); - pin_mode(scl, PullUp); + pin_mode(sda, OpenDrainPullUp); + pin_mode(scl, OpenDrainPullUp); obj_s->event_i2cIRQ = I2C4_EV_IRQn; obj_s->error_i2cIRQ = I2C4_ER_IRQn; } @@ -332,8 +332,8 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) { // Configure I2C pins pinmap_pinout(sda, PinMap_I2C_SDA); pinmap_pinout(scl, PinMap_I2C_SCL); - pin_mode(sda, PullUp); - pin_mode(scl, PullUp); + pin_mode(sda, OpenDrainPullUp); + pin_mode(scl, OpenDrainPullUp); obj_s->event_i2cIRQ = FMPI2C1_EV_IRQn; obj_s->error_i2cIRQ = FMPI2C1_ER_IRQn; } diff --git a/targets/TARGET_STM/pinmap.c b/targets/TARGET_STM/pinmap.c new file mode 100644 index 0000000000..2546378af9 --- /dev/null +++ b/targets/TARGET_STM/pinmap.c @@ -0,0 +1,148 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2017, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include "mbed_assert.h" +#include "pinmap.h" +#include "PortNames.h" +#include "mbed_error.h" +#include "pin_device.h" + +extern GPIO_TypeDef *Set_GPIO_Clock(uint32_t port_idx); + +const uint32_t ll_pin_defines[16] = { + LL_GPIO_PIN_0, + LL_GPIO_PIN_1, + LL_GPIO_PIN_2, + LL_GPIO_PIN_3, + LL_GPIO_PIN_4, + LL_GPIO_PIN_5, + LL_GPIO_PIN_6, + LL_GPIO_PIN_7, + LL_GPIO_PIN_8, + LL_GPIO_PIN_9, + LL_GPIO_PIN_10, + LL_GPIO_PIN_11, + LL_GPIO_PIN_12, + LL_GPIO_PIN_13, + LL_GPIO_PIN_14, + LL_GPIO_PIN_15 +}; + +/** + * Configure pin (mode, speed, output type and pull-up/pull-down) + */ +void pin_function(PinName pin, int data) +{ + MBED_ASSERT(pin != (PinName)NC); + + // Get the pin informations + uint32_t mode = STM_PIN_FUNCTION(data); + uint32_t afnum = STM_PIN_AFNUM(data); + uint32_t port = STM_PORT(pin); + uint32_t ll_pin = ll_pin_defines[STM_PIN(pin)]; + uint32_t ll_mode = 0; + + // Enable GPIO clock + GPIO_TypeDef *gpio = Set_GPIO_Clock(port); + + switch (mode) { + case STM_PIN_INPUT: + ll_mode = LL_GPIO_MODE_INPUT; + break; + case STM_PIN_OUTPUT: + ll_mode = LL_GPIO_MODE_OUTPUT; + break; + case STM_PIN_ALTERNATE: + ll_mode = LL_GPIO_MODE_ALTERNATE; + // In case of ALT function, also set he afnum + stm_pin_SetAFPin(gpio, pin, afnum); + break; + case STM_PIN_ANALOG: + ll_mode = LL_GPIO_MODE_ANALOG; + break; + default: + MBED_ASSERT(0); + break; + } + LL_GPIO_SetPinMode(gpio, ll_pin, ll_mode); + +#if defined(GPIO_ASCR_ASC0) + /* For families where Analog Control ASC0 register is present */ + if (STM_PIN_ANALOG_CONTROL(data)) { + LL_GPIO_EnablePinAnalogControl(gpio, ll_pin); + } else { + LL_GPIO_DisablePinAnalogControl(gpio, ll_pin); + } +#endif + + /* For now by default use Speed HIGH for output or alt modes */ + if ((mode == STM_PIN_OUTPUT) ||(mode == STM_PIN_ALTERNATE)) { + LL_GPIO_SetPinSpeed(gpio, ll_pin, LL_GPIO_SPEED_FREQ_HIGH); + if (STM_PIN_OD(data)) { + LL_GPIO_SetPinOutputType(gpio, ll_pin, LL_GPIO_OUTPUT_OPENDRAIN); + } else { + LL_GPIO_SetPinOutputType(gpio, ll_pin, LL_GPIO_OUTPUT_PUSHPULL); + } + } + + stm_pin_PullConfig(gpio, ll_pin, STM_PIN_PUPD(data)); + + stm_pin_DisconnectDebug(pin); +} + +/** + * Configure pin pull-up/pull-down + */ +void pin_mode(PinName pin, PinMode mode) +{ + MBED_ASSERT(pin != (PinName)NC); + + uint32_t port_index = STM_PORT(pin); + uint32_t ll_pin = ll_pin_defines[STM_PIN(pin)]; + // Enable GPIO clock + GPIO_TypeDef *gpio = Set_GPIO_Clock(port_index); + uint32_t function = LL_GPIO_GetPinMode(gpio, ll_pin); + + if ((function == LL_GPIO_MODE_OUTPUT) || (function == LL_GPIO_MODE_ALTERNATE)) + { + if ((mode == OpenDrainNoPull) || (mode == OpenDrainPullUp) || (mode == OpenDrainPullDown)) { + LL_GPIO_SetPinOutputType(gpio, ll_pin, LL_GPIO_OUTPUT_OPENDRAIN); + } else { + LL_GPIO_SetPinOutputType(gpio, ll_pin, LL_GPIO_OUTPUT_PUSHPULL); + } + } + + if ((mode == OpenDrainPullUp) || (mode == PullUp)) { + stm_pin_PullConfig(gpio, ll_pin, GPIO_PULLUP); + } else if ((mode == OpenDrainPullDown) || (mode == PullDown)) { + stm_pin_PullConfig(gpio, ll_pin, GPIO_PULLDOWN); + } else { + stm_pin_PullConfig(gpio, ll_pin, GPIO_NOPULL); + } +} diff --git a/targets/TARGET_STM/TARGET_STM32F2/port_api.c b/targets/TARGET_STM/port_api.c similarity index 95% rename from targets/TARGET_STM/TARGET_STM32F2/port_api.c rename to targets/TARGET_STM/port_api.c index 532b57e8fa..04c7c8a280 100644 --- a/targets/TARGET_STM/TARGET_STM32F2/port_api.c +++ b/targets/TARGET_STM/port_api.c @@ -34,7 +34,7 @@ #if DEVICE_PORTIN || DEVICE_PORTOUT -extern uint32_t Set_GPIO_Clock(uint32_t port_idx); +extern GPIO_TypeDef *Set_GPIO_Clock(uint32_t port_idx); // high nibble = port number (0=A, 1=B, 2=C, 3=D, 4=E, 5=F, ...) // low nibble = pin number @@ -48,8 +48,7 @@ void port_init(port_t *obj, PortName port, int mask, PinDirection dir) uint32_t port_index = (uint32_t)port; // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add; + GPIO_TypeDef *gpio = Set_GPIO_Clock(port_index); // Fill PORT object structure for future use obj->port = port; diff --git a/targets/TARGET_STM/sleep.c b/targets/TARGET_STM/sleep.c index e2d9a5834a..825c760b2f 100644 --- a/targets/TARGET_STM/sleep.c +++ b/targets/TARGET_STM/sleep.c @@ -27,28 +27,33 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* */ -#include "sleep_api.h" -#include "rtc_api_hal.h" - #if DEVICE_SLEEP #include "cmsis.h" +#include "us_ticker_api.h" +#include "sleep_api.h" +#include "rtc_api_hal.h" +#include "hal_tick.h" +extern void HAL_SuspendTick(void); +extern void HAL_ResumeTick(void); void hal_sleep(void) { - // Stop HAL systick + // Stop HAL tick to avoid to exit sleep in 1ms HAL_SuspendTick(); // Request to enter SLEEP mode HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI); - // Restart HAL systick + + // Restart HAL tick HAL_ResumeTick(); } void hal_deepsleep(void) { - // Stop HAL systick + // Stop HAL tick HAL_SuspendTick(); + uint32_t EnterTimeUS = us_ticker_read(); // Request to enter STOP mode with regulator in low power mode #if TARGET_STM32L4 @@ -74,12 +79,16 @@ void hal_deepsleep(void) HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); #endif /* TARGET_STM32L4 */ - // Restart HAL systick + // Restart HAL tick HAL_ResumeTick(); // After wake-up from STOP reconfigure the PLL SetSysClock(); + TIM_HandleTypeDef TimMasterHandle; + TimMasterHandle.Instance = TIM_MST; + __HAL_TIM_SET_COUNTER(&TimMasterHandle, EnterTimeUS); + #if DEVICE_LOWPOWERTIMER rtc_synchronize(); #endif diff --git a/targets/TARGET_STM/stm_spi_api.c b/targets/TARGET_STM/stm_spi_api.c index 65ce41dc5a..1928253bb6 100644 --- a/targets/TARGET_STM/stm_spi_api.c +++ b/targets/TARGET_STM/stm_spi_api.c @@ -291,23 +291,28 @@ void spi_frequency(spi_t *obj, int hz) { struct spi_s *spiobj = SPI_S(obj); int spi_hz = 0; uint8_t prescaler_rank = 0; + uint8_t last_index = (sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0])) - 1; SPI_HandleTypeDef *handle = &(spiobj->handle); - /* Get the clock of the peripheral */ - spi_hz = spi_get_clock_freq(obj); + /* Calculate the spi clock for prescaler_rank 0: SPI_BAUDRATEPRESCALER_2 */ + spi_hz = spi_get_clock_freq(obj) / 2; /* Define pre-scaler in order to get highest available frequency below requested frequency */ - while ((spi_hz > hz) && (prescaler_rank < sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0]))){ + while ((spi_hz > hz) && (prescaler_rank < last_index)) { spi_hz = spi_hz / 2; prescaler_rank++; } - if (prescaler_rank <= sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0])) { - handle->Init.BaudRatePrescaler = baudrate_prescaler_table[prescaler_rank-1]; - } else { - error("Couldn't setup requested SPI frequency"); + /* Use the best fit pre-scaler */ + handle->Init.BaudRatePrescaler = baudrate_prescaler_table[prescaler_rank]; + + /* In case maximum pre-scaler still gives too high freq, raise an error */ + if (spi_hz > hz) { + error("Couldn't set suitable spi freq: request:%d, lowest:%d\r\n", hz, spi_hz); } + DEBUG_PRINTF("spi_frequency, request:%d, select:%d\r\n", hz, spi_hz); + init_spi(obj); } diff --git a/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_GCC_ARM/startup_hi2110.s b/targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_GCC_ARM/startup_hi2110.S similarity index 100% rename from targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_GCC_ARM/startup_hi2110.s rename to targets/TARGET_ublox/TARGET_HI2110/device/TOOLCHAIN_GCC_ARM/startup_hi2110.S diff --git a/targets/targets.json b/targets/targets.json index d62496f2dd..af5971049e 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" @@ -881,11 +881,11 @@ "inherits": ["Target"], "core": "Cortex-M4F", "default_toolchain": "ARM", - "extra_labels": ["STM", "STM32F4", "STM32F429", "STM32F429ZI", "STM32F429xx", "STM32F429xI"], + "extra_labels": ["STM", "STM32F4", "STM32F429", "STM32F429ZI", "STM32F429xx", "STM32F429xI", "FLASH_CMSIS_ALGO"], "supported_toolchains": ["ARM", "uARM", "GCC_ARM", "IAR"], "progen": {"target": "nucleo-f429zi"}, "macros": ["TRANSACTION_QUEUE_SIZE_SPI=2", "USB_STM_HAL", "USBHOST_OTHER"], - "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "ERROR_RED", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG"], + "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "ERROR_RED", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG", "FLASH"], "detect_code": ["0796"], "features": ["LWIP"], "release_versions": ["2", "5"], @@ -896,11 +896,11 @@ "inherits": ["Target"], "core": "Cortex-M4F", "default_toolchain": "ARM", - "extra_labels": ["STM", "STM32F4", "STM32F439", "STM32F439ZI", "STM32F439xx", "STM32F439xI"], + "extra_labels": ["STM", "STM32F4", "STM32F439", "STM32F439ZI", "STM32F439xx", "STM32F439xI", "FLASH_CMSIS_ALGO"], "supported_toolchains": ["ARM", "uARM", "GCC_ARM", "IAR"], "progen": {"target": "nucleo-f439zi"}, "macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"], - "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "ERROR_RED", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG"], + "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "ERROR_RED", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG", "FLASH"], "detect_code": ["0797"], "features": ["LWIP"], "release_versions": ["2", "5"], @@ -1170,10 +1170,10 @@ "inherits": ["Target"], "core": "Cortex-M4F", "default_toolchain": "ARM", - "extra_labels": ["STM", "STM32F4", "STM32F429", "STM32F429ZI", "STM32F429xI", "STM32F429xx"], + "extra_labels": ["STM", "STM32F4", "STM32F429", "STM32F429ZI", "STM32F429xI", "STM32F429xx", "FLASH_CMSIS_ALGO"], "macros": ["RTC_LSI=1","TRANSACTION_QUEUE_SIZE_SPI=2", "USBHOST_OTHER"], "supported_toolchains": ["ARM", "uARM", "GCC_ARM", "IAR"], - "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "ERROR_RED", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG"], + "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "ERROR_RED", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG", "FLASH"], "release_versions": ["2", "5"], "device_name": "STM32F429ZI" }, @@ -1321,10 +1321,10 @@ "core": "Cortex-M4F", "default_toolchain": "ARM", "supported_toolchains": ["ARM", "uARM", "GCC_ARM", "IAR"], - "extra_labels": ["STM", "STM32F4", "STM32F439", "STM32F439ZI","STM32F439xx"], + "extra_labels": ["STM", "STM32F4", "STM32F439", "STM32F439ZI","STM32F439xx", "FLASH_CMSIS_ALGO"], "macros": ["HSE_VALUE=24000000", "HSE_STARTUP_TIMEOUT=5000", "CB_INTERFACE_SDIO","CB_CHIP_WL18XX","SUPPORT_80211D_ALWAYS","WLAN_ENABLED","MBEDTLS_ARC4_C","MBEDTLS_DES_C","MBEDTLS_MD4_C","MBEDTLS_MD5_C","MBEDTLS_SHA1_C"], "inherits": ["Target"], - "device_has": ["ANALOGIN", "CAN", "EMAC", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES", "TRNG"], + "device_has": ["ANALOGIN", "CAN", "EMAC", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES", "TRNG", "FLASH"], "features": ["LWIP"], "release_versions": ["5"], "device_name": "STM32F439ZI" @@ -2553,7 +2553,7 @@ "NUMAKER_PFM_NUC472": { "core": "Cortex-M4F", "default_toolchain": "ARM", - "extra_labels": ["NUVOTON", "NUC472", "NUMAKER_PFM_NUC472"], + "extra_labels": ["NUVOTON", "NUC472", "NU_XRAM_SUPPORTED"], "is_disk_virtual": true, "supported_toolchains": ["ARM", "uARM", "GCC_ARM", "IAR"], "inherits": ["Target"], diff --git a/tools/export/README.md b/tools/export/README.md deleted file mode 100644 index bf062acc71..0000000000 --- a/tools/export/README.md +++ /dev/null @@ -1,1148 +0,0 @@ -Exporter IDE/Platform Support ------------------------------------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Platformcodesourcerycoideds5_5emblocksgcc_armiarkdslpcxpressouvision
APPNEARME_MICRONFCBOARD--------
ARCH_BLE-----
ARCH_GPRS--------
ARCH_MAX-----
ARCH_PRO-
ARM_MPS2--------
ARM_MPS2_M0--------
ARM_MPS2_M0P--------
ARM_MPS2_M1--------
ARM_MPS2_M3--------
ARM_MPS2_M4--------
ARM_MPS2_M7--------
DELTA_DFCM_NNN40-----
DELTA_DFCM_NNN40_OTA--------
DISCO_F051R8------
DISCO_F100RB------
DISCO_F303VC------
DISCO_F334C8------
DISCO_F401VC------
DISCO_F407VG-----
DISCO_F429ZI------
DISCO_L053C8-----
HRM1017-----
K20D50M-----
K22F----
K64F----
KL05Z----
KL25Z----
KL43Z------
KL46Z-----
LPC1114----
LPC11C24-------
LPC11U24----
LPC11U24_301--------
LPC11U34_421--------
LPC11U35_401-----
LPC11U35_501-----
LPC11U35_Y5_MBUG--------
LPC11U37H_401-----
LPC11U37_501--------
LPC11U68------
LPC1347------
LPC1549----
LPC1768-
LPC2368-------
LPC4088----
LPC4088_DM----
LPC4330_M0---------
LPC4330_M4-----
LPC4337--------
LPC810---------
LPC812------
LPC824-----
LPCCAPPUCCINO------
MTS_DRAGONFLY_F411RE-------
MTS_GAMBIT------
MTS_MDOT_F405RG----
MTS_MDOT_F411RE-----
NRF51822-----
NRF51822_BOOT--------
NRF51822_OTA--------
NRF51822_Y5_MBUG--------
NRF51_DK-----
NRF51_DK_BOOT--------
NRF51_DK_OTA--------
NRF51_DONGLE-----
NUCLEO_F030R8----
NUCLEO_F070RB----
NUCLEO_F072RB----
NUCLEO_F091RC----
NUCLEO_F103RB----
NUCLEO_F302R8----
NUCLEO_F303RE----
NUCLEO_F334R8----
NUCLEO_F401RE----
NUCLEO_F411RE----
NUCLEO_L053R8----
NUCLEO_L073RZ-----
NUCLEO_L152RE----
OC_MBUINO--------
RBLAB_BLENANO--------
RBLAB_NRF51822------
RZ_A1H-------
SEEED_TINY_BLE-----
SEEED_TINY_BLE_BOOT--------
SEEED_TINY_BLE_OTA--------
SSCI824------
STM32F3XX--------
STM32F407-------
TEENSY3_1------
UBLOX_C027-
UBLOX_EVK_ODIN_W2--------
WALLBOT_BLE--------
XADOW_M0--------
-Total IDEs: 9 -
Total platforms: 94 -
Total permutations: 288 diff --git a/tools/export/__init__.py b/tools/export/__init__.py index fe1baf5278..9806e0222d 100644 --- a/tools/export/__init__.py +++ b/tools/export/__init__.py @@ -15,15 +15,16 @@ # See the License for the specific language governing permissions and # limitations under the License. -from tools.export import codered, ds5_5, iar, makefile +from tools.export import lpcxpresso, ds5_5, iar, makefile from tools.export import embitz, coide, kds, simplicity, atmelstudio from tools.export import sw4stm32, e2studio, zip, cmsis, uvision, cdt +from tools.export import gnuarmeclipse from tools.targets import TARGET_NAMES EXPORTERS = { 'uvision5': uvision.Uvision, 'uvision': uvision.Uvision, - 'lpcxpresso': codered.CodeRed, + 'lpcxpresso': lpcxpresso.LPCXpresso, 'gcc_arm': makefile.GccArm, 'make_gcc_arm': makefile.GccArm, 'make_armc5': makefile.Armc5, @@ -40,6 +41,7 @@ EXPORTERS = { 'eclipse_gcc_arm' : cdt.EclipseGcc, 'eclipse_iar' : cdt.EclipseIAR, 'eclipse_armc5' : cdt.EclipseArmc5, + 'gnuarmeclipse': gnuarmeclipse.GNUARMEclipse, 'zip' : zip.ZIP, 'cmsis' : cmsis.CMSIS } diff --git a/tools/export/codered/arch_pro_project.tmpl b/tools/export/codered/arch_pro_project.tmpl deleted file mode 100644 index d77c507eb0..0000000000 --- a/tools/export/codered/arch_pro_project.tmpl +++ /dev/null @@ -1 +0,0 @@ -{% extends "codered_project_common.tmpl" %} diff --git a/tools/export/codered/cproject_cortexm0_common.tmpl b/tools/export/codered/cproject_cortexm0_common.tmpl deleted file mode 100644 index 895485f3bc..0000000000 --- a/tools/export/codered/cproject_cortexm0_common.tmpl +++ /dev/null @@ -1,3 +0,0 @@ -{% extends "codered_cproject_common.tmpl" %} - -{% block core %}cm0{% endblock %} diff --git a/tools/export/codered/cproject_cortexm3_common.tmpl b/tools/export/codered/cproject_cortexm3_common.tmpl deleted file mode 100644 index 894afaae0d..0000000000 --- a/tools/export/codered/cproject_cortexm3_common.tmpl +++ /dev/null @@ -1,3 +0,0 @@ -{% extends "codered_cproject_common.tmpl" %} - -{% block core %}cm3{% endblock %} diff --git a/tools/export/codered/lpc1114_project.tmpl b/tools/export/codered/lpc1114_project.tmpl deleted file mode 100644 index d77c507eb0..0000000000 --- a/tools/export/codered/lpc1114_project.tmpl +++ /dev/null @@ -1 +0,0 @@ -{% extends "codered_project_common.tmpl" %} diff --git a/tools/export/codered/lpc11u35_401_project.tmpl b/tools/export/codered/lpc11u35_401_project.tmpl deleted file mode 100644 index d77c507eb0..0000000000 --- a/tools/export/codered/lpc11u35_401_project.tmpl +++ /dev/null @@ -1 +0,0 @@ -{% extends "codered_project_common.tmpl" %} diff --git a/tools/export/codered/lpc11u35_501_project.tmpl b/tools/export/codered/lpc11u35_501_project.tmpl deleted file mode 100644 index d77c507eb0..0000000000 --- a/tools/export/codered/lpc11u35_501_project.tmpl +++ /dev/null @@ -1 +0,0 @@ -{% extends "codered_project_common.tmpl" %} diff --git a/tools/export/codered/lpc11u37h_401_project.tmpl b/tools/export/codered/lpc11u37h_401_project.tmpl deleted file mode 100644 index d77c507eb0..0000000000 --- a/tools/export/codered/lpc11u37h_401_project.tmpl +++ /dev/null @@ -1 +0,0 @@ -{% extends "codered_project_common.tmpl" %} diff --git a/tools/export/codered/lpc11u68_project.tmpl b/tools/export/codered/lpc11u68_project.tmpl deleted file mode 100644 index d77c507eb0..0000000000 --- a/tools/export/codered/lpc11u68_project.tmpl +++ /dev/null @@ -1 +0,0 @@ -{% extends "codered_project_common.tmpl" %} diff --git a/tools/export/codered/lpc1549_project.tmpl b/tools/export/codered/lpc1549_project.tmpl deleted file mode 100644 index d77c507eb0..0000000000 --- a/tools/export/codered/lpc1549_project.tmpl +++ /dev/null @@ -1 +0,0 @@ -{% extends "codered_project_common.tmpl" %} diff --git a/tools/export/codered/lpc1768_project.tmpl b/tools/export/codered/lpc1768_project.tmpl deleted file mode 100644 index d77c507eb0..0000000000 --- a/tools/export/codered/lpc1768_project.tmpl +++ /dev/null @@ -1 +0,0 @@ -{% extends "codered_project_common.tmpl" %} diff --git a/tools/export/codered/lpc4088_dm_project.tmpl b/tools/export/codered/lpc4088_dm_project.tmpl deleted file mode 100644 index d77c507eb0..0000000000 --- a/tools/export/codered/lpc4088_dm_project.tmpl +++ /dev/null @@ -1 +0,0 @@ -{% extends "codered_project_common.tmpl" %} diff --git a/tools/export/codered/lpc4088_project.tmpl b/tools/export/codered/lpc4088_project.tmpl deleted file mode 100644 index d77c507eb0..0000000000 --- a/tools/export/codered/lpc4088_project.tmpl +++ /dev/null @@ -1 +0,0 @@ -{% extends "codered_project_common.tmpl" %} diff --git a/tools/export/codered/lpc4330_m4_project.tmpl b/tools/export/codered/lpc4330_m4_project.tmpl deleted file mode 100644 index d77c507eb0..0000000000 --- a/tools/export/codered/lpc4330_m4_project.tmpl +++ /dev/null @@ -1 +0,0 @@ -{% extends "codered_project_common.tmpl" %} diff --git a/tools/export/codered/lpc824_project.tmpl b/tools/export/codered/lpc824_project.tmpl deleted file mode 100644 index d77c507eb0..0000000000 --- a/tools/export/codered/lpc824_project.tmpl +++ /dev/null @@ -1 +0,0 @@ -{% extends "codered_project_common.tmpl" %} diff --git a/tools/export/codered/lpccappuccino_project.tmpl b/tools/export/codered/lpccappuccino_project.tmpl deleted file mode 100644 index d77c507eb0..0000000000 --- a/tools/export/codered/lpccappuccino_project.tmpl +++ /dev/null @@ -1 +0,0 @@ -{% extends "codered_project_common.tmpl" %} diff --git a/tools/export/codered/ublox_c027_project.tmpl b/tools/export/codered/ublox_c027_project.tmpl deleted file mode 100644 index d77c507eb0..0000000000 --- a/tools/export/codered/ublox_c027_project.tmpl +++ /dev/null @@ -1 +0,0 @@ -{% extends "codered_project_common.tmpl" %} diff --git a/tools/export/gnuarmeclipse/.cproject.tmpl b/tools/export/gnuarmeclipse/.cproject.tmpl new file mode 100644 index 0000000000..965510b087 --- /dev/null +++ b/tools/export/gnuarmeclipse/.cproject.tmpl @@ -0,0 +1,414 @@ + + + + + + {% for cfg_key in options %} + {% set opts = options[cfg_key] %} + + + + + + + + + + + + + + + + + + + + + + + + + + {% endfor %} + + + + + + + {% for cfg_key in options %} + {% set opts = options[cfg_key] %} + + + + {% endfor %} + {% for cfg_key in options %} + {% set opts = options[cfg_key] %} + + + + {% endfor %} + + + + diff --git a/tools/export/gnuarmeclipse/.project.tmpl b/tools/export/gnuarmeclipse/.project.tmpl new file mode 100644 index 0000000000..cc88934389 --- /dev/null +++ b/tools/export/gnuarmeclipse/.project.tmpl @@ -0,0 +1,28 @@ + + + + {{name}} + This file was automagically generated by mbed.org. For more information, see http://mbed.org/handbook/Exporting-To-GNU-ARM-Eclipse + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/tools/export/gnuarmeclipse/NOTES.md b/tools/export/gnuarmeclipse/NOTES.md new file mode 100644 index 0000000000..6c3068eec8 --- /dev/null +++ b/tools/export/gnuarmeclipse/NOTES.md @@ -0,0 +1,488 @@ +# GNU ARM Eclipse + +The [GNU ARM Eclipse](http://gnuarmeclipse.github.io) is an open source project that includes a family of Eclipse plug-ins and tools for multi-platform embedded ARM development, based on GNU toolchains. The project is hosted on [GitHub](https://github.com/gnuarmeclipse). + +This exporter aims to create managed GNU ARM Eclipse projects, ready to build, and with as many options properly identified and set in the Eclipse C/C++ Build -> Settings page. + +## Build plug-in configuration options + +All options are prefixed by `ilg.gnuarmeclipse.managedbuild.cross.option.`. + +### Target Processor + +- `arm.target.family` enumerated + - **ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.mcpu.cortex-m3** '-mcpu=cortex-m3' + - cortex-m0 '-mcpu=%s' + - cortex-m0-small-multiply '-mcpu=%s' + - cortex-m0plus '-mcpu=%s' + - cortex-m0plus-small-multiply '-mcpu=%s' + - cortex-m1 '-mcpu=%s' + - cortex-m1-small-multiply '-mcpu=%s' + - cortex-m4 '-mcpu=%s' + - cortex-m7 '-mcpu=%s' + +- `arm.target.architecture` enumerated + - **ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.arch.none** '' + - armv6-m '-march=%s' + - armv7-m '-march=%s' + +- `arm.target.instructionset` enumerated + - **ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset.thumb** '-mthumb' + - arm '-marm' + +- `arm.target.thumbinterwork` bool + - true `-mthumb-interwork` + +- `arm.target.endianness` enumerated + - **ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.endianness.default** + - little `-mlittle-endian` + - big `-mbig-endian` + +- `arm.target.fpu.abi` enumerated + - **ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.abi.default** + - soft '-mfloat-abi=soft' + - softfp '-mfloat-abi=softfp' + - hard '-mfloat-abi=hard' + +- `arm.target.fpu.unit` enumerated + - **ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.unit.default** + - fpv4spd16 '-mfpu=fpv4-sp-d16' + - fpv5d16 '-mfpu=fpv5-d16' + - fpv5spd16 '-mfpu=fpv5-sp-d16' + - ... + +- `arm.target.unalignedaccess` + - **ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.unalignedaccess.default** + - enabled '-munaligned-access' + - disabled '-mno-unaligned-access' + +- `target.other` string + +### Optimization + +- `optimization.level` enumerated + - **ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.more** '-O2' + - none '-O0' + - optimize '-O1' + - most '-O3' + - size '-Os' + - debug '-Og' + +- `optimization.messagelength` bool + - **false** '' + - true '-fmessage-length=0' + +- `optimization.signedchar` bool + - **false** + - true '-fsigned-char' + +- `optimization.functionsections` bool + - **false** + - true '-ffunction-sections' + +- `optimization.datasections` bool + - **false** + - true '-fdata-sections' + +- `optimization.nocommon` bool + - **false** + - true '-fno-common' + +- `optimization.noinlinefunctions` bool + - **false** '' + - true '-fno-inline-functions' + +- `optimization.freestanding` bool + - **false** '' + - true '-ffreestanding' + +- `optimization.nobuiltin` bool + - **false** '' + - true '-fno-builtin' + +- `optimization.spconstant` bool + - **false** '' + - true '-fsingle-precision-constant' + +- `optimization.PIC` bool + - **false** '' + - true '-fPIC' + +- `optimization.lto` bool + - **false** '' + - true '-flto' + +- `optimization.nomoveloopinvariants` bool + - **false** '' + - true '-fno-move-loop-invariants' + +- `optimization.other` string + +- `` bool + - **false** '' + - true '' + +### Warnings + +- `warnings.syntaxonly` bool + - **false** '' + - true '-fsyntax-only' + +- `warnings.pedantic` bool + - **false** '' + - true '-pedantic' + +- `warnings.pedanticerrors` bool + - **false** '' + - true '-pedantic-errors' + +- `warnings.nowarn` bool + - **false** '' + - true '-w' + +- `warnings.unused` bool + - **false** '' + - true '-Wunused' + +- `warnings.uninitialized` bool + - **false** '' + - true '-Wuninitialized' + +- `warnings.allwarn` bool + - **false** '' + - true '-Wall' + +- `warnings.extrawarn` bool + - **false** '' + - true '-Wextra' + +- `warnings.missingdeclaration` bool + - **false** '' + - true '-Wmissing-declarations' + +- `warnings.conversion` bool + - **false** '' + - true '-Wconversion' + +- `warnings.pointerarith` bool + - **false** '' + - true '-Wpointer-arith' + +- `warnings.padded` bool + - **false** '' + - true '-Wpadded' + +- `warnings.shadow` bool + - **false** '' + - true '-Wshadow' + +- `warnings.logicalop` bool + - **false** '' + - true '-Wlogical-op' + +- `warnings.agreggatereturn` bool + - **false** '' + - true '-Waggregate-return' + +- `warnings.floatequal` bool + - **false** '' + - true '-Wfloat-equal' + +- `warnings.toerrors` bool + - **false** '' + - true '-Werror' + +- `warnings.other` string + +### Debugging + +- `debugging.level` enumerated + - **ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level.default** '-g' + - none '' + - minimal '-g1' + - max '-g3' + +- `debugging.format` enumerated + - **ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format.default** '' + - gdb '-ggdb' + - stabs '-gstabs' + - stabsplus '-gstabs+' + - dwarf2 '-gdwarf-2' + - dwarf3 '-gdwarf-3' + - dwarf4 '-gdwarf-4' + - dwarf5 '-gdwarf-5' + +- `debugging.prof` bool + - **false** '' + - true '-p' + +- `debugging.gprof` bool + - **false** '' + - true '-pg' + +- `debugging.other` string + + +### Compiler common options + +- `verbose` bool + - **false** '' + - true '-v' + +- `savetemps` bool + - **false** '' + - true '--save-temps' + +- `nostdinc` bool + - **false** '' + - true '-nostdinc' + +- `asmlisting` bool + - **false** '' + - true '-Wa,-adhlns="$@.lst"' + +- `preprocessor.preprocessonly` bool + - **false** '' + - true '-E' + +- `dirs.include.files` + - '-include%s' + +- `compiler.other` string + +### Linker common options + +- `mapfilename` string + - '-Wl,-Map,"${BuildArtifactFileBaseName}.map"' + +- `linker.scriptfile` + - '-T %s' + +- `cref` bool + - **false** '' + - true '-Xlinker --cref' + +- `printmap` bool + - **false** '' + - true '-Xlinker --print-map' + +- `linker.nostart` bool + - **false** '' + - true '-nostartfiles' + +- `linker.nodeflibs` bool + - **false** '' + - true '-nodefaultlibs' + +- `linker.nostdlibs` bool + - **false** '' + - true '-nostdlib' + +- `linker.gcsections` bool + - **false** '' + - true '-Xlinker --gc-sections' + +- `linker.printgcsections` bool + - **false** '' + - true '-Xlinker --print-gc-sections' + +- `linker.strip` bool + - **false** '' + - true '-s' + +- `linker.other` string + +- `linker.usenewlibnano` bool + - **false** '' + - true '--specs=nano.specs' + +- `linker.useprintffloat` bool + - **false** '' + - true '-u \_printf\_float' + +- `linker.usescanffloat` bool + - **false** '' + - true '-u \_scanf\_float' + + +### Cross ARM GNU Assembler + +#### Preprocessor + +- `nostdinc` bool + - **false** '' + - true '-nostdinc' + +#### Includes + +#### Warnings + +#### Miscellaneous + +- `verbose` bool + - **false** '' + - true '-v' + +- `assembler.other` string + +### Cross ARM GNU C Compiler + +#### Preprocessor + +- `nostdinc` bool + - **false** '' + - true '-nostdinc' + +#### Includes + +#### Optimization + +- `c.compiler.std` enumerated + - **ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.std.default** '' + - ansi '-ansi' + - c90 '-std=c90' (c89) + - gnu90 '-std=gnu90' (gnu89) + - c99 '-std=c99' (c9x) + - gnu99 '-std=gnu99' (gnu9x) + - c11 '-std=c11' (c1x) + - gnu11 '-std=gnu11' (gnu1x) + +#### Warnings + +- `c.compiler.warning.missingprototypes` bool + - **false** '' + - true '-Wmissing-prototypes' + +- `c.compiler.warning.strictprototypes` bool + - **false** '' + - true '-Wstrict-prototypes' + +- `c.compiler.warning.badfunctioncast` bool + - **false** '' + - true '-Wbad-function-cast' + +#### Miscellaneous + +- `verbose` bool + - **false** '' + - true '-v' + +- `c.compiler.other` string + +### Cross ARM GNU C++ Compiler + +#### Preprocessor + +- `nostdinc` bool + - **false** '' + - true '-nostdinc' + +- `nostdincpp` bool + - **false** '' + - true '-nostdinc++' + +#### Includes + +#### Optimization + +- `cpp.compiler.std` enumerated + - **ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.std.default** '' + - ansi (-ansi) + - cpp98 '-std=c++98' (c++03) + - gnucpp98 '-std=gnu++98' (gnu++03) + - cpp0x '-std=c++0x' + - gnucpp0x '-std=gnu++0x' + - cpp11 '-std=c++11' + - gnucpp11 '-std=gnu++11' + - cpp1y '-std=c++1y' + - gnucpp1y '-std=gnu++1y' + - cpp14 '-std=c++14' + - gnucpp1 4'-std=gnu++14' + - cpp1z '-std=c++1z' + - gnucpp1z '-std=gnu++1z' + +- `cpp.compiler.abiversion` enumerated + - **ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.abiversion.0** '-fabi-version=0' + - default '' + - 1 '-fabi-version=1' + - 2 '-fabi-version=2' + - 3 '-fabi-version=3' + - 4 '-fabi-version=4' + - 5 '-fabi-version=5' + - 6 '-fabi-version=6' + +- `cpp.compiler.noexceptions` bool + - **false** '' + - true '-fno-exceptions' + +- `cpp.compiler.nortti` bool + - **false** '' + - true '-fno-rtti' + +- `cpp.compiler.nousecxaatexit` bool + - **false** '' + - true '-fno-use-cxa-atexit' + +- `cpp.compiler.nothreadsafestatics` bool + - **false** '' + - true '-fno-threadsafe-statics' + + +#### Warnings + +- `cpp.compiler.warnabi` bool + - **false** '-Wabi' + +- `cpp.compiler.warning.ctordtorprivacy` bool + - **false** '-Wctor-dtor-privacy' + +- `cpp.compiler.warning.noexcept` bool + - **false** '-Wnoexcept' + +- `cpp.compiler.warning.nonvirtualdtor` bool + - **false** '-Wnon-virtual-dtor' + +- `cpp.compiler.warning.strictnullsentinel` bool + - **false** '-Wstrict-null-sentinel' + +- `cpp.compiler.warning.signpromo` bool + - **false** '-Wsign-promo' + +- `cpp.compiler.warneffc` bool + - **false** '' + - true '-Weffc++' + +#### Miscellaneous + +- `verbose` bool + - **false** '' + - true '-v' + +- `cpp.compiler.other` string + +### Cross ARM GNU C++ Linker + +#### General + +- `cpp.linker.nostart` + - **false** '' + - true '-nostartfiles' + +- `cpp.linker.nodeflibs` + - **false** '' + - true '-nodefaultlibs' + +- `cpp.linker.nostdlibs` + - **false** '' + - true '-nostdlib' + +#### Libraries + +#### Miscellaneous + + +## Template + +- `` bool + - **false** '' + - true '' diff --git a/tools/export/gnuarmeclipse/__init__.py b/tools/export/gnuarmeclipse/__init__.py new file mode 100644 index 0000000000..ced50dec4c --- /dev/null +++ b/tools/export/gnuarmeclipse/__init__.py @@ -0,0 +1,1060 @@ +""" +mbed SDK +Copyright (c) 2011-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. + +Title: GNU ARM Eclipse (http://gnuarmeclipse.github.io) exporter. + +Description: Creates a managed build project that can be imported by +the GNU ARM Eclipse plug-ins. + +Author: Liviu Ionescu +""" + +import os +import copy +import tempfile +import shutil +import copy + +from subprocess import call, Popen, PIPE +from os.path import splitext, basename, relpath, dirname, exists, join, dirname +from random import randint +from json import load + +from tools.export.exporters import Exporter +from tools.options import list_profiles +from tools.targets import TARGET_MAP +from tools.utils import NotSupportedException +from tools.build_api import prepare_toolchain + +# ============================================================================= + + +class UID: + """ + Helper class, used to generate unique ids required by .cproject symbols. + """ + @property + def id(self): + return "%0.9u" % randint(0, 999999999) + +# Global UID generator instance. +# Passed to the template engine, and referred as {{u.id}}. +# Each invocation generates a new number. +u = UID() + +# ============================================================================= + + +class GNUARMEclipse(Exporter): + NAME = 'GNU ARM Eclipse' + TOOLCHAIN = 'GCC_ARM' + + # Indirectly support all GCC_ARM targets. + TARGETS = [target for target, obj in TARGET_MAP.iteritems() + if 'GCC_ARM' in obj.supported_toolchains] + + # override + @property + def flags(self): + """Returns a dictionary of toolchain flags. + Keys of the dictionary are: + cxx_flags - c++ flags + c_flags - c flags + ld_flags - linker flags + asm_flags - assembler flags + common_flags - common options + + The difference from the parent function is that it does not + add macro definitions, since they are passed separately. + """ + + config_header = self.toolchain.get_config_header() + flags = {key + "_flags": copy.deepcopy(value) for key, value + in self.toolchain.flags.iteritems()} + if config_header: + config_header = relpath(config_header, + self.resources.file_basepath[config_header]) + flags['c_flags'] += self.toolchain.get_config_option(config_header) + flags['cxx_flags'] += self.toolchain.get_config_option( + config_header) + return flags + + def toolchain_flags(self, toolchain): + """Returns a dictionary of toolchain flags. + Keys of the dictionary are: + cxx_flags - c++ flags + c_flags - c flags + ld_flags - linker flags + asm_flags - assembler flags + common_flags - common options + + The difference from the above is that it takes a parameter. + """ + + # Note: use the config options from the currently selected toolchain. + config_header = self.toolchain.get_config_header() + + flags = {key + "_flags": copy.deepcopy(value) for key, value + in toolchain.flags.iteritems()} + if config_header: + config_header = relpath(config_header, + self.resources.file_basepath[config_header]) + header_options = self.toolchain.get_config_option(config_header) + flags['c_flags'] += header_options + flags['cxx_flags'] += header_options + return flags + + # override + def generate(self): + """ + Generate the .project and .cproject files. + """ + if not self.resources.linker_script: + raise NotSupportedException("No linker script found.") + + print + print 'Create a GNU ARM Eclipse C++ managed project' + print 'Project name: {0}'.format(self.project_name) + print 'Target: {0}'.format(self.toolchain.target.name) + print 'Toolchain: {0}'.format(self.TOOLCHAIN) + + self.resources.win_to_unix() + + # TODO: use some logger to display additional info if verbose + + libraries = [] + # print 'libraries' + # print self.resources.libraries + for lib in self.resources.libraries: + l, _ = splitext(basename(lib)) + libraries.append(l[3:]) + + self.system_libraries = [ + 'stdc++', 'supc++', 'm', 'c', 'gcc', 'nosys' + ] + + # Read in all profiles, we'll extract compiler options. + profiles = self.get_all_profiles() + + profile_ids = [s.lower() for s in profiles] + profile_ids.sort() + + # TODO: get the list from existing .cproject + build_folders = [s.capitalize() for s in profile_ids] + build_folders.append('BUILD') + # print build_folders + + objects = [self.filter_dot(s) for s in self.resources.objects] + for bf in build_folders: + objects = [o for o in objects if not o.startswith(bf + '/')] + # print 'objects' + # print objects + + self.compute_exclusions() + + self.include_path = [ + self.filter_dot(s) for s in self.resources.inc_dirs] + print 'Include folders: {0}'.format(len(self.include_path)) + + self.as_defines = self.toolchain.get_symbols(True) + self.c_defines = self.toolchain.get_symbols() + self.cpp_defines = self.c_defines + print 'Symbols: {0}'.format(len(self.c_defines)) + + self.ld_script = self.filter_dot( + self.resources.linker_script) + print 'Linker script: {0}'.format(self.ld_script) + + self.options = {} + for id in profile_ids: + + # There are 4 categories of options, a category common too + # all tools and a specific category for each of the tools. + opts = {} + opts['common'] = {} + opts['as'] = {} + opts['c'] = {} + opts['cpp'] = {} + opts['ld'] = {} + + opts['id'] = id + opts['name'] = opts['id'].capitalize() + + print + print 'Build configuration: {0}'.format(opts['name']) + + profile = profiles[id] + profile_toolchain = profile[self.TOOLCHAIN] + + # A small hack, do not bother with src_path again, + # pass an empty string to avoid crashing. + src_paths = [''] + target_name = self.toolchain.target.name + toolchain = prepare_toolchain( + src_paths, target_name, self.TOOLCHAIN, build_profile=profile_toolchain) + + # Hack to fill in build_dir + toolchain.build_dir = self.toolchain.build_dir + + flags = self.toolchain_flags(toolchain) + + print 'Common flags:', ' '.join(flags['common_flags']) + print 'C++ flags:', ' '.join(flags['cxx_flags']) + print 'C flags:', ' '.join(flags['c_flags']) + print 'ASM flags:', ' '.join(flags['asm_flags']) + print 'Linker flags:', ' '.join(flags['ld_flags']) + + # Most GNU ARM Eclipse options have a parent, + # either debug or release. + if '-O0' in flags['common_flags'] or '-Og' in flags['common_flags']: + opts['parent_id'] = 'debug' + else: + opts['parent_id'] = 'release' + + self.process_options(opts, flags) + + opts['as']['defines'] = self.as_defines + opts['c']['defines'] = self.c_defines + opts['cpp']['defines'] = self.cpp_defines + + opts['common']['include_paths'] = self.include_path + opts['common']['excluded_folders'] = '|'.join( + self.excluded_folders) + + opts['ld']['library_paths'] = [ + self.filter_dot(s) for s in self.resources.lib_dirs] + + opts['ld']['object_files'] = objects + opts['ld']['user_libraries'] = libraries + opts['ld']['system_libraries'] = self.system_libraries + opts['ld']['script'] = self.ld_script + + # Unique IDs used in multiple places. + # Those used only once are implemented with {{u.id}}. + uid = {} + uid['config'] = u.id + uid['tool_c_compiler'] = u.id + uid['tool_c_compiler_input'] = u.id + uid['tool_cpp_compiler'] = u.id + uid['tool_cpp_compiler_input'] = u.id + + opts['uid'] = uid + + self.options[id] = opts + + jinja_ctx = { + 'name': self.project_name, + + # Compiler & linker command line options + 'options': self.options, + + # Must be an object with an `id` property, which + # will be called repeatedly, to generate multiple UIDs. + 'u': u, + } + + # TODO: it would be good to have jinja stop if one of the + # expected context values is not defined. + self.gen_file('gnuarmeclipse/.project.tmpl', jinja_ctx, + '.project', trim_blocks=True, lstrip_blocks=True) + self.gen_file('gnuarmeclipse/.cproject.tmpl', jinja_ctx, + '.cproject', trim_blocks=True, lstrip_blocks=True) + self.gen_file('gnuarmeclipse/makefile.targets.tmpl', jinja_ctx, + 'makefile.targets', trim_blocks=True, lstrip_blocks=True) + + if not exists('.mbedignore'): + print + print 'Create .mbedignore' + with open('.mbedignore', 'w') as f: + for bf in build_folders: + print bf + '/' + f.write(bf + '/\n') + + print + print 'Done. Import the \'{0}\' project in Eclipse.'.format(self.project_name) + + # override + @staticmethod + def build(project_name, log_name="build_log.txt", cleanup=True): + """ + Headless build an Eclipse project. + + The following steps are performed: + - a temporary workspace is created, + - the project is imported, + - a clean build of all configurations is performed and + - the temporary workspace is removed. + + The build results are in the Debug & Release folders. + + All executables (eclipse & toolchain) must be in the PATH. + + The general method to start a headless Eclipse build is: + + $ eclipse \ + --launcher.suppressErrors \ + -nosplash \ + -application org.eclipse.cdt.managedbuilder.core.headlessbuild \ + -data /path/to/workspace \ + -import /path/to/project \ + -cleanBuild "project[/configuration] | all" + """ + + # TODO: possibly use the log file. + + # Create a temporary folder for the workspace. + tmp_folder = tempfile.mkdtemp() + + cmd = [ + 'eclipse', + '--launcher.suppressErrors', + '-nosplash', + '-application org.eclipse.cdt.managedbuilder.core.headlessbuild', + '-data', tmp_folder, + '-import', os.getcwd(), + '-cleanBuild', project_name + ] + + p = Popen(' '.join(cmd), shell=True, stdout=PIPE, stderr=PIPE) + out, err = p.communicate() + ret_code = p.returncode + stdout_string = "=" * 10 + "STDOUT" + "=" * 10 + "\n" + err_string = "=" * 10 + "STDERR" + "=" * 10 + "\n" + err_string += err + + ret_string = "SUCCESS\n" + if ret_code != 0: + ret_string += "FAILURE\n" + + print "%s\n%s\n%s\n%s" % (stdout_string, out, err_string, ret_string) + + if log_name: + # Write the output to the log file + with open(log_name, 'w+') as f: + f.write(stdout_string) + f.write(out) + f.write(err_string) + f.write(ret_string) + + # Cleanup the exported and built files + if cleanup: + if exists(log_name): + os.remove(log_name) + os.remove('.project') + os.remove('.cproject') + if exists('Debug'): + shutil.rmtree('Debug') + if exists('Release'): + shutil.rmtree('Release') + if exists('makefile.targets'): + os.remove('makefile.targets') + + # Always remove the temporary folder. + if exists(tmp_folder): + shutil.rmtree(tmp_folder) + + if ret_code == 0: + # Return Success + return 0 + + # Seems like something went wrong. + return -1 + + # ------------------------------------------------------------------------- + + @staticmethod + def get_all_profiles(): + tools_path = dirname(dirname(dirname(__file__))) + file_names = [join(tools_path, "profiles", fn) for fn in os.listdir( + join(tools_path, "profiles")) if fn.endswith(".json")] + + # print file_names + + profile_names = [basename(fn).replace(".json", "") + for fn in file_names] + # print profile_names + + profiles = {} + + for fn in file_names: + content = load(open(fn)) + profile_name = basename(fn).replace(".json", "") + profiles[profile_name] = content + + return profiles + + # ------------------------------------------------------------------------- + # Process source files/folders exclusions. + + def compute_exclusions(self): + """ + With the project root as the only source folder known to CDT, + based on the list of source files, compute the folders to not + be included in the build. + + The steps are: + - get the list of source folders, as dirname(source_file) + - compute the top folders (subfolders of the project folder) + - iterate all subfolders and add them to a tree, with all + nodes markes as 'not used' + - iterate the source folders and mark them as 'used' in the + tree, including all intermediate nodes + - recurse the tree and collect all unused folders; descend + the hierarchy only for used nodes + """ + source_folders = [self.filter_dot(s) for s in set(dirname( + src) for src in self.resources.c_sources + self.resources.cpp_sources + self.resources.s_sources)] + if '.' in source_folders: + source_folders.remove('.') + + # print 'source folders' + # print source_folders + + # Source folders were converted before and are guaranteed to + # use the POSIX separator. + top_folders = [f for f in set(s.split('/')[0] + for s in source_folders)] + # print 'top folders' + # print top_folders + + self.source_tree = {} + for top_folder in top_folders: + for root, dirs, files in os.walk(top_folder, topdown=True): + # print root, dirs, files + + # Paths returned by os.walk() must be split with os.dep + # to accomodate Windows weirdness. + parts = root.split(os.sep) + + # Ignore paths that include parts starting with dot. + skip = False + for part in parts: + if part.startswith('.'): + skip = True + break + if skip: + continue + + # Further process only leaf paths, (that do not have + # sub-folders). + if len(dirs) == 0: + # The path is reconstructed using POSIX separators. + self.add_source_folder_to_tree('/'.join(parts)) + + for folder in source_folders: + self.add_source_folder_to_tree(folder, True) + + # print + # print self.source_tree + # self.dump_paths(self.source_tree) + # self.dump_tree(self.source_tree) + + # print 'excludings' + self.excluded_folders = ['BUILD'] + self.recurse_excludings(self.source_tree) + + print 'Source folders: {0}, with {1} exclusions'.format(len(source_folders), len(self.excluded_folders)) + + def add_source_folder_to_tree(self, path, is_used=False): + """ + Decompose a path in an array of folder names and create the tree. + On the second pass the nodes should be already there; mark them + as used. + """ + # print path, is_used + + # All paths arriving here are guaranteed to use the POSIX + # separators, os.walk() paths were also explicitly converted. + parts = path.split('/') + # print parts + node = self.source_tree + prev = None + for part in parts: + if part not in node.keys(): + new_node = {} + new_node['name'] = part + new_node['children'] = {} + if prev != None: + new_node['parent'] = prev + node[part] = new_node + node[part]['is_used'] = is_used + prev = node[part] + node = node[part]['children'] + + def recurse_excludings(self, nodes): + """ + Recurse the tree and collect all unused folders; descend + the hierarchy only for used nodes. + """ + for k in nodes.keys(): + node = nodes[k] + if node['is_used'] == False: + parts = [] + cnode = node + while True: + parts.insert(0, cnode['name']) + if 'parent' not in cnode: + break + cnode = cnode['parent'] + + # Compose a POSIX path. + path = '/'.join(parts) + # print path + self.excluded_folders.append(path) + else: + self.recurse_excludings(node['children']) + + # ------------------------------------------------------------------------- + + @staticmethod + def filter_dot(str): + """ + Remove the './' prefix, if present. + This function assumes that resources.win_to_unix() + replaced all windows backslashes with slashes. + """ + if str == None: + return None + if str[:2] == './': + return str[2:] + return str + + # ------------------------------------------------------------------------- + + def dump_tree(self, nodes, depth=0): + for k in nodes.keys(): + node = nodes[k] + parent_name = node['parent'][ + 'name'] if 'parent' in node.keys() else '' + print ' ' * depth, node['name'], node['is_used'], parent_name + if len(node['children'].keys()) != 0: + self.dump_tree(node['children'], depth + 1) + + def dump_paths(self, nodes, depth=0): + for k in nodes.keys(): + node = nodes[k] + parts = [] + while True: + parts.insert(0, node['name']) + if 'parent' not in node: + break + node = node['parent'] + path = '/'.join(parts) + print path, nodes[k]['is_used'] + self.dump_paths(nodes[k]['children'], depth + 1) + + # ------------------------------------------------------------------------- + + def process_options(self, opts, flags_in): + """ + CDT managed projects store lots of build options in separate + variables, with separate IDs in the .cproject file. + When the CDT build is started, all these options are brought + together to compose the compiler and linker command lines. + + Here the process is reversed, from the compiler and linker + command lines, the options are identified and various flags are + set to control the template generation process. + + Once identified, the options are removed from the command lines. + + The options that were not identified are options that do not + have CDT equivalents and will be passed in the 'Other options' + categories. + + Although this process does not have a very complicated logic, + given the large number of explicit configuration options + used by the GNU ARM Eclipse managed build plug-in, it is tedious... + """ + + # Make a copy of the flags, to be one by one removed after processing. + flags = copy.deepcopy(flags_in) + + if False: + print + print 'common_flags', flags['common_flags'] + print 'asm_flags', flags['asm_flags'] + print 'c_flags', flags['c_flags'] + print 'cxx_flags', flags['cxx_flags'] + print 'ld_flags', flags['ld_flags'] + + # Initialise the 'last resort' options where all unrecognised + # options will be collected. + opts['as']['other'] = '' + opts['c']['other'] = '' + opts['cpp']['other'] = '' + opts['ld']['other'] = '' + + MCPUS = { + 'Cortex-M0': {'mcpu': 'cortex-m0', 'fpu_unit': None}, + 'Cortex-M0+': {'mcpu': 'cortex-m0plus', 'fpu_unit': None}, + 'Cortex-M1': {'mcpu': 'cortex-m1', 'fpu_unit': None}, + 'Cortex-M3': {'mcpu': 'cortex-m3', 'fpu_unit': None}, + 'Cortex-M4': {'mcpu': 'cortex-m4', 'fpu_unit': None}, + 'Cortex-M4F': {'mcpu': 'cortex-m4', 'fpu_unit': 'fpv4spd16'}, + 'Cortex-M7': {'mcpu': 'cortex-m7', 'fpu_unit': None}, + 'Cortex-M7F': {'mcpu': 'cortex-m7', 'fpu_unit': 'fpv4spd16'}, + 'Cortex-M7FD': {'mcpu': 'cortex-m7', 'fpu_unit': 'fpv5d16'}, + 'Cortex-A9': {'mcpu': 'cortex-a9', 'fpu_unit': 'vfpv3'} + } + + # Remove options that are supplied by CDT + self.remove_option(flags['common_flags'], '-c') + self.remove_option(flags['common_flags'], '-MMD') + + # As 'plan B', get the CPU from the target definition. + core = self.toolchain.target.core + + opts['common']['arm.target.family'] = None + + # cortex-m0, cortex-m0-small-multiply, cortex-m0plus, + # cortex-m0plus-small-multiply, cortex-m1, cortex-m1-small-multiply, + # cortex-m3, cortex-m4, cortex-m7. + str = self.find_options(flags['common_flags'], '-mcpu=') + if str != None: + opts['common']['arm.target.family'] = str[len('-mcpu='):] + self.remove_option(flags['common_flags'], str) + self.remove_option(flags['ld_flags'], str) + else: + if core not in MCPUS: + raise NotSupportedException( + 'Target core {0} not supported.'.format(core)) + opts['common']['arm.target.family'] = MCPUS[core]['mcpu'] + + opts['common']['arm.target.arch'] = 'none' + str = self.find_options(flags['common_flags'], '-march=') + arch = str[len('-march='):] + archs = {'armv6-m': 'armv6-m', 'armv7-m': 'armv7-m', 'armv7-a': 'armv7-a'} + if arch in archs: + opts['common']['arm.target.arch'] = archs[arch] + self.remove_option(flags['common_flags'], str) + + opts['common']['arm.target.instructionset'] = 'thumb' + if '-mthumb' in flags['common_flags']: + self.remove_option(flags['common_flags'], '-mthumb') + self.remove_option(flags['ld_flags'], '-mthumb') + elif '-marm' in flags['common_flags']: + opts['common']['arm.target.instructionset'] = 'arm' + self.remove_option(flags['common_flags'], '-marm') + self.remove_option(flags['ld_flags'], '-marm') + + opts['common']['arm.target.thumbinterwork'] = False + if '-mthumb-interwork' in flags['common_flags']: + opts['common']['arm.target.thumbinterwork'] = True + self.remove_option(flags['common_flags'], '-mthumb-interwork') + + opts['common']['arm.target.endianness'] = None + if '-mlittle-endian' in flags['common_flags']: + opts['common']['arm.target.endianness'] = 'little' + self.remove_option(flags['common_flags'], '-mlittle-endian') + elif '-mbig-endian' in flags['common_flags']: + opts['common']['arm.target.endianness'] = 'big' + self.remove_option(flags['common_flags'], '-mbig-endian') + + opts['common']['arm.target.fpu.unit'] = None + # default, fpv4spd16, fpv5d16, fpv5spd16 + str = self.find_options(flags['common_flags'], '-mfpu=') + if str != None: + fpu = str[len('-mfpu='):] + fpus = { + 'fpv4-sp-d16': 'fpv4spd16', + 'fpv5-d16': 'fpv5d16', + 'fpv5-sp-d16': 'fpv5spd16' + } + if fpu in fpus: + opts['common']['arm.target.fpu.unit'] = fpus[fpu] + + self.remove_option(flags['common_flags'], str) + self.remove_option(flags['ld_flags'], str) + if opts['common']['arm.target.fpu.unit'] == None: + if core not in MCPUS: + raise NotSupportedException( + 'Target core {0} not supported.'.format(core)) + if MCPUS[core]['fpu_unit']: + opts['common'][ + 'arm.target.fpu.unit'] = MCPUS[core]['fpu_unit'] + + # soft, softfp, hard. + str = self.find_options(flags['common_flags'], '-mfloat-abi=') + if str != None: + opts['common']['arm.target.fpu.abi'] = str[ + len('-mfloat-abi='):] + self.remove_option(flags['common_flags'], str) + self.remove_option(flags['ld_flags'], str) + + opts['common']['arm.target.unalignedaccess'] = None + if '-munaligned-access' in flags['common_flags']: + opts['common']['arm.target.unalignedaccess'] = 'enabled' + self.remove_option(flags['common_flags'], '-munaligned-access') + elif '-mno-unaligned-access' in flags['common_flags']: + opts['common']['arm.target.unalignedaccess'] = 'disabled' + self.remove_option(flags['common_flags'], '-mno-unaligned-access') + + # Default optimisation level for Release. + opts['common']['optimization.level'] = '-Os' + + # If the project defines an optimisation level, it is used + # only for the Release configuration, the Debug one used '-Og'. + str = self.find_options(flags['common_flags'], '-O') + if str != None: + levels = { + '-O0': 'none', '-O1': 'optimize', '-O2': 'more', + '-O3': 'most', '-Os': 'size', '-Og': 'debug' + } + if str in levels: + opts['common']['optimization.level'] = levels[str] + self.remove_option(flags['common_flags'], str) + + include_files = [] + for all_flags in [flags['common_flags'], flags['c_flags'], flags['cxx_flags']]: + while '-include' in all_flags: + ix = all_flags.index('-include') + str = all_flags[ix + 1] + if str not in include_files: + include_files.append(str) + self.remove_option(all_flags, '-include') + self.remove_option(all_flags, str) + + opts['common']['include_files'] = include_files + + if '-ansi' in flags['c_flags']: + opts['c']['compiler.std'] = '-ansi' + self.remove_option(flags['c_flags'], str) + else: + str = self.find_options(flags['c_flags'], '-std') + std = str[len('-std='):] + c_std = { + 'c90': 'c90', 'c89': 'c90', 'gnu90': 'gnu90', 'gnu89': 'gnu90', + 'c99': 'c99', 'c9x': 'c99', 'gnu99': 'gnu99', 'gnu9x': 'gnu98', + 'c11': 'c11', 'c1x': 'c11', 'gnu11': 'gnu11', 'gnu1x': 'gnu11' + } + if std in c_std: + opts['c']['compiler.std'] = c_std[std] + self.remove_option(flags['c_flags'], str) + + if '-ansi' in flags['cxx_flags']: + opts['cpp']['compiler.std'] = '-ansi' + self.remove_option(flags['cxx_flags'], str) + else: + str = self.find_options(flags['cxx_flags'], '-std') + std = str[len('-std='):] + cpp_std = { + 'c++98': 'cpp98', 'c++03': 'cpp98', + 'gnu++98': 'gnucpp98', 'gnu++03': 'gnucpp98', + 'c++0x': 'cpp0x', 'gnu++0x': 'gnucpp0x', + 'c++11': 'cpp11', 'gnu++11': 'gnucpp11', + 'c++1y': 'cpp1y', 'gnu++1y': 'gnucpp1y', + 'c++14': 'cpp14', 'gnu++14': 'gnucpp14', + 'c++1z': 'cpp1z', 'gnu++1z': 'gnucpp1z', + } + if std in cpp_std: + opts['cpp']['compiler.std'] = cpp_std[std] + self.remove_option(flags['cxx_flags'], str) + + # Common optimisation options. + optimization_options = { + '-fmessage-length=0': 'optimization.messagelength', + '-fsigned-char': 'optimization.signedchar', + '-ffunction-sections': 'optimization.functionsections', + '-fdata-sections': 'optimization.datasections', + '-fno-common': 'optimization.nocommon', + '-fno-inline-functions': 'optimization.noinlinefunctions', + '-ffreestanding': 'optimization.freestanding', + '-fno-builtin': 'optimization.nobuiltin', + '-fsingle-precision-constant': 'optimization.spconstant', + '-fPIC': 'optimization.PIC', + '-fno-move-loop-invariants': 'optimization.nomoveloopinvariants', + } + + for option in optimization_options: + opts['common'][optimization_options[option]] = False + if option in flags['common_flags']: + opts['common'][optimization_options[option]] = True + self.remove_option(flags['common_flags'], option) + + # Common warning options. + warning_options = { + '-fsyntax-only': 'warnings.syntaxonly', + '-pedantic': 'warnings.pedantic', + '-pedantic-errors': 'warnings.pedanticerrors', + '-w': 'warnings.nowarn', + '-Wunused': 'warnings.unused', + '-Wuninitialized': 'warnings.uninitialized', + '-Wall': 'warnings.allwarn', + '-Wextra': 'warnings.extrawarn', + '-Wmissing-declarations': 'warnings.missingdeclaration', + '-Wconversion': 'warnings.conversion', + '-Wpointer-arith': 'warnings.pointerarith', + '-Wpadded': 'warnings.padded', + '-Wshadow': 'warnings.shadow', + '-Wlogical-op': 'warnings.logicalop', + '-Waggregate-return': 'warnings.agreggatereturn', + '-Wfloat-equal': 'warnings.floatequal', + '-Werror': 'warnings.toerrors', + } + + for option in warning_options: + opts['common'][warning_options[option]] = False + if option in flags['common_flags']: + opts['common'][warning_options[option]] = True + self.remove_option(flags['common_flags'], option) + + # Common debug options. + debug_levels = { + '-g': 'default', + '-g1': 'minimal', + '-g3': 'max', + } + opts['common']['debugging.level'] = 'none' + for option in debug_levels: + if option in flags['common_flags']: + opts['common'][ + 'debugging.level'] = debug_levels[option] + self.remove_option(flags['common_flags'], option) + + debug_formats = { + '-ggdb': 'gdb', + '-gstabs': 'stabs', + '-gstabs+': 'stabsplus', + '-gdwarf-2': 'dwarf2', + '-gdwarf-3': 'dwarf3', + '-gdwarf-4': 'dwarf4', + '-gdwarf-5': 'dwarf5', + } + + opts['common']['debugging.format'] = '' + for option in debug_levels: + if option in flags['common_flags']: + opts['common'][ + 'debugging.format'] = debug_formats[option] + self.remove_option(flags['common_flags'], option) + + opts['common']['debugging.prof'] = False + if '-p' in flags['common_flags']: + opts['common']['debugging.prof'] = True + self.remove_option(flags['common_flags'], '-p') + + opts['common']['debugging.gprof'] = False + if '-pg' in flags['common_flags']: + opts['common']['debugging.gprof'] = True + self.remove_option(flags['common_flags'], '-gp') + + # Assembler options. + opts['as']['usepreprocessor'] = False + while '-x' in flags['asm_flags']: + ix = flags['asm_flags'].index('-x') + str = flags['asm_flags'][ix + 1] + + if str == 'assembler-with-cpp': + opts['as']['usepreprocessor'] = True + else: + # Collect all other assembler options. + opts['as']['other'] += ' -x ' + str + + self.remove_option(flags['asm_flags'], '-x') + self.remove_option(flags['asm_flags'], 'assembler-with-cpp') + + opts['as']['nostdinc'] = False + if '-nostdinc' in flags['asm_flags']: + opts['as']['nostdinc'] = True + self.remove_option(flags['asm_flags'], '-nostdinc') + + opts['as']['verbose'] = False + if '-v' in flags['asm_flags']: + opts['as']['verbose'] = True + self.remove_option(flags['asm_flags'], '-v') + + # C options. + opts['c']['nostdinc'] = False + if '-nostdinc' in flags['c_flags']: + opts['c']['nostdinc'] = True + self.remove_option(flags['c_flags'], '-nostdinc') + + opts['c']['verbose'] = False + if '-v' in flags['c_flags']: + opts['c']['verbose'] = True + self.remove_option(flags['c_flags'], '-v') + + warning_options = { + '-Wmissing-prototypes': 'warnings.missingprototypes', + '-Wstrict-prototypes': 'warnings.strictprototypes', + '-Wbad-function-cast': 'warnings.badfunctioncast', + } + + for option in warning_options: + opts['c'][warning_options[option]] = False + if option in flags['common_flags']: + opts['c'][warning_options[option]] = True + self.remove_option(flags['common_flags'], option) + + # C++ options. + opts['cpp']['nostdinc'] = False + if '-nostdinc' in flags['cxx_flags']: + opts['cpp']['nostdinc'] = True + self.remove_option(flags['cxx_flags'], '-nostdinc') + + opts['cpp']['nostdincpp'] = False + if '-nostdinc++' in flags['cxx_flags']: + opts['cpp']['nostdincpp'] = True + self.remove_option(flags['cxx_flags'], '-nostdinc++') + + optimization_options = { + '-fno-exceptions': 'optimization.noexceptions', + '-fno-rtti': 'optimization.nortti', + '-fno-use-cxa-atexit': 'optimization.nousecxaatexit', + '-fno-threadsafe-statics': 'optimization.nothreadsafestatics', + } + + for option in optimization_options: + opts['cpp'][optimization_options[option]] = False + if option in flags['cxx_flags']: + opts['cpp'][optimization_options[option]] = True + self.remove_option(flags['cxx_flags'], option) + if option in flags['common_flags']: + opts['cpp'][optimization_options[option]] = True + self.remove_option(flags['common_flags'], option) + + warning_options = { + '-Wabi': 'warnabi', + '-Wctor-dtor-privacy': 'warnings.ctordtorprivacy', + '-Wnoexcept': 'warnings.noexcept', + '-Wnon-virtual-dtor': 'warnings.nonvirtualdtor', + '-Wstrict-null-sentinel': 'warnings.strictnullsentinel', + '-Wsign-promo': 'warnings.signpromo', + '-Weffc++': 'warneffc', + } + + for option in warning_options: + opts['cpp'][warning_options[option]] = False + if option in flags['cxx_flags']: + opts['cpp'][warning_options[option]] = True + self.remove_option(flags['cxx_flags'], option) + if option in flags['common_flags']: + opts['cpp'][warning_options[option]] = True + self.remove_option(flags['common_flags'], option) + + opts['cpp']['verbose'] = False + if '-v' in flags['cxx_flags']: + opts['cpp']['verbose'] = True + self.remove_option(flags['cxx_flags'], '-v') + + # Linker options. + linker_options = { + '-nostartfiles': 'nostart', + '-nodefaultlibs': 'nodeflibs', + '-nostdlib': 'nostdlibs', + } + + for option in linker_options: + opts['ld'][linker_options[option]] = False + if option in flags['ld_flags']: + opts['ld'][linker_options[option]] = True + self.remove_option(flags['ld_flags'], option) + + opts['ld']['gcsections'] = False + if '-Wl,--gc-sections' in flags['ld_flags']: + opts['ld']['gcsections'] = True + self.remove_option(flags['ld_flags'], '-Wl,--gc-sections') + + opts['ld']['flags'] = [] + to_remove = [] + for opt in flags['ld_flags']: + if opt.startswith('-Wl,--wrap,'): + opts['ld']['flags'].append( + '--wrap=' + opt[len('-Wl,--wrap,'):]) + to_remove.append(opt) + for opt in to_remove: + self.remove_option(flags['ld_flags'], opt) + + # Other tool remaining options are separated by category. + opts['as']['otherwarnings'] = self.find_options( + flags['asm_flags'], '-W') + + opts['c']['otherwarnings'] = self.find_options( + flags['c_flags'], '-W') + opts['c']['otheroptimizations'] = self.find_options(flags[ + 'c_flags'], '-f') + + opts['cpp']['otherwarnings'] = self.find_options( + flags['cxx_flags'], '-W') + opts['cpp']['otheroptimizations'] = self.find_options( + flags['cxx_flags'], '-f') + + # Other common remaining options are separated by category. + opts['common']['optimization.other'] = self.find_options( + flags['common_flags'], '-f') + opts['common']['warnings.other'] = self.find_options( + flags['common_flags'], '-W') + + # Remaining common flags are added to each tool. + opts['as']['other'] += ' ' + \ + ' '.join(flags['common_flags']) + ' ' + \ + ' '.join(flags['asm_flags']) + opts['c']['other'] += ' ' + \ + ' '.join(flags['common_flags']) + ' ' + ' '.join(flags['c_flags']) + opts['cpp']['other'] += ' ' + \ + ' '.join(flags['common_flags']) + ' ' + \ + ' '.join(flags['cxx_flags']) + opts['ld']['other'] += ' ' + \ + ' '.join(flags['common_flags']) + ' ' + ' '.join(flags['ld_flags']) + + if len(self.system_libraries) > 0: + opts['ld']['other'] += ' -Wl,--start-group ' + opts['ld'][ + 'other'] += ' '.join('-l' + s for s in self.system_libraries) + opts['ld']['other'] += ' -Wl,--end-group ' + + # Strip all 'other' flags, since they might have leading spaces. + opts['as']['other'] = opts['as']['other'].strip() + opts['c']['other'] = opts['c']['other'].strip() + opts['cpp']['other'] = opts['cpp']['other'].strip() + opts['ld']['other'] = opts['ld']['other'].strip() + + if False: + print + print opts + + print + print 'common_flags', flags['common_flags'] + print 'asm_flags', flags['asm_flags'] + print 'c_flags', flags['c_flags'] + print 'cxx_flags', flags['cxx_flags'] + print 'ld_flags', flags['ld_flags'] + + @staticmethod + def find_options(lst, option): + tmp = [str for str in lst if str.startswith(option)] + if len(tmp) > 0: + return tmp[0] + else: + return None + + @staticmethod + def find_options(lst, prefix): + other = '' + opts = [str for str in lst if str.startswith(prefix)] + if len(opts) > 0: + for opt in opts: + other += ' ' + opt + GNUARMEclipse.remove_option(lst, opt) + return other.strip() + + @staticmethod + def remove_option(lst, option): + if option in lst: + lst.remove(option) + +# ============================================================================= diff --git a/tools/export/gnuarmeclipse/makefile.targets.tmpl b/tools/export/gnuarmeclipse/makefile.targets.tmpl new file mode 100644 index 0000000000..00466357c7 --- /dev/null +++ b/tools/export/gnuarmeclipse/makefile.targets.tmpl @@ -0,0 +1,7 @@ +# DO NOT REMOVE! Generated by the GNU ARM Eclipse exporter from an mBed project. + +mbedclean: + $(RM) $(OBJS) + $(RM) $(CC_DEPS)$(C++_DEPS)$(C_UPPER_DEPS)$(CXX_DEPS)$(ASM_DEPS)$(S_UPPER_DEPS)$(C_DEPS)$(CPP_DEPS) + $(RM) $(SECONDARY_FLASH)$(SECONDARY_SIZE) {{name}}.* + -@echo ' ' \ No newline at end of file diff --git a/tools/export/codered/__init__.py b/tools/export/lpcxpresso/__init__.py similarity index 85% rename from tools/export/codered/__init__.py rename to tools/export/lpcxpresso/__init__.py index 325191553b..aeaa12df02 100644 --- a/tools/export/codered/__init__.py +++ b/tools/export/lpcxpresso/__init__.py @@ -18,9 +18,9 @@ from os.path import splitext, basename from tools.export.exporters import Exporter -class CodeRed(Exporter): - NAME = 'CodeRed' - TOOLCHAIN = 'GCC_CR' +class LPCXpresso(Exporter): + NAME = 'LPCXpresso' + TOOLCHAIN = 'GCC_ARM' MBED_CONFIG_HEADER_SUPPORTED = True @@ -56,5 +56,5 @@ class CodeRed(Exporter): 'symbols': self.toolchain.get_symbols() } ctx.update(self.flags) - self.gen_file('codered/%s_project.tmpl' % self.target.lower(), ctx, '.project') - self.gen_file('codered/%s_cproject.tmpl' % self.target.lower(), ctx, '.cproject') + self.gen_file('lpcxpresso/%s_project.tmpl' % self.target.lower(), ctx, '.project') + self.gen_file('lpcxpresso/%s_cproject.tmpl' % self.target.lower(), ctx, '.cproject') diff --git a/tools/export/codered/arch_pro_cproject.tmpl b/tools/export/lpcxpresso/arch_pro_cproject.tmpl similarity index 99% rename from tools/export/codered/arch_pro_cproject.tmpl rename to tools/export/lpcxpresso/arch_pro_cproject.tmpl index b39438a4ad..291569de82 100644 --- a/tools/export/codered/arch_pro_cproject.tmpl +++ b/tools/export/lpcxpresso/arch_pro_cproject.tmpl @@ -1,4 +1,4 @@ -{% extends "codered_cproject_cortexm3_common.tmpl" %} +{% extends "lpcxpresso/cproject_cortexm3_common.tmpl" %} {% block startup_file %}cr_startup_lpc176x.c{% endblock %} diff --git a/tools/export/lpcxpresso/arch_pro_project.tmpl b/tools/export/lpcxpresso/arch_pro_project.tmpl new file mode 100644 index 0000000000..8b0351edb0 --- /dev/null +++ b/tools/export/lpcxpresso/arch_pro_project.tmpl @@ -0,0 +1 @@ +{% extends "lpcxpresso/project_common.tmpl" %} diff --git a/tools/export/codered/cproject_common.tmpl b/tools/export/lpcxpresso/cproject_common.tmpl similarity index 100% rename from tools/export/codered/cproject_common.tmpl rename to tools/export/lpcxpresso/cproject_common.tmpl diff --git a/tools/export/lpcxpresso/cproject_cortexm0_common.tmpl b/tools/export/lpcxpresso/cproject_cortexm0_common.tmpl new file mode 100644 index 0000000000..1635ee262d --- /dev/null +++ b/tools/export/lpcxpresso/cproject_cortexm0_common.tmpl @@ -0,0 +1,3 @@ +{% extends "lpcxpresso/cproject_common.tmpl" %} + +{% block core %}cm0{% endblock %} diff --git a/tools/export/lpcxpresso/cproject_cortexm3_common.tmpl b/tools/export/lpcxpresso/cproject_cortexm3_common.tmpl new file mode 100644 index 0000000000..6ebc79f587 --- /dev/null +++ b/tools/export/lpcxpresso/cproject_cortexm3_common.tmpl @@ -0,0 +1,3 @@ +{% extends "lpcxpresso/cproject_common.tmpl" %} + +{% block core %}cm3{% endblock %} diff --git a/tools/export/codered/lpc1114_cproject.tmpl b/tools/export/lpcxpresso/lpc1114_cproject.tmpl similarity index 98% rename from tools/export/codered/lpc1114_cproject.tmpl rename to tools/export/lpcxpresso/lpc1114_cproject.tmpl index ae49cd5b2d..42b25d00b8 100644 --- a/tools/export/codered/lpc1114_cproject.tmpl +++ b/tools/export/lpcxpresso/lpc1114_cproject.tmpl @@ -1,4 +1,4 @@ -{% extends "codered_cproject_cortexm0_common.tmpl" %} +{% extends "lpcxpresso/cproject_cortexm0_common.tmpl" %} {% block startup_file %}cr_startup_lpc11xx.c{% endblock %} diff --git a/tools/export/lpcxpresso/lpc1114_project.tmpl b/tools/export/lpcxpresso/lpc1114_project.tmpl new file mode 100644 index 0000000000..8b0351edb0 --- /dev/null +++ b/tools/export/lpcxpresso/lpc1114_project.tmpl @@ -0,0 +1 @@ +{% extends "lpcxpresso/project_common.tmpl" %} diff --git a/tools/export/codered/lpc11u35_401_cproject.tmpl b/tools/export/lpcxpresso/lpc11u35_401_cproject.tmpl similarity index 98% rename from tools/export/codered/lpc11u35_401_cproject.tmpl rename to tools/export/lpcxpresso/lpc11u35_401_cproject.tmpl index e874ee607d..5d6714345a 100644 --- a/tools/export/codered/lpc11u35_401_cproject.tmpl +++ b/tools/export/lpcxpresso/lpc11u35_401_cproject.tmpl @@ -1,4 +1,4 @@ -{% extends "codered_cproject_cortexm0_common.tmpl" %} +{% extends "lpcxpresso/cproject_cortexm0_common.tmpl" %} {% block startup_file %}cr_startup_lpc11xx.c{% endblock %} diff --git a/tools/export/lpcxpresso/lpc11u35_401_project.tmpl b/tools/export/lpcxpresso/lpc11u35_401_project.tmpl new file mode 100644 index 0000000000..8b0351edb0 --- /dev/null +++ b/tools/export/lpcxpresso/lpc11u35_401_project.tmpl @@ -0,0 +1 @@ +{% extends "lpcxpresso/project_common.tmpl" %} diff --git a/tools/export/codered/lpc11u35_501_cproject.tmpl b/tools/export/lpcxpresso/lpc11u35_501_cproject.tmpl similarity index 98% rename from tools/export/codered/lpc11u35_501_cproject.tmpl rename to tools/export/lpcxpresso/lpc11u35_501_cproject.tmpl index 622844e158..28c3ad01dc 100644 --- a/tools/export/codered/lpc11u35_501_cproject.tmpl +++ b/tools/export/lpcxpresso/lpc11u35_501_cproject.tmpl @@ -1,4 +1,4 @@ -{% extends "codered_cproject_cortexm0_common.tmpl" %} +{% extends "lpcxpresso/cproject_cortexm0_common.tmpl" %} {% block startup_file %}cr_startup_lpc11xx.c{% endblock %} diff --git a/tools/export/lpcxpresso/lpc11u35_501_project.tmpl b/tools/export/lpcxpresso/lpc11u35_501_project.tmpl new file mode 100644 index 0000000000..8b0351edb0 --- /dev/null +++ b/tools/export/lpcxpresso/lpc11u35_501_project.tmpl @@ -0,0 +1 @@ +{% extends "lpcxpresso/project_common.tmpl" %} diff --git a/tools/export/codered/lpc11u37h_401_cproject.tmpl b/tools/export/lpcxpresso/lpc11u37h_401_cproject.tmpl similarity index 98% rename from tools/export/codered/lpc11u37h_401_cproject.tmpl rename to tools/export/lpcxpresso/lpc11u37h_401_cproject.tmpl index 4b9fd6e6be..614f61fb4e 100644 --- a/tools/export/codered/lpc11u37h_401_cproject.tmpl +++ b/tools/export/lpcxpresso/lpc11u37h_401_cproject.tmpl @@ -1,4 +1,4 @@ -{% extends "codered_cproject_cortexm0_common.tmpl" %} +{% extends "lpcxpresso/cproject_cortexm0_common.tmpl" %} {% block startup_file %}cr_startup_lpc11xx.c{% endblock %} diff --git a/tools/export/lpcxpresso/lpc11u37h_401_project.tmpl b/tools/export/lpcxpresso/lpc11u37h_401_project.tmpl new file mode 100644 index 0000000000..8b0351edb0 --- /dev/null +++ b/tools/export/lpcxpresso/lpc11u37h_401_project.tmpl @@ -0,0 +1 @@ +{% extends "lpcxpresso/project_common.tmpl" %} diff --git a/tools/export/codered/lpc11u68_cproject.tmpl b/tools/export/lpcxpresso/lpc11u68_cproject.tmpl similarity index 98% rename from tools/export/codered/lpc11u68_cproject.tmpl rename to tools/export/lpcxpresso/lpc11u68_cproject.tmpl index 0af417408c..3c37890c5a 100644 --- a/tools/export/codered/lpc11u68_cproject.tmpl +++ b/tools/export/lpcxpresso/lpc11u68_cproject.tmpl @@ -1,4 +1,4 @@ -{% extends "codered_cproject_cortexm0_common.tmpl" %} +{% extends "lpcxpresso/cproject_cortexm0_common.tmpl" %} {% block startup_file %}startup_LPC11U68.cpp{% endblock %} diff --git a/tools/export/lpcxpresso/lpc11u68_project.tmpl b/tools/export/lpcxpresso/lpc11u68_project.tmpl new file mode 100644 index 0000000000..8b0351edb0 --- /dev/null +++ b/tools/export/lpcxpresso/lpc11u68_project.tmpl @@ -0,0 +1 @@ +{% extends "lpcxpresso/project_common.tmpl" %} diff --git a/tools/export/codered/lpc1549_cproject.tmpl b/tools/export/lpcxpresso/lpc1549_cproject.tmpl similarity index 99% rename from tools/export/codered/lpc1549_cproject.tmpl rename to tools/export/lpcxpresso/lpc1549_cproject.tmpl index 73529ef57d..518055219b 100644 --- a/tools/export/codered/lpc1549_cproject.tmpl +++ b/tools/export/lpcxpresso/lpc1549_cproject.tmpl @@ -1,4 +1,4 @@ -{% extends "codered_cproject_cortexm3_common.tmpl" %} +{% extends "lpcxpresso/cproject_cortexm3_common.tmpl" %} {% block startup_file %}cr_startup_lpc15xx.c{% endblock %} diff --git a/tools/export/lpcxpresso/lpc1549_project.tmpl b/tools/export/lpcxpresso/lpc1549_project.tmpl new file mode 100644 index 0000000000..8eb937ea08 --- /dev/null +++ b/tools/export/lpcxpresso/lpc1549_project.tmpl @@ -0,0 +1 @@ +{% extends "lpcxprosso/project_common.tmpl" %} diff --git a/tools/export/codered/lpc1768_cproject.tmpl b/tools/export/lpcxpresso/lpc1768_cproject.tmpl similarity index 99% rename from tools/export/codered/lpc1768_cproject.tmpl rename to tools/export/lpcxpresso/lpc1768_cproject.tmpl index b39438a4ad..291569de82 100644 --- a/tools/export/codered/lpc1768_cproject.tmpl +++ b/tools/export/lpcxpresso/lpc1768_cproject.tmpl @@ -1,4 +1,4 @@ -{% extends "codered_cproject_cortexm3_common.tmpl" %} +{% extends "lpcxpresso/cproject_cortexm3_common.tmpl" %} {% block startup_file %}cr_startup_lpc176x.c{% endblock %} diff --git a/tools/export/lpcxpresso/lpc1768_project.tmpl b/tools/export/lpcxpresso/lpc1768_project.tmpl new file mode 100644 index 0000000000..8b0351edb0 --- /dev/null +++ b/tools/export/lpcxpresso/lpc1768_project.tmpl @@ -0,0 +1 @@ +{% extends "lpcxpresso/project_common.tmpl" %} diff --git a/tools/export/codered/lpc4088_cproject.tmpl b/tools/export/lpcxpresso/lpc4088_cproject.tmpl similarity index 100% rename from tools/export/codered/lpc4088_cproject.tmpl rename to tools/export/lpcxpresso/lpc4088_cproject.tmpl diff --git a/tools/export/codered/lpc4088_dm_cproject.tmpl b/tools/export/lpcxpresso/lpc4088_dm_cproject.tmpl similarity index 100% rename from tools/export/codered/lpc4088_dm_cproject.tmpl rename to tools/export/lpcxpresso/lpc4088_dm_cproject.tmpl diff --git a/tools/export/lpcxpresso/lpc4088_dm_project.tmpl b/tools/export/lpcxpresso/lpc4088_dm_project.tmpl new file mode 100644 index 0000000000..8b0351edb0 --- /dev/null +++ b/tools/export/lpcxpresso/lpc4088_dm_project.tmpl @@ -0,0 +1 @@ +{% extends "lpcxpresso/project_common.tmpl" %} diff --git a/tools/export/lpcxpresso/lpc4088_project.tmpl b/tools/export/lpcxpresso/lpc4088_project.tmpl new file mode 100644 index 0000000000..8b0351edb0 --- /dev/null +++ b/tools/export/lpcxpresso/lpc4088_project.tmpl @@ -0,0 +1 @@ +{% extends "lpcxpresso/project_common.tmpl" %} diff --git a/tools/export/codered/lpc4330_m4_cproject.tmpl b/tools/export/lpcxpresso/lpc4330_m4_cproject.tmpl similarity index 100% rename from tools/export/codered/lpc4330_m4_cproject.tmpl rename to tools/export/lpcxpresso/lpc4330_m4_cproject.tmpl diff --git a/tools/export/lpcxpresso/lpc4330_m4_project.tmpl b/tools/export/lpcxpresso/lpc4330_m4_project.tmpl new file mode 100644 index 0000000000..8b0351edb0 --- /dev/null +++ b/tools/export/lpcxpresso/lpc4330_m4_project.tmpl @@ -0,0 +1 @@ +{% extends "lpcxpresso/project_common.tmpl" %} diff --git a/tools/export/codered/lpc824_cproject.tmpl b/tools/export/lpcxpresso/lpc824_cproject.tmpl similarity index 98% rename from tools/export/codered/lpc824_cproject.tmpl rename to tools/export/lpcxpresso/lpc824_cproject.tmpl index ee22cb6a4e..57343e05e5 100644 --- a/tools/export/codered/lpc824_cproject.tmpl +++ b/tools/export/lpcxpresso/lpc824_cproject.tmpl @@ -1,4 +1,4 @@ -{% extends "codered_cproject_cortexm0_common.tmpl" %} +{% extends "lpcxpresso/cproject_cortexm0_common.tmpl" %} {% block startup_file %}startup_LPC824_CR.cpp{% endblock %} diff --git a/tools/export/lpcxpresso/lpc824_project.tmpl b/tools/export/lpcxpresso/lpc824_project.tmpl new file mode 100644 index 0000000000..8b0351edb0 --- /dev/null +++ b/tools/export/lpcxpresso/lpc824_project.tmpl @@ -0,0 +1 @@ +{% extends "lpcxpresso/project_common.tmpl" %} diff --git a/tools/export/codered/lpccappuccino_cproject.tmpl b/tools/export/lpcxpresso/lpccappuccino_cproject.tmpl similarity index 98% rename from tools/export/codered/lpccappuccino_cproject.tmpl rename to tools/export/lpcxpresso/lpccappuccino_cproject.tmpl index 69256f8f83..0fce5208a2 100644 --- a/tools/export/codered/lpccappuccino_cproject.tmpl +++ b/tools/export/lpcxpresso/lpccappuccino_cproject.tmpl @@ -1,4 +1,4 @@ -{% extends "codered_cproject_cortexm0_common.tmpl" %} +{% extends "lpcxpresso/cproject_cortexm0_common.tmpl" %} {% block startup_file %}cr_startup_lpc11xx.c{% endblock %} diff --git a/tools/export/lpcxpresso/lpccappuccino_project.tmpl b/tools/export/lpcxpresso/lpccappuccino_project.tmpl new file mode 100644 index 0000000000..8b0351edb0 --- /dev/null +++ b/tools/export/lpcxpresso/lpccappuccino_project.tmpl @@ -0,0 +1 @@ +{% extends "lpcxpresso/project_common.tmpl" %} diff --git a/tools/export/codered/project_common.tmpl b/tools/export/lpcxpresso/project_common.tmpl similarity index 100% rename from tools/export/codered/project_common.tmpl rename to tools/export/lpcxpresso/project_common.tmpl diff --git a/tools/export/codered/ublox_c027_cproject.tmpl b/tools/export/lpcxpresso/ublox_c027_cproject.tmpl similarity index 99% rename from tools/export/codered/ublox_c027_cproject.tmpl rename to tools/export/lpcxpresso/ublox_c027_cproject.tmpl index b39438a4ad..291569de82 100644 --- a/tools/export/codered/ublox_c027_cproject.tmpl +++ b/tools/export/lpcxpresso/ublox_c027_cproject.tmpl @@ -1,4 +1,4 @@ -{% extends "codered_cproject_cortexm3_common.tmpl" %} +{% extends "lpcxpresso/cproject_cortexm3_common.tmpl" %} {% block startup_file %}cr_startup_lpc176x.c{% endblock %} diff --git a/tools/export/lpcxpresso/ublox_c027_project.tmpl b/tools/export/lpcxpresso/ublox_c027_project.tmpl new file mode 100644 index 0000000000..8b0351edb0 --- /dev/null +++ b/tools/export/lpcxpresso/ublox_c027_project.tmpl @@ -0,0 +1 @@ +{% extends "lpcxpresso/project_common.tmpl" %} diff --git a/tools/export/makefile/__init__.py b/tools/export/makefile/__init__.py index c6a1512094..a76369cda7 100644 --- a/tools/export/makefile/__init__.py +++ b/tools/export/makefile/__init__.py @@ -78,9 +78,7 @@ class Makefile(Exporter): 'asm_cmd': " ".join(["\'" + part + "\'" for part in ([basename(self.toolchain.asm[0])] + self.toolchain.asm[1:])]), - 'ld_cmd': " ".join(["\'" + part + "\'" for part - in ([basename(self.toolchain.ld[0])] + - self.toolchain.ld[1:])]), + 'ld_cmd': "\'" + basename(self.toolchain.ld[0]) + "\'", 'elf2bin_cmd': "\'" + basename(self.toolchain.elf2bin) + "\'", 'link_script_ext': self.toolchain.LINKER_EXT, 'link_script_option': self.LINK_SCRIPT_OPTION, diff --git a/tools/memap.py b/tools/memap.py index 5553048dbe..c98479776a 100644 --- a/tools/memap.py +++ b/tools/memap.py @@ -541,7 +541,7 @@ class MemapParser(object): return output - toolchains = ["ARM", "ARM_STD", "ARM_MICRO", "GCC_ARM", "IAR"] + toolchains = ["ARM", "ARM_STD", "ARM_MICRO", "GCC_ARM", "GCC_CR", "IAR"] def compute_report(self): for k in self.sections: @@ -596,7 +596,7 @@ class MemapParser(object): toolchain == "ARM_MICRO": self.search_objects(os.path.abspath(mapfile)) self.parse_map_file_armcc(file_input) - elif toolchain == "GCC_ARM": + elif toolchain == "GCC_ARM" or toolchain == "GCC_CR": self.parse_map_file_gcc(file_input) elif toolchain == "IAR": self.search_objects(os.path.abspath(mapfile)) diff --git a/tools/project_api.py b/tools/project_api.py index 39a3e2460a..f55f57ebf0 100644 --- a/tools/project_api.py +++ b/tools/project_api.py @@ -104,33 +104,32 @@ def zip_export(file_name, prefix, resources, project_files, inc_repos): with zipfile.ZipFile(file_name, "w") as zip_file: for prj_file in project_files: zip_file.write(prj_file, join(prefix, basename(prj_file))) - for loc, resource in resources.iteritems(): - for res in [resource] + resource.features.values(): - to_zip = ( - res.headers + res.s_sources + res.c_sources +\ - res.cpp_sources + res.libraries + res.hex_files + \ - [res.linker_script] + res.bin_files + res.objects + \ - res.json_files + res.lib_refs + res.lib_builds) - if inc_repos: - for directory in res.repo_dirs: - for root, _, files in walk(directory): - for repo_file in files: - source = join(root, repo_file) - to_zip.append(source) - res.file_basepath[source] = res.base_path - to_zip += res.repo_files - for source in to_zip: - if source: - zip_file.write( - source, - join(prefix, loc, - relpath(source, res.file_basepath[source]))) - for source in res.lib_builds: - target_dir, _ = splitext(source) - dest = join(prefix, loc, - relpath(target_dir, res.file_basepath[source]), - ".bld", "bldrc") - zip_file.write(source, dest) + for loc, res in resources.iteritems(): + to_zip = ( + res.headers + res.s_sources + res.c_sources +\ + res.cpp_sources + res.libraries + res.hex_files + \ + [res.linker_script] + res.bin_files + res.objects + \ + res.json_files + res.lib_refs + res.lib_builds) + if inc_repos: + for directory in res.repo_dirs: + for root, _, files in walk(directory): + for repo_file in files: + source = join(root, repo_file) + to_zip.append(source) + res.file_basepath[source] = res.base_path + to_zip += res.repo_files + for source in to_zip: + if source: + zip_file.write( + source, + join(prefix, loc, + relpath(source, res.file_basepath[source]))) + for source in res.lib_builds: + target_dir, _ = splitext(source) + dest = join(prefix, loc, + relpath(target_dir, res.file_basepath[source]), + ".bld", "bldrc") + zip_file.write(source, dest) @@ -223,8 +222,13 @@ def export_project(src_paths, export_path, target, ide, libraries_paths=None, macros=macros) files.append(config_header) if zip_proj: + for resource in resource_dict.values(): + for label, res in resource.features.iteritems(): + if label not in toolchain.target.features: + resource.add(res) if isinstance(zip_proj, basestring): - zip_export(join(export_path, zip_proj), name, resource_dict, files, inc_repos) + zip_export(join(export_path, zip_proj), name, resource_dict, files, + inc_repos) else: zip_export(zip_proj, name, resource_dict, files, inc_repos) diff --git a/tools/toolchains/__init__.py b/tools/toolchains/__init__.py index 10f7cd882f..ffce23e65d 100644 --- a/tools/toolchains/__init__.py +++ b/tools/toolchains/__init__.py @@ -1395,26 +1395,24 @@ class mbedToolchain: return Config.config_to_macros(self.config_data) if self.config_data else [] from tools.settings import ARM_PATH -from tools.settings import GCC_ARM_PATH, GCC_CR_PATH +from tools.settings import GCC_ARM_PATH from tools.settings import IAR_PATH TOOLCHAIN_PATHS = { 'ARM': ARM_PATH, 'uARM': ARM_PATH, 'GCC_ARM': GCC_ARM_PATH, - 'GCC_CR': GCC_CR_PATH, 'IAR': IAR_PATH } from tools.toolchains.arm import ARM_STD, ARM_MICRO -from tools.toolchains.gcc import GCC_ARM, GCC_CR +from tools.toolchains.gcc import GCC_ARM from tools.toolchains.iar import IAR TOOLCHAIN_CLASSES = { 'ARM': ARM_STD, 'uARM': ARM_MICRO, 'GCC_ARM': GCC_ARM, - 'GCC_CR': GCC_CR, 'IAR': IAR } diff --git a/tools/toolchains/gcc.py b/tools/toolchains/gcc.py index d3a155ea9c..46d9f1a23d 100644 --- a/tools/toolchains/gcc.py +++ b/tools/toolchains/gcc.py @@ -29,12 +29,12 @@ class GCC(mbedToolchain): INDEX_PATTERN = re.compile('(?P\s*)\^') def __init__(self, target, notify=None, macros=None, - silent=False, tool_path="", extra_verbose=False, - build_profile=None): + silent=False, extra_verbose=False, build_profile=None): mbedToolchain.__init__(self, target, notify, macros, silent, extra_verbose=extra_verbose, build_profile=build_profile) + tool_path=TOOLCHAIN_PATHS['GCC_ARM'] # Add flags for current size setting default_lib = "std" if hasattr(target, "default_lib"): @@ -58,7 +58,7 @@ class GCC(mbedToolchain): cpu = target.core.lower() self.cpu = ["-mcpu=%s" % cpu] - if target.core.startswith("Cortex"): + if target.core.startswith("Cortex-M"): self.cpu.append("-mthumb") # FPU handling, M7 possibly to have double FPU @@ -92,7 +92,7 @@ class GCC(mbedToolchain): self.flags['ld'] += self.cpu self.ld = [join(tool_path, "arm-none-eabi-gcc")] + self.flags['ld'] - self.sys_libs = ["stdc++", "supc++", "m", "c", "gcc"] + self.sys_libs = ["stdc++", "supc++", "m", "c", "gcc", "nosys"] self.preproc = [join(tool_path, "arm-none-eabi-cpp"), "-E", "-P"] self.ar = join(tool_path, "arm-none-eabi-ar") @@ -126,7 +126,7 @@ class GCC(mbedToolchain): # The warning/error notification is multiline msg = None for line in output.splitlines(): - match = GCC.DIAGNOSTIC_PATTERN.search(line) + match = self.DIAGNOSTIC_PATTERN.search(line) if match is not None: if msg is not None: self.cc_info(msg) @@ -143,7 +143,7 @@ class GCC(mbedToolchain): } elif msg is not None: # Determine the warning/error column by calculating the ^ position - match = GCC.INDEX_PATTERN.match(line) + match = self.INDEX_PATTERN.match(line) if match is not None: msg['col'] = len(match.group('col')) self.cc_info(msg) @@ -280,8 +280,6 @@ class GCC(mbedToolchain): def redirect_symbol(source, sync, build_dir): return "-Wl,--defsym=%s=%s" % (source, sync) - -class GCC_ARM(GCC): @staticmethod def check_executable(): """Returns True if the executable (arm-none-eabi-gcc) location @@ -289,37 +287,5 @@ class GCC_ARM(GCC): Returns False otherwise.""" return mbedToolchain.generic_check_executable("GCC_ARM", 'arm-none-eabi-gcc', 1) - def __init__(self, target, notify=None, macros=None, - silent=False, extra_verbose=False, build_profile=None): - GCC.__init__(self, target, notify, macros, silent, - TOOLCHAIN_PATHS['GCC_ARM'], extra_verbose=extra_verbose, - build_profile=build_profile) - - self.sys_libs.append("nosys") - - -class GCC_CR(GCC): - @staticmethod - def check_executable(): - """Returns True if the executable (arm-none-eabi-gcc) location - specified by the user exists OR the executable can be found on the PATH. - Returns False otherwise.""" - return mbedToolchain.generic_check_executable("GCC_CR", 'arm-none-eabi-gcc', 1) - - def __init__(self, target, notify=None, macros=None, - silent=False, extra_verbose=False, build_profile=None): - GCC.__init__(self, target, notify, macros, silent, - TOOLCHAIN_PATHS['GCC_CR'], extra_verbose=extra_verbose, - build_profile=build_profile) - - additional_compiler_flags = [ - "-D__NEWLIB__", "-D__CODE_RED", "-D__USE_CMSIS", "-DCPP_USE_HEAP", - ] - self.cc += additional_compiler_flags - self.cppc += additional_compiler_flags - - # Use latest gcc nanolib - self.ld.append("--specs=nano.specs") - if target.name in ["LPC1768", "LPC4088", "LPC4088_DM", "LPC4330", "UBLOX_C027", "LPC2368"]: - self.ld.extend(["-u _printf_float", "-u _scanf_float"]) - self.ld += ["-nostdlib"] +class GCC_ARM(GCC): + pass