diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 0288ca11f3c9..f7e4d48c911b 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -18,7 +18,7 @@ --> [ ] Fix [ ] Refactor - [ ] New target - [ ] Feature + [ ] Target update + [ ] Functionality change [ ] Breaking change diff --git a/.travis.yml b/.travis.yml index 57795e867656..7ec90150096a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -200,7 +200,7 @@ matrix: - fusermount --version before_script: # Setup and patch littlefs-fuse - - git clone https://github.com/geky/littlefs-fuse littlefs_fuse + - git clone https://github.com/armmbed/littlefs-fuse littlefs_fuse - git -C littlefs_fuse checkout 3f1ed6e37799e49e3710830dc6abb926d5503cf2 - echo '*' > littlefs_fuse/.mbedignore - rm -rf littlefs_fuse/littlefs/* @@ -238,7 +238,7 @@ matrix: - make clean size CC='arm-none-eabi-gcc -mthumb' OBJ="$(ls lfs*.o | tr '\n' ' ')" - CFLAGS+="-DLFS_NO{ASSERT,DEBUG,WARN,ERROR}" + CFLAGS+="-DLFS_NO_ASSERT -DLFS_NO_DEBUG -DLFS_NO_WARN -DLFS_NO_ERROR" | tee sizes after_success: # update status if we succeeded, compare with master if possible diff --git a/Jenkinsfile b/Jenkinsfile index 846827c2a09d..c938dd0a24a8 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,31 +1,2 @@ - -// List of targets to compile -def targets = [ - //"LPC1768", - //"NUCLEO_F401RE", - //"NRF51822", - "K64F" - ] - -// Map toolchains to compiler labels on Jenkins -def toolchains = [ - ARM: "armcc", - //IAR: "iar_arm", - GCC_ARM: "arm-none-eabi-gcc" - ] - -// mbed.getCurrentBranch returns either local branch name or reference to pull request -def currentBranch = mbed.getCurrentBranch() - -// Create a map of predefined build steps -def parallelSteps = mbed.createParalleSteps("mbed-os", targets, toolchains) - -// Run build steps parallel, map as paramater -mbed.compile(parallelSteps) - -def testApps = [ - "mbed-os-cliapp" - ] - -// buildTestApps accepts array of test application names and a mbed-os branch or PR reference as parameters -mbed.buildTestApps(testApps, "${currentBranch}") +// This is internal file to run tests in internal Jenkins +mbed.run_job() diff --git a/TESTS/events/queue/main.cpp b/TESTS/events/queue/main.cpp index 7a7253346dbc..4bde3c8e230b 100644 --- a/TESTS/events/queue/main.cpp +++ b/TESTS/events/queue/main.cpp @@ -21,7 +21,7 @@ #include "utest.h" #if !DEVICE_USTICKER - #error [NOT_SUPPORTED] test not supported +#error [NOT_SUPPORTED] test not supported #endif using namespace utest::v1; @@ -38,32 +38,38 @@ using namespace utest::v1; volatile bool touched = false; // static functions -void func5(int a0, int a1, int a2, int a3, int a4) { +void func5(int a0, int a1, int a2, int a3, int a4) +{ touched = true; TEST_ASSERT_EQUAL(a0 | a1 | a2 | a3 | a4, 0x1f); } -void func4(int a0, int a1, int a2, int a3) { +void func4(int a0, int a1, int a2, int a3) +{ touched = true; - TEST_ASSERT_EQUAL(a0 | a1 | a2 | a3, 0xf); + TEST_ASSERT_EQUAL(a0 | a1 | a2 | a3, 0xf); } -void func3(int a0, int a1, int a2) { +void func3(int a0, int a1, int a2) +{ touched = true; TEST_ASSERT_EQUAL(a0 | a1 | a2, 0x7); } -void func2(int a0, int a1) { +void func2(int a0, int a1) +{ touched = true; TEST_ASSERT_EQUAL(a0 | a1, 0x3); } -void func1(int a0) { +void func1(int a0) +{ touched = true; TEST_ASSERT_EQUAL(a0, 0x1); } -void func0() { +void func0() +{ touched = true; } @@ -95,40 +101,44 @@ SIMPLE_POSTS_TEST(1, 0x01) SIMPLE_POSTS_TEST(0) -void time_func(Timer *t, int ms) { +void time_func(Timer *t, int ms) +{ TEST_ASSERT_INT_WITHIN(DELTA(ms), ms, t->read_ms()); t->reset(); } template -void call_in_test() { +void call_in_test() +{ Timer tickers[N]; EventQueue queue(TEST_EQUEUE_SIZE); for (int i = 0; i < N; i++) { tickers[i].start(); - queue.call_in((i+1)*100, time_func, &tickers[i], (i+1)*100); + queue.call_in((i + 1) * 100, time_func, &tickers[i], (i + 1) * 100); } - queue.dispatch(N*100); + queue.dispatch(N * 100); } template -void call_every_test() { +void call_every_test() +{ Timer tickers[N]; EventQueue queue(TEST_EQUEUE_SIZE); for (int i = 0; i < N; i++) { tickers[i].start(); - queue.call_every((i+1)*100, time_func, &tickers[i], (i+1)*100); + queue.call_every((i + 1) * 100, time_func, &tickers[i], (i + 1) * 100); } - queue.dispatch(N*100); + queue.dispatch(N * 100); } -void allocate_failure_test() { +void allocate_failure_test() +{ EventQueue queue(TEST_EQUEUE_SIZE); int id; @@ -139,12 +149,14 @@ void allocate_failure_test() { TEST_ASSERT(!id); } -void no() { +void no() +{ TEST_ASSERT(false); } template -void cancel_test1() { +void cancel_test1() +{ EventQueue queue(TEST_EQUEUE_SIZE); int ids[N]; @@ -153,7 +165,7 @@ void cancel_test1() { ids[i] = queue.call_in(1000, no); } - for (int i = N-1; i >= 0; i--) { + for (int i = N - 1; i >= 0; i--) { queue.cancel(ids[i]); } @@ -164,31 +176,38 @@ void cancel_test1() { // Testing the dynamic arguments to the event class unsigned counter = 0; -void count5(unsigned a0, unsigned a1, unsigned a2, unsigned a3, unsigned a5) { +void count5(unsigned a0, unsigned a1, unsigned a2, unsigned a3, unsigned a5) +{ counter += a0 + a1 + a2 + a3 + a5; } -void count4(unsigned a0, unsigned a1, unsigned a2, unsigned a3) { +void count4(unsigned a0, unsigned a1, unsigned a2, unsigned a3) +{ counter += a0 + a1 + a2 + a3; } -void count3(unsigned a0, unsigned a1, unsigned a2) { +void count3(unsigned a0, unsigned a1, unsigned a2) +{ counter += a0 + a1 + a2; } -void count2(unsigned a0, unsigned a1) { +void count2(unsigned a0, unsigned a1) +{ counter += a0 + a1; } -void count1(unsigned a0) { +void count1(unsigned a0) +{ counter += a0; } -void count0() { +void count0() +{ counter += 0; } -void event_class_test() { +void event_class_test() +{ counter = 0; EventQueue queue(TEST_EQUEUE_SIZE); @@ -211,7 +230,8 @@ void event_class_test() { TEST_ASSERT_EQUAL(counter, 30); } -void event_class_helper_test() { +void event_class_helper_test() +{ counter = 0; EventQueue queue(TEST_EQUEUE_SIZE); @@ -234,7 +254,8 @@ void event_class_helper_test() { TEST_ASSERT_EQUAL(counter, 15); } -void event_inference_test() { +void event_inference_test() +{ counter = 0; EventQueue queue(TEST_EQUEUE_SIZE); @@ -259,23 +280,26 @@ void event_inference_test() { int timeleft_events[2]; -void check_time_left(EventQueue* queue, int index, int expected) { +void check_time_left(EventQueue *queue, int index, int expected) +{ const int event_id = timeleft_events[index]; TEST_ASSERT_INT_WITHIN(2, expected, queue->time_left(event_id)); touched = true; } -void time_left(EventQueue* queue, int index) { +void time_left(EventQueue *queue, int index) +{ const int event_id = timeleft_events[index]; TEST_ASSERT_EQUAL(0, queue->time_left(event_id)); } -void time_left_test() { +void time_left_test() +{ EventQueue queue(TEST_EQUEUE_SIZE); // Enque check events - TEST_ASSERT(queue.call_in(50, check_time_left, &queue, 0, 100-50)); - TEST_ASSERT(queue.call_in(200, check_time_left, &queue, 1, 200-200)); + TEST_ASSERT(queue.call_in(50, check_time_left, &queue, 0, 100 - 50)); + TEST_ASSERT(queue.call_in(200, check_time_left, &queue, 1, 200 - 200)); // Enque events to be checked timeleft_events[0] = queue.call_in(100, time_left, &queue, 0); @@ -299,7 +323,8 @@ void time_left_test() { } // Test setup -utest::v1::status_t test_setup(const size_t number_of_cases) { +utest::v1::status_t test_setup(const size_t number_of_cases) +{ GREENTEA_SETUP(20, "default_auto"); return verbose_test_setup_handler(number_of_cases); } @@ -327,7 +352,8 @@ const Case cases[] = { Specification specification(test_setup, cases); -int main() { +int main() +{ return !Harness::run(specification); } diff --git a/TESTS/events/timing/main.cpp b/TESTS/events/timing/main.cpp index e93c75cfb0cf..adc001640b27 100644 --- a/TESTS/events/timing/main.cpp +++ b/TESTS/events/timing/main.cpp @@ -25,7 +25,7 @@ using namespace utest::v1; #if !DEVICE_USTICKER - #error [NOT_SUPPORTED] test not supported +#error [NOT_SUPPORTED] test not supported #endif // Test delay @@ -42,16 +42,18 @@ using namespace utest::v1; #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 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; + return mu + z * sigma; } -float chisq(float sigma) { +float chisq(float sigma) +{ return pow(gauss(0, sqrt(sigma)), 2); } @@ -62,16 +64,17 @@ DigitalOut led(LED1); equeue_sema_t sema; // Timer timing test -void timer_timing_test() { +void timer_timing_test() +{ timer.reset(); timer.start(); int prev = timer.read_us(); - while (prev < TEST_EVENTS_TIMING_TIME*1000) { + 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); + prev, next, prev, next); } TEST_ASSERT(next >= prev); prev = next; @@ -79,7 +82,8 @@ void timer_timing_test() { } // equeue tick timing test -void tick_timing_test() { +void tick_timing_test() +{ unsigned start = equeue_tick(); int prev = 0; @@ -87,7 +91,7 @@ void tick_timing_test() { int next = equeue_tick() - start; if (next < prev) { printf("backwards drift %d -> %d (%08x -> %08x)\r\n", - prev, next, prev, next); + prev, next, prev, next); } TEST_ASSERT(next >= prev); prev = next; @@ -95,7 +99,8 @@ void tick_timing_test() { } // equeue semaphore timing test -void semaphore_timing_test() { +void semaphore_timing_test() +{ srand(0); timer.reset(); timer.start(); @@ -124,8 +129,9 @@ void semaphore_timing_test() { // Test setup -utest::v1::status_t test_setup(const size_t number_of_cases) { - GREENTEA_SETUP((number_of_cases+1)*TEST_EVENTS_TIMING_TIME/1000, "default_auto"); +utest::v1::status_t test_setup(const size_t number_of_cases) +{ + GREENTEA_SETUP((number_of_cases + 1)*TEST_EVENTS_TIMING_TIME / 1000, "default_auto"); return verbose_test_setup_handler(number_of_cases); } @@ -137,7 +143,8 @@ const Case cases[] = { Specification specification(test_setup, cases); -int main() { +int main() +{ return !Harness::run(specification); } diff --git a/TESTS/integration/basic/main.cpp b/TESTS/integration/basic/main.cpp index ec202446879d..3989aada9a4b 100644 --- a/TESTS/integration/basic/main.cpp +++ b/TESTS/integration/basic/main.cpp @@ -15,7 +15,8 @@ */ #include "test_env.h" -int main() { +int main() +{ GREENTEA_SETUP(15, "default_auto"); GREENTEA_TESTSUITE_RESULT(true); } diff --git a/TESTS/lorawan/loraradio/main.cpp b/TESTS/lorawan/loraradio/main.cpp index 1f5c6d171bd6..29ab638c7970 100644 --- a/TESTS/lorawan/loraradio/main.cpp +++ b/TESTS/lorawan/loraradio/main.cpp @@ -29,21 +29,20 @@ #define SX1276 0xEE #if (MBED_CONF_APP_LORA_RADIO == SX1272) - #include "SX1272_LoRaRadio.h" +#include "SX1272_LoRaRadio.h" #elif (MBED_CONF_APP_LORA_RADIO == SX1276) - #include "SX1276_LoRaRadio.h" +#include "SX1276_LoRaRadio.h" #else - #error [NOT_SUPPORTED] Requires parameters from application config file. +#error [NOT_SUPPORTED] Requires parameters from application config file. #endif using namespace utest::v1; -static LoRaRadio* radio = NULL; +static LoRaRadio *radio = NULL; rtos::Semaphore event_sem(0); -enum event_t -{ +enum event_t { EV_NONE, EV_TX_DONE, EV_TX_TIMEOUT, @@ -94,8 +93,7 @@ static void rx_error() TEST_ASSERT_EQUAL(osOK, event_sem.release()); } -static radio_events radio_callbacks = -{ +static radio_events radio_callbacks = { .tx_done = tx_done, .tx_timeout = tx_timeout, .rx_done = rx_done, @@ -187,7 +185,8 @@ void test_check_rf_frequency() } // Test setup -utest::v1::status_t test_setup(const size_t number_of_cases) { +utest::v1::status_t test_setup(const size_t number_of_cases) +{ GREENTEA_SETUP(20, "default_auto"); mbed_trace_init(); @@ -240,7 +239,7 @@ utest::v1::status_t case_setup_handler(const Case *const source, const size_t in MBED_CONF_APP_LORA_TCXO); #else - #error [NOT_SUPPORTED] Unknown LoRa radio specified (SX1272,SX1276 are valid) +#error [NOT_SUPPORTED] Unknown LoRa radio specified (SX1272,SX1276 are valid) #endif TEST_ASSERT(radio); @@ -255,11 +254,11 @@ utest::v1::status_t case_teardown_handler(const Case *const source, const size_t radio->sleep(); #if (MBED_CONF_APP_LORA_RADIO == SX1272) - delete static_cast(radio); + delete static_cast(radio); #elif (MBED_CONF_APP_LORA_RADIO == SX1276) - delete static_cast(radio); + delete static_cast(radio); #else - #error [NOT_SUPPORTED] Unknown LoRa radio specified (SX1272,SX1276 are valid) +#error [NOT_SUPPORTED] Unknown LoRa radio specified (SX1272,SX1276 are valid) #endif radio = NULL; @@ -277,6 +276,7 @@ const Case cases[] = { Specification specification(test_setup, cases); -int main() { +int main() +{ return !Harness::run(specification); } diff --git a/TESTS/mbed_drivers/c_strings/main.cpp b/TESTS/mbed_drivers/c_strings/main.cpp index 68a25e068dc5..beb69e15c1f6 100644 --- a/TESTS/mbed_drivers/c_strings/main.cpp +++ b/TESTS/mbed_drivers/c_strings/main.cpp @@ -33,68 +33,76 @@ static char buffer[256] = {0}; using namespace utest::v1; -void test_case_c_string_i_d() { +void test_case_c_string_i_d() +{ CLEAN_BUFFER; sprintf(buffer, "%i %d %i %d %i %d %i %d %i %d %i %i", NEGATIVE_INTEGERS); TEST_ASSERT_EQUAL_STRING("-32768 -3214 -999 -100 -1 0 -1 -4231 -999 -4123 -32760 -99999", buffer); } -void test_case_c_string_u_d() { +void test_case_c_string_u_d() +{ CLEAN_BUFFER; sprintf(buffer, "%u %d %u %d %u %d %u %d %u %d %u %d", POSITIVE_INTEGERS); TEST_ASSERT_EQUAL_STRING("32768 3214 999 100 1 0 1 4231 999 4123 32760 99999", buffer); } -void test_case_c_string_x_E() { +void test_case_c_string_x_E() +{ CLEAN_BUFFER; sprintf(buffer, "%x %X %x %X %x %X %x %X %x %X %x %X", POSITIVE_INTEGERS); TEST_ASSERT_EQUAL_STRING("8000 C8E 3e7 64 1 0 1 1087 3e7 101B 7ff8 1869F", buffer); } -void test_case_c_string_f_f() { +void test_case_c_string_f_f() +{ CLEAN_BUFFER; sprintf(buffer, "%f %f %f %f %f %f %f %f %f %f", FLOATS); TEST_ASSERT_EQUAL_STRING("0.002000 0.924300 15.913200 791.773680 6208.200000 25719.495200 426815.982588 6429271.046000 42468024.930000 212006462.910000", buffer); } -void test_case_c_string_g_g() { +void test_case_c_string_g_g() +{ CLEAN_BUFFER; sprintf(buffer, "%g %g %g %g %g %g %g %g %g %g", FLOATS); TEST_ASSERT_EQUAL_STRING("0.002 0.9243 15.9132 791.774 6208.2 25719.5 426816 6.42927e+06 4.2468e+07 2.12006e+08", buffer); } -void test_case_c_string_e_E() { +void test_case_c_string_e_E() +{ CLEAN_BUFFER; sprintf(buffer, "%e %E %e %E %e %E %e %E %e %E", FLOATS); TEST_ASSERT_EQUAL_STRING("2.000000e-03 9.243000E-01 1.591320e+01 7.917737E+02 6.208200e+03 2.571950E+04 4.268160e+05 6.429271E+06 4.246802e+07 2.120065E+08", buffer); } -void test_case_c_string_strtok() { +void test_case_c_string_strtok() +{ CLEAN_BUFFER; - char str[] ="- This, a sample string."; - char * pch = strtok (str," ,.-"); + char str[] = "- This, a sample string."; + char *pch = strtok(str, " ,.-"); while (pch != NULL) { strcat(buffer, pch); - pch = strtok (NULL, " ,.-"); + pch = strtok(NULL, " ,.-"); } TEST_ASSERT_EQUAL_STRING("Thisasamplestring", buffer); } -void test_case_c_string_strpbrk() { +void test_case_c_string_strpbrk() +{ CLEAN_BUFFER; char str[] = "This is a sample string"; char key[] = "aeiou"; char *pch = strpbrk(str, key); - while (pch != NULL) - { + while (pch != NULL) { char buf[2] = {*pch, '\0'}; strcat(buffer, buf); - pch = strpbrk(pch + 1,key); + pch = strpbrk(pch + 1, key); } TEST_ASSERT_EQUAL_STRING("iiaaei", buffer); } -utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) { +utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) +{ greentea_case_failure_abort_handler(source, reason); return STATUS_CONTINUE; } @@ -110,13 +118,15 @@ Case cases[] = { Case("C strings: %g %g float formatting", test_case_c_string_g_g, greentea_failure_handler), }; -utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { +utest::v1::status_t greentea_test_setup(const size_t number_of_cases) +{ GREENTEA_SETUP(5, "default_auto"); return greentea_test_setup_handler(number_of_cases); } Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); -int main() { +int main() +{ Harness::run(specification); } diff --git a/TESTS/mbed_drivers/crc/main.cpp b/TESTS/mbed_drivers/crc/main.cpp index 656711efb57d..f531f2795140 100644 --- a/TESTS/mbed_drivers/crc/main.cpp +++ b/TESTS/mbed_drivers/crc/main.cpp @@ -30,27 +30,27 @@ void test_supported_polynomials() { MbedCRC ct; - TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char*)test), &crc)); + TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char *)test), &crc)); TEST_ASSERT_EQUAL(0xEA, crc); } { MbedCRC ct; - TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char*)test), &crc)); + TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char *)test), &crc)); TEST_ASSERT_EQUAL(0xF4, crc); } { MbedCRC ct; - TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char*)test), &crc)); + TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char *)test), &crc)); TEST_ASSERT_EQUAL(0x29B1, crc); } { MbedCRC ct; - TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char*)test), &crc)); + TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char *)test), &crc)); TEST_ASSERT_EQUAL(0xBB3D, crc); } { MbedCRC ct; - TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char*)test), &crc)); + TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char *)test), &crc)); TEST_ASSERT_EQUAL(0xCBF43926, crc); } } @@ -82,7 +82,7 @@ void test_sd_crc() test[3] = 0x00; test[4] = 0x00; TEST_ASSERT_EQUAL(0, crc7.compute((void *)test, 5, &crc)); - crc = (crc | 0x1 ) & 0xFF; + crc = (crc | 0x1) & 0xFF; TEST_ASSERT_EQUAL(0x95, crc); test[0] = 0x48; @@ -91,7 +91,7 @@ void test_sd_crc() test[3] = 0x01; test[4] = 0xAA; TEST_ASSERT_EQUAL(0, crc7.compute((void *)test, 5, &crc)); - crc = (crc | 0x1 ) & 0xFF; + crc = (crc | 0x1) & 0xFF; TEST_ASSERT_EQUAL(0x87, crc); test[0] = 0x51; @@ -100,7 +100,7 @@ void test_sd_crc() test[3] = 0x00; test[4] = 0x00; TEST_ASSERT_EQUAL(0, crc7.compute((void *)test, 5, &crc)); - crc = (crc | 0x1 ) & 0xFF; + crc = (crc | 0x1) & 0xFF; TEST_ASSERT_EQUAL(0x55, crc); MbedCRC crc16(0, 0, false, false); @@ -115,12 +115,12 @@ void test_any_polynomial() uint32_t crc; { MbedCRC<0x3D65, 16> ct(0x0, 0xFFFF, 0, 0); - TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char*)test), &crc)); + TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char *)test), &crc)); TEST_ASSERT_EQUAL(0xC2B7, crc); } { MbedCRC<0x1EDC6F41, 32> ct(0xFFFFFFFF, 0xFFFFFFFF, 1, 1); - TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char*)test), &crc)); + TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char *)test), &crc)); TEST_ASSERT_EQUAL(0xE3069283, crc); } } @@ -132,13 +132,15 @@ Case cases[] = { Case("Test not supported polynomials", test_any_polynomial) }; -utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { +utest::v1::status_t greentea_test_setup(const size_t number_of_cases) +{ GREENTEA_SETUP(15, "default_auto"); return greentea_test_setup_handler(number_of_cases); } Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); -int main() { +int main() +{ Harness::run(specification); } diff --git a/TESTS/mbed_drivers/dev_null/main.cpp b/TESTS/mbed_drivers/dev_null/main.cpp index 5513ca64fc45..880979282e30 100644 --- a/TESTS/mbed_drivers/dev_null/main.cpp +++ b/TESTS/mbed_drivers/dev_null/main.cpp @@ -22,17 +22,20 @@ class DevNull : public Stream { DevNull(const char *name = NULL) : Stream(name) {} protected: - virtual int _getc() { + virtual int _getc() + { return 0; } - virtual int _putc(int c) { + virtual int _putc(int c) + { return c; } }; DevNull null("null"); -int main() { +int main() +{ GREENTEA_SETUP(2, "dev_null_auto"); printf("MBED: before re-routing stdout to /null\n"); // This shouldn't appear @@ -45,7 +48,7 @@ int main() { printf("MBED: this printf is already redirected to /null\n"); } - while(1) { - // Success is determined by the host test at this point, so busy wait + while (1) { + // Success is determined by the host test at this point, so busy wait } } diff --git a/TESTS/mbed_drivers/echo/main.cpp b/TESTS/mbed_drivers/echo/main.cpp index 7295ddb4a6de..7ea6e422b38f 100644 --- a/TESTS/mbed_drivers/echo/main.cpp +++ b/TESTS/mbed_drivers/echo/main.cpp @@ -26,7 +26,8 @@ using namespace utest::v1; // Fill a buffer with a slice of the ASCII alphabet. -void fill_buffer(char* buffer, unsigned int length, unsigned int index) { +void fill_buffer(char *buffer, unsigned int length, unsigned int index) +{ unsigned int start = length * index; for (int i = 0; i < length - 1; i++) { buffer[i] = 'a' + ((start + i) % 26); @@ -36,7 +37,8 @@ void fill_buffer(char* buffer, unsigned int length, unsigned int index) { // Echo server (echo payload to host) template -void test_case_echo_server_x() { +void test_case_echo_server_x() +{ char _key[11] = {}; char _tx_value[PAYLOAD_LENGTH + 1] = {}; char _rx_value[PAYLOAD_LENGTH + 1] = {}; @@ -55,7 +57,7 @@ void test_case_echo_server_x() { } while (expected_key); TEST_ASSERT_EQUAL_INT(echo_count, atoi(_rx_value)); - for (int i=0; i < echo_count; ++i) { + for (int i = 0; i < echo_count; ++i) { fill_buffer(_tx_value, PAYLOAD_LENGTH, i); greentea_send_kv(_echo_key_const, _tx_value); do { @@ -67,7 +69,8 @@ void test_case_echo_server_x() { } } -utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) { +utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) +{ greentea_case_failure_abort_handler(source, reason); return STATUS_CONTINUE; } @@ -76,13 +79,15 @@ Case cases[] = { Case("Echo server: x16", test_case_echo_server_x<16>, greentea_failure_handler), }; -utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { +utest::v1::status_t greentea_test_setup(const size_t number_of_cases) +{ GREENTEA_SETUP(30, "device_echo"); return greentea_test_setup_handler(number_of_cases); } Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); -int main() { +int main() +{ Harness::run(specification); } diff --git a/TESTS/mbed_drivers/flashiap/main.cpp b/TESTS/mbed_drivers/flashiap/main.cpp index 08df4b2575b5..6fecee4c79af 100644 --- a/TESTS/mbed_drivers/flashiap/main.cpp +++ b/TESTS/mbed_drivers/flashiap/main.cpp @@ -16,18 +16,22 @@ */ #if !DEVICE_FLASH - #error [NOT_SUPPORTED] Flash API not supported for this target +#error [NOT_SUPPORTED] Flash API not supported for this target #endif #include "utest/utest.h" +#include "utest/utest_serial.h" #include "unity/unity.h" #include "greentea-client/test_env.h" +#include "FlashIAP.h" +#include "unity.h" #include #include "mbed.h" using namespace utest::v1; + void flashiap_init_test() { FlashIAP flash_device; @@ -58,6 +62,9 @@ void flashiap_program_test() // 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); + utest_printf("ROM ends at 0x%lx, test starts at 0x%lx\n", FLASHIAP_ROM_END, address); + TEST_SKIP_UNLESS_MESSAGE(address >= FLASHIAP_ROM_END, "Test skipped. Test region overlaps code."); + ret = flash_device.erase(address, sector_size); TEST_ASSERT_EQUAL_INT32(0, ret); @@ -92,6 +99,7 @@ void flashiap_program_test() TEST_ASSERT_EQUAL_INT32(0, ret); } + void flashiap_cross_sector_program_test() { FlashIAP flash_device; @@ -110,6 +118,7 @@ void flashiap_cross_sector_program_test() agg_size += sector_size; address -= sector_size; } + TEST_SKIP_UNLESS_MESSAGE(address >= FLASHIAP_ROM_END, "Test skipped. Test region overlaps code."); ret = flash_device.erase(address, agg_size); TEST_ASSERT_EQUAL_INT32(0, ret); @@ -165,6 +174,7 @@ void flashiap_program_error_test() TEST_ASSERT_TRUE(address != 0UL); // unaligned address + TEST_SKIP_UNLESS_MESSAGE(address >= FLASHIAP_ROM_END, "Test skipped. Test region overlaps code."); ret = flash_device.erase(address + 1, sector_size); TEST_ASSERT_EQUAL_INT32(-1, ret); if (flash_device.get_page_size() > 1) { @@ -178,20 +188,102 @@ void flashiap_program_error_test() TEST_ASSERT_EQUAL_INT32(0, ret); } +void flashiap_timing_test() +{ + FlashIAP flash_device; + uint32_t ret = flash_device.init(); + TEST_ASSERT_EQUAL_INT32(0, ret); + mbed::Timer timer; + unsigned int num_write_sizes; + unsigned int curr_time, byte_usec_ratio; + unsigned int avg_erase_time = 0; + unsigned int max_erase_time = 0, min_erase_time = (unsigned int) -1; + const unsigned int max_writes = 128; + const unsigned int max_write_sizes = 6; + const unsigned int max_byte_usec_ratio = 200; + + uint32_t page_size = flash_device.get_page_size(); + uint32_t write_size = page_size; + + uint32_t end_address = flash_device.get_flash_start() + flash_device.get_flash_size(); + + utest_printf("\nFlash timing:\n"); + uint32_t sector_size = flash_device.get_sector_size(end_address - 1UL); + uint32_t base_address = end_address - sector_size; + timer.start(); + for (num_write_sizes = 0; num_write_sizes < max_write_sizes; num_write_sizes++) { + if (write_size > sector_size) { + break; + } + uint8_t *buf = new (std::nothrow) uint8_t[write_size]; + if (!buf) { + // Don't fail the test on lack of heap memory for the buffer + break; + } + memset(buf, 0x5A, write_size); + timer.reset(); + ret = flash_device.erase(base_address, sector_size); + curr_time = timer.read_us(); + avg_erase_time += curr_time; + TEST_ASSERT_EQUAL_INT32(0, ret); + max_erase_time = std::max(max_erase_time, curr_time); + min_erase_time = std::min(min_erase_time, curr_time); + uint32_t address = base_address; + unsigned int avg_write_time = 0; + unsigned int max_write_time = 0, min_write_time = (unsigned int) -1; + unsigned int num_writes; + for (num_writes = 0; num_writes < max_writes; num_writes++) { + if ((address + write_size) > end_address) { + break; + } + timer.reset(); + ret = flash_device.program(buf, address, write_size); + curr_time = timer.read_us(); + avg_write_time += curr_time; + TEST_ASSERT_EQUAL_INT32(0, ret); + max_write_time = std::max(max_write_time, curr_time); + min_write_time = std::min(min_write_time, curr_time); + address += write_size; + } + delete[] buf; + avg_write_time /= num_writes; + utest_printf("Write size %6u bytes: avg %10u, min %10u, max %10u (usec)\n", + write_size, avg_write_time, min_write_time, max_write_time); + byte_usec_ratio = write_size / avg_write_time; + TEST_ASSERT(byte_usec_ratio < max_byte_usec_ratio); + write_size *= 4; + } + + if (num_write_sizes) { + avg_erase_time /= num_write_sizes; + utest_printf("\nErase size %6u bytes: avg %10u, min %10u, max %10u (usec)\n\n", + sector_size, avg_erase_time, min_erase_time, max_erase_time); + byte_usec_ratio = sector_size / avg_erase_time; + TEST_ASSERT(byte_usec_ratio < max_byte_usec_ratio); + } + + 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 across sectors", flashiap_cross_sector_program_test), Case("FlashIAP - program errors", flashiap_program_error_test), + Case("FlashIAP - timing", flashiap_timing_test), }; -utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { - GREENTEA_SETUP(20, "default_auto"); +utest::v1::status_t greentea_test_setup(const size_t number_of_cases) +{ + GREENTEA_SETUP(120, "default_auto"); return greentea_test_setup_handler(number_of_cases); } Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); -int main() { +int main() +{ Harness::run(specification); } diff --git a/TESTS/mbed_drivers/generic_tests/main.cpp b/TESTS/mbed_drivers/generic_tests/main.cpp index dc177e3f4d52..6c30816dc85d 100644 --- a/TESTS/mbed_drivers/generic_tests/main.cpp +++ b/TESTS/mbed_drivers/generic_tests/main.cpp @@ -28,48 +28,56 @@ using namespace utest::v1; class CppTestCaseHelperClass { private: - const char* name; + const char *name; const unsigned pattern; public: - CppTestCaseHelperClass(const char* _name) : name(_name), pattern(PATTERN_CHECK_VALUE) { + CppTestCaseHelperClass(const char *_name) : name(_name), pattern(PATTERN_CHECK_VALUE) + { print("init"); } - void print(const char *message) { + void print(const char *message) + { printf("%s::%s\n", name, message); } - bool check_init(void) { + bool check_init(void) + { bool result = (pattern == PATTERN_CHECK_VALUE); print(result ? "check_init: OK" : "check_init: ERROR"); return result; } - void stack_test(void) { + void stack_test(void) + { print("stack_test"); CppTestCaseHelperClass t("Stack"); t.hello(); } - void hello(void) { + void hello(void) + { print("hello"); } - ~CppTestCaseHelperClass() { + ~CppTestCaseHelperClass() + { print("destroy"); } }; -void test_case_basic() { +void test_case_basic() +{ TEST_ASSERT_TRUE(true); TEST_ASSERT_FALSE(false); TEST_ASSERT_EQUAL_STRING("The quick brown fox jumps over the lazy dog", - "The quick brown fox jumps over the lazy dog"); + "The quick brown fox jumps over the lazy dog"); } -void test_case_blinky() { +void test_case_blinky() +{ static DigitalOut myled(LED1); const int cnt_max = 1024; for (int cnt = 0; cnt < cnt_max; ++cnt) { @@ -77,7 +85,8 @@ void test_case_blinky() { } } -void test_case_cpp_stack() { +void test_case_cpp_stack() +{ // Check C++ start-up initialisation CppTestCaseHelperClass s("Static"); @@ -86,7 +95,8 @@ void test_case_cpp_stack() { TEST_ASSERT_TRUE_MESSAGE(s.check_init(), "s.check_init() failed"); } -void test_case_cpp_heap() { +void test_case_cpp_heap() +{ // Heap test object simple test CppTestCaseHelperClass *m = new CppTestCaseHelperClass("Heap"); m->hello(); @@ -94,7 +104,8 @@ void test_case_cpp_heap() { delete m; } -utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) { +utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) +{ greentea_case_failure_abort_handler(source, reason); return STATUS_CONTINUE; } @@ -107,13 +118,15 @@ Case cases[] = { Case("C++ heap", test_case_cpp_heap, greentea_failure_handler) }; -utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { +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() { +int main() +{ Harness::run(specification); } diff --git a/TESTS/mbed_drivers/lp_ticker/main.cpp b/TESTS/mbed_drivers/lp_ticker/main.cpp index 35a5b87a4357..ece4562f06c7 100644 --- a/TESTS/mbed_drivers/lp_ticker/main.cpp +++ b/TESTS/mbed_drivers/lp_ticker/main.cpp @@ -20,7 +20,7 @@ #if !DEVICE_LPTICKER - #error [NOT_SUPPORTED] Low power ticker not supported for this target +#error [NOT_SUPPORTED] Low power ticker not supported for this target #endif using utest::v1::Case; @@ -53,12 +53,12 @@ void sem_release(Semaphore *sem) void stop_gtimer_set_flag(void) { gtimer.stop(); - core_util_atomic_incr_u32((uint32_t*)&ticker_callback_flag, 1); + core_util_atomic_incr_u32((uint32_t *)&ticker_callback_flag, 1); } void increment_multi_counter(void) { - core_util_atomic_incr_u32((uint32_t*)&multi_counter, 1);; + core_util_atomic_incr_u32((uint32_t *)&multi_counter, 1);; } /** Test many tickers run one after the other @@ -83,7 +83,7 @@ void test_multi_ticker(void) TEST_ASSERT_EQUAL(TICKER_COUNT, multi_counter); for (int i = 0; i < TICKER_COUNT; i++) { - ticker[i].detach(); + ticker[i].detach(); } // Because detach calls schedule_interrupt in some circumstances // (e.g. when head event is removed), it's good to check if @@ -125,7 +125,7 @@ void test_multi_call_time(void) gtimer.start(); ticker.attach_us(callback(stop_gtimer_set_flag), MULTI_TICKER_TIME_MS * 1000); - while(!ticker_callback_flag); + while (!ticker_callback_flag); time_diff = gtimer.read_us(); TEST_ASSERT_UINT32_WITHIN(TOLERANCE_US(MULTI_TICKER_TIME_MS * 1000), MULTI_TICKER_TIME_MS * 1000, time_diff); @@ -174,7 +174,7 @@ void test_attach_time(void) gtimer.reset(); gtimer.start(); ticker.attach(callback(stop_gtimer_set_flag), ((float)DELAY_US) / 1000000.0f); - while(!ticker_callback_flag); + while (!ticker_callback_flag); ticker.detach(); const int time_diff = gtimer.read_us(); @@ -196,7 +196,7 @@ void test_attach_us_time(void) gtimer.reset(); gtimer.start(); ticker.attach_us(callback(stop_gtimer_set_flag), DELAY_US); - while(!ticker_callback_flag); + while (!ticker_callback_flag); ticker.detach(); const int time_diff = gtimer.read_us(); diff --git a/TESTS/mbed_drivers/lp_timeout/main.cpp b/TESTS/mbed_drivers/lp_timeout/main.cpp index b3cbe7de0acc..ec8f36e60cb5 100644 --- a/TESTS/mbed_drivers/lp_timeout/main.cpp +++ b/TESTS/mbed_drivers/lp_timeout/main.cpp @@ -15,7 +15,7 @@ */ #if !DEVICE_LPTICKER - #error [NOT_SUPPORTED] Low power timer not supported for this target +#error [NOT_SUPPORTED] Low power timer not supported for this target #endif #include "mbed.h" @@ -26,7 +26,7 @@ using namespace utest::v1; -utest::v1::status_t greentea_failure_handler(const Case * const source, const failure_t reason) +utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) { greentea_case_failure_abort_handler(source, reason); return STATUS_CONTINUE; @@ -49,30 +49,30 @@ Case cases[] = { Case("Zero delay (attach_us)", test_no_wait >), Case("10 ms delay accuracy (attach)", test_delay_accuracy, 10000, SHORT_DELTA_US>, - greentea_failure_handler), + greentea_failure_handler), Case("10 ms delay accuracy (attach_us)", test_delay_accuracy, 10000, SHORT_DELTA_US>, - greentea_failure_handler), + greentea_failure_handler), Case("1 s delay accuracy (attach)", test_delay_accuracy, 1000000, LONG_DELTA_US>, - greentea_failure_handler), + greentea_failure_handler), Case("1 s delay accuracy (attach_us)", test_delay_accuracy, 1000000, LONG_DELTA_US>, - greentea_failure_handler), + greentea_failure_handler), Case("5 s delay accuracy (attach)", test_delay_accuracy, 5000000, LONG_DELTA_US>, - greentea_failure_handler), + greentea_failure_handler), Case("5 s delay accuracy (attach_us)", test_delay_accuracy, 5000000, LONG_DELTA_US>, - greentea_failure_handler), + greentea_failure_handler), #if DEVICE_SLEEP Case("1 s delay during sleep (attach)", test_sleep, 1000000, LONG_DELTA_US>, - greentea_failure_handler), + greentea_failure_handler), Case("1 s delay during sleep (attach_us)", test_sleep, 1000000, LONG_DELTA_US>, - greentea_failure_handler), + greentea_failure_handler), Case("1 s delay during deepsleep (attach)", test_deepsleep, 1000000, LONG_DELTA_US>, - greentea_failure_handler), + greentea_failure_handler), Case("1 s delay during deepsleep (attach_us)", test_deepsleep, 1000000, LONG_DELTA_US>, - greentea_failure_handler), + greentea_failure_handler), #endif Case("Timing drift (attach)", test_drift >), diff --git a/TESTS/mbed_drivers/lp_timer/main.cpp b/TESTS/mbed_drivers/lp_timer/main.cpp index 56d37fd8d5d9..d41fd806affb 100644 --- a/TESTS/mbed_drivers/lp_timer/main.cpp +++ b/TESTS/mbed_drivers/lp_timer/main.cpp @@ -35,17 +35,17 @@ extern uint32_t SystemCoreClock; * timer we need to adjust delta. */ - /* - * Define tolerance as follows: - * tolerance = 500 us + 5% of measured time - * - * e.g. - * 1 ms delay: tolerance = 550 us - * 10 ms delay: tolerance = 1000 us - * 100 ms delay: tolerance = 5500 us - * 1000 ms delay: tolerance = 50500 us - * - * */ +/* +* Define tolerance as follows: +* tolerance = 500 us + 5% of measured time +* +* e.g. +* 1 ms delay: tolerance = 550 us +* 10 ms delay: tolerance = 1000 us +* 100 ms delay: tolerance = 5500 us +* 1000 ms delay: tolerance = 50500 us +* +* */ #define US_PER_SEC 1000000 #define US_PER_MSEC 1000 @@ -292,7 +292,7 @@ void test_lptimer_float_operator() lp_timer.stop(); /* Check result - 10 ms elapsed. */ - TEST_ASSERT_FLOAT_WITHIN(DELTA_S(10), 0.010f, (float )(lp_timer)); + TEST_ASSERT_FLOAT_WITHIN(DELTA_S(10), 0.010f, (float)(lp_timer)); } /* This test verifies if time counted by the low power timer is @@ -320,7 +320,7 @@ void test_lptimer_time_measurement() lp_timer.stop(); /* Check results - wait_val_us us have elapsed. */ - TEST_ASSERT_FLOAT_WITHIN(DELTA_S(delta_ms), (float )wait_val_us / 1000000, lp_timer.read()); + TEST_ASSERT_FLOAT_WITHIN(DELTA_S(delta_ms), (float)wait_val_us / 1000000, lp_timer.read()); TEST_ASSERT_INT32_WITHIN(DELTA_MS(delta_ms), wait_val_us / 1000, lp_timer.read_ms()); TEST_ASSERT_INT32_WITHIN(DELTA_US(delta_ms), wait_val_us, lp_timer.read_us()); TEST_ASSERT_UINT64_WITHIN(DELTA_US(delta_ms), wait_val_us, lp_timer.read_high_resolution_us()); diff --git a/TESTS/mbed_drivers/mem_trace/main.cpp b/TESTS/mbed_drivers/mem_trace/main.cpp index 286be0377b00..77dd39716caf 100644 --- a/TESTS/mbed_drivers/mem_trace/main.cpp +++ b/TESTS/mbed_drivers/mem_trace/main.cpp @@ -25,7 +25,7 @@ #include #ifndef MBED_MEM_TRACING_ENABLED - #error [NOT_SUPPORTED] test not supported +#error [NOT_SUPPORTED] test not supported #endif using utest::v1::Case; @@ -99,7 +99,7 @@ extern "C" void test_trace_cb(uint8_t op, void *res, void *caller, ...) va_start(va, caller); pmem->op = op; pmem->res = res; - switch(op) { + switch (op) { case MBED_MEM_TRACE_MALLOC: pmem->malloc_info.arg_size = va_arg(va, size_t); break; @@ -180,7 +180,7 @@ void malloc_free(volatile bool *thread_continue) { const size_t block_size = 126; - while(*thread_continue) { + while (*thread_continue) { void *p = malloc(block_size); TEST_ASSERT_NOT_EQUAL(p, NULL); free(p); @@ -403,8 +403,7 @@ static void test_case_multithread_malloc_free() -static Case cases[] = -{ +static Case cases[] = { Case("Test single malloc/free trace", test_case_single_malloc_free), Case("Test all memory operations trace", test_case_all_memory_ops), Case("Test trace off", test_case_trace_off), diff --git a/TESTS/mbed_drivers/race_test/main.cpp b/TESTS/mbed_drivers/race_test/main.cpp index d1fb39f1d533..ca03daaaf43f 100644 --- a/TESTS/mbed_drivers/race_test/main.cpp +++ b/TESTS/mbed_drivers/race_test/main.cpp @@ -23,7 +23,7 @@ #include #ifdef MBED_RTOS_SINGLE_THREAD - #error [NOT_SUPPORTED] test not supported for single threaded enviroment +#error [NOT_SUPPORTED] test not supported for single threaded enviroment #endif #if !DEVICE_USTICKER @@ -37,21 +37,24 @@ static uint32_t instance_count = 0; class TestClass { public: - TestClass() { + TestClass() + { Thread::wait(500); instance_count++; } - void do_something() { + void do_something() + { Thread::wait(100); } - ~TestClass() { + ~TestClass() + { instance_count--; } }; -static TestClass* get_test_class() +static TestClass *get_test_class() { static TestClass tc; return &tc; diff --git a/TESTS/mbed_drivers/rtc/main.cpp b/TESTS/mbed_drivers/rtc/main.cpp index d0ebba2c72bb..460785b1203b 100644 --- a/TESTS/mbed_drivers/rtc/main.cpp +++ b/TESTS/mbed_drivers/rtc/main.cpp @@ -56,9 +56,9 @@ static time_t read_rtc_stub(void) /* Stub of RTC write function. */ static void write_rtc_stub(time_t t) { - rtc_write_called = true; + rtc_write_called = true; - rtc_time_val = t; + rtc_time_val = t; } /* Stub of RTC init function. */ @@ -294,7 +294,7 @@ void test_time_read_RTC_func_undefined() seconds = time(NULL); /* Check if expected value has been returned. */ - TEST_ASSERT_EQUAL((time_t)-1, seconds); + TEST_ASSERT_EQUAL((time_t) -1, seconds); } /* This test verifies if time() function stores @@ -490,6 +490,7 @@ Case cases[] = { Specification specification(test_setup, cases); -int main() { +int main() +{ return !Harness::run(specification); } diff --git a/TESTS/mbed_drivers/sleep_lock/main.cpp b/TESTS/mbed_drivers/sleep_lock/main.cpp index 2e1bcbd80a21..7986845f5780 100644 --- a/TESTS/mbed_drivers/sleep_lock/main.cpp +++ b/TESTS/mbed_drivers/sleep_lock/main.cpp @@ -16,7 +16,7 @@ */ #if !DEVICE_SLEEP - #error [NOT_SUPPORTED] Sleep not supported for this target +#error [NOT_SUPPORTED] Sleep not supported for this target #endif #include "utest/utest.h" @@ -29,90 +29,90 @@ using namespace utest::v1; void deep_sleep_lock_lock_test() { - TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep()); + TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check()); { // Check basic usage works DeepSleepLock lock; - TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep()); + TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep_test_check()); } - TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep()); + TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check()); { // Check that unlock and lock change can deep sleep as expected DeepSleepLock lock; - TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep()); + TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep_test_check()); lock.unlock(); - TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep()); + TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check()); lock.lock(); - TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep()); + TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep_test_check()); } - TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep()); + TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check()); { // Check that unlock releases sleep based on count DeepSleepLock lock; lock.lock(); lock.lock(); lock.unlock(); - TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep()); + TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep_test_check()); } - TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep()); + TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check()); { // Check that unbalanced locks do not leave deep sleep locked DeepSleepLock lock; lock.lock(); - TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep()); + TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep_test_check()); } - TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep()); + TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check()); } void timer_lock_test() { - TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep()); + TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check()); { // Just creating a timer object does not lock sleep Timer timer; - TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep()); + TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check()); } - TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep()); + TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check()); { // Starting a timer does lock sleep Timer timer; timer.start(); - TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep()); + TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep_test_check()); } - TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep()); + TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check()); { // Stopping a timer after starting it allows sleep Timer timer; timer.start(); timer.stop(); - TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep()); + TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check()); } - TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep()); + TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check()); { // Starting a timer multiple times still lets you sleep Timer timer; timer.start(); timer.start(); } - TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep()); + TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check()); - TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep()); + TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check()); { // Stopping a timer multiple times still lets you sleep Timer timer; timer.start(); timer.stop(); timer.stop(); - TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep()); + TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check()); } - TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep()); + TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check()); } Case cases[] = { @@ -120,13 +120,15 @@ Case cases[] = { Case("timer lock test", timer_lock_test), }; -utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { +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() { +int main() +{ Harness::run(specification); } diff --git a/TESTS/mbed_drivers/stl_features/main.cpp b/TESTS/mbed_drivers/stl_features/main.cpp index a8a8f904e246..7d0b289e331b 100644 --- a/TESTS/mbed_drivers/stl_features/main.cpp +++ b/TESTS/mbed_drivers/stl_features/main.cpp @@ -39,16 +39,17 @@ using namespace utest::v1; namespace { template -void BubbleSort(T& _array, size_t array_size, F functor) { +void BubbleSort(T &_array, size_t array_size, F functor) +{ bool flag = true; size_t numLength = array_size; - for(size_t i = 1; (i <= numLength) && flag; i++) { + for (size_t i = 1; (i <= numLength) && flag; i++) { flag = false; for (size_t j = 0; j < (numLength - 1); j++) { - if (functor(_array[j+1], _array[j])) { + if (functor(_array[j + 1], _array[j])) { int temp = _array[j]; _array[j] = _array[j + 1]; - _array[j+1] = temp; + _array[j + 1] = temp; flag = true; } } @@ -56,27 +57,33 @@ void BubbleSort(T& _array, size_t array_size, F functor) { } struct greaterAbs { - bool operator()(int a, int b) { return abs(a) > abs(b); } + bool operator()(int a, int b) + { + return abs(a) > abs(b); + } }; } // namespace -void test_case_stl_equal() { +void test_case_stl_equal() +{ const int n_integers[] = {NEGATIVE_INTEGERS}; std::vector v_pints(n_integers, n_integers + TABLE_SIZE(n_integers)); TEST_ASSERT_TRUE(std::equal(v_pints.begin(), v_pints.end(), n_integers)); } -void test_case_stl_transform() { +void test_case_stl_transform() +{ const float floats[] = {FLOATS}; - const char* floats_str[] = {FLOATS_STR}; + const char *floats_str[] = {FLOATS_STR}; float floats_transform[TABLE_SIZE(floats_str)] = {0.0}; std::transform(floats_str, floats_str + TABLE_SIZE(floats_str), floats_transform, atof); TEST_ASSERT_TRUE(std::equal(floats_transform, floats_transform + TABLE_SIZE(floats_transform), floats)); } -void test_case_stl_sort_greater() { +void test_case_stl_sort_greater() +{ int n_integers[] = {NEGATIVE_INTEGERS}; int n_integers2[] = {NEGATIVE_INTEGERS}; @@ -87,7 +94,8 @@ void test_case_stl_sort_greater() { } -void test_case_stl_sort_abs() { +void test_case_stl_sort_abs() +{ int n_integers[] = {NEGATIVE_INTEGERS}; int n_integers2[] = {NEGATIVE_INTEGERS}; @@ -98,7 +106,8 @@ void test_case_stl_sort_abs() { } -utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) { +utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) +{ greentea_case_failure_abort_handler(source, reason); return STATUS_CONTINUE; } @@ -110,13 +119,15 @@ Case cases[] = { Case("STL std::sort abs", test_case_stl_sort_abs, greentea_failure_handler) }; -utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { +utest::v1::status_t greentea_test_setup(const size_t number_of_cases) +{ GREENTEA_SETUP(5, "default_auto"); return greentea_test_setup_handler(number_of_cases); } Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); -int main() { +int main() +{ Harness::run(specification); } diff --git a/TESTS/mbed_drivers/ticker/main.cpp b/TESTS/mbed_drivers/ticker/main.cpp index 70e2ea99550b..35e696e5f922 100644 --- a/TESTS/mbed_drivers/ticker/main.cpp +++ b/TESTS/mbed_drivers/ticker/main.cpp @@ -19,7 +19,7 @@ #include "unity/unity.h" #if !DEVICE_USTICKER - #error [NOT_SUPPORTED] test not supported +#error [NOT_SUPPORTED] test not supported #endif using utest::v1::Case; @@ -48,7 +48,7 @@ volatile int ticker_count = 0; void switch_led1_state(void) { // blink 3 times per second - if((callback_trigger_count % 333) == 0) { + if ((callback_trigger_count % 333) == 0) { led1 = !led1; } } @@ -57,7 +57,7 @@ void switch_led2_state(void) { // blink 3 times per second // make led2 blink at the same callback_trigger_count value as led1 - if(((callback_trigger_count - 1) % 333) == 0) { + if (((callback_trigger_count - 1) % 333) == 0) { led2 = !led2; } } @@ -84,12 +84,12 @@ void sem_release(Semaphore *sem) void stop_gtimer_set_flag(void) { gtimer.stop(); - core_util_atomic_incr_u32((uint32_t*)&ticker_callback_flag, 1); + core_util_atomic_incr_u32((uint32_t *)&ticker_callback_flag, 1); } void increment_multi_counter(void) { - core_util_atomic_incr_u32((uint32_t*)&multi_counter, 1); + core_util_atomic_incr_u32((uint32_t *)&multi_counter, 1); } @@ -130,7 +130,7 @@ void test_case_1x_ticker() //get the results from host greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value)); - TEST_ASSERT_EQUAL_STRING_MESSAGE("pass", _key,"Host side script reported a fail..."); + TEST_ASSERT_EQUAL_STRING_MESSAGE("pass", _key, "Host side script reported a fail..."); } /* Tests is to measure the accuracy of Ticker over a period of time @@ -174,7 +174,7 @@ void test_case_2x_ticker() //get the results from host greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value)); - TEST_ASSERT_EQUAL_STRING_MESSAGE("pass", _key,"Host side script reported a fail..."); + TEST_ASSERT_EQUAL_STRING_MESSAGE("pass", _key, "Host side script reported a fail..."); } /** Test many tickers run one after the other @@ -199,7 +199,7 @@ void test_multi_ticker(void) TEST_ASSERT_EQUAL(TICKER_COUNT, multi_counter); for (int i = 0; i < TICKER_COUNT; i++) { - ticker[i].detach(); + ticker[i].detach(); } // Because detach calls schedule_interrupt in some circumstances // (e.g. when head event is removed), it's good to check if @@ -241,7 +241,7 @@ void test_multi_call_time(void) gtimer.start(); ticker.attach_us(callback(stop_gtimer_set_flag), MULTI_TICKER_TIME_MS * 1000); - while(!ticker_callback_flag); + while (!ticker_callback_flag); time_diff = gtimer.read_us(); TEST_ASSERT_UINT32_WITHIN(TOLERANCE_US, MULTI_TICKER_TIME_MS * 1000, time_diff); @@ -290,7 +290,7 @@ void test_attach_time(void) gtimer.reset(); gtimer.start(); ticker.attach(callback(stop_gtimer_set_flag), ((float)DELAY_US) / 1000000.0f); - while(!ticker_callback_flag); + while (!ticker_callback_flag); ticker.detach(); const int time_diff = gtimer.read_us(); @@ -312,7 +312,7 @@ void test_attach_us_time(void) gtimer.reset(); gtimer.start(); ticker.attach_us(callback(stop_gtimer_set_flag), DELAY_US); - while(!ticker_callback_flag); + while (!ticker_callback_flag); ticker.detach(); const int time_diff = gtimer.read_us(); diff --git a/TESTS/mbed_drivers/timeout/main.cpp b/TESTS/mbed_drivers/timeout/main.cpp index 8670a7300dd2..2be400a8b44f 100644 --- a/TESTS/mbed_drivers/timeout/main.cpp +++ b/TESTS/mbed_drivers/timeout/main.cpp @@ -25,7 +25,7 @@ using namespace utest::v1; -utest::v1::status_t greentea_failure_handler(const Case * const source, const failure_t reason) +utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) { greentea_case_failure_abort_handler(source, reason); return STATUS_CONTINUE; @@ -48,25 +48,25 @@ Case cases[] = { Case("Zero delay (attach_us)", test_no_wait >), Case("10 ms delay accuracy (attach)", test_delay_accuracy, 10000, SHORT_DELTA_US>, - greentea_failure_handler), + greentea_failure_handler), Case("10 ms delay accuracy (attach_us)", test_delay_accuracy, 10000, SHORT_DELTA_US>, - greentea_failure_handler), + greentea_failure_handler), Case("1 s delay accuracy (attach)", test_delay_accuracy, 1000000, LONG_DELTA_US>, - greentea_failure_handler), + greentea_failure_handler), Case("1 s delay accuracy (attach_us)", test_delay_accuracy, 1000000, LONG_DELTA_US>, - greentea_failure_handler), + greentea_failure_handler), Case("5 s delay accuracy (attach)", test_delay_accuracy, 5000000, LONG_DELTA_US>, - greentea_failure_handler), + greentea_failure_handler), Case("5 s delay accuracy (attach_us)", test_delay_accuracy, 5000000, LONG_DELTA_US>, - greentea_failure_handler), + greentea_failure_handler), #if DEVICE_SLEEP Case("1 s delay during sleep (attach)", test_sleep, 1000000, LONG_DELTA_US>, - greentea_failure_handler), + greentea_failure_handler), Case("1 s delay during sleep (attach_us)", test_sleep, 1000000, LONG_DELTA_US>, - greentea_failure_handler), + greentea_failure_handler), #endif Case("Timing drift (attach)", test_drift >), diff --git a/TESTS/mbed_drivers/timeout/timeout_tests.h b/TESTS/mbed_drivers/timeout/timeout_tests.h index 390432848bba..4c1311d85da8 100644 --- a/TESTS/mbed_drivers/timeout/timeout_tests.h +++ b/TESTS/mbed_drivers/timeout/timeout_tests.h @@ -81,10 +81,10 @@ void test_single_call(void) int32_t sem_slots = sem.wait(0); TEST_ASSERT_EQUAL(0, sem_slots); - sem_slots = sem.wait(TEST_DELAY_MS + 1); + sem_slots = sem.wait(TEST_DELAY_MS + 2); TEST_ASSERT_EQUAL(1, sem_slots); - sem_slots = sem.wait(TEST_DELAY_MS + 1); + sem_slots = sem.wait(TEST_DELAY_MS + 2); TEST_ASSERT_EQUAL(0, sem_slots); timeout.detach(); @@ -114,7 +114,7 @@ void test_cancel(void) TEST_ASSERT_EQUAL(0, sem_slots); timeout.detach(); - sem_slots = sem.wait(TEST_DELAY_MS + 1); + sem_slots = sem.wait(TEST_DELAY_MS + 2); TEST_ASSERT_EQUAL(0, sem_slots); } @@ -147,7 +147,7 @@ void test_override(void) TEST_ASSERT_EQUAL(0, sem_slots); timeout.attach_callback(mbed::callback(sem_callback, &sem2), 2.0f * TEST_DELAY_US); - sem_slots = sem2.wait(2 * TEST_DELAY_MS + 1); + sem_slots = sem2.wait(2 * TEST_DELAY_MS + 2); TEST_ASSERT_EQUAL(1, sem_slots); sem_slots = sem1.wait(0); TEST_ASSERT_EQUAL(0, sem_slots); @@ -177,7 +177,7 @@ void test_multiple(void) for (size_t i = 0; i < NUM_TIMEOUTS; i++) { timeouts[i].attach_callback(mbed::callback(cnt_callback, &callback_count), TEST_DELAY_US); } - Thread::wait(TEST_DELAY_MS + 1); + Thread::wait(TEST_DELAY_MS + 2); TEST_ASSERT_EQUAL(NUM_TIMEOUTS, callback_count); } @@ -263,7 +263,7 @@ void test_sleep(void) timer.start(); timeout.attach_callback(mbed::callback(sem_callback, &sem), delay_us); - bool deep_sleep_allowed = sleep_manager_can_deep_sleep(); + bool deep_sleep_allowed = sleep_manager_can_deep_sleep_test_check(); TEST_ASSERT_FALSE_MESSAGE(deep_sleep_allowed, "Deep sleep should be disallowed"); while (sem.wait(0) != 1) { sleep(); @@ -322,7 +322,7 @@ void test_deepsleep(void) timer.start(); timeout.attach_callback(mbed::callback(sem_callback, &sem), delay_us); - bool deep_sleep_allowed = sleep_manager_can_deep_sleep(); + bool deep_sleep_allowed = sleep_manager_can_deep_sleep_test_check(); TEST_ASSERT_TRUE_MESSAGE(deep_sleep_allowed, "Deep sleep should be allowed"); while (sem.wait(0) != 1) { sleep(); @@ -340,7 +340,7 @@ template class TimeoutDriftTester { public: TimeoutDriftTester(us_timestamp_t period = 1000) : - _callback_count(0), _period(period), _timeout() + _callback_count(0), _period(period), _timeout() { } diff --git a/TESTS/mbed_drivers/timer/main.cpp b/TESTS/mbed_drivers/timer/main.cpp index d94ef6b686d7..d04cd54e76e2 100644 --- a/TESTS/mbed_drivers/timer/main.cpp +++ b/TESTS/mbed_drivers/timer/main.cpp @@ -23,7 +23,7 @@ #include "hal/us_ticker_api.h" #if !DEVICE_USTICKER - #error [NOT_SUPPORTED] test not supported +#error [NOT_SUPPORTED] test not supported #endif using namespace utest::v1; @@ -34,17 +34,17 @@ extern uint32_t SystemCoreClock; #define US_PER_MSEC 1000 #define MSEC_PER_SEC 1000 - /* - * Define tolerance as follows: - * tolerance = 500 us + 2% of measured time - * - * e.g. - * 1 ms delay: tolerance = 520 us - * 10 ms delay: tolerance = 700 us - * 100 ms delay: tolerance = 2500 us - * 1000 ms delay: tolerance = 20500 us - * - * */ +/* +* Define tolerance as follows: +* tolerance = 500 us + 2% of measured time +* +* e.g. +* 1 ms delay: tolerance = 520 us +* 10 ms delay: tolerance = 700 us +* 100 ms delay: tolerance = 2500 us +* 1000 ms delay: tolerance = 20500 us +* +* */ #ifdef NO_SYSTICK #define TOLERANCE 5 #else @@ -65,6 +65,20 @@ static Timer *p_timer = NULL; */ static uint32_t curr_ticker_ticks_val; + +/* Replacement for generic wait functions to avoid invoking OS scheduling stuff. */ +void busy_wait_us(int us) +{ + const ticker_data_t *const ticker = get_us_ticker_data(); + uint32_t start = ticker_read(ticker); + while ((ticker_read(ticker) - start) < (uint32_t)us); +} + +void busy_wait_ms(int ms) +{ + busy_wait_us(ms * US_PER_MSEC); +} + /* User ticker interface function. */ static void stub_interface_init() { @@ -103,10 +117,16 @@ static void stub_fire_interrupt(void) /* do nothing. */ } +/* User ticker interface function. */ +static void stub_free(void) +{ + /* do nothing. */ +} + ticker_info_t info = { TICKER_FREQ_1MHZ, TICKER_BITS }; -const ticker_info_t * stub_get_info(void) +const ticker_info_t *stub_get_info(void) { return &info; } @@ -122,6 +142,7 @@ static const ticker_interface_t us_interface = { .clear_interrupt = stub_clear_interrupt, .set_interrupt = stub_set_interrupt, .fire_interrupt = stub_fire_interrupt, + .free = stub_free, .get_info = stub_get_info, }; @@ -132,7 +153,7 @@ static const ticker_data_t us_data = { }; /* Function which returns user ticker data. */ -const ticker_data_t* get_user_ticker_data(void) +const ticker_data_t *get_user_ticker_data(void) { return &us_data; } @@ -196,7 +217,7 @@ void test_timer_creation_os_ticker() /* Wait 10 ms. * After that operation timer read routines should still return 0. */ - wait_ms(10); + busy_wait_ms(10); /* Check results. */ TEST_ASSERT_EQUAL_FLOAT(0, p_timer->read()); @@ -406,7 +427,7 @@ void test_timer_time_accumulation_os_ticker() p_timer->start(); /* Wait 10 ms. */ - wait_ms(10); + busy_wait_ms(10); /* Stop the timer. */ p_timer->stop(); @@ -420,7 +441,7 @@ void test_timer_time_accumulation_os_ticker() /* Wait 50 ms - this is done to show that time elapsed when * the timer is stopped does not have influence on the * timer counted time. */ - wait_ms(50); + busy_wait_ms(50); /* ------ */ @@ -428,7 +449,7 @@ void test_timer_time_accumulation_os_ticker() p_timer->start(); /* Wait 20 ms. */ - wait_ms(20); + busy_wait_ms(20); /* Stop the timer. */ p_timer->stop(); @@ -449,7 +470,7 @@ void test_timer_time_accumulation_os_ticker() p_timer->start(); /* Wait 30 ms. */ - wait_ms(30); + busy_wait_ms(30); /* Stop the timer. */ p_timer->stop(); @@ -463,7 +484,7 @@ void test_timer_time_accumulation_os_ticker() /* Wait 50 ms - this is done to show that time elapsed when * the timer is stopped does not have influence on the * timer time. */ - wait_ms(50); + busy_wait_ms(50); /* ------ */ @@ -471,7 +492,7 @@ void test_timer_time_accumulation_os_ticker() p_timer->start(); /* Wait 1 sec. */ - wait_ms(1000); + busy_wait_ms(1000); /* Stop the timer. */ p_timer->stop(); @@ -500,7 +521,7 @@ void test_timer_reset_os_ticker() p_timer->start(); /* Wait 10 ms. */ - wait_ms(10); + busy_wait_ms(10); /* Stop the timer. */ p_timer->stop(); @@ -518,7 +539,7 @@ void test_timer_reset_os_ticker() p_timer->start(); /* Wait 20 ms. */ - wait_ms(20); + busy_wait_ms(20); /* Stop the timer. */ p_timer->stop(); @@ -596,13 +617,13 @@ void test_timer_start_started_timer_os_ticker() p_timer->start(); /* Wait 10 ms. */ - wait_ms(10); + busy_wait_ms(10); /* Now start timer again. */ p_timer->start(); /* Wait 20 ms. */ - wait_ms(20); + busy_wait_ms(20); /* Stop the timer. */ p_timer->stop(); @@ -666,7 +687,7 @@ void test_timer_float_operator_os_ticker() p_timer->start(); /* Wait 10 ms. */ - wait_ms(10); + busy_wait_ms(10); /* Stop the timer. */ p_timer->stop(); @@ -721,7 +742,7 @@ void test_timer_time_measurement() p_timer->start(); /* Wait us. */ - wait_us(wait_val_us); + busy_wait_us(wait_val_us); /* Stop the timer. */ p_timer->stop(); @@ -733,7 +754,8 @@ void test_timer_time_measurement() TEST_ASSERT_UINT64_WITHIN(DELTA_US(wait_val_us / US_PER_MSEC), wait_val_us, p_timer->read_high_resolution_us()); } -utest::v1::status_t test_setup(const size_t number_of_cases) { +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); } @@ -762,7 +784,8 @@ Case cases[] = { Specification specification(test_setup, cases); -int main() { +int main() +{ return !Harness::run(specification); } diff --git a/TESTS/mbed_drivers/timerevent/main.cpp b/TESTS/mbed_drivers/timerevent/main.cpp index 817a8606a6a0..8231edc8f772 100644 --- a/TESTS/mbed_drivers/timerevent/main.cpp +++ b/TESTS/mbed_drivers/timerevent/main.cpp @@ -28,7 +28,7 @@ using namespace utest::v1; #if !DEVICE_USTICKER - #error [NOT_SUPPORTED] test not supported +#error [NOT_SUPPORTED] test not supported #endif #define TEST_DELAY_US 50000ULL @@ -37,22 +37,26 @@ using namespace utest::v1; class TestTimerEvent: public TimerEvent { private: Semaphore sem; - virtual void handler() { + virtual void handler() + { sem.release(); } public: TestTimerEvent() : - TimerEvent(), sem(0, 1) { + TimerEvent(), sem(0, 1) + { sleep_manager_lock_deep_sleep(); } TestTimerEvent(const ticker_data_t *data) : - TimerEvent(data), sem(0, 1) { + TimerEvent(data), sem(0, 1) + { } - virtual ~TestTimerEvent() { + virtual ~TestTimerEvent() + { sleep_manager_unlock_deep_sleep(); } @@ -61,7 +65,8 @@ class TestTimerEvent: public TimerEvent { using TimerEvent::insert_absolute; using TimerEvent::remove; - int32_t sem_wait(uint32_t millisec) { + int32_t sem_wait(uint32_t millisec) + { return sem.wait(millisec); } }; @@ -70,19 +75,23 @@ class TestTimerEventRelative: public TestTimerEvent { public: static const int32_t SEM_SLOTS_AFTER_PAST_TS_INSERTED = 0; TestTimerEventRelative() : - TestTimerEvent() { + TestTimerEvent() + { } TestTimerEventRelative(const ticker_data_t *data) : - TestTimerEvent(data) { + TestTimerEvent(data) + { } // Set relative timestamp of internal event to present_time + ts - void set_future_timestamp(timestamp_t ts) { + void set_future_timestamp(timestamp_t ts) + { insert(::ticker_read(_ticker_data) + ts); } - void set_past_timestamp(void) { + void set_past_timestamp(void) + { insert(::ticker_read(_ticker_data) - 1UL); } }; @@ -91,19 +100,23 @@ class TestTimerEventAbsolute: public TestTimerEvent { public: static const int32_t SEM_SLOTS_AFTER_PAST_TS_INSERTED = 1; TestTimerEventAbsolute() : - TestTimerEvent() { + TestTimerEvent() + { } TestTimerEventAbsolute(const ticker_data_t *data) : - TestTimerEvent(data) { + TestTimerEvent(data) + { } // Set absolute timestamp of internal event to present_time + ts - void set_future_timestamp(us_timestamp_t ts) { + void set_future_timestamp(us_timestamp_t ts) + { insert_absolute(::ticker_read_us(_ticker_data) + ts); } - void set_past_timestamp(void) { + void set_past_timestamp(void) + { insert_absolute(::ticker_read_us(_ticker_data) - 1ULL); } }; @@ -123,7 +136,8 @@ class TestTimerEventAbsolute: public TestTimerEvent { * Then an event handler is called */ template -void test_insert(void) { +void test_insert(void) +{ T tte; tte.set_future_timestamp(TEST_DELAY_US); @@ -151,7 +165,8 @@ void test_insert(void) { * Then the event handler is never called */ template -void test_remove(void) { +void test_remove(void) +{ T tte; tte.set_future_timestamp(TEST_DELAY_US * 2); @@ -168,7 +183,8 @@ void test_remove(void) { * When a timestamp of 0 us is set with @a insert_absolute() * Then an event handler is called instantly */ -void test_insert_zero(void) { +void test_insert_zero(void) +{ TestTimerEvent tte; tte.insert_absolute(0ULL); @@ -194,7 +210,8 @@ void test_insert_zero(void) { * Then an event handler is called instantly */ template -void test_insert_past(void) { +void test_insert_past(void) +{ T tte; tte.set_past_timestamp(); @@ -205,7 +222,7 @@ void test_insert_past(void) { } utest::v1::status_t test_setup(const size_t number_of_cases) - { +{ GREENTEA_SETUP(5, "default_auto"); return verbose_test_setup_handler(number_of_cases); } diff --git a/TESTS/mbed_functional/callback/main.cpp b/TESTS/mbed_functional/callback/main.cpp index f14d75379372..ea941fd77191 100644 --- a/TESTS/mbed_functional/callback/main.cpp +++ b/TESTS/mbed_functional/callback/main.cpp @@ -24,22 +24,34 @@ using namespace utest::v1; // static functions template T static_func0() - { return 0; } +{ + return 0; +} template T static_func1(T a0) - { return 0 | a0; } +{ + return 0 | a0; +} template T static_func2(T a0, T a1) - { return 0 | a0 | a1; } +{ + return 0 | a0 | a1; +} template T static_func3(T a0, T a1, T a2) - { return 0 | a0 | a1 | a2; } +{ + return 0 | a0 | a1 | a2; +} template T static_func4(T a0, T a1, T a2, T a3) - { return 0 | a0 | a1 | a2 | a3; } +{ + return 0 | a0 | a1 | a2 | a3; +} template T static_func5(T a0, T a1, T a2, T a3, T a4) - { return 0 | a0 | a1 | a2 | a3 | a4; } +{ + return 0 | a0 | a1 | a2 | a3 | a4; +} // class functions template @@ -48,205 +60,349 @@ struct Thing { Thing() : t(0x80) {} T member_func0() - { return t; } + { + return t; + } T member_func1(T a0) - { return t | a0; } + { + return t | a0; + } T member_func2(T a0, T a1) - { return t | a0 | a1; } + { + return t | a0 | a1; + } T member_func3(T a0, T a1, T a2) - { return t | a0 | a1 | a2; } + { + return t | a0 | a1 | a2; + } T member_func4(T a0, T a1, T a2, T a3) - { return t | a0 | a1 | a2 | a3; } + { + return t | a0 | a1 | a2 | a3; + } T member_func5(T a0, T a1, T a2, T a3, T a4) - { return t | a0 | a1 | a2 | a3 | a4; } + { + return t | a0 | a1 | a2 | a3 | a4; + } T const_member_func0() const - { return t; } + { + return t; + } T const_member_func1(T a0) const - { return t | a0; } + { + return t | a0; + } T const_member_func2(T a0, T a1) const - { return t | a0 | a1; } + { + return t | a0 | a1; + } T const_member_func3(T a0, T a1, T a2) const - { return t | a0 | a1 | a2; } + { + return t | a0 | a1 | a2; + } T const_member_func4(T a0, T a1, T a2, T a3) const - { return t | a0 | a1 | a2 | a3; } + { + return t | a0 | a1 | a2 | a3; + } T const_member_func5(T a0, T a1, T a2, T a3, T a4) const - { return t | a0 | a1 | a2 | a3 | a4; } + { + return t | a0 | a1 | a2 | a3 | a4; + } T volatile_member_func0() volatile - { return t; } + { + return t; + } T volatile_member_func1(T a0) volatile - { return t | a0; } + { + return t | a0; + } T volatile_member_func2(T a0, T a1) volatile - { return t | a0 | a1; } + { + return t | a0 | a1; + } T volatile_member_func3(T a0, T a1, T a2) volatile - { return t | a0 | a1 | a2; } + { + return t | a0 | a1 | a2; + } T volatile_member_func4(T a0, T a1, T a2, T a3) volatile - { return t | a0 | a1 | a2 | a3; } + { + return t | a0 | a1 | a2 | a3; + } T volatile_member_func5(T a0, T a1, T a2, T a3, T a4) volatile - { return t | a0 | a1 | a2 | a3 | a4; } + { + return t | a0 | a1 | a2 | a3 | a4; + } T const_volatile_member_func0() const volatile - { return t; } + { + return t; + } T const_volatile_member_func1(T a0) const volatile - { return t | a0; } + { + return t | a0; + } T const_volatile_member_func2(T a0, T a1) const volatile - { return t | a0 | a1; } + { + return t | a0 | a1; + } T const_volatile_member_func3(T a0, T a1, T a2) const volatile - { return t | a0 | a1 | a2; } + { + return t | a0 | a1 | a2; + } T const_volatile_member_func4(T a0, T a1, T a2, T a3) const volatile - { return t | a0 | a1 | a2 | a3; } + { + return t | a0 | a1 | a2 | a3; + } T const_volatile_member_func5(T a0, T a1, T a2, T a3, T a4) const volatile - { return t | a0 | a1 | a2 | a3 | a4; } + { + return t | a0 | a1 | a2 | a3 | a4; + } }; // bound functions template T bound_func0(Thing *t) - { return t->t; } +{ + return t->t; +} template T bound_func1(Thing *t, T a0) - { return t->t | a0; } +{ + return t->t | a0; +} template T bound_func2(Thing *t, T a0, T a1) - { return t->t | a0 | a1; } +{ + return t->t | a0 | a1; +} template T bound_func3(Thing *t, T a0, T a1, T a2) - { return t->t | a0 | a1 | a2; } +{ + return t->t | a0 | a1 | a2; +} template T bound_func4(Thing *t, T a0, T a1, T a2, T a3) - { return t->t | a0 | a1 | a2 | a3; } +{ + return t->t | a0 | a1 | a2 | a3; +} template T bound_func5(Thing *t, T a0, T a1, T a2, T a3, T a4) - { return t->t | a0 | a1 | a2 | a3 | a4; } +{ + return t->t | a0 | a1 | a2 | a3 | a4; +} template T const_bound_func0(const Thing *t) - { return t->t; } +{ + return t->t; +} template T const_bound_func1(const Thing *t, T a0) - { return t->t | a0; } +{ + return t->t | a0; +} template T const_bound_func2(const Thing *t, T a0, T a1) - { return t->t | a0 | a1; } +{ + return t->t | a0 | a1; +} template T const_bound_func3(const Thing *t, T a0, T a1, T a2) - { return t->t | a0 | a1 | a2; } +{ + return t->t | a0 | a1 | a2; +} template T const_bound_func4(const Thing *t, T a0, T a1, T a2, T a3) - { return t->t | a0 | a1 | a2 | a3; } +{ + return t->t | a0 | a1 | a2 | a3; +} template T const_bound_func5(const Thing *t, T a0, T a1, T a2, T a3, T a4) - { return t->t | a0 | a1 | a2 | a3 | a4; } +{ + return t->t | a0 | a1 | a2 | a3 | a4; +} template T volatile_bound_func0(volatile Thing *t) - { return t->t; } +{ + return t->t; +} template T volatile_bound_func1(volatile Thing *t, T a0) - { return t->t | a0; } +{ + return t->t | a0; +} template T volatile_bound_func2(volatile Thing *t, T a0, T a1) - { return t->t | a0 | a1; } +{ + return t->t | a0 | a1; +} template T volatile_bound_func3(volatile Thing *t, T a0, T a1, T a2) - { return t->t | a0 | a1 | a2; } +{ + return t->t | a0 | a1 | a2; +} template T volatile_bound_func4(volatile Thing *t, T a0, T a1, T a2, T a3) - { return t->t | a0 | a1 | a2 | a3; } +{ + return t->t | a0 | a1 | a2 | a3; +} template T volatile_bound_func5(volatile Thing *t, T a0, T a1, T a2, T a3, T a4) - { return t->t | a0 | a1 | a2 | a3 | a4; } +{ + return t->t | a0 | a1 | a2 | a3 | a4; +} template T const_volatile_bound_func0(const volatile Thing *t) - { return t->t; } +{ + return t->t; +} template T const_volatile_bound_func1(const volatile Thing *t, T a0) - { return t->t | a0; } +{ + return t->t | a0; +} template T const_volatile_bound_func2(const volatile Thing *t, T a0, T a1) - { return t->t | a0 | a1; } +{ + return t->t | a0 | a1; +} template T const_volatile_bound_func3(const volatile Thing *t, T a0, T a1, T a2) - { return t->t | a0 | a1 | a2; } +{ + return t->t | a0 | a1 | a2; +} template T const_volatile_bound_func4(const volatile Thing *t, T a0, T a1, T a2, T a3) - { return t->t | a0 | a1 | a2 | a3; } +{ + return t->t | a0 | a1 | a2 | a3; +} template T const_volatile_bound_func5(const volatile Thing *t, T a0, T a1, T a2, T a3, T a4) - { return t->t | a0 | a1 | a2 | a3 | a4; } +{ + return t->t | a0 | a1 | a2 | a3 | a4; +} // void functions template T void_func0(void *t) - { return static_cast*>(t)->t; } +{ + return static_cast*>(t)->t; +} template T void_func1(void *t, T a0) - { return static_cast*>(t)->t | a0; } +{ + return static_cast*>(t)->t | a0; +} template T void_func2(void *t, T a0, T a1) - { return static_cast*>(t)->t | a0 | a1; } +{ + return static_cast*>(t)->t | a0 | a1; +} template T void_func3(void *t, T a0, T a1, T a2) - { return static_cast*>(t)->t | a0 | a1 | a2; } +{ + return static_cast*>(t)->t | a0 | a1 | a2; +} template T void_func4(void *t, T a0, T a1, T a2, T a3) - { return static_cast*>(t)->t | a0 | a1 | a2 | a3; } +{ + return static_cast*>(t)->t | a0 | a1 | a2 | a3; +} template T void_func5(void *t, T a0, T a1, T a2, T a3, T a4) - { return static_cast*>(t)->t | a0 | a1 | a2 | a3 | a4; } +{ + return static_cast*>(t)->t | a0 | a1 | a2 | a3 | a4; +} template T const_void_func0(const void *t) - { return static_cast*>(t)->t; } +{ + return static_cast*>(t)->t; +} template T const_void_func1(const void *t, T a0) - { return static_cast*>(t)->t | a0; } +{ + return static_cast*>(t)->t | a0; +} template T const_void_func2(const void *t, T a0, T a1) - { return static_cast*>(t)->t | a0 | a1; } +{ + return static_cast*>(t)->t | a0 | a1; +} template T const_void_func3(const void *t, T a0, T a1, T a2) - { return static_cast*>(t)->t | a0 | a1 | a2; } +{ + return static_cast*>(t)->t | a0 | a1 | a2; +} template T const_void_func4(const void *t, T a0, T a1, T a2, T a3) - { return static_cast*>(t)->t | a0 | a1 | a2 | a3; } +{ + return static_cast*>(t)->t | a0 | a1 | a2 | a3; +} template T const_void_func5(const void *t, T a0, T a1, T a2, T a3, T a4) - { return static_cast*>(t)->t | a0 | a1 | a2 | a3 | a4; } +{ + return static_cast*>(t)->t | a0 | a1 | a2 | a3 | a4; +} template T volatile_void_func0(volatile void *t) - { return static_cast*>(t)->t; } +{ + return static_cast*>(t)->t; +} template T volatile_void_func1(volatile void *t, T a0) - { return static_cast*>(t)->t | a0; } +{ + return static_cast*>(t)->t | a0; +} template T volatile_void_func2(volatile void *t, T a0, T a1) - { return static_cast*>(t)->t | a0 | a1; } +{ + return static_cast*>(t)->t | a0 | a1; +} template T volatile_void_func3(volatile void *t, T a0, T a1, T a2) - { return static_cast*>(t)->t | a0 | a1 | a2; } +{ + return static_cast*>(t)->t | a0 | a1 | a2; +} template T volatile_void_func4(volatile void *t, T a0, T a1, T a2, T a3) - { return static_cast*>(t)->t | a0 | a1 | a2 | a3; } +{ + return static_cast*>(t)->t | a0 | a1 | a2 | a3; +} template T volatile_void_func5(volatile void *t, T a0, T a1, T a2, T a3, T a4) - { return static_cast*>(t)->t | a0 | a1 | a2 | a3 | a4; } +{ + return static_cast*>(t)->t | a0 | a1 | a2 | a3 | a4; +} template T const_volatile_void_func0(const volatile void *t) - { return static_cast*>(t)->t; } +{ + return static_cast*>(t)->t; +} template T const_volatile_void_func1(const volatile void *t, T a0) - { return static_cast*>(t)->t | a0; } +{ + return static_cast*>(t)->t | a0; +} template T const_volatile_void_func2(const volatile void *t, T a0, T a1) - { return static_cast*>(t)->t | a0 | a1; } +{ + return static_cast*>(t)->t | a0 | a1; +} template T const_volatile_void_func3(const volatile void *t, T a0, T a1, T a2) - { return static_cast*>(t)->t | a0 | a1 | a2; } +{ + return static_cast*>(t)->t | a0 | a1 | a2; +} template T const_volatile_void_func4(const volatile void *t, T a0, T a1, T a2, T a3) - { return static_cast*>(t)->t | a0 | a1 | a2 | a3; } +{ + return static_cast*>(t)->t | a0 | a1 | a2 | a3; +} template T const_volatile_void_func5(const volatile void *t, T a0, T a1, T a2, T a3, T a4) - { return static_cast*>(t)->t | a0 | a1 | a2 | a3 | a4; } +{ + return static_cast*>(t)->t | a0 | a1 | a2 | a3 | a4; +} // Inheriting class template @@ -257,73 +413,85 @@ class Thing2 : public Thing { // function call and result verification template struct Verifier { - static void verify0(Callback func) { + static void verify0(Callback func) + { T result = func(); TEST_ASSERT_EQUAL(result, 0x00); } template - static void verify0(O *obj, M method) { + static void verify0(O *obj, M method) + { Callback func(obj, method); T result = func(); TEST_ASSERT_EQUAL(result, 0x80); } - static void verify1(Callback func) { + static void verify1(Callback func) + { T result = func((1 << 0)); TEST_ASSERT_EQUAL(result, 0x00 | (1 << 0)); } template - static void verify1(O *obj, M method) { + static void verify1(O *obj, M method) + { Callback func(obj, method); T result = func((1 << 0)); TEST_ASSERT_EQUAL(result, 0x80 | (1 << 0)); } - static void verify2(Callback func) { + static void verify2(Callback func) + { T result = func((1 << 0), (1 << 1)); TEST_ASSERT_EQUAL(result, 0x00 | (1 << 0) | (1 << 1)); } template - static void verify2(O *obj, M method) { + static void verify2(O *obj, M method) + { Callback func(obj, method); T result = func((1 << 0), (1 << 1)); TEST_ASSERT_EQUAL(result, 0x80 | (1 << 0) | (1 << 1)); } - static void verify3(Callback func) { + static void verify3(Callback func) + { T result = func((1 << 0), (1 << 1), (1 << 2)); TEST_ASSERT_EQUAL(result, 0x00 | (1 << 0) | (1 << 1) | (1 << 2)); } template - static void verify3(O *obj, M method) { + static void verify3(O *obj, M method) + { Callback func(obj, method); T result = func((1 << 0), (1 << 1), (1 << 2)); TEST_ASSERT_EQUAL(result, 0x80 | (1 << 0) | (1 << 1) | (1 << 2)); } - static void verify4(Callback func) { + static void verify4(Callback func) + { T result = func((1 << 0), (1 << 1), (1 << 2), (1 << 3)); TEST_ASSERT_EQUAL(result, 0x00 | (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3)); } template - static void verify4(O *obj, M method) { + static void verify4(O *obj, M method) + { Callback func(obj, method); T result = func((1 << 0), (1 << 1), (1 << 2), (1 << 3)); TEST_ASSERT_EQUAL(result, 0x80 | (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3)); } - static void verify5(Callback func) { + static void verify5(Callback func) + { T result = func((1 << 0), (1 << 1), (1 << 2), (1 << 3), (1 << 4)); TEST_ASSERT_EQUAL(result, 0x00 | (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4)); } template - static void verify5(O *obj, M method) { + static void verify5(O *obj, M method) + { Callback func(obj, method); T result = func((1 << 0), (1 << 1), (1 << 2), (1 << 3), (1 << 4)); TEST_ASSERT_EQUAL(result, 0x80 | (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4)); @@ -333,24 +501,25 @@ struct Verifier { // test dispatch template -void test_dispatch0() { +void test_dispatch0() +{ Thing thing; Thing2 thing2; Verifier::verify0(static_func0); Verifier::verify0(&thing, &Thing::member_func0); - Verifier::verify0((const Thing*)&thing, &Thing::const_member_func0); - Verifier::verify0((volatile Thing*)&thing, &Thing::volatile_member_func0); - Verifier::verify0((const volatile Thing*)&thing, &Thing::const_volatile_member_func0); + Verifier::verify0((const Thing *)&thing, &Thing::const_member_func0); + Verifier::verify0((volatile Thing *)&thing, &Thing::volatile_member_func0); + Verifier::verify0((const volatile Thing *)&thing, &Thing::const_volatile_member_func0); Verifier::verify0(&thing2, &Thing2::member_func0); Verifier::verify0(&bound_func0, &thing); - Verifier::verify0(&const_bound_func0, (const Thing*)&thing); - Verifier::verify0(&volatile_bound_func0, (volatile Thing*)&thing); - Verifier::verify0(&const_volatile_bound_func0, (const volatile Thing*)&thing); + Verifier::verify0(&const_bound_func0, (const Thing *)&thing); + Verifier::verify0(&volatile_bound_func0, (volatile Thing *)&thing); + Verifier::verify0(&const_volatile_bound_func0, (const volatile Thing *)&thing); Verifier::verify0(&bound_func0, &thing2); Verifier::verify0(&void_func0, &thing); - Verifier::verify0(&const_void_func0, (const Thing*)&thing); - Verifier::verify0(&volatile_void_func0, (volatile Thing*)&thing); - Verifier::verify0(&const_volatile_void_func0, (const volatile Thing*)&thing); + Verifier::verify0(&const_void_func0, (const Thing *)&thing); + Verifier::verify0(&volatile_void_func0, (volatile Thing *)&thing); + Verifier::verify0(&const_volatile_void_func0, (const volatile Thing *)&thing); Verifier::verify0(callback(static_func0)); Callback cb(static_func0); @@ -359,28 +528,29 @@ void test_dispatch0() { Verifier::verify0(cb); cb.attach(&bound_func0, &thing); Verifier::verify0(&cb, &Callback::call); - Verifier::verify0(&Callback::thunk, (void*)&cb); + Verifier::verify0(&Callback::thunk, (void *)&cb); } template -void test_dispatch1() { +void test_dispatch1() +{ Thing thing; Thing2 thing2; Verifier::verify1(static_func1); Verifier::verify1(&thing, &Thing::member_func1); - Verifier::verify1((const Thing*)&thing, &Thing::const_member_func1); - Verifier::verify1((volatile Thing*)&thing, &Thing::volatile_member_func1); - Verifier::verify1((const volatile Thing*)&thing, &Thing::const_volatile_member_func1); + Verifier::verify1((const Thing *)&thing, &Thing::const_member_func1); + Verifier::verify1((volatile Thing *)&thing, &Thing::volatile_member_func1); + Verifier::verify1((const volatile Thing *)&thing, &Thing::const_volatile_member_func1); Verifier::verify1(&thing2, &Thing2::member_func1); Verifier::verify1(&bound_func1, &thing); - Verifier::verify1(&const_bound_func1, (const Thing*)&thing); - Verifier::verify1(&volatile_bound_func1, (volatile Thing*)&thing); - Verifier::verify1(&const_volatile_bound_func1, (const volatile Thing*)&thing); + Verifier::verify1(&const_bound_func1, (const Thing *)&thing); + Verifier::verify1(&volatile_bound_func1, (volatile Thing *)&thing); + Verifier::verify1(&const_volatile_bound_func1, (const volatile Thing *)&thing); Verifier::verify1(&bound_func1, &thing2); Verifier::verify1(&void_func1, &thing); - Verifier::verify1(&const_void_func1, (const Thing*)&thing); - Verifier::verify1(&volatile_void_func1, (volatile Thing*)&thing); - Verifier::verify1(&const_volatile_void_func1, (const volatile Thing*)&thing); + Verifier::verify1(&const_void_func1, (const Thing *)&thing); + Verifier::verify1(&volatile_void_func1, (volatile Thing *)&thing); + Verifier::verify1(&const_volatile_void_func1, (const volatile Thing *)&thing); Verifier::verify1(callback(static_func1)); Callback cb(static_func1); @@ -389,28 +559,29 @@ void test_dispatch1() { Verifier::verify1(cb); cb.attach(&bound_func1, &thing); Verifier::verify1(&cb, &Callback::call); - Verifier::verify1(&Callback::thunk, (void*)&cb); + Verifier::verify1(&Callback::thunk, (void *)&cb); } template -void test_dispatch2() { +void test_dispatch2() +{ Thing thing; Thing2 thing2; Verifier::verify2(static_func2); Verifier::verify2(&thing, &Thing::member_func2); - Verifier::verify2((const Thing*)&thing, &Thing::const_member_func2); - Verifier::verify2((volatile Thing*)&thing, &Thing::volatile_member_func2); - Verifier::verify2((const volatile Thing*)&thing, &Thing::const_volatile_member_func2); + Verifier::verify2((const Thing *)&thing, &Thing::const_member_func2); + Verifier::verify2((volatile Thing *)&thing, &Thing::volatile_member_func2); + Verifier::verify2((const volatile Thing *)&thing, &Thing::const_volatile_member_func2); Verifier::verify2(&thing2, &Thing2::member_func2); Verifier::verify2(&bound_func2, &thing); - Verifier::verify2(&const_bound_func2, (const Thing*)&thing); - Verifier::verify2(&volatile_bound_func2, (volatile Thing*)&thing); - Verifier::verify2(&const_volatile_bound_func2, (const volatile Thing*)&thing); + Verifier::verify2(&const_bound_func2, (const Thing *)&thing); + Verifier::verify2(&volatile_bound_func2, (volatile Thing *)&thing); + Verifier::verify2(&const_volatile_bound_func2, (const volatile Thing *)&thing); Verifier::verify2(&bound_func2, &thing2); Verifier::verify2(&void_func2, &thing); - Verifier::verify2(&const_void_func2, (const Thing*)&thing); - Verifier::verify2(&volatile_void_func2, (volatile Thing*)&thing); - Verifier::verify2(&const_volatile_void_func2, (const volatile Thing*)&thing); + Verifier::verify2(&const_void_func2, (const Thing *)&thing); + Verifier::verify2(&volatile_void_func2, (volatile Thing *)&thing); + Verifier::verify2(&const_volatile_void_func2, (const volatile Thing *)&thing); Verifier::verify2(callback(static_func2)); Callback cb(static_func2); @@ -419,28 +590,29 @@ void test_dispatch2() { Verifier::verify2(cb); cb.attach(&bound_func2, &thing); Verifier::verify2(&cb, &Callback::call); - Verifier::verify2(&Callback::thunk, (void*)&cb); + Verifier::verify2(&Callback::thunk, (void *)&cb); } template -void test_dispatch3() { +void test_dispatch3() +{ Thing thing; Thing2 thing2; Verifier::verify3(static_func3); Verifier::verify3(&thing, &Thing::member_func3); - Verifier::verify3((const Thing*)&thing, &Thing::const_member_func3); - Verifier::verify3((volatile Thing*)&thing, &Thing::volatile_member_func3); - Verifier::verify3((const volatile Thing*)&thing, &Thing::const_volatile_member_func3); + Verifier::verify3((const Thing *)&thing, &Thing::const_member_func3); + Verifier::verify3((volatile Thing *)&thing, &Thing::volatile_member_func3); + Verifier::verify3((const volatile Thing *)&thing, &Thing::const_volatile_member_func3); Verifier::verify3(&thing2, &Thing2::member_func3); Verifier::verify3(&bound_func3, &thing); - Verifier::verify3(&const_bound_func3, (const Thing*)&thing); - Verifier::verify3(&volatile_bound_func3, (volatile Thing*)&thing); - Verifier::verify3(&const_volatile_bound_func3, (const volatile Thing*)&thing); + Verifier::verify3(&const_bound_func3, (const Thing *)&thing); + Verifier::verify3(&volatile_bound_func3, (volatile Thing *)&thing); + Verifier::verify3(&const_volatile_bound_func3, (const volatile Thing *)&thing); Verifier::verify3(&bound_func3, &thing2); Verifier::verify3(&void_func3, &thing); - Verifier::verify3(&const_void_func3, (const Thing*)&thing); - Verifier::verify3(&volatile_void_func3, (volatile Thing*)&thing); - Verifier::verify3(&const_volatile_void_func3, (const volatile Thing*)&thing); + Verifier::verify3(&const_void_func3, (const Thing *)&thing); + Verifier::verify3(&volatile_void_func3, (volatile Thing *)&thing); + Verifier::verify3(&const_volatile_void_func3, (const volatile Thing *)&thing); Verifier::verify3(callback(static_func3)); Callback cb(static_func3); @@ -449,28 +621,29 @@ void test_dispatch3() { Verifier::verify3(cb); cb.attach(&bound_func3, &thing); Verifier::verify3(&cb, &Callback::call); - Verifier::verify3(&Callback::thunk, (void*)&cb); + Verifier::verify3(&Callback::thunk, (void *)&cb); } template -void test_dispatch4() { +void test_dispatch4() +{ Thing thing; Thing2 thing2; Verifier::verify4(static_func4); Verifier::verify4(&thing, &Thing::member_func4); - Verifier::verify4((const Thing*)&thing, &Thing::const_member_func4); - Verifier::verify4((volatile Thing*)&thing, &Thing::volatile_member_func4); - Verifier::verify4((const volatile Thing*)&thing, &Thing::const_volatile_member_func4); + Verifier::verify4((const Thing *)&thing, &Thing::const_member_func4); + Verifier::verify4((volatile Thing *)&thing, &Thing::volatile_member_func4); + Verifier::verify4((const volatile Thing *)&thing, &Thing::const_volatile_member_func4); Verifier::verify4(&thing2, &Thing2::member_func4); Verifier::verify4(&bound_func4, &thing); - Verifier::verify4(&const_bound_func4, (const Thing*)&thing); - Verifier::verify4(&volatile_bound_func4, (volatile Thing*)&thing); - Verifier::verify4(&const_volatile_bound_func4, (const volatile Thing*)&thing); + Verifier::verify4(&const_bound_func4, (const Thing *)&thing); + Verifier::verify4(&volatile_bound_func4, (volatile Thing *)&thing); + Verifier::verify4(&const_volatile_bound_func4, (const volatile Thing *)&thing); Verifier::verify4(&bound_func4, &thing2); Verifier::verify4(&void_func4, &thing); - Verifier::verify4(&const_void_func4, (const Thing*)&thing); - Verifier::verify4(&volatile_void_func4, (volatile Thing*)&thing); - Verifier::verify4(&const_volatile_void_func4, (const volatile Thing*)&thing); + Verifier::verify4(&const_void_func4, (const Thing *)&thing); + Verifier::verify4(&volatile_void_func4, (volatile Thing *)&thing); + Verifier::verify4(&const_volatile_void_func4, (const volatile Thing *)&thing); Verifier::verify4(callback(static_func4)); Callback cb(static_func4); @@ -479,28 +652,29 @@ void test_dispatch4() { Verifier::verify4(cb); cb.attach(&bound_func4, &thing); Verifier::verify4(&cb, &Callback::call); - Verifier::verify4(&Callback::thunk, (void*)&cb); + Verifier::verify4(&Callback::thunk, (void *)&cb); } template -void test_dispatch5() { +void test_dispatch5() +{ Thing thing; Thing2 thing2; Verifier::verify5(static_func5); Verifier::verify5(&thing, &Thing::member_func5); - Verifier::verify5((const Thing*)&thing, &Thing::const_member_func5); - Verifier::verify5((volatile Thing*)&thing, &Thing::volatile_member_func5); - Verifier::verify5((const volatile Thing*)&thing, &Thing::const_volatile_member_func5); + Verifier::verify5((const Thing *)&thing, &Thing::const_member_func5); + Verifier::verify5((volatile Thing *)&thing, &Thing::volatile_member_func5); + Verifier::verify5((const volatile Thing *)&thing, &Thing::const_volatile_member_func5); Verifier::verify5(&thing2, &Thing2::member_func5); Verifier::verify5(&bound_func5, &thing); - Verifier::verify5(&const_bound_func5, (const Thing*)&thing); - Verifier::verify5(&volatile_bound_func5, (volatile Thing*)&thing); - Verifier::verify5(&const_volatile_bound_func5, (const volatile Thing*)&thing); + Verifier::verify5(&const_bound_func5, (const Thing *)&thing); + Verifier::verify5(&volatile_bound_func5, (volatile Thing *)&thing); + Verifier::verify5(&const_volatile_bound_func5, (const volatile Thing *)&thing); Verifier::verify5(&bound_func5, &thing2); Verifier::verify5(&void_func5, &thing); - Verifier::verify5(&const_void_func5, (const Thing*)&thing); - Verifier::verify5(&volatile_void_func5, (volatile Thing*)&thing); - Verifier::verify5(&const_volatile_void_func5, (const volatile Thing*)&thing); + Verifier::verify5(&const_void_func5, (const Thing *)&thing); + Verifier::verify5(&volatile_void_func5, (volatile Thing *)&thing); + Verifier::verify5(&const_volatile_void_func5, (const volatile Thing *)&thing); Verifier::verify5(callback(static_func5)); Callback cb(static_func5); @@ -509,12 +683,13 @@ void test_dispatch5() { Verifier::verify5(cb); cb.attach(&bound_func5, &thing); Verifier::verify5(&cb, &Callback::call); - Verifier::verify5(&Callback::thunk, (void*)&cb); + Verifier::verify5(&Callback::thunk, (void *)&cb); } // Test setup -utest::v1::status_t test_setup(const size_t number_of_cases) { +utest::v1::status_t test_setup(const size_t number_of_cases) +{ GREENTEA_SETUP(10, "default_auto"); return verbose_test_setup_handler(number_of_cases); } @@ -530,6 +705,7 @@ Case cases[] = { Specification specification(test_setup, cases); -int main() { +int main() +{ return !Harness::run(specification); } diff --git a/TESTS/mbed_functional/callback_big/main.cpp b/TESTS/mbed_functional/callback_big/main.cpp index 1aec88470e7e..cac6827171a1 100644 --- a/TESTS/mbed_functional/callback_big/main.cpp +++ b/TESTS/mbed_functional/callback_big/main.cpp @@ -23,17 +23,35 @@ using namespace utest::v1; // static functions template -T static_func0() { return 0; } +T static_func0() +{ + return 0; +} template -T static_func1(T a0) { return 0 | a0; } +T static_func1(T a0) +{ + return 0 | a0; +} template -T static_func2(T a0, T a1) { return 0 | a0 | a1; } +T static_func2(T a0, T a1) +{ + return 0 | a0 | a1; +} template -T static_func3(T a0, T a1, T a2) { return 0 | a0 | a1 | a2; } +T static_func3(T a0, T a1, T a2) +{ + return 0 | a0 | a1 | a2; +} template -T static_func4(T a0, T a1, T a2, T a3) { return 0 | a0 | a1 | a2 | a3; } +T static_func4(T a0, T a1, T a2, T a3) +{ + return 0 | a0 | a1 | a2 | a3; +} template -T static_func5(T a0, T a1, T a2, T a3, T a4) { return 0 | a0 | a1 | a2 | a3 | a4; } +T static_func5(T a0, T a1, T a2, T a3, T a4) +{ + return 0 | a0 | a1 | a2 | a3 | a4; +} // class functions template @@ -41,162 +59,318 @@ struct Thing { T t; Thing() : t(0x80) {} - T member_func0() { return t; } - T member_func1(T a0) { return t | a0; } - T member_func2(T a0, T a1) { return t | a0 | a1; } - T member_func3(T a0, T a1, T a2) { return t | a0 | a1 | a2; } - T member_func4(T a0, T a1, T a2, T a3) { return t | a0 | a1 | a2 | a3; } - T member_func5(T a0, T a1, T a2, T a3, T a4) { return t | a0 | a1 | a2 | a3 | a4; } - - T const_member_func0() const { return t; } - T const_member_func1(T a0) const { return t | a0; } - T const_member_func2(T a0, T a1) const { return t | a0 | a1; } - T const_member_func3(T a0, T a1, T a2) const { return t | a0 | a1 | a2; } - T const_member_func4(T a0, T a1, T a2, T a3) const { return t | a0 | a1 | a2 | a3; } - T const_member_func5(T a0, T a1, T a2, T a3, T a4) const { return t | a0 | a1 | a2 | a3 | a4; } - - T volatile_member_func0() volatile { return t; } - T volatile_member_func1(T a0) volatile { return t | a0; } - T volatile_member_func2(T a0, T a1) volatile { return t | a0 | a1; } - T volatile_member_func3(T a0, T a1, T a2) volatile { return t | a0 | a1 | a2; } - T volatile_member_func4(T a0, T a1, T a2, T a3) volatile { return t | a0 | a1 | a2 | a3; } - T volatile_member_func5(T a0, T a1, T a2, T a3, T a4) volatile { return t | a0 | a1 | a2 | a3 | a4; } - - T const_volatile_member_func0() const volatile { return t; } - T const_volatile_member_func1(T a0) const volatile { return t | a0; } - T const_volatile_member_func2(T a0, T a1) const volatile { return t | a0 | a1; } - T const_volatile_member_func3(T a0, T a1, T a2) const volatile { return t | a0 | a1 | a2; } - T const_volatile_member_func4(T a0, T a1, T a2, T a3) const volatile { return t | a0 | a1 | a2 | a3; } - T const_volatile_member_func5(T a0, T a1, T a2, T a3, T a4) const volatile { return t | a0 | a1 | a2 | a3 | a4; } + T member_func0() + { + return t; + } + T member_func1(T a0) + { + return t | a0; + } + T member_func2(T a0, T a1) + { + return t | a0 | a1; + } + T member_func3(T a0, T a1, T a2) + { + return t | a0 | a1 | a2; + } + T member_func4(T a0, T a1, T a2, T a3) + { + return t | a0 | a1 | a2 | a3; + } + T member_func5(T a0, T a1, T a2, T a3, T a4) + { + return t | a0 | a1 | a2 | a3 | a4; + } + + T const_member_func0() const + { + return t; + } + T const_member_func1(T a0) const + { + return t | a0; + } + T const_member_func2(T a0, T a1) const + { + return t | a0 | a1; + } + T const_member_func3(T a0, T a1, T a2) const + { + return t | a0 | a1 | a2; + } + T const_member_func4(T a0, T a1, T a2, T a3) const + { + return t | a0 | a1 | a2 | a3; + } + T const_member_func5(T a0, T a1, T a2, T a3, T a4) const + { + return t | a0 | a1 | a2 | a3 | a4; + } + + T volatile_member_func0() volatile + { + return t; + } + T volatile_member_func1(T a0) volatile + { + return t | a0; + } + T volatile_member_func2(T a0, T a1) volatile + { + return t | a0 | a1; + } + T volatile_member_func3(T a0, T a1, T a2) volatile + { + return t | a0 | a1 | a2; + } + T volatile_member_func4(T a0, T a1, T a2, T a3) volatile + { + return t | a0 | a1 | a2 | a3; + } + T volatile_member_func5(T a0, T a1, T a2, T a3, T a4) volatile + { + return t | a0 | a1 | a2 | a3 | a4; + } + + T const_volatile_member_func0() const volatile + { + return t; + } + T const_volatile_member_func1(T a0) const volatile + { + return t | a0; + } + T const_volatile_member_func2(T a0, T a1) const volatile + { + return t | a0 | a1; + } + T const_volatile_member_func3(T a0, T a1, T a2) const volatile + { + return t | a0 | a1 | a2; + } + T const_volatile_member_func4(T a0, T a1, T a2, T a3) const volatile + { + return t | a0 | a1 | a2 | a3; + } + T const_volatile_member_func5(T a0, T a1, T a2, T a3, T a4) const volatile + { + return t | a0 | a1 | a2 | a3 | a4; + } }; // bound functions template -T bound_func0(Thing *t) { return t->t; } +T bound_func0(Thing *t) +{ + return t->t; +} template -T bound_func1(Thing *t, T a0) { return t->t | a0; } +T bound_func1(Thing *t, T a0) +{ + return t->t | a0; +} template -T bound_func2(Thing *t, T a0, T a1) { return t->t | a0 | a1; } +T bound_func2(Thing *t, T a0, T a1) +{ + return t->t | a0 | a1; +} template -T bound_func3(Thing *t, T a0, T a1, T a2) { return t->t | a0 | a1 | a2; } +T bound_func3(Thing *t, T a0, T a1, T a2) +{ + return t->t | a0 | a1 | a2; +} template -T bound_func4(Thing *t, T a0, T a1, T a2, T a3) { return t->t | a0 | a1 | a2 | a3; } +T bound_func4(Thing *t, T a0, T a1, T a2, T a3) +{ + return t->t | a0 | a1 | a2 | a3; +} template -T bound_func5(Thing *t, T a0, T a1, T a2, T a3, T a4) { return t->t | a0 | a1 | a2 | a3 | a4; } +T bound_func5(Thing *t, T a0, T a1, T a2, T a3, T a4) +{ + return t->t | a0 | a1 | a2 | a3 | a4; +} // const bound functions template -T const_func0(const Thing *t) { return t->t; } +T const_func0(const Thing *t) +{ + return t->t; +} template -T const_func1(const Thing *t, T a0) { return t->t | a0; } +T const_func1(const Thing *t, T a0) +{ + return t->t | a0; +} template -T const_func2(const Thing *t, T a0, T a1) { return t->t | a0 | a1; } +T const_func2(const Thing *t, T a0, T a1) +{ + return t->t | a0 | a1; +} template -T const_func3(const Thing *t, T a0, T a1, T a2) { return t->t | a0 | a1 | a2; } +T const_func3(const Thing *t, T a0, T a1, T a2) +{ + return t->t | a0 | a1 | a2; +} template -T const_func4(const Thing *t, T a0, T a1, T a2, T a3) { return t->t | a0 | a1 | a2 | a3; } +T const_func4(const Thing *t, T a0, T a1, T a2, T a3) +{ + return t->t | a0 | a1 | a2 | a3; +} template -T const_func5(const Thing *t, T a0, T a1, T a2, T a3, T a4) { return t->t | a0 | a1 | a2 | a3 | a4; } +T const_func5(const Thing *t, T a0, T a1, T a2, T a3, T a4) +{ + return t->t | a0 | a1 | a2 | a3 | a4; +} // volatile bound functions template -T volatile_func0(volatile Thing *t) { return t->t; } +T volatile_func0(volatile Thing *t) +{ + return t->t; +} template -T volatile_func1(volatile Thing *t, T a0) { return t->t | a0; } +T volatile_func1(volatile Thing *t, T a0) +{ + return t->t | a0; +} template -T volatile_func2(volatile Thing *t, T a0, T a1) { return t->t | a0 | a1; } +T volatile_func2(volatile Thing *t, T a0, T a1) +{ + return t->t | a0 | a1; +} template -T volatile_func3(volatile Thing *t, T a0, T a1, T a2) { return t->t | a0 | a1 | a2; } +T volatile_func3(volatile Thing *t, T a0, T a1, T a2) +{ + return t->t | a0 | a1 | a2; +} template -T volatile_func4(volatile Thing *t, T a0, T a1, T a2, T a3) { return t->t | a0 | a1 | a2 | a3; } +T volatile_func4(volatile Thing *t, T a0, T a1, T a2, T a3) +{ + return t->t | a0 | a1 | a2 | a3; +} template -T volatile_func5(volatile Thing *t, T a0, T a1, T a2, T a3, T a4) { return t->t | a0 | a1 | a2 | a3 | a4; } +T volatile_func5(volatile Thing *t, T a0, T a1, T a2, T a3, T a4) +{ + return t->t | a0 | a1 | a2 | a3 | a4; +} // const volatile bound functions template -T const_volatile_func0(const volatile Thing *t) { return t->t; } +T const_volatile_func0(const volatile Thing *t) +{ + return t->t; +} template -T const_volatile_func1(const volatile Thing *t, T a0) { return t->t | a0; } +T const_volatile_func1(const volatile Thing *t, T a0) +{ + return t->t | a0; +} template -T const_volatile_func2(const volatile Thing *t, T a0, T a1) { return t->t | a0 | a1; } +T const_volatile_func2(const volatile Thing *t, T a0, T a1) +{ + return t->t | a0 | a1; +} template -T const_volatile_func3(const volatile Thing *t, T a0, T a1, T a2) { return t->t | a0 | a1 | a2; } +T const_volatile_func3(const volatile Thing *t, T a0, T a1, T a2) +{ + return t->t | a0 | a1 | a2; +} template -T const_volatile_func4(const volatile Thing *t, T a0, T a1, T a2, T a3) { return t->t | a0 | a1 | a2 | a3; } +T const_volatile_func4(const volatile Thing *t, T a0, T a1, T a2, T a3) +{ + return t->t | a0 | a1 | a2 | a3; +} template -T const_volatile_func5(const volatile Thing *t, T a0, T a1, T a2, T a3, T a4) { return t->t | a0 | a1 | a2 | a3 | a4; } +T const_volatile_func5(const volatile Thing *t, T a0, T a1, T a2, T a3, T a4) +{ + return t->t | a0 | a1 | a2 | a3 | a4; +} // function call and result verification template struct Verifier { - static void verify0(Callback func) { + static void verify0(Callback func) + { T result = func(); TEST_ASSERT_EQUAL(result, 0x00); } template - static void verify0(O *obj, M method) { + static void verify0(O *obj, M method) + { Callback func(obj, method); T result = func(); TEST_ASSERT_EQUAL(result, 0x80); } - static void verify1(Callback func) { + static void verify1(Callback func) + { T result = func((1 << 0)); TEST_ASSERT_EQUAL(result, 0x00 | (1 << 0)); } template - static void verify1(O *obj, M method) { + static void verify1(O *obj, M method) + { Callback func(obj, method); T result = func((1 << 0)); TEST_ASSERT_EQUAL(result, 0x80 | (1 << 0)); } - static void verify2(Callback func) { + static void verify2(Callback func) + { T result = func((1 << 0), (1 << 1)); TEST_ASSERT_EQUAL(result, 0x00 | (1 << 0) | (1 << 1)); } template - static void verify2(O *obj, M method) { + static void verify2(O *obj, M method) + { Callback func(obj, method); T result = func((1 << 0), (1 << 1)); TEST_ASSERT_EQUAL(result, 0x80 | (1 << 0) | (1 << 1)); } - static void verify3(Callback func) { + static void verify3(Callback func) + { T result = func((1 << 0), (1 << 1), (1 << 2)); TEST_ASSERT_EQUAL(result, 0x00 | (1 << 0) | (1 << 1) | (1 << 2)); } template - static void verify3(O *obj, M method) { + static void verify3(O *obj, M method) + { Callback func(obj, method); T result = func((1 << 0), (1 << 1), (1 << 2)); TEST_ASSERT_EQUAL(result, 0x80 | (1 << 0) | (1 << 1) | (1 << 2)); } - static void verify4(Callback func) { + static void verify4(Callback func) + { T result = func((1 << 0), (1 << 1), (1 << 2), (1 << 3)); TEST_ASSERT_EQUAL(result, 0x00 | (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3)); } template - static void verify4(O *obj, M method) { + static void verify4(O *obj, M method) + { Callback func(obj, method); T result = func((1 << 0), (1 << 1), (1 << 2), (1 << 3)); TEST_ASSERT_EQUAL(result, 0x80 | (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3)); } - static void verify5(Callback func) { + static void verify5(Callback func) + { T result = func((1 << 0), (1 << 1), (1 << 2), (1 << 3), (1 << 4)); TEST_ASSERT_EQUAL(result, 0x00 | (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4)); } template - static void verify5(O *obj, M method) { + static void verify5(O *obj, M method) + { Callback func(obj, method); T result = func((1 << 0), (1 << 1), (1 << 2), (1 << 3), (1 << 4)); TEST_ASSERT_EQUAL(result, 0x80 | (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4)); @@ -206,17 +380,18 @@ struct Verifier { // test dispatch template -void test_dispatch0() { +void test_dispatch0() +{ Thing thing; Verifier::verify0(static_func0); Verifier::verify0(&thing, &Thing::member_func0); - Verifier::verify0((const Thing*)&thing, &Thing::const_member_func0); - Verifier::verify0((volatile Thing*)&thing, &Thing::volatile_member_func0); - Verifier::verify0((const volatile Thing*)&thing, &Thing::const_volatile_member_func0); + Verifier::verify0((const Thing *)&thing, &Thing::const_member_func0); + Verifier::verify0((volatile Thing *)&thing, &Thing::volatile_member_func0); + Verifier::verify0((const volatile Thing *)&thing, &Thing::const_volatile_member_func0); Verifier::verify0(&bound_func0, &thing); - Verifier::verify0(&const_func0, (const Thing*)&thing); - Verifier::verify0(&volatile_func0, (volatile Thing*)&thing); - Verifier::verify0(&const_volatile_func0, (const volatile Thing*)&thing); + Verifier::verify0(&const_func0, (const Thing *)&thing); + Verifier::verify0(&volatile_func0, (volatile Thing *)&thing); + Verifier::verify0(&const_volatile_func0, (const volatile Thing *)&thing); Verifier::verify0(callback(static_func0)); Callback cb(static_func0); @@ -225,21 +400,22 @@ void test_dispatch0() { Verifier::verify0(cb); cb.attach(&bound_func0, &thing); Verifier::verify0(&cb, &Callback::call); - Verifier::verify0(&Callback::thunk, (void*)&cb); + Verifier::verify0(&Callback::thunk, (void *)&cb); } template -void test_dispatch1() { +void test_dispatch1() +{ Thing thing; Verifier::verify1(static_func1); Verifier::verify1(&thing, &Thing::member_func1); - Verifier::verify1((const Thing*)&thing, &Thing::const_member_func1); - Verifier::verify1((volatile Thing*)&thing, &Thing::volatile_member_func1); - Verifier::verify1((const volatile Thing*)&thing, &Thing::const_volatile_member_func1); + Verifier::verify1((const Thing *)&thing, &Thing::const_member_func1); + Verifier::verify1((volatile Thing *)&thing, &Thing::volatile_member_func1); + Verifier::verify1((const volatile Thing *)&thing, &Thing::const_volatile_member_func1); Verifier::verify1(&bound_func1, &thing); - Verifier::verify1(&const_func1, (const Thing*)&thing); - Verifier::verify1(&volatile_func1, (volatile Thing*)&thing); - Verifier::verify1(&const_volatile_func1, (const volatile Thing*)&thing); + Verifier::verify1(&const_func1, (const Thing *)&thing); + Verifier::verify1(&volatile_func1, (volatile Thing *)&thing); + Verifier::verify1(&const_volatile_func1, (const volatile Thing *)&thing); Verifier::verify1(callback(static_func1)); Callback cb(static_func1); @@ -248,21 +424,22 @@ void test_dispatch1() { Verifier::verify1(cb); cb.attach(&bound_func1, &thing); Verifier::verify1(&cb, &Callback::call); - Verifier::verify1(&Callback::thunk, (void*)&cb); + Verifier::verify1(&Callback::thunk, (void *)&cb); } template -void test_dispatch2() { +void test_dispatch2() +{ Thing thing; Verifier::verify2(static_func2); Verifier::verify2(&thing, &Thing::member_func2); - Verifier::verify2((const Thing*)&thing, &Thing::const_member_func2); - Verifier::verify2((volatile Thing*)&thing, &Thing::volatile_member_func2); - Verifier::verify2((const volatile Thing*)&thing, &Thing::const_volatile_member_func2); + Verifier::verify2((const Thing *)&thing, &Thing::const_member_func2); + Verifier::verify2((volatile Thing *)&thing, &Thing::volatile_member_func2); + Verifier::verify2((const volatile Thing *)&thing, &Thing::const_volatile_member_func2); Verifier::verify2(&bound_func2, &thing); - Verifier::verify2(&const_func2, (const Thing*)&thing); - Verifier::verify2(&volatile_func2, (volatile Thing*)&thing); - Verifier::verify2(&const_volatile_func2, (const volatile Thing*)&thing); + Verifier::verify2(&const_func2, (const Thing *)&thing); + Verifier::verify2(&volatile_func2, (volatile Thing *)&thing); + Verifier::verify2(&const_volatile_func2, (const volatile Thing *)&thing); Verifier::verify2(callback(static_func2)); Callback cb(static_func2); @@ -271,21 +448,22 @@ void test_dispatch2() { Verifier::verify2(cb); cb.attach(&bound_func2, &thing); Verifier::verify2(&cb, &Callback::call); - Verifier::verify2(&Callback::thunk, (void*)&cb); + Verifier::verify2(&Callback::thunk, (void *)&cb); } template -void test_dispatch3() { +void test_dispatch3() +{ Thing thing; Verifier::verify3(static_func3); Verifier::verify3(&thing, &Thing::member_func3); - Verifier::verify3((const Thing*)&thing, &Thing::const_member_func3); - Verifier::verify3((volatile Thing*)&thing, &Thing::volatile_member_func3); - Verifier::verify3((const volatile Thing*)&thing, &Thing::const_volatile_member_func3); + Verifier::verify3((const Thing *)&thing, &Thing::const_member_func3); + Verifier::verify3((volatile Thing *)&thing, &Thing::volatile_member_func3); + Verifier::verify3((const volatile Thing *)&thing, &Thing::const_volatile_member_func3); Verifier::verify3(&bound_func3, &thing); - Verifier::verify3(&const_func3, (const Thing*)&thing); - Verifier::verify3(&volatile_func3, (volatile Thing*)&thing); - Verifier::verify3(&const_volatile_func3, (const volatile Thing*)&thing); + Verifier::verify3(&const_func3, (const Thing *)&thing); + Verifier::verify3(&volatile_func3, (volatile Thing *)&thing); + Verifier::verify3(&const_volatile_func3, (const volatile Thing *)&thing); Verifier::verify3(callback(static_func3)); Callback cb(static_func3); @@ -294,21 +472,22 @@ void test_dispatch3() { Verifier::verify3(cb); cb.attach(&bound_func3, &thing); Verifier::verify3(&cb, &Callback::call); - Verifier::verify3(&Callback::thunk, (void*)&cb); + Verifier::verify3(&Callback::thunk, (void *)&cb); } template -void test_dispatch4() { +void test_dispatch4() +{ Thing thing; Verifier::verify4(static_func4); Verifier::verify4(&thing, &Thing::member_func4); - Verifier::verify4((const Thing*)&thing, &Thing::const_member_func4); - Verifier::verify4((volatile Thing*)&thing, &Thing::volatile_member_func4); - Verifier::verify4((const volatile Thing*)&thing, &Thing::const_volatile_member_func4); + Verifier::verify4((const Thing *)&thing, &Thing::const_member_func4); + Verifier::verify4((volatile Thing *)&thing, &Thing::volatile_member_func4); + Verifier::verify4((const volatile Thing *)&thing, &Thing::const_volatile_member_func4); Verifier::verify4(&bound_func4, &thing); - Verifier::verify4(&const_func4, (const Thing*)&thing); - Verifier::verify4(&volatile_func4, (volatile Thing*)&thing); - Verifier::verify4(&const_volatile_func4, (const volatile Thing*)&thing); + Verifier::verify4(&const_func4, (const Thing *)&thing); + Verifier::verify4(&volatile_func4, (volatile Thing *)&thing); + Verifier::verify4(&const_volatile_func4, (const volatile Thing *)&thing); Verifier::verify4(callback(static_func4)); Callback cb(static_func4); @@ -317,21 +496,22 @@ void test_dispatch4() { Verifier::verify4(cb); cb.attach(&bound_func4, &thing); Verifier::verify4(&cb, &Callback::call); - Verifier::verify4(&Callback::thunk, (void*)&cb); + Verifier::verify4(&Callback::thunk, (void *)&cb); } template -void test_dispatch5() { +void test_dispatch5() +{ Thing thing; Verifier::verify5(static_func5); Verifier::verify5(&thing, &Thing::member_func5); - Verifier::verify5((const Thing*)&thing, &Thing::const_member_func5); - Verifier::verify5((volatile Thing*)&thing, &Thing::volatile_member_func5); - Verifier::verify5((const volatile Thing*)&thing, &Thing::const_volatile_member_func5); + Verifier::verify5((const Thing *)&thing, &Thing::const_member_func5); + Verifier::verify5((volatile Thing *)&thing, &Thing::volatile_member_func5); + Verifier::verify5((const volatile Thing *)&thing, &Thing::const_volatile_member_func5); Verifier::verify5(&bound_func5, &thing); - Verifier::verify5(&const_func5, (const Thing*)&thing); - Verifier::verify5(&volatile_func5, (volatile Thing*)&thing); - Verifier::verify5(&const_volatile_func5, (const volatile Thing*)&thing); + Verifier::verify5(&const_func5, (const Thing *)&thing); + Verifier::verify5(&volatile_func5, (volatile Thing *)&thing); + Verifier::verify5(&const_volatile_func5, (const volatile Thing *)&thing); Verifier::verify5(callback(static_func5)); Callback cb(static_func5); @@ -340,12 +520,13 @@ void test_dispatch5() { Verifier::verify5(cb); cb.attach(&bound_func5, &thing); Verifier::verify5(&cb, &Callback::call); - Verifier::verify5(&Callback::thunk, (void*)&cb); + Verifier::verify5(&Callback::thunk, (void *)&cb); } // Test setup -utest::v1::status_t test_setup(const size_t number_of_cases) { +utest::v1::status_t test_setup(const size_t number_of_cases) +{ GREENTEA_SETUP(10, "default_auto"); return verbose_test_setup_handler(number_of_cases); } @@ -361,6 +542,7 @@ Case cases[] = { Specification specification(test_setup, cases); -int main() { +int main() +{ return !Harness::run(specification); } diff --git a/TESTS/mbed_functional/callback_small/main.cpp b/TESTS/mbed_functional/callback_small/main.cpp index 583b8d0f5347..262f69948e98 100644 --- a/TESTS/mbed_functional/callback_small/main.cpp +++ b/TESTS/mbed_functional/callback_small/main.cpp @@ -23,17 +23,35 @@ using namespace utest::v1; // static functions template -T static_func0() { return 0; } +T static_func0() +{ + return 0; +} template -T static_func1(T a0) { return 0 | a0; } +T static_func1(T a0) +{ + return 0 | a0; +} template -T static_func2(T a0, T a1) { return 0 | a0 | a1; } +T static_func2(T a0, T a1) +{ + return 0 | a0 | a1; +} template -T static_func3(T a0, T a1, T a2) { return 0 | a0 | a1 | a2; } +T static_func3(T a0, T a1, T a2) +{ + return 0 | a0 | a1 | a2; +} template -T static_func4(T a0, T a1, T a2, T a3) { return 0 | a0 | a1 | a2 | a3; } +T static_func4(T a0, T a1, T a2, T a3) +{ + return 0 | a0 | a1 | a2 | a3; +} template -T static_func5(T a0, T a1, T a2, T a3, T a4) { return 0 | a0 | a1 | a2 | a3 | a4; } +T static_func5(T a0, T a1, T a2, T a3, T a4) +{ + return 0 | a0 | a1 | a2 | a3 | a4; +} // class functions template @@ -41,162 +59,318 @@ struct Thing { T t; Thing() : t(0x80) {} - T member_func0() { return t; } - T member_func1(T a0) { return t | a0; } - T member_func2(T a0, T a1) { return t | a0 | a1; } - T member_func3(T a0, T a1, T a2) { return t | a0 | a1 | a2; } - T member_func4(T a0, T a1, T a2, T a3) { return t | a0 | a1 | a2 | a3; } - T member_func5(T a0, T a1, T a2, T a3, T a4) { return t | a0 | a1 | a2 | a3 | a4; } - - T const_member_func0() const { return t; } - T const_member_func1(T a0) const { return t | a0; } - T const_member_func2(T a0, T a1) const { return t | a0 | a1; } - T const_member_func3(T a0, T a1, T a2) const { return t | a0 | a1 | a2; } - T const_member_func4(T a0, T a1, T a2, T a3) const { return t | a0 | a1 | a2 | a3; } - T const_member_func5(T a0, T a1, T a2, T a3, T a4) const { return t | a0 | a1 | a2 | a3 | a4; } - - T volatile_member_func0() volatile { return t; } - T volatile_member_func1(T a0) volatile { return t | a0; } - T volatile_member_func2(T a0, T a1) volatile { return t | a0 | a1; } - T volatile_member_func3(T a0, T a1, T a2) volatile { return t | a0 | a1 | a2; } - T volatile_member_func4(T a0, T a1, T a2, T a3) volatile { return t | a0 | a1 | a2 | a3; } - T volatile_member_func5(T a0, T a1, T a2, T a3, T a4) volatile { return t | a0 | a1 | a2 | a3 | a4; } - - T const_volatile_member_func0() const volatile { return t; } - T const_volatile_member_func1(T a0) const volatile { return t | a0; } - T const_volatile_member_func2(T a0, T a1) const volatile { return t | a0 | a1; } - T const_volatile_member_func3(T a0, T a1, T a2) const volatile { return t | a0 | a1 | a2; } - T const_volatile_member_func4(T a0, T a1, T a2, T a3) const volatile { return t | a0 | a1 | a2 | a3; } - T const_volatile_member_func5(T a0, T a1, T a2, T a3, T a4) const volatile { return t | a0 | a1 | a2 | a3 | a4; } + T member_func0() + { + return t; + } + T member_func1(T a0) + { + return t | a0; + } + T member_func2(T a0, T a1) + { + return t | a0 | a1; + } + T member_func3(T a0, T a1, T a2) + { + return t | a0 | a1 | a2; + } + T member_func4(T a0, T a1, T a2, T a3) + { + return t | a0 | a1 | a2 | a3; + } + T member_func5(T a0, T a1, T a2, T a3, T a4) + { + return t | a0 | a1 | a2 | a3 | a4; + } + + T const_member_func0() const + { + return t; + } + T const_member_func1(T a0) const + { + return t | a0; + } + T const_member_func2(T a0, T a1) const + { + return t | a0 | a1; + } + T const_member_func3(T a0, T a1, T a2) const + { + return t | a0 | a1 | a2; + } + T const_member_func4(T a0, T a1, T a2, T a3) const + { + return t | a0 | a1 | a2 | a3; + } + T const_member_func5(T a0, T a1, T a2, T a3, T a4) const + { + return t | a0 | a1 | a2 | a3 | a4; + } + + T volatile_member_func0() volatile + { + return t; + } + T volatile_member_func1(T a0) volatile + { + return t | a0; + } + T volatile_member_func2(T a0, T a1) volatile + { + return t | a0 | a1; + } + T volatile_member_func3(T a0, T a1, T a2) volatile + { + return t | a0 | a1 | a2; + } + T volatile_member_func4(T a0, T a1, T a2, T a3) volatile + { + return t | a0 | a1 | a2 | a3; + } + T volatile_member_func5(T a0, T a1, T a2, T a3, T a4) volatile + { + return t | a0 | a1 | a2 | a3 | a4; + } + + T const_volatile_member_func0() const volatile + { + return t; + } + T const_volatile_member_func1(T a0) const volatile + { + return t | a0; + } + T const_volatile_member_func2(T a0, T a1) const volatile + { + return t | a0 | a1; + } + T const_volatile_member_func3(T a0, T a1, T a2) const volatile + { + return t | a0 | a1 | a2; + } + T const_volatile_member_func4(T a0, T a1, T a2, T a3) const volatile + { + return t | a0 | a1 | a2 | a3; + } + T const_volatile_member_func5(T a0, T a1, T a2, T a3, T a4) const volatile + { + return t | a0 | a1 | a2 | a3 | a4; + } }; // bound functions template -T bound_func0(Thing *t) { return t->t; } +T bound_func0(Thing *t) +{ + return t->t; +} template -T bound_func1(Thing *t, T a0) { return t->t | a0; } +T bound_func1(Thing *t, T a0) +{ + return t->t | a0; +} template -T bound_func2(Thing *t, T a0, T a1) { return t->t | a0 | a1; } +T bound_func2(Thing *t, T a0, T a1) +{ + return t->t | a0 | a1; +} template -T bound_func3(Thing *t, T a0, T a1, T a2) { return t->t | a0 | a1 | a2; } +T bound_func3(Thing *t, T a0, T a1, T a2) +{ + return t->t | a0 | a1 | a2; +} template -T bound_func4(Thing *t, T a0, T a1, T a2, T a3) { return t->t | a0 | a1 | a2 | a3; } +T bound_func4(Thing *t, T a0, T a1, T a2, T a3) +{ + return t->t | a0 | a1 | a2 | a3; +} template -T bound_func5(Thing *t, T a0, T a1, T a2, T a3, T a4) { return t->t | a0 | a1 | a2 | a3 | a4; } +T bound_func5(Thing *t, T a0, T a1, T a2, T a3, T a4) +{ + return t->t | a0 | a1 | a2 | a3 | a4; +} // const bound functions template -T const_func0(const Thing *t) { return t->t; } +T const_func0(const Thing *t) +{ + return t->t; +} template -T const_func1(const Thing *t, T a0) { return t->t | a0; } +T const_func1(const Thing *t, T a0) +{ + return t->t | a0; +} template -T const_func2(const Thing *t, T a0, T a1) { return t->t | a0 | a1; } +T const_func2(const Thing *t, T a0, T a1) +{ + return t->t | a0 | a1; +} template -T const_func3(const Thing *t, T a0, T a1, T a2) { return t->t | a0 | a1 | a2; } +T const_func3(const Thing *t, T a0, T a1, T a2) +{ + return t->t | a0 | a1 | a2; +} template -T const_func4(const Thing *t, T a0, T a1, T a2, T a3) { return t->t | a0 | a1 | a2 | a3; } +T const_func4(const Thing *t, T a0, T a1, T a2, T a3) +{ + return t->t | a0 | a1 | a2 | a3; +} template -T const_func5(const Thing *t, T a0, T a1, T a2, T a3, T a4) { return t->t | a0 | a1 | a2 | a3 | a4; } +T const_func5(const Thing *t, T a0, T a1, T a2, T a3, T a4) +{ + return t->t | a0 | a1 | a2 | a3 | a4; +} // volatile bound functions template -T volatile_func0(volatile Thing *t) { return t->t; } +T volatile_func0(volatile Thing *t) +{ + return t->t; +} template -T volatile_func1(volatile Thing *t, T a0) { return t->t | a0; } +T volatile_func1(volatile Thing *t, T a0) +{ + return t->t | a0; +} template -T volatile_func2(volatile Thing *t, T a0, T a1) { return t->t | a0 | a1; } +T volatile_func2(volatile Thing *t, T a0, T a1) +{ + return t->t | a0 | a1; +} template -T volatile_func3(volatile Thing *t, T a0, T a1, T a2) { return t->t | a0 | a1 | a2; } +T volatile_func3(volatile Thing *t, T a0, T a1, T a2) +{ + return t->t | a0 | a1 | a2; +} template -T volatile_func4(volatile Thing *t, T a0, T a1, T a2, T a3) { return t->t | a0 | a1 | a2 | a3; } +T volatile_func4(volatile Thing *t, T a0, T a1, T a2, T a3) +{ + return t->t | a0 | a1 | a2 | a3; +} template -T volatile_func5(volatile Thing *t, T a0, T a1, T a2, T a3, T a4) { return t->t | a0 | a1 | a2 | a3 | a4; } +T volatile_func5(volatile Thing *t, T a0, T a1, T a2, T a3, T a4) +{ + return t->t | a0 | a1 | a2 | a3 | a4; +} // const volatile bound functions template -T const_volatile_func0(const volatile Thing *t) { return t->t; } +T const_volatile_func0(const volatile Thing *t) +{ + return t->t; +} template -T const_volatile_func1(const volatile Thing *t, T a0) { return t->t | a0; } +T const_volatile_func1(const volatile Thing *t, T a0) +{ + return t->t | a0; +} template -T const_volatile_func2(const volatile Thing *t, T a0, T a1) { return t->t | a0 | a1; } +T const_volatile_func2(const volatile Thing *t, T a0, T a1) +{ + return t->t | a0 | a1; +} template -T const_volatile_func3(const volatile Thing *t, T a0, T a1, T a2) { return t->t | a0 | a1 | a2; } +T const_volatile_func3(const volatile Thing *t, T a0, T a1, T a2) +{ + return t->t | a0 | a1 | a2; +} template -T const_volatile_func4(const volatile Thing *t, T a0, T a1, T a2, T a3) { return t->t | a0 | a1 | a2 | a3; } +T const_volatile_func4(const volatile Thing *t, T a0, T a1, T a2, T a3) +{ + return t->t | a0 | a1 | a2 | a3; +} template -T const_volatile_func5(const volatile Thing *t, T a0, T a1, T a2, T a3, T a4) { return t->t | a0 | a1 | a2 | a3 | a4; } +T const_volatile_func5(const volatile Thing *t, T a0, T a1, T a2, T a3, T a4) +{ + return t->t | a0 | a1 | a2 | a3 | a4; +} // function call and result verification template struct Verifier { - static void verify0(Callback func) { + static void verify0(Callback func) + { T result = func(); TEST_ASSERT_EQUAL(result, 0x00); } template - static void verify0(O *obj, M method) { + static void verify0(O *obj, M method) + { Callback func(obj, method); T result = func(); TEST_ASSERT_EQUAL(result, 0x80); } - static void verify1(Callback func) { + static void verify1(Callback func) + { T result = func((1 << 0)); TEST_ASSERT_EQUAL(result, 0x00 | (1 << 0)); } template - static void verify1(O *obj, M method) { + static void verify1(O *obj, M method) + { Callback func(obj, method); T result = func((1 << 0)); TEST_ASSERT_EQUAL(result, 0x80 | (1 << 0)); } - static void verify2(Callback func) { + static void verify2(Callback func) + { T result = func((1 << 0), (1 << 1)); TEST_ASSERT_EQUAL(result, 0x00 | (1 << 0) | (1 << 1)); } template - static void verify2(O *obj, M method) { + static void verify2(O *obj, M method) + { Callback func(obj, method); T result = func((1 << 0), (1 << 1)); TEST_ASSERT_EQUAL(result, 0x80 | (1 << 0) | (1 << 1)); } - static void verify3(Callback func) { + static void verify3(Callback func) + { T result = func((1 << 0), (1 << 1), (1 << 2)); TEST_ASSERT_EQUAL(result, 0x00 | (1 << 0) | (1 << 1) | (1 << 2)); } template - static void verify3(O *obj, M method) { + static void verify3(O *obj, M method) + { Callback func(obj, method); T result = func((1 << 0), (1 << 1), (1 << 2)); TEST_ASSERT_EQUAL(result, 0x80 | (1 << 0) | (1 << 1) | (1 << 2)); } - static void verify4(Callback func) { + static void verify4(Callback func) + { T result = func((1 << 0), (1 << 1), (1 << 2), (1 << 3)); TEST_ASSERT_EQUAL(result, 0x00 | (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3)); } template - static void verify4(O *obj, M method) { + static void verify4(O *obj, M method) + { Callback func(obj, method); T result = func((1 << 0), (1 << 1), (1 << 2), (1 << 3)); TEST_ASSERT_EQUAL(result, 0x80 | (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3)); } - static void verify5(Callback func) { + static void verify5(Callback func) + { T result = func((1 << 0), (1 << 1), (1 << 2), (1 << 3), (1 << 4)); TEST_ASSERT_EQUAL(result, 0x00 | (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4)); } template - static void verify5(O *obj, M method) { + static void verify5(O *obj, M method) + { Callback func(obj, method); T result = func((1 << 0), (1 << 1), (1 << 2), (1 << 3), (1 << 4)); TEST_ASSERT_EQUAL(result, 0x80 | (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4)); @@ -206,17 +380,18 @@ struct Verifier { // test dispatch template -void test_dispatch0() { +void test_dispatch0() +{ Thing thing; Verifier::verify0(static_func0); Verifier::verify0(&thing, &Thing::member_func0); - Verifier::verify0((const Thing*)&thing, &Thing::const_member_func0); - Verifier::verify0((volatile Thing*)&thing, &Thing::volatile_member_func0); - Verifier::verify0((const volatile Thing*)&thing, &Thing::const_volatile_member_func0); + Verifier::verify0((const Thing *)&thing, &Thing::const_member_func0); + Verifier::verify0((volatile Thing *)&thing, &Thing::volatile_member_func0); + Verifier::verify0((const volatile Thing *)&thing, &Thing::const_volatile_member_func0); Verifier::verify0(&bound_func0, &thing); - Verifier::verify0(&const_func0, (const Thing*)&thing); - Verifier::verify0(&volatile_func0, (volatile Thing*)&thing); - Verifier::verify0(&const_volatile_func0, (const volatile Thing*)&thing); + Verifier::verify0(&const_func0, (const Thing *)&thing); + Verifier::verify0(&volatile_func0, (volatile Thing *)&thing); + Verifier::verify0(&const_volatile_func0, (const volatile Thing *)&thing); Verifier::verify0(callback(static_func0)); Callback cb(static_func0); @@ -225,21 +400,22 @@ void test_dispatch0() { Verifier::verify0(cb); cb.attach(&bound_func0, &thing); Verifier::verify0(&cb, &Callback::call); - Verifier::verify0(&Callback::thunk, (void*)&cb); + Verifier::verify0(&Callback::thunk, (void *)&cb); } template -void test_dispatch1() { +void test_dispatch1() +{ Thing thing; Verifier::verify1(static_func1); Verifier::verify1(&thing, &Thing::member_func1); - Verifier::verify1((const Thing*)&thing, &Thing::const_member_func1); - Verifier::verify1((volatile Thing*)&thing, &Thing::volatile_member_func1); - Verifier::verify1((const volatile Thing*)&thing, &Thing::const_volatile_member_func1); + Verifier::verify1((const Thing *)&thing, &Thing::const_member_func1); + Verifier::verify1((volatile Thing *)&thing, &Thing::volatile_member_func1); + Verifier::verify1((const volatile Thing *)&thing, &Thing::const_volatile_member_func1); Verifier::verify1(&bound_func1, &thing); - Verifier::verify1(&const_func1, (const Thing*)&thing); - Verifier::verify1(&volatile_func1, (volatile Thing*)&thing); - Verifier::verify1(&const_volatile_func1, (const volatile Thing*)&thing); + Verifier::verify1(&const_func1, (const Thing *)&thing); + Verifier::verify1(&volatile_func1, (volatile Thing *)&thing); + Verifier::verify1(&const_volatile_func1, (const volatile Thing *)&thing); Verifier::verify1(callback(static_func1)); Callback cb(static_func1); @@ -248,21 +424,22 @@ void test_dispatch1() { Verifier::verify1(cb); cb.attach(&bound_func1, &thing); Verifier::verify1(&cb, &Callback::call); - Verifier::verify1(&Callback::thunk, (void*)&cb); + Verifier::verify1(&Callback::thunk, (void *)&cb); } template -void test_dispatch2() { +void test_dispatch2() +{ Thing thing; Verifier::verify2(static_func2); Verifier::verify2(&thing, &Thing::member_func2); - Verifier::verify2((const Thing*)&thing, &Thing::const_member_func2); - Verifier::verify2((volatile Thing*)&thing, &Thing::volatile_member_func2); - Verifier::verify2((const volatile Thing*)&thing, &Thing::const_volatile_member_func2); + Verifier::verify2((const Thing *)&thing, &Thing::const_member_func2); + Verifier::verify2((volatile Thing *)&thing, &Thing::volatile_member_func2); + Verifier::verify2((const volatile Thing *)&thing, &Thing::const_volatile_member_func2); Verifier::verify2(&bound_func2, &thing); - Verifier::verify2(&const_func2, (const Thing*)&thing); - Verifier::verify2(&volatile_func2, (volatile Thing*)&thing); - Verifier::verify2(&const_volatile_func2, (const volatile Thing*)&thing); + Verifier::verify2(&const_func2, (const Thing *)&thing); + Verifier::verify2(&volatile_func2, (volatile Thing *)&thing); + Verifier::verify2(&const_volatile_func2, (const volatile Thing *)&thing); Verifier::verify2(callback(static_func2)); Callback cb(static_func2); @@ -271,21 +448,22 @@ void test_dispatch2() { Verifier::verify2(cb); cb.attach(&bound_func2, &thing); Verifier::verify2(&cb, &Callback::call); - Verifier::verify2(&Callback::thunk, (void*)&cb); + Verifier::verify2(&Callback::thunk, (void *)&cb); } template -void test_dispatch3() { +void test_dispatch3() +{ Thing thing; Verifier::verify3(static_func3); Verifier::verify3(&thing, &Thing::member_func3); - Verifier::verify3((const Thing*)&thing, &Thing::const_member_func3); - Verifier::verify3((volatile Thing*)&thing, &Thing::volatile_member_func3); - Verifier::verify3((const volatile Thing*)&thing, &Thing::const_volatile_member_func3); + Verifier::verify3((const Thing *)&thing, &Thing::const_member_func3); + Verifier::verify3((volatile Thing *)&thing, &Thing::volatile_member_func3); + Verifier::verify3((const volatile Thing *)&thing, &Thing::const_volatile_member_func3); Verifier::verify3(&bound_func3, &thing); - Verifier::verify3(&const_func3, (const Thing*)&thing); - Verifier::verify3(&volatile_func3, (volatile Thing*)&thing); - Verifier::verify3(&const_volatile_func3, (const volatile Thing*)&thing); + Verifier::verify3(&const_func3, (const Thing *)&thing); + Verifier::verify3(&volatile_func3, (volatile Thing *)&thing); + Verifier::verify3(&const_volatile_func3, (const volatile Thing *)&thing); Verifier::verify3(callback(static_func3)); Callback cb(static_func3); @@ -294,21 +472,22 @@ void test_dispatch3() { Verifier::verify3(cb); cb.attach(&bound_func3, &thing); Verifier::verify3(&cb, &Callback::call); - Verifier::verify3(&Callback::thunk, (void*)&cb); + Verifier::verify3(&Callback::thunk, (void *)&cb); } template -void test_dispatch4() { +void test_dispatch4() +{ Thing thing; Verifier::verify4(static_func4); Verifier::verify4(&thing, &Thing::member_func4); - Verifier::verify4((const Thing*)&thing, &Thing::const_member_func4); - Verifier::verify4((volatile Thing*)&thing, &Thing::volatile_member_func4); - Verifier::verify4((const volatile Thing*)&thing, &Thing::const_volatile_member_func4); + Verifier::verify4((const Thing *)&thing, &Thing::const_member_func4); + Verifier::verify4((volatile Thing *)&thing, &Thing::volatile_member_func4); + Verifier::verify4((const volatile Thing *)&thing, &Thing::const_volatile_member_func4); Verifier::verify4(&bound_func4, &thing); - Verifier::verify4(&const_func4, (const Thing*)&thing); - Verifier::verify4(&volatile_func4, (volatile Thing*)&thing); - Verifier::verify4(&const_volatile_func4, (const volatile Thing*)&thing); + Verifier::verify4(&const_func4, (const Thing *)&thing); + Verifier::verify4(&volatile_func4, (volatile Thing *)&thing); + Verifier::verify4(&const_volatile_func4, (const volatile Thing *)&thing); Verifier::verify4(callback(static_func4)); Callback cb(static_func4); @@ -317,21 +496,22 @@ void test_dispatch4() { Verifier::verify4(cb); cb.attach(&bound_func4, &thing); Verifier::verify4(&cb, &Callback::call); - Verifier::verify4(&Callback::thunk, (void*)&cb); + Verifier::verify4(&Callback::thunk, (void *)&cb); } template -void test_dispatch5() { +void test_dispatch5() +{ Thing thing; Verifier::verify5(static_func5); Verifier::verify5(&thing, &Thing::member_func5); - Verifier::verify5((const Thing*)&thing, &Thing::const_member_func5); - Verifier::verify5((volatile Thing*)&thing, &Thing::volatile_member_func5); - Verifier::verify5((const volatile Thing*)&thing, &Thing::const_volatile_member_func5); + Verifier::verify5((const Thing *)&thing, &Thing::const_member_func5); + Verifier::verify5((volatile Thing *)&thing, &Thing::volatile_member_func5); + Verifier::verify5((const volatile Thing *)&thing, &Thing::const_volatile_member_func5); Verifier::verify5(&bound_func5, &thing); - Verifier::verify5(&const_func5, (const Thing*)&thing); - Verifier::verify5(&volatile_func5, (volatile Thing*)&thing); - Verifier::verify5(&const_volatile_func5, (const volatile Thing*)&thing); + Verifier::verify5(&const_func5, (const Thing *)&thing); + Verifier::verify5(&volatile_func5, (volatile Thing *)&thing); + Verifier::verify5(&const_volatile_func5, (const volatile Thing *)&thing); Verifier::verify5(callback(static_func5)); Callback cb(static_func5); @@ -340,12 +520,13 @@ void test_dispatch5() { Verifier::verify5(cb); cb.attach(&bound_func5, &thing); Verifier::verify5(&cb, &Callback::call); - Verifier::verify5(&Callback::thunk, (void*)&cb); + Verifier::verify5(&Callback::thunk, (void *)&cb); } // Test setup -utest::v1::status_t test_setup(const size_t number_of_cases) { +utest::v1::status_t test_setup(const size_t number_of_cases) +{ GREENTEA_SETUP(10, "default_auto"); return verbose_test_setup_handler(number_of_cases); } @@ -361,6 +542,7 @@ Case cases[] = { Specification specification(test_setup, cases); -int main() { +int main() +{ return !Harness::run(specification); } diff --git a/TESTS/mbed_functional/functionpointer/main.cpp b/TESTS/mbed_functional/functionpointer/main.cpp index 0850cf0da0b2..ff4f370b06a0 100644 --- a/TESTS/mbed_functional/functionpointer/main.cpp +++ b/TESTS/mbed_functional/functionpointer/main.cpp @@ -24,22 +24,34 @@ using namespace utest::v1; // static functions template T static_func0() - { return 0; } +{ + return 0; +} template T static_func1(T a0) - { return 0 | a0; } +{ + return 0 | a0; +} template T static_func2(T a0, T a1) - { return 0 | a0 | a1; } +{ + return 0 | a0 | a1; +} template T static_func3(T a0, T a1, T a2) - { return 0 | a0 | a1 | a2; } +{ + return 0 | a0 | a1 | a2; +} template T static_func4(T a0, T a1, T a2, T a3) - { return 0 | a0 | a1 | a2 | a3; } +{ + return 0 | a0 | a1 | a2 | a3; +} template T static_func5(T a0, T a1, T a2, T a3, T a4) - { return 0 | a0 | a1 | a2 | a3 | a4; } +{ + return 0 | a0 | a1 | a2 | a3 | a4; +} // class functions template @@ -48,277 +60,433 @@ struct Thing { Thing() : t(0x80) {} T member_func0() - { return t; } + { + return t; + } T member_func1(T a0) - { return t | a0; } + { + return t | a0; + } T member_func2(T a0, T a1) - { return t | a0 | a1; } + { + return t | a0 | a1; + } T member_func3(T a0, T a1, T a2) - { return t | a0 | a1 | a2; } + { + return t | a0 | a1 | a2; + } T member_func4(T a0, T a1, T a2, T a3) - { return t | a0 | a1 | a2 | a3; } + { + return t | a0 | a1 | a2 | a3; + } T member_func5(T a0, T a1, T a2, T a3, T a4) - { return t | a0 | a1 | a2 | a3 | a4; } + { + return t | a0 | a1 | a2 | a3 | a4; + } T const_member_func0() const - { return t; } + { + return t; + } T const_member_func1(T a0) const - { return t | a0; } + { + return t | a0; + } T const_member_func2(T a0, T a1) const - { return t | a0 | a1; } + { + return t | a0 | a1; + } T const_member_func3(T a0, T a1, T a2) const - { return t | a0 | a1 | a2; } + { + return t | a0 | a1 | a2; + } T const_member_func4(T a0, T a1, T a2, T a3) const - { return t | a0 | a1 | a2 | a3; } + { + return t | a0 | a1 | a2 | a3; + } T const_member_func5(T a0, T a1, T a2, T a3, T a4) const - { return t | a0 | a1 | a2 | a3 | a4; } + { + return t | a0 | a1 | a2 | a3 | a4; + } T volatile_member_func0() volatile - { return t; } + { + return t; + } T volatile_member_func1(T a0) volatile - { return t | a0; } + { + return t | a0; + } T volatile_member_func2(T a0, T a1) volatile - { return t | a0 | a1; } + { + return t | a0 | a1; + } T volatile_member_func3(T a0, T a1, T a2) volatile - { return t | a0 | a1 | a2; } + { + return t | a0 | a1 | a2; + } T volatile_member_func4(T a0, T a1, T a2, T a3) volatile - { return t | a0 | a1 | a2 | a3; } + { + return t | a0 | a1 | a2 | a3; + } T volatile_member_func5(T a0, T a1, T a2, T a3, T a4) volatile - { return t | a0 | a1 | a2 | a3 | a4; } + { + return t | a0 | a1 | a2 | a3 | a4; + } T const_volatile_member_func0() const volatile - { return t; } + { + return t; + } T const_volatile_member_func1(T a0) const volatile - { return t | a0; } + { + return t | a0; + } T const_volatile_member_func2(T a0, T a1) const volatile - { return t | a0 | a1; } + { + return t | a0 | a1; + } T const_volatile_member_func3(T a0, T a1, T a2) const volatile - { return t | a0 | a1 | a2; } + { + return t | a0 | a1 | a2; + } T const_volatile_member_func4(T a0, T a1, T a2, T a3) const volatile - { return t | a0 | a1 | a2 | a3; } + { + return t | a0 | a1 | a2 | a3; + } T const_volatile_member_func5(T a0, T a1, T a2, T a3, T a4) const volatile - { return t | a0 | a1 | a2 | a3 | a4; } + { + return t | a0 | a1 | a2 | a3 | a4; + } }; // bound functions template T bound_func0(Thing *t) - { return t->t; } +{ + return t->t; +} template T bound_func1(Thing *t, T a0) - { return t->t | a0; } +{ + return t->t | a0; +} template T bound_func2(Thing *t, T a0, T a1) - { return t->t | a0 | a1; } +{ + return t->t | a0 | a1; +} template T bound_func3(Thing *t, T a0, T a1, T a2) - { return t->t | a0 | a1 | a2; } +{ + return t->t | a0 | a1 | a2; +} template T bound_func4(Thing *t, T a0, T a1, T a2, T a3) - { return t->t | a0 | a1 | a2 | a3; } +{ + return t->t | a0 | a1 | a2 | a3; +} template T bound_func5(Thing *t, T a0, T a1, T a2, T a3, T a4) - { return t->t | a0 | a1 | a2 | a3 | a4; } +{ + return t->t | a0 | a1 | a2 | a3 | a4; +} template T const_bound_func0(const Thing *t) - { return t->t; } +{ + return t->t; +} template T const_bound_func1(const Thing *t, T a0) - { return t->t | a0; } +{ + return t->t | a0; +} template T const_bound_func2(const Thing *t, T a0, T a1) - { return t->t | a0 | a1; } +{ + return t->t | a0 | a1; +} template T const_bound_func3(const Thing *t, T a0, T a1, T a2) - { return t->t | a0 | a1 | a2; } +{ + return t->t | a0 | a1 | a2; +} template T const_bound_func4(const Thing *t, T a0, T a1, T a2, T a3) - { return t->t | a0 | a1 | a2 | a3; } +{ + return t->t | a0 | a1 | a2 | a3; +} template T const_bound_func5(const Thing *t, T a0, T a1, T a2, T a3, T a4) - { return t->t | a0 | a1 | a2 | a3 | a4; } +{ + return t->t | a0 | a1 | a2 | a3 | a4; +} template T volatile_bound_func0(volatile Thing *t) - { return t->t; } +{ + return t->t; +} template T volatile_bound_func1(volatile Thing *t, T a0) - { return t->t | a0; } +{ + return t->t | a0; +} template T volatile_bound_func2(volatile Thing *t, T a0, T a1) - { return t->t | a0 | a1; } +{ + return t->t | a0 | a1; +} template T volatile_bound_func3(volatile Thing *t, T a0, T a1, T a2) - { return t->t | a0 | a1 | a2; } +{ + return t->t | a0 | a1 | a2; +} template T volatile_bound_func4(volatile Thing *t, T a0, T a1, T a2, T a3) - { return t->t | a0 | a1 | a2 | a3; } +{ + return t->t | a0 | a1 | a2 | a3; +} template T volatile_bound_func5(volatile Thing *t, T a0, T a1, T a2, T a3, T a4) - { return t->t | a0 | a1 | a2 | a3 | a4; } +{ + return t->t | a0 | a1 | a2 | a3 | a4; +} template T const_volatile_bound_func0(const volatile Thing *t) - { return t->t; } +{ + return t->t; +} template T const_volatile_bound_func1(const volatile Thing *t, T a0) - { return t->t | a0; } +{ + return t->t | a0; +} template T const_volatile_bound_func2(const volatile Thing *t, T a0, T a1) - { return t->t | a0 | a1; } +{ + return t->t | a0 | a1; +} template T const_volatile_bound_func3(const volatile Thing *t, T a0, T a1, T a2) - { return t->t | a0 | a1 | a2; } +{ + return t->t | a0 | a1 | a2; +} template T const_volatile_bound_func4(const volatile Thing *t, T a0, T a1, T a2, T a3) - { return t->t | a0 | a1 | a2 | a3; } +{ + return t->t | a0 | a1 | a2 | a3; +} template T const_volatile_bound_func5(const volatile Thing *t, T a0, T a1, T a2, T a3, T a4) - { return t->t | a0 | a1 | a2 | a3 | a4; } +{ + return t->t | a0 | a1 | a2 | a3 | a4; +} // void functions template T void_func0(void *t) - { return static_cast*>(t)->t; } +{ + return static_cast*>(t)->t; +} template T void_func1(void *t, T a0) - { return static_cast*>(t)->t | a0; } +{ + return static_cast*>(t)->t | a0; +} template T void_func2(void *t, T a0, T a1) - { return static_cast*>(t)->t | a0 | a1; } +{ + return static_cast*>(t)->t | a0 | a1; +} template T void_func3(void *t, T a0, T a1, T a2) - { return static_cast*>(t)->t | a0 | a1 | a2; } +{ + return static_cast*>(t)->t | a0 | a1 | a2; +} template T void_func4(void *t, T a0, T a1, T a2, T a3) - { return static_cast*>(t)->t | a0 | a1 | a2 | a3; } +{ + return static_cast*>(t)->t | a0 | a1 | a2 | a3; +} template T void_func5(void *t, T a0, T a1, T a2, T a3, T a4) - { return static_cast*>(t)->t | a0 | a1 | a2 | a3 | a4; } +{ + return static_cast*>(t)->t | a0 | a1 | a2 | a3 | a4; +} template T const_void_func0(const void *t) - { return static_cast*>(t)->t; } +{ + return static_cast*>(t)->t; +} template T const_void_func1(const void *t, T a0) - { return static_cast*>(t)->t | a0; } +{ + return static_cast*>(t)->t | a0; +} template T const_void_func2(const void *t, T a0, T a1) - { return static_cast*>(t)->t | a0 | a1; } +{ + return static_cast*>(t)->t | a0 | a1; +} template T const_void_func3(const void *t, T a0, T a1, T a2) - { return static_cast*>(t)->t | a0 | a1 | a2; } +{ + return static_cast*>(t)->t | a0 | a1 | a2; +} template T const_void_func4(const void *t, T a0, T a1, T a2, T a3) - { return static_cast*>(t)->t | a0 | a1 | a2 | a3; } +{ + return static_cast*>(t)->t | a0 | a1 | a2 | a3; +} template T const_void_func5(const void *t, T a0, T a1, T a2, T a3, T a4) - { return static_cast*>(t)->t | a0 | a1 | a2 | a3 | a4; } +{ + return static_cast*>(t)->t | a0 | a1 | a2 | a3 | a4; +} template T volatile_void_func0(volatile void *t) - { return static_cast*>(t)->t; } +{ + return static_cast*>(t)->t; +} template T volatile_void_func1(volatile void *t, T a0) - { return static_cast*>(t)->t | a0; } +{ + return static_cast*>(t)->t | a0; +} template T volatile_void_func2(volatile void *t, T a0, T a1) - { return static_cast*>(t)->t | a0 | a1; } +{ + return static_cast*>(t)->t | a0 | a1; +} template T volatile_void_func3(volatile void *t, T a0, T a1, T a2) - { return static_cast*>(t)->t | a0 | a1 | a2; } +{ + return static_cast*>(t)->t | a0 | a1 | a2; +} template T volatile_void_func4(volatile void *t, T a0, T a1, T a2, T a3) - { return static_cast*>(t)->t | a0 | a1 | a2 | a3; } +{ + return static_cast*>(t)->t | a0 | a1 | a2 | a3; +} template T volatile_void_func5(volatile void *t, T a0, T a1, T a2, T a3, T a4) - { return static_cast*>(t)->t | a0 | a1 | a2 | a3 | a4; } +{ + return static_cast*>(t)->t | a0 | a1 | a2 | a3 | a4; +} template T const_volatile_void_func0(const volatile void *t) - { return static_cast*>(t)->t; } +{ + return static_cast*>(t)->t; +} template T const_volatile_void_func1(const volatile void *t, T a0) - { return static_cast*>(t)->t | a0; } +{ + return static_cast*>(t)->t | a0; +} template T const_volatile_void_func2(const volatile void *t, T a0, T a1) - { return static_cast*>(t)->t | a0 | a1; } +{ + return static_cast*>(t)->t | a0 | a1; +} template T const_volatile_void_func3(const volatile void *t, T a0, T a1, T a2) - { return static_cast*>(t)->t | a0 | a1 | a2; } +{ + return static_cast*>(t)->t | a0 | a1 | a2; +} template T const_volatile_void_func4(const volatile void *t, T a0, T a1, T a2, T a3) - { return static_cast*>(t)->t | a0 | a1 | a2 | a3; } +{ + return static_cast*>(t)->t | a0 | a1 | a2 | a3; +} template T const_volatile_void_func5(const volatile void *t, T a0, T a1, T a2, T a3, T a4) - { return static_cast*>(t)->t | a0 | a1 | a2 | a3 | a4; } +{ + return static_cast*>(t)->t | a0 | a1 | a2 | a3 | a4; +} // function call and result verification template struct Verifier { - static void verify0(Callback func) { + static void verify0(Callback func) + { T result = func(); TEST_ASSERT_EQUAL(result, 0x00); } template - static void verify0(O *obj, M method) { + static void verify0(O *obj, M method) + { Callback func(obj, method); T result = func(); TEST_ASSERT_EQUAL(result, 0x80); } - static void verify1(Callback func) { + static void verify1(Callback func) + { T result = func((1 << 0)); TEST_ASSERT_EQUAL(result, 0x00 | (1 << 0)); } template - static void verify1(O *obj, M method) { + static void verify1(O *obj, M method) + { Callback func(obj, method); T result = func((1 << 0)); TEST_ASSERT_EQUAL(result, 0x80 | (1 << 0)); } - static void verify2(Callback func) { + static void verify2(Callback func) + { T result = func((1 << 0), (1 << 1)); TEST_ASSERT_EQUAL(result, 0x00 | (1 << 0) | (1 << 1)); } template - static void verify2(O *obj, M method) { + static void verify2(O *obj, M method) + { Callback func(obj, method); T result = func((1 << 0), (1 << 1)); TEST_ASSERT_EQUAL(result, 0x80 | (1 << 0) | (1 << 1)); } - static void verify3(Callback func) { + static void verify3(Callback func) + { T result = func((1 << 0), (1 << 1), (1 << 2)); TEST_ASSERT_EQUAL(result, 0x00 | (1 << 0) | (1 << 1) | (1 << 2)); } template - static void verify3(O *obj, M method) { + static void verify3(O *obj, M method) + { Callback func(obj, method); T result = func((1 << 0), (1 << 1), (1 << 2)); TEST_ASSERT_EQUAL(result, 0x80 | (1 << 0) | (1 << 1) | (1 << 2)); } - static void verify4(Callback func) { + static void verify4(Callback func) + { T result = func((1 << 0), (1 << 1), (1 << 2), (1 << 3)); TEST_ASSERT_EQUAL(result, 0x00 | (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3)); } template - static void verify4(O *obj, M method) { + static void verify4(O *obj, M method) + { Callback func(obj, method); T result = func((1 << 0), (1 << 1), (1 << 2), (1 << 3)); TEST_ASSERT_EQUAL(result, 0x80 | (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3)); } - static void verify5(Callback func) { + static void verify5(Callback func) + { T result = func((1 << 0), (1 << 1), (1 << 2), (1 << 3), (1 << 4)); TEST_ASSERT_EQUAL(result, 0x00 | (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4)); } template - static void verify5(O *obj, M method) { + static void verify5(O *obj, M method) + { Callback func(obj, method); T result = func((1 << 0), (1 << 1), (1 << 2), (1 << 3), (1 << 4)); TEST_ASSERT_EQUAL(result, 0x80 | (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4)); @@ -328,24 +496,27 @@ struct Verifier { // test dispatch template -void test_fparg1() { +void test_fparg1() +{ Thing thing; - FunctionPointerArg1 fp(static_func1); + FunctionPointerArg1 fp(static_func1); Verifier::verify1(fp); Verifier::verify1(fp.get_function()); } template -void test_fparg0() { +void test_fparg0() +{ Thing thing; - FunctionPointerArg1 fp(static_func0); + FunctionPointerArg1 fp(static_func0); Verifier::verify0(fp); Verifier::verify0(fp.get_function()); } // Test setup -utest::v1::status_t test_setup(const size_t number_of_cases) { +utest::v1::status_t test_setup(const size_t number_of_cases) +{ GREENTEA_SETUP(10, "default_auto"); return verbose_test_setup_handler(number_of_cases); } @@ -357,6 +528,7 @@ Case cases[] = { Specification specification(test_setup, cases); -int main() { +int main() +{ return !Harness::run(specification); } diff --git a/TESTS/mbed_hal/common_tickers/main.cpp b/TESTS/mbed_hal/common_tickers/main.cpp index b7fac5055ea3..d81dc809a60d 100644 --- a/TESTS/mbed_hal/common_tickers/main.cpp +++ b/TESTS/mbed_hal/common_tickers/main.cpp @@ -20,6 +20,7 @@ #include "ticker_api_tests.h" #include "hal/us_ticker_api.h" #include "hal/lp_ticker_api.h" +#include "hal/mbed_lp_ticker_wrapper.h" #ifdef __cplusplus extern "C" { @@ -33,6 +34,8 @@ extern "C" { #error [NOT_SUPPORTED] test not supported #endif +#define US_PER_S 1000000 + #define FORCE_OVERFLOW_TEST (false) #define TICKER_INT_VAL 500 #define TICKER_DELTA 10 @@ -43,6 +46,7 @@ extern "C" { #define US_TICKER_OVERFLOW_DELTA2 60 #define TICKER_100_TICKS 100 +#define TICKER_500_TICKS 500 #define MAX_FUNC_EXEC_TIME_US 20 /* On CC3220SF, each write/read register access takes 800us. This is HW limitation, per TI, @@ -54,7 +58,7 @@ extern "C" { #endif #define DELTA_FUNC_EXEC_TIME_US 5 -#define NUM_OF_CALLS 1000 +#define NUM_OF_CALLS 100 #define NUM_OF_CYCLES 100000 @@ -64,7 +68,7 @@ extern "C" { using namespace utest::v1; volatile int intFlag = 0; -const ticker_interface_t* intf; +const ticker_interface_t *intf; ticker_irq_handler_type prev_irq_handler; /* Some targets might fail overflow test uncertainly due to getting trapped in busy * intf->read() loop. In the loop, some ticker values wouldn't get caught in time @@ -72,7 +76,7 @@ ticker_irq_handler_type prev_irq_handler; * 1. Lower CPU clock * 2. Compiled code with worse performance * 3. Interrupt at that time - * + * * We fix it by checking small ticker value range rather than one exact ticker point * in near overflow check. */ @@ -86,7 +90,7 @@ uint32_t count_ticks(uint32_t cycles, uint32_t step) { register uint32_t reg_cycles = cycles; - const ticker_info_t* p_ticker_info = intf->get_info(); + const ticker_info_t *p_ticker_info = intf->get_info(); const uint32_t max_count = ((1 << p_ticker_info->bits) - 1); core_util_critical_section_enter(); @@ -125,7 +129,7 @@ void overflow_protect() } const uint32_t ticks_now = intf->read(); - const ticker_info_t* p_ticker_info = intf->get_info(); + const ticker_info_t *p_ticker_info = intf->get_info(); const uint32_t max_count = ((1 << p_ticker_info->bits) - 1); @@ -136,7 +140,7 @@ void overflow_protect() while (intf->read() > ticks_now); } -void ticker_event_handler_stub(const ticker_data_t * const ticker) +void ticker_event_handler_stub(const ticker_data_t *const ticker) { if (ticker == get_us_ticker_data()) { us_ticker_clear_interrupt(); @@ -157,6 +161,19 @@ void wait_cycles(volatile unsigned int cycles) while (cycles--); } +/* Auxiliary function to determine how long ticker function are executed. + * This function returns number of us between and + * taking into account counter roll-over, counter size and frequency. + */ +uint32_t diff_us(uint32_t start_ticks, uint32_t stop_ticks, const ticker_info_t *info) +{ + uint32_t counter_mask = ((1 << info->bits) - 1); + + uint32_t diff_ticks = ((stop_ticks - start_ticks) & counter_mask); + + return (uint32_t)((uint64_t) diff_ticks * US_PER_S / info->frequency); +} + /* Test that ticker_init can be called multiple times and * ticker_init allows the ticker to keep counting and disables the ticker interrupt. */ @@ -193,7 +210,7 @@ void ticker_init_test() /* Test that ticker frequency is non-zero and counter is at least 8 bits */ void ticker_info_test(void) { - const ticker_info_t* p_ticker_info = intf->get_info(); + const ticker_info_t *p_ticker_info = intf->get_info(); TEST_ASSERT(p_ticker_info->frequency != 0); TEST_ASSERT(p_ticker_info->bits >= 8); @@ -305,7 +322,7 @@ void ticker_fire_now_test(void) /* Test that the ticker correctly handles overflow. */ void ticker_overflow_test(void) { - const ticker_info_t* p_ticker_info = intf->get_info(); + const ticker_info_t *p_ticker_info = intf->get_info(); /* We need to check how long it will take to overflow. * We will perform this test only if this time is no longer than 30 sec. @@ -323,7 +340,7 @@ void ticker_overflow_test(void) /* Wait for max count. */ while (intf->read() >= (max_count - ticker_overflow_delta2) && - intf->read() <= (max_count - ticker_overflow_delta1)) { + intf->read() <= (max_count - ticker_overflow_delta1)) { /* Just wait. */ } @@ -360,7 +377,7 @@ void ticker_overflow_test(void) /* Test that the ticker increments by one on each tick. */ void ticker_increment_test(void) { - const ticker_info_t* p_ticker_info = intf->get_info(); + const ticker_info_t *p_ticker_info = intf->get_info(); /* Perform test based on ticker speed. */ if (p_ticker_info->frequency <= 250000) { // low frequency tickers @@ -400,7 +417,7 @@ void ticker_increment_test(void) } else { /* Check if we got 1 tick diff. */ if (next_tick_count - base_tick_count == 1 || - base_tick_count - next_tick_count == 1) { + base_tick_count - next_tick_count == 1) { break; } @@ -427,8 +444,13 @@ void ticker_increment_test(void) /* Test that common ticker functions complete with the required amount of time. */ void ticker_speed_test(void) { - Timer timer; int counter = NUM_OF_CALLS; +<<<<<<< HEAD + uint32_t start; + uint32_t stop; + + const ticker_info_t *us_ticker_info = get_us_ticker_data()->interface->get_info(); +======= int max_func_exec_time = NUM_OF_CALLS * (MAX_FUNC_EXEC_TIME_US + DELTA_FUNC_EXEC_TIME_US); #if TARGET_TI @@ -438,37 +460,46 @@ void ticker_speed_test(void) lp_test = true; } #endif +>>>>>>> 0b7e2062cc6b5f7f8e94b8c3269c0d28638007aa /* ---- Test ticker_read function. ---- */ - timer.reset(); - timer.start(); + start = us_ticker_read(); while (counter--) { intf->read(); } - timer.stop(); + stop = us_ticker_read(); +<<<<<<< HEAD + TEST_ASSERT(diff_us(start, stop, us_ticker_info) < (NUM_OF_CALLS * (MAX_FUNC_EXEC_TIME_US + DELTA_FUNC_EXEC_TIME_US))); +======= TEST_ASSERT(timer.read_us() < max_func_exec_time); +>>>>>>> 0b7e2062cc6b5f7f8e94b8c3269c0d28638007aa /* ---- Test ticker_clear_interrupt function. ---- */ counter = NUM_OF_CALLS; - timer.reset(); - timer.start(); + start = us_ticker_read(); while (counter--) { intf->clear_interrupt(); } - timer.stop(); + stop = us_ticker_read(); +<<<<<<< HEAD + TEST_ASSERT(diff_us(start, stop, us_ticker_info) < (NUM_OF_CALLS * (MAX_FUNC_EXEC_TIME_US + DELTA_FUNC_EXEC_TIME_US))); +======= TEST_ASSERT(timer.read_us() < max_func_exec_time); +>>>>>>> 0b7e2062cc6b5f7f8e94b8c3269c0d28638007aa /* ---- Test ticker_set_interrupt function. ---- */ counter = NUM_OF_CALLS; - timer.reset(); - timer.start(); + start = us_ticker_read(); while (counter--) { intf->set_interrupt(0); } - timer.stop(); + stop = us_ticker_read(); +<<<<<<< HEAD + TEST_ASSERT(diff_us(start, stop, us_ticker_info) < (NUM_OF_CALLS * (MAX_FUNC_EXEC_TIME_US + DELTA_FUNC_EXEC_TIME_US))); +======= #ifdef TARGET_TI if (lp_test) { @@ -476,25 +507,34 @@ void ticker_speed_test(void) } #endif TEST_ASSERT(timer.read_us() < max_func_exec_time); +>>>>>>> 0b7e2062cc6b5f7f8e94b8c3269c0d28638007aa /* ---- Test fire_interrupt function. ---- */ counter = NUM_OF_CALLS; - timer.reset(); - timer.start(); + start = us_ticker_read(); while (counter--) { intf->fire_interrupt(); } - timer.stop(); + stop = us_ticker_read(); +<<<<<<< HEAD + TEST_ASSERT(diff_us(start, stop, us_ticker_info) < (NUM_OF_CALLS * (MAX_FUNC_EXEC_TIME_US + DELTA_FUNC_EXEC_TIME_US))); +======= TEST_ASSERT(timer.read_us() < max_func_exec_time); +>>>>>>> 0b7e2062cc6b5f7f8e94b8c3269c0d28638007aa /* ---- Test disable_interrupt function. ---- */ counter = NUM_OF_CALLS; - timer.reset(); - timer.start(); + start = us_ticker_read(); while (counter--) { intf->disable_interrupt(); } +<<<<<<< HEAD + stop = us_ticker_read(); + + TEST_ASSERT(diff_us(start, stop, us_ticker_info) < (NUM_OF_CALLS * (MAX_FUNC_EXEC_TIME_US + DELTA_FUNC_EXEC_TIME_US))); + +======= timer.stop(); #ifdef TARGET_TI if (lp_test) @@ -504,13 +544,22 @@ void ticker_speed_test(void) #endif TEST_ASSERT(timer.read_us() < max_func_exec_time); +>>>>>>> 0b7e2062cc6b5f7f8e94b8c3269c0d28638007aa } utest::v1::status_t us_ticker_setup(const Case *const source, const size_t index_of_case) { intf = get_us_ticker_data()->interface; - OS_Tick_Disable(); + /* OS, common ticker and low power ticker wrapper + * may make use of us ticker so suspend them for this test */ + osKernelSuspend(); +#if DEVICE_LPTICKER && (LPTICKER_DELAY_TICKS > 0) + /* Suspend the lp ticker wrapper since it makes use of the us ticker */ + ticker_suspend(get_lp_ticker_data()); + lp_ticker_wrapper_suspend(); +#endif + ticker_suspend(get_us_ticker_data()); intf->init(); @@ -522,14 +571,19 @@ utest::v1::status_t us_ticker_setup(const Case *const source, const size_t index return greentea_case_setup_handler(source, index_of_case); } -utest::v1::status_t us_ticker_teardown(const Case * const source, const size_t passed, const size_t failed, - const failure_t reason) +utest::v1::status_t us_ticker_teardown(const Case *const source, const size_t passed, const size_t failed, + const failure_t reason) { set_us_ticker_irq_handler(prev_irq_handler); prev_irq_handler = NULL; - OS_Tick_Enable(); + ticker_resume(get_us_ticker_data()); +#if DEVICE_LPTICKER && (LPTICKER_DELAY_TICKS > 0) + lp_ticker_wrapper_resume(); + ticker_resume(get_lp_ticker_data()); +#endif + osKernelResume(0); return greentea_case_teardown_handler(source, passed, failed, reason); } @@ -539,7 +593,9 @@ utest::v1::status_t lp_ticker_setup(const Case *const source, const size_t index { intf = get_lp_ticker_data()->interface; - OS_Tick_Disable(); + /* OS and common ticker may make use of lp ticker so suspend them for this test */ + osKernelSuspend(); + ticker_suspend(get_lp_ticker_data()); intf->init(); @@ -551,14 +607,15 @@ utest::v1::status_t lp_ticker_setup(const Case *const source, const size_t index return greentea_case_setup_handler(source, index_of_case); } -utest::v1::status_t lp_ticker_teardown(const Case * const source, const size_t passed, const size_t failed, - const failure_t reason) +utest::v1::status_t lp_ticker_teardown(const Case *const source, const size_t passed, const size_t failed, + const failure_t reason) { set_lp_ticker_irq_handler(prev_irq_handler); prev_irq_handler = NULL; - OS_Tick_Enable(); + ticker_resume(get_lp_ticker_data()); + osKernelResume(0); return greentea_case_teardown_handler(source, passed, failed, reason); } diff --git a/TESTS/mbed_hal/common_tickers_freq/main.cpp b/TESTS/mbed_hal/common_tickers_freq/main.cpp index c9952f11616e..bf5c9a0301c0 100644 --- a/TESTS/mbed_hal/common_tickers_freq/main.cpp +++ b/TESTS/mbed_hal/common_tickers_freq/main.cpp @@ -28,6 +28,7 @@ #include "ticker_api_test_freq.h" #include "hal/us_ticker_api.h" #include "hal/lp_ticker_api.h" +#include "hal/mbed_lp_ticker_wrapper.h" #if !DEVICE_USTICKER #error [NOT_SUPPORTED] test not supported @@ -37,26 +38,52 @@ using namespace utest::v1; -const ticker_interface_t* intf; - -static volatile unsigned int overflowCounter; +const ticker_interface_t *intf; +uint32_t intf_mask; +uint32_t intf_last_tick; +uint32_t intf_elapsed_ticks; +ticker_irq_handler_type prev_handler; uint32_t ticks_to_us(uint32_t ticks, uint32_t freq) { return (uint32_t)((uint64_t)ticks * US_PER_S / freq); } -void ticker_event_handler_stub(const ticker_data_t * const ticker) +void elapsed_ticks_reset() { - if (ticker == get_us_ticker_data()) { - us_ticker_clear_interrupt(); - } else { -#if DEVICE_LPTICKER - lp_ticker_clear_interrupt(); -#endif - } + core_util_critical_section_enter(); + + const uint32_t ticker_bits = intf->get_info()->bits; + + intf_mask = (1 << ticker_bits) - 1; + intf_last_tick = intf->read(); + intf_elapsed_ticks = 0; + + core_util_critical_section_exit(); +} - overflowCounter++; +uint32_t elapsed_ticks_update() +{ + core_util_critical_section_enter(); + + const uint32_t current_tick = intf->read(); + intf_elapsed_ticks += (current_tick - intf_last_tick) & intf_mask; + intf_last_tick = current_tick; + + /* Schedule next interrupt half way to overflow */ + uint32_t next = (current_tick + intf_mask / 2) & intf_mask; + intf->set_interrupt(next); + + uint32_t elapsed = intf_elapsed_ticks; + + core_util_critical_section_exit(); + return elapsed; +} + +void ticker_event_handler_stub(const ticker_data_t *const ticker) +{ + intf->clear_interrupt(); + elapsed_ticks_update(); } /* Test that the ticker is operating at the frequency it specifies. */ @@ -66,13 +93,13 @@ void ticker_frequency_test() char _value[128] = { }; int expected_key = 1; const uint32_t ticker_freq = intf->get_info()->frequency; - const uint32_t ticker_bits = intf->get_info()->bits; - const uint32_t ticker_max = (1 << ticker_bits) - 1; intf->init(); + elapsed_ticks_reset(); + /* Detect overflow for tickers with lower counters width. */ - intf->set_interrupt(0); + elapsed_ticks_update(); greentea_send_kv("timing_drift_check_start", 0); @@ -82,9 +109,7 @@ void ticker_frequency_test() expected_key = strcmp(_key, "base_time"); } while (expected_key); - overflowCounter = 0; - - const uint32_t begin_ticks = intf->read(); + const uint32_t begin_ticks = elapsed_ticks_update(); /* Assume that there was no overflow at this point - we are just after init. */ greentea_send_kv(_key, ticks_to_us(begin_ticks, ticker_freq)); @@ -92,57 +117,88 @@ void ticker_frequency_test() /* Wait for 2nd signal from host. */ greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value)); - const uint32_t end_ticks = intf->read(); + const uint32_t end_ticks = elapsed_ticks_update(); - greentea_send_kv(_key, ticks_to_us(end_ticks + overflowCounter * ticker_max, ticker_freq)); + greentea_send_kv(_key, ticks_to_us(end_ticks, ticker_freq)); /* Get the results from host. */ greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value)); - TEST_ASSERT_EQUAL_STRING_MESSAGE("pass", _key,"Host side script reported a fail..."); + TEST_ASSERT_EQUAL_STRING_MESSAGE("pass", _key, "Host side script reported a fail..."); intf->disable_interrupt(); } -utest::v1::status_t us_ticker_case_setup_handler_t(const Case * const source, const size_t index_of_case) +utest::v1::status_t us_ticker_case_setup_handler_t(const Case *const source, const size_t index_of_case) { +#if DEVICE_LPTICKER && (LPTICKER_DELAY_TICKS > 0) + /* Suspend the lp ticker wrapper since it makes use of the us ticker */ + ticker_suspend(get_lp_ticker_data()); + lp_ticker_wrapper_suspend(); +#endif + ticker_suspend(get_us_ticker_data()); intf = get_us_ticker_data()->interface; - set_us_ticker_irq_handler(ticker_event_handler_stub); + prev_handler = set_us_ticker_irq_handler(ticker_event_handler_stub); return greentea_case_setup_handler(source, index_of_case); } +utest::v1::status_t us_ticker_case_teardown_handler_t(const Case *const source, const size_t passed, const size_t failed, + const failure_t reason) +{ + set_us_ticker_irq_handler(prev_handler); + ticker_resume(get_us_ticker_data()); +#if DEVICE_LPTICKER && (LPTICKER_DELAY_TICKS > 0) + lp_ticker_wrapper_resume(); + ticker_resume(get_lp_ticker_data()); +#endif + return greentea_case_teardown_handler(source, passed, failed, reason); +} + #if DEVICE_LPTICKER -utest::v1::status_t lp_ticker_case_setup_handler_t(const Case * const source, const size_t index_of_case) +utest::v1::status_t lp_ticker_case_setup_handler_t(const Case *const source, const size_t index_of_case) { + ticker_suspend(get_lp_ticker_data()); intf = get_lp_ticker_data()->interface; - set_lp_ticker_irq_handler(ticker_event_handler_stub); + prev_handler = set_lp_ticker_irq_handler(ticker_event_handler_stub); return greentea_case_setup_handler(source, index_of_case); } -#endif -utest::v1::status_t ticker_case_teardown_handler_t(const Case * const source, const size_t passed, const size_t failed, - const failure_t reason) +utest::v1::status_t lp_ticker_case_teardown_handler_t(const Case *const source, const size_t passed, const size_t failed, + const failure_t reason) { + set_lp_ticker_irq_handler(prev_handler); + ticker_resume(get_lp_ticker_data()); return greentea_case_teardown_handler(source, passed, failed, reason); } +#endif // Test cases Case cases[] = { Case("Microsecond ticker frequency test", us_ticker_case_setup_handler_t, ticker_frequency_test, - ticker_case_teardown_handler_t), + us_ticker_case_teardown_handler_t), #if DEVICE_LPTICKER Case("Low power ticker frequency test", lp_ticker_case_setup_handler_t, ticker_frequency_test, - ticker_case_teardown_handler_t), + lp_ticker_case_teardown_handler_t), #endif - }; +}; utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { + /* Suspend RTOS Kernel so the timers are not in use. */ + osKernelSuspend(); + GREENTEA_SETUP(120, "timing_drift_auto"); return greentea_test_setup_handler(number_of_cases); } -Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); +void greentea_test_teardown(const size_t passed, const size_t failed, const failure_t failure) +{ + osKernelResume(0); + + greentea_test_teardown_handler(passed, failed, failure); +} + +Specification specification(greentea_test_setup, cases, greentea_test_teardown); int main() { diff --git a/TESTS/mbed_hal/crc/main.cpp b/TESTS/mbed_hal/crc/main.cpp index 27f32341600d..c233c120d60c 100644 --- a/TESTS/mbed_hal/crc/main.cpp +++ b/TESTS/mbed_hal/crc/main.cpp @@ -35,8 +35,7 @@ using namespace utest::v1; const uint8_t input_data[] = "123456789"; -typedef struct -{ +typedef struct { const crc_mbed_config config_data; uint32_t expected_result; @@ -72,7 +71,7 @@ void crc_calc_single_test() if (hal_crc_is_supported(&test_cases[i].config_data) == true) { hal_crc_compute_partial_start(&test_cases[i].config_data); - hal_crc_compute_partial((uint8_t*) input_data, strlen((const char*) input_data)); + hal_crc_compute_partial((uint8_t *) input_data, strlen((const char *) input_data)); const uint32_t crc = hal_crc_get_result(); TEST_ASSERT_EQUAL(test_cases[i].expected_result, crc); @@ -89,14 +88,14 @@ void crc_calc_multi_test() const uint32_t first_part_bytes = 3; const uint32_t second_part_bytes = 1; - const uint32_t third_part_bytes = strlen((const char*) input_data) - first_part_bytes - - second_part_bytes; + const uint32_t third_part_bytes = strlen((const char *) input_data) - first_part_bytes + - second_part_bytes; hal_crc_compute_partial_start(&test_cases[i].config_data); - hal_crc_compute_partial((uint8_t*) input_data, first_part_bytes); - hal_crc_compute_partial((uint8_t*) (input_data + first_part_bytes), second_part_bytes); - hal_crc_compute_partial((uint8_t*) (input_data + first_part_bytes + second_part_bytes), - third_part_bytes); + hal_crc_compute_partial((uint8_t *) input_data, first_part_bytes); + hal_crc_compute_partial((uint8_t *)(input_data + first_part_bytes), second_part_bytes); + hal_crc_compute_partial((uint8_t *)(input_data + first_part_bytes + second_part_bytes), + third_part_bytes); const uint32_t crc = hal_crc_get_result(); TEST_ASSERT_EQUAL(test_cases[i].expected_result, crc); @@ -137,7 +136,7 @@ void crc_reconfigure_test() /* Init CRC module and provide some data, but do not read the result. */ hal_crc_compute_partial_start(&test_cases[pol_idx[pol_cnt]].config_data); - hal_crc_compute_partial((uint8_t*) dummy_input_data, strlen((const char*) dummy_input_data)); + hal_crc_compute_partial((uint8_t *) dummy_input_data, strlen((const char *) dummy_input_data)); /* Change index only if more than one supported polynomial has been found. */ if (pol_idx[POL_CNT - 1] != UNSUPPORTED) { @@ -146,7 +145,7 @@ void crc_reconfigure_test() /* Now re-init CRC module and provide new data and check the result. */ hal_crc_compute_partial_start(&test_cases[pol_idx[pol_cnt]].config_data); - hal_crc_compute_partial((uint8_t*) input_data, strlen((const char*) input_data)); + hal_crc_compute_partial((uint8_t *) input_data, strlen((const char *) input_data)); const uint32_t crc = hal_crc_get_result(); TEST_ASSERT_EQUAL(test_cases[pol_idx[pol_cnt]].expected_result, crc); @@ -165,12 +164,12 @@ void crc_compute_partial_invalid_param_test() hal_crc_compute_partial_start(&test_cases[i].config_data); /* Call hal_crc_compute_partial() with invalid parameters. */ - hal_crc_compute_partial((uint8_t*) NULL, strlen((const char*) input_data)); - hal_crc_compute_partial((uint8_t*) input_data, 0); + hal_crc_compute_partial((uint8_t *) NULL, strlen((const char *) input_data)); + hal_crc_compute_partial((uint8_t *) input_data, 0); /* Now use valid parameters. */ - hal_crc_compute_partial((uint8_t*) input_data, - strlen((const char*) input_data)); + hal_crc_compute_partial((uint8_t *) input_data, + strlen((const char *) input_data)); crc = hal_crc_get_result(); @@ -206,73 +205,75 @@ Specification specification(greentea_test_setup, cases, greentea_test_teardown_h int main() { + // *INDENT-OFF* TEST_CASE local_test_cases[] = { /* Predefined polynomials. */ -/* 00 */{ {POLY_7BIT_SD , 7, 0x00000000, 0x00000000, false, false}, 0xEA }, -/* 01 */{ {POLY_7BIT_SD , 7, 0x0000007F, 0x00000000, false, false}, 0xA0 }, -/* 02 */{ {POLY_7BIT_SD , 7, 0x0000002B, 0x00000000, false, false}, 0x74 }, -/* 03 */{ {POLY_7BIT_SD , 7, 0x00000000, 0x0000007F, false, false}, 0x95 }, -/* 04 */{ {POLY_7BIT_SD , 7, 0x00000000, 0x0000002B, false, false}, 0xC1 }, -/* 05 */{ {POLY_7BIT_SD , 7, 0x00000000, 0x00000000, true , false}, 0xA4 }, -/* 06 */{ {POLY_7BIT_SD , 7, 0x00000000, 0x00000000, false, true }, 0x57 }, - -/* 07 */{ {POLY_8BIT_CCITT , 8, 0x00000000, 0x00000000, false, false}, 0xF4 }, -/* 08 */{ {POLY_8BIT_CCITT , 8, 0x000000FF, 0x00000000, false, false}, 0xFB }, -/* 09 */{ {POLY_8BIT_CCITT , 8, 0x000000AB, 0x00000000, false, false}, 0x87 }, -/* 10 */{ {POLY_8BIT_CCITT , 8, 0x00000000, 0x000000FF, false, false}, 0x0B }, -/* 11 */{ {POLY_8BIT_CCITT , 8, 0x00000000, 0x000000AB, false, false}, 0x5F }, -/* 12 */{ {POLY_8BIT_CCITT , 8, 0x00000000, 0x00000000, true , false}, 0x04 }, -/* 13 */{ {POLY_8BIT_CCITT , 8, 0x00000000, 0x00000000, false, true }, 0x2F }, - -/* 14 */{ {POLY_16BIT_CCITT , 16, 0x00000000, 0x00000000, false, false}, 0x31C3 }, -/* 15 */{ {POLY_16BIT_CCITT , 16, 0x0000FFFF, 0x00000000, false, false}, 0x29B1 }, -/* 16 */{ {POLY_16BIT_CCITT , 16, 0x0000ABAB, 0x00000000, false, false}, 0x7D70 }, -/* 17 */{ {POLY_16BIT_CCITT , 16, 0x00000000, 0x0000FFFF, false, false}, 0xCE3C }, -/* 18 */{ {POLY_16BIT_CCITT , 16, 0x00000000, 0x0000ABAB, false, false}, 0x9A68 }, -/* 19 */{ {POLY_16BIT_CCITT , 16, 0x00000000, 0x00000000, true , false}, 0x9184 }, -/* 20 */{ {POLY_16BIT_CCITT , 16, 0x00000000, 0x00000000, false, true }, 0xC38C }, - -/* 21 */{ {POLY_16BIT_IBM , 16, 0x00000000, 0x00000000, false, false}, 0xFEE8 }, -/* 22 */{ {POLY_16BIT_IBM , 16, 0x0000FFFF, 0x00000000, false, false}, 0xAEE7 }, -/* 23 */{ {POLY_16BIT_IBM , 16, 0x0000ABAB, 0x00000000, false, false}, 0x0887 }, -/* 24 */{ {POLY_16BIT_IBM , 16, 0x00000000, 0x0000FFFF, false, false}, 0x0117 }, -/* 25 */{ {POLY_16BIT_IBM , 16, 0x00000000, 0x0000ABAB, false, false}, 0x5543 }, -/* 26 */{ {POLY_16BIT_IBM , 16, 0x00000000, 0x00000000, true , false}, 0xBCDD }, -/* 27 */{ {POLY_16BIT_IBM , 16, 0x00000000, 0x00000000, false, true }, 0x177F }, - -/* 28 */{ {POLY_32BIT_ANSI , 32, 0x00000000, 0x00000000, false, false}, 0x89A1897F }, -/* 29 */{ {POLY_32BIT_ANSI , 32, 0xFFFFFFFF, 0x00000000, false, false}, 0x0376E6E7 }, -/* 30 */{ {POLY_32BIT_ANSI , 32, 0xABABABAB, 0x00000000, false, false}, 0x871A2FAA }, -/* 31 */{ {POLY_32BIT_ANSI , 32, 0x00000000, 0xFFFFFFFF, false, false}, 0x765E7680 }, -/* 32 */{ {POLY_32BIT_ANSI , 32, 0x00000000, 0xABABABAB, false, false}, 0x220A22D4 }, -/* 33 */{ {POLY_32BIT_ANSI , 32, 0x00000000, 0x00000000, true , false}, 0x11B4BFB4 }, -/* 34 */{ {POLY_32BIT_ANSI , 32, 0x00000000, 0x00000000, false, true }, 0xFE918591 }, - - /* Not-predefined polynomials. */ -/* 35 */{ {POLY_8BIT_MAXIM , 8, 0x00000000, 0x00000000, false, false}, 0xA2 }, -/* 36 */{ {POLY_8BIT_MAXIM , 8, 0x000000FF, 0x00000000, false, false}, 0xF7 }, -/* 37 */{ {POLY_8BIT_MAXIM , 8, 0x000000AB, 0x00000000, false, false}, 0x71 }, -/* 38 */{ {POLY_8BIT_MAXIM , 8, 0x00000000, 0x000000FF, false, false}, 0x5D }, -/* 39 */{ {POLY_8BIT_MAXIM , 8, 0x00000000, 0x000000AB, false, false}, 0x09 }, -/* 40 */{ {POLY_8BIT_MAXIM , 8, 0x00000000, 0x00000000, true , false}, 0x85 }, -/* 41 */{ {POLY_8BIT_MAXIM , 8, 0x00000000, 0x00000000, false, true }, 0x45 }, - -/* 42 */{ {POLY_16BIT_MAXIM , 16, 0x00000000, 0x00000000, false, false}, 0xFEE8 }, -/* 43 */{ {POLY_16BIT_MAXIM , 16, 0x0000FFFF, 0x00000000, false, false}, 0xAEE7 }, -/* 44 */{ {POLY_16BIT_MAXIM , 16, 0x0000ABAB, 0x00000000, false, false}, 0x0887 }, -/* 45 */{ {POLY_16BIT_MAXIM , 16, 0x00000000, 0x0000FFFF, false, false}, 0x0117 }, -/* 46 */{ {POLY_16BIT_MAXIM , 16, 0x00000000, 0x0000ABAB, false, false}, 0x5543 }, -/* 47 */{ {POLY_16BIT_MAXIM , 16, 0x00000000, 0x00000000, true , false}, 0xBCDD }, -/* 48 */{ {POLY_16BIT_MAXIM , 16, 0x00000000, 0x00000000, false, true }, 0x177F }, - -/* 49 */{ {POLY_32BIT_POSIX , 32, 0x00000000, 0x00000000, false, false}, 0x89A1897F }, -/* 50 */{ {POLY_32BIT_POSIX , 32, 0xFFFFFFFF, 0x00000000, false, false}, 0x0376E6E7 }, -/* 51 */{ {POLY_32BIT_POSIX , 32, 0xABABABAB, 0x00000000, false, false}, 0x871A2FAA }, -/* 52 */{ {POLY_32BIT_POSIX , 32, 0x00000000, 0xFFFFFFFF, false, false}, 0x765E7680 }, -/* 53 */{ {POLY_32BIT_POSIX , 32, 0x00000000, 0xABABABAB, false, false}, 0x220A22D4 }, -/* 54 */{ {POLY_32BIT_POSIX , 32, 0x00000000, 0x00000000, true , false}, 0x11B4BFB4 }, -/* 55 */{ {POLY_32BIT_POSIX , 32, 0x00000000, 0x00000000, false, true }, 0xFE918591 }, + /* 00 */{ {POLY_7BIT_SD , 7, 0x00000000, 0x00000000, false, false}, 0xEA }, + /* 01 */{ {POLY_7BIT_SD , 7, 0x0000007F, 0x00000000, false, false}, 0xA0 }, + /* 02 */{ {POLY_7BIT_SD , 7, 0x0000002B, 0x00000000, false, false}, 0x74 }, + /* 03 */{ {POLY_7BIT_SD , 7, 0x00000000, 0x0000007F, false, false}, 0x95 }, + /* 04 */{ {POLY_7BIT_SD , 7, 0x00000000, 0x0000002B, false, false}, 0xC1 }, + /* 05 */{ {POLY_7BIT_SD , 7, 0x00000000, 0x00000000, true , false}, 0xA4 }, + /* 06 */{ {POLY_7BIT_SD , 7, 0x00000000, 0x00000000, false, true }, 0x57 }, + + /* 07 */{ {POLY_8BIT_CCITT , 8, 0x00000000, 0x00000000, false, false}, 0xF4 }, + /* 08 */{ {POLY_8BIT_CCITT , 8, 0x000000FF, 0x00000000, false, false}, 0xFB }, + /* 09 */{ {POLY_8BIT_CCITT , 8, 0x000000AB, 0x00000000, false, false}, 0x87 }, + /* 10 */{ {POLY_8BIT_CCITT , 8, 0x00000000, 0x000000FF, false, false}, 0x0B }, + /* 11 */{ {POLY_8BIT_CCITT , 8, 0x00000000, 0x000000AB, false, false}, 0x5F }, + /* 12 */{ {POLY_8BIT_CCITT , 8, 0x00000000, 0x00000000, true , false}, 0x04 }, + /* 13 */{ {POLY_8BIT_CCITT , 8, 0x00000000, 0x00000000, false, true }, 0x2F }, + + /* 14 */{ {POLY_16BIT_CCITT , 16, 0x00000000, 0x00000000, false, false}, 0x31C3 }, + /* 15 */{ {POLY_16BIT_CCITT , 16, 0x0000FFFF, 0x00000000, false, false}, 0x29B1 }, + /* 16 */{ {POLY_16BIT_CCITT , 16, 0x0000ABAB, 0x00000000, false, false}, 0x7D70 }, + /* 17 */{ {POLY_16BIT_CCITT , 16, 0x00000000, 0x0000FFFF, false, false}, 0xCE3C }, + /* 18 */{ {POLY_16BIT_CCITT , 16, 0x00000000, 0x0000ABAB, false, false}, 0x9A68 }, + /* 19 */{ {POLY_16BIT_CCITT , 16, 0x00000000, 0x00000000, true , false}, 0x9184 }, + /* 20 */{ {POLY_16BIT_CCITT , 16, 0x00000000, 0x00000000, false, true }, 0xC38C }, + + /* 21 */{ {POLY_16BIT_IBM , 16, 0x00000000, 0x00000000, false, false}, 0xFEE8 }, + /* 22 */{ {POLY_16BIT_IBM , 16, 0x0000FFFF, 0x00000000, false, false}, 0xAEE7 }, + /* 23 */{ {POLY_16BIT_IBM , 16, 0x0000ABAB, 0x00000000, false, false}, 0x0887 }, + /* 24 */{ {POLY_16BIT_IBM , 16, 0x00000000, 0x0000FFFF, false, false}, 0x0117 }, + /* 25 */{ {POLY_16BIT_IBM , 16, 0x00000000, 0x0000ABAB, false, false}, 0x5543 }, + /* 26 */{ {POLY_16BIT_IBM , 16, 0x00000000, 0x00000000, true , false}, 0xBCDD }, + /* 27 */{ {POLY_16BIT_IBM , 16, 0x00000000, 0x00000000, false, true }, 0x177F }, + + /* 28 */{ {POLY_32BIT_ANSI , 32, 0x00000000, 0x00000000, false, false}, 0x89A1897F }, + /* 29 */{ {POLY_32BIT_ANSI , 32, 0xFFFFFFFF, 0x00000000, false, false}, 0x0376E6E7 }, + /* 30 */{ {POLY_32BIT_ANSI , 32, 0xABABABAB, 0x00000000, false, false}, 0x871A2FAA }, + /* 31 */{ {POLY_32BIT_ANSI , 32, 0x00000000, 0xFFFFFFFF, false, false}, 0x765E7680 }, + /* 32 */{ {POLY_32BIT_ANSI , 32, 0x00000000, 0xABABABAB, false, false}, 0x220A22D4 }, + /* 33 */{ {POLY_32BIT_ANSI , 32, 0x00000000, 0x00000000, true , false}, 0x11B4BFB4 }, + /* 34 */{ {POLY_32BIT_ANSI , 32, 0x00000000, 0x00000000, false, true }, 0xFE918591 }, + + /* Not-predefined polynomials. */ + /* 35 */{ {POLY_8BIT_MAXIM , 8, 0x00000000, 0x00000000, false, false}, 0xA2 }, + /* 36 */{ {POLY_8BIT_MAXIM , 8, 0x000000FF, 0x00000000, false, false}, 0xF7 }, + /* 37 */{ {POLY_8BIT_MAXIM , 8, 0x000000AB, 0x00000000, false, false}, 0x71 }, + /* 38 */{ {POLY_8BIT_MAXIM , 8, 0x00000000, 0x000000FF, false, false}, 0x5D }, + /* 39 */{ {POLY_8BIT_MAXIM , 8, 0x00000000, 0x000000AB, false, false}, 0x09 }, + /* 40 */{ {POLY_8BIT_MAXIM , 8, 0x00000000, 0x00000000, true , false}, 0x85 }, + /* 41 */{ {POLY_8BIT_MAXIM , 8, 0x00000000, 0x00000000, false, true }, 0x45 }, + + /* 42 */{ {POLY_16BIT_MAXIM , 16, 0x00000000, 0x00000000, false, false}, 0xFEE8 }, + /* 43 */{ {POLY_16BIT_MAXIM , 16, 0x0000FFFF, 0x00000000, false, false}, 0xAEE7 }, + /* 44 */{ {POLY_16BIT_MAXIM , 16, 0x0000ABAB, 0x00000000, false, false}, 0x0887 }, + /* 45 */{ {POLY_16BIT_MAXIM , 16, 0x00000000, 0x0000FFFF, false, false}, 0x0117 }, + /* 46 */{ {POLY_16BIT_MAXIM , 16, 0x00000000, 0x0000ABAB, false, false}, 0x5543 }, + /* 47 */{ {POLY_16BIT_MAXIM , 16, 0x00000000, 0x00000000, true , false}, 0xBCDD }, + /* 48 */{ {POLY_16BIT_MAXIM , 16, 0x00000000, 0x00000000, false, true }, 0x177F }, + + /* 49 */{ {POLY_32BIT_POSIX , 32, 0x00000000, 0x00000000, false, false}, 0x89A1897F }, + /* 50 */{ {POLY_32BIT_POSIX , 32, 0xFFFFFFFF, 0x00000000, false, false}, 0x0376E6E7 }, + /* 51 */{ {POLY_32BIT_POSIX , 32, 0xABABABAB, 0x00000000, false, false}, 0x871A2FAA }, + /* 52 */{ {POLY_32BIT_POSIX , 32, 0x00000000, 0xFFFFFFFF, false, false}, 0x765E7680 }, + /* 53 */{ {POLY_32BIT_POSIX , 32, 0x00000000, 0xABABABAB, false, false}, 0x220A22D4 }, + /* 54 */{ {POLY_32BIT_POSIX , 32, 0x00000000, 0x00000000, true , false}, 0x11B4BFB4 }, + /* 55 */{ {POLY_32BIT_POSIX , 32, 0x00000000, 0x00000000, false, true }, 0xFE918591 }, }; + // *INDENT-ON* test_cases = local_test_cases; test_cases_size = sizeof(local_test_cases); diff --git a/TESTS/mbed_hal/critical_section/main.cpp b/TESTS/mbed_hal/critical_section/main.cpp index e8dc26daee2f..c3ae160e3359 100644 --- a/TESTS/mbed_hal/critical_section/main.cpp +++ b/TESTS/mbed_hal/critical_section/main.cpp @@ -31,11 +31,11 @@ bool test_are_interrupts_enabled(void) // NRF5x targets don't disable interrupts when in critical section, instead they mask application interrupts this is due to BLE stack // (BLE to be operational requires some interrupts to be always enabled) #if defined(TARGET_NRF52) - // check if APP interrupts are masked for NRF52 boards - return (((NVIC->ISER[0] & __NRF_NVIC_APP_IRQS_0) != 0) || ((NVIC->ISER[1] & __NRF_NVIC_APP_IRQS_1) != 0)); + // check if APP interrupts are masked for NRF52 boards + return (((NVIC->ISER[0] & __NRF_NVIC_APP_IRQS_0) != 0) || ((NVIC->ISER[1] & __NRF_NVIC_APP_IRQS_1) != 0)); #elif defined(TARGET_NRF51) - // check if APP interrupts are masked for other NRF51 boards - return ((NVIC->ISER[0] & __NRF_NVIC_APP_IRQS_0) != 0); + // check if APP interrupts are masked for other NRF51 boards + return ((NVIC->ISER[0] & __NRF_NVIC_APP_IRQS_0) != 0); #else #if defined(__CORTEX_A9) return ((__get_CPSR() & 0x80) == 0); diff --git a/TESTS/mbed_hal/flash/functional_tests/main.cpp b/TESTS/mbed_hal/flash/functional_tests/main.cpp index 808ab18e54a7..aec1ffea8134 100644 --- a/TESTS/mbed_hal/flash/functional_tests/main.cpp +++ b/TESTS/mbed_hal/flash/functional_tests/main.cpp @@ -15,7 +15,7 @@ */ #if !DEVICE_FLASH - #error [NOT_SUPPORTED] Flash API not supported for this target +#error [NOT_SUPPORTED] Flash API not supported for this target #endif #include "utest/utest.h" @@ -57,40 +57,43 @@ static void erase_range(flash_t *flash, uint32_t addr, uint32_t size) MBED_NOINLINE __asm static void delay_loop(uint32_t count) { +// AStyle should not format inline assembly +// *INDENT-OFF* 1 SUBS a1, a1, #1 BCS %BT1 BX lr +// *INDENT-ON* } #elif defined (__ICCARM__) MBED_NOINLINE static void delay_loop(uint32_t count) { - __asm volatile( - "loop: \n" - " SUBS %0, %0, #1 \n" - " BCS.n loop\n" - : "+r" (count) - : - : "cc" - ); + __asm volatile( + "loop: \n" + " SUBS %0, %0, #1 \n" + " BCS.n loop\n" + : "+r"(count) + : + : "cc" + ); } #elif defined ( __GNUC__ ) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) MBED_NOINLINE static void delay_loop(uint32_t count) { - __asm__ volatile ( - "%=:\n\t" + __asm__ volatile( + "%=:\n\t" #if defined(__thumb__) && !defined(__thumb2__) && !defined(__ARMCC_VERSION) - "SUB %0, #1\n\t" + "SUB %0, #1\n\t" #else - "SUBS %0, %0, #1\n\t" + "SUBS %0, %0, #1\n\t" #endif - "BCS %=b\n\t" - : "+l" (count) - : - : "cc" - ); + "BCS %=b\n\t" + : "+l"(count) + : + : "cc" + ); } #endif @@ -193,7 +196,7 @@ void flash_program_page_test() } // 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); + 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)); @@ -246,13 +249,15 @@ Case cases[] = { Case("Flash - clock and cache test", flash_clock_and_cache_test), }; -utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { +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() { +int main() +{ Harness::run(specification); } diff --git a/TESTS/mbed_hal/lp_ticker/main.cpp b/TESTS/mbed_hal/lp_ticker/main.cpp index 07304f2bb7f5..d7b18e1fb4bd 100644 --- a/TESTS/mbed_hal/lp_ticker/main.cpp +++ b/TESTS/mbed_hal/lp_ticker/main.cpp @@ -20,15 +20,18 @@ #include "rtos.h" #include "lp_ticker_api_tests.h" #include "hal/lp_ticker_api.h" +#include "hal/mbed_lp_ticker_wrapper.h" #if !DEVICE_LPTICKER - #error [NOT_SUPPORTED] Low power timer not supported for this target +#error [NOT_SUPPORTED] Low power timer not supported for this target #endif using namespace utest::v1; volatile int intFlag = 0; +ticker_irq_handler_type prev_handler; + #define US_PER_MS 1000 #define TICKER_GLITCH_TEST_TICKS 1000 @@ -74,7 +77,7 @@ void overflow_protect() time_window = LP_TICKER_OV_LIMIT; const uint32_t ticks_now = lp_ticker_read(); - const ticker_info_t* p_ticker_info = lp_ticker_get_info(); + const ticker_info_t *p_ticker_info = lp_ticker_get_info(); const uint32_t max_count = ((1 << p_ticker_info->bits) - 1); @@ -85,7 +88,7 @@ void overflow_protect() while (lp_ticker_read() > ticks_now); } -void ticker_event_handler_stub(const ticker_data_t * const ticker) +void ticker_event_handler_stub(const ticker_data_t *const ticker) { /* Indicate that ISR has been executed in interrupt context. */ if (core_util_is_isr_active()) { @@ -100,7 +103,7 @@ void ticker_event_handler_stub(const ticker_data_t * const ticker) /* Test that the ticker has the correct frequency and number of bits. */ void lp_ticker_info_test() { - const ticker_info_t* p_ticker_info = lp_ticker_get_info(); + const ticker_info_t *p_ticker_info = lp_ticker_get_info(); TEST_ASSERT(p_ticker_info->frequency >= 4000); TEST_ASSERT(p_ticker_info->frequency <= 64000); @@ -113,8 +116,6 @@ void lp_ticker_deepsleep_test() { intFlag = 0; - set_lp_ticker_irq_handler(ticker_event_handler_stub); - lp_ticker_init(); /* Give some time Green Tea to finish UART transmission before entering @@ -130,7 +131,7 @@ void lp_ticker_deepsleep_test() * tick_count + TICKER_INT_VAL. */ lp_ticker_set_interrupt(tick_count + TICKER_INT_VAL); - TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep()); + TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep_test_check()); while (!intFlag) { sleep(); @@ -157,6 +158,32 @@ void lp_ticker_glitch_test() } } +#if DEVICE_LPTICKER +utest::v1::status_t lp_ticker_deepsleep_test_setup_handler(const Case *const source, const size_t index_of_case) +{ + /* disable everything using the lp ticker for this test */ + osKernelSuspend(); + ticker_suspend(get_lp_ticker_data()); +#if DEVICE_LPTICKER && (LPTICKER_DELAY_TICKS > 0) + lp_ticker_wrapper_suspend(); +#endif + prev_handler = set_lp_ticker_irq_handler(ticker_event_handler_stub); + return greentea_case_setup_handler(source, index_of_case); +} + +utest::v1::status_t lp_ticker_deepsleep_test_teardown_handler(const Case *const source, const size_t passed, const size_t failed, + const failure_t reason) +{ + set_lp_ticker_irq_handler(prev_handler); +#if DEVICE_LPTICKER && (LPTICKER_DELAY_TICKS > 0) + lp_ticker_wrapper_resume(); +#endif + ticker_resume(get_lp_ticker_data()); + osKernelResume(0); + return greentea_case_teardown_handler(source, passed, failed, reason); +} +#endif + utest::v1::status_t test_setup(const size_t number_of_cases) { GREENTEA_SETUP(20, "default_auto"); @@ -166,7 +193,7 @@ utest::v1::status_t test_setup(const size_t number_of_cases) Case cases[] = { Case("lp ticker info test", lp_ticker_info_test), #if DEVICE_SLEEP - Case("lp ticker sleep test", lp_ticker_deepsleep_test), + Case("lp ticker sleep test", lp_ticker_deepsleep_test_setup_handler, lp_ticker_deepsleep_test, lp_ticker_deepsleep_test_teardown_handler), #endif Case("lp ticker glitch test", lp_ticker_glitch_test) }; diff --git a/TESTS/mbed_hal/rtc/main.cpp b/TESTS/mbed_hal/rtc/main.cpp index 0aab34531d1d..bd65e38cd4f5 100644 --- a/TESTS/mbed_hal/rtc/main.cpp +++ b/TESTS/mbed_hal/rtc/main.cpp @@ -15,7 +15,7 @@ */ #if !DEVICE_RTC - #error [NOT_SUPPORTED] RTC API not supported for this target +#error [NOT_SUPPORTED] RTC API not supported for this target #endif #include "utest/utest.h" @@ -37,7 +37,7 @@ static const uint32_t WAIT_TOLERANCE = 1; static const uint32_t DELAY_4S = 4; static const uint32_t DELAY_10S = 10; static const uint32_t RTC_TOLERANCE = 1; -static const uint32_t TOLERANCE_ACCURACY_US = (DELAY_10S * US_PER_SEC / ACCURACY_FACTOR); +static const uint32_t TOLERANCE_ACCURACY_US = (DELAY_10S *US_PER_SEC / ACCURACY_FACTOR); #if DEVICE_LPTICKER volatile bool expired; @@ -49,7 +49,7 @@ void callback(void) /* Auxiliary function to test if RTC continue counting in * sleep and deep-sleep modes. */ -void rtc_sleep_test_support (bool deepsleep_mode) +void rtc_sleep_test_support(bool deepsleep_mode) { LowPowerTimeout timeout; const uint32_t start = 100; @@ -66,7 +66,7 @@ void rtc_sleep_test_support (bool deepsleep_mode) rtc_init(); - if(deepsleep_mode == false) { + if (deepsleep_mode == false) { sleep_manager_lock_deep_sleep(); } @@ -74,9 +74,11 @@ void rtc_sleep_test_support (bool deepsleep_mode) timeout.attach(callback, DELAY_4S); - TEST_ASSERT(sleep_manager_can_deep_sleep() == deepsleep_mode); + TEST_ASSERT(sleep_manager_can_deep_sleep_test_check() == deepsleep_mode); - while(!expired) sleep(); + while (!expired) { + sleep(); + } const uint32_t stop = rtc_read(); @@ -84,7 +86,7 @@ void rtc_sleep_test_support (bool deepsleep_mode) timeout.detach(); - if(deepsleep_mode == false) { + if (deepsleep_mode == false) { sleep_manager_unlock_deep_sleep(); } @@ -155,10 +157,10 @@ void rtc_glitch_test() void rtc_range_test() { static const uint32_t starts[] = { - 0x00000000, - 0xEFFFFFFF, - 0x00001000, - 0x00010000, + 0x00000000, + 0xEFFFFFFF, + 0x00001000, + 0x00010000, }; rtc_init(); @@ -182,7 +184,7 @@ void rtc_accuracy_test() rtc_write(start); timer1.start(); - while(rtc_read() < (start + DELAY_10S)) { + while (rtc_read() < (start + DELAY_10S)) { /* Just wait. */ } timer1.stop(); diff --git a/TESTS/mbed_hal/rtc_reset/main.cpp b/TESTS/mbed_hal/rtc_reset/main.cpp index f07b194e9d62..de9fdf85c6a6 100644 --- a/TESTS/mbed_hal/rtc_reset/main.cpp +++ b/TESTS/mbed_hal/rtc_reset/main.cpp @@ -15,7 +15,7 @@ */ #if !DEVICE_RTC - #error [NOT_SUPPORTED] RTC API not supported for this target +#error [NOT_SUPPORTED] RTC API not supported for this target #endif #include "utest/utest.h" diff --git a/TESTS/mbed_hal/rtc_time/main.cpp b/TESTS/mbed_hal/rtc_time/main.cpp index c101e19b6253..fe0632967723 100644 --- a/TESTS/mbed_hal/rtc_time/main.cpp +++ b/TESTS/mbed_hal/rtc_time/main.cpp @@ -73,8 +73,7 @@ void test_is_leap_year() } /* Structure to test border values for _rtc_maketime(). */ -typedef struct -{ +typedef struct { struct tm timeinfo; time_t exp_seconds; // if result is false then exp_seconds is irrelevant bool result; @@ -85,7 +84,7 @@ typedef struct * Expected range: the 1st of January 1970 at 00:00:00 (seconds: 0) to the 7th of February 2106 at 06:28:15 (seconds: UINT_MAX). */ test_mk_time_struct test_mk_time_arr_full[] = { - {{ 0, 0, 0, 1, 0, 70, 0, 0, 0 }, (time_t) 0, true}, // valid lower bound - the 1st of January 1970 at 00:00:00 + {{ 0, 0, 0, 1, 0, 70, 0, 0, 0 }, (time_t) 0, true}, // valid lower bound - the 1st of January 1970 at 00:00:00 {{ 59, 59, 23, 31, 11, 59, 0, 0, 0 }, (time_t) 0, false }, // invalid lower bound - the 31st of December 1969 at 23:59:59 {{ 15, 28, 6, 7, 1, 206, 0, 0, 0 }, (time_t)(UINT_MAX), true }, // valid upper bound - the 7th of February 2106 at 06:28:15 @@ -98,7 +97,7 @@ test_mk_time_struct test_mk_time_arr_full[] = { * Expected range: the 1st of January 1970 at 00:00:00 (seconds: 0) to the 6th of February 2106 at 06:28:15 (seconds: UINT_MAX). */ test_mk_time_struct test_mk_time_arr_partial[] = { - {{ 0, 0, 0, 1, 0, 70, 0, 0, 0 }, (time_t) 0, true}, // valid lower bound - the 1st of January 1970 at 00:00:00 + {{ 0, 0, 0, 1, 0, 70, 0, 0, 0 }, (time_t) 0, true}, // valid lower bound - the 1st of January 1970 at 00:00:00 {{ 59, 59, 23, 31, 11, 59, 0, 0, 0 }, (time_t) 0, false }, // invalid lower bound - the 31st of December 1969 at 23:59:59 {{ 15, 28, 6, 6, 1, 206, 0, 0, 0 }, (time_t)(UINT_MAX), true }, // valid upper bound - the 6th of February 2106 at 06:28:15 @@ -152,10 +151,10 @@ void test_mk_time_invalid_param() time_t seconds; struct tm timeinfo; - TEST_ASSERT_EQUAL(false, _rtc_maketime(NULL, &seconds, RTC_FULL_LEAP_YEAR_SUPPORT )); - TEST_ASSERT_EQUAL(false, _rtc_maketime(NULL, &seconds, RTC_4_YEAR_LEAP_YEAR_SUPPORT )); - TEST_ASSERT_EQUAL(false, _rtc_maketime(&timeinfo, NULL, RTC_FULL_LEAP_YEAR_SUPPORT )); - TEST_ASSERT_EQUAL(false, _rtc_maketime(&timeinfo, NULL, RTC_4_YEAR_LEAP_YEAR_SUPPORT )); + TEST_ASSERT_EQUAL(false, _rtc_maketime(NULL, &seconds, RTC_FULL_LEAP_YEAR_SUPPORT)); + TEST_ASSERT_EQUAL(false, _rtc_maketime(NULL, &seconds, RTC_4_YEAR_LEAP_YEAR_SUPPORT)); + TEST_ASSERT_EQUAL(false, _rtc_maketime(&timeinfo, NULL, RTC_FULL_LEAP_YEAR_SUPPORT)); + TEST_ASSERT_EQUAL(false, _rtc_maketime(&timeinfo, NULL, RTC_4_YEAR_LEAP_YEAR_SUPPORT)); } /* Test _rtc_localtime() function - call with invalid parameters. @@ -166,24 +165,24 @@ void test_mk_time_invalid_param() */ void test_local_time_invalid_param() { - TEST_ASSERT_EQUAL(false, _rtc_localtime(1, NULL, RTC_FULL_LEAP_YEAR_SUPPORT )); - TEST_ASSERT_EQUAL(false, _rtc_localtime(1, NULL, RTC_4_YEAR_LEAP_YEAR_SUPPORT )); + TEST_ASSERT_EQUAL(false, _rtc_localtime(1, NULL, RTC_FULL_LEAP_YEAR_SUPPORT)); + TEST_ASSERT_EQUAL(false, _rtc_localtime(1, NULL, RTC_4_YEAR_LEAP_YEAR_SUPPORT)); } -utest::v1::status_t teardown_handler_t(const Case * const source, const size_t passed, const size_t failed, - const failure_t reason) +utest::v1::status_t teardown_handler_t(const Case *const source, const size_t passed, const size_t failed, + const failure_t reason) { return greentea_case_teardown_handler(source, passed, failed, reason); } -utest::v1::status_t full_leap_year_case_setup_handler_t(const Case * const source, const size_t index_of_case) +utest::v1::status_t full_leap_year_case_setup_handler_t(const Case *const source, const size_t index_of_case) { rtc_leap_year_support = RTC_FULL_LEAP_YEAR_SUPPORT; return greentea_case_setup_handler(source, index_of_case); } -utest::v1::status_t partial_leap_year_case_setup_handler_t(const Case * const source, const size_t index_of_case) +utest::v1::status_t partial_leap_year_case_setup_handler_t(const Case *const source, const size_t index_of_case) { rtc_leap_year_support = RTC_4_YEAR_LEAP_YEAR_SUPPORT; @@ -191,12 +190,12 @@ utest::v1::status_t partial_leap_year_case_setup_handler_t(const Case * const so } Case cases[] = { - Case("test is leap year - RTC leap years full support", full_leap_year_case_setup_handler_t, test_is_leap_year, teardown_handler_t), - Case("test is leap year - RTC leap years partial support", partial_leap_year_case_setup_handler_t, test_is_leap_year, teardown_handler_t), - Case("test make time boundary values - RTC leap years full support", full_leap_year_case_setup_handler_t, test_mk_time_boundary, teardown_handler_t), - Case("test make time boundary values - RTC leap years partial support", partial_leap_year_case_setup_handler_t, test_mk_time_boundary, teardown_handler_t), - Case("test make time - invalid param", test_mk_time_invalid_param, teardown_handler_t), - Case("test local time - invalid param", test_local_time_invalid_param, teardown_handler_t), + Case("test is leap year - RTC leap years full support", full_leap_year_case_setup_handler_t, test_is_leap_year, teardown_handler_t), + Case("test is leap year - RTC leap years partial support", partial_leap_year_case_setup_handler_t, test_is_leap_year, teardown_handler_t), + Case("test make time boundary values - RTC leap years full support", full_leap_year_case_setup_handler_t, test_mk_time_boundary, teardown_handler_t), + Case("test make time boundary values - RTC leap years partial support", partial_leap_year_case_setup_handler_t, test_mk_time_boundary, teardown_handler_t), + Case("test make time - invalid param", test_mk_time_invalid_param, teardown_handler_t), + Case("test local time - invalid param", test_local_time_invalid_param, teardown_handler_t), }; utest::v1::status_t greentea_test_setup(const size_t number_of_cases) diff --git a/TESTS/mbed_hal/rtc_time_conv/main.cpp b/TESTS/mbed_hal/rtc_time_conv/main.cpp index a33b363492d1..0a716542403c 100644 --- a/TESTS/mbed_hal/rtc_time_conv/main.cpp +++ b/TESTS/mbed_hal/rtc_time_conv/main.cpp @@ -51,8 +51,8 @@ bool is_leap_year(int year) struct tm make_time_info(int year, int month, int day, int hours, int minutes, int seconds) { - struct tm timeinfo = - { seconds, // tm_sec + struct tm timeinfo = { + seconds, // tm_sec minutes, // tm_min hours, // tm_hour day, // tm_mday @@ -61,7 +61,7 @@ struct tm make_time_info(int year, int month, int day, int hours, int minutes, i 0, // tm_wday 0, // tm_yday 0, // tm_isdst - }; + }; return timeinfo; } @@ -79,9 +79,9 @@ struct tm make_time_info(int year, int month, int day, int hours, int minutes, i void test_case_mktime_localtime() { char _key[11] = - { }; + { }; char _value[128] = - { }; + { }; size_t years[] = {70, 71, 100, 196, 200, 205}; @@ -89,7 +89,7 @@ void test_case_mktime_localtime() greentea_send_kv("leap_year_setup", rtc_leap_year_support); /* Check the first and last last day of each month. */ - for (size_t year_id = 0; year_id < (sizeof(years) /sizeof(size_t)) ; ++year_id) { + for (size_t year_id = 0; year_id < (sizeof(years) / sizeof(size_t)) ; ++year_id) { for (size_t month = 0; month < 12; ++month) { for (size_t dayid = 0; dayid < 2; ++dayid) { @@ -100,8 +100,7 @@ void test_case_mktime_localtime() * day 0 - first, * day 1 - last * */ - switch (dayid) - { + switch (dayid) { case 0: day = 1; break; @@ -122,7 +121,7 @@ void test_case_mktime_localtime() } /* Additional conditions for RTCs with partial leap year support. */ - if(month == 1 && year == 200 && rtc_leap_year_support == RTC_4_YEAR_LEAP_YEAR_SUPPORT) { + if (month == 1 && year == 200 && rtc_leap_year_support == RTC_4_YEAR_LEAP_YEAR_SUPPORT) { day = 29; } @@ -172,30 +171,30 @@ void test_case_mktime_localtime() } } -utest::v1::status_t full_leap_year_case_setup_handler_t(const Case * const source, const size_t index_of_case) +utest::v1::status_t full_leap_year_case_setup_handler_t(const Case *const source, const size_t index_of_case) { rtc_leap_year_support = RTC_FULL_LEAP_YEAR_SUPPORT; return greentea_case_setup_handler(source, index_of_case); } -utest::v1::status_t partial_leap_year_case_setup_handler_t(const Case * const source, const size_t index_of_case) +utest::v1::status_t partial_leap_year_case_setup_handler_t(const Case *const source, const size_t index_of_case) { rtc_leap_year_support = RTC_4_YEAR_LEAP_YEAR_SUPPORT; return greentea_case_setup_handler(source, index_of_case); } -utest::v1::status_t teardown_handler_t(const Case * const source, const size_t passed, const size_t failed, - const failure_t reason) +utest::v1::status_t teardown_handler_t(const Case *const source, const size_t passed, const size_t failed, + const failure_t reason) { return greentea_case_teardown_handler(source, passed, failed, reason); } // Test cases -Case cases[] ={ - Case("test make time and local time - RTC leap years full support", full_leap_year_case_setup_handler_t, test_case_mktime_localtime, teardown_handler_t), - Case("test make time and local time - RTC leap years partial support", partial_leap_year_case_setup_handler_t, test_case_mktime_localtime, teardown_handler_t), +Case cases[] = { + Case("test make time and local time - RTC leap years full support", full_leap_year_case_setup_handler_t, test_case_mktime_localtime, teardown_handler_t), + Case("test make time and local time - RTC leap years partial support", partial_leap_year_case_setup_handler_t, test_case_mktime_localtime, teardown_handler_t), }; utest::v1::status_t greentea_test_setup(const size_t number_of_cases) diff --git a/TESTS/mbed_hal/sleep/main.cpp b/TESTS/mbed_hal/sleep/main.cpp index 23e5839f26c3..46beb039b24d 100644 --- a/TESTS/mbed_hal/sleep/main.cpp +++ b/TESTS/mbed_hal/sleep/main.cpp @@ -23,6 +23,7 @@ #include "utest/utest.h" #include "unity/unity.h" #include "greentea-client/test_env.h" +#include "mbed_lp_ticker_wrapper.h" #include "sleep_api_tests.h" @@ -40,7 +41,7 @@ * * This should be replaced with a better function that checks if the * hardware buffers are empty. However, such an API does not exist now, - * so we'll use the wait_ms() function for now. + * so we'll use the busy_wait_ms() function for now. */ #define SERIAL_FLUSH_TIME_MS 20 @@ -66,12 +67,12 @@ static const uint32_t deepsleep_mode_delta_us = (10000 + 125 + 5); unsigned int ticks_to_us(unsigned int ticks, unsigned int freq) { - return (unsigned int) ((unsigned long long) ticks * US_PER_S / freq); + return (unsigned int)((unsigned long long) ticks * US_PER_S / freq); } unsigned int us_to_ticks(unsigned int us, unsigned int freq) { - return (unsigned int) ((unsigned long long) us * freq / US_PER_S); + return (unsigned int)((unsigned long long) us * freq / US_PER_S); } unsigned int overflow_protect(unsigned int timestamp, unsigned int ticker_width) @@ -103,7 +104,21 @@ bool compare_timestamps(unsigned int delta_ticks, unsigned int ticker_width, uns } } -void us_ticker_isr(const ticker_data_t * const ticker_data) +void busy_wait_ms(int ms) +{ + const ticker_info_t *info = us_ticker_get_info(); + uint32_t mask = (1 << info->bits) - 1; + int delay = (int)((uint64_t)ms * info->frequency / 1000); + + uint32_t prev = us_ticker_read(); + while (delay > 0) { + uint32_t next = us_ticker_read(); + delay -= (next - prev) & mask; + prev = next; + } +} + +void us_ticker_isr(const ticker_data_t *const ticker_data) { us_ticker_clear_interrupt(); } @@ -119,23 +134,12 @@ void lp_ticker_isr(const ticker_data_t *const ticker_data) * high frequency ticker interrupt can wake-up target from sleep. */ void sleep_usticker_test() { - const ticker_data_t * ticker = get_us_ticker_data(); + const ticker_data_t *ticker = get_us_ticker_data(); const unsigned int ticker_freq = ticker->interface->get_info()->frequency; const unsigned int ticker_width = ticker->interface->get_info()->bits; const ticker_irq_handler_type us_ticker_irq_handler_org = set_us_ticker_irq_handler(us_ticker_isr); - // call ticker_read_us to initialize ticker upper layer - // prevents subsequent scheduling of max_delta interrupt during ticker initialization while test execution - // (e.g when ticker_read_us is called) - ticker_read_us(ticker); -#ifdef DEVICE_LPTICKER - // call ticker_read_us to initialize lp_ticker - // prevents scheduling interrupt during ticker initialization (in lp_ticker_init) while test execution - // (e.g when ticker_read_us is called for lp_ticker, see MBED_CPU_STATS_ENABLED) - ticker_read_us(get_lp_ticker_data()); -#endif - /* Test only sleep functionality. */ sleep_manager_lock_deep_sleep(); TEST_ASSERT_FALSE_MESSAGE(sleep_manager_can_deep_sleep(), "deep sleep should be locked"); @@ -144,7 +148,7 @@ void sleep_usticker_test() for (timestamp_t i = 100; i < 1000; i += 100) { /* note: us_ticker_read() operates on ticks. */ const timestamp_t next_match_timestamp = overflow_protect(us_ticker_read() + us_to_ticks(i, ticker_freq), - ticker_width); + ticker_width); us_ticker_set_interrupt(next_match_timestamp); @@ -153,8 +157,8 @@ void sleep_usticker_test() const unsigned int wakeup_timestamp = us_ticker_read(); TEST_ASSERT( - compare_timestamps(us_to_ticks(sleep_mode_delta_us, ticker_freq), ticker_width, next_match_timestamp, - wakeup_timestamp)); + compare_timestamps(us_to_ticks(sleep_mode_delta_us, ticker_freq), ticker_width, next_match_timestamp, + wakeup_timestamp)); } set_us_ticker_irq_handler(us_ticker_irq_handler_org); @@ -169,21 +173,16 @@ void sleep_usticker_test() * low power ticker interrupt can wake-up target from sleep. */ void deepsleep_lpticker_test() { - const ticker_data_t * ticker = get_lp_ticker_data(); + const ticker_data_t *ticker = get_lp_ticker_data(); const unsigned int ticker_freq = ticker->interface->get_info()->frequency; const unsigned int ticker_width = ticker->interface->get_info()->bits; - // call ticker_read_us to initialize ticker upper layer - // prevents subsequent scheduling of max_delta interrupt during ticker initialization while test execution - // (e.g when ticker_read_us is called) - ticker_read_us(ticker); - const ticker_irq_handler_type lp_ticker_irq_handler_org = set_lp_ticker_irq_handler(lp_ticker_isr); /* Give some time Green Tea to finish UART transmission before entering * deep-sleep mode. */ - wait_ms(SERIAL_FLUSH_TIME_MS); + busy_wait_ms(SERIAL_FLUSH_TIME_MS); TEST_ASSERT_TRUE_MESSAGE(sleep_manager_can_deep_sleep(), "deep sleep should not be locked"); @@ -207,8 +206,8 @@ void deepsleep_lpticker_test() void deepsleep_high_speed_clocks_turned_off_test() { - const ticker_data_t * us_ticker = get_us_ticker_data(); - const ticker_data_t * lp_ticker = get_lp_ticker_data(); + const ticker_data_t *us_ticker = get_us_ticker_data(); + const ticker_data_t *lp_ticker = get_lp_ticker_data(); const unsigned int us_ticker_freq = us_ticker->interface->get_info()->frequency; const unsigned int lp_ticker_freq = lp_ticker->interface->get_info()->frequency; const unsigned int us_ticker_width = us_ticker->interface->get_info()->bits; @@ -218,7 +217,7 @@ void deepsleep_high_speed_clocks_turned_off_test() /* Give some time Green Tea to finish UART transmission before entering * deep-sleep mode. */ - wait_ms(SERIAL_FLUSH_TIME_MS); + busy_wait_ms(SERIAL_FLUSH_TIME_MS); TEST_ASSERT_TRUE_MESSAGE(sleep_manager_can_deep_sleep(), "deep sleep should not be locked"); @@ -247,7 +246,7 @@ void deepsleep_high_speed_clocks_turned_off_test() #endif -utest::v1::status_t greentea_failure_handler(const Case * const source, const failure_t reason) +utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) { greentea_case_failure_abort_handler(source, reason); return STATUS_CONTINUE; @@ -256,24 +255,47 @@ utest::v1::status_t greentea_failure_handler(const Case * const source, const fa utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { GREENTEA_SETUP(60, "default_auto"); + /* Suspend RTOS Kernel to enable sleep modes. */ + osKernelSuspend(); +#if DEVICE_LPTICKER + ticker_suspend(get_lp_ticker_data()); +#if DEVICE_LPTICKER && (LPTICKER_DELAY_TICKS > 0) + lp_ticker_wrapper_suspend(); +#endif +#endif + ticker_suspend(get_us_ticker_data()); + us_ticker_init(); #if DEVICE_LPTICKER lp_ticker_init(); #endif - /* Suspend RTOS Kernel to enable sleep modes. */ - osKernelSuspend(); + return greentea_test_setup_handler(number_of_cases); } -Case cases[] = - { Case("sleep - source of wake-up - us ticker", sleep_usticker_test, greentea_failure_handler), +void greentea_test_teardown(const size_t passed, const size_t failed, const failure_t failure) +{ + ticker_resume(get_us_ticker_data()); +#if DEVICE_LPTICKER +#if DEVICE_LPTICKER && (LPTICKER_DELAY_TICKS > 0) + lp_ticker_wrapper_resume(); +#endif + ticker_resume(get_lp_ticker_data()); +#endif + osKernelResume(0); + + greentea_test_teardown_handler(passed, failed, failure); +} + +Case cases[] = { + Case("sleep - source of wake-up - us ticker", sleep_usticker_test, greentea_failure_handler), #if DEVICE_LPTICKER - Case("deep-sleep - source of wake-up - lp ticker",deepsleep_lpticker_test, greentea_failure_handler), - Case("deep-sleep - high-speed clocks are turned off",deepsleep_high_speed_clocks_turned_off_test, greentea_failure_handler), + Case("deep-sleep - source of wake-up - lp ticker", deepsleep_lpticker_test, greentea_failure_handler), + Case("deep-sleep - high-speed clocks are turned off", deepsleep_high_speed_clocks_turned_off_test, greentea_failure_handler), #endif - }; +}; -Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); +Specification specification(greentea_test_setup, cases, greentea_test_teardown); int main() { diff --git a/TESTS/mbed_hal/sleep_manager/main.cpp b/TESTS/mbed_hal/sleep_manager/main.cpp index 07353f17d782..3d3e392b50c7 100644 --- a/TESTS/mbed_hal/sleep_manager/main.cpp +++ b/TESTS/mbed_hal/sleep_manager/main.cpp @@ -25,25 +25,25 @@ using namespace utest::v1; void sleep_manager_deepsleep_counter_test() { - bool deep_sleep_allowed = sleep_manager_can_deep_sleep(); + bool deep_sleep_allowed = sleep_manager_can_deep_sleep_test_check(); TEST_ASSERT_TRUE(deep_sleep_allowed); - + sleep_manager_lock_deep_sleep(); - deep_sleep_allowed = sleep_manager_can_deep_sleep(); + deep_sleep_allowed = sleep_manager_can_deep_sleep_test_check(); TEST_ASSERT_FALSE(deep_sleep_allowed); sleep_manager_unlock_deep_sleep(); - deep_sleep_allowed = sleep_manager_can_deep_sleep(); + deep_sleep_allowed = sleep_manager_can_deep_sleep_test_check(); TEST_ASSERT_TRUE(deep_sleep_allowed); } -utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) +utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) { greentea_case_failure_abort_handler(source, reason); return STATUS_CONTINUE; } -utest::v1::status_t greentea_test_setup(const size_t number_of_cases) +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); @@ -55,6 +55,7 @@ Case cases[] = { Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); -int main() { +int main() +{ Harness::run(specification); } diff --git a/TESTS/mbed_hal/sleep_manager_racecondition/main.cpp b/TESTS/mbed_hal/sleep_manager_racecondition/main.cpp index ee4158fa1318..d43492c05258 100644 --- a/TESTS/mbed_hal/sleep_manager_racecondition/main.cpp +++ b/TESTS/mbed_hal/sleep_manager_racecondition/main.cpp @@ -23,7 +23,7 @@ #endif #if !DEVICE_USTICKER - #error [NOT_SUPPORTED] test not supported +#error [NOT_SUPPORTED] test not supported #endif using namespace utest::v1; @@ -55,7 +55,7 @@ void sleep_manager_multithread_test() t2.join(); } - bool deep_sleep_allowed = sleep_manager_can_deep_sleep(); + bool deep_sleep_allowed = sleep_manager_can_deep_sleep_test_check(); TEST_ASSERT_TRUE_MESSAGE(deep_sleep_allowed, "Deep sleep should be allowed"); } @@ -83,11 +83,11 @@ void sleep_manager_irq_test() timer.stop(); } - bool deep_sleep_allowed = sleep_manager_can_deep_sleep(); + bool deep_sleep_allowed = sleep_manager_can_deep_sleep_test_check(); TEST_ASSERT_TRUE_MESSAGE(deep_sleep_allowed, "Deep sleep should be allowed"); } -utest::v1::status_t greentea_test_setup(const size_t number_of_cases) +utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { GREENTEA_SETUP(30, "default_auto"); return greentea_test_setup_handler(number_of_cases); @@ -100,6 +100,7 @@ Case cases[] = { Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); -int main() { +int main() +{ Harness::run(specification); } diff --git a/TESTS/mbed_hal/ticker/main.cpp b/TESTS/mbed_hal/ticker/main.cpp index c81b8e368aff..754728cc27f4 100644 --- a/TESTS/mbed_hal/ticker/main.cpp +++ b/TESTS/mbed_hal/ticker/main.cpp @@ -32,12 +32,12 @@ using namespace utest::v1; #define TIMESTAMP_MAX_DELTA_BITS(bits) ((uint64_t)(0x7 << ((bits) - 4))) #define TIMESTAMP_MAX_DELTA TIMESTAMP_MAX_DELTA_BITS(32) -struct ticker_interface_stub_t { +struct ticker_interface_stub_t { ticker_interface_t interface; - bool initialized; + bool initialized; bool interrupt_flag; timestamp_t timestamp ; - timestamp_t interrupt_timestamp; + timestamp_t interrupt_timestamp; unsigned int init_call; unsigned int read_call; unsigned int disable_interrupt_call; @@ -60,10 +60,10 @@ static uint32_t ticker_interface_stub_read() { ++interface_stub.read_call; return interface_stub.timestamp; -} +} static void ticker_interface_stub_disable_interrupt() -{ +{ ++interface_stub.disable_interrupt_call; } @@ -76,7 +76,7 @@ static void ticker_interface_stub_clear_interrupt() static void ticker_interface_stub_set_interrupt(timestamp_t timestamp) { ++interface_stub.set_interrupt_call; - interface_stub.interrupt_timestamp = timestamp; + interface_stub.interrupt_timestamp = timestamp; } static void ticker_interface_stub_fire_interrupt() @@ -94,11 +94,11 @@ static void reset_ticker_interface_stub() { interface_stub.interface.init = ticker_interface_stub_init; interface_stub.interface.read = ticker_interface_stub_read; - interface_stub.interface.disable_interrupt = + interface_stub.interface.disable_interrupt = ticker_interface_stub_disable_interrupt; - interface_stub.interface.clear_interrupt = + interface_stub.interface.clear_interrupt = ticker_interface_stub_clear_interrupt; - interface_stub.interface.set_interrupt =ticker_interface_stub_set_interrupt; + interface_stub.interface.set_interrupt = ticker_interface_stub_set_interrupt; interface_stub.interface.fire_interrupt = ticker_interface_stub_fire_interrupt; interface_stub.interface.get_info = ticker_interface_stub_get_info; interface_stub.initialized = false; @@ -116,7 +116,7 @@ static void reset_ticker_interface_stub() interface_info_stub.bits = 32; } -// stub of the event queue +// stub of the event queue static ticker_event_queue_t queue_stub = { /* event handler */ NULL, /* head */ NULL, @@ -180,7 +180,8 @@ static void test_over_frequency_and_width(void) static utest::v1::status_t case_setup_handler( const Case *const source, const size_t index_of_case -) { +) +{ utest::v1::status_t status = greentea_case_setup_handler(source, index_of_case); reset_ticker_stub(); return status; @@ -188,20 +189,22 @@ static utest::v1::status_t case_setup_handler( static utest::v1::status_t case_teardown_handler( const Case *const source, const size_t passed, const size_t failed, const failure_t reason -) { +) +{ reset_ticker_stub(); utest::v1::status_t status = greentea_case_teardown_handler( - source, passed, failed, reason - ); + source, passed, failed, reason + ); return status; } static utest::v1::status_t greentea_failure_handler( const Case *const source, const failure_t reason -) { +) +{ utest::v1::status_t status = greentea_case_failure_abort_handler( - source, reason - ); + source, reason + ); return status; } @@ -217,13 +220,13 @@ static utest::v1::status_t greentea_failure_handler( } /** - * Given an unitialized ticker_data instance. - * When the ticker is initialized - * Then: - * - The ticker interface should be initialized + * Given an unitialized ticker_data instance. + * When the ticker is initialized + * Then: + * - The ticker interface should be initialized * - The queue handler should be set to the handler provided in parameter * - The internal ticker timestamp should be zero - * - interrupt should be scheduled in current timestamp + + * - interrupt should be scheduled in current timestamp + * TIMESTAMP_MAX_DELTA * - The queue should not contains any event */ @@ -231,7 +234,7 @@ static void test_ticker_initialization() { ticker_event_handler dummy_handler = (ticker_event_handler)0xDEADBEEF; - // setup of the stub + // setup of the stub interface_stub.timestamp = 0xFEEDBABE; ticker_set_handler(&ticker_stub, dummy_handler); @@ -249,9 +252,9 @@ static void test_ticker_initialization() } /** - * Given an initialized ticker_data instance. - * When the ticker handler is set to a new value - * Then: + * Given an initialized ticker_data instance. + * When the ticker handler is set to a new value + * Then: * - The ticker interface initialization function should not be called. * - The queue handler should be set to the new handler. * - The events in the queue should remains the same. @@ -260,10 +263,10 @@ static void test_ticker_re_initialization() { ticker_event_handler dummy_handler = (ticker_event_handler) 0xDEADBEEF; ticker_event_handler expected_handler = (ticker_event_handler) 0xFEEDDEAF; - - ticker_event_t first_event = { 0 }; - ticker_event_t second_event = { 0 }; - ticker_event_t third_event = { 0 }; + + ticker_event_t first_event = { 0 }; + ticker_event_t second_event = { 0 }; + ticker_event_t third_event = { 0 }; first_event.next = &second_event; second_event.next = &third_event; @@ -287,15 +290,15 @@ static void test_ticker_re_initialization() } /** - * Given an initialized ticker_data instance. - * When the ticker is read + * Given an initialized ticker_data instance. + * When the ticker is read * Then it should return the value present in the ticker interface */ static void test_ticker_read() { ticker_set_handler(&ticker_stub, NULL); - timestamp_t timestamps[] = { + timestamp_t timestamps[] = { 0xA, 0xAA, 0xAAA, @@ -316,19 +319,19 @@ static void test_ticker_read() } /** - * Given an initialized ticker_data instance. - * When the ticker is read and the value read is less than the previous + * Given an initialized ticker_data instance. + * When the ticker is read and the value read is less than the previous * value read. * Then: - * - ticker_read should return the value read in the ticker interface - * - ticker_read_us should return a value where: + * - ticker_read should return the value read in the ticker interface + * - ticker_read_us should return a value where: * + lower 8 bytes should be equal to the value in the ticker interface * + upper 8 bytes should be equal to the previous value of upper 8 bytes * plus one. */ static void test_ticker_read_overflow() { - const timestamp_t timestamps[] = { + const timestamp_t timestamps[] = { 0xAAAAAAAA, 0xAAAAAAA, 0xAAAAAA, @@ -356,15 +359,15 @@ static void test_ticker_read_overflow() } /** - * Given an initialized ticker without user registered events. - * When an event is inserted with ticker_insert_event and the timestamp passed - * in parameter is in range [ticker_timestamp : ticker_timestamp + + * Given an initialized ticker without user registered events. + * When an event is inserted with ticker_insert_event and the timestamp passed + * in parameter is in range [ticker_timestamp : ticker_timestamp + * TIMESTAMP_MAX_DELTA[. - * Then + * Then * - The event should be in the queue - * - The interrupt timestamp should be equal to the timestamp of the event - * - The timestamp of the event should reflect the timestamp requested. - * - The id of the event should be equal to the id passed in parameter. + * - The interrupt timestamp should be equal to the timestamp of the event + * - The timestamp of the event should reflect the timestamp requested. + * - The id of the event should be equal to the id passed in parameter. */ static void test_legacy_insert_event_outside_overflow_range() { @@ -373,17 +376,17 @@ static void test_legacy_insert_event_outside_overflow_range() // test the end of the range ticker_event_t last_event = { 0 }; - const timestamp_t timestamp_last_event = - interface_stub.timestamp + TIMESTAMP_MAX_DELTA; + const timestamp_t timestamp_last_event = + interface_stub.timestamp + TIMESTAMP_MAX_DELTA; const uint32_t id_last_event = 0xDEADDEAF; ticker_insert_event( - &ticker_stub, + &ticker_stub, &last_event, timestamp_last_event, id_last_event ); TEST_ASSERT_EQUAL_PTR(&last_event, queue_stub.head); - TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call); + TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call); TEST_ASSERT_EQUAL_UINT32( timestamp_last_event, interface_stub.interrupt_timestamp ); @@ -397,12 +400,12 @@ static void test_legacy_insert_event_outside_overflow_range() const uint32_t id_first_event = 0xAAAAAAAA; ticker_insert_event( - &ticker_stub, + &ticker_stub, &first_event, timestamp_first_event, id_first_event ); TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head); - TEST_ASSERT_EQUAL(2, interface_stub.set_interrupt_call); + TEST_ASSERT_EQUAL(2, interface_stub.set_interrupt_call); TEST_ASSERT_EQUAL_UINT32( timestamp_first_event, interface_stub.interrupt_timestamp ); @@ -413,19 +416,19 @@ static void test_legacy_insert_event_outside_overflow_range() TEST_ASSERT_EQUAL_UINT32(id_first_event, first_event.id); TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); -} +} /** - * Given an initialized ticker without user registered events. - * When an event is inserted with ticker_insert_event and a timestamp in the - * range [ticker_timestamp + TIMESTAMP_MAX_DELTA + 1 : + * Given an initialized ticker without user registered events. + * When an event is inserted with ticker_insert_event and a timestamp in the + * range [ticker_timestamp + TIMESTAMP_MAX_DELTA + 1 : * ticker_timestamp + UINT32MAX [ - * Then + * Then * - The event should be in the queue - * - The interrupt timestamp should be equal to - * TIMESTAMP_MAX_DELTA - * - The timestamp of the event should reflect the timestamp requested. - * - The id of the event should be equal to the id passed in parameter. + * - The interrupt timestamp should be equal to + * TIMESTAMP_MAX_DELTA + * - The timestamp of the event should reflect the timestamp requested. + * - The id of the event should be equal to the id passed in parameter. */ static void test_legacy_insert_event_in_overflow_range() { @@ -434,19 +437,19 @@ static void test_legacy_insert_event_in_overflow_range() // test the end of the range ticker_event_t last_event = { 0 }; - const timestamp_t timestamp_last_event = - interface_stub.timestamp + UINT32_MAX; + const timestamp_t timestamp_last_event = + interface_stub.timestamp + UINT32_MAX; const uint32_t id_last_event = 0xDEADDEAF; ticker_insert_event( - &ticker_stub, + &ticker_stub, &last_event, timestamp_last_event, id_last_event ); TEST_ASSERT_EQUAL_PTR(&last_event, queue_stub.head); - TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call); + TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call); TEST_ASSERT_EQUAL_UINT32( - interface_stub.timestamp + TIMESTAMP_MAX_DELTA, + interface_stub.timestamp + TIMESTAMP_MAX_DELTA, interface_stub.interrupt_timestamp ); TEST_ASSERT_EQUAL_PTR(NULL, queue_stub.head->next); @@ -457,19 +460,19 @@ static void test_legacy_insert_event_in_overflow_range() ++interface_stub.timestamp; ticker_event_t first_event = { 0 }; - const timestamp_t timestamp_first_event = - interface_stub.timestamp + TIMESTAMP_MAX_DELTA + 1; + const timestamp_t timestamp_first_event = + interface_stub.timestamp + TIMESTAMP_MAX_DELTA + 1; const uint32_t id_first_event = 0xAAAAAAAA; ticker_insert_event( - &ticker_stub, + &ticker_stub, &first_event, timestamp_first_event, id_first_event ); TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head); - TEST_ASSERT_EQUAL(2, interface_stub.set_interrupt_call); + TEST_ASSERT_EQUAL(2, interface_stub.set_interrupt_call); TEST_ASSERT_EQUAL_UINT32( - interface_stub.timestamp + TIMESTAMP_MAX_DELTA, + interface_stub.timestamp + TIMESTAMP_MAX_DELTA, interface_stub.interrupt_timestamp ); TEST_ASSERT_EQUAL_PTR(&last_event, queue_stub.head->next); @@ -479,21 +482,22 @@ static void test_legacy_insert_event_in_overflow_range() TEST_ASSERT_EQUAL_UINT32(id_first_event, first_event.id); TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); -} +} /** - * Given an initialized ticker without user registered events. - * When an event is inserted with ticker_insert_event and the timestamp in + * Given an initialized ticker without user registered events. + * When an event is inserted with ticker_insert_event and the timestamp in * parameter is less than the current timestamp value. - * Then + * Then * - The event should be in the queue * - The timestamp of the event should reflect the timestamp requested: - * + lower 8 bytes should be equal to the timestamp in input. + * + lower 8 bytes should be equal to the timestamp in input. * + upper 8 bytes should be equal to the upper of the upper 8 bytes of the * timestamp state stored in the queue plus one. - * - The id of the event should be equal to the id passed in parameter. + * - The id of the event should be equal to the id passed in parameter. */ -static void test_legacy_insert_event_overflow(){ +static void test_legacy_insert_event_overflow() +{ ticker_set_handler(&ticker_stub, NULL); interface_stub.set_interrupt_call = 0; @@ -501,23 +505,23 @@ static void test_legacy_insert_event_overflow(){ ticker_read(&ticker_stub); ticker_event_t event = { 0 }; - const timestamp_t expected_timestamp = - interface_stub.timestamp + - TIMESTAMP_MAX_DELTA + - 1; - const us_timestamp_t expected_us_timestamp = + const timestamp_t expected_timestamp = + interface_stub.timestamp + + TIMESTAMP_MAX_DELTA + + 1; + const us_timestamp_t expected_us_timestamp = (((queue_stub.present_time >> 32) + 1) << 32) | expected_timestamp; const uint32_t expected_id = 0xDEADDEAF; ticker_insert_event( - &ticker_stub, + &ticker_stub, &event, expected_timestamp, expected_id ); TEST_ASSERT_EQUAL_PTR(&event, queue_stub.head); - TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call); + TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call); TEST_ASSERT_EQUAL_UINT32( - interface_stub.timestamp + TIMESTAMP_MAX_DELTA, + interface_stub.timestamp + TIMESTAMP_MAX_DELTA, interface_stub.interrupt_timestamp ); TEST_ASSERT_EQUAL_PTR(NULL, queue_stub.head->next); @@ -525,18 +529,18 @@ static void test_legacy_insert_event_overflow(){ TEST_ASSERT_EQUAL_UINT32(expected_id, event.id); TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); -} +} /** * Given an initialized ticker. - * When an event is inserted with ticker_insert_event and a timestamp less than + * When an event is inserted with ticker_insert_event and a timestamp less than * the one for the next scheduled timestamp. - * Then + * Then * - The event inserted should be the first in the queue - * - The interrupt timestamp should be equal to the timestamp of the event or + * - The interrupt timestamp should be equal to the timestamp of the event or * TIMESTAMP_MAX_DELTA if in the overflow range. * - The timestamp of the event should reflect the timestamp requested. - * - The id of the event should be equal to the id passed in parameter. + * - The id of the event should be equal to the id passed in parameter. * - Events in the queue should remained ordered by timestamp. */ static void test_legacy_insert_event_head() @@ -544,7 +548,7 @@ static void test_legacy_insert_event_head() ticker_set_handler(&ticker_stub, NULL); interface_stub.set_interrupt_call = 0; - const timestamp_t timestamps[] = { + const timestamp_t timestamps[] = { UINT32_MAX, TIMESTAMP_MAX_DELTA + 1, TIMESTAMP_MAX_DELTA, @@ -555,22 +559,22 @@ static void test_legacy_insert_event_head() }; ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 }; - for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { + for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { ticker_insert_event( - &ticker_stub, + &ticker_stub, &events[i], timestamps[i], i ); TEST_ASSERT_EQUAL_PTR(&events[i], queue_stub.head); - TEST_ASSERT_EQUAL(i + 1, interface_stub.set_interrupt_call); - if (timestamps[i] < TIMESTAMP_MAX_DELTA) { + TEST_ASSERT_EQUAL(i + 1, interface_stub.set_interrupt_call); + if (timestamps[i] < TIMESTAMP_MAX_DELTA) { TEST_ASSERT_EQUAL_UINT32( - timestamps[i], + timestamps[i], interface_stub.interrupt_timestamp ); - } else { + } else { TEST_ASSERT_EQUAL_UINT32( - TIMESTAMP_MAX_DELTA, + TIMESTAMP_MAX_DELTA, interface_stub.interrupt_timestamp ); } @@ -580,13 +584,13 @@ static void test_legacy_insert_event_head() ); TEST_ASSERT_EQUAL_UINT32(i, events[i].id); - ticker_event_t* e = &events[i]; - while (e) { + ticker_event_t *e = &events[i]; + while (e) { TEST_ASSERT_EQUAL_UINT32(timestamps[e->id], e->timestamp); - if (e->next) { + if (e->next) { TEST_ASSERT_TRUE(e->id > e->next->id); TEST_ASSERT_TRUE(e->timestamp < e->next->timestamp); - } else { + } else { TEST_ASSERT_EQUAL_UINT32(0, e->id); } e = e->next; @@ -594,18 +598,18 @@ static void test_legacy_insert_event_head() } TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); -} +} -/** +/** * Given an initialized ticker. - * When an event is inserted with ticker_insert_event and its timestamp is bigger + * When an event is inserted with ticker_insert_event and its timestamp is bigger * than the one of the last event in the queue. - * Then + * Then * - The event inserted should be the last in the queue - * - The interrupt timestamp should remains equal to the interrupt timestamp + * - The interrupt timestamp should remains equal to the interrupt timestamp * of the head event . * - The timestamp of the event should reflect the timestamp requested. - * - The id of the event should be equal to the id passed in parameter. + * - The id of the event should be equal to the id passed in parameter. * - Events in the queue should remained ordered by timestamp. */ static void test_legacy_insert_event_tail() @@ -613,7 +617,7 @@ static void test_legacy_insert_event_tail() ticker_set_handler(&ticker_stub, NULL); interface_stub.set_interrupt_call = 0; - const timestamp_t timestamps[] = { + const timestamp_t timestamps[] = { 0xA, 0xAA, 0xAAA, @@ -625,9 +629,9 @@ static void test_legacy_insert_event_tail() }; ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 }; - for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { + for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { ticker_insert_event( - &ticker_stub, + &ticker_stub, &events[i], timestamps[i], i ); @@ -639,13 +643,13 @@ static void test_legacy_insert_event_tail() TEST_ASSERT_EQUAL_UINT32(timestamps[i], events[i].timestamp); TEST_ASSERT_EQUAL_UINT32(i, events[i].id); - ticker_event_t* e = queue_stub.head; - while (e) { + ticker_event_t *e = queue_stub.head; + while (e) { TEST_ASSERT_EQUAL_UINT32(timestamps[e->id], e->timestamp); - if (e->next) { + if (e->next) { TEST_ASSERT_TRUE(e->id < e->next->id); TEST_ASSERT_TRUE(e->timestamp < e->next->timestamp); - } else { + } else { TEST_ASSERT_EQUAL_UINT32(&events[i], e); } e = e->next; @@ -653,19 +657,19 @@ static void test_legacy_insert_event_tail() } TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); -} +} /** * Given an initialized ticker. - * When an event is inserted with ticker_insert_event and a timestamp less - * than the current timestamp in the interface and less than the relative + * When an event is inserted with ticker_insert_event and a timestamp less + * than the current timestamp in the interface and less than the relative * timestamp of the next event to execute. - * Then + * Then * - The event inserted should be after the head - * - The interrupt timestamp should remains equal to the interrupt timestamp + * - The interrupt timestamp should remains equal to the interrupt timestamp * of the head event . * - The timestamp of the event should reflect the timestamp requested (overflow) - * - The id of the event should be equal to the id passed in parameter. + * - The id of the event should be equal to the id passed in parameter. * - Events in the queue should remained ordered by timestamp. */ static void test_legacy_insert_event_multiple_overflow() @@ -673,7 +677,7 @@ static void test_legacy_insert_event_multiple_overflow() ticker_set_handler(&ticker_stub, NULL); interface_stub.set_interrupt_call = 0; - const timestamp_t timestamps[] = { + const timestamp_t timestamps[] = { 0xA, 0xAA, 0xAAA, @@ -688,20 +692,20 @@ static void test_legacy_insert_event_multiple_overflow() ticker_event_t ref_event; timestamp_t ref_event_timestamp = 0xCCCCCCCC; ticker_insert_event( - &ticker_stub, + &ticker_stub, &ref_event, ref_event_timestamp, 0xDEADBEEF ); - timestamp_t last_timestamp_to_insert = + timestamp_t last_timestamp_to_insert = timestamps[MBED_ARRAY_SIZE(timestamps) - 1]; - interface_stub.timestamp = - last_timestamp_to_insert + + interface_stub.timestamp = + last_timestamp_to_insert + ((ref_event_timestamp - last_timestamp_to_insert) / 2); ticker_irq_handler(&ticker_stub); - for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { + for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { ticker_insert_event( - &ticker_stub, + &ticker_stub, &events[i], timestamps[i], i ); @@ -714,13 +718,13 @@ static void test_legacy_insert_event_multiple_overflow() TEST_ASSERT_EQUAL_UINT32(timestamps[i], events[i].timestamp); TEST_ASSERT_EQUAL_UINT32(i, events[i].id); - ticker_event_t* e = queue_stub.head->next; - while (e) { + ticker_event_t *e = queue_stub.head->next; + while (e) { TEST_ASSERT_EQUAL_UINT32(timestamps[e->id], e->timestamp); - if (e->next) { + if (e->next) { TEST_ASSERT_TRUE(e->id < e->next->id); TEST_ASSERT_TRUE(e->timestamp < e->next->timestamp); - } else { + } else { TEST_ASSERT_EQUAL_UINT32(&events[i], e); } e = e->next; @@ -733,14 +737,14 @@ static void test_legacy_insert_event_multiple_overflow() /** * Given an initialized ticker. * When an event is inserted with ticker_insert_event. - * Then + * Then * - The event inserted should be at the correct position in the queue * - The event queue should remain ordered by timestamp - * - The interrupt timestamp should be equal to the interrupt timestamp - * of the head event or TIMESTAMP_MAX_DELTA if the + * - The interrupt timestamp should be equal to the interrupt timestamp + * of the head event or TIMESTAMP_MAX_DELTA if the * timestamp is in the overflow range. * - The timestamp of the event should reflect the timestamp requested (overflow) - * - The id of the event should be equal to the id passed in parameter. + * - The id of the event should be equal to the id passed in parameter. * - Events in the queue should remained ordered by timestamp. */ static void test_legacy_insert_event_multiple_random() @@ -751,9 +755,9 @@ static void test_legacy_insert_event_multiple_random() const timestamp_t ref_timestamp = UINT32_MAX / 2; interface_stub.timestamp = ref_timestamp; - // insert first event at the head of the queue + // insert first event at the head of the queue ticker_event_t first_event; - const timestamp_t first_event_timestamp = + const timestamp_t first_event_timestamp = ref_timestamp + TIMESTAMP_MAX_DELTA + 100; ticker_insert_event( @@ -769,7 +773,7 @@ static void test_legacy_insert_event_multiple_random() TEST_ASSERT_EQUAL_UINT32(first_event_timestamp, first_event.timestamp); TEST_ASSERT_EQUAL_UINT64( first_event.timestamp, - first_event_timestamp + + first_event_timestamp + ((first_event_timestamp < ref_timestamp) ? (1ULL << 32) : 0) ); TEST_ASSERT_EQUAL_UINT32((uint32_t) &first_event, first_event.id); @@ -792,7 +796,7 @@ static void test_legacy_insert_event_multiple_random() TEST_ASSERT_EQUAL_UINT32(second_event_timestamp, second_event.timestamp); TEST_ASSERT_EQUAL_UINT64( second_event.timestamp, - second_event_timestamp + + second_event_timestamp + ((second_event_timestamp < ref_timestamp) ? (1ULL << 32) : 0) ); TEST_ASSERT_EQUAL_UINT32((uint32_t) &second_event, second_event.id); @@ -800,7 +804,7 @@ static void test_legacy_insert_event_multiple_random() // insert third event at the head of the queue out the overflow zone ticker_event_t third_event; - const timestamp_t third_event_timestamp = + const timestamp_t third_event_timestamp = ref_timestamp + TIMESTAMP_MAX_DELTA - 100; ticker_insert_event( @@ -818,7 +822,7 @@ static void test_legacy_insert_event_multiple_random() TEST_ASSERT_EQUAL_UINT32(third_event_timestamp, third_event.timestamp); TEST_ASSERT_EQUAL_UINT64( third_event.timestamp, - third_event_timestamp + + third_event_timestamp + ((third_event_timestamp < ref_timestamp) ? (1ULL << 32) : 0) ); TEST_ASSERT_EQUAL_UINT32((uint32_t) &third_event, third_event.id); @@ -843,7 +847,7 @@ static void test_legacy_insert_event_multiple_random() TEST_ASSERT_EQUAL_UINT32(fourth_event_timestamp, fourth_event.timestamp); TEST_ASSERT_EQUAL_UINT64( fourth_event.timestamp, - fourth_event_timestamp + + fourth_event_timestamp + ((fourth_event_timestamp < ref_timestamp) ? (1ULL << 32) : 0) ); TEST_ASSERT_EQUAL_UINT32((uint32_t) &fourth_event, fourth_event.id); @@ -852,15 +856,15 @@ static void test_legacy_insert_event_multiple_random() } /** - * Given an initialized ticker without user registered events. - * When an event is inserted with ticker_insert_event_us and the timestamp passed - * in parameter is in range [ticker_timestamp : ticker_timestamp + + * Given an initialized ticker without user registered events. + * When an event is inserted with ticker_insert_event_us and the timestamp passed + * in parameter is in range [ticker_timestamp : ticker_timestamp + * TIMESTAMP_MAX_DELTA[. - * Then + * Then * - The event should be in the queue - * - The interrupt timestamp should be equal to the lower 8 bytes of the event. - * - The timestamp of the event should be equal to the timestamp requested. - * - The id of the event should be equal to the id passed in parameter. + * - The interrupt timestamp should be equal to the lower 8 bytes of the event. + * - The timestamp of the event should be equal to the timestamp requested. + * - The id of the event should be equal to the id passed in parameter. */ static void test_insert_event_us_outside_overflow_range() { @@ -872,17 +876,17 @@ static void test_insert_event_us_outside_overflow_range() // test the end of the range ticker_event_t last_event = { 0 }; - const us_timestamp_t timestamp_last_event = + const us_timestamp_t timestamp_last_event = queue_stub.present_time + TIMESTAMP_MAX_DELTA; const uint32_t id_last_event = 0xDEADDEAF; ticker_insert_event_us( - &ticker_stub, + &ticker_stub, &last_event, timestamp_last_event, id_last_event ); TEST_ASSERT_EQUAL_PTR(&last_event, queue_stub.head); - TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call); + TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call); TEST_ASSERT_EQUAL_UINT32( timestamp_last_event, interface_stub.interrupt_timestamp ); @@ -896,12 +900,12 @@ static void test_insert_event_us_outside_overflow_range() const uint32_t id_first_event = 0xAAAAAAAA; ticker_insert_event_us( - &ticker_stub, + &ticker_stub, &first_event, timestamp_first_event, id_first_event ); TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head); - TEST_ASSERT_EQUAL(2, interface_stub.set_interrupt_call); + TEST_ASSERT_EQUAL(2, interface_stub.set_interrupt_call); TEST_ASSERT_EQUAL_UINT32( timestamp_first_event, interface_stub.interrupt_timestamp ); @@ -912,17 +916,17 @@ static void test_insert_event_us_outside_overflow_range() TEST_ASSERT_EQUAL_UINT32(id_first_event, first_event.id); TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); -} +} /** - * Given an initialized ticker without user registered events. - * When an event is inserted with ticker_insert_event_us and a timestamp in the - * range [ticker_timestamp + TIMESTAMP_MAX_DELTA + 1 : UINT64_MAX [ - * Then + * Given an initialized ticker without user registered events. + * When an event is inserted with ticker_insert_event_us and a timestamp in the + * range [ticker_timestamp + TIMESTAMP_MAX_DELTA + 1 : UINT64_MAX [ + * Then * - The event should be in the queue - * - The interrupt timestamp should be equal to TIMESTAMP_MAX_DELTA - * - The timestamp of the event should be equal to the timestamp in parameter. - * - The id of the event should be equal to the id passed in parameter. + * - The interrupt timestamp should be equal to TIMESTAMP_MAX_DELTA + * - The timestamp of the event should be equal to the timestamp in parameter. + * - The id of the event should be equal to the id passed in parameter. */ static void test_insert_event_us_in_overflow_range() { @@ -934,18 +938,18 @@ static void test_insert_event_us_in_overflow_range() // test the end of the range ticker_event_t last_event = { 0 }; - const us_timestamp_t timestamp_last_event = UINT64_MAX; + const us_timestamp_t timestamp_last_event = UINT64_MAX; const uint32_t id_last_event = 0xDEADDEAF; ticker_insert_event_us( - &ticker_stub, + &ticker_stub, &last_event, timestamp_last_event, id_last_event ); TEST_ASSERT_EQUAL_PTR(&last_event, queue_stub.head); - TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call); + TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call); TEST_ASSERT_EQUAL_UINT32( - interface_stub.timestamp + TIMESTAMP_MAX_DELTA, + interface_stub.timestamp + TIMESTAMP_MAX_DELTA, interface_stub.interrupt_timestamp ); TEST_ASSERT_EQUAL_PTR(NULL, queue_stub.head->next); @@ -957,18 +961,18 @@ static void test_insert_event_us_in_overflow_range() ++queue_stub.present_time; ticker_event_t first_event = { 0 }; - const us_timestamp_t timestamp_first_event = + const us_timestamp_t timestamp_first_event = queue_stub.present_time + TIMESTAMP_MAX_DELTA + 1; uint32_t id_first_event = 0xAAAAAAAA; - ticker_insert_event_us(&ticker_stub, - &first_event, timestamp_first_event, id_first_event - ); + ticker_insert_event_us(&ticker_stub, + &first_event, timestamp_first_event, id_first_event + ); TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head); - TEST_ASSERT_EQUAL(2, interface_stub.set_interrupt_call); + TEST_ASSERT_EQUAL(2, interface_stub.set_interrupt_call); TEST_ASSERT_EQUAL_UINT32( - interface_stub.timestamp + TIMESTAMP_MAX_DELTA, + interface_stub.timestamp + TIMESTAMP_MAX_DELTA, interface_stub.interrupt_timestamp ); TEST_ASSERT_EQUAL_PTR(&last_event, queue_stub.head->next); @@ -976,13 +980,13 @@ static void test_insert_event_us_in_overflow_range() TEST_ASSERT_EQUAL_UINT32(id_first_event, first_event.id); TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); -} +} /** - * Given an initialized ticker without user registered events. - * When an event is inserted with ticker_insert_event_us and a timestamp less + * Given an initialized ticker without user registered events. + * When an event is inserted with ticker_insert_event_us and a timestamp less * than timestamp value in the ticker interface. - * Then + * Then * - The event should be in the queue * - The interrupt timestamp should be set to interface_stub.timestamp so it * is scheduled immediately. @@ -1010,18 +1014,18 @@ static void test_insert_event_us_underflow() TEST_ASSERT_EQUAL(1, interface_stub.fire_interrupt_call); TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); -} +} /** * Given an initialized ticker. - * When an event is inserted with ticker_insert_event_us and a timestamp less + * When an event is inserted with ticker_insert_event_us and a timestamp less * than the one for the next scheduled timestamp. - * Then + * Then * - The event inserted should be the first in the queue - * - The interrupt timestamp should be equal to the timestamp of the event or + * - The interrupt timestamp should be equal to the timestamp of the event or * TIMESTAMP_MAX_DELTA if in the overflow range. - * - The timestamp of the event should be equal to the timestamp in parameter. - * - The id of the event should be equal to the id passed in parameter. + * - The timestamp of the event should be equal to the timestamp in parameter. + * - The id of the event should be equal to the id passed in parameter. * - Events in the queue should remained ordered by timestamp. */ static void test_insert_event_us_head() @@ -1032,7 +1036,7 @@ static void test_insert_event_us_head() queue_stub.tick_last_read = interface_stub.timestamp; queue_stub.present_time = 10ULL << 32 | interface_stub.timestamp; - const us_timestamp_t timestamps[] = { + const us_timestamp_t timestamps[] = { UINT64_MAX, queue_stub.present_time + TIMESTAMP_MAX_DELTA + 1, queue_stub.present_time + TIMESTAMP_MAX_DELTA, @@ -1043,19 +1047,19 @@ static void test_insert_event_us_head() }; ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 }; - for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { + for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { ticker_insert_event_us( - &ticker_stub, + &ticker_stub, &events[i], timestamps[i], i ); TEST_ASSERT_EQUAL_PTR(&events[i], queue_stub.head); if ((timestamps[i] - queue_stub.present_time) < TIMESTAMP_MAX_DELTA) { TEST_ASSERT_EQUAL_UINT32( - timestamps[i], + timestamps[i], interface_stub.interrupt_timestamp ); - } else { + } else { TEST_ASSERT_EQUAL_UINT32( queue_stub.present_time + TIMESTAMP_MAX_DELTA, interface_stub.interrupt_timestamp @@ -1065,13 +1069,13 @@ static void test_insert_event_us_head() TEST_ASSERT_EQUAL_UINT64(timestamps[i], events[i].timestamp); TEST_ASSERT_EQUAL_UINT32(i, events[i].id); - ticker_event_t* e = &events[i]; - while (e) { + ticker_event_t *e = &events[i]; + while (e) { TEST_ASSERT_EQUAL_UINT32(timestamps[e->id], e->timestamp); - if (e->next) { + if (e->next) { TEST_ASSERT_TRUE(e->id > e->next->id); TEST_ASSERT_TRUE(e->timestamp < e->next->timestamp); - } else { + } else { TEST_ASSERT_EQUAL_UINT32(0, e->id); } e = e->next; @@ -1079,18 +1083,18 @@ static void test_insert_event_us_head() } TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); -} +} -/** +/** * Given an initialized ticker. - * When an event is inserted with ticker_insert_event_us and its timestamp is + * When an event is inserted with ticker_insert_event_us and its timestamp is * bigger than the one of the last event in the queue. - * Then + * Then * - The event inserted should be the last in the queue - * - The interrupt timestamp should remains equal to the interrupt timestamp + * - The interrupt timestamp should remains equal to the interrupt timestamp * of the head event . * - The timestamp of the event should reflect the timestamp requested. - * - The id of the event should be equal to the id passed in parameter. + * - The id of the event should be equal to the id passed in parameter. * - Events in the queue should remained ordered by timestamp. */ static void test_insert_event_us_tail() @@ -1098,7 +1102,7 @@ static void test_insert_event_us_tail() ticker_set_handler(&ticker_stub, NULL); interface_stub.set_interrupt_call = 0; - const us_timestamp_t timestamps[] = { + const us_timestamp_t timestamps[] = { 0xA, (1ULL << 32), (2ULL << 32), @@ -1110,26 +1114,26 @@ static void test_insert_event_us_tail() }; ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 }; - for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { + for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { ticker_insert_event_us( - &ticker_stub, + &ticker_stub, &events[i], timestamps[i], i ); - TEST_ASSERT_EQUAL_PTR(&events[0], queue_stub.head); + TEST_ASSERT_EQUAL_PTR(&events[0], queue_stub.head); TEST_ASSERT_EQUAL_UINT32( timestamps[0], interface_stub.interrupt_timestamp ); TEST_ASSERT_EQUAL_UINT64(timestamps[i], events[i].timestamp); TEST_ASSERT_EQUAL_UINT32(i, events[i].id); - ticker_event_t* e = queue_stub.head; - while (e) { + ticker_event_t *e = queue_stub.head; + while (e) { TEST_ASSERT_EQUAL_UINT32(timestamps[e->id], e->timestamp); - if (e->next) { + if (e->next) { TEST_ASSERT_TRUE(e->id < e->next->id); TEST_ASSERT_TRUE(e->timestamp < e->next->timestamp); - } else { + } else { TEST_ASSERT_EQUAL_UINT32(&events[i], e); } e = e->next; @@ -1137,19 +1141,19 @@ static void test_insert_event_us_tail() } TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); -} +} /** * Given an initialized ticker. * When an event is inserted with ticker_insert_event_us. - * Then + * Then * - The event inserted should be at the correct position in the queue * - The event queue should remain ordered by timestamp - * - The interrupt timestamp should be equal to the interrupt timestamp - * of the head event or TIMESTAMP_MAX_DELTA if the + * - The interrupt timestamp should be equal to the interrupt timestamp + * of the head event or TIMESTAMP_MAX_DELTA if the * timestamp is in the overflow range. * - The timestamp of the event should be equal to the timestamp parameter. - * - The id of the event should be equal to the id passed in parameter. + * - The id of the event should be equal to the id passed in parameter. * - Events in the queue should remained ordered by timestamp. */ static void test_insert_event_us_multiple_random() @@ -1160,9 +1164,9 @@ static void test_insert_event_us_multiple_random() const timestamp_t ref_timestamp = UINT32_MAX / 2; interface_stub.timestamp = ref_timestamp; - // insert first event at the head of the queue + // insert first event at the head of the queue ticker_event_t first_event; - const us_timestamp_t first_event_timestamp = + const us_timestamp_t first_event_timestamp = ref_timestamp + TIMESTAMP_MAX_DELTA + 100; ticker_insert_event_us( @@ -1199,7 +1203,7 @@ static void test_insert_event_us_multiple_random() // insert third event at the head of the queue out the overflow zone ticker_event_t third_event; - const us_timestamp_t third_event_timestamp = + const us_timestamp_t third_event_timestamp = ref_timestamp + TIMESTAMP_MAX_DELTA - 100; ticker_insert_event_us( @@ -1241,17 +1245,17 @@ static void test_insert_event_us_multiple_random() } /** - * Given an initialized ticker with multiple events registered. + * Given an initialized ticker with multiple events registered. * When the event at the tail of the queue is removed from the queue. - * Then: + * Then: * - The event should not be in the queue. * - The events in the queue should remain ordered - * - The interrupt timestamp should be unchanged. + * - The interrupt timestamp should be unchanged. */ static void test_remove_event_tail() { ticker_set_handler(&ticker_stub, NULL); - const us_timestamp_t timestamps[] = { + const us_timestamp_t timestamps[] = { 0xA, (1ULL << 32), (2ULL << 32), @@ -1263,21 +1267,21 @@ static void test_remove_event_tail() }; ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 }; - for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { + for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { ticker_insert_event_us( - &ticker_stub, + &ticker_stub, &events[i], timestamps[i], i ); } - for (ssize_t i = MBED_ARRAY_SIZE(events) - 1; i >= 0; --i) { + for (ssize_t i = MBED_ARRAY_SIZE(events) - 1; i >= 0; --i) { ticker_remove_event(&ticker_stub, &events[i]); - ticker_event_t* e = queue_stub.head; + ticker_event_t *e = queue_stub.head; size_t event_count = 0; - while (e) { + while (e) { TEST_ASSERT_NOT_EQUAL(e, &events[i]); - if (e->next) { + if (e->next) { TEST_ASSERT_TRUE(e->timestamp <= e->next->timestamp); } e = e->next; @@ -1286,12 +1290,12 @@ static void test_remove_event_tail() TEST_ASSERT_EQUAL(i, event_count); - if (i != 0 ) { + if (i != 0) { TEST_ASSERT_EQUAL( timestamps[0], interface_stub.interrupt_timestamp ); - } else { + } else { TEST_ASSERT_EQUAL( interface_stub.timestamp + TIMESTAMP_MAX_DELTA, interface_stub.interrupt_timestamp @@ -1303,20 +1307,20 @@ static void test_remove_event_tail() } /** - * Given an initialized ticker with multiple events registered. + * Given an initialized ticker with multiple events registered. * When the event at the head of the queue is removed from the queue. - * Then: + * Then: * - The event should not be in the queue. - * - The event at the head of the queue should be the equal to the one + * - The event at the head of the queue should be the equal to the one * after the event removed. - * - The interrupt timestamp should be equal to the interrupt timestamp - * of the head event or TIMESTAMP_MAX_DELTA if the + * - The interrupt timestamp should be equal to the interrupt timestamp + * of the head event or TIMESTAMP_MAX_DELTA if the * timestamp is in the overflow range. */ static void test_remove_event_head() { ticker_set_handler(&ticker_stub, NULL); - const us_timestamp_t timestamps[] = { + const us_timestamp_t timestamps[] = { TIMESTAMP_MAX_DELTA / 8, TIMESTAMP_MAX_DELTA / 4, TIMESTAMP_MAX_DELTA / 2, @@ -1328,20 +1332,20 @@ static void test_remove_event_head() }; ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 }; - for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { - ticker_insert_event_us(&ticker_stub, - &events[i], timestamps[i], i - ); + for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { + ticker_insert_event_us(&ticker_stub, + &events[i], timestamps[i], i + ); } - for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { + for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { ticker_remove_event(&ticker_stub, &events[i]); - ticker_event_t* e = queue_stub.head; + ticker_event_t *e = queue_stub.head; size_t event_count = 0; - while (e) { + while (e) { TEST_ASSERT_NOT_EQUAL(e, &events[i]); - if (e->next) { + if (e->next) { TEST_ASSERT_TRUE(e->timestamp <= e->next->timestamp); } e = e->next; @@ -1350,15 +1354,15 @@ static void test_remove_event_head() TEST_ASSERT_EQUAL(MBED_ARRAY_SIZE(events) - i - 1, event_count); - if (event_count) { + if (event_count) { TEST_ASSERT_EQUAL( std::min( - timestamps[i + 1], + timestamps[i + 1], interface_stub.timestamp + TIMESTAMP_MAX_DELTA ), interface_stub.interrupt_timestamp ); - } else { + } else { TEST_ASSERT_EQUAL( interface_stub.timestamp + TIMESTAMP_MAX_DELTA, interface_stub.interrupt_timestamp @@ -1371,14 +1375,14 @@ static void test_remove_event_head() } /** - * Given an initialized ticker with multiple events registered. + * Given an initialized ticker with multiple events registered. * When an event not in the queue is attempted to be removed. * Then the queue should remains identical as before. */ static void test_remove_event_invalid() { ticker_set_handler(&ticker_stub, NULL); - const us_timestamp_t timestamps[] = { + const us_timestamp_t timestamps[] = { TIMESTAMP_MAX_DELTA / 8, TIMESTAMP_MAX_DELTA / 4, TIMESTAMP_MAX_DELTA / 2, @@ -1390,9 +1394,9 @@ static void test_remove_event_invalid() }; ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 }; - for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { + for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { ticker_insert_event_us( - &ticker_stub, + &ticker_stub, &events[i], timestamps[i], i ); } @@ -1402,9 +1406,9 @@ static void test_remove_event_invalid() TEST_ASSERT_EQUAL(&events[0], queue_stub.head); - ticker_event_t* e = queue_stub.head; + ticker_event_t *e = queue_stub.head; size_t event_count = 0; - while (e) { + while (e) { TEST_ASSERT_EQUAL(e, &events[event_count]); e = e->next; ++event_count; @@ -1418,8 +1422,8 @@ static void test_remove_event_invalid() * Then: * - the event should not be in the queue * - the queue should remain ordered - * - the interrupt timestamp should be set to either head->timestamp or - * TIMESTAMP_MAX_DELTA depending on the distance between the current time + * - the interrupt timestamp should be set to either head->timestamp or + * TIMESTAMP_MAX_DELTA depending on the distance between the current time * ans the timestamp of the event at the head of the queue. */ static void test_remove_random() @@ -1430,9 +1434,9 @@ static void test_remove_random() const timestamp_t ref_timestamp = UINT32_MAX / 2; interface_stub.timestamp = ref_timestamp; - // insert all events + // insert all events ticker_event_t first_event; - const us_timestamp_t first_event_timestamp = + const us_timestamp_t first_event_timestamp = ref_timestamp + TIMESTAMP_MAX_DELTA + 100; ticker_insert_event_us( @@ -1450,7 +1454,7 @@ static void test_remove_random() ); ticker_event_t third_event; - const us_timestamp_t third_event_timestamp = + const us_timestamp_t third_event_timestamp = ref_timestamp + TIMESTAMP_MAX_DELTA - 100; ticker_insert_event_us( @@ -1466,7 +1470,7 @@ static void test_remove_random() &fourth_event, fourth_event_timestamp, (uint32_t) &fourth_event ); - // test that the queue is in the correct state + // test that the queue is in the correct state TEST_ASSERT_EQUAL_PTR(&third_event, queue_stub.head); TEST_ASSERT_EQUAL_PTR(&fourth_event, third_event.next); TEST_ASSERT_EQUAL_PTR(&first_event, fourth_event.next); @@ -1478,7 +1482,7 @@ static void test_remove_random() TEST_ASSERT_EQUAL_UINT64(fourth_event_timestamp, fourth_event.timestamp); TEST_ASSERT_EQUAL_UINT32((uint32_t) &fourth_event, fourth_event.id); - // remove fourth event + // remove fourth event ticker_remove_event(&ticker_stub, &fourth_event); TEST_ASSERT_EQUAL_PTR(&third_event, queue_stub.head); @@ -1491,7 +1495,7 @@ static void test_remove_random() TEST_ASSERT_EQUAL_UINT64(third_event_timestamp, third_event.timestamp); TEST_ASSERT_EQUAL_UINT32((uint32_t) &third_event, third_event.id); - // remove third event + // remove third event ticker_remove_event(&ticker_stub, &third_event); TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head); @@ -1503,7 +1507,7 @@ static void test_remove_random() TEST_ASSERT_EQUAL_UINT64(second_event_timestamp, second_event.timestamp); TEST_ASSERT_EQUAL_UINT32((uint32_t) &second_event, second_event.id); - // remove second event + // remove second event ticker_remove_event(&ticker_stub, &second_event); TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head); @@ -1514,7 +1518,7 @@ static void test_remove_random() TEST_ASSERT_EQUAL_UINT64(first_event.timestamp, first_event_timestamp); TEST_ASSERT_EQUAL_UINT32((uint32_t) &first_event, first_event.id); - // remove first event + // remove first event ticker_remove_event(&ticker_stub, &first_event); TEST_ASSERT_EQUAL_PTR(NULL, queue_stub.head); @@ -1526,21 +1530,22 @@ static void test_remove_random() TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); } -/** - * Given an initialized ticker without user registered events and a ticker - * interface timestamp equal or bigger than the one registered by the overflow +/** + * Given an initialized ticker without user registered events and a ticker + * interface timestamp equal or bigger than the one registered by the overflow * event. * When the interrupt handler is called. * Then: - * - The interrupt timestamp should be updated to the timestamp of the ticker - * interface plus TIMESTAMP_MAX_DELTA. + * - The interrupt timestamp should be updated to the timestamp of the ticker + * interface plus TIMESTAMP_MAX_DELTA. * - The irq handler registered should not be called. */ static void test_overflow_event_update() { static uint32_t handler_call = 0; - struct irq_handler_stub_t { - static void event_handler(uint32_t id) { + struct irq_handler_stub_t { + static void event_handler(uint32_t id) + { ++handler_call; } }; @@ -1551,10 +1556,10 @@ static void test_overflow_event_update() for (size_t i = 0; i < 8; ++i) { us_timestamp_t previous_timestamp = queue_stub.present_time; - timestamp_t interface_timestamp = + timestamp_t interface_timestamp = previous_timestamp + (TIMESTAMP_MAX_DELTA + i * 100); interface_stub.timestamp = interface_timestamp; - + ticker_irq_handler(&ticker_stub); TEST_ASSERT_EQUAL(i + 1, interface_stub.clear_interrupt_call); @@ -1567,22 +1572,23 @@ static void test_overflow_event_update() } TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); -} +} -/** - * Given an initialized ticker without user registered events and a ticker +/** + * Given an initialized ticker without user registered events and a ticker * interface timestamp less than the one registered to handle overflow. * When the interrupt handler is called. * Then: - * - The interrupt timestamp should be updated to the timestamp of the ticker - * interface plus TIMESTAMP_MAX_DELTA. + * - The interrupt timestamp should be updated to the timestamp of the ticker + * interface plus TIMESTAMP_MAX_DELTA. * - The irq handler registered should not be called. */ static void test_overflow_event_update_when_spurious_interrupt() { static uint32_t handler_call = 0; - struct irq_handler_stub_t { - static void event_handler(uint32_t id) { + struct irq_handler_stub_t { + static void event_handler(uint32_t id) + { ++handler_call; } }; @@ -1593,10 +1599,10 @@ static void test_overflow_event_update_when_spurious_interrupt() for (size_t i = 0; i < 8; ++i) { us_timestamp_t previous_timestamp = queue_stub.present_time; - timestamp_t interface_timestamp = + timestamp_t interface_timestamp = previous_timestamp + (TIMESTAMP_MAX_DELTA / (2 + i)); interface_stub.timestamp = interface_timestamp; - + ticker_irq_handler(&ticker_stub); TEST_ASSERT_EQUAL(i + 1, interface_stub.clear_interrupt_call); @@ -1609,18 +1615,18 @@ static void test_overflow_event_update_when_spurious_interrupt() } TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); -} +} /** - * Given an initialized ticker with a single ticker event inserted and a ticker - * interface timestamp bigger than the one set for interrupt. + * Given an initialized ticker with a single ticker event inserted and a ticker + * interface timestamp bigger than the one set for interrupt. * When ticker_irq_handler is called. - * Then: - * - The IRQ handler should be called with the id of the event at the head of + * Then: + * - The IRQ handler should be called with the id of the event at the head of * the queue. * - The event at the head of the queue should be replaced by the next event. - * - The interrupt timestamp in the ticker interface should be set to the - * value of the interface timestamp + TIMESTAMP_MAX_DELTA + * - The interrupt timestamp in the ticker interface should be set to the + * value of the interface timestamp + TIMESTAMP_MAX_DELTA */ static void test_irq_handler_single_event() { @@ -1628,9 +1634,10 @@ static void test_irq_handler_single_event() static const timestamp_t interface_timestamp_after_irq = event_timestamp + 100; uint32_t handler_call = 0; - struct irq_handler_stub_t { - static void event_handler(uint32_t id) { - ++ (*((uint32_t*) id)); + struct irq_handler_stub_t { + static void event_handler(uint32_t id) + { + ++ (*((uint32_t *) id)); interface_stub.timestamp = interface_timestamp_after_irq; } }; @@ -1638,7 +1645,7 @@ static void test_irq_handler_single_event() ticker_set_handler(&ticker_stub, irq_handler_stub_t::event_handler); interface_stub.set_interrupt_call = 0; - ticker_event_t e; + ticker_event_t e; ticker_insert_event(&ticker_stub, &e, event_timestamp, (uint32_t) &handler_call); interface_stub.timestamp = event_timestamp; @@ -1660,19 +1667,20 @@ static void test_irq_handler_single_event() } /** - * Given an initialized ticker with at least a ticker event inserted and a ticker - * interface timestamp less than the one set for interrupt. + * Given an initialized ticker with at least a ticker event inserted and a ticker + * interface timestamp less than the one set for interrupt. * When ticker_irq_handler is called. - * Then: + * Then: * - The IRQ handler should not be called. * - The event at the head of the queue should remains the same. - * - The interrupt timestamp in the ticker interface should be set to the - * value of the event timestamp + * - The interrupt timestamp in the ticker interface should be set to the + * value of the event timestamp */ static void test_irq_handler_single_event_spurious() { - struct irq_handler_stub_t { - static void event_handler(uint32_t id) { + struct irq_handler_stub_t { + static void event_handler(uint32_t id) + { TEST_FAIL(); } }; @@ -1681,17 +1689,17 @@ static void test_irq_handler_single_event_spurious() interface_stub.set_interrupt_call = 0; const us_timestamp_t timestamps [] = { - UINT32_MAX, - TIMESTAMP_MAX_DELTA + 1, + UINT32_MAX, + TIMESTAMP_MAX_DELTA + 1, TIMESTAMP_MAX_DELTA, TIMESTAMP_MAX_DELTA - 1 }; ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 }; - for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { + for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { ticker_insert_event_us( - &ticker_stub, + &ticker_stub, &events[i], timestamps[i], timestamps[i] ); interface_stub.set_interrupt_call = 0; @@ -1711,11 +1719,11 @@ static void test_irq_handler_single_event_spurious() } /** - * Given an initialized ticker with multiple ticker event inserted, its - * interface timestamp at greater than the timestamp of the next schedule event + * Given an initialized ticker with multiple ticker event inserted, its + * interface timestamp at greater than the timestamp of the next schedule event * and all event execution time taking at least the time befor ethe next event. * When ticker_irq_handler is called. - * Then: + * Then: * - The IRQ handler should have been called for every event. * - The head of the queue should be set to NULL. * - The interrupt timestamp in the ticker interface should be scheduled in @@ -1724,19 +1732,20 @@ static void test_irq_handler_single_event_spurious() static void test_irq_handler_multiple_event_multiple_dequeue() { const us_timestamp_t timestamps [] = { - 10, + 10, 10 + TIMESTAMP_MAX_DELTA - 1, 10 + TIMESTAMP_MAX_DELTA, - 10 + TIMESTAMP_MAX_DELTA + 1, + 10 + TIMESTAMP_MAX_DELTA + 1, UINT32_MAX }; static size_t handler_called = 0; - struct irq_handler_stub_t { - static void event_handler(uint32_t id) { + struct irq_handler_stub_t { + static void event_handler(uint32_t id) + { ++handler_called; - ticker_event_t* e = (ticker_event_t*) id; - if (e->next) { + ticker_event_t *e = (ticker_event_t *) id; + if (e->next) { interface_stub.timestamp = e->next->timestamp; } } @@ -1748,9 +1757,9 @@ static void test_irq_handler_multiple_event_multiple_dequeue() ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 }; - for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { + for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { ticker_insert_event_us( - &ticker_stub, + &ticker_stub, &events[i], timestamps[i], (uint32_t) &events[i] ); } @@ -1758,7 +1767,7 @@ static void test_irq_handler_multiple_event_multiple_dequeue() interface_stub.set_interrupt_call = 0; interface_stub.clear_interrupt_call = 0; interface_stub.timestamp = timestamps[0]; - + ticker_irq_handler(&ticker_stub); TEST_ASSERT_EQUAL(1, interface_stub.clear_interrupt_call); @@ -1774,11 +1783,11 @@ static void test_irq_handler_multiple_event_multiple_dequeue() } /** - * Given an initialized ticker with two ticker event inserted scheduled from more - * than TIMESTAMP_MAX_DELTA from one another. The interface - * timestamp is equal to the timestamp of the first event. + * Given an initialized ticker with two ticker event inserted scheduled from more + * than TIMESTAMP_MAX_DELTA from one another. The interface + * timestamp is equal to the timestamp of the first event. * When ticker_irq_handler is called. - * Then: + * Then: * - The IRQ handler should have been called for the first event. * - The head of the queue should be set to the event after the first event. * - The interrupt timestamp in the ticker interface should be scheduled in @@ -1787,14 +1796,15 @@ static void test_irq_handler_multiple_event_multiple_dequeue() static void test_irq_handler_multiple_event_single_dequeue_overflow() { const us_timestamp_t timestamps [] = { - 10, + 10, 10 + TIMESTAMP_MAX_DELTA + 1 }; size_t handler_called = 0; - struct irq_handler_stub_t { - static void event_handler(uint32_t id) { - ++ (*((size_t*) id)); + struct irq_handler_stub_t { + static void event_handler(uint32_t id) + { + ++ (*((size_t *) id)); } }; @@ -1803,9 +1813,9 @@ static void test_irq_handler_multiple_event_single_dequeue_overflow() ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 }; - for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { + for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { ticker_insert_event_us( - &ticker_stub, + &ticker_stub, &events[i], timestamps[i], (uint32_t) &handler_called ); } @@ -1813,7 +1823,7 @@ static void test_irq_handler_multiple_event_single_dequeue_overflow() interface_stub.set_interrupt_call = 0; interface_stub.clear_interrupt_call = 0; interface_stub.timestamp = timestamps[0]; - + ticker_irq_handler(&ticker_stub); TEST_ASSERT_EQUAL(1, interface_stub.clear_interrupt_call); @@ -1829,27 +1839,28 @@ static void test_irq_handler_multiple_event_single_dequeue_overflow() } /** - * Given an initialized ticker with two ticker event inserted scheduled from less - * than TIMESTAMP_MAX_DELTA from one another. The interface - * timestamp is equal to the timestamp of the first event. + * Given an initialized ticker with two ticker event inserted scheduled from less + * than TIMESTAMP_MAX_DELTA from one another. The interface + * timestamp is equal to the timestamp of the first event. * When ticker_irq_handler is called. - * Then: + * Then: * - The IRQ handler should have been called for the first event. * - The head of the queue should be set to second event. - * - The interrupt timestamp in the ticker interface should be equal to the + * - The interrupt timestamp in the ticker interface should be equal to the * timestamp of the second event. */ static void test_irq_handler_multiple_event_single_dequeue() { const us_timestamp_t timestamps [] = { - 10, + 10, 10 + TIMESTAMP_MAX_DELTA - 1 }; size_t handler_called = 0; - struct irq_handler_stub_t { - static void event_handler(uint32_t id) { - ++ (*((size_t*) id)); + struct irq_handler_stub_t { + static void event_handler(uint32_t id) + { + ++ (*((size_t *) id)); } }; @@ -1858,9 +1869,9 @@ static void test_irq_handler_multiple_event_single_dequeue() ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 }; - for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { + for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { ticker_insert_event_us( - &ticker_stub, + &ticker_stub, &events[i], timestamps[i], (uint32_t) &handler_called ); } @@ -1868,7 +1879,7 @@ static void test_irq_handler_multiple_event_single_dequeue() interface_stub.set_interrupt_call = 0; interface_stub.clear_interrupt_call = 0; interface_stub.timestamp = timestamps[0]; - + ticker_irq_handler(&ticker_stub); TEST_ASSERT_EQUAL(1, interface_stub.clear_interrupt_call); @@ -1884,47 +1895,48 @@ static void test_irq_handler_multiple_event_single_dequeue() } /** - * Given an initialized ticker with multiple ticker event inserted and the + * Given an initialized ticker with multiple ticker event inserted and the * interface timestamp is equal to the timestamp of the first event. The first - * event to execute will insert an events in the ticker which have to be executed + * event to execute will insert an events in the ticker which have to be executed * immediately. * When ticker_irq_handler is called. - * Then: - * - The IRQ handler should have been called for the first event and the event + * Then: + * - The IRQ handler should have been called for the first event and the event * inserted during irq. * - The head of the queue should be set correctly. - * - The interrupt timestamp in the ticker interface should be equal to + * - The interrupt timestamp in the ticker interface should be equal to * timestamp of the head event. */ static void test_irq_handler_insert_immediate_in_irq() { static const us_timestamp_t timestamps [] = { - 10, + 10, 10 + TIMESTAMP_MAX_DELTA - 1 }; - static const us_timestamp_t expected_timestamp = + static const us_timestamp_t expected_timestamp = ((timestamps[1] - timestamps[0]) / 2) + timestamps[0]; - struct ctrl_block_t { + struct ctrl_block_t { bool irq_event_called; - ticker_event_t immediate_event; + ticker_event_t immediate_event; size_t handler_called; }; ctrl_block_t ctrl_block = { 0 }; - struct irq_handler_stub_t { - static void event_handler(uint32_t id) { - ctrl_block_t* ctrl_block = (ctrl_block_t*) id; + struct irq_handler_stub_t { + static void event_handler(uint32_t id) + { + ctrl_block_t *ctrl_block = (ctrl_block_t *) id; if (ctrl_block->handler_called == 0) { ticker_insert_event( - &ticker_stub, + &ticker_stub, &ctrl_block->immediate_event, expected_timestamp, id ); interface_stub.timestamp = expected_timestamp; - } else if (ctrl_block->handler_called > 1) { + } else if (ctrl_block->handler_called > 1) { TEST_FAIL(); } ++ctrl_block->handler_called; @@ -1936,9 +1948,9 @@ static void test_irq_handler_insert_immediate_in_irq() ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 }; - for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { + for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { ticker_insert_event_us( - &ticker_stub, + &ticker_stub, &events[i], timestamps[i], (uint32_t) &ctrl_block ); } @@ -1946,7 +1958,7 @@ static void test_irq_handler_insert_immediate_in_irq() interface_stub.set_interrupt_call = 0; interface_stub.clear_interrupt_call = 0; interface_stub.timestamp = timestamps[0]; - + ticker_irq_handler(&ticker_stub); TEST_ASSERT_EQUAL(1, interface_stub.clear_interrupt_call); @@ -1961,45 +1973,46 @@ static void test_irq_handler_insert_immediate_in_irq() } /** - * Given an initialized ticker with multiple ticker event inserted and the + * Given an initialized ticker with multiple ticker event inserted and the * interface timestamp is equal to the timestamp of the first event. The first - * event to execute will insert an events in the ticker which does not have to + * event to execute will insert an events in the ticker which does not have to * be executed immediately. * When ticker_irq_handler is called. - * Then: + * Then: * - The IRQ handler should have been called for the first event. * - The head of the queue should be set to the event inserted in IRQ. - * - The interrupt timestamp in the ticker interface should be equal to + * - The interrupt timestamp in the ticker interface should be equal to * timestamp of the head event. */ static void test_irq_handler_insert_non_immediate_in_irq() { static const us_timestamp_t timestamps [] = { - 10, + 10, 10 + TIMESTAMP_MAX_DELTA - 1 }; - static const us_timestamp_t expected_timestamp = + static const us_timestamp_t expected_timestamp = ((timestamps[1] - timestamps[0]) / 2) + timestamps[0]; - struct ctrl_block_t { + struct ctrl_block_t { bool irq_event_called; - ticker_event_t non_immediate_event; + ticker_event_t non_immediate_event; size_t handler_called; }; ctrl_block_t ctrl_block = { 0 }; - struct irq_handler_stub_t { - static void event_handler(uint32_t id) { - ctrl_block_t* ctrl_block = (ctrl_block_t*) id; + struct irq_handler_stub_t { + static void event_handler(uint32_t id) + { + ctrl_block_t *ctrl_block = (ctrl_block_t *) id; if (ctrl_block->handler_called == 0) { ticker_insert_event( - &ticker_stub, + &ticker_stub, &ctrl_block->non_immediate_event, expected_timestamp, id ); - } else { + } else { TEST_FAIL(); } ++ctrl_block->handler_called; @@ -2012,9 +2025,9 @@ static void test_irq_handler_insert_non_immediate_in_irq() ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 }; - for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { + for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { ticker_insert_event_us( - &ticker_stub, + &ticker_stub, &events[i], timestamps[i], (uint32_t) &ctrl_block ); } @@ -2022,7 +2035,7 @@ static void test_irq_handler_insert_non_immediate_in_irq() interface_stub.set_interrupt_call = 0; interface_stub.clear_interrupt_call = 0; interface_stub.timestamp = timestamps[0]; - + ticker_irq_handler(&ticker_stub); TEST_ASSERT_EQUAL(1, interface_stub.clear_interrupt_call); @@ -2046,7 +2059,7 @@ static uint32_t ticker_interface_stub_read_interrupt_time() } else { return interface_stub.timestamp; } -} +} /** * Test to insert an event that is already in the past, the fire_interrupt should @@ -2223,28 +2236,28 @@ typedef struct { static void test_match_interval_passed_table() { static const match_interval_entry_t test_values[] = { - /* prev, cur, match, result */ - {0x00000000, 0x00000000, 0x00000000, false}, - {0x00000000, 0x00000000, 0xffffffff, false}, - {0x00000000, 0x00000000, 0x00000001, false}, - {0x00000000, 0xffffffff, 0x00000000, false}, - {0x00000000, 0x00000001, 0x00000000, false}, - {0xffffffff, 0x00000000, 0x00000000, true}, - {0x00000001, 0x00000000, 0x00000000, true}, - {0x00005555, 0x00005555, 0x00005555, false}, - {0x00005555, 0x00005555, 0x00005554, false}, - {0x00005555, 0x00005555, 0x00005556, false}, - {0x00005555, 0x00005554, 0x00005555, false}, - {0x00005555, 0x00005556, 0x00005555, false}, - {0x00005554, 0x00005555, 0x00005555, true}, - {0x00005556, 0x00005555, 0x00005555, true}, - {0xffffffff, 0xffffffff, 0xffffffff, false}, - {0xffffffff, 0xffffffff, 0xfffffffe, false}, - {0xffffffff, 0xffffffff, 0x00000000, false}, - {0xffffffff, 0xfffffffe, 0xffffffff, false}, - {0xffffffff, 0x00000000, 0xffffffff, false}, - {0xfffffffe, 0xffffffff, 0xffffffff, true}, - {0x00000000, 0xffffffff, 0xffffffff, true}, + /* prev, cur, match, result */ + {0x00000000, 0x00000000, 0x00000000, false}, + {0x00000000, 0x00000000, 0xffffffff, false}, + {0x00000000, 0x00000000, 0x00000001, false}, + {0x00000000, 0xffffffff, 0x00000000, false}, + {0x00000000, 0x00000001, 0x00000000, false}, + {0xffffffff, 0x00000000, 0x00000000, true}, + {0x00000001, 0x00000000, 0x00000000, true}, + {0x00005555, 0x00005555, 0x00005555, false}, + {0x00005555, 0x00005555, 0x00005554, false}, + {0x00005555, 0x00005555, 0x00005556, false}, + {0x00005555, 0x00005554, 0x00005555, false}, + {0x00005555, 0x00005556, 0x00005555, false}, + {0x00005554, 0x00005555, 0x00005555, true}, + {0x00005556, 0x00005555, 0x00005555, true}, + {0xffffffff, 0xffffffff, 0xffffffff, false}, + {0xffffffff, 0xffffffff, 0xfffffffe, false}, + {0xffffffff, 0xffffffff, 0x00000000, false}, + {0xffffffff, 0xfffffffe, 0xffffffff, false}, + {0xffffffff, 0x00000000, 0xffffffff, false}, + {0xfffffffe, 0xffffffff, 0xffffffff, true}, + {0x00000000, 0xffffffff, 0xffffffff, true}, }; for (int i = 0; i < MBED_ARRAY_SIZE(test_values); i++) { const uint32_t prev = test_values[i].prev; @@ -2255,6 +2268,82 @@ static void test_match_interval_passed_table() } } +/** + * Check that suspend and resume work as expected + * + * Check the following + * -time does not change while suspended + * -restricted interface functions are not called + * -scheduling resumes correctly + */ +static void test_suspend_resume() +{ + ticker_set_handler(&ticker_stub, NULL); + + interface_stub.timestamp = 1000; + us_timestamp_t start = ticker_read_us(&ticker_stub); + TEST_ASSERT_EQUAL(1000, start); + + /* Reset call count */ + interface_stub.init_call = 0; + interface_stub.read_call = 0; + interface_stub.set_interrupt_call = 0; + + /* Suspend the ticker */ + ticker_suspend(&ticker_stub); + const timestamp_t suspend_time = queue_stub.present_time; + + + /* Simulate time passing */ + interface_stub.timestamp = 1500; + us_timestamp_t next = ticker_read_us(&ticker_stub); + + /* Time should not have passed and no calls to interface should have been made */ + TEST_ASSERT_EQUAL(start, next); + TEST_ASSERT_EQUAL(0, interface_stub.init_call); + TEST_ASSERT_EQUAL(0, interface_stub.read_call); + TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); + TEST_ASSERT_EQUAL(0, interface_stub.clear_interrupt_call); + TEST_ASSERT_EQUAL(0, interface_stub.set_interrupt_call); + TEST_ASSERT_EQUAL(0, interface_stub.fire_interrupt_call); + + + /* Simulate a reinit (time reset to 0) */ + interface_stub.timestamp = 0; + next = ticker_read_us(&ticker_stub); + + /* Time should not have passed and no calls to interface should have been made */ + TEST_ASSERT_EQUAL(start, next); + TEST_ASSERT_EQUAL(0, interface_stub.init_call); + TEST_ASSERT_EQUAL(0, interface_stub.read_call); + TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); + TEST_ASSERT_EQUAL(0, interface_stub.clear_interrupt_call); + TEST_ASSERT_EQUAL(0, interface_stub.set_interrupt_call); + TEST_ASSERT_EQUAL(0, interface_stub.fire_interrupt_call); + + + /* Insert an event in the past and future */ + ticker_event_t event_past = { 0 }; + const timestamp_t event_past_timestamp = suspend_time - 10; + ticker_insert_event_us(&ticker_stub, &event_past, event_past_timestamp, 0); + + ticker_event_t event_future = { 0 }; + const timestamp_t event_future_timestamp = suspend_time + 10; + ticker_insert_event_us(&ticker_stub, &event_future, event_future_timestamp, 0); + + TEST_ASSERT_EQUAL(0, interface_stub.init_call); + TEST_ASSERT_EQUAL(0, interface_stub.read_call); + TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); + TEST_ASSERT_EQUAL(0, interface_stub.clear_interrupt_call); + TEST_ASSERT_EQUAL(0, interface_stub.set_interrupt_call); + TEST_ASSERT_EQUAL(0, interface_stub.fire_interrupt_call); + + /* Resume and verify everything starts again */ + ticker_resume(&ticker_stub); + TEST_ASSERT_EQUAL(suspend_time, queue_stub.present_time); + TEST_ASSERT_EQUAL(1, interface_stub.fire_interrupt_call); +} + static const case_t cases[] = { MAKE_TEST_CASE("ticker initialization", test_ticker_initialization), MAKE_TEST_CASE( @@ -2263,11 +2352,11 @@ static const case_t cases[] = { MAKE_TEST_CASE("ticker read", test_ticker_read), MAKE_TEST_CASE("ticker read overflow", test_ticker_read_overflow), MAKE_TEST_CASE( - "legacy insert event outside overflow range", + "legacy insert event outside overflow range", test_legacy_insert_event_outside_overflow_range ), MAKE_TEST_CASE( - "legacy insert event in overflow range", + "legacy insert event in overflow range", test_legacy_insert_event_in_overflow_range ), MAKE_TEST_CASE( @@ -2280,19 +2369,19 @@ static const case_t cases[] = { "legacy insert event tail", test_legacy_insert_event_tail ), MAKE_TEST_CASE( - "legacy insert event multiple overflow", + "legacy insert event multiple overflow", test_legacy_insert_event_multiple_overflow ), MAKE_TEST_CASE( - "test_legacy_insert_event_multiple_random", + "test_legacy_insert_event_multiple_random", test_legacy_insert_event_multiple_random ), MAKE_TEST_CASE( - "test_insert_event_us_outside_overflow_range", + "test_insert_event_us_outside_overflow_range", test_insert_event_us_outside_overflow_range ), MAKE_TEST_CASE( - "test_insert_event_us_in_overflow_range", + "test_insert_event_us_in_overflow_range", test_insert_event_us_in_overflow_range ), MAKE_TEST_CASE( @@ -2301,7 +2390,7 @@ static const case_t cases[] = { MAKE_TEST_CASE("test_insert_event_us_head", test_insert_event_us_head), MAKE_TEST_CASE("test_insert_event_us_tail", test_insert_event_us_tail), MAKE_TEST_CASE( - "test_insert_event_us_multiple_random", + "test_insert_event_us_multiple_random", test_insert_event_us_multiple_random ), MAKE_TEST_CASE("test_remove_event_tail", test_remove_event_tail), @@ -2310,42 +2399,42 @@ static const case_t cases[] = { MAKE_TEST_CASE("test_remove_random", test_remove_random), MAKE_TEST_CASE("update overflow guard", test_overflow_event_update), MAKE_TEST_CASE( - "update overflow guard in case of spurious interrupt", + "update overflow guard in case of spurious interrupt", test_overflow_event_update_when_spurious_interrupt ), MAKE_TEST_CASE( "test_irq_handler_single_event", test_irq_handler_single_event ), MAKE_TEST_CASE( - "test_irq_handler_single_event_spurious", + "test_irq_handler_single_event_spurious", test_irq_handler_single_event_spurious ), MAKE_TEST_CASE( - "test_irq_handler_multiple_event_multiple_dequeue", + "test_irq_handler_multiple_event_multiple_dequeue", test_irq_handler_multiple_event_multiple_dequeue ), MAKE_TEST_CASE( - "test_irq_handler_multiple_event_single_dequeue_overflow", + "test_irq_handler_multiple_event_single_dequeue_overflow", test_irq_handler_multiple_event_single_dequeue_overflow ), MAKE_TEST_CASE( - "test_irq_handler_multiple_event_single_dequeue", + "test_irq_handler_multiple_event_single_dequeue", test_irq_handler_multiple_event_single_dequeue ), MAKE_TEST_CASE( - "test_irq_handler_insert_immediate_in_irq", + "test_irq_handler_insert_immediate_in_irq", test_irq_handler_insert_immediate_in_irq ), MAKE_TEST_CASE( - "test_irq_handler_insert_non_immediate_in_irq", + "test_irq_handler_insert_non_immediate_in_irq", test_irq_handler_insert_non_immediate_in_irq ), MAKE_TEST_CASE( - "test_set_interrupt_past_time", + "test_set_interrupt_past_time", test_set_interrupt_past_time ), MAKE_TEST_CASE( - "test_set_interrupt_past_time_with_delay", + "test_set_interrupt_past_time_with_delay", test_set_interrupt_past_time_with_delay ), MAKE_TEST_CASE( @@ -2363,6 +2452,10 @@ static const case_t cases[] = { MAKE_TEST_CASE( "test_match_interval_passed_table", test_match_interval_passed_table + ), + MAKE_TEST_CASE( + "test_suspend_resume", + test_suspend_resume ) }; diff --git a/TESTS/mbed_hal/us_ticker/main.cpp b/TESTS/mbed_hal/us_ticker/main.cpp index 0aa8550817b2..c701066f7032 100644 --- a/TESTS/mbed_hal/us_ticker/main.cpp +++ b/TESTS/mbed_hal/us_ticker/main.cpp @@ -29,7 +29,7 @@ using namespace utest::v1; /* Test that the ticker has the correct frequency and number of bits. */ void us_ticker_info_test() { - const ticker_info_t* p_ticker_info = us_ticker_get_info(); + const ticker_info_t *p_ticker_info = us_ticker_get_info(); TEST_ASSERT(p_ticker_info->frequency >= 250000); TEST_ASSERT(p_ticker_info->frequency <= 8000000); diff --git a/TESTS/mbed_platform/FileHandle/TestFile.h b/TESTS/mbed_platform/FileHandle/TestFile.h index 1ec0315c49b0..38e001ad0092 100644 --- a/TESTS/mbed_platform/FileHandle/TestFile.h +++ b/TESTS/mbed_platform/FileHandle/TestFile.h @@ -39,10 +39,9 @@ class TestFile : public FileHandle { ssize_t read; _fnCalled = fnRead; - for(read = 0; (size_t)read < size; read++) - { - if(POS_IS_VALID(_pos)) { - ((uint8_t*)buffer)[read] = _data[_pos++]; + for (read = 0; (size_t)read < size; read++) { + if (POS_IS_VALID(_pos)) { + ((uint8_t *)buffer)[read] = _data[_pos++]; } else { break; } @@ -55,17 +54,16 @@ class TestFile : public FileHandle { ssize_t written; _fnCalled = fnWrite; - for(written = 0; (size_t)written < size; written++) - { - if(NEW_POS_IS_VALID(_pos)) { - _data[_pos++] = ((uint8_t*)buffer)[written]; + for (written = 0; (size_t)written < size; written++) { + if (NEW_POS_IS_VALID(_pos)) { + _data[_pos++] = ((uint8_t *)buffer)[written]; } else { - if(0 == written) { + if (0 == written) { return -ENOSPC; } break; } - if(_end < _pos) { + if (_end < _pos) { _end++; } } // for @@ -77,8 +75,7 @@ class TestFile : public FileHandle { _fnCalled = fnSeek; int32_t new_pos = INVALID_POS; - switch(whence) - { + switch (whence) { case SEEK_SET: new_pos = offset; break; @@ -96,7 +93,7 @@ class TestFile : public FileHandle { break; } - if(SEEK_POS_IS_VALID(new_pos)) { + if (SEEK_POS_IS_VALID(new_pos)) { _pos = new_pos; } else { return -EINVAL; diff --git a/TESTS/mbed_platform/SharedPtr/main.cpp b/TESTS/mbed_platform/SharedPtr/main.cpp new file mode 100644 index 000000000000..3afc936763d6 --- /dev/null +++ b/TESTS/mbed_platform/SharedPtr/main.cpp @@ -0,0 +1,128 @@ +/* mbed Microcontroller Library + * Copyright (c) 2018 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 "mbed.h" +#include "greentea-client/test_env.h" +#include "utest/utest.h" +#include "unity/unity.h" + +#include "platform/SharedPtr.h" + +using utest::v1::Case; + +struct TestStruct { + TestStruct() + { + s_count++; + value = 42; + } + + ~TestStruct() + { + s_count--; + value = 0; + } + + int value; + static int s_count; +}; + +int TestStruct::s_count = 0; + +/** + * Test that a shared pointer correctly manages the lifetime of the underlying raw pointer + */ +void test_single_sharedptr_lifetime() +{ + // Sanity-check value of counter + TEST_ASSERT_EQUAL(0, TestStruct::s_count); + + // Create and destroy shared pointer in given scope + { + SharedPtr s_ptr(new TestStruct); + TEST_ASSERT_EQUAL(1, TestStruct::s_count); + } + + // Destroy shared pointer + TEST_ASSERT_EQUAL(0, TestStruct::s_count); +} + +/** + * Test that multiple instances of shared pointers correctly manage the reference count + * to release the object at the correct point + */ +void test_instance_sharing() +{ + SharedPtr s_ptr1(NULL); + + // Sanity-check value of counter + TEST_ASSERT_EQUAL(0, TestStruct::s_count); + + // Create and destroy shared pointer in given scope + { + SharedPtr s_ptr2(new TestStruct); + TEST_ASSERT_EQUAL(1, TestStruct::s_count); + s_ptr1 = s_ptr2; + TEST_ASSERT_EQUAL(1, TestStruct::s_count); + } + + TEST_ASSERT_EQUAL(1, TestStruct::s_count); + + s_ptr1 = NULL; + + // Destroy shared pointer + TEST_ASSERT_EQUAL(0, TestStruct::s_count); +} + +/** + * Test whether comparison operators operate as expected, both between + * shared pointers managing the same object, + * and a shared pointer and underlying raw pointer + */ +void test_equality_comparators() +{ + TestStruct *raw_ptr1 = new TestStruct; + TestStruct *raw_ptr2 = new TestStruct; + SharedPtr s_ptr1_1(raw_ptr1); + SharedPtr s_ptr1_2 = s_ptr1_1; + SharedPtr s_ptr2(raw_ptr2); + + // Pointers that should be deemed equal + TEST_ASSERT_TRUE(s_ptr1_1 == raw_ptr1); // Shared pointer / Raw pointer + TEST_ASSERT_TRUE(s_ptr1_1 == s_ptr1_2); // Shared pointer / Shared pointer + + // Pointers that should be deemed different + TEST_ASSERT_TRUE(s_ptr1_1 != raw_ptr2); // Shared pointer / Raw pointer + TEST_ASSERT_TRUE(s_ptr1_1 != s_ptr2); // Shared pointer / Shared pointer +} + +utest::v1::status_t test_setup(const size_t number_of_cases) +{ + GREENTEA_SETUP(10, "default_auto"); + return utest::v1::verbose_test_setup_handler(number_of_cases); +} + +Case cases[] = { + Case("Test single shared pointer instance", test_single_sharedptr_lifetime), + Case("Test instance sharing across multiple shared pointers", test_instance_sharing), + Case("Test equality comparators", test_equality_comparators) +}; + +utest::v1::Specification specification(test_setup, cases); + +int main() +{ + return !utest::v1::Harness::run(specification); +} diff --git a/TESTS/mbed_platform/Transaction/main.cpp b/TESTS/mbed_platform/Transaction/main.cpp index 0b2029be73d6..46eb5768bef2 100644 --- a/TESTS/mbed_platform/Transaction/main.cpp +++ b/TESTS/mbed_platform/Transaction/main.cpp @@ -23,7 +23,7 @@ using utest::v1::Case; static void dummy_callback(int) { - /* do nothing. */ + /* do nothing. */ } /** Test Transaction class - creation with initialisation @@ -43,7 +43,7 @@ void test_Transaction_init() const uint8_t word_width = 8; unsigned char tx_buffer[tx_buffer_size]; unsigned char rx_buffer[rx_buffer_size]; - const event_callback_t& callback = dummy_callback; + const event_callback_t &callback = dummy_callback; transaction_t transaction_data = { tx_buffer, tx_buffer_size, rx_buffer, rx_buffer_size, event_id, callback, word_width }; @@ -51,8 +51,8 @@ void test_Transaction_init() TEST_ASSERT_EQUAL(&object, test_transaction.get_object()); - TEST_ASSERT_EQUAL((void*)tx_buffer, test_transaction.get_transaction()->tx_buffer); - TEST_ASSERT_EQUAL((void*)rx_buffer, test_transaction.get_transaction()->rx_buffer); + TEST_ASSERT_EQUAL((void *)tx_buffer, test_transaction.get_transaction()->tx_buffer); + TEST_ASSERT_EQUAL((void *)rx_buffer, test_transaction.get_transaction()->rx_buffer); TEST_ASSERT_EQUAL(tx_buffer_size, test_transaction.get_transaction()->tx_length); TEST_ASSERT_EQUAL(rx_buffer_size, test_transaction.get_transaction()->rx_length); TEST_ASSERT_EQUAL(event_id, test_transaction.get_transaction()->event); diff --git a/TESTS/mbed_platform/critical_section/main.cpp b/TESTS/mbed_platform/critical_section/main.cpp index 16054310b656..43ce94c4fcf9 100644 --- a/TESTS/mbed_platform/critical_section/main.cpp +++ b/TESTS/mbed_platform/critical_section/main.cpp @@ -38,7 +38,7 @@ void critical_section_raii_recursive(Timeout &timeout) depth++; TEST_ASSERT_TRUE(core_util_in_critical_section()); - if(depth < N) { + if (depth < N) { critical_section_raii_recursive(timeout); } else { // max depth reached - do the test @@ -87,7 +87,7 @@ void test_C_API(void) wait_us(wait_time_us); TEST_ASSERT_TRUE(callback_called); - for(int i = 0; i < N; i++) { + for (int i = 0; i < N; i++) { core_util_critical_section_enter(); TEST_ASSERT_TRUE(core_util_in_critical_section()); } @@ -98,7 +98,7 @@ void test_C_API(void) TEST_ASSERT_FALSE(callback_called); TEST_ASSERT_TRUE(core_util_in_critical_section()); - for(int i = 0; i < N - 1; i++) { + for (int i = 0; i < N - 1; i++) { core_util_critical_section_exit(); TEST_ASSERT_TRUE(core_util_in_critical_section()); TEST_ASSERT_FALSE(callback_called); @@ -184,7 +184,7 @@ void test_CPP_API_enable_disable(void) wait_us(wait_time_us); TEST_ASSERT_TRUE(callback_called); - for(int i = 0; i < N; i++) { + for (int i = 0; i < N; i++) { CriticalSectionLock::enable(); TEST_ASSERT_TRUE(core_util_in_critical_section()); } @@ -195,7 +195,7 @@ void test_CPP_API_enable_disable(void) TEST_ASSERT_FALSE(callback_called); TEST_ASSERT_TRUE(core_util_in_critical_section()); - for(int i = 0; i < N - 1; i++) { + for (int i = 0; i < N - 1; i++) { CriticalSectionLock::disable(); TEST_ASSERT_TRUE(core_util_in_critical_section()); TEST_ASSERT_FALSE(callback_called); diff --git a/TESTS/mbed_platform/error_handling/main.cpp b/TESTS/mbed_platform/error_handling/main.cpp index 55debe261492..ca7602a1ce92 100644 --- a/TESTS/mbed_platform/error_handling/main.cpp +++ b/TESTS/mbed_platform/error_handling/main.cpp @@ -28,20 +28,20 @@ using utest::v1::Case; void test_error_count_and_reset() { int count = 7; - + //Log multiple errors and get the error count and make sure its 15 - for(int i=0; ithread_addr, error_ctx.thread_entry_address); @@ -134,7 +134,7 @@ void test_error_context_capture() TEST_ASSERT_EQUAL_UINT((uint32_t)current_thread->stack_mem, error_ctx.thread_stack_mem); #if MBED_CONF_PLATFORM_ERROR_FILENAME_CAPTURE_ENABLED TEST_ASSERT_EQUAL_STRING(MBED_FILENAME, error_ctx.error_filename); -#endif +#endif } #if MBED_CONF_PLATFORM_ERROR_HIST_ENABLED @@ -143,67 +143,68 @@ void test_error_context_capture() void test_error_logging() { mbed_error_ctx error_ctx = {0}; - + //clear the current errors first mbed_clear_all_errors(); - + //log 3 errors and retrieve them to ensure they are correct - MBED_WARNING1(MBED_ERROR_INVALID_ARGUMENT, "Invalid argument", 1 ); - MBED_WARNING1(MBED_ERROR_INVALID_SIZE, "Invalid size", 2 ); - MBED_WARNING1(MBED_ERROR_INVALID_FORMAT, "Invalid format", 3 ); - - mbed_error_status_t status = mbed_get_error_hist_info( 0, &error_ctx ); + MBED_WARNING1(MBED_ERROR_INVALID_ARGUMENT, "Invalid argument", 1); + MBED_WARNING1(MBED_ERROR_INVALID_SIZE, "Invalid size", 2); + MBED_WARNING1(MBED_ERROR_INVALID_FORMAT, "Invalid format", 3); + + mbed_error_status_t status = mbed_get_error_hist_info(0, &error_ctx); TEST_ASSERT_EQUAL_UINT(MBED_ERROR_INVALID_ARGUMENT, error_ctx.error_status); TEST_ASSERT_EQUAL_UINT(1, error_ctx.error_value); - - status = mbed_get_error_hist_info( 1, &error_ctx ); + + status = mbed_get_error_hist_info(1, &error_ctx); TEST_ASSERT_EQUAL_UINT(MBED_ERROR_INVALID_SIZE, error_ctx.error_status); TEST_ASSERT_EQUAL_UINT(2, error_ctx.error_value); - - status = mbed_get_error_hist_info( 2, &error_ctx ); + + status = mbed_get_error_hist_info(2, &error_ctx); TEST_ASSERT_EQUAL_UINT(MBED_ERROR_INVALID_FORMAT, error_ctx.error_status); TEST_ASSERT_EQUAL_UINT(3, error_ctx.error_value); - + //Log a bunch of errors to overflow the error log and retrieve them - MBED_WARNING1(MBED_ERROR_INVALID_ARGUMENT, "Invalid argument", 6 ); - MBED_WARNING1(MBED_ERROR_INVALID_SIZE, "Invalid size", 7 ); - MBED_WARNING1(MBED_ERROR_INVALID_FORMAT, "Invalid format", 8 ); - MBED_WARNING1(MBED_ERROR_NOT_READY, "Not ready error", 9 ); - + MBED_WARNING1(MBED_ERROR_INVALID_ARGUMENT, "Invalid argument", 6); + MBED_WARNING1(MBED_ERROR_INVALID_SIZE, "Invalid size", 7); + MBED_WARNING1(MBED_ERROR_INVALID_FORMAT, "Invalid format", 8); + MBED_WARNING1(MBED_ERROR_NOT_READY, "Not ready error", 9); + //Last 4 entries - MBED_WARNING1(MBED_ERROR_TIME_OUT, "Timeout error", 10 ); - MBED_WARNING1(MBED_ERROR_ALREADY_IN_USE, "Already in use error", 11 ); - MBED_WARNING1(MBED_ERROR_UNSUPPORTED, "Not supported", 12 ); - MBED_WARNING1(MBED_ERROR_ACCESS_DENIED, "Access denied", 13 ); - - status = mbed_get_error_hist_info( 0, &error_ctx ); + MBED_WARNING1(MBED_ERROR_TIME_OUT, "Timeout error", 10); + MBED_WARNING1(MBED_ERROR_ALREADY_IN_USE, "Already in use error", 11); + MBED_WARNING1(MBED_ERROR_UNSUPPORTED, "Not supported", 12); + MBED_WARNING1(MBED_ERROR_ACCESS_DENIED, "Access denied", 13); + + status = mbed_get_error_hist_info(0, &error_ctx); TEST_ASSERT_EQUAL_UINT(MBED_ERROR_TIME_OUT, error_ctx.error_status); TEST_ASSERT_EQUAL_UINT(10, error_ctx.error_value); - - status = mbed_get_error_hist_info( 1, &error_ctx ); + + status = mbed_get_error_hist_info(1, &error_ctx); TEST_ASSERT_EQUAL_UINT(MBED_ERROR_ALREADY_IN_USE, error_ctx.error_status); TEST_ASSERT_EQUAL_UINT(11, error_ctx.error_value); - - status = mbed_get_error_hist_info( 2, &error_ctx ); + + status = mbed_get_error_hist_info(2, &error_ctx); TEST_ASSERT_EQUAL_UINT(MBED_ERROR_UNSUPPORTED, error_ctx.error_status); TEST_ASSERT_EQUAL_UINT(12, error_ctx.error_value); - - status = mbed_get_error_hist_info( 3, &error_ctx ); + + status = mbed_get_error_hist_info(3, &error_ctx); TEST_ASSERT_EQUAL_UINT(MBED_ERROR_ACCESS_DENIED, error_ctx.error_status); TEST_ASSERT_EQUAL_UINT(13, error_ctx.error_value); - + //Try an index which is invalid, we should get ERROR_INVALID_ARGUMENT back - status = mbed_get_error_hist_info( 99, &error_ctx ); + status = mbed_get_error_hist_info(99, &error_ctx); TEST_ASSERT_EQUAL_UINT(MBED_ERROR_INVALID_ARGUMENT, status); - + } #define NUM_TEST_THREADS 5 +#define THREAD_STACK_SIZE 512 //Error logger threads void err_thread_func(mbed_error_status_t *error_status) { - MBED_WARNING1(*error_status, "Error from Multi-Threaded error logging test", *error_status ); + MBED_WARNING1(*error_status, "Error from Multi-Threaded error logging test", *error_status); } @@ -211,31 +212,35 @@ void err_thread_func(mbed_error_status_t *error_status) */ void test_error_logging_multithread() { + uint8_t *dummy = new (std::nothrow) uint8_t[NUM_TEST_THREADS * THREAD_STACK_SIZE]; + TEST_SKIP_UNLESS_MESSAGE(dummy, "Not enough memory for test"); + delete[] dummy; + mbed_error_ctx error_ctx = {0}; - int i=0; + int i; Thread *errThread[NUM_TEST_THREADS]; - mbed_error_status_t error_status[NUM_TEST_THREADS] = { - MBED_ERROR_INVALID_ARGUMENT, MBED_ERROR_INVALID_DATA_DETECTED, MBED_ERROR_INVALID_FORMAT, MBED_ERROR_INVALID_SIZE, MBED_ERROR_INVALID_OPERATION + mbed_error_status_t error_status[NUM_TEST_THREADS] = { + MBED_ERROR_INVALID_ARGUMENT, MBED_ERROR_INVALID_DATA_DETECTED, MBED_ERROR_INVALID_FORMAT, MBED_ERROR_INVALID_SIZE, MBED_ERROR_INVALID_OPERATION }; - - - for(; istart(callback(err_thread_func, &error_status[i])); } wait(2.0); - for(i=0; ijoin(); } - - i = mbed_get_error_hist_count()-1; - - for(;i>=0;--i) { - mbed_error_status_t status = mbed_get_error_hist_info( i, &error_ctx ); - if(status != MBED_SUCCESS) { + + i = mbed_get_error_hist_count() - 1; + + for (; i >= 0; --i) { + mbed_error_status_t status = mbed_get_error_hist_info(i, &error_ctx); + if (status != MBED_SUCCESS) { TEST_FAIL(); } - + TEST_ASSERT_EQUAL_UINT((unsigned int)error_ctx.error_value, (unsigned int)error_ctx.error_status); } } @@ -251,13 +256,13 @@ void MyErrorHook(const mbed_error_ctx *error_ctx) */ void test_error_hook() { - if( MBED_SUCCESS != mbed_set_error_hook(MyErrorHook)) { + if (MBED_SUCCESS != mbed_set_error_hook(MyErrorHook)) { TEST_FAIL(); } - + MBED_WARNING1(MBED_ERROR_INVALID_ARGUMENT, "Test for error hook", 1234); int32_t sem_status = callback_sem.wait(5000); - + TEST_ASSERT(sem_status > 0); } @@ -296,42 +301,42 @@ MBED_TEST_SIM_BLOCKDEVICE_DECL; void test_save_error_log() { //Log some errors - MBED_WARNING1(MBED_ERROR_TIME_OUT, "Timeout error", 1 ); - MBED_WARNING1(MBED_ERROR_ALREADY_IN_USE, "Already in use error", 2 ); - MBED_WARNING1(MBED_ERROR_UNSUPPORTED, "Not supported error", 3 ); - MBED_WARNING1(MBED_ERROR_ACCESS_DENIED, "Access denied error", 4 ); - MBED_WARNING1(MBED_ERROR_ITEM_NOT_FOUND, "Not found error", 5 ); - + MBED_WARNING1(MBED_ERROR_TIME_OUT, "Timeout error", 1); + MBED_WARNING1(MBED_ERROR_ALREADY_IN_USE, "Already in use error", 2); + MBED_WARNING1(MBED_ERROR_UNSUPPORTED, "Not supported error", 3); + MBED_WARNING1(MBED_ERROR_ACCESS_DENIED, "Access denied error", 4); + MBED_WARNING1(MBED_ERROR_ITEM_NOT_FOUND, "Not found error", 5); + int error = 0; - + error = MBED_TEST_FILESYSTEM::format(&fd); - if(error < 0) { + if (error < 0) { TEST_FAIL_MESSAGE("Failed formatting"); } - + error = fs.mount(&fd); - if(error < 0) { + if (error < 0) { TEST_FAIL_MESSAGE("Failed mounting fs"); } - - if(MBED_SUCCESS != mbed_save_error_hist("/fs/errors.log")) { + + if (MBED_SUCCESS != mbed_save_error_hist("/fs/errors.log")) { TEST_FAIL_MESSAGE("Failed saving error log"); } - + FILE *error_file = fopen("/fs/errors.log", "r"); - if(error_file == NULL) { + if (error_file == NULL) { TEST_FAIL_MESSAGE("Unable to find error log in fs"); } - + char buff[64] = {0}; - while (!feof(error_file)){ - int size = fread(&buff[0], 1, 15, error_file); - fwrite(&buff[0], 1, size, stdout); + while (!feof(error_file)) { + int size = fread(&buff[0], 1, 15, error_file); + fwrite(&buff[0], 1, size, stdout); } fclose(error_file); - + error = fs.unmount(); - if(error < 0) { + if (error < 0) { TEST_FAIL_MESSAGE("Failed unmounting fs"); } } @@ -351,7 +356,7 @@ Case cases[] = { Case("Test error context capture", test_error_context_capture), #endif //MBED_CONF_RTOS_PRESENT Case("Test error hook", test_error_hook), -#if MBED_CONF_PLATFORM_ERROR_HIST_ENABLED +#if MBED_CONF_PLATFORM_ERROR_HIST_ENABLED Case("Test error logging", test_error_logging), #if MBED_CONF_RTOS_PRESENT Case("Test error handling multi-threaded", test_error_logging_multithread), diff --git a/TESTS/mbed_platform/stats_cpu/main.cpp b/TESTS/mbed_platform/stats_cpu/main.cpp index 077d7199f299..9ae162b245d8 100644 --- a/TESTS/mbed_platform/stats_cpu/main.cpp +++ b/TESTS/mbed_platform/stats_cpu/main.cpp @@ -38,7 +38,7 @@ static int32_t wait_time = 5000; static void busy_thread() { volatile uint64_t i = ~0; - + while (i--) { led1 = !led1; wait_us(wait_time); diff --git a/TESTS/mbed_platform/stats_heap/main.cpp b/TESTS/mbed_platform/stats_heap/main.cpp index b99adead2f1c..2d7d6b27e909 100644 --- a/TESTS/mbed_platform/stats_heap/main.cpp +++ b/TESTS/mbed_platform/stats_heap/main.cpp @@ -23,7 +23,7 @@ #include #if !defined(MBED_HEAP_STATS_ENABLED) - #error [NOT_SUPPORTED] test not supported +#error [NOT_SUPPORTED] test not supported #endif using namespace utest::v1; @@ -33,12 +33,12 @@ using namespace utest::v1; #define ALLOCATION_SIZE_LARGE 700 #define ALLOCATION_SIZE_FAIL (1024 * 1024 *1024) -typedef void* (*malloc_cb_t) (uint32_t size); +typedef void *(*malloc_cb_t)(uint32_t size); -static void* thunk_malloc(uint32_t size); -static void* thunk_calloc_1(uint32_t size); -static void* thunk_calloc_4(uint32_t size); -static void* thunk_realloc(uint32_t size); +static void *thunk_malloc(uint32_t size); +static void *thunk_calloc_1(uint32_t size); +static void *thunk_calloc_4(uint32_t size); +static void *thunk_realloc(uint32_t size); malloc_cb_t malloc_thunk_array[] = { thunk_malloc, @@ -124,23 +124,23 @@ void test_case_allocate_fail() } } -static void* thunk_malloc(uint32_t size) +static void *thunk_malloc(uint32_t size) { return malloc(size); } -static void* thunk_calloc_1(uint32_t size) +static void *thunk_calloc_1(uint32_t size) { return calloc(size / 1, 1); } -static void* thunk_calloc_4(uint32_t size) +static void *thunk_calloc_4(uint32_t size) { return calloc(size / 4, 4); } -static void* thunk_realloc(uint32_t size) +static void *thunk_realloc(uint32_t size) { return realloc(NULL, size); } diff --git a/TESTS/mbed_platform/stats_thread/main.cpp b/TESTS/mbed_platform/stats_thread/main.cpp index 399267f5ee91..f79375db93a4 100644 --- a/TESTS/mbed_platform/stats_thread/main.cpp +++ b/TESTS/mbed_platform/stats_thread/main.cpp @@ -101,7 +101,7 @@ void test_case_multi_threads_blocked() TEST_ASSERT_EQUAL(TEST_STACK_SIZE, stats[i].stack_size); TEST_ASSERT_EQUAL(osPriorityNormal1, stats[i].priority); TEST_ASSERT_EQUAL(osThreadBlocked, stats[i].state); - } else if (0 == strcmp (stats[i].name, "Th1")) { + } else if (0 == strcmp(stats[i].name, "Th1")) { TEST_ASSERT_EQUAL(TEST_STACK_SIZE, stats[i].stack_size); TEST_ASSERT_EQUAL(osPriorityNormal, stats[i].priority); } diff --git a/TESTS/mbedmicro-mbed/attributes/attributes.c b/TESTS/mbedmicro-mbed/attributes/attributes.c index e08f124f0c88..5329b8a3c5e6 100644 --- a/TESTS/mbedmicro-mbed/attributes/attributes.c +++ b/TESTS/mbedmicro-mbed/attributes/attributes.c @@ -9,12 +9,15 @@ MBED_PACKED(struct) TestAttrPackedStruct1 { int x; }; -typedef MBED_PACKED(struct) { +typedef MBED_PACKED(struct) +{ char a; int x; -} TestAttrPackedStruct2; +} +TestAttrPackedStruct2; -int testPacked() { +int testPacked() +{ int failed = 0; if (sizeof(struct TestAttrPackedStruct1) != sizeof(int) + sizeof(char)) { @@ -35,22 +38,23 @@ MBED_ALIGN(16) char c; MBED_ALIGN(8) char d; MBED_ALIGN(16) char e; -int testAlign() { +int testAlign() +{ int failed = 0; - if(((uintptr_t)&a) & 0x7){ + if (((uintptr_t)&a) & 0x7) { failed++; } - if(((uintptr_t)&b) & 0x7){ + if (((uintptr_t)&b) & 0x7) { failed++; } - if(((uintptr_t)&c) & 0xf){ + if (((uintptr_t)&c) & 0xf) { failed++; } - if(((uintptr_t)&d) & 0x7){ + if (((uintptr_t)&d) & 0x7) { failed++; } - if(((uintptr_t)&e) & 0xf){ + if (((uintptr_t)&e) & 0xf) { failed++; } @@ -58,11 +62,13 @@ int testAlign() { } -int testUnused1(MBED_UNUSED int arg) { +int testUnused1(MBED_UNUSED int arg) +{ return 0; } -int testUnused() { +int testUnused() +{ return testUnused1(0); } @@ -70,42 +76,51 @@ int testUnused() { int testWeak1(); int testWeak2(); -MBED_WEAK int testWeak1() { +MBED_WEAK int testWeak1() +{ return 1; } -int testWeak2() { +int testWeak2() +{ return 0; } -int testWeak() { +int testWeak() +{ return testWeak1() | testWeak2(); } -MBED_PURE int testPure1() { +MBED_PURE int testPure1() +{ return 0; } -int testPure() { +int testPure() +{ return testPure1(); } -MBED_FORCEINLINE int testForceInline1() { +MBED_FORCEINLINE int testForceInline1() +{ return 0; } -int testForceInline() { +int testForceInline() +{ return testForceInline1(); } -MBED_NORETURN int testNoReturn1() { +MBED_NORETURN int testNoReturn1() +{ while (1) {} } -int testNoReturn() { +int testNoReturn() +{ if (0) { testNoReturn1(); } @@ -113,7 +128,8 @@ int testNoReturn() { } -int testUnreachable1(int i) { +int testUnreachable1(int i) +{ switch (i) { case 0: return 0; @@ -122,18 +138,20 @@ int testUnreachable1(int i) { MBED_UNREACHABLE; } -int testUnreachable() { +int testUnreachable() +{ return testUnreachable1(0); } MBED_DEPRECATED("this message should not be displayed") -void testDeprecatedUnused(); +void testDeprecatedUnused(); void testDeprecatedUnused() { } MBED_DEPRECATED("this message should be displayed") int testDeprecatedUsed(); -int testDeprecatedUsed() { +int testDeprecatedUsed() +{ return 0; } @@ -143,11 +161,13 @@ void testDeprecatedSinceUnused() { } MBED_DEPRECATED_SINCE("mbed-os-3.14", "this message should be displayed") int testDeprecatedSinceUsed(); -int testDeprecatedSinceUsed() { +int testDeprecatedSinceUsed() +{ return 0; } -int testDeprecated() { +int testDeprecated() +{ return testDeprecatedUsed() + testDeprecatedSinceUsed(); } diff --git a/TESTS/mbedmicro-mbed/attributes/main.cpp b/TESTS/mbedmicro-mbed/attributes/main.cpp index c64c29cba79b..31d014e4ba31 100644 --- a/TESTS/mbedmicro-mbed/attributes/main.cpp +++ b/TESTS/mbedmicro-mbed/attributes/main.cpp @@ -40,11 +40,13 @@ extern "C" { // Test wrapper and test cases for utest template -void test_wrapper() { +void test_wrapper() +{ TEST_ASSERT_UNLESS(F()); } -utest::v1::status_t test_setup(const size_t number_of_cases) { +utest::v1::status_t test_setup(const size_t number_of_cases) +{ GREENTEA_SETUP(5, "default_auto"); return verbose_test_setup_handler(number_of_cases); } @@ -63,6 +65,7 @@ Case cases[] = { Specification specification(test_setup, cases); -int main() { +int main() +{ return !Harness::run(specification); } diff --git a/TESTS/mbedmicro-mbed/attributes/weak.c b/TESTS/mbedmicro-mbed/attributes/weak.c index 4bf279614b4d..7b2f862177a8 100644 --- a/TESTS/mbedmicro-mbed/attributes/weak.c +++ b/TESTS/mbedmicro-mbed/attributes/weak.c @@ -1,10 +1,12 @@ #include "mbed_toolchain.h" -int testWeak1() { +int testWeak1() +{ return 0; } -MBED_WEAK int testWeak2() { +MBED_WEAK int testWeak2() +{ return 1; } diff --git a/TESTS/mbedmicro-mbed/call_before_main/main.cpp b/TESTS/mbedmicro-mbed/call_before_main/main.cpp index 1d6266b7b6fb..c185c5959bd9 100644 --- a/TESTS/mbedmicro-mbed/call_before_main/main.cpp +++ b/TESTS/mbedmicro-mbed/call_before_main/main.cpp @@ -16,15 +16,17 @@ #include "greentea-client/test_env.h" namespace { - bool mbed_main_called = false; +bool mbed_main_called = false; } -extern "C" void mbed_main() { +extern "C" void mbed_main() +{ printf("MBED: mbed_main() call before main()\r\n"); mbed_main_called = true; } -int main() { +int main() +{ GREENTEA_SETUP(5, "default_auto"); printf("MBED: main() starts now!\r\n"); GREENTEA_TESTSUITE_RESULT(mbed_main_called); diff --git a/TESTS/mbedmicro-mbed/cpp/main.cpp b/TESTS/mbedmicro-mbed/cpp/main.cpp index 931748e316bf..5597831f26ed 100644 --- a/TESTS/mbedmicro-mbed/cpp/main.cpp +++ b/TESTS/mbedmicro-mbed/cpp/main.cpp @@ -20,37 +20,43 @@ class Test { private: - const char* name; + const char *name; const int pattern; public: - Test(const char* _name, bool print_message=true) : name(_name), pattern(PATTERN_CHECK_VALUE) { + Test(const char *_name, bool print_message = true) : name(_name), pattern(PATTERN_CHECK_VALUE) + { if (print_message) { print("init"); } } - void print(const char *message) { + void print(const char *message) + { printf("%s::%s\n", name, message); } - bool check_init(void) { + bool check_init(void) + { bool result = (pattern == PATTERN_CHECK_VALUE); print(result ? "check_init: OK" : "check_init: ERROR"); return result; } - void stack_test(void) { + void stack_test(void) + { print("stack_test"); Test t("Stack"); t.hello(); } - void hello(void) { + void hello(void) + { print("hello"); } - ~Test() { + ~Test() + { print("destroy"); } }; @@ -70,17 +76,16 @@ Heap::init Heap::hello Heap::destroy *******************/ -int main (void) { +int main(void) +{ GREENTEA_SETUP(10, "default_auto"); bool result = true; - for (;;) - { + for (;;) { s.print("init"); // Global stack object simple test s.stack_test(); - if (s.check_init() == false) - { + if (s.check_init() == false) { result = false; break; } @@ -89,8 +94,7 @@ int main (void) { Test *m = new Test("Heap"); m->hello(); - if (m->check_init() == false) - { + if (m->check_init() == false) { result = false; } delete m; diff --git a/TESTS/mbedmicro-mbed/div/main.cpp b/TESTS/mbedmicro-mbed/div/main.cpp index 1e9fc4cd5891..05a018b59ae2 100644 --- a/TESTS/mbedmicro-mbed/div/main.cpp +++ b/TESTS/mbedmicro-mbed/div/main.cpp @@ -17,7 +17,8 @@ #include "mbed.h" #include "greentea-client/test_env.h" -uint32_t test_64(uint64_t ticks) { +uint32_t test_64(uint64_t ticks) +{ ticks >>= 3; // divide by 8 if (ticks > 0xFFFFFFFF) { ticks /= 3; @@ -27,16 +28,19 @@ uint32_t test_64(uint64_t ticks) { return (uint32_t)(0xFFFFFFFF & ticks); } -const char *result_str(bool result) { +const char *result_str(bool result) +{ return result ? "[OK]" : "[FAIL]"; } -int main() { +int main() +{ GREENTEA_SETUP(5, "default_auto"); bool result = true; - { // 0xFFFFFFFF * 8 = 0x7fffffff8 + { + // 0xFFFFFFFF * 8 = 0x7fffffff8 std::pair values = std::make_pair(0x55555555, 0x7FFFFFFF8); uint32_t test_ret = test_64(values.second); bool test_res = values.first == test_ret; @@ -44,7 +48,8 @@ int main() { printf("64bit: 0x7FFFFFFF8: expected 0x%lX got 0x%lX ... %s\r\n", values.first, test_ret, result_str(test_res)); } - { // 0xFFFFFFFF * 24 = 0x17ffffffe8 + { + // 0xFFFFFFFF * 24 = 0x17ffffffe8 std::pair values = std::make_pair(0xFFFFFFFF, 0x17FFFFFFE8); uint32_t test_ret = test_64(values.second); bool test_res = values.first == test_ret; diff --git a/TESTS/mbedmicro-mbed/static_assert/main.cpp b/TESTS/mbedmicro-mbed/static_assert/main.cpp index 844a60aff442..dd963e0c25b7 100644 --- a/TESTS/mbedmicro-mbed/static_assert/main.cpp +++ b/TESTS/mbedmicro-mbed/static_assert/main.cpp @@ -25,7 +25,8 @@ using namespace utest::v1; void no_test() {} -utest::v1::status_t test_setup(const size_t number_of_cases) { +utest::v1::status_t test_setup(const size_t number_of_cases) +{ GREENTEA_SETUP(5, "default_auto"); return verbose_test_setup_handler(number_of_cases); } @@ -36,6 +37,7 @@ Case cases[] = { Specification specification(test_setup, cases); -int main() { +int main() +{ return !Harness::run(specification); } diff --git a/TESTS/mbedmicro-mbed/static_assert/test_c.c b/TESTS/mbedmicro-mbed/static_assert/test_c.c index e0f9923415aa..b908a2e872db 100644 --- a/TESTS/mbedmicro-mbed/static_assert/test_c.c +++ b/TESTS/mbedmicro-mbed/static_assert/test_c.c @@ -6,34 +6,35 @@ // Test for static asserts in global context MBED_STATIC_ASSERT(sizeof(int) >= sizeof(char), - "An int must be larger than char"); + "An int must be larger than char"); MBED_STATIC_ASSERT(2 + 2 == 4, - "Hopefully the universe is mathematically consistent"); + "Hopefully the universe is mathematically consistent"); MBED_STATIC_ASSERT(THE_ANSWER == 42, - "Said Deep Thought, with infinite majesty and calm"); + "Said Deep Thought, with infinite majesty and calm"); struct test { int dummy; // Test for static asserts in struct context MBED_STRUCT_STATIC_ASSERT(sizeof(int) >= sizeof(char), - "An int must be larger than char"); + "An int must be larger than char"); MBED_STRUCT_STATIC_ASSERT(2 + 2 == 4, - "Hopefully the universe is mathematically consistent"); + "Hopefully the universe is mathematically consistent"); MBED_STRUCT_STATIC_ASSERT(THE_ANSWER == 42, - "Said Deep Thought, with infinite majesty and calm"); + "Said Deep Thought, with infinite majesty and calm"); }; MBED_STATIC_ASSERT(sizeof(struct test) == sizeof(int), - "Static assertions should not change the size of a struct"); + "Static assertions should not change the size of a struct"); -void doit_c(void) { +void doit_c(void) +{ // Test for static asserts in function context MBED_STATIC_ASSERT(sizeof(int) >= sizeof(char), - "An int must be larger than char"); + "An int must be larger than char"); MBED_STATIC_ASSERT(2 + 2 == 4, - "Hopefully the universe is mathematically consistent"); + "Hopefully the universe is mathematically consistent"); MBED_STATIC_ASSERT(THE_ANSWER == 42, - "Said Deep Thought, with infinite majesty and calm"); + "Said Deep Thought, with infinite majesty and calm"); } diff --git a/TESTS/mbedmicro-mbed/static_assert/test_cpp.cpp b/TESTS/mbedmicro-mbed/static_assert/test_cpp.cpp index 05741d321585..2bff2780cb97 100644 --- a/TESTS/mbedmicro-mbed/static_assert/test_cpp.cpp +++ b/TESTS/mbedmicro-mbed/static_assert/test_cpp.cpp @@ -6,41 +6,42 @@ // Test for static asserts in global context MBED_STATIC_ASSERT(sizeof(int) >= sizeof(char), - "An int must be larger than char"); + "An int must be larger than char"); MBED_STATIC_ASSERT(2 + 2 == 4, - "Hopefully the universe is mathematically consistent"); + "Hopefully the universe is mathematically consistent"); MBED_STATIC_ASSERT(THE_ANSWER == 42, - "Said Deep Thought, with infinite majesty and calm"); + "Said Deep Thought, with infinite majesty and calm"); struct test { int dummy; // Test for static asserts in struct context MBED_STRUCT_STATIC_ASSERT(sizeof(int) >= sizeof(char), - "An int must be larger than char"); + "An int must be larger than char"); MBED_STRUCT_STATIC_ASSERT(2 + 2 == 4, - "Hopefully the universe is mathematically consistent"); + "Hopefully the universe is mathematically consistent"); MBED_STRUCT_STATIC_ASSERT(THE_ANSWER == 42, - "Said Deep Thought, with infinite majesty and calm"); + "Said Deep Thought, with infinite majesty and calm"); MBED_STATIC_ASSERT(sizeof(int) >= sizeof(char), - "An int must be larger than char"); + "An int must be larger than char"); MBED_STATIC_ASSERT(2 + 2 == 4, - "Hopefully the universe is mathematically consistent"); + "Hopefully the universe is mathematically consistent"); MBED_STATIC_ASSERT(THE_ANSWER == 42, - "Said Deep Thought, with infinite majesty and calm"); + "Said Deep Thought, with infinite majesty and calm"); }; MBED_STATIC_ASSERT(sizeof(struct test) == sizeof(int), - "Static assertions should not change the size of a struct"); + "Static assertions should not change the size of a struct"); -void doit_c(void) { +void doit_c(void) +{ // Test for static asserts in function context MBED_STATIC_ASSERT(sizeof(int) >= sizeof(char), - "An int must be larger than char"); + "An int must be larger than char"); MBED_STATIC_ASSERT(2 + 2 == 4, - "Hopefully the universe is mathematically consistent"); + "Hopefully the universe is mathematically consistent"); MBED_STATIC_ASSERT(THE_ANSWER == 42, - "Said Deep Thought, with infinite majesty and calm"); + "Said Deep Thought, with infinite majesty and calm"); } diff --git a/TESTS/mbedmicro-rtos-mbed/CircularBuffer/main.cpp b/TESTS/mbedmicro-rtos-mbed/CircularBuffer/main.cpp index bc7e0c6d7819..418194fc37cd 100644 --- a/TESTS/mbedmicro-rtos-mbed/CircularBuffer/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/CircularBuffer/main.cpp @@ -23,8 +23,7 @@ using namespace utest::v1; /* Structure for complex type. */ -typedef struct -{ +typedef struct { int a; char b; int c; diff --git a/TESTS/mbedmicro-rtos-mbed/MemoryPool/main.cpp b/TESTS/mbedmicro-rtos-mbed/MemoryPool/main.cpp index 1428d48e9489..30e335873a12 100644 --- a/TESTS/mbedmicro-rtos-mbed/MemoryPool/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/MemoryPool/main.cpp @@ -21,14 +21,12 @@ using namespace utest::v1; /* Enum used to select block allocation method. */ -typedef enum -{ +typedef enum { ALLOC, CALLOC } AllocType; /* Structure for complex block type. */ -typedef struct -{ +typedef struct { int a; char b; int c; @@ -75,7 +73,7 @@ template void test_mem_pool_alloc_success(AllocType atype) { MemoryPool mem_pool; - T * p_blocks[numOfEntries]; + T *p_blocks[numOfEntries]; uint32_t i; /* Test alloc()/calloc() methods - try to allocate max number of @@ -121,7 +119,7 @@ template void test_mem_pool_alloc_success_complex(AllocType atype) { MemoryPool mem_pool; - T * p_blocks[numOfEntries]; + T *p_blocks[numOfEntries]; uint32_t i; /* Test alloc()/calloc() methods - try to allocate max number of @@ -164,8 +162,8 @@ template void test_mem_pool_alloc_fail(AllocType atype) { MemoryPool mem_pool; - T * p_blocks[numOfEntries]; - T * p_extra_block; + T *p_blocks[numOfEntries]; + T *p_extra_block; uint32_t i; /* Allocate all available blocks. */ @@ -203,7 +201,7 @@ template void test_mem_pool_free_success(AllocType atype) { MemoryPool mem_pool; - T * p_blocks[numOfEntries]; + T *p_blocks[numOfEntries]; uint32_t i; osStatus status; @@ -243,7 +241,7 @@ template void test_mem_pool_free_realloc_last(AllocType atype) { MemoryPool mem_pool; - T * p_blocks[numOfEntries]; + T *p_blocks[numOfEntries]; uint32_t i; osStatus status; @@ -299,7 +297,7 @@ template void test_mem_pool_free_realloc_last_complex(AllocType atype) { MemoryPool mem_pool; - T * p_blocks[numOfEntries]; + T *p_blocks[numOfEntries]; uint32_t i; osStatus status; @@ -355,7 +353,7 @@ template void test_mem_pool_free_realloc_first(AllocType atype) { MemoryPool mem_pool; - T * p_blocks[numOfEntries]; + T *p_blocks[numOfEntries]; uint32_t i; osStatus status; @@ -411,7 +409,7 @@ template void test_mem_pool_free_realloc_first_complex(AllocType atype) { MemoryPool mem_pool; - T * p_blocks[numOfEntries]; + T *p_blocks[numOfEntries]; uint32_t i; osStatus status; @@ -462,7 +460,7 @@ void test_mem_pool_free_realloc_first_complex(AllocType atype) void test_mem_pool_free_on_freed_block() { MemoryPool mem_pool; - int * p_block; + int *p_block; osStatus status; /* Allocate memory block. */ @@ -518,7 +516,7 @@ void free_block_invalid_parameter() osStatus status; /* Try to free block passing invalid parameter (variable address). */ - status = mem_pool.free(reinterpret_cast(&status)); + status = mem_pool.free(reinterpret_cast(&status)); /* Check operation status. */ TEST_ASSERT_EQUAL(osErrorParameter, status); diff --git a/TESTS/mbedmicro-rtos-mbed/basic/main.cpp b/TESTS/mbedmicro-rtos-mbed/basic/main.cpp index 72aa241931f9..a266fdb51b7e 100644 --- a/TESTS/mbedmicro-rtos-mbed/basic/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/basic/main.cpp @@ -24,7 +24,7 @@ #endif #if !DEVICE_USTICKER - #error [NOT_SUPPORTED] test not supported +#error [NOT_SUPPORTED] test not supported #endif using utest::v1::Case; @@ -100,7 +100,7 @@ void test(void) //get the results from host greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value)); - TEST_ASSERT_EQUAL_STRING_MESSAGE("pass", _key,"Host side script reported a fail..."); + TEST_ASSERT_EQUAL_STRING_MESSAGE("pass", _key, "Host side script reported a fail..."); } Case cases[] = { diff --git a/TESTS/mbedmicro-rtos-mbed/condition_variable/main.cpp b/TESTS/mbedmicro-rtos-mbed/condition_variable/main.cpp index 9d63b20afb3c..3592f0a93ec8 100644 --- a/TESTS/mbedmicro-rtos-mbed/condition_variable/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/condition_variable/main.cpp @@ -20,11 +20,11 @@ #include "rtos.h" #if defined(MBED_RTOS_SINGLE_THREAD) - #error [NOT_SUPPORTED] test not supported +#error [NOT_SUPPORTED] test not supported #endif #if !DEVICE_USTICKER - #error [NOT_SUPPORTED] test not supported +#error [NOT_SUPPORTED] test not supported #endif using namespace utest::v1; diff --git a/TESTS/mbedmicro-rtos-mbed/event_flags/main.cpp b/TESTS/mbedmicro-rtos-mbed/event_flags/main.cpp index c07a0062af60..a519cb165bb7 100644 --- a/TESTS/mbedmicro-rtos-mbed/event_flags/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/event_flags/main.cpp @@ -23,11 +23,11 @@ using utest::v1::Case; #if defined(MBED_RTOS_SINGLE_THREAD) - #error [NOT_SUPPORTED] test not supported +#error [NOT_SUPPORTED] test not supported #endif #if !DEVICE_USTICKER - #error [NOT_SUPPORTED] test not supported +#error [NOT_SUPPORTED] test not supported #endif #if defined(__CORTEX_M23) || defined(__CORTEX_M33) @@ -56,12 +56,13 @@ Semaphore sync_sem(0, 1); * which aborts test program. */ #if defined(MBED_TRAP_ERRORS_ENABLED) && MBED_TRAP_ERRORS_ENABLED -void error(const char* format, ...) { +void error(const char *format, ...) +{ (void) format; } -//Override the set_error function to trap the errors -mbed_error_status_t mbed_error(mbed_error_status_t error_status, const char *error_msg, unsigned int error_value, const char *filename, int line_number) +//Override the set_error function to trap the errors +mbed_error_status_t mbed_error(mbed_error_status_t error_status, const char *error_msg, unsigned int error_value, const char *filename, int line_number) { return MBED_SUCCESS; } @@ -278,7 +279,7 @@ void test_multi_thread_any_timeout(void) EventFlags ef; uint32_t ret; Thread thread(osPriorityNormal, THREAD_STACK_SIZE); - thread.start(callback(send_thread_sync, &ef)); + thread.start(callback(send_thread_sync < FLAG01 | FLAG02 | FLAG03, 1 >, &ef)); for (int i = 0; i <= MAX_FLAG_POS; i++) { uint32_t flag = 1 << i; diff --git a/TESTS/mbedmicro-rtos-mbed/heap_and_stack/main.cpp b/TESTS/mbedmicro-rtos-mbed/heap_and_stack/main.cpp index af6511c25a32..d4334ad6f63e 100644 --- a/TESTS/mbedmicro-rtos-mbed/heap_and_stack/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/heap_and_stack/main.cpp @@ -16,11 +16,11 @@ */ #if defined(TARGET_CORTEX_A) - #error [NOT_SUPPORTED] This function not supported for this target +#error [NOT_SUPPORTED] This function not supported for this target #endif #if !DEVICE_USTICKER - #error [NOT_SUPPORTED] test not supported +#error [NOT_SUPPORTED] test not supported #endif #include @@ -50,7 +50,7 @@ extern uint32_t mbed_stack_isr_size; struct linked_list { - linked_list * next; + linked_list *next; uint8_t data[MALLOC_TEST_SIZE]; }; @@ -90,7 +90,7 @@ static bool rangeinrange(uint32_t addr, uint32_t size, uint32_t start, uint32_t /* * Return true if the region is filled only with the specified value */ -static bool valid_fill(uint8_t * data, uint32_t size, uint8_t fill) +static bool valid_fill(uint8_t *data, uint32_t size, uint8_t fill) { for (uint32_t i = 0; i < size; i++) { if (data[i] != fill) { @@ -104,18 +104,18 @@ static void allocate_and_fill_heap(linked_list *&head) { linked_list *current; - current = (linked_list*) malloc(sizeof(linked_list)); + current = (linked_list *) malloc(sizeof(linked_list)); TEST_ASSERT_NOT_NULL(current); current->next = NULL; - memset((void*) current->data, MALLOC_FILL, sizeof(current->data)); + memset((void *) current->data, MALLOC_FILL, sizeof(current->data)); // Allocate until malloc returns NULL head = current; while (true) { // Allocate - linked_list *temp = (linked_list*) malloc(sizeof(linked_list)); + linked_list *temp = (linked_list *) malloc(sizeof(linked_list)); if (NULL == temp) { break; @@ -126,7 +126,7 @@ static void allocate_and_fill_heap(linked_list *&head) // Init temp->next = NULL; - memset((void*) temp->data, MALLOC_FILL, sizeof(current->data)); + memset((void *) temp->data, MALLOC_FILL, sizeof(current->data)); // Add to list current->next = temp; @@ -137,7 +137,7 @@ static void allocate_and_fill_heap(linked_list *&head) static void check_and_free_heap(linked_list *head, uint32_t &max_allocation_size) { uint32_t total_size = 0; - linked_list * current = head; + linked_list *current = head; while (current != NULL) { total_size += sizeof(linked_list); @@ -145,7 +145,7 @@ static void check_and_free_heap(linked_list *head, uint32_t &max_allocation_size TEST_ASSERT_TRUE_MESSAGE(result, "Memory fill check failed"); - linked_list * next = current->next; + linked_list *next = current->next; free(current); current = next; } @@ -165,7 +165,7 @@ void test_heap_in_range(void) char *initial_heap; // Sanity check malloc - initial_heap = (char*) malloc(1); + initial_heap = (char *) malloc(1); TEST_ASSERT_NOT_NULL(initial_heap); bool result = inrange((uint32_t) initial_heap, mbed_heap_start, mbed_heap_size); @@ -185,7 +185,7 @@ void test_main_stack_in_range(void) mbed_rtos_storage_thread_t *thread = (mbed_rtos_storage_thread_t *) osThreadGetId(); uint32_t psp = __get_PSP(); - uint8_t *stack_mem = (uint8_t*) thread->stack_mem; + uint8_t *stack_mem = (uint8_t *) thread->stack_mem; uint32_t stack_size = thread->stack_size; // PSP stack should be somewhere in the middle diff --git a/TESTS/mbedmicro-rtos-mbed/mail/main.cpp b/TESTS/mbedmicro-rtos-mbed/mail/main.cpp index 47ad767fa8f1..8594c88565c8 100644 --- a/TESTS/mbedmicro-rtos-mbed/mail/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/mail/main.cpp @@ -20,11 +20,11 @@ #include "rtos.h" #if defined(MBED_RTOS_SINGLE_THREAD) - #error [NOT_SUPPORTED] test not supported +#error [NOT_SUPPORTED] test not supported #endif #if !DEVICE_USTICKER - #error [NOT_SUPPORTED] test not supported +#error [NOT_SUPPORTED] test not supported #endif using namespace utest::v1; @@ -74,7 +74,7 @@ void receive_thread(Mail *m) for (uint32_t i = 0; i < queue_size; i++) { osEvent evt = m->get(); if (evt.status == osEventMail) { - mail_t *mail = (mail_t*)evt.value.p; + mail_t *mail = (mail_t *)evt.value.p; const uint8_t id = mail->thread_id; // verify thread id @@ -112,7 +112,7 @@ void test_single_thread_order(void) // mail receive (main thread) osEvent evt = mail_box.get(); if (evt.status == osEventMail) { - mail_t *mail = (mail_t*)evt.value.p; + mail_t *mail = (mail_t *)evt.value.p; const uint8_t id = mail->thread_id; // verify thread id @@ -154,7 +154,7 @@ void test_multi_thread_order(void) // mail receive (main thread) osEvent evt = mail_box.get(); if (evt.status == osEventMail) { - mail_t *mail = (mail_t*)evt.value.p; + mail_t *mail = (mail_t *)evt.value.p; const uint8_t id = mail->thread_id; // verify thread id @@ -351,13 +351,13 @@ void test_order(void) evt = mail_box.get(); TEST_ASSERT_EQUAL(evt.status, osEventMail); - mail1 = (int32_t*)evt.value.p; + mail1 = (int32_t *)evt.value.p; TEST_ASSERT_EQUAL(TEST_VAL1, *mail1); evt = mail_box.get(); TEST_ASSERT_EQUAL(evt.status, osEventMail); - mail2 = (int32_t*)evt.value.p; + mail2 = (int32_t *)evt.value.p; TEST_ASSERT_EQUAL(TEST_VAL2, *mail2); @@ -439,7 +439,7 @@ void test_data_type(void) osEvent evt = mail_box.get(); TEST_ASSERT_EQUAL(evt.status, osEventMail); - mail = (T*)evt.value.p; + mail = (T *)evt.value.p; TEST_ASSERT_EQUAL(TEST_VAL, *mail); diff --git a/TESTS/mbedmicro-rtos-mbed/malloc/main.cpp b/TESTS/mbedmicro-rtos-mbed/malloc/main.cpp index e97e78833c15..a16577b59513 100644 --- a/TESTS/mbedmicro-rtos-mbed/malloc/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/malloc/main.cpp @@ -20,11 +20,11 @@ #if defined(MBED_RTOS_SINGLE_THREAD) - #error [NOT_SUPPORTED] test not supported +#error [NOT_SUPPORTED] test not supported #endif #if !DEVICE_USTICKER - #error [NOT_SUPPORTED] test not supported +#error [NOT_SUPPORTED] test not supported #endif using utest::v1::Case; @@ -138,7 +138,7 @@ void test_zero_allocation(void) void *data = NULL; data = malloc(0); - if(data != NULL) { + if (data != NULL) { free(data); } TEST_ASSERT_MESSAGE(true, "malloc(0) succeed - no undefined behaviour happens"); diff --git a/TESTS/mbedmicro-rtos-mbed/mutex/main.cpp b/TESTS/mbedmicro-rtos-mbed/mutex/main.cpp index 4e07d4b5bb3d..846476c6fffa 100644 --- a/TESTS/mbedmicro-rtos-mbed/mutex/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/mutex/main.cpp @@ -20,11 +20,11 @@ #include "rtos.h" #if defined(MBED_RTOS_SINGLE_THREAD) - #error [NOT_SUPPORTED] test not supported +#error [NOT_SUPPORTED] test not supported #endif #if !DEVICE_USTICKER - #error [NOT_SUPPORTED] test not supported +#error [NOT_SUPPORTED] test not supported #endif using namespace utest::v1; @@ -204,7 +204,7 @@ void test_dual_thread_lock_lock_thread(Mutex *mutex) osStatus stat = mutex->lock(TEST_DELAY); TEST_ASSERT_EQUAL(osErrorTimeout, stat); - TEST_ASSERT_UINT32_WITHIN(5000, TEST_DELAY*1000, timer.read_us()); + TEST_ASSERT_UINT32_WITHIN(5000, TEST_DELAY * 1000, timer.read_us()); } /** Test dual thread lock diff --git a/TESTS/mbedmicro-rtos-mbed/queue/main.cpp b/TESTS/mbedmicro-rtos-mbed/queue/main.cpp index efa5d9a30ea9..b2a1c0257e5b 100644 --- a/TESTS/mbedmicro-rtos-mbed/queue/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/queue/main.cpp @@ -20,7 +20,7 @@ #include "rtos.h" #if defined(MBED_RTOS_SINGLE_THREAD) - #error [NOT_SUPPORTED] test not supported +#error [NOT_SUPPORTED] test not supported #endif #if !DEVICE_USTICKER @@ -38,7 +38,7 @@ template void thread_put_uint_msg(Queue *q) { Thread::wait(ms); - osStatus stat = q->put((uint32_t*) TEST_UINT_MSG); + osStatus stat = q->put((uint32_t *) TEST_UINT_MSG); TEST_ASSERT_EQUAL(osOK, stat); } @@ -61,7 +61,7 @@ void thread_get_uint_msg(Queue *q) void test_pass_uint() { Queue q; - osStatus stat = q.put((uint32_t*)TEST_UINT_MSG); + osStatus stat = q.put((uint32_t *)TEST_UINT_MSG); TEST_ASSERT_EQUAL(osOK, stat); osEvent evt = q.get(); @@ -81,14 +81,14 @@ void test_pass_uint() void test_pass_uint_twice() { Queue q; - osStatus stat = q.put((uint32_t*)TEST_UINT_MSG); + osStatus stat = q.put((uint32_t *)TEST_UINT_MSG); TEST_ASSERT_EQUAL(osOK, stat); osEvent evt = q.get(); TEST_ASSERT_EQUAL(osEventMessage, evt.status); TEST_ASSERT_EQUAL(TEST_UINT_MSG, evt.value.v); - stat = q.put((uint32_t*)TEST_UINT_MSG2); + stat = q.put((uint32_t *)TEST_UINT_MSG2); TEST_ASSERT_EQUAL(osOK, stat); evt = q.get(); @@ -181,10 +181,10 @@ void test_put_full_no_timeout() { Queue q; - osStatus stat = q.put((uint32_t*) TEST_UINT_MSG); + osStatus stat = q.put((uint32_t *) TEST_UINT_MSG); TEST_ASSERT_EQUAL(osOK, stat); - stat = q.put((uint32_t*) TEST_UINT_MSG); + stat = q.put((uint32_t *) TEST_UINT_MSG); TEST_ASSERT_EQUAL(osErrorResource, stat); } @@ -198,13 +198,13 @@ void test_put_full_timeout() { Queue q; - osStatus stat = q.put((uint32_t*) TEST_UINT_MSG, TEST_TIMEOUT); + osStatus stat = q.put((uint32_t *) TEST_UINT_MSG, TEST_TIMEOUT); TEST_ASSERT_EQUAL(osOK, stat); Timer timer; timer.start(); - stat = q.put((uint32_t*) TEST_UINT_MSG, TEST_TIMEOUT); + stat = q.put((uint32_t *) TEST_UINT_MSG, TEST_TIMEOUT); TEST_ASSERT_EQUAL(osErrorTimeout, stat); TEST_ASSERT_UINT32_WITHIN(TEST_TIMEOUT * 100, TEST_TIMEOUT * 1000, timer.read_us()); } @@ -224,12 +224,12 @@ void test_put_full_waitforever() t.start(callback(thread_get_uint_msg, &q)); - osStatus stat = q.put((uint32_t*) TEST_UINT_MSG); + osStatus stat = q.put((uint32_t *) TEST_UINT_MSG); TEST_ASSERT_EQUAL(osOK, stat); Timer timer; timer.start(); - stat = q.put((uint32_t*) TEST_UINT_MSG, osWaitForever); + stat = q.put((uint32_t *) TEST_UINT_MSG, osWaitForever); TEST_ASSERT_EQUAL(osOK, stat); TEST_ASSERT_UINT32_WITHIN(TEST_TIMEOUT * 100, TEST_TIMEOUT * 1000, timer.read_us()); @@ -246,10 +246,10 @@ void test_msg_order() { Queue q; - osStatus stat = q.put((uint32_t*) TEST_UINT_MSG, TEST_TIMEOUT); + osStatus stat = q.put((uint32_t *) TEST_UINT_MSG, TEST_TIMEOUT); TEST_ASSERT_EQUAL(osOK, stat); - stat = q.put((uint32_t*) TEST_UINT_MSG2, TEST_TIMEOUT); + stat = q.put((uint32_t *) TEST_UINT_MSG2, TEST_TIMEOUT); TEST_ASSERT_EQUAL(osOK, stat); osEvent evt = q.get(); @@ -271,10 +271,10 @@ void test_msg_prio() { Queue q; - osStatus stat = q.put((uint32_t*) TEST_UINT_MSG, TEST_TIMEOUT, 0); + osStatus stat = q.put((uint32_t *) TEST_UINT_MSG, TEST_TIMEOUT, 0); TEST_ASSERT_EQUAL(osOK, stat); - stat = q.put((uint32_t*) TEST_UINT_MSG2, TEST_TIMEOUT, 1); + stat = q.put((uint32_t *) TEST_UINT_MSG2, TEST_TIMEOUT, 1); TEST_ASSERT_EQUAL(osOK, stat); osEvent evt = q.get(); @@ -298,7 +298,7 @@ void test_queue_empty() TEST_ASSERT_EQUAL(true, q.empty()); - q.put((uint32_t*) TEST_UINT_MSG, TEST_TIMEOUT, 1); + q.put((uint32_t *) TEST_UINT_MSG, TEST_TIMEOUT, 1); TEST_ASSERT_EQUAL(false, q.empty()); } @@ -315,7 +315,7 @@ void test_queue_full() TEST_ASSERT_EQUAL(false, q.full()); - q.put((uint32_t*) TEST_UINT_MSG, TEST_TIMEOUT, 1); + q.put((uint32_t *) TEST_UINT_MSG, TEST_TIMEOUT, 1); TEST_ASSERT_EQUAL(true, q.full()); } diff --git a/TESTS/mbedmicro-rtos-mbed/rtostimer/main.cpp b/TESTS/mbedmicro-rtos-mbed/rtostimer/main.cpp index 12baae3b65ea..cf81729f722f 100644 --- a/TESTS/mbedmicro-rtos-mbed/rtostimer/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/rtostimer/main.cpp @@ -31,7 +31,7 @@ using namespace utest::v1; #endif #if !DEVICE_USTICKER - #error [NOT_SUPPORTED] test not supported +#error [NOT_SUPPORTED] test not supported #endif class Stopwatch: public Timer { @@ -40,7 +40,7 @@ class Stopwatch: public Timer { public: Stopwatch() : - Timer(), _sem(1) + Timer(), _sem(1) { } @@ -85,12 +85,12 @@ void sem_callback(Semaphore *sem) * which aborts test program. */ #if defined(MBED_TRAP_ERRORS_ENABLED) && MBED_TRAP_ERRORS_ENABLED -void error(const char* format, ...) +void error(const char *format, ...) { (void) format; } -mbed_error_status_t mbed_error(mbed_error_status_t error_status, const char *error_msg, unsigned int error_value, const char *filename, int line_number) +mbed_error_status_t mbed_error(mbed_error_status_t error_status, const char *error_msg, unsigned int error_value, const char *filename, int line_number) { return MBED_SUCCESS; } diff --git a/TESTS/mbedmicro-rtos-mbed/semaphore/main.cpp b/TESTS/mbedmicro-rtos-mbed/semaphore/main.cpp index 7e23c1f6091e..69c92fdbcfbf 100644 --- a/TESTS/mbedmicro-rtos-mbed/semaphore/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/semaphore/main.cpp @@ -22,11 +22,11 @@ using namespace utest::v1; #if defined(MBED_RTOS_SINGLE_THREAD) - #error [NOT_SUPPORTED] test not supported +#error [NOT_SUPPORTED] test not supported #endif #if !DEVICE_USTICKER - #error [NOT_SUPPORTED] test not supported +#error [NOT_SUPPORTED] test not supported #endif #define THREAD_DELAY 30 @@ -204,7 +204,7 @@ void test_multiple_tokens_wait() { Semaphore sem(5); - for(int i = 5; i >= 0; i--) { + for (int i = 5; i >= 0; i--) { int32_t cnt = sem.wait(0); TEST_ASSERT_EQUAL(i, cnt); } @@ -220,7 +220,7 @@ void test_multiple_tokens_release() { Semaphore sem(0, 5); - for(int i = 5; i > 0; i--) { + for (int i = 5; i > 0; i--) { osStatus stat = sem.release(); TEST_ASSERT_EQUAL(osOK, stat); } diff --git a/TESTS/mbedmicro-rtos-mbed/signals/main.cpp b/TESTS/mbedmicro-rtos-mbed/signals/main.cpp index 2e66b5d86dbd..cd852b2ef09c 100644 --- a/TESTS/mbedmicro-rtos-mbed/signals/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/signals/main.cpp @@ -21,11 +21,11 @@ using utest::v1::Case; #if defined(MBED_RTOS_SINGLE_THREAD) - #error [NOT_SUPPORTED] test not supported +#error [NOT_SUPPORTED] test not supported #endif #if !DEVICE_USTICKER - #error [NOT_SUPPORTED] test not supported +#error [NOT_SUPPORTED] test not supported #endif #define TEST_STACK_SIZE 512 @@ -55,11 +55,12 @@ struct Sync { * which aborts test program. */ #if defined(MBED_TRAP_ERRORS_ENABLED) && MBED_TRAP_ERRORS_ENABLED -void error(const char* format, ...) { +void error(const char *format, ...) +{ (void) format; } -mbed_error_status_t mbed_error(mbed_error_status_t error_status, const char *error_msg, unsigned int error_value, const char *filename, int line_number) +mbed_error_status_t mbed_error(mbed_error_status_t error_status, const char *error_msg, unsigned int error_value, const char *filename, int line_number) { return MBED_SUCCESS; } @@ -364,7 +365,7 @@ void test_set_double(void) Semaphore sem(0, 1); Thread t(osPriorityNormal, TEST_STACK_SIZE); - t.start(callback(run_release_signal_wait, &sem)); + t.start(callback(run_release_signal_wait < SIGNAL1 | SIGNAL2 | SIGNAL3, osWaitForever, osEventSignal >, &sem)); sem.wait(); TEST_ASSERT_EQUAL(Thread::WaitingThreadFlag, t.get_state()); diff --git a/TESTS/mbedmicro-rtos-mbed/systimer/main.cpp b/TESTS/mbedmicro-rtos-mbed/systimer/main.cpp index e1e474d6d4d4..8a25ad287193 100644 --- a/TESTS/mbedmicro-rtos-mbed/systimer/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/systimer/main.cpp @@ -53,12 +53,12 @@ class SysTimerTest: public rtos::internal::SysTimer { public: SysTimerTest() : - SysTimer(), _sem(0, 1) + SysTimer(), _sem(0, 1) { } SysTimerTest(const ticker_data_t *data) : - SysTimer(data), _sem(0, 1) + SysTimer(data), _sem(0, 1) { } @@ -99,6 +99,10 @@ void mock_ticker_fire_interrupt() { } +void mock_ticker_free() +{ +} + const ticker_info_t *mock_ticker_get_info() { static const ticker_info_t mock_ticker_info = { @@ -115,6 +119,7 @@ ticker_interface_t mock_ticker_interface = { .clear_interrupt = mock_ticker_clear_interrupt, .set_interrupt = mock_ticker_set_interrupt, .fire_interrupt = mock_ticker_fire_interrupt, + .free = mock_ticker_free, .get_info = mock_ticker_get_info, }; @@ -308,7 +313,7 @@ void test_deepsleep(void) lptimer.start(); st.schedule_tick(TEST_TICKS); - TEST_ASSERT_TRUE_MESSAGE(sleep_manager_can_deep_sleep(), "Deep sleep should be allowed"); + TEST_ASSERT_TRUE_MESSAGE(sleep_manager_can_deep_sleep_test_check(), "Deep sleep should be allowed"); while (st.sem_wait(0) != 1) { sleep(); } diff --git a/TESTS/mbedmicro-rtos-mbed/threads/LockGuard.h b/TESTS/mbedmicro-rtos-mbed/threads/LockGuard.h index 1db706310911..fd5fd6571974 100644 --- a/TESTS/mbedmicro-rtos-mbed/threads/LockGuard.h +++ b/TESTS/mbedmicro-rtos-mbed/threads/LockGuard.h @@ -31,21 +31,23 @@ class LockGuard { * Construct a LockGuard instance and ackire ownership of mutex in input. * @param mutex The mutex to ackire ownership of. */ - LockGuard(rtos::Mutex& mutex) : _mutex(mutex) { + LockGuard(rtos::Mutex &mutex) : _mutex(mutex) + { _mutex.lock(); } /** * Destruct the lock and release the inner mutex. */ - ~LockGuard() { + ~LockGuard() + { _mutex.unlock(); } private: - LockGuard(const LockGuard&); - LockGuard& operator=(const LockGuard&); - rtos::Mutex& _mutex; + LockGuard(const LockGuard &); + LockGuard &operator=(const LockGuard &); + rtos::Mutex &_mutex; }; #endif /* MBEDMICRO_RTOS_MBED_THREADS_LOCK_GUARD */ diff --git a/TESTS/mbedmicro-rtos-mbed/threads/SynchronizedIntegral.h b/TESTS/mbedmicro-rtos-mbed/threads/SynchronizedIntegral.h index a7b66255301f..afb3ce0ef42c 100644 --- a/TESTS/mbedmicro-rtos-mbed/threads/SynchronizedIntegral.h +++ b/TESTS/mbedmicro-rtos-mbed/threads/SynchronizedIntegral.h @@ -31,37 +31,43 @@ class SynchronizedIntegral { SynchronizedIntegral(T value) : _mutex(), _value(value) { } // preincrement operator - T operator++() { + T operator++() + { LockGuard lock(_mutex); return ++_value; } // predecrement operator - T operator--() { + T operator--() + { LockGuard lock(_mutex); return --_value; } // post increment operator - T operator++(int) { + T operator++(int) + { LockGuard lock(_mutex); return _value++; } // post decrement operator - T operator--(int) { + T operator--(int) + { LockGuard lock(_mutex); return _value--; } // conversion operator, used also for <,>,<=,>=,== and != - operator T() const { + operator T() const + { LockGuard lock(_mutex); return _value; } // access to the internal mutex - rtos::Mutex& internal_mutex() { + rtos::Mutex &internal_mutex() + { return _mutex; } diff --git a/TESTS/mbedmicro-rtos-mbed/threads/main.cpp b/TESTS/mbedmicro-rtos-mbed/threads/main.cpp index e58981c0e409..5575ce652256 100644 --- a/TESTS/mbedmicro-rtos-mbed/threads/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/threads/main.cpp @@ -22,11 +22,11 @@ #include "LockGuard.h" #if defined(MBED_RTOS_SINGLE_THREAD) - #error [NOT_SUPPORTED] test not supported +#error [NOT_SUPPORTED] test not supported #endif #if !DEVICE_USTICKER - #error [NOT_SUPPORTED] test not supported +#error [NOT_SUPPORTED] test not supported #endif #define THREAD_STACK_SIZE 512 @@ -52,42 +52,66 @@ class ParallelThread : public Thread { }; // Tasks with different functions to test on threads -void increment(counter_t* counter) { +void increment(counter_t *counter) +{ (*counter)++; } -void increment_with_yield(counter_t* counter) { +void increment_with_yield(counter_t *counter) +{ Thread::yield(); (*counter)++; } -void increment_with_wait(counter_t* counter) { +void increment_with_wait(counter_t *counter) +{ Thread::wait(100); (*counter)++; } -void increment_with_child(counter_t* counter) { - Thread *child = new Thread(osPriorityNormal, CHILD_THREAD_STACK_SIZE); +void increment_with_child(counter_t *counter) +{ + Thread *child = new (std::nothrow) Thread(osPriorityNormal, CHILD_THREAD_STACK_SIZE); + char *dummy = new (std::nothrow) char[CHILD_THREAD_STACK_SIZE]; + delete[] dummy; + + // Don't fail test due to lack of memory. Call function directly instead + if (!child || !dummy) { + increment(counter); + delete child; + return; + } child->start(callback(increment, counter)); child->join(); delete child; } -void increment_with_murder(counter_t* counter) { +void increment_with_murder(counter_t *counter) +{ { // take ownership of the counter mutex so it prevent the child to // modify counter. LockGuard lock(counter->internal_mutex()); - Thread *child = new Thread(osPriorityNormal, CHILD_THREAD_STACK_SIZE); + Thread *child = new (std::nothrow) Thread(osPriorityNormal, CHILD_THREAD_STACK_SIZE); + char *dummy = new (std::nothrow) char[CHILD_THREAD_STACK_SIZE]; + delete[] dummy; + + // Don't fail test due to lack of memory. + if (!child || !dummy) { + delete child; + goto end; + } child->start(callback(increment, counter)); child->terminate(); delete child; } +end: (*counter)++; } -void self_terminate(Thread *self) { +void self_terminate(Thread *self) +{ self->terminate(); // Code should not get here TEST_ASSERT(0); @@ -126,7 +150,12 @@ void self_terminate(Thread *self) { then the final value of the counter is equal to 1 */ template -void test_single_thread() { +void test_single_thread() +{ + char *dummy = new (std::nothrow) char[THREAD_STACK_SIZE]; + delete[] dummy; + TEST_SKIP_UNLESS_MESSAGE(dummy, "Not enough memory to run test"); + counter_t counter(0); Thread thread(osPriorityNormal, THREAD_STACK_SIZE); thread.start(callback(F, &counter)); @@ -165,7 +194,12 @@ void test_single_thread() { then the final value of the counter is equal to number of parallel threads */ template -void test_parallel_threads() { +void test_parallel_threads() +{ + char *dummy = new (std::nothrow) char[PARALLEL_THREAD_STACK_SIZE * N]; + delete[] dummy; + TEST_SKIP_UNLESS_MESSAGE(dummy, "Not enough memory to run test"); + counter_t counter(0); ParallelThread threads[N]; @@ -211,8 +245,12 @@ void test_parallel_threads() { then the final value of the counter is equal to number of serial threads */ template -void test_serial_threads() { +void test_serial_threads() +{ counter_t counter(0); + char *dummy = new (std::nothrow) char[THREAD_STACK_SIZE]; + delete[] dummy; + TEST_SKIP_UNLESS_MESSAGE(dummy, "Not enough memory to run test"); for (int i = 0; i < N; i++) { Thread thread(osPriorityNormal, THREAD_STACK_SIZE); @@ -229,10 +267,20 @@ void test_serial_threads() { when the thread calls @a terminate on its self then the thread terminates execution cleanly */ -void test_self_terminate() { - Thread *thread = new Thread(osPriorityNormal, THREAD_STACK_SIZE); +void test_self_terminate() +{ + Thread *thread = new (std::nothrow) Thread(osPriorityNormal, THREAD_STACK_SIZE); + char *dummy = new (std::nothrow) char[THREAD_STACK_SIZE]; + delete[] dummy; + + // Don't fail test due to lack of memory. + if (!thread || !dummy) { + goto end; + } thread->start(callback(self_terminate, thread)); thread->join(); + +end: delete thread; } @@ -290,6 +338,10 @@ void signal_wait_multibit_tout() template void test_thread_signal() { + char *dummy = new (std::nothrow) char[THREAD_STACK_SIZE]; + delete[] dummy; + TEST_SKIP_UNLESS_MESSAGE(dummy, "Not enough memory to run test"); + Thread t_wait(osPriorityNormal, THREAD_STACK_SIZE); t_wait.start(callback(F)); @@ -326,6 +378,10 @@ void signal_clr() */ void test_thread_signal_clr() { + char *dummy = new (std::nothrow) char[THREAD_STACK_SIZE]; + delete[] dummy; + TEST_SKIP_UNLESS_MESSAGE(dummy, "Not enough memory to run test"); + Thread t_wait(osPriorityNormal, THREAD_STACK_SIZE); t_wait.start(callback(signal_clr)); @@ -336,11 +392,13 @@ void test_thread_signal_clr() t_wait.join(); } -void thread_wait_signal() { +void thread_wait_signal() +{ Thread::signal_wait(0x1); } -void stack_info() { +void stack_info() +{ Thread::signal_wait(0x1); thread_wait_signal(); @@ -360,7 +418,12 @@ void stack_info() { and the reported stack size is as requested in the constructor and the sum of free and used stack sizes is equal to the total stack size */ -void test_thread_stack_info() { +void test_thread_stack_info() +{ + char *dummy = new (std::nothrow) char[THREAD_STACK_SIZE]; + delete[] dummy; + TEST_SKIP_UNLESS_MESSAGE(dummy, "Not enough memory to run test"); + Thread t(osPriorityNormal, THREAD_STACK_SIZE); t.start(callback(stack_info)); @@ -394,7 +457,8 @@ void test_thread_stack_info() { when the @a wait function is called then the thread sleeps for given amount of time */ -void test_thread_wait() { +void test_thread_wait() +{ Timer timer; timer.start(); @@ -409,7 +473,12 @@ void test_thread_wait() { when the name is queried using @a get_name then the returned name is as set */ -void test_thread_name() { +void test_thread_name() +{ + char *dummy = new (std::nothrow) char[THREAD_STACK_SIZE]; + delete[] dummy; + TEST_SKIP_UNLESS_MESSAGE(dummy, "Not enough memory to run test"); + const char tname[] = "Amazing thread"; Thread t(osPriorityNormal, THREAD_STACK_SIZE, NULL, tname); t.start(callback(thread_wait_signal)); @@ -431,6 +500,10 @@ void test_deleted_thread() */ void test_deleted() { + char *dummy = new (std::nothrow) char[THREAD_STACK_SIZE]; + delete[] dummy; + TEST_SKIP_UNLESS_MESSAGE(dummy, "Not enough memory to run test"); + Thread t(osPriorityNormal, THREAD_STACK_SIZE); TEST_ASSERT_EQUAL(Thread::Deleted, t.get_state()); @@ -454,6 +527,10 @@ void test_delay_thread() */ void test_delay() { + char *dummy = new (std::nothrow) char[THREAD_STACK_SIZE]; + delete[] dummy; + TEST_SKIP_UNLESS_MESSAGE(dummy, "Not enough memory to run test"); + Thread t(osPriorityNormal, THREAD_STACK_SIZE); t.start(callback(test_delay_thread)); @@ -479,6 +556,10 @@ void test_signal_thread() */ void test_signal() { + char *dummy = new (std::nothrow) char[THREAD_STACK_SIZE]; + delete[] dummy; + TEST_SKIP_UNLESS_MESSAGE(dummy, "Not enough memory to run test"); + Thread t(osPriorityNormal, THREAD_STACK_SIZE); t.start(callback(test_signal_thread)); @@ -503,6 +584,10 @@ void test_evt_flag_thread(osEventFlagsId_t evtflg) */ void test_evt_flag() { + char *dummy = new (std::nothrow) char[THREAD_STACK_SIZE]; + delete[] dummy; + TEST_SKIP_UNLESS_MESSAGE(dummy, "Not enough memory to run test"); + Thread t(osPriorityNormal, THREAD_STACK_SIZE); mbed_rtos_storage_event_flags_t evtflg_mem; osEventFlagsAttr_t evtflg_attr; @@ -535,6 +620,10 @@ void test_mutex_thread(Mutex *mutex) */ void test_mutex() { + char *dummy = new (std::nothrow) char[THREAD_STACK_SIZE]; + delete[] dummy; + TEST_SKIP_UNLESS_MESSAGE(dummy, "Not enough memory to run test"); + Thread t(osPriorityNormal, THREAD_STACK_SIZE); Mutex mutex; @@ -562,6 +651,10 @@ void test_semaphore_thread(Semaphore *sem) */ void test_semaphore() { + char *dummy = new (std::nothrow) char[THREAD_STACK_SIZE]; + delete[] dummy; + TEST_SKIP_UNLESS_MESSAGE(dummy, "Not enough memory to run test"); + Thread t(osPriorityNormal, THREAD_STACK_SIZE); Semaphore sem; @@ -587,6 +680,10 @@ void test_msg_get_thread(Queue *queue) */ void test_msg_get() { + char *dummy = new (std::nothrow) char[THREAD_STACK_SIZE]; + delete[] dummy; + TEST_SKIP_UNLESS_MESSAGE(dummy, "Not enough memory to run test"); + Thread t(osPriorityNormal, THREAD_STACK_SIZE); Queue queue; @@ -613,6 +710,10 @@ void test_msg_put_thread(Queue *queue) */ void test_msg_put() { + char *dummy = new (std::nothrow) char[THREAD_STACK_SIZE]; + delete[] dummy; + TEST_SKIP_UNLESS_MESSAGE(dummy, "Not enough memory to run test"); + Thread t(osPriorityNormal, THREAD_STACK_SIZE); Queue queue; @@ -627,7 +728,8 @@ void test_msg_put() } /** Utility function that places some date on the stack */ -void use_some_stack () { +void use_some_stack() +{ volatile uint32_t stack_filler[10] = {0xDEADBEEF}; } @@ -637,18 +739,20 @@ void use_some_stack () { when the thread executes then the supplies buffer is used as a stack */ -void test_thread_ext_stack() { +void test_thread_ext_stack() +{ char stack[512]; - Thread t(osPriorityNormal, sizeof(stack), (unsigned char*)stack); + Thread t(osPriorityNormal, sizeof(stack), (unsigned char *)stack); memset(&stack, 0, sizeof(stack)); t.start(callback(use_some_stack)); t.join(); /* If buffer was used as a stack it was cleared with pattern and some data were placed in it */ - for(unsigned i = 0; i < sizeof(stack); i++) { - if (stack[i] != 0) + for (unsigned i = 0; i < sizeof(stack); i++) { + if (stack[i] != 0) { return; + } } TEST_FAIL_MESSAGE("External stack was not used."); @@ -660,7 +764,12 @@ void test_thread_ext_stack() { when new priority is set using @a set_priority then priority is changed and can be retrieved using @a get_priority */ -void test_thread_prio() { +void test_thread_prio() +{ + char *dummy = new (std::nothrow) char[THREAD_STACK_SIZE]; + delete[] dummy; + TEST_SKIP_UNLESS_MESSAGE(dummy, "Not enough memory to run test"); + Thread t(osPriorityNormal, THREAD_STACK_SIZE); t.start(callback(thread_wait_signal)); @@ -674,7 +783,8 @@ void test_thread_prio() { t.join(); } -utest::v1::status_t test_setup(const size_t number_of_cases) { +utest::v1::status_t test_setup(const size_t number_of_cases) +{ GREENTEA_SETUP(20, "default_auto"); return verbose_test_setup_handler(number_of_cases); } @@ -685,8 +795,8 @@ utest::v1::status_t test_setup(const size_t number_of_cases) { // macros don't play nicely with the templates (extra comma). static const case_t cases[] = { {"Testing single thread", test_single_thread, DEFAULT_HANDLERS}, - {"Testing parallel threads", test_parallel_threads<3, increment> , DEFAULT_HANDLERS}, - {"Testing serial threads", test_serial_threads<10, increment> , DEFAULT_HANDLERS}, + {"Testing parallel threads", test_parallel_threads<3, increment>, DEFAULT_HANDLERS}, + {"Testing serial threads", test_serial_threads<10, increment>, DEFAULT_HANDLERS}, {"Testing single thread with yield", test_single_thread, DEFAULT_HANDLERS}, {"Testing parallel threads with yield", test_parallel_threads<3, increment_with_yield>, DEFAULT_HANDLERS}, @@ -733,6 +843,7 @@ static const case_t cases[] = { Specification specification(test_setup, cases); -int main() { +int main() +{ return !Harness::run(specification); } diff --git a/TESTS/mbedtls/multi/main.cpp b/TESTS/mbedtls/multi/main.cpp index f89b8444c46d..e84ad489efd5 100644 --- a/TESTS/mbedtls/multi/main.cpp +++ b/TESTS/mbedtls/multi/main.cpp @@ -34,65 +34,73 @@ using namespace utest::v1; #if defined(MBEDTLS_SHA256_C) /* Tests several call to mbedtls_sha256_update function that are not modulo 64 bytes */ -void test_case_sha256_split() { - const unsigned char test_buf[] = {"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopqabcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopqabcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}; - // sha256_output_values for 3*abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq - const unsigned char test_sum[] = - { 0x50, 0xEA, 0x82, 0x5D, 0x96, 0x84, 0xF4, 0x22, - 0x9C, 0xA2, 0x9F, 0x1F, 0xEC, 0x51, 0x15, 0x93, - 0xE2, 0x81, 0xE4, 0x6A, 0x14, 0x0D, 0x81, 0xE0, - 0x00, 0x5F, 0x8F, 0x68, 0x86, 0x69, 0xA0, 0x6C}; - unsigned char outsum[32]; - int i; - - mbedtls_sha256_context ctx; - printf("test sha256\n"); - mbedtls_sha256_init( &ctx ); - mbedtls_sha256_starts( &ctx, 0); - #if 0 +void test_case_sha256_split() +{ + const unsigned char test_buf[] = {"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopqabcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopqabcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}; + // sha256_output_values for 3*abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq + const unsigned char test_sum[] = { + 0x50, 0xEA, 0x82, 0x5D, 0x96, 0x84, 0xF4, 0x22, + 0x9C, 0xA2, 0x9F, 0x1F, 0xEC, 0x51, 0x15, 0x93, + 0xE2, 0x81, 0xE4, 0x6A, 0x14, 0x0D, 0x81, 0xE0, + 0x00, 0x5F, 0x8F, 0x68, 0x86, 0x69, 0xA0, 0x6C + }; + unsigned char outsum[32]; + int i; + + mbedtls_sha256_context ctx; + printf("test sha256\n"); + mbedtls_sha256_init(&ctx); + mbedtls_sha256_starts(&ctx, 0); +#if 0 printf("test not splitted\n"); - mbedtls_sha256_update( &ctx, test_buf, 168 ); - #else + mbedtls_sha256_update(&ctx, test_buf, 168); +#else printf("test splitted into 3 pieces\n"); - mbedtls_sha256_update( &ctx, test_buf, 2 ); - mbedtls_sha256_update( &ctx, test_buf+2, 66 ); - mbedtls_sha256_update( &ctx, test_buf+68, 100 ); - #endif - - mbedtls_sha256_finish( &ctx, outsum ); - mbedtls_sha256_free( &ctx ); - + mbedtls_sha256_update(&ctx, test_buf, 2); + mbedtls_sha256_update(&ctx, test_buf + 2, 66); + mbedtls_sha256_update(&ctx, test_buf + 68, 100); +#endif + + mbedtls_sha256_finish(&ctx, outsum); + mbedtls_sha256_free(&ctx); + printf("\nreceived result : "); - for (i=0;i<32;i++) { printf("%02X",outsum[i]);} + for (i = 0; i < 32; i++) { + printf("%02X", outsum[i]); + } printf("\nawaited result : 50EA825D9684F4229CA29F1FEC511593E281E46A140D81E0005F8F688669A06C\n"); // for abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq - + printf("\nend of test sha256\n"); - TEST_ASSERT_EQUAL_UINT8_ARRAY(outsum, test_sum,32); + TEST_ASSERT_EQUAL_UINT8_ARRAY(outsum, test_sum, 32); } /* Tests that treating 2 sha256 objects in // does not impact the result */ -void test_case_sha256_multi() { +void test_case_sha256_multi() +{ const unsigned char test_buf[] = {"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopqabcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopqabcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}; const unsigned char test_buf2[] = {"abcdefghijklmnopqrstuvwxyz012345678901234567890123456789"}; // sha256_output_values for abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq - const unsigned char test_sum1[] = - { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8, - 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39, - 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67, - 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 }; + const unsigned char test_sum1[] = { + 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8, + 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39, + 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67, + 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 + }; // sha256_output_values for 3*abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq - const unsigned char test_sum2[] = - { 0x50, 0xEA, 0x82, 0x5D, 0x96, 0x84, 0xF4, 0x22, - 0x9C, 0xA2, 0x9F, 0x1F, 0xEC, 0x51, 0x15, 0x93, - 0xE2, 0x81, 0xE4, 0x6A, 0x14, 0x0D, 0x81, 0xE0, - 0x00, 0x5F, 0x8F, 0x68, 0x86, 0x69, 0xA0, 0x6C}; + const unsigned char test_sum2[] = { + 0x50, 0xEA, 0x82, 0x5D, 0x96, 0x84, 0xF4, 0x22, + 0x9C, 0xA2, 0x9F, 0x1F, 0xEC, 0x51, 0x15, 0x93, + 0xE2, 0x81, 0xE4, 0x6A, 0x14, 0x0D, 0x81, 0xE0, + 0x00, 0x5F, 0x8F, 0x68, 0x86, 0x69, 0xA0, 0x6C + }; // sha256_output_values for abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopqabcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopqabcdefghijklmnopqrstuvwxyz012345678901234567890123456789 - const unsigned char test_sum3[] = - { 0x6D, 0x5D, 0xDB, 0x5F, 0x4A, 0x94, 0xAB, 0x7E, - 0x5C, 0xF7, 0x9A, 0xD8, 0x3F, 0x58, 0xD3, 0x97, - 0xFE, 0x79, 0xFB, 0x0D, 0x79, 0xB2, 0x0D, 0x22, - 0xFF, 0x95, 0x9F, 0x04, 0xA2, 0xE4, 0x6C, 0x68}; + const unsigned char test_sum3[] = { + 0x6D, 0x5D, 0xDB, 0x5F, 0x4A, 0x94, 0xAB, 0x7E, + 0x5C, 0xF7, 0x9A, 0xD8, 0x3F, 0x58, 0xD3, 0x97, + 0xFE, 0x79, 0xFB, 0x0D, 0x79, 0xB2, 0x0D, 0x22, + 0xFF, 0x95, 0x9F, 0x04, 0xA2, 0xE4, 0x6C, 0x68 + }; unsigned char outsum1[32], outsum2[32], outsum3[32]; int i; @@ -101,55 +109,62 @@ void test_case_sha256_multi() { mbedtls_sha256_context ctx3; printf("test sha256_multi\n"); //Init both contexts - mbedtls_sha256_init( &ctx1); - mbedtls_sha256_init( &ctx2); - mbedtls_sha256_init( &ctx3); + mbedtls_sha256_init(&ctx1); + mbedtls_sha256_init(&ctx2); + mbedtls_sha256_init(&ctx3); //Start both contexts - mbedtls_sha256_starts( &ctx1, 0); - mbedtls_sha256_starts( &ctx2, 0); + mbedtls_sha256_starts(&ctx1, 0); + mbedtls_sha256_starts(&ctx2, 0); printf("upd ctx1\n"); - mbedtls_sha256_update( &ctx1, test_buf, 56 ); + mbedtls_sha256_update(&ctx1, test_buf, 56); printf("upd ctx2\n"); - mbedtls_sha256_update( &ctx2, test_buf, 66 ); + mbedtls_sha256_update(&ctx2, test_buf, 66); printf("finish ctx1\n"); - mbedtls_sha256_finish( &ctx1, outsum1 ); + mbedtls_sha256_finish(&ctx1, outsum1); printf("upd ctx2\n"); - mbedtls_sha256_update( &ctx2, test_buf+66, 46 ); + mbedtls_sha256_update(&ctx2, test_buf + 66, 46); printf("clone ctx2 in ctx3\n"); mbedtls_sha256_clone(&ctx3, (const mbedtls_sha256_context *)&ctx2); printf("free ctx1\n"); - mbedtls_sha256_free( &ctx1 ); + mbedtls_sha256_free(&ctx1); printf("upd ctx2\n"); - mbedtls_sha256_update( &ctx2, test_buf+112, 56 ); + mbedtls_sha256_update(&ctx2, test_buf + 112, 56); printf("upd ctx3 with different values than ctx2\n"); - mbedtls_sha256_update( &ctx3, test_buf2, 56 ); + mbedtls_sha256_update(&ctx3, test_buf2, 56); printf("finish ctx2\n"); - mbedtls_sha256_finish( &ctx2, outsum2 ); + mbedtls_sha256_finish(&ctx2, outsum2); printf("finish ctx3\n"); - mbedtls_sha256_finish( &ctx3, outsum3 ); + mbedtls_sha256_finish(&ctx3, outsum3); printf("free ctx2\n"); - mbedtls_sha256_free( &ctx2 ); + mbedtls_sha256_free(&ctx2); printf("free ctx3\n"); - mbedtls_sha256_free( &ctx3 ); + mbedtls_sha256_free(&ctx3); printf("\nreceived result ctx1 : "); - for (i=0;i<32;i++) { printf("%02X",outsum1[i]);} + for (i = 0; i < 32; i++) { + printf("%02X", outsum1[i]); + } printf("\nawaited result : 248D6A61D20638B8E5C026930C3E6039A33CE45964FF216F6ECEDD19DB06C1\n"); // for abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq printf("\nreceived result ctx2 : "); - for (i=0;i<32;i++) { printf("%02X",outsum2[i]);} + for (i = 0; i < 32; i++) { + printf("%02X", outsum2[i]); + } printf("\nawaited result : 50EA825D9684F4229CA29F1FEC511593E281E46A140D81E0005F8F688669A06C\n"); // for 3*abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq printf("\nreceived result ctx3 : "); - for (i=0;i<32;i++) { printf("%02X",outsum3[i]);} + for (i = 0; i < 32; i++) { + printf("%02X", outsum3[i]); + } printf("\nawaited result : 6D5DDB5F4A94AB7E5CF79AD83F58D397FE79FB0D79B20D22FF959F04A2E46C68\n"); // for 2*abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq+3*0123456789 printf("\nend of test sha256\n"); - TEST_ASSERT_EQUAL_UINT8_ARRAY(outsum1, test_sum1,32); - TEST_ASSERT_EQUAL_UINT8_ARRAY(outsum2, test_sum2,32); - TEST_ASSERT_EQUAL_UINT8_ARRAY(outsum3, test_sum3,32); + TEST_ASSERT_EQUAL_UINT8_ARRAY(outsum1, test_sum1, 32); + TEST_ASSERT_EQUAL_UINT8_ARRAY(outsum2, test_sum2, 32); + TEST_ASSERT_EQUAL_UINT8_ARRAY(outsum3, test_sum3, 32); } #endif //MBEDTLS_SHA256_C -utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) { +utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) +{ greentea_case_failure_abort_handler(source, reason); return STATUS_CONTINUE; } @@ -161,19 +176,20 @@ Case cases[] = { #endif }; -utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { +utest::v1::status_t greentea_test_setup(const size_t number_of_cases) +{ GREENTEA_SETUP(10, "default_auto"); return greentea_test_setup_handler(number_of_cases); } Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); -int main() { +int main() +{ int ret = 0; #if defined(MBEDTLS_PLATFORM_C) mbedtls_platform_context platform_ctx; - if((ret = mbedtls_platform_setup(&platform_ctx))!= 0) - { + if ((ret = mbedtls_platform_setup(&platform_ctx)) != 0) { mbedtls_printf("Mbed TLS multitest failed! mbedtls_platform_setup returned %d\n", ret); return 1; } diff --git a/TESTS/mbedtls/selftest/main.cpp b/TESTS/mbedtls/selftest/main.cpp index 6635bd0cf222..f2ef3582c22a 100644 --- a/TESTS/mbedtls/selftest/main.cpp +++ b/TESTS/mbedtls/selftest/main.cpp @@ -84,19 +84,20 @@ Case cases[] = { #endif /* MBEDTLS_SELF_TEST */ }; -utest::v1::status_t test_setup(const size_t num_cases) { +utest::v1::status_t test_setup(const size_t num_cases) +{ GREENTEA_SETUP(120, "default_auto"); return verbose_test_setup_handler(num_cases); } Specification specification(test_setup, cases); -int main() { +int main() +{ int ret = 0; #if defined(MBEDTLS_PLATFORM_C) mbedtls_platform_context platform_ctx; - if((ret = mbedtls_platform_setup(&platform_ctx))!= 0) - { + if ((ret = mbedtls_platform_setup(&platform_ctx)) != 0) { mbedtls_printf("Mbed TLS selftest failed! mbedtls_platform_setup returned %d\n", ret); return 1; } diff --git a/TESTS/netsocket/dns/main.cpp b/TESTS/netsocket/dns/main.cpp index 9dee6b2d9906..768790105ae0 100644 --- a/TESTS/netsocket/dns/main.cpp +++ b/TESTS/netsocket/dns/main.cpp @@ -142,7 +142,9 @@ Case cases[] = { Case("ASYNCHRONOUS_DNS_EXTERNAL_EVENT_QUEUE", ASYNCHRONOUS_DNS_EXTERNAL_EVENT_QUEUE), Case("ASYNCHRONOUS_DNS_INVALID_HOST", ASYNCHRONOUS_DNS_INVALID_HOST), Case("ASYNCHRONOUS_DNS_TIMEOUTS", ASYNCHRONOUS_DNS_TIMEOUTS), +#ifdef MBED_EXTENDED_TESTS Case("ASYNCHRONOUS_DNS_SIMULTANEOUS_REPEAT", ASYNCHRONOUS_DNS_SIMULTANEOUS_REPEAT), +#endif }; Specification specification(test_setup, cases); diff --git a/TESTS/netsocket/tcp/main.cpp b/TESTS/netsocket/tcp/main.cpp index 703bf8c1d947..70644e4fa79f 100644 --- a/TESTS/netsocket/tcp/main.cpp +++ b/TESTS/netsocket/tcp/main.cpp @@ -29,20 +29,21 @@ using namespace utest::v1; -namespace -{ - NetworkInterface* net; +namespace { +NetworkInterface *net; +Timer tc_bucket; // Timer to limit a test cases run time } char tcp_global::rx_buffer[RX_BUFF_SIZE]; char tcp_global::tx_buffer[TX_BUFF_SIZE]; -NetworkInterface* get_interface() +NetworkInterface *get_interface() { return net; } -void drop_bad_packets(TCPSocket& sock, int orig_timeout) { +void drop_bad_packets(TCPSocket &sock, int orig_timeout) +{ nsapi_error_t err; sock.set_timeout(0); while (true) { @@ -54,55 +55,74 @@ void drop_bad_packets(TCPSocket& sock, int orig_timeout) { sock.set_timeout(orig_timeout); } -static void _ifup() { +static void _ifup() +{ net = MBED_CONF_APP_OBJECT_CONSTRUCTION; nsapi_error_t err = MBED_CONF_APP_CONNECT_STATEMENT; TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, err); printf("MBED: TCPClient IP address is '%s'\n", net->get_ip_address()); } -static void _ifdown() { +static void _ifdown() +{ net->disconnect(); printf("MBED: ifdown\n"); } -void tcpsocket_connect_to_echo_srv(TCPSocket& sock) { +nsapi_error_t tcpsocket_connect_to_echo_srv(TCPSocket &sock) +{ SocketAddress tcp_addr; get_interface()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &tcp_addr); tcp_addr.set_port(MBED_CONF_APP_ECHO_SERVER_PORT); - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(get_interface())); - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.connect(tcp_addr)); + nsapi_error_t err = sock.open(get_interface()); + if (err != NSAPI_ERROR_OK) { + return err; + } + + return sock.connect(tcp_addr); } -void tcpsocket_connect_to_discard_srv(TCPSocket& sock) { +nsapi_error_t tcpsocket_connect_to_discard_srv(TCPSocket &sock) +{ SocketAddress tcp_addr; get_interface()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &tcp_addr); tcp_addr.set_port(9); - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(get_interface())); - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.connect(tcp_addr)); + nsapi_error_t err = sock.open(get_interface()); + if (err != NSAPI_ERROR_OK) { + return err; + } + + return sock.connect(tcp_addr); } void fill_tx_buffer_ascii(char *buff, size_t len) { - for (size_t i = 0; i= time_allotted) { + TEST_FAIL(); + break; + } wait(1); continue; } else if (recvd < 0) { TEST_FAIL(); + break; } bytes2recv -= recvd; } - TEST_ASSERT_EQUAL(0, memcmp(tcp_global::tx_buffer, tcp_global::rx_buffer, *(int*)receive_bytes)); + TEST_ASSERT_EQUAL(0, memcmp(tcp_global::tx_buffer, tcp_global::rx_buffer, *(int *)receive_bytes)); static int round = 0; - printf("[Recevr#%02d] bytes received: %d\n", round++, *(int*)receive_bytes); + printf("[Recevr#%02d] bytes received: %d\n", round++, *(int *)receive_bytes); tx_sem.release(); @@ -99,6 +115,9 @@ void tcpsocket_echotest_nonblock_receiver(void *receive_bytes) void TCPSOCKET_ECHOTEST_NONBLOCK() { + tc_exec_time.start(); + time_allotted = split2half_rmng_tcp_test_time(); // [s] + tcpsocket_connect_to_echo_srv(sock); sock.set_blocking(false); sock.sigio(callback(_sigio_handler, Thread::gettid())); @@ -122,21 +141,32 @@ void TCPSOCKET_ECHOTEST_NONBLOCK() bytes2send = pkt_s; while (bytes2send > 0) { - sent = sock.send(&(tcp_global::tx_buffer[pkt_s-bytes2send]), bytes2send); + sent = sock.send(&(tcp_global::tx_buffer[pkt_s - bytes2send]), bytes2send); if (sent == NSAPI_ERROR_WOULD_BLOCK) { - TEST_ASSERT_NOT_EQUAL(osEventTimeout, osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status); + if (tc_exec_time.read() >= time_allotted || + osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status == osEventTimeout) { + thread->terminate(); + delete thread; + TEST_FAIL(); + goto END; + } continue; } else if (sent <= 0) { printf("[Sender#%02d] network error %d\n", s_idx, sent); + thread->terminate(); + delete thread; TEST_FAIL(); + goto END; } bytes2send -= sent; } printf("[Sender#%02d] bytes sent: %d\n", s_idx, pkt_s); - tx_sem.wait(); + tx_sem.wait(split2half_rmng_tcp_test_time()); thread->join(); delete thread; } +END: + tc_exec_time.stop(); free(stack_mem); TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close()); } diff --git a/TESTS/netsocket/tcp/tcpsocket_echotest_burst.cpp b/TESTS/netsocket/tcp/tcpsocket_echotest_burst.cpp index 12b8fdf40304..2b6d7fa3e54b 100644 --- a/TESTS/netsocket/tcp/tcpsocket_echotest_burst.cpp +++ b/TESTS/netsocket/tcp/tcpsocket_echotest_burst.cpp @@ -25,16 +25,16 @@ using namespace utest::v1; -namespace -{ - static const int SIGNAL_SIGIO = 0x1; - static const int SIGIO_TIMEOUT = 5000; //[ms] +namespace { +static const int SIGNAL_SIGIO = 0x1; +static const int SIGIO_TIMEOUT = 5000; //[ms] - static const int BURST_CNT = 100; - static const int BURST_SIZE = 1220; +static const int BURST_CNT = 100; +static const int BURST_SIZE = 1220; } -static void _sigio_handler(osThreadId id) { +static void _sigio_handler(osThreadId id) +{ osSignalSet(id, SIGNAL_SIGIO); } @@ -53,22 +53,24 @@ void TCPSOCKET_ECHOTEST_BURST() for (int i = 0; i < BURST_CNT; i++) { bt_left = BURST_SIZE; while (bt_left > 0) { - sent = sock.send(&(tcp_global::tx_buffer[BURST_SIZE-bt_left]), bt_left); + sent = sock.send(&(tcp_global::tx_buffer[BURST_SIZE - bt_left]), bt_left); if (sent == NSAPI_ERROR_WOULD_BLOCK) { - if(osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status == osEventTimeout) { + if (osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status == osEventTimeout) { TEST_FAIL(); + goto END; } continue; } else if (sent < 0) { printf("[%02d] network error %d\n", i, sent); TEST_FAIL(); + goto END; } bt_left -= sent; } bt_left = BURST_SIZE; while (bt_left > 0) { - recvd = sock.recv(&(tcp_global::rx_buffer[BURST_SIZE-bt_left]), BURST_SIZE); + recvd = sock.recv(&(tcp_global::rx_buffer[BURST_SIZE - bt_left]), BURST_SIZE); if (recvd < 0) { printf("[%02d] network error %d\n", i, recvd); break; @@ -79,10 +81,12 @@ void TCPSOCKET_ECHOTEST_BURST() if (bt_left != 0) { drop_bad_packets(sock, 0); TEST_FAIL(); + goto END; } TEST_ASSERT_EQUAL(0, memcmp(tcp_global::tx_buffer, tcp_global::rx_buffer, BURST_SIZE)); } +END: TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close()); } @@ -102,25 +106,30 @@ void TCPSOCKET_ECHOTEST_BURST_NONBLOCK() for (int i = 0; i < BURST_CNT; i++) { bt_left = BURST_SIZE; while (bt_left > 0) { - sent = sock.send(&(tcp_global::tx_buffer[BURST_SIZE-bt_left]), bt_left); + sent = sock.send(&(tcp_global::tx_buffer[BURST_SIZE - bt_left]), bt_left); if (sent == NSAPI_ERROR_WOULD_BLOCK) { - if(osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status == osEventTimeout) { + if (osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status == osEventTimeout) { TEST_FAIL(); + goto END; } continue; } else if (sent < 0) { printf("[%02d] network error %d\n", i, sent); TEST_FAIL(); + goto END; } bt_left -= sent; } - TEST_ASSERT_EQUAL(0, bt_left); + if (bt_left != 0) { + TEST_FAIL(); + goto END; + } bt_left = BURST_SIZE; while (bt_left > 0) { - recvd = sock.recv(&(tcp_global::rx_buffer[BURST_SIZE-bt_left]), BURST_SIZE); + recvd = sock.recv(&(tcp_global::rx_buffer[BURST_SIZE - bt_left]), BURST_SIZE); if (recvd == NSAPI_ERROR_WOULD_BLOCK) { - if(osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status == osEventTimeout) { + if (osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status == osEventTimeout) { printf("[bt#%02d] packet timeout...", i); break; } @@ -136,9 +145,11 @@ void TCPSOCKET_ECHOTEST_BURST_NONBLOCK() printf("network error %d, missing %d bytes from a burst\n", recvd, bt_left); drop_bad_packets(sock, -1); TEST_FAIL(); + goto END; } TEST_ASSERT_EQUAL(0, memcmp(tcp_global::tx_buffer, tcp_global::rx_buffer, BURST_SIZE)); } +END: TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close()); } diff --git a/TESTS/netsocket/tcp/tcpsocket_endpoint_close.cpp b/TESTS/netsocket/tcp/tcpsocket_endpoint_close.cpp index ae06707ef596..ea045109d3f0 100644 --- a/TESTS/netsocket/tcp/tcpsocket_endpoint_close.cpp +++ b/TESTS/netsocket/tcp/tcpsocket_endpoint_close.cpp @@ -25,24 +25,29 @@ using namespace utest::v1; -namespace -{ - static const int SIGNAL_SIGIO = 0x1; - static const int SIGIO_TIMEOUT = 5000; //[ms] +namespace { +static const int SIGNAL_SIGIO = 0x1; +static const int SIGIO_TIMEOUT = 5000; //[ms] } -static void _sigio_handler(osThreadId id) { +static void _sigio_handler(osThreadId id) +{ osSignalSet(id, SIGNAL_SIGIO); } -static void _tcpsocket_connect_to_daytime_srv(TCPSocket& sock) { +static nsapi_error_t _tcpsocket_connect_to_daytime_srv(TCPSocket &sock) +{ SocketAddress tcp_addr; get_interface()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &tcp_addr); tcp_addr.set_port(13); - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(get_interface())); - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.connect(tcp_addr)); + nsapi_error_t err = sock.open(get_interface()); + if (err != NSAPI_ERROR_OK) { + return err; + } + + return sock.connect(tcp_addr); } @@ -50,27 +55,37 @@ void TCPSOCKET_ENDPOINT_CLOSE() { static const int MORE_THAN_AVAILABLE = 30; char buff[MORE_THAN_AVAILABLE]; + int time_allotted = split2half_rmng_tcp_test_time(); // [s] + Timer tc_exec_time; + tc_exec_time.start(); TCPSocket sock; - _tcpsocket_connect_to_daytime_srv(sock); + if (_tcpsocket_connect_to_daytime_srv(sock) != NSAPI_ERROR_OK) { + TEST_FAIL(); + return; + } sock.sigio(callback(_sigio_handler, Thread::gettid())); int recvd = 0; int recvd_total = 0; while (true) { - recvd = sock.recv(&(buff[recvd_total]), MORE_THAN_AVAILABLE); - if (recvd_total > 0 && recvd == 0) { - break; // Endpoint closed socket, success - } else if (recvd == 0) { + recvd = sock.recv(&(buff[recvd_total]), MORE_THAN_AVAILABLE); + if (recvd_total > 0 && recvd == 0) { + break; // Endpoint closed socket, success + } else if (recvd <= 0) { TEST_FAIL(); - } else if (recvd == NSAPI_ERROR_WOULD_BLOCK) { - if(osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status == osEventTimeout) { - TEST_FAIL(); - } - continue; - } - recvd_total += recvd; - TEST_ASSERT(recvd_total < MORE_THAN_AVAILABLE); + break; + } else if (recvd == NSAPI_ERROR_WOULD_BLOCK) { + if (tc_exec_time.read() >= time_allotted || + osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status == osEventTimeout) { + TEST_FAIL(); + break; + } + continue; + } + recvd_total += recvd; + TEST_ASSERT(recvd_total < MORE_THAN_AVAILABLE); } + tc_exec_time.stop(); TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close()); } diff --git a/TESTS/netsocket/tcp/tcpsocket_open_limit.cpp b/TESTS/netsocket/tcp/tcpsocket_open_limit.cpp index fcc1ac80badc..f0cd3ac7e3c2 100644 --- a/TESTS/netsocket/tcp/tcpsocket_open_limit.cpp +++ b/TESTS/netsocket/tcp/tcpsocket_open_limit.cpp @@ -25,12 +25,11 @@ using namespace utest::v1; -namespace -{ - typedef struct TCPSocketItem { - TCPSocket *sock; - TCPSocketItem *next; - } SocketItem; +namespace { +typedef struct TCPSocketItem { + TCPSocket *sock; + TCPSocketItem *next; +} SocketItem; } void TCPSOCKET_OPEN_LIMIT() @@ -73,7 +72,7 @@ void TCPSOCKET_OPEN_LIMIT() } TCPSocketItem *tmp; - for(TCPSocketItem *it = socket_list_head; it;) { + for (TCPSocketItem *it = socket_list_head; it;) { ++open_sockets[i]; tmp = it; it = it->next; diff --git a/TESTS/netsocket/tcp/tcpsocket_recv_100k.cpp b/TESTS/netsocket/tcp/tcpsocket_recv_100k.cpp index ba9e5ffa250b..726804c1e632 100644 --- a/TESTS/netsocket/tcp/tcpsocket_recv_100k.cpp +++ b/TESTS/netsocket/tcp/tcpsocket_recv_100k.cpp @@ -25,20 +25,24 @@ using namespace utest::v1; -namespace -{ - static const int SIGNAL_SIGIO = 0x1; - static const int SIGIO_TIMEOUT = 20000; //[ms] +namespace { +static const int SIGNAL_SIGIO = 0x1; +static const int SIGIO_TIMEOUT = 20000; //[ms] } -static void _tcpsocket_connect_to_chargen_srv(TCPSocket& sock) { +static nsapi_error_t _tcpsocket_connect_to_chargen_srv(TCPSocket &sock) +{ SocketAddress tcp_addr; get_interface()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &tcp_addr); tcp_addr.set_port(19); - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(get_interface())); - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.connect(tcp_addr)); + nsapi_error_t err = sock.open(get_interface()); + if (err != NSAPI_ERROR_OK) { + return err; + } + + return sock.connect(tcp_addr); } /** Generate RFC 864 example pattern. @@ -58,12 +62,13 @@ static void _tcpsocket_connect_to_chargen_srv(TCPSocket& sock) { static void generate_RFC_864_pattern(size_t offset, uint8_t *buf, size_t len) { while (len--) { - if (offset % 74 == 72) + if (offset % 74 == 72) { *buf++ = '\r'; - else if (offset % 74 == 73) + } else if (offset % 74 == 73) { *buf++ = '\n'; - else - *buf++ = ' ' + (offset%74 + offset/74) % 95 ; + } else { + *buf++ = ' ' + (offset % 74 + offset / 74) % 95 ; + } offset++; } } @@ -73,48 +78,60 @@ static void check_RFC_864_pattern(void *rx_buff, const size_t len, const size_t void *ref_buff = malloc(len); TEST_ASSERT_NOT_NULL(ref_buff); - generate_RFC_864_pattern(offset, (uint8_t*)ref_buff, len); + generate_RFC_864_pattern(offset, (uint8_t *)ref_buff, len); bool match = memcmp(ref_buff, rx_buff, len) == 0; free(ref_buff); TEST_ASSERT(match); } -void rcv_n_chk_against_rfc864_pattern(TCPSocket& sock) { +void rcv_n_chk_against_rfc864_pattern(TCPSocket &sock) +{ static const size_t total_size = 1024 * 100; static const size_t buff_size = 1220; uint8_t buff[buff_size]; size_t recvd_size = 0; + Timer timer; + timer.start(); + // Verify received data while (recvd_size < total_size) { int rd = sock.recv(buff, buff_size); TEST_ASSERT(rd > 0); + if (rd < 0) { + break; + } check_RFC_864_pattern(buff, rd, recvd_size); recvd_size += rd; } + timer.stop(); + printf("MBED: Time taken: %fs\n", timer.read()); } void TCPSOCKET_RECV_100K() { TCPSocket sock; - _tcpsocket_connect_to_chargen_srv(sock); + if (_tcpsocket_connect_to_chargen_srv(sock) != NSAPI_ERROR_OK) { + TEST_FAIL(); + return; + } - Timer timer; - timer.start(); rcv_n_chk_against_rfc864_pattern(sock); - timer.stop(); TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close()); - - printf("MBED: Time taken: %fs\n", timer.read()); } -void rcv_n_chk_against_rfc864_pattern_nonblock(TCPSocket& sock) { +void rcv_n_chk_against_rfc864_pattern_nonblock(TCPSocket &sock) +{ static const size_t total_size = 1024 * 100; static const size_t buff_size = 1220; uint8_t buff[buff_size]; size_t recvd_size = 0; + int time_allotted = split2half_rmng_tcp_test_time(); // [s] + + Timer timer; + timer.start(); // Verify received data while (recvd_size < total_size) { @@ -124,28 +141,39 @@ void rcv_n_chk_against_rfc864_pattern_nonblock(TCPSocket& sock) { check_RFC_864_pattern(buff, rd, recvd_size); recvd_size += rd; } else if (rd == NSAPI_ERROR_WOULD_BLOCK) { + if (timer.read() >= time_allotted) { + TEST_FAIL(); + break; + } TEST_ASSERT_NOT_EQUAL(osEventTimeout, osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status); + } else { + TEST_FAIL(); + break; } } + timer.stop(); + printf("MBED: Time taken: %fs\n", timer.read()); } -static void _sigio_handler(osThreadId id) { +static void _sigio_handler(osThreadId id) +{ osSignalSet(id, SIGNAL_SIGIO); } void TCPSOCKET_RECV_100K_NONBLOCK() { - TCPSocket sock; - _tcpsocket_connect_to_chargen_srv(sock); + TCPSocket sock; + nsapi_error_t err = _tcpsocket_connect_to_chargen_srv(sock); + + if (err != NSAPI_ERROR_OK) { + TEST_FAIL(); + return; + } + sock.set_blocking(false); sock.sigio(callback(_sigio_handler, Thread::gettid())); - Timer timer; - timer.start(); rcv_n_chk_against_rfc864_pattern_nonblock(sock); - timer.stop(); TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close()); - - printf("MBED: Time taken: %fs\n", timer.read()); } diff --git a/TESTS/netsocket/tcp/tcpsocket_recv_timeout.cpp b/TESTS/netsocket/tcp/tcpsocket_recv_timeout.cpp index c2ce6ccf8114..9f69614bd643 100644 --- a/TESTS/netsocket/tcp/tcpsocket_recv_timeout.cpp +++ b/TESTS/netsocket/tcp/tcpsocket_recv_timeout.cpp @@ -25,13 +25,13 @@ using namespace utest::v1; -namespace -{ - static const int SIGNAL_SIGIO = 0x1; - static const int SIGIO_TIMEOUT = 5000; //[ms] +namespace { +static const int SIGNAL_SIGIO = 0x1; +static const int SIGIO_TIMEOUT = 5000; //[ms] } -static void _sigio_handler(osThreadId id) { +static void _sigio_handler(osThreadId id) +{ osSignalSet(id, SIGNAL_SIGIO); } @@ -39,6 +39,9 @@ void TCPSOCKET_RECV_TIMEOUT() { static const int DATA_LEN = 100; char buff[DATA_LEN] = {0}; + int time_allotted = split2half_rmng_tcp_test_time(); // [s] + Timer tc_exec_time; + tc_exec_time.start(); TCPSocket sock; tcpsocket_connect_to_echo_srv(sock); @@ -55,12 +58,14 @@ void TCPSOCKET_RECV_TIMEOUT() while (pkt_unrecvd) { timer.reset(); timer.start(); - recvd = sock.recv(&(buff[DATA_LEN-pkt_unrecvd]), pkt_unrecvd); + recvd = sock.recv(&(buff[DATA_LEN - pkt_unrecvd]), pkt_unrecvd); timer.stop(); if (recvd == NSAPI_ERROR_WOULD_BLOCK) { - if(osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status == osEventTimeout) { + if (tc_exec_time.read() >= time_allotted || + (osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status == osEventTimeout)) { TEST_FAIL(); + goto CLEANUP; } printf("MBED: recv() took: %dms\n", timer.read_ms()); TEST_ASSERT_INT_WITHIN(50, 150, timer.read_ms()); @@ -68,9 +73,13 @@ void TCPSOCKET_RECV_TIMEOUT() } else if (recvd < 0) { printf("[pkt#%02d] network error %d\n", i, recvd); TEST_FAIL(); + goto CLEANUP; } pkt_unrecvd -= recvd; } } + +CLEANUP: + tc_exec_time.stop(); TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close()); } diff --git a/TESTS/netsocket/tcp/tcpsocket_send_repeat.cpp b/TESTS/netsocket/tcp/tcpsocket_send_repeat.cpp index 4f6390f9153e..1c0aa9daccd7 100644 --- a/TESTS/netsocket/tcp/tcpsocket_send_repeat.cpp +++ b/TESTS/netsocket/tcp/tcpsocket_send_repeat.cpp @@ -30,12 +30,15 @@ void TCPSOCKET_SEND_REPEAT() TCPSocket sock; tcpsocket_connect_to_discard_srv(sock); - int err; + int snd; Timer timer; - static const char tx_buffer[] = {'h','e','l','l','o'}; + static const char tx_buffer[] = {'h', 'e', 'l', 'l', 'o'}; for (int i = 0; i < 1000; i++) { - err = sock.send(tx_buffer, sizeof(tx_buffer)); - TEST_ASSERT_EQUAL(sizeof(tx_buffer), err); + snd = sock.send(tx_buffer, sizeof(tx_buffer)); + if (snd != sizeof(tx_buffer)) { + TEST_FAIL(); + break; + } } TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close()); diff --git a/TESTS/netsocket/tcp/tcpsocket_send_timeout.cpp b/TESTS/netsocket/tcp/tcpsocket_send_timeout.cpp index 98f1a10e0d93..a302c2cc23af 100644 --- a/TESTS/netsocket/tcp/tcpsocket_send_timeout.cpp +++ b/TESTS/netsocket/tcp/tcpsocket_send_timeout.cpp @@ -28,18 +28,25 @@ using namespace utest::v1; void TCPSOCKET_SEND_TIMEOUT() { TCPSocket sock; - tcpsocket_connect_to_discard_srv(sock); + if (tcpsocket_connect_to_discard_srv(sock) != NSAPI_ERROR_OK) { + TEST_FAIL(); + return; + } int err; Timer timer; - static const char tx_buffer[] = {'h','e','l','l','o'}; + static const char tx_buffer[] = {'h', 'e', 'l', 'l', 'o'}; for (int i = 0; i < 10; i++) { timer.reset(); timer.start(); err = sock.send(tx_buffer, sizeof(tx_buffer)); timer.stop(); - TEST_ASSERT_EQUAL(sizeof(tx_buffer), err); - TEST_ASSERT(timer.read_ms() <= 800); + if ((err == sizeof(tx_buffer)) && + (timer.read_ms() <= 800)) { + continue; + } + TEST_FAIL(); + break; } TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close()); diff --git a/TESTS/netsocket/tcp/tcpsocket_thread_per_socket_safety.cpp b/TESTS/netsocket/tcp/tcpsocket_thread_per_socket_safety.cpp index aded7319fa71..7a0226e2c0cd 100644 --- a/TESTS/netsocket/tcp/tcpsocket_thread_per_socket_safety.cpp +++ b/TESTS/netsocket/tcp/tcpsocket_thread_per_socket_safety.cpp @@ -25,21 +25,22 @@ using namespace utest::v1; -namespace -{ - static const int SIGNAL_SIGIO1 = 0x1; - static const int SIGNAL_SIGIO2 = 0x2; - static const int SIGIO_TIMEOUT = 5000; //[ms] +namespace { +static const int SIGNAL_SIGIO1 = 0x1; +static const int SIGNAL_SIGIO2 = 0x2; +static const int SIGIO_TIMEOUT = 5000; //[ms] - Thread thread; - volatile bool running = true; +Thread thread; +volatile bool running = true; } -static void _sigio_handler1(osThreadId id) { +static void _sigio_handler1(osThreadId id) +{ osSignalSet(id, SIGNAL_SIGIO1); } -static void _sigio_handler2(osThreadId id) { +static void _sigio_handler2(osThreadId id) +{ osSignalSet(id, SIGNAL_SIGIO2); } @@ -61,27 +62,30 @@ static void check_const_len_rand_sequence() fill_tx_buffer_ascii(tx_buff, BUFF_SIZE); bytes2process = BUFF_SIZE; while (bytes2process > 0) { - sent = sock.send(&(tx_buff[BUFF_SIZE-bytes2process]), bytes2process); + sent = sock.send(&(tx_buff[BUFF_SIZE - bytes2process]), bytes2process); if (sent == NSAPI_ERROR_WOULD_BLOCK) { - if(osSignalWait(SIGNAL_SIGIO1, SIGIO_TIMEOUT).status == osEventTimeout) { + if (osSignalWait(SIGNAL_SIGIO1, SIGIO_TIMEOUT).status == osEventTimeout) { TEST_FAIL(); + goto END; } continue; } else if (sent < 0) { printf("network error %d\n", sent); TEST_FAIL(); + goto END; } bytes2process -= sent; } bytes2process = BUFF_SIZE; while (bytes2process > 0) { - recvd = sock.recv(&(rx_buff[BUFF_SIZE-bytes2process]), bytes2process); + recvd = sock.recv(&(rx_buff[BUFF_SIZE - bytes2process]), bytes2process); if (recvd == NSAPI_ERROR_WOULD_BLOCK) { continue; } else if (recvd < 0) { printf("network error %d\n", recvd); TEST_FAIL(); + goto END; } bytes2process -= recvd; } @@ -89,9 +93,11 @@ static void check_const_len_rand_sequence() if (bytes2process != 0) { drop_bad_packets(sock, 0); TEST_FAIL(); + goto END; } TEST_ASSERT_EQUAL(0, memcmp(tx_buff, rx_buff, BUFF_SIZE)); } +END: TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close()); } @@ -113,27 +119,30 @@ static void check_var_len_rand_sequence() fill_tx_buffer_ascii(tx_buff, i); bytes2process = i; while (bytes2process > 0) { - sent = sock.send(&(tx_buff[i-bytes2process]), bytes2process); + sent = sock.send(&(tx_buff[i - bytes2process]), bytes2process); if (sent == NSAPI_ERROR_WOULD_BLOCK) { - if(osSignalWait(SIGNAL_SIGIO2, SIGIO_TIMEOUT).status == osEventTimeout) { + if (osSignalWait(SIGNAL_SIGIO2, SIGIO_TIMEOUT).status == osEventTimeout) { TEST_FAIL(); + goto END; } continue; } else if (sent < 0) { printf("[%02d] network error %d\n", i, sent); TEST_FAIL(); + goto END; } - bytes2process -= sent; + bytes2process -= sent; } bytes2process = i; while (bytes2process > 0) { - recvd = sock.recv(&(rx_buff[i-bytes2process]), bytes2process); + recvd = sock.recv(&(rx_buff[i - bytes2process]), bytes2process); if (recvd == NSAPI_ERROR_WOULD_BLOCK) { continue; } else if (recvd < 0) { printf("[%02d] network error %d\n", i, recvd); TEST_FAIL(); + goto END; } bytes2process -= recvd; } @@ -141,10 +150,11 @@ static void check_var_len_rand_sequence() if (bytes2process != 0) { drop_bad_packets(sock, 0); TEST_FAIL(); + goto END; } TEST_ASSERT_EQUAL(0, memcmp(tx_buff, rx_buff, i)); } - +END: TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close()); } diff --git a/TESTS/netsocket/udp/main.cpp b/TESTS/netsocket/udp/main.cpp index 9e171b8a04d8..31cb7cfb9169 100644 --- a/TESTS/netsocket/udp/main.cpp +++ b/TESTS/netsocket/udp/main.cpp @@ -29,29 +29,31 @@ using namespace utest::v1; -namespace -{ - NetworkInterface* net; +namespace { +NetworkInterface *net; } -NetworkInterface* get_interface() +NetworkInterface *get_interface() { return net; } -static void _ifup() { +static void _ifup() +{ net = MBED_CONF_APP_OBJECT_CONSTRUCTION; nsapi_error_t err = MBED_CONF_APP_CONNECT_STATEMENT; TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, err); printf("MBED: UDPClient IP address is '%s'\n", net->get_ip_address()); } -static void _ifdown() { +static void _ifdown() +{ net->disconnect(); printf("MBED: ifdown\n"); } -void drop_bad_packets(UDPSocket& sock, int orig_timeout) { +void drop_bad_packets(UDPSocket &sock, int orig_timeout) +{ nsapi_error_t err; sock.set_timeout(0); while (true) { @@ -65,7 +67,7 @@ void drop_bad_packets(UDPSocket& sock, int orig_timeout) { void fill_tx_buffer_ascii(char *buff, size_t len) { - for (size_t i = 0; i RECV_TIMEOUT ? recv_timeout/2 : RECV_TIMEOUT; + recv_timeout = recv_timeout > RECV_TIMEOUT ? recv_timeout / 2 : RECV_TIMEOUT; // Packets might arrive unordered for (int k = 0; k < BURST_PKTS; k++) { if (tx_buffers[k].len == recvd && - (memcmp(tx_buffers[k].payload, rx_buffer, recvd) == 0)) { + (memcmp(tx_buffers[k].payload, rx_buffer, recvd) == 0)) { bt_total += recvd; } } @@ -135,13 +137,13 @@ void UDPSOCKET_ECHOTEST_BURST() free_tx_buffers(); - double loss_ratio = 1 - ((double)(BURST_CNT*BURST_PKTS-pkg_fail) / (double)(BURST_CNT*BURST_PKTS)); + double loss_ratio = 1 - ((double)(BURST_CNT * BURST_PKTS - pkg_fail) / (double)(BURST_CNT * BURST_PKTS)); printf("Packets sent: %d, packets received %d, loss ratio %.2lf\r\n", - BURST_CNT*BURST_PKTS, BURST_CNT*BURST_PKTS-pkg_fail, loss_ratio); + BURST_CNT * BURST_PKTS, BURST_CNT * BURST_PKTS - pkg_fail, loss_ratio); // Packet loss up to 30% tolerated TEST_ASSERT_DOUBLE_WITHIN(TOLERATED_LOSS_RATIO, EXPECTED_LOSS_RATIO, loss_ratio); // 70% of the bursts need to be successful - TEST_ASSERT_INT_WITHIN(3*(BURST_CNT/10), BURST_CNT, ok_bursts); + TEST_ASSERT_INT_WITHIN(3 * (BURST_CNT / 10), BURST_CNT, ok_bursts); TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close()); } @@ -175,8 +177,8 @@ void UDPSOCKET_ECHOTEST_BURST_NONBLOCK() for (int j = 0; j < BURST_PKTS; j++) { recvd = sock.recvfrom(&temp_addr, rx_buffer, 500); if (recvd == NSAPI_ERROR_WOULD_BLOCK) { - if(osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status == osEventTimeout) { - pkg_fail += BURST_PKTS-j; + if (osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status == osEventTimeout) { + pkg_fail += BURST_PKTS - j; break; } --j; @@ -191,7 +193,7 @@ void UDPSOCKET_ECHOTEST_BURST_NONBLOCK() // Packets might arrive unordered for (int k = 0; k < BURST_PKTS; k++) { if (tx_buffers[k].len == recvd && - (memcmp(tx_buffers[k].payload, rx_buffer, recvd) == 0)) { + (memcmp(tx_buffers[k].payload, rx_buffer, recvd) == 0)) { bt_total += recvd; goto PKT_OK; } @@ -213,13 +215,13 @@ void UDPSOCKET_ECHOTEST_BURST_NONBLOCK() free_tx_buffers(); - double loss_ratio = 1 - ((double)(BURST_CNT*BURST_PKTS-pkg_fail) / (double)(BURST_CNT*BURST_PKTS)); + double loss_ratio = 1 - ((double)(BURST_CNT * BURST_PKTS - pkg_fail) / (double)(BURST_CNT * BURST_PKTS)); printf("Packets sent: %d, packets received %d, loss ratio %.2lf\r\n", - BURST_CNT*BURST_PKTS, BURST_CNT*BURST_PKTS-pkg_fail, loss_ratio); + BURST_CNT * BURST_PKTS, BURST_CNT * BURST_PKTS - pkg_fail, loss_ratio); // Packet loss up to 30% tolerated TEST_ASSERT_DOUBLE_WITHIN(TOLERATED_LOSS_RATIO, EXPECTED_LOSS_RATIO, loss_ratio); // 70% of the bursts need to be successful - TEST_ASSERT_INT_WITHIN(3*(BURST_CNT/10), BURST_CNT, ok_bursts); + TEST_ASSERT_INT_WITHIN(3 * (BURST_CNT / 10), BURST_CNT, ok_bursts); TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close()); } diff --git a/TESTS/netsocket/udp/udpsocket_open_limit.cpp b/TESTS/netsocket/udp/udpsocket_open_limit.cpp index 3766ee49b26c..4d4fcf572165 100644 --- a/TESTS/netsocket/udp/udpsocket_open_limit.cpp +++ b/TESTS/netsocket/udp/udpsocket_open_limit.cpp @@ -25,12 +25,11 @@ using namespace utest::v1; -namespace -{ - typedef struct UDPSocketItem { - UDPSocket *sock; - UDPSocketItem *next; - } SocketItem; +namespace { +typedef struct UDPSocketItem { + UDPSocket *sock; + UDPSocketItem *next; +} SocketItem; } void UDPSOCKET_OPEN_LIMIT() @@ -73,7 +72,7 @@ void UDPSOCKET_OPEN_LIMIT() } UDPSocketItem *tmp; - for(UDPSocketItem *it = socket_list_head; it;) { + for (UDPSocketItem *it = socket_list_head; it;) { ++open_sockets[i]; tmp = it; it = it->next; diff --git a/TESTS/netsocket/udp/udpsocket_recv_timeout.cpp b/TESTS/netsocket/udp/udpsocket_recv_timeout.cpp index 3c00c183998b..ea0b9be829bf 100644 --- a/TESTS/netsocket/udp/udpsocket_recv_timeout.cpp +++ b/TESTS/netsocket/udp/udpsocket_recv_timeout.cpp @@ -25,13 +25,13 @@ using namespace utest::v1; -namespace -{ - static const int SIGNAL_SIGIO = 0x1; - static const int SIGIO_TIMEOUT = 5000; //[ms] +namespace { +static const int SIGNAL_SIGIO = 0x1; +static const int SIGIO_TIMEOUT = 5000; //[ms] } -static void _sigio_handler(osThreadId id) { +static void _sigio_handler(osThreadId id) +{ osSignalSet(id, SIGNAL_SIGIO); } diff --git a/TESTS/netsocket/udp/udpsocket_sendto_repeat.cpp b/TESTS/netsocket/udp/udpsocket_sendto_repeat.cpp index 4b78f9592a76..db7a1d8297b8 100644 --- a/TESTS/netsocket/udp/udpsocket_sendto_repeat.cpp +++ b/TESTS/netsocket/udp/udpsocket_sendto_repeat.cpp @@ -37,7 +37,7 @@ void UDPSOCKET_SENDTO_REPEAT() int sent; Timer timer; int i; - static const char tx_buffer[] = {'h','e','l','l','o'}; + static const char tx_buffer[] = {'h', 'e', 'l', 'l', 'o'}; bool oom_earlier = false; // 2 times in a row -> time to give up for (i = 0; i < 100; i++) { sent = sock.sendto(udp_addr, tx_buffer, sizeof(tx_buffer)); diff --git a/TESTS/network/emac/emac_TestMemoryManager.cpp b/TESTS/network/emac/emac_TestMemoryManager.cpp index 05a0a62663e3..c37dc2068a73 100644 --- a/TESTS/network/emac/emac_TestMemoryManager.cpp +++ b/TESTS/network/emac/emac_TestMemoryManager.cpp @@ -203,7 +203,7 @@ emac_mem_buf_t *EmacTestMemoryManager::alloc_pool(uint32_t size, uint32_t align, if (size_left > pool_buffer_max_size) { size_left = size_left - pool_buffer_max_size; alloc_size = pool_buffer_max_size; - // New smaller than alloc size buffer needed + // New smaller than alloc size buffer needed } else { alloc_size = size_left; size_left = 0; @@ -550,7 +550,8 @@ void EmacTestMemoryManager::validate_list() const m_mem_mutex.unlock(); } -EmacTestMemoryManager &EmacTestMemoryManager::get_instance() { +EmacTestMemoryManager &EmacTestMemoryManager::get_instance() +{ static EmacTestMemoryManager test_memory_manager; return test_memory_manager; } diff --git a/TESTS/network/emac/emac_TestNetworkStack.h b/TESTS/network/emac/emac_TestNetworkStack.h index d781d15190b3..9b128b53a28a 100644 --- a/TESTS/network/emac/emac_TestNetworkStack.h +++ b/TESTS/network/emac/emac_TestNetworkStack.h @@ -56,7 +56,7 @@ class EmacTestNetworkStack : public OnboardNetworkStack, private mbed::NonCopyab const char *netmask, const char *gw, nsapi_ip_stack_t stack = DEFAULT_STACK, bool blocking = true - ); + ); /** Disconnect interface from the network * @@ -148,7 +148,7 @@ class EmacTestNetworkStack : public OnboardNetworkStack, private mbed::NonCopyab * @return 0 on success, negative error code on failure */ virtual nsapi_error_t gethostbyname(const char *host, - SocketAddress *address, nsapi_version_t version = NSAPI_UNSPEC); + SocketAddress *address, nsapi_version_t version = NSAPI_UNSPEC); /** Add a domain name server to list of servers to query * @@ -236,7 +236,7 @@ class EmacTestNetworkStack : public OnboardNetworkStack, private mbed::NonCopyab * @return 0 on success, negative error code on failure */ virtual nsapi_error_t socket_accept(nsapi_socket_t server, - nsapi_socket_t *handle, SocketAddress *address=0); + nsapi_socket_t *handle, SocketAddress *address = 0); /** Send data over a TCP socket * diff --git a/TESTS/network/emac/emac_ctp.cpp b/TESTS/network/emac/emac_ctp.cpp index dde3b82ca09b..71b5d22a93cc 100644 --- a/TESTS/network/emac/emac_ctp.cpp +++ b/TESTS/network/emac/emac_ctp.cpp @@ -90,7 +90,7 @@ ctp_function emac_if_ctp_header_handle(unsigned char *eth_input_frame, unsigned // Copy own address to origin memcpy(ð_output_frame[6], origin_addr, 6); return CTP_FORWARD; - // reply + // reply } else if (function == 0x0001) { *receipt_number = ethernet_ptr[1] << 8 | ethernet_ptr[0]; return CTP_REPLY; diff --git a/TESTS/network/emac/emac_test_initialize.cpp b/TESTS/network/emac/emac_test_initialize.cpp index 568cc577d60e..7d6638028816 100644 --- a/TESTS/network/emac/emac_test_initialize.cpp +++ b/TESTS/network/emac/emac_test_initialize.cpp @@ -83,7 +83,7 @@ void test_emac_initialize() int size = network_interface->scan(ap, 30); - for (int i=0; i(ð_mac_addr[0])); emac->get_hwaddr(eth_mac_addr); emac->set_hwaddr(eth_mac_addr); - printf("emac hwaddr %x:%x:%x:%x:%x:%x\r\n\r\n", eth_mac_addr[0],eth_mac_addr[1],eth_mac_addr[2],eth_mac_addr[3],eth_mac_addr[4],eth_mac_addr[5]); + printf("emac hwaddr %x:%x:%x:%x:%x:%x\r\n\r\n", eth_mac_addr[0], eth_mac_addr[1], eth_mac_addr[2], eth_mac_addr[3], eth_mac_addr[4], eth_mac_addr[5]); int mtu_size = emac->get_mtu_size(); printf("emac mtu %i\r\n\r\n", mtu_size); diff --git a/TESTS/network/emac/emac_test_memory.cpp b/TESTS/network/emac/emac_test_memory.cpp index 4c358af6e415..2bb781850ff6 100644 --- a/TESTS/network/emac/emac_test_memory.cpp +++ b/TESTS/network/emac/emac_test_memory.cpp @@ -86,19 +86,19 @@ void test_emac_memory_cb(int opt) break; case 6: - printf("STEP 6: memory available\r\n\r\n"); - emac_if_set_output_memory(true); - emac_if_set_input_memory(true); - memory = true; - break; + printf("STEP 6: memory available\r\n\r\n"); + emac_if_set_output_memory(true); + emac_if_set_input_memory(true); + memory = true; + break; case 7: - printf("STEP 7: memory available, alloc from heap\r\n\r\n"); - emac_if_set_output_memory(true); - emac_if_set_input_memory(true); - options |= CTP_OPT_HEAP; - memory = true; - break; + printf("STEP 7: memory available, alloc from heap\r\n\r\n"); + emac_if_set_output_memory(true); + emac_if_set_input_memory(true); + options |= CTP_OPT_HEAP; + memory = true; + break; case 8: // Test ended @@ -121,7 +121,7 @@ void test_emac_memory_cb(int opt) printf("too many retries\r\n\r\n"); SET_ERROR_FLAGS(TEST_FAILED); END_TEST_LOOP; - // Otherwise continues test + // Otherwise continues test } else { RESET_OUTGOING_MSG_DATA; next_len = true; diff --git a/TESTS/network/emac/emac_test_unicast.cpp b/TESTS/network/emac/emac_test_unicast.cpp index 53b258d33e12..fc20b0771b52 100644 --- a/TESTS/network/emac/emac_test_unicast.cpp +++ b/TESTS/network/emac/emac_test_unicast.cpp @@ -58,8 +58,8 @@ void test_emac_unicast_cb(int opt) if (++test_step == 3) { END_TEST_LOOP; } else { - retries = 0; - send_request = true; + retries = 0; + send_request = true; } } } diff --git a/TESTS/network/emac/emac_util.cpp b/TESTS/network/emac/emac_util.cpp index ede4925e13d0..f812adc2e4e7 100644 --- a/TESTS/network/emac/emac_util.cpp +++ b/TESTS/network/emac/emac_util.cpp @@ -81,7 +81,7 @@ typedef struct { extern struct netif *netif_list; // Broadcast address -const unsigned char eth_mac_broadcast_addr[ETH_MAC_ADDR_LEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; +const unsigned char eth_mac_broadcast_addr[ETH_MAC_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; // MTU size static int eth_mtu_size = 0; @@ -213,9 +213,9 @@ void emac_if_validate_outgoing_msg(void) if (!(outgoing_msgs[i].flags & PRINTED)) { if ((trace_level & TRACE_SUCCESS) || ((trace_level & TRACE_FAILURE) && failure)) { printf("response: receipt number %i %s %s %s\r\n\r\n", outgoing_msgs[i].receipt_number, - outgoing_msgs[i].flags & INVALID_LENGHT ? "LENGTH INVALID" : "LENGTH OK", - outgoing_msgs[i].flags & INVALID_DATA ? "DATA INVALID" : "DATA OK", - outgoing_msgs[i].flags & BROADCAST ? "BROADCAST" : "UNICAST"); + outgoing_msgs[i].flags & INVALID_LENGHT ? "LENGTH INVALID" : "LENGTH OK", + outgoing_msgs[i].flags & INVALID_DATA ? "DATA INVALID" : "DATA OK", + outgoing_msgs[i].flags & BROADCAST ? "BROADCAST" : "UNICAST"); outgoing_msgs[i].flags |= PRINTED; } } @@ -338,22 +338,22 @@ void emac_if_reset_all_error_flags(void) void emac_if_print_error_flags(void) { - int error_flags_value = emac_if_get_error_flags(); + int error_flags_value = emac_if_get_error_flags(); - char no_resp_message[50]; - if (error_flags_value & NO_RESPONSE) { - snprintf(no_resp_message, 50, "no response from echo server, counter: %i", no_response_cnt); - } else if (no_response_cnt > 0) { - printf("no response from echo server, counter: %i\r\n\r\n", no_response_cnt); - } + char no_resp_message[50]; + if (error_flags_value & NO_RESPONSE) { + snprintf(no_resp_message, 50, "no response from echo server, counter: %i", no_response_cnt); + } else if (no_response_cnt > 0) { + printf("no response from echo server, counter: %i\r\n\r\n", no_response_cnt); + } - printf("test result: %s%s%s%s%s%s\r\n\r\n", - error_flags_value ? "Test FAILED, reason: ": "PASS", - error_flags_value & TEST_FAILED ? "test failed ": "", - error_flags_value & MSG_VALID_ERROR ? "message content validation error ": "", - error_flags_value & OUT_OF_MSG_DATA ? "out of message validation data storage ": "", - error_flags_value & NO_FREE_MEM_BUF ? "no free memory buffers ": "", - error_flags_value & NO_RESPONSE ? no_resp_message: ""); + printf("test result: %s%s%s%s%s%s\r\n\r\n", + error_flags_value ? "Test FAILED, reason: " : "PASS", + error_flags_value & TEST_FAILED ? "test failed " : "", + error_flags_value & MSG_VALID_ERROR ? "message content validation error " : "", + error_flags_value & OUT_OF_MSG_DATA ? "out of message validation data storage " : "", + error_flags_value & NO_FREE_MEM_BUF ? "no free memory buffers " : "", + error_flags_value & NO_RESPONSE ? no_resp_message : ""); } void emac_if_set_trace_level(char trace_level_value) @@ -371,14 +371,14 @@ void emac_if_trace_to_ascii_hex_dump(const char *prefix, int len, unsigned char int line_len = 0; for (int i = 0; i < len; i++) { - if ((line_len % 14) == 0) { - if (line_len != 0) { - printf("\r\n"); - } - printf("%s %06x", prefix, line_len); - } - line_len++; - printf(" %02x", data[i]); + if ((line_len % 14) == 0) { + if (line_len != 0) { + printf("\r\n"); + } + printf("%s %06x", prefix, line_len); + } + line_len++; + printf(" %02x", data[i]); } printf("\r\n\r\n"); } @@ -417,7 +417,7 @@ void emac_if_check_memory(bool output) void emac_if_set_memory(bool memory) { static bool memory_value = true; - if (memory_value != memory ) { + if (memory_value != memory) { memory_value = memory; EmacTestMemoryManager *mem_mngr = emac_m_mngr_get(); mem_mngr->set_memory_available(memory); @@ -468,7 +468,7 @@ static void link_input_event_cb(void *buf) worker_loop_event_queue.call(current_test_step_cb_fnc, INPUT); } #if MBED_CONF_APP_ECHO_SERVER - // Echoes only if configured as echo server + // Echoes only if configured as echo server } else if (function == CTP_FORWARD) { emac_if_memory_buffer_write(buf, eth_output_frame_data, false); emac_if_get()->link_out(buf); @@ -479,9 +479,9 @@ static void link_input_event_cb(void *buf) emac_if_add_echo_server_addr(ð_input_frame_data[6]); if (trace_level & TRACE_ETH_FRAMES) { - printf("INP> LEN %i\r\n\r\n", length); - const char trace_type[] = "INP>"; - emac_if_trace_to_ascii_hex_dump(trace_type, ETH_FRAME_HEADER_LEN, eth_input_frame_data); + printf("INP> LEN %i\r\n\r\n", length); + const char trace_type[] = "INP>"; + emac_if_trace_to_ascii_hex_dump(trace_type, ETH_FRAME_HEADER_LEN, eth_input_frame_data); } } } diff --git a/TESTS/network/emac/main.cpp b/TESTS/network/emac/main.cpp index fe05b721abca..9d8dcff25ff7 100644 --- a/TESTS/network/emac/main.cpp +++ b/TESTS/network/emac/main.cpp @@ -43,10 +43,6 @@ #endif #endif -#ifndef DEVICE_EMAC -#error [NOT_SUPPORTED] Device EMAC has to be enabled for the target -#endif - #include "greentea-client/test_env.h" #include "unity.h" #include "utest.h" @@ -57,7 +53,8 @@ using namespace utest::v1; // Test setup -utest::v1::status_t test_setup(const size_t number_of_cases) { +utest::v1::status_t test_setup(const size_t number_of_cases) +{ #if !MBED_CONF_APP_ECHO_SERVER GREENTEA_SETUP(600, "default_auto"); #endif diff --git a/TESTS/network/wifi/get_interface.cpp b/TESTS/network/wifi/get_interface.cpp index a3ffcf0b53f4..9a4759e1bdf9 100644 --- a/TESTS/network/wifi/get_interface.cpp +++ b/TESTS/network/wifi/get_interface.cpp @@ -16,11 +16,11 @@ */ #ifndef MBED_CONF_APP_OBJECT_CONSTRUCTION - #error [NOT_SUPPORTED] No network interface found for this target. +#error [NOT_SUPPORTED] No network interface found for this target. #endif #if !defined(MBED_CONF_APP_WIFI_SECURE_SSID) && !defined(MBED_CONF_APP_WIFI_UNSECURE_SSID) - #error [NOT_SUPPORTED] Requires parameters from mbed_app.json +#error [NOT_SUPPORTED] Requires parameters from mbed_app.json #endif #include "mbed.h" diff --git a/TESTS/network/wifi/main.cpp b/TESTS/network/wifi/main.cpp index 7cd699e33b35..703ff0406e33 100644 --- a/TESTS/network/wifi/main.cpp +++ b/TESTS/network/wifi/main.cpp @@ -16,7 +16,7 @@ */ #ifndef MBED_CONF_APP_OBJECT_CONSTRUCTION - #error [NOT_SUPPORTED] No network interface found for this target. +#error [NOT_SUPPORTED] No network interface found for this target. #endif #include "mbed.h" @@ -48,7 +48,8 @@ using namespace utest::v1; -utest::v1::status_t test_setup(const size_t number_of_cases) { +utest::v1::status_t test_setup(const size_t number_of_cases) +{ GREENTEA_SETUP(240, "default_auto"); return verbose_test_setup_handler(number_of_cases); } @@ -90,6 +91,7 @@ Case cases[] = { Specification specification(test_setup, cases); // Entry point into the tests -int main() { +int main() +{ return !Harness::run(specification); } diff --git a/TESTS/network/wifi/wifi-constructor.cpp b/TESTS/network/wifi/wifi-constructor.cpp index 3fa80ff5cbb2..d97d3a3fde26 100644 --- a/TESTS/network/wifi/wifi-constructor.cpp +++ b/TESTS/network/wifi/wifi-constructor.cpp @@ -23,7 +23,8 @@ using namespace utest::v1; -void wifi_constructor() { +void wifi_constructor() +{ WiFiInterface *wifi = get_interface(); TEST_ASSERT(wifi); } diff --git a/TESTS/network/wifi/wifi_connect_disconnect_repeat.cpp b/TESTS/network/wifi/wifi_connect_disconnect_repeat.cpp index 90f4c5994bd6..e23980e18af1 100644 --- a/TESTS/network/wifi/wifi_connect_disconnect_repeat.cpp +++ b/TESTS/network/wifi/wifi_connect_disconnect_repeat.cpp @@ -33,7 +33,7 @@ void wifi_connect_disconnect_repeat(void) error = wifi->set_credentials(MBED_CONF_APP_WIFI_UNSECURE_SSID, NULL); TEST_ASSERT(error == NSAPI_ERROR_OK); - for(int i=0; i<10; i++) { + for (int i = 0; i < 10; i++) { error = wifi->connect(); TEST_ASSERT(error == NSAPI_ERROR_OK); error = wifi->disconnect(); diff --git a/TESTS/network/wifi/wifi_connect_params_channel_fail.cpp b/TESTS/network/wifi/wifi_connect_params_channel_fail.cpp index a3c531fd1038..d365ed77d849 100644 --- a/TESTS/network/wifi/wifi_connect_params_channel_fail.cpp +++ b/TESTS/network/wifi/wifi_connect_params_channel_fail.cpp @@ -35,7 +35,7 @@ void wifi_connect_params_channel_fail(void) } nsapi_error_t error = wifi->connect(MBED_CONF_APP_WIFI_SECURE_SSID, MBED_CONF_APP_WIFI_PASSWORD, get_security(), MBED_CONF_APP_WIFI_CH_UNSECURE); - TEST_ASSERT(error==NSAPI_ERROR_CONNECTION_TIMEOUT || error==NSAPI_ERROR_NO_CONNECTION); + TEST_ASSERT(error == NSAPI_ERROR_CONNECTION_TIMEOUT || error == NSAPI_ERROR_NO_CONNECTION); } #endif // defined(MBED_CONF_APP_WIFI_SECURE_SSID) diff --git a/TESTS/network/wifi/wifi_connect_params_valid_secure.cpp b/TESTS/network/wifi/wifi_connect_params_valid_secure.cpp index 112a4af389c9..eca57ef20239 100644 --- a/TESTS/network/wifi/wifi_connect_params_valid_secure.cpp +++ b/TESTS/network/wifi/wifi_connect_params_valid_secure.cpp @@ -29,7 +29,7 @@ void wifi_connect_params_valid_secure(void) { WiFiInterface *wifi = get_interface(); - if(wifi->connect(MBED_CONF_APP_WIFI_SECURE_SSID, MBED_CONF_APP_WIFI_PASSWORD, get_security()) == NSAPI_ERROR_OK) { + if (wifi->connect(MBED_CONF_APP_WIFI_SECURE_SSID, MBED_CONF_APP_WIFI_PASSWORD, get_security()) == NSAPI_ERROR_OK) { return; } diff --git a/TESTS/network/wifi/wifi_scan.cpp b/TESTS/network/wifi/wifi_scan.cpp index 6986d64d1ef1..ab74e5deb991 100644 --- a/TESTS/network/wifi/wifi_scan.cpp +++ b/TESTS/network/wifi/wifi_scan.cpp @@ -44,7 +44,7 @@ void wifi_scan(void) TEST_ASSERT_EQUAL_INT_MESSAGE(6, sscanf(MBED_CONF_APP_AP_MAC_SECURE, coversion_string, &secure_bssid[0], &secure_bssid[1], &secure_bssid[2], &secure_bssid[3], &secure_bssid[4], &secure_bssid[5]), "Failed to convert ap-mac-secure from mbed_app.json"); TEST_ASSERT_EQUAL_INT_MESSAGE(6, sscanf(MBED_CONF_APP_AP_MAC_UNSECURE, coversion_string, &unsecure_bssid[0], &unsecure_bssid[1], &unsecure_bssid[2], &unsecure_bssid[3], &unsecure_bssid[4], &unsecure_bssid[5]), "Failed to convert ap-mac-unsecure from mbed_app.json"); - for (int i=0; i + +// Export ROM end address +#if defined(TOOLCHAIN_GCC_ARM) +extern uint32_t __etext; +#define FLASHIAP_ROM_END ((uint32_t) &__etext) +#elif defined(TOOLCHAIN_ARM) +extern uint32_t Load$$LR$$LR_IROM1$$Limit[]; +#define FLASHIAP_ROM_END ((uint32_t)Load$$LR$$LR_IROM1$$Limit) +#elif defined(TOOLCHAIN_IAR) +#pragma section=".rodata" +#pragma section=".text" +#define FLASHIAP_ROM_END (std::max((uint32_t) __section_end(".rodata"), (uint32_t) __section_end(".text"))) +#endif namespace mbed { diff --git a/drivers/MbedCRC.cpp b/drivers/MbedCRC.cpp index cc90945ac09f..9ddca26c6fea 100644 --- a/drivers/MbedCRC.cpp +++ b/drivers/MbedCRC.cpp @@ -24,46 +24,6 @@ namespace mbed { /* Default values for different types of polynomials */ -template<> -MbedCRC::MbedCRC(uint32_t initial_xor, uint32_t final_xor, bool reflect_data, bool reflect_remainder): - _initial_value(initial_xor), _final_xor(final_xor), _reflect_data(reflect_data), _reflect_remainder(reflect_remainder), - _crc_table((uint32_t *)Table_CRC_32bit_ANSI) -{ - mbed_crc_ctor(); -} - -template<> -MbedCRC::MbedCRC(uint32_t initial_xor, uint32_t final_xor, bool reflect_data, bool reflect_remainder): - _initial_value(initial_xor), _final_xor(final_xor), _reflect_data(reflect_data), _reflect_remainder(reflect_remainder), - _crc_table((uint32_t *)Table_CRC_8bit_CCITT) -{ - mbed_crc_ctor(); -} - -template<> -MbedCRC::MbedCRC(uint32_t initial_xor, uint32_t final_xor, bool reflect_data, bool reflect_remainder): - _initial_value(initial_xor), _final_xor(final_xor), _reflect_data(reflect_data), _reflect_remainder(reflect_remainder), - _crc_table((uint32_t *)Table_CRC_7Bit_SD) -{ - mbed_crc_ctor(); -} - -template<> -MbedCRC::MbedCRC(uint32_t initial_xor, uint32_t final_xor, bool reflect_data, bool reflect_remainder): - _initial_value(initial_xor), _final_xor(final_xor), _reflect_data(reflect_data), _reflect_remainder(reflect_remainder), - _crc_table((uint32_t *)Table_CRC_16bit_CCITT) -{ - mbed_crc_ctor(); -} - -template<> -MbedCRC::MbedCRC(uint32_t initial_xor, uint32_t final_xor, bool reflect_data, bool reflect_remainder): - _initial_value(initial_xor), _final_xor(final_xor), _reflect_data(reflect_data), _reflect_remainder(reflect_remainder), - _crc_table((uint32_t *)Table_CRC_16bit_IBM) -{ - mbed_crc_ctor(); -} - template<> MbedCRC::MbedCRC(): _initial_value(~(0x0)), _final_xor(~(0x0)), _reflect_data(true), _reflect_remainder(true), diff --git a/drivers/MbedCRC.h b/drivers/MbedCRC.h index 1221c4fe0bcd..b85131f5d327 100644 --- a/drivers/MbedCRC.h +++ b/drivers/MbedCRC.h @@ -95,7 +95,14 @@ namespace mbed { template class MbedCRC { public: - enum CrcMode { HARDWARE = 0, TABLE, BITWISE }; + enum CrcMode + { +#ifdef DEVICE_CRC + HARDWARE = 0, +#endif + TABLE = 1, + BITWISE + }; public: typedef uint64_t crc_data_size_t; @@ -117,7 +124,7 @@ class MbedCRC { */ MbedCRC(uint32_t initial_xor, uint32_t final_xor, bool reflect_data, bool reflect_remainder) : _initial_value(initial_xor), _final_xor(final_xor), _reflect_data(reflect_data), - _reflect_remainder(reflect_remainder), _crc_table(NULL) + _reflect_remainder(reflect_remainder) { mbed_crc_ctor(); } @@ -170,12 +177,12 @@ class MbedCRC { int32_t compute_partial(void *buffer, crc_data_size_t size, uint32_t *crc) { switch (_mode) { - case HARDWARE: #ifdef DEVICE_CRC + case HARDWARE: hal_crc_compute_partial((uint8_t *)buffer, size); -#endif // DEVICE_CRC *crc = 0; return 0; +#endif case TABLE: return table_compute_partial(buffer, size, crc); case BITWISE: @@ -229,20 +236,22 @@ class MbedCRC { { MBED_ASSERT(crc != NULL); - if (_mode == HARDWARE) { #ifdef DEVICE_CRC + if (_mode == HARDWARE) { *crc = hal_crc_get_result(); return 0; -#else - return -1; -#endif } - +#endif uint32_t p_crc = *crc; if ((width < 8) && (NULL == _crc_table)) { p_crc = (uint32_t)(p_crc << (8 - width)); } - *crc = (reflect_remainder(p_crc) ^ _final_xor) & get_crc_mask(); + // Optimized algorithm for 32BitANSI does not need additional reflect_remainder + if ((TABLE == _mode) && (POLY_32BIT_ANSI == polynomial)) { + *crc = (p_crc ^ _final_xor) & get_crc_mask(); + } else { + *crc = (reflect_remainder(p_crc) ^ _final_xor) & get_crc_mask(); + } return 0; } @@ -420,9 +429,9 @@ class MbedCRC { } } else { uint32_t *crc_table = (uint32_t *)_crc_table; - for (crc_data_size_t byte = 0; byte < size; byte++) { - data_byte = reflect_bytes(data[byte]) ^ (p_crc >> (width - 8)); - p_crc = crc_table[data_byte] ^ (p_crc << 8); + for (crc_data_size_t i = 0; i < size; i++) { + p_crc = (p_crc >> 4) ^ crc_table[(p_crc ^ (data[i] >> 0)) & 0xf]; + p_crc = (p_crc >> 4) ^ crc_table[(p_crc ^ (data[i] >> 4)) & 0xf]; } } *crc = p_crc & get_crc_mask(); @@ -436,8 +445,6 @@ class MbedCRC { { MBED_STATIC_ASSERT(width <= 32, "Max 32-bit CRC supported"); - _mode = (_crc_table != NULL) ? TABLE : BITWISE; - #ifdef DEVICE_CRC crc_mbed_config_t config; config.polynomial = polynomial; @@ -449,8 +456,30 @@ class MbedCRC { if (hal_crc_is_supported(&config)) { _mode = HARDWARE; + return; } #endif + switch (polynomial) { + case POLY_32BIT_ANSI: + _crc_table = (uint32_t *)Table_CRC_32bit_ANSI; + break; + case POLY_8BIT_CCITT: + _crc_table = (uint32_t *)Table_CRC_8bit_CCITT; + break; + case POLY_7BIT_SD: + _crc_table = (uint32_t *)Table_CRC_7Bit_SD; + break; + case POLY_16BIT_CCITT: + _crc_table = (uint32_t *)Table_CRC_16bit_CCITT; + break; + case POLY_16BIT_IBM: + _crc_table = (uint32_t *)Table_CRC_16bit_IBM; + break; + default: + _crc_table = NULL; + break; + } + _mode = (_crc_table != NULL) ? TABLE : BITWISE; } }; diff --git a/drivers/TableCRC.cpp b/drivers/TableCRC.cpp index b63cfcaaf7d7..f3cb42158a9d 100644 --- a/drivers/TableCRC.cpp +++ b/drivers/TableCRC.cpp @@ -108,39 +108,11 @@ extern const uint16_t Table_CRC_16bit_IBM[MBED_CRC_TABLE_SIZE] = { 0x220, 0x8225, 0x822f, 0x22a, 0x823b, 0x23e, 0x234, 0x8231, 0x8213, 0x216, 0x21c, 0x8219 }; -extern const uint32_t Table_CRC_32bit_ANSI[MBED_CRC_TABLE_SIZE] = { - 0x0, 0x4c11db7, 0x9823b6e, 0xd4326d9, 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005, - 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, - 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, - 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd, - 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, - 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, - 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95, - 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, - 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, - 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x18aeb13, 0x54bf6a4, 0x808d07d, 0xcc9cdca, - 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, - 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, - 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692, - 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, - 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, - 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a, - 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, - 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, - 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b, - 0x315d626, 0x7d4cb91, 0xa97ed48, 0xe56f0ff, 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, - 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, - 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3, - 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, - 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, - 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, - 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, - 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, 0x29f3d35, 0x65e2082, 0xb1d065b, 0xfdc1bec, - 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, - 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, - 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, - 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c, - 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 +extern const uint32_t Table_CRC_32bit_ANSI[MBED_OPTIMIZED_CRC_TABLE_SIZE] = { + 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, + 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, + 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, + 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c }; /** @}*/ diff --git a/drivers/TableCRC.h b/drivers/TableCRC.h index 224e14e532bd..6a8715915784 100644 --- a/drivers/TableCRC.h +++ b/drivers/TableCRC.h @@ -23,13 +23,14 @@ namespace mbed { /** \addtogroup drivers */ /** @{*/ -#define MBED_CRC_TABLE_SIZE 256 +#define MBED_CRC_TABLE_SIZE 256 +#define MBED_OPTIMIZED_CRC_TABLE_SIZE 16 extern const uint8_t Table_CRC_7Bit_SD[MBED_CRC_TABLE_SIZE]; extern const uint8_t Table_CRC_8bit_CCITT[MBED_CRC_TABLE_SIZE]; extern const uint16_t Table_CRC_16bit_CCITT[MBED_CRC_TABLE_SIZE]; extern const uint16_t Table_CRC_16bit_IBM[MBED_CRC_TABLE_SIZE]; -extern const uint32_t Table_CRC_32bit_ANSI[MBED_CRC_TABLE_SIZE]; +extern const uint32_t Table_CRC_32bit_ANSI[MBED_OPTIMIZED_CRC_TABLE_SIZE]; /** @}*/ } // namespace mbed diff --git a/events/Event.h b/events/Event.h index a704409bf8ba..6032856cdc0a 100644 --- a/events/Event.h +++ b/events/Event.h @@ -48,9 +48,10 @@ class Event { * @param f Function to execute when the event is dispatched */ template - Event(EventQueue *q, F f) { + Event(EventQueue *q, F f) + { _event = static_cast( - equeue_alloc(&q->_equeue, sizeof(struct event) + sizeof(F))); + equeue_alloc(&q->_equeue, sizeof(struct event) + sizeof(F))); if (_event) { _event->equeue = &q->_equeue; @@ -61,7 +62,7 @@ class Event { _event->post = &Event::event_post; _event->dtor = &Event::event_dtor; - new (_event+1) F(f); + new (_event + 1) F(f); _event->ref = 1; } @@ -69,7 +70,8 @@ class Event { /** Copy constructor for events */ - Event(const Event &e) { + Event(const Event &e) + { _event = 0; if (e._event) { _event = e._event; @@ -79,7 +81,8 @@ class Event { /** Assignment operator for events */ - Event &operator=(const Event &that) { + Event &operator=(const Event &that) + { if (this != &that) { this->~Event(); new (this) Event(that); @@ -90,7 +93,8 @@ class Event { /** Destructor for events */ - ~Event() { + ~Event() + { if (_event) { _event->ref -= 1; if (_event->ref == 0) { @@ -104,7 +108,8 @@ class Event { * * @param delay Millisecond delay before dispatching the event */ - void delay(int delay) { + void delay(int delay) + { if (_event) { _event->delay = delay; } @@ -114,7 +119,8 @@ class Event { * * @param period Millisecond period for repeatedly dispatching an event */ - void period(int period) { + void period(int period) + { if (_event) { _event->period = period; } @@ -132,7 +138,8 @@ class Event { * be passed to EventQueue::cancel, or an id of 0 if * there is not enough memory to allocate the event. */ - int post() const { + int post() const + { if (!_event) { return 0; } @@ -144,7 +151,8 @@ class Event { /** Posts an event onto the underlying event queue, returning void * */ - void call() const { + void call() const + { MBED_UNUSED int id = post(); MBED_ASSERT(id); } @@ -152,7 +160,8 @@ class Event { /** Posts an event onto the underlying event queue, returning void * */ - void operator()() const { + void operator()() const + { return call(); } @@ -160,8 +169,9 @@ class Event { * * @param func Event to call passed as a void pointer */ - static void thunk(void *func) { - return static_cast(func)->call(); + static void thunk(void *func) + { + return static_cast(func)->call(); } /** Cancels the most recently posted event @@ -175,7 +185,8 @@ class Event { * function does not guarantee that the event will not execute after it * returns, as the event may have already begun executing. */ - void cancel() const { + void cancel() const + { if (_event) { equeue_cancel(_event->equeue, _event->id); } @@ -198,14 +209,15 @@ class Event { // Event attributes template - static int event_post(struct event *e) { + static int event_post(struct event *e) + { typedef EventQueue::context00 C; void *p = equeue_alloc(e->equeue, sizeof(C)); if (!p) { return 0; } - new (p) C(*(F*)(e + 1)); + new (p) C(*(F *)(e + 1)); equeue_event_delay(p, e->delay); equeue_event_period(p, e->period); equeue_event_dtor(p, &EventQueue::function_dtor); @@ -213,8 +225,9 @@ class Event { } template - static void event_dtor(struct event *e) { - ((F*)(e + 1))->~F(); + static void event_dtor(struct event *e) + { + ((F *)(e + 1))->~F(); } public: @@ -227,7 +240,8 @@ class Event { * arguments to the underlying callback. */ template - Event(EventQueue *q, F f, C0 c0) { + Event(EventQueue *q, F f, C0 c0) + { new (this) Event(q, EventQueue::context10(f, c0)); } @@ -240,7 +254,8 @@ class Event { * arguments to the underlying callback. */ template - Event(EventQueue *q, F f, C0 c0, C1 c1) { + Event(EventQueue *q, F f, C0 c0, C1 c1) + { new (this) Event(q, EventQueue::context20(f, c0, c1)); } @@ -253,7 +268,8 @@ class Event { * arguments to the underlying callback. */ template - Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2) { + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2) + { new (this) Event(q, EventQueue::context30(f, c0, c1, c2)); } @@ -266,7 +282,8 @@ class Event { * arguments to the underlying callback. */ template - Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3) { + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3) + { new (this) Event(q, EventQueue::context40(f, c0, c1, c2, c3)); } @@ -279,7 +296,8 @@ class Event { * arguments to the underlying callback. */ template - Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) + { new (this) Event(q, EventQueue::context50(f, c0, c1, c2, c3, c4)); } @@ -287,7 +305,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, T *obj, R (T::*method)(B0), B0 b0) { + Event(EventQueue *q, T *obj, R(T::*method)(B0), B0 b0) + { new (this) Event(q, mbed::callback(obj, method), b0); } @@ -295,7 +314,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const T *obj, R (T::*method)(B0) const, B0 b0) { + Event(EventQueue *q, const T *obj, R(T::*method)(B0) const, B0 b0) + { new (this) Event(q, mbed::callback(obj, method), b0); } @@ -303,7 +323,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, volatile T *obj, R (T::*method)(B0) volatile, B0 b0) { + Event(EventQueue *q, volatile T *obj, R(T::*method)(B0) volatile, B0 b0) + { new (this) Event(q, mbed::callback(obj, method), b0); } @@ -311,7 +332,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0) const volatile, B0 b0) { + Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0) const volatile, B0 b0) + { new (this) Event(q, mbed::callback(obj, method), b0); } @@ -319,7 +341,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, T *obj, R (T::*method)(B0, B1), B0 b0, B1 b1) { + Event(EventQueue *q, T *obj, R(T::*method)(B0, B1), B0 b0, B1 b1) + { new (this) Event(q, mbed::callback(obj, method), b0, b1); } @@ -327,7 +350,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1) const, B0 b0, B1 b1) { + Event(EventQueue *q, const T *obj, R(T::*method)(B0, B1) const, B0 b0, B1 b1) + { new (this) Event(q, mbed::callback(obj, method), b0, b1); } @@ -335,7 +359,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1) volatile, B0 b0, B1 b1) { + Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, B1) volatile, B0 b0, B1 b1) + { new (this) Event(q, mbed::callback(obj, method), b0, b1); } @@ -343,7 +368,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1) const volatile, B0 b0, B1 b1) { + Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, B1) const volatile, B0 b0, B1 b1) + { new (this) Event(q, mbed::callback(obj, method), b0, b1); } @@ -351,7 +377,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2), B0 b0, B1 b1, B2 b2) { + Event(EventQueue *q, T *obj, R(T::*method)(B0, B1, B2), B0 b0, B1 b1, B2 b2) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); } @@ -359,7 +386,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2) const, B0 b0, B1 b1, B2 b2) { + Event(EventQueue *q, const T *obj, R(T::*method)(B0, B1, B2) const, B0 b0, B1 b1, B2 b2) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); } @@ -367,7 +395,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2) volatile, B0 b0, B1 b1, B2 b2) { + Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, B1, B2) volatile, B0 b0, B1 b1, B2 b2) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); } @@ -375,7 +404,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2) const volatile, B0 b0, B1 b1, B2 b2) { + Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, B1, B2) const volatile, B0 b0, B1 b1, B2 b2) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); } @@ -383,7 +413,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, B3), B0 b0, B1 b1, B2 b2, B3 b3) { + Event(EventQueue *q, T *obj, R(T::*method)(B0, B1, B2, B3), B0 b0, B1 b1, B2 b2, B3 b3) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); } @@ -391,7 +422,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, B3) const, B0 b0, B1 b1, B2 b2, B3 b3) { + Event(EventQueue *q, const T *obj, R(T::*method)(B0, B1, B2, B3) const, B0 b0, B1 b1, B2 b2, B3 b3) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); } @@ -399,7 +431,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, B3) volatile, B0 b0, B1 b1, B2 b2, B3 b3) { + Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, B1, B2, B3) volatile, B0 b0, B1 b1, B2 b2, B3 b3) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); } @@ -407,7 +440,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, B3) const volatile, B0 b0, B1 b1, B2 b2, B3 b3) { + Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, B1, B2, B3) const volatile, B0 b0, B1 b1, B2 b2, B3 b3) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); } @@ -415,7 +449,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, B3, B4), B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + Event(EventQueue *q, T *obj, R(T::*method)(B0, B1, B2, B3, B4), B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); } @@ -423,7 +458,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, B3, B4) const, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + Event(EventQueue *q, const T *obj, R(T::*method)(B0, B1, B2, B3, B4) const, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); } @@ -431,7 +467,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4) volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, B1, B2, B3, B4) volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); } @@ -439,7 +476,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4) const volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, B1, B2, B3, B4) const volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); } }; @@ -462,9 +500,10 @@ class Event { * @param f Function to execute when the event is dispatched */ template - Event(EventQueue *q, F f) { + Event(EventQueue *q, F f) + { _event = static_cast( - equeue_alloc(&q->_equeue, sizeof(struct event) + sizeof(F))); + equeue_alloc(&q->_equeue, sizeof(struct event) + sizeof(F))); if (_event) { _event->equeue = &q->_equeue; @@ -475,7 +514,7 @@ class Event { _event->post = &Event::event_post; _event->dtor = &Event::event_dtor; - new (_event+1) F(f); + new (_event + 1) F(f); _event->ref = 1; } @@ -483,7 +522,8 @@ class Event { /** Copy constructor for events */ - Event(const Event &e) { + Event(const Event &e) + { _event = 0; if (e._event) { _event = e._event; @@ -493,7 +533,8 @@ class Event { /** Assignment operator for events */ - Event &operator=(const Event &that) { + Event &operator=(const Event &that) + { if (this != &that) { this->~Event(); new (this) Event(that); @@ -504,7 +545,8 @@ class Event { /** Destructor for events */ - ~Event() { + ~Event() + { if (_event) { _event->ref -= 1; if (_event->ref == 0) { @@ -518,7 +560,8 @@ class Event { * * @param delay Millisecond delay before dispatching the event */ - void delay(int delay) { + void delay(int delay) + { if (_event) { _event->delay = delay; } @@ -528,7 +571,8 @@ class Event { * * @param period Millisecond period for repeatedly dispatching an event */ - void period(int period) { + void period(int period) + { if (_event) { _event->period = period; } @@ -547,7 +591,8 @@ class Event { * be passed to EventQueue::cancel, or an id of 0 if * there is not enough memory to allocate the event. */ - int post(A0 a0) const { + int post(A0 a0) const + { if (!_event) { return 0; } @@ -560,7 +605,8 @@ class Event { * * @param a0 Argument to pass to the event */ - void call(A0 a0) const { + void call(A0 a0) const + { MBED_UNUSED int id = post(a0); MBED_ASSERT(id); } @@ -569,7 +615,8 @@ class Event { * * @param a0 Argument to pass to the event */ - void operator()(A0 a0) const { + void operator()(A0 a0) const + { return call(a0); } @@ -578,8 +625,9 @@ class Event { * @param func Event to call passed as a void pointer * @param a0 Argument to pass to the event */ - static void thunk(void *func, A0 a0) { - return static_cast(func)->call(a0); + static void thunk(void *func, A0 a0) + { + return static_cast(func)->call(a0); } /** Cancels the most recently posted event @@ -593,7 +641,8 @@ class Event { * function does not guarantee that the event will not execute after it * returns, as the event may have already begun executing. */ - void cancel() const { + void cancel() const + { if (_event) { equeue_cancel(_event->equeue, _event->id); } @@ -616,14 +665,15 @@ class Event { // Event attributes template - static int event_post(struct event *e, A0 a0) { + static int event_post(struct event *e, A0 a0) + { typedef EventQueue::context10 C; void *p = equeue_alloc(e->equeue, sizeof(C)); if (!p) { return 0; } - new (p) C(*(F*)(e + 1), a0); + new (p) C(*(F *)(e + 1), a0); equeue_event_delay(p, e->delay); equeue_event_period(p, e->period); equeue_event_dtor(p, &EventQueue::function_dtor); @@ -631,8 +681,9 @@ class Event { } template - static void event_dtor(struct event *e) { - ((F*)(e + 1))->~F(); + static void event_dtor(struct event *e) + { + ((F *)(e + 1))->~F(); } public: @@ -645,7 +696,8 @@ class Event { * arguments to the underlying callback. */ template - Event(EventQueue *q, F f, C0 c0) { + Event(EventQueue *q, F f, C0 c0) + { new (this) Event(q, EventQueue::context11(f, c0)); } @@ -658,7 +710,8 @@ class Event { * arguments to the underlying callback. */ template - Event(EventQueue *q, F f, C0 c0, C1 c1) { + Event(EventQueue *q, F f, C0 c0, C1 c1) + { new (this) Event(q, EventQueue::context21(f, c0, c1)); } @@ -671,7 +724,8 @@ class Event { * arguments to the underlying callback. */ template - Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2) { + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2) + { new (this) Event(q, EventQueue::context31(f, c0, c1, c2)); } @@ -684,7 +738,8 @@ class Event { * arguments to the underlying callback. */ template - Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3) { + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3) + { new (this) Event(q, EventQueue::context41(f, c0, c1, c2, c3)); } @@ -697,7 +752,8 @@ class Event { * arguments to the underlying callback. */ template - Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) + { new (this) Event(q, EventQueue::context51(f, c0, c1, c2, c3, c4)); } @@ -705,7 +761,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, T *obj, R (T::*method)(B0, A0), B0 b0) { + Event(EventQueue *q, T *obj, R(T::*method)(B0, A0), B0 b0) + { new (this) Event(q, mbed::callback(obj, method), b0); } @@ -713,7 +770,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const T *obj, R (T::*method)(B0, A0) const, B0 b0) { + Event(EventQueue *q, const T *obj, R(T::*method)(B0, A0) const, B0 b0) + { new (this) Event(q, mbed::callback(obj, method), b0); } @@ -721,7 +779,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, A0) volatile, B0 b0) { + Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, A0) volatile, B0 b0) + { new (this) Event(q, mbed::callback(obj, method), b0); } @@ -729,7 +788,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, A0) const volatile, B0 b0) { + Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, A0) const volatile, B0 b0) + { new (this) Event(q, mbed::callback(obj, method), b0); } @@ -737,7 +797,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, A0), B0 b0, B1 b1) { + Event(EventQueue *q, T *obj, R(T::*method)(B0, B1, A0), B0 b0, B1 b1) + { new (this) Event(q, mbed::callback(obj, method), b0, b1); } @@ -745,7 +806,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, A0) const, B0 b0, B1 b1) { + Event(EventQueue *q, const T *obj, R(T::*method)(B0, B1, A0) const, B0 b0, B1 b1) + { new (this) Event(q, mbed::callback(obj, method), b0, b1); } @@ -753,7 +815,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, A0) volatile, B0 b0, B1 b1) { + Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, B1, A0) volatile, B0 b0, B1 b1) + { new (this) Event(q, mbed::callback(obj, method), b0, b1); } @@ -761,7 +824,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, A0) const volatile, B0 b0, B1 b1) { + Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, B1, A0) const volatile, B0 b0, B1 b1) + { new (this) Event(q, mbed::callback(obj, method), b0, b1); } @@ -769,7 +833,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, A0), B0 b0, B1 b1, B2 b2) { + Event(EventQueue *q, T *obj, R(T::*method)(B0, B1, B2, A0), B0 b0, B1 b1, B2 b2) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); } @@ -777,7 +842,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, A0) const, B0 b0, B1 b1, B2 b2) { + Event(EventQueue *q, const T *obj, R(T::*method)(B0, B1, B2, A0) const, B0 b0, B1 b1, B2 b2) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); } @@ -785,7 +851,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, A0) volatile, B0 b0, B1 b1, B2 b2) { + Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, B1, B2, A0) volatile, B0 b0, B1 b1, B2 b2) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); } @@ -793,7 +860,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, A0) const volatile, B0 b0, B1 b1, B2 b2) { + Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, B1, B2, A0) const volatile, B0 b0, B1 b1, B2 b2) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); } @@ -801,7 +869,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, B3, A0), B0 b0, B1 b1, B2 b2, B3 b3) { + Event(EventQueue *q, T *obj, R(T::*method)(B0, B1, B2, B3, A0), B0 b0, B1 b1, B2 b2, B3 b3) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); } @@ -809,7 +878,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, B3, A0) const, B0 b0, B1 b1, B2 b2, B3 b3) { + Event(EventQueue *q, const T *obj, R(T::*method)(B0, B1, B2, B3, A0) const, B0 b0, B1 b1, B2 b2, B3 b3) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); } @@ -817,7 +887,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0) volatile, B0 b0, B1 b1, B2 b2, B3 b3) { + Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, B1, B2, B3, A0) volatile, B0 b0, B1 b1, B2 b2, B3 b3) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); } @@ -825,7 +896,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0) const volatile, B0 b0, B1 b1, B2 b2, B3 b3) { + Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, B1, B2, B3, A0) const volatile, B0 b0, B1 b1, B2 b2, B3 b3) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); } @@ -833,7 +905,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0), B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + Event(EventQueue *q, T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0), B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); } @@ -841,7 +914,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0) const, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + Event(EventQueue *q, const T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0) const, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); } @@ -849,7 +923,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0) volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0) volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); } @@ -857,7 +932,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0) const volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0) const volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); } }; @@ -880,9 +956,10 @@ class Event { * @param f Function to execute when the event is dispatched */ template - Event(EventQueue *q, F f) { + Event(EventQueue *q, F f) + { _event = static_cast( - equeue_alloc(&q->_equeue, sizeof(struct event) + sizeof(F))); + equeue_alloc(&q->_equeue, sizeof(struct event) + sizeof(F))); if (_event) { _event->equeue = &q->_equeue; @@ -893,7 +970,7 @@ class Event { _event->post = &Event::event_post; _event->dtor = &Event::event_dtor; - new (_event+1) F(f); + new (_event + 1) F(f); _event->ref = 1; } @@ -901,7 +978,8 @@ class Event { /** Copy constructor for events */ - Event(const Event &e) { + Event(const Event &e) + { _event = 0; if (e._event) { _event = e._event; @@ -911,7 +989,8 @@ class Event { /** Assignment operator for events */ - Event &operator=(const Event &that) { + Event &operator=(const Event &that) + { if (this != &that) { this->~Event(); new (this) Event(that); @@ -922,7 +1001,8 @@ class Event { /** Destructor for events */ - ~Event() { + ~Event() + { if (_event) { _event->ref -= 1; if (_event->ref == 0) { @@ -936,7 +1016,8 @@ class Event { * * @param delay Millisecond delay before dispatching the event */ - void delay(int delay) { + void delay(int delay) + { if (_event) { _event->delay = delay; } @@ -946,7 +1027,8 @@ class Event { * * @param period Millisecond period for repeatedly dispatching an event */ - void period(int period) { + void period(int period) + { if (_event) { _event->period = period; } @@ -965,7 +1047,8 @@ class Event { * be passed to EventQueue::cancel, or an id of 0 if * there is not enough memory to allocate the event. */ - int post(A0 a0, A1 a1) const { + int post(A0 a0, A1 a1) const + { if (!_event) { return 0; } @@ -978,7 +1061,8 @@ class Event { * * @param a0,a1 Arguments to pass to the event */ - void call(A0 a0, A1 a1) const { + void call(A0 a0, A1 a1) const + { MBED_UNUSED int id = post(a0, a1); MBED_ASSERT(id); } @@ -987,7 +1071,8 @@ class Event { * * @param a0,a1 Arguments to pass to the event */ - void operator()(A0 a0, A1 a1) const { + void operator()(A0 a0, A1 a1) const + { return call(a0, a1); } @@ -996,8 +1081,9 @@ class Event { * @param func Event to call passed as a void pointer * @param a0,a1 Arguments to pass to the event */ - static void thunk(void *func, A0 a0, A1 a1) { - return static_cast(func)->call(a0, a1); + static void thunk(void *func, A0 a0, A1 a1) + { + return static_cast(func)->call(a0, a1); } /** Cancels the most recently posted event @@ -1011,7 +1097,8 @@ class Event { * function does not guarantee that the event will not execute after it * returns, as the event may have already begun executing. */ - void cancel() const { + void cancel() const + { if (_event) { equeue_cancel(_event->equeue, _event->id); } @@ -1034,14 +1121,15 @@ class Event { // Event attributes template - static int event_post(struct event *e, A0 a0, A1 a1) { + static int event_post(struct event *e, A0 a0, A1 a1) + { typedef EventQueue::context20 C; void *p = equeue_alloc(e->equeue, sizeof(C)); if (!p) { return 0; } - new (p) C(*(F*)(e + 1), a0, a1); + new (p) C(*(F *)(e + 1), a0, a1); equeue_event_delay(p, e->delay); equeue_event_period(p, e->period); equeue_event_dtor(p, &EventQueue::function_dtor); @@ -1049,8 +1137,9 @@ class Event { } template - static void event_dtor(struct event *e) { - ((F*)(e + 1))->~F(); + static void event_dtor(struct event *e) + { + ((F *)(e + 1))->~F(); } public: @@ -1063,7 +1152,8 @@ class Event { * arguments to the underlying callback. */ template - Event(EventQueue *q, F f, C0 c0) { + Event(EventQueue *q, F f, C0 c0) + { new (this) Event(q, EventQueue::context12(f, c0)); } @@ -1076,7 +1166,8 @@ class Event { * arguments to the underlying callback. */ template - Event(EventQueue *q, F f, C0 c0, C1 c1) { + Event(EventQueue *q, F f, C0 c0, C1 c1) + { new (this) Event(q, EventQueue::context22(f, c0, c1)); } @@ -1089,7 +1180,8 @@ class Event { * arguments to the underlying callback. */ template - Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2) { + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2) + { new (this) Event(q, EventQueue::context32(f, c0, c1, c2)); } @@ -1102,7 +1194,8 @@ class Event { * arguments to the underlying callback. */ template - Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3) { + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3) + { new (this) Event(q, EventQueue::context42(f, c0, c1, c2, c3)); } @@ -1115,7 +1208,8 @@ class Event { * arguments to the underlying callback. */ template - Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) + { new (this) Event(q, EventQueue::context52(f, c0, c1, c2, c3, c4)); } @@ -1123,7 +1217,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, T *obj, R (T::*method)(B0, A0, A1), B0 b0) { + Event(EventQueue *q, T *obj, R(T::*method)(B0, A0, A1), B0 b0) + { new (this) Event(q, mbed::callback(obj, method), b0); } @@ -1131,7 +1226,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const T *obj, R (T::*method)(B0, A0, A1) const, B0 b0) { + Event(EventQueue *q, const T *obj, R(T::*method)(B0, A0, A1) const, B0 b0) + { new (this) Event(q, mbed::callback(obj, method), b0); } @@ -1139,7 +1235,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, A0, A1) volatile, B0 b0) { + Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, A0, A1) volatile, B0 b0) + { new (this) Event(q, mbed::callback(obj, method), b0); } @@ -1147,7 +1244,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, A0, A1) const volatile, B0 b0) { + Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, A0, A1) const volatile, B0 b0) + { new (this) Event(q, mbed::callback(obj, method), b0); } @@ -1155,7 +1253,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, A0, A1), B0 b0, B1 b1) { + Event(EventQueue *q, T *obj, R(T::*method)(B0, B1, A0, A1), B0 b0, B1 b1) + { new (this) Event(q, mbed::callback(obj, method), b0, b1); } @@ -1163,7 +1262,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, A0, A1) const, B0 b0, B1 b1) { + Event(EventQueue *q, const T *obj, R(T::*method)(B0, B1, A0, A1) const, B0 b0, B1 b1) + { new (this) Event(q, mbed::callback(obj, method), b0, b1); } @@ -1171,7 +1271,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, A0, A1) volatile, B0 b0, B1 b1) { + Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, B1, A0, A1) volatile, B0 b0, B1 b1) + { new (this) Event(q, mbed::callback(obj, method), b0, b1); } @@ -1179,7 +1280,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, A0, A1) const volatile, B0 b0, B1 b1) { + Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, B1, A0, A1) const volatile, B0 b0, B1 b1) + { new (this) Event(q, mbed::callback(obj, method), b0, b1); } @@ -1187,7 +1289,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, A0, A1), B0 b0, B1 b1, B2 b2) { + Event(EventQueue *q, T *obj, R(T::*method)(B0, B1, B2, A0, A1), B0 b0, B1 b1, B2 b2) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); } @@ -1195,7 +1298,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, A0, A1) const, B0 b0, B1 b1, B2 b2) { + Event(EventQueue *q, const T *obj, R(T::*method)(B0, B1, B2, A0, A1) const, B0 b0, B1 b1, B2 b2) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); } @@ -1203,7 +1307,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1) volatile, B0 b0, B1 b1, B2 b2) { + Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, B1, B2, A0, A1) volatile, B0 b0, B1 b1, B2 b2) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); } @@ -1211,7 +1316,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1) const volatile, B0 b0, B1 b1, B2 b2) { + Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, B1, B2, A0, A1) const volatile, B0 b0, B1 b1, B2 b2) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); } @@ -1219,7 +1325,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1), B0 b0, B1 b1, B2 b2, B3 b3) { + Event(EventQueue *q, T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1), B0 b0, B1 b1, B2 b2, B3 b3) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); } @@ -1227,7 +1334,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1) const, B0 b0, B1 b1, B2 b2, B3 b3) { + Event(EventQueue *q, const T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1) const, B0 b0, B1 b1, B2 b2, B3 b3) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); } @@ -1235,7 +1343,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1) volatile, B0 b0, B1 b1, B2 b2, B3 b3) { + Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1) volatile, B0 b0, B1 b1, B2 b2, B3 b3) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); } @@ -1243,7 +1352,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1) const volatile, B0 b0, B1 b1, B2 b2, B3 b3) { + Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1) const volatile, B0 b0, B1 b1, B2 b2, B3 b3) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); } @@ -1251,7 +1361,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1), B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + Event(EventQueue *q, T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1), B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); } @@ -1259,7 +1370,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1) const, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + Event(EventQueue *q, const T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1) const, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); } @@ -1267,7 +1379,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1) volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1) volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); } @@ -1275,7 +1388,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1) const volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1) const volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); } }; @@ -1298,9 +1412,10 @@ class Event { * @param f Function to execute when the event is dispatched */ template - Event(EventQueue *q, F f) { + Event(EventQueue *q, F f) + { _event = static_cast( - equeue_alloc(&q->_equeue, sizeof(struct event) + sizeof(F))); + equeue_alloc(&q->_equeue, sizeof(struct event) + sizeof(F))); if (_event) { _event->equeue = &q->_equeue; @@ -1311,7 +1426,7 @@ class Event { _event->post = &Event::event_post; _event->dtor = &Event::event_dtor; - new (_event+1) F(f); + new (_event + 1) F(f); _event->ref = 1; } @@ -1319,7 +1434,8 @@ class Event { /** Copy constructor for events */ - Event(const Event &e) { + Event(const Event &e) + { _event = 0; if (e._event) { _event = e._event; @@ -1329,7 +1445,8 @@ class Event { /** Assignment operator for events */ - Event &operator=(const Event &that) { + Event &operator=(const Event &that) + { if (this != &that) { this->~Event(); new (this) Event(that); @@ -1340,7 +1457,8 @@ class Event { /** Destructor for events */ - ~Event() { + ~Event() + { if (_event) { _event->ref -= 1; if (_event->ref == 0) { @@ -1354,7 +1472,8 @@ class Event { * * @param delay Millisecond delay before dispatching the event */ - void delay(int delay) { + void delay(int delay) + { if (_event) { _event->delay = delay; } @@ -1364,7 +1483,8 @@ class Event { * * @param period Millisecond period for repeatedly dispatching an event */ - void period(int period) { + void period(int period) + { if (_event) { _event->period = period; } @@ -1383,7 +1503,8 @@ class Event { * be passed to EventQueue::cancel, or an id of 0 if * there is not enough memory to allocate the event. */ - int post(A0 a0, A1 a1, A2 a2) const { + int post(A0 a0, A1 a1, A2 a2) const + { if (!_event) { return 0; } @@ -1396,7 +1517,8 @@ class Event { * * @param a0,a1,a2 Arguments to pass to the event */ - void call(A0 a0, A1 a1, A2 a2) const { + void call(A0 a0, A1 a1, A2 a2) const + { MBED_UNUSED int id = post(a0, a1, a2); MBED_ASSERT(id); } @@ -1405,7 +1527,8 @@ class Event { * * @param a0,a1,a2 Arguments to pass to the event */ - void operator()(A0 a0, A1 a1, A2 a2) const { + void operator()(A0 a0, A1 a1, A2 a2) const + { return call(a0, a1, a2); } @@ -1414,8 +1537,9 @@ class Event { * @param func Event to call passed as a void pointer * @param a0,a1,a2 Arguments to pass to the event */ - static void thunk(void *func, A0 a0, A1 a1, A2 a2) { - return static_cast(func)->call(a0, a1, a2); + static void thunk(void *func, A0 a0, A1 a1, A2 a2) + { + return static_cast(func)->call(a0, a1, a2); } /** Cancels the most recently posted event @@ -1429,7 +1553,8 @@ class Event { * function does not guarantee that the event will not execute after it * returns, as the event may have already begun executing. */ - void cancel() const { + void cancel() const + { if (_event) { equeue_cancel(_event->equeue, _event->id); } @@ -1452,14 +1577,15 @@ class Event { // Event attributes template - static int event_post(struct event *e, A0 a0, A1 a1, A2 a2) { + static int event_post(struct event *e, A0 a0, A1 a1, A2 a2) + { typedef EventQueue::context30 C; void *p = equeue_alloc(e->equeue, sizeof(C)); if (!p) { return 0; } - new (p) C(*(F*)(e + 1), a0, a1, a2); + new (p) C(*(F *)(e + 1), a0, a1, a2); equeue_event_delay(p, e->delay); equeue_event_period(p, e->period); equeue_event_dtor(p, &EventQueue::function_dtor); @@ -1467,8 +1593,9 @@ class Event { } template - static void event_dtor(struct event *e) { - ((F*)(e + 1))->~F(); + static void event_dtor(struct event *e) + { + ((F *)(e + 1))->~F(); } public: @@ -1481,7 +1608,8 @@ class Event { * arguments to the underlying callback. */ template - Event(EventQueue *q, F f, C0 c0) { + Event(EventQueue *q, F f, C0 c0) + { new (this) Event(q, EventQueue::context13(f, c0)); } @@ -1494,7 +1622,8 @@ class Event { * arguments to the underlying callback. */ template - Event(EventQueue *q, F f, C0 c0, C1 c1) { + Event(EventQueue *q, F f, C0 c0, C1 c1) + { new (this) Event(q, EventQueue::context23(f, c0, c1)); } @@ -1507,7 +1636,8 @@ class Event { * arguments to the underlying callback. */ template - Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2) { + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2) + { new (this) Event(q, EventQueue::context33(f, c0, c1, c2)); } @@ -1520,7 +1650,8 @@ class Event { * arguments to the underlying callback. */ template - Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3) { + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3) + { new (this) Event(q, EventQueue::context43(f, c0, c1, c2, c3)); } @@ -1533,7 +1664,8 @@ class Event { * arguments to the underlying callback. */ template - Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) + { new (this) Event(q, EventQueue::context53(f, c0, c1, c2, c3, c4)); } @@ -1541,7 +1673,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, T *obj, R (T::*method)(B0, A0, A1, A2), B0 b0) { + Event(EventQueue *q, T *obj, R(T::*method)(B0, A0, A1, A2), B0 b0) + { new (this) Event(q, mbed::callback(obj, method), b0); } @@ -1549,7 +1682,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const T *obj, R (T::*method)(B0, A0, A1, A2) const, B0 b0) { + Event(EventQueue *q, const T *obj, R(T::*method)(B0, A0, A1, A2) const, B0 b0) + { new (this) Event(q, mbed::callback(obj, method), b0); } @@ -1557,7 +1691,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, A0, A1, A2) volatile, B0 b0) { + Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, A0, A1, A2) volatile, B0 b0) + { new (this) Event(q, mbed::callback(obj, method), b0); } @@ -1565,7 +1700,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, A0, A1, A2) const volatile, B0 b0) { + Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, A0, A1, A2) const volatile, B0 b0) + { new (this) Event(q, mbed::callback(obj, method), b0); } @@ -1573,7 +1709,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, A0, A1, A2), B0 b0, B1 b1) { + Event(EventQueue *q, T *obj, R(T::*method)(B0, B1, A0, A1, A2), B0 b0, B1 b1) + { new (this) Event(q, mbed::callback(obj, method), b0, b1); } @@ -1581,7 +1718,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, A0, A1, A2) const, B0 b0, B1 b1) { + Event(EventQueue *q, const T *obj, R(T::*method)(B0, B1, A0, A1, A2) const, B0 b0, B1 b1) + { new (this) Event(q, mbed::callback(obj, method), b0, b1); } @@ -1589,7 +1727,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2) volatile, B0 b0, B1 b1) { + Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, B1, A0, A1, A2) volatile, B0 b0, B1 b1) + { new (this) Event(q, mbed::callback(obj, method), b0, b1); } @@ -1597,7 +1736,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2) const volatile, B0 b0, B1 b1) { + Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, B1, A0, A1, A2) const volatile, B0 b0, B1 b1) + { new (this) Event(q, mbed::callback(obj, method), b0, b1); } @@ -1605,7 +1745,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2), B0 b0, B1 b1, B2 b2) { + Event(EventQueue *q, T *obj, R(T::*method)(B0, B1, B2, A0, A1, A2), B0 b0, B1 b1, B2 b2) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); } @@ -1613,7 +1754,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2) const, B0 b0, B1 b1, B2 b2) { + Event(EventQueue *q, const T *obj, R(T::*method)(B0, B1, B2, A0, A1, A2) const, B0 b0, B1 b1, B2 b2) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); } @@ -1621,7 +1763,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2) volatile, B0 b0, B1 b1, B2 b2) { + Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, B1, B2, A0, A1, A2) volatile, B0 b0, B1 b1, B2 b2) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); } @@ -1629,7 +1772,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2) const volatile, B0 b0, B1 b1, B2 b2) { + Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, B1, B2, A0, A1, A2) const volatile, B0 b0, B1 b1, B2 b2) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); } @@ -1637,7 +1781,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2), B0 b0, B1 b1, B2 b2, B3 b3) { + Event(EventQueue *q, T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1, A2), B0 b0, B1 b1, B2 b2, B3 b3) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); } @@ -1645,7 +1790,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2) const, B0 b0, B1 b1, B2 b2, B3 b3) { + Event(EventQueue *q, const T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1, A2) const, B0 b0, B1 b1, B2 b2, B3 b3) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); } @@ -1653,7 +1799,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2) volatile, B0 b0, B1 b1, B2 b2, B3 b3) { + Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1, A2) volatile, B0 b0, B1 b1, B2 b2, B3 b3) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); } @@ -1661,7 +1808,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2) const volatile, B0 b0, B1 b1, B2 b2, B3 b3) { + Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1, A2) const volatile, B0 b0, B1 b1, B2 b2, B3 b3) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); } @@ -1669,7 +1817,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2), B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + Event(EventQueue *q, T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1, A2), B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); } @@ -1677,7 +1826,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2) const, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + Event(EventQueue *q, const T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1, A2) const, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); } @@ -1685,7 +1835,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2) volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1, A2) volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); } @@ -1693,7 +1844,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2) const volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1, A2) const volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); } }; @@ -1716,9 +1868,10 @@ class Event { * @param f Function to execute when the event is dispatched */ template - Event(EventQueue *q, F f) { + Event(EventQueue *q, F f) + { _event = static_cast( - equeue_alloc(&q->_equeue, sizeof(struct event) + sizeof(F))); + equeue_alloc(&q->_equeue, sizeof(struct event) + sizeof(F))); if (_event) { _event->equeue = &q->_equeue; @@ -1729,7 +1882,7 @@ class Event { _event->post = &Event::event_post; _event->dtor = &Event::event_dtor; - new (_event+1) F(f); + new (_event + 1) F(f); _event->ref = 1; } @@ -1737,7 +1890,8 @@ class Event { /** Copy constructor for events */ - Event(const Event &e) { + Event(const Event &e) + { _event = 0; if (e._event) { _event = e._event; @@ -1747,7 +1901,8 @@ class Event { /** Assignment operator for events */ - Event &operator=(const Event &that) { + Event &operator=(const Event &that) + { if (this != &that) { this->~Event(); new (this) Event(that); @@ -1758,7 +1913,8 @@ class Event { /** Destructor for events */ - ~Event() { + ~Event() + { if (_event) { _event->ref -= 1; if (_event->ref == 0) { @@ -1772,7 +1928,8 @@ class Event { * * @param delay Millisecond delay before dispatching the event */ - void delay(int delay) { + void delay(int delay) + { if (_event) { _event->delay = delay; } @@ -1782,7 +1939,8 @@ class Event { * * @param period Millisecond period for repeatedly dispatching an event */ - void period(int period) { + void period(int period) + { if (_event) { _event->period = period; } @@ -1801,7 +1959,8 @@ class Event { * be passed to EventQueue::cancel, or an id of 0 if * there is not enough memory to allocate the event. */ - int post(A0 a0, A1 a1, A2 a2, A3 a3) const { + int post(A0 a0, A1 a1, A2 a2, A3 a3) const + { if (!_event) { return 0; } @@ -1814,7 +1973,8 @@ class Event { * * @param a0,a1,a2,a3 Arguments to pass to the event */ - void call(A0 a0, A1 a1, A2 a2, A3 a3) const { + void call(A0 a0, A1 a1, A2 a2, A3 a3) const + { MBED_UNUSED int id = post(a0, a1, a2, a3); MBED_ASSERT(id); } @@ -1823,7 +1983,8 @@ class Event { * * @param a0,a1,a2,a3 Arguments to pass to the event */ - void operator()(A0 a0, A1 a1, A2 a2, A3 a3) const { + void operator()(A0 a0, A1 a1, A2 a2, A3 a3) const + { return call(a0, a1, a2, a3); } @@ -1832,8 +1993,9 @@ class Event { * @param func Event to call passed as a void pointer * @param a0,a1,a2,a3 Arguments to pass to the event */ - static void thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3) { - return static_cast(func)->call(a0, a1, a2, a3); + static void thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3) + { + return static_cast(func)->call(a0, a1, a2, a3); } /** Cancels the most recently posted event @@ -1847,7 +2009,8 @@ class Event { * function does not guarantee that the event will not execute after it * returns, as the event may have already begun executing. */ - void cancel() const { + void cancel() const + { if (_event) { equeue_cancel(_event->equeue, _event->id); } @@ -1870,14 +2033,15 @@ class Event { // Event attributes template - static int event_post(struct event *e, A0 a0, A1 a1, A2 a2, A3 a3) { + static int event_post(struct event *e, A0 a0, A1 a1, A2 a2, A3 a3) + { typedef EventQueue::context40 C; void *p = equeue_alloc(e->equeue, sizeof(C)); if (!p) { return 0; } - new (p) C(*(F*)(e + 1), a0, a1, a2, a3); + new (p) C(*(F *)(e + 1), a0, a1, a2, a3); equeue_event_delay(p, e->delay); equeue_event_period(p, e->period); equeue_event_dtor(p, &EventQueue::function_dtor); @@ -1885,8 +2049,9 @@ class Event { } template - static void event_dtor(struct event *e) { - ((F*)(e + 1))->~F(); + static void event_dtor(struct event *e) + { + ((F *)(e + 1))->~F(); } public: @@ -1899,7 +2064,8 @@ class Event { * arguments to the underlying callback. */ template - Event(EventQueue *q, F f, C0 c0) { + Event(EventQueue *q, F f, C0 c0) + { new (this) Event(q, EventQueue::context14(f, c0)); } @@ -1912,7 +2078,8 @@ class Event { * arguments to the underlying callback. */ template - Event(EventQueue *q, F f, C0 c0, C1 c1) { + Event(EventQueue *q, F f, C0 c0, C1 c1) + { new (this) Event(q, EventQueue::context24(f, c0, c1)); } @@ -1925,7 +2092,8 @@ class Event { * arguments to the underlying callback. */ template - Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2) { + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2) + { new (this) Event(q, EventQueue::context34(f, c0, c1, c2)); } @@ -1938,7 +2106,8 @@ class Event { * arguments to the underlying callback. */ template - Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3) { + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3) + { new (this) Event(q, EventQueue::context44(f, c0, c1, c2, c3)); } @@ -1951,7 +2120,8 @@ class Event { * arguments to the underlying callback. */ template - Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) + { new (this) Event(q, EventQueue::context54(f, c0, c1, c2, c3, c4)); } @@ -1959,7 +2129,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, T *obj, R (T::*method)(B0, A0, A1, A2, A3), B0 b0) { + Event(EventQueue *q, T *obj, R(T::*method)(B0, A0, A1, A2, A3), B0 b0) + { new (this) Event(q, mbed::callback(obj, method), b0); } @@ -1967,7 +2138,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const T *obj, R (T::*method)(B0, A0, A1, A2, A3) const, B0 b0) { + Event(EventQueue *q, const T *obj, R(T::*method)(B0, A0, A1, A2, A3) const, B0 b0) + { new (this) Event(q, mbed::callback(obj, method), b0); } @@ -1975,7 +2147,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, A0, A1, A2, A3) volatile, B0 b0) { + Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, A0, A1, A2, A3) volatile, B0 b0) + { new (this) Event(q, mbed::callback(obj, method), b0); } @@ -1983,7 +2156,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, A0, A1, A2, A3) const volatile, B0 b0) { + Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, A0, A1, A2, A3) const volatile, B0 b0) + { new (this) Event(q, mbed::callback(obj, method), b0); } @@ -1991,7 +2165,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3), B0 b0, B1 b1) { + Event(EventQueue *q, T *obj, R(T::*method)(B0, B1, A0, A1, A2, A3), B0 b0, B1 b1) + { new (this) Event(q, mbed::callback(obj, method), b0, b1); } @@ -1999,7 +2174,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3) const, B0 b0, B1 b1) { + Event(EventQueue *q, const T *obj, R(T::*method)(B0, B1, A0, A1, A2, A3) const, B0 b0, B1 b1) + { new (this) Event(q, mbed::callback(obj, method), b0, b1); } @@ -2007,7 +2183,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3) volatile, B0 b0, B1 b1) { + Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, B1, A0, A1, A2, A3) volatile, B0 b0, B1 b1) + { new (this) Event(q, mbed::callback(obj, method), b0, b1); } @@ -2015,7 +2192,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3) const volatile, B0 b0, B1 b1) { + Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, B1, A0, A1, A2, A3) const volatile, B0 b0, B1 b1) + { new (this) Event(q, mbed::callback(obj, method), b0, b1); } @@ -2023,7 +2201,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3), B0 b0, B1 b1, B2 b2) { + Event(EventQueue *q, T *obj, R(T::*method)(B0, B1, B2, A0, A1, A2, A3), B0 b0, B1 b1, B2 b2) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); } @@ -2031,7 +2210,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3) const, B0 b0, B1 b1, B2 b2) { + Event(EventQueue *q, const T *obj, R(T::*method)(B0, B1, B2, A0, A1, A2, A3) const, B0 b0, B1 b1, B2 b2) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); } @@ -2039,7 +2219,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3) volatile, B0 b0, B1 b1, B2 b2) { + Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, B1, B2, A0, A1, A2, A3) volatile, B0 b0, B1 b1, B2 b2) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); } @@ -2047,7 +2228,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3) const volatile, B0 b0, B1 b1, B2 b2) { + Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, B1, B2, A0, A1, A2, A3) const volatile, B0 b0, B1 b1, B2 b2) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); } @@ -2055,7 +2237,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3), B0 b0, B1 b1, B2 b2, B3 b3) { + Event(EventQueue *q, T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1, A2, A3), B0 b0, B1 b1, B2 b2, B3 b3) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); } @@ -2063,7 +2246,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3) const, B0 b0, B1 b1, B2 b2, B3 b3) { + Event(EventQueue *q, const T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1, A2, A3) const, B0 b0, B1 b1, B2 b2, B3 b3) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); } @@ -2071,7 +2255,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3) volatile, B0 b0, B1 b1, B2 b2, B3 b3) { + Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1, A2, A3) volatile, B0 b0, B1 b1, B2 b2, B3 b3) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); } @@ -2079,7 +2264,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3) const volatile, B0 b0, B1 b1, B2 b2, B3 b3) { + Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1, A2, A3) const volatile, B0 b0, B1 b1, B2 b2, B3 b3) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); } @@ -2087,7 +2273,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3), B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + Event(EventQueue *q, T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3), B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); } @@ -2095,7 +2282,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3) const, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + Event(EventQueue *q, const T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3) const, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); } @@ -2103,7 +2291,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3) volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3) volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); } @@ -2111,7 +2300,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3) const volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3) const volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); } }; @@ -2134,9 +2324,10 @@ class Event { * @param f Function to execute when the event is dispatched */ template - Event(EventQueue *q, F f) { + Event(EventQueue *q, F f) + { _event = static_cast( - equeue_alloc(&q->_equeue, sizeof(struct event) + sizeof(F))); + equeue_alloc(&q->_equeue, sizeof(struct event) + sizeof(F))); if (_event) { _event->equeue = &q->_equeue; @@ -2147,7 +2338,7 @@ class Event { _event->post = &Event::event_post; _event->dtor = &Event::event_dtor; - new (_event+1) F(f); + new (_event + 1) F(f); _event->ref = 1; } @@ -2155,7 +2346,8 @@ class Event { /** Copy constructor for events */ - Event(const Event &e) { + Event(const Event &e) + { _event = 0; if (e._event) { _event = e._event; @@ -2165,7 +2357,8 @@ class Event { /** Assignment operator for events */ - Event &operator=(const Event &that) { + Event &operator=(const Event &that) + { if (this != &that) { this->~Event(); new (this) Event(that); @@ -2176,7 +2369,8 @@ class Event { /** Destructor for events */ - ~Event() { + ~Event() + { if (_event) { _event->ref -= 1; if (_event->ref == 0) { @@ -2190,7 +2384,8 @@ class Event { * * @param delay Millisecond delay before dispatching the event */ - void delay(int delay) { + void delay(int delay) + { if (_event) { _event->delay = delay; } @@ -2200,7 +2395,8 @@ class Event { * * @param period Millisecond period for repeatedly dispatching an event */ - void period(int period) { + void period(int period) + { if (_event) { _event->period = period; } @@ -2219,7 +2415,8 @@ class Event { * be passed to EventQueue::cancel, or an id of 0 if * there is not enough memory to allocate the event. */ - int post(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const { + int post(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const + { if (!_event) { return 0; } @@ -2232,7 +2429,8 @@ class Event { * * @param a0,a1,a2,a3,a4 Arguments to pass to the event */ - void call(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const { + void call(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const + { MBED_UNUSED int id = post(a0, a1, a2, a3, a4); MBED_ASSERT(id); } @@ -2241,7 +2439,8 @@ class Event { * * @param a0,a1,a2,a3,a4 Arguments to pass to the event */ - void operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const { + void operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const + { return call(a0, a1, a2, a3, a4); } @@ -2250,8 +2449,9 @@ class Event { * @param func Event to call passed as a void pointer * @param a0,a1,a2,a3,a4 Arguments to pass to the event */ - static void thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { - return static_cast(func)->call(a0, a1, a2, a3, a4); + static void thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) + { + return static_cast(func)->call(a0, a1, a2, a3, a4); } /** Cancels the most recently posted event @@ -2265,7 +2465,8 @@ class Event { * function does not guarantee that the event will not execute after it * returns, as the event may have already begun executing. */ - void cancel() const { + void cancel() const + { if (_event) { equeue_cancel(_event->equeue, _event->id); } @@ -2288,14 +2489,15 @@ class Event { // Event attributes template - static int event_post(struct event *e, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + static int event_post(struct event *e, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) + { typedef EventQueue::context50 C; void *p = equeue_alloc(e->equeue, sizeof(C)); if (!p) { return 0; } - new (p) C(*(F*)(e + 1), a0, a1, a2, a3, a4); + new (p) C(*(F *)(e + 1), a0, a1, a2, a3, a4); equeue_event_delay(p, e->delay); equeue_event_period(p, e->period); equeue_event_dtor(p, &EventQueue::function_dtor); @@ -2303,8 +2505,9 @@ class Event { } template - static void event_dtor(struct event *e) { - ((F*)(e + 1))->~F(); + static void event_dtor(struct event *e) + { + ((F *)(e + 1))->~F(); } public: @@ -2317,7 +2520,8 @@ class Event { * arguments to the underlying callback. */ template - Event(EventQueue *q, F f, C0 c0) { + Event(EventQueue *q, F f, C0 c0) + { new (this) Event(q, EventQueue::context15(f, c0)); } @@ -2330,7 +2534,8 @@ class Event { * arguments to the underlying callback. */ template - Event(EventQueue *q, F f, C0 c0, C1 c1) { + Event(EventQueue *q, F f, C0 c0, C1 c1) + { new (this) Event(q, EventQueue::context25(f, c0, c1)); } @@ -2343,7 +2548,8 @@ class Event { * arguments to the underlying callback. */ template - Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2) { + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2) + { new (this) Event(q, EventQueue::context35(f, c0, c1, c2)); } @@ -2356,7 +2562,8 @@ class Event { * arguments to the underlying callback. */ template - Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3) { + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3) + { new (this) Event(q, EventQueue::context45(f, c0, c1, c2, c3)); } @@ -2369,7 +2576,8 @@ class Event { * arguments to the underlying callback. */ template - Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) + { new (this) Event(q, EventQueue::context55(f, c0, c1, c2, c3, c4)); } @@ -2377,7 +2585,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, T *obj, R (T::*method)(B0, A0, A1, A2, A3, A4), B0 b0) { + Event(EventQueue *q, T *obj, R(T::*method)(B0, A0, A1, A2, A3, A4), B0 b0) + { new (this) Event(q, mbed::callback(obj, method), b0); } @@ -2385,7 +2594,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const T *obj, R (T::*method)(B0, A0, A1, A2, A3, A4) const, B0 b0) { + Event(EventQueue *q, const T *obj, R(T::*method)(B0, A0, A1, A2, A3, A4) const, B0 b0) + { new (this) Event(q, mbed::callback(obj, method), b0); } @@ -2393,7 +2603,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, A0, A1, A2, A3, A4) volatile, B0 b0) { + Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, A0, A1, A2, A3, A4) volatile, B0 b0) + { new (this) Event(q, mbed::callback(obj, method), b0); } @@ -2401,7 +2612,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, A0, A1, A2, A3, A4) const volatile, B0 b0) { + Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, A0, A1, A2, A3, A4) const volatile, B0 b0) + { new (this) Event(q, mbed::callback(obj, method), b0); } @@ -2409,7 +2621,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3, A4), B0 b0, B1 b1) { + Event(EventQueue *q, T *obj, R(T::*method)(B0, B1, A0, A1, A2, A3, A4), B0 b0, B1 b1) + { new (this) Event(q, mbed::callback(obj, method), b0, b1); } @@ -2417,7 +2630,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3, A4) const, B0 b0, B1 b1) { + Event(EventQueue *q, const T *obj, R(T::*method)(B0, B1, A0, A1, A2, A3, A4) const, B0 b0, B1 b1) + { new (this) Event(q, mbed::callback(obj, method), b0, b1); } @@ -2425,7 +2639,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3, A4) volatile, B0 b0, B1 b1) { + Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, B1, A0, A1, A2, A3, A4) volatile, B0 b0, B1 b1) + { new (this) Event(q, mbed::callback(obj, method), b0, b1); } @@ -2433,7 +2648,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3, A4) const volatile, B0 b0, B1 b1) { + Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, B1, A0, A1, A2, A3, A4) const volatile, B0 b0, B1 b1) + { new (this) Event(q, mbed::callback(obj, method), b0, b1); } @@ -2441,7 +2657,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3, A4), B0 b0, B1 b1, B2 b2) { + Event(EventQueue *q, T *obj, R(T::*method)(B0, B1, B2, A0, A1, A2, A3, A4), B0 b0, B1 b1, B2 b2) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); } @@ -2449,7 +2666,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3, A4) const, B0 b0, B1 b1, B2 b2) { + Event(EventQueue *q, const T *obj, R(T::*method)(B0, B1, B2, A0, A1, A2, A3, A4) const, B0 b0, B1 b1, B2 b2) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); } @@ -2457,7 +2675,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3, A4) volatile, B0 b0, B1 b1, B2 b2) { + Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, B1, B2, A0, A1, A2, A3, A4) volatile, B0 b0, B1 b1, B2 b2) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); } @@ -2465,7 +2684,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3, A4) const volatile, B0 b0, B1 b1, B2 b2) { + Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, B1, B2, A0, A1, A2, A3, A4) const volatile, B0 b0, B1 b1, B2 b2) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); } @@ -2473,7 +2693,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3, A4), B0 b0, B1 b1, B2 b2, B3 b3) { + Event(EventQueue *q, T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1, A2, A3, A4), B0 b0, B1 b1, B2 b2, B3 b3) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); } @@ -2481,7 +2702,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3, A4) const, B0 b0, B1 b1, B2 b2, B3 b3) { + Event(EventQueue *q, const T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1, A2, A3, A4) const, B0 b0, B1 b1, B2 b2, B3 b3) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); } @@ -2489,7 +2711,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3, A4) volatile, B0 b0, B1 b1, B2 b2, B3 b3) { + Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1, A2, A3, A4) volatile, B0 b0, B1 b1, B2 b2, B3 b3) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); } @@ -2497,7 +2720,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3, A4) const volatile, B0 b0, B1 b1, B2 b2, B3 b3) { + Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1, A2, A3, A4) const volatile, B0 b0, B1 b1, B2 b2, B3 b3) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); } @@ -2505,7 +2729,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4), B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + Event(EventQueue *q, T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4), B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); } @@ -2513,7 +2738,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4) const, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + Event(EventQueue *q, const T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4) const, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); } @@ -2521,7 +2747,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4) volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4) volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); } @@ -2529,7 +2756,8 @@ class Event { * @see Event::Event */ template - Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4) const volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4) const volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) + { new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); } }; @@ -2541,1082 +2769,1298 @@ class Event { // Convenience functions declared here to avoid cyclic // dependency between Event and EventQueue template -Event EventQueue::event(R (*func)()) { +Event EventQueue::event(R(*func)()) +{ return Event(this, func); } template -Event EventQueue::event(T *obj, R (T::*method)()) { +Event EventQueue::event(T *obj, R(T::*method)()) +{ return Event(this, mbed::callback(obj, method)); } template -Event EventQueue::event(const T *obj, R (T::*method)() const) { +Event EventQueue::event(const T *obj, R(T::*method)() const) +{ return Event(this, mbed::callback(obj, method)); } template -Event EventQueue::event(volatile T *obj, R (T::*method)() volatile) { +Event EventQueue::event(volatile T *obj, R(T::*method)() volatile) +{ return Event(this, mbed::callback(obj, method)); } template -Event EventQueue::event(const volatile T *obj, R (T::*method)() const volatile) { +Event EventQueue::event(const volatile T *obj, R(T::*method)() const volatile) +{ return Event(this, mbed::callback(obj, method)); } template -Event EventQueue::event(mbed::Callback cb) { +Event EventQueue::event(mbed::Callback cb) +{ return Event(this, cb); } template -Event EventQueue::event(R (*func)(B0), C0 c0) { +Event EventQueue::event(R(*func)(B0), C0 c0) +{ return Event(this, func, c0); } template -Event EventQueue::event(T *obj, R (T::*method)(B0), C0 c0) { +Event EventQueue::event(T *obj, R(T::*method)(B0), C0 c0) +{ return Event(this, mbed::callback(obj, method), c0); } template -Event EventQueue::event(const T *obj, R (T::*method)(B0) const, C0 c0) { +Event EventQueue::event(const T *obj, R(T::*method)(B0) const, C0 c0) +{ return Event(this, mbed::callback(obj, method), c0); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(B0) volatile, C0 c0) { +Event EventQueue::event(volatile T *obj, R(T::*method)(B0) volatile, C0 c0) +{ return Event(this, mbed::callback(obj, method), c0); } template -Event EventQueue::event(const volatile T *obj, R (T::*method)(B0) const volatile, C0 c0) { +Event EventQueue::event(const volatile T *obj, R(T::*method)(B0) const volatile, C0 c0) +{ return Event(this, mbed::callback(obj, method), c0); } template -Event EventQueue::event(mbed::Callback cb, C0 c0) { +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) { +Event EventQueue::event(R(*func)(B0, B1), C0 c0, C1 c1) +{ return Event(this, func, c0, c1); } template -Event EventQueue::event(T *obj, R (T::*method)(B0, B1), C0 c0, C1 c1) { +Event EventQueue::event(T *obj, R(T::*method)(B0, B1), C0 c0, C1 c1) +{ return Event(this, mbed::callback(obj, method), c0, c1); } template -Event EventQueue::event(const T *obj, R (T::*method)(B0, B1) const, C0 c0, C1 c1) { +Event EventQueue::event(const T *obj, R(T::*method)(B0, B1) const, C0 c0, C1 c1) +{ return Event(this, mbed::callback(obj, method), c0, c1); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1) volatile, C0 c0, C1 c1) { +Event EventQueue::event(volatile T *obj, R(T::*method)(B0, B1) volatile, C0 c0, C1 c1) +{ return Event(this, mbed::callback(obj, method), c0, c1); } template -Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1) const volatile, C0 c0, C1 c1) { +Event EventQueue::event(const volatile T *obj, R(T::*method)(B0, B1) const volatile, C0 c0, C1 c1) +{ return Event(this, mbed::callback(obj, method), c0, c1); } template -Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1) { +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) { +Event EventQueue::event(R(*func)(B0, B1, B2), C0 c0, C1 c1, C2 c2) +{ return Event(this, func, c0, c1, c2); } template -Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2), C0 c0, C1 c1, C2 c2) { +Event EventQueue::event(T *obj, R(T::*method)(B0, B1, B2), C0 c0, C1 c1, C2 c2) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2); } template -Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2) const, C0 c0, C1 c1, C2 c2) { +Event EventQueue::event(const T *obj, R(T::*method)(B0, B1, B2) const, C0 c0, C1 c1, C2 c2) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2) volatile, C0 c0, C1 c1, C2 c2) { +Event EventQueue::event(volatile T *obj, R(T::*method)(B0, B1, B2) volatile, C0 c0, C1 c1, C2 c2) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2); } template -Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, B2) const volatile, C0 c0, C1 c1, C2 c2) { +Event EventQueue::event(const volatile T *obj, R(T::*method)(B0, B1, B2) const volatile, C0 c0, C1 c1, C2 c2) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2); } template -Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1, C2 c2) { +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) { +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); } template -Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, B3), C0 c0, C1 c1, C2 c2, C3 c3) { +Event EventQueue::event(T *obj, R(T::*method)(B0, B1, B2, B3), C0 c0, C1 c1, C2 c2, C3 c3) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); } template -Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, B3) const, C0 c0, C1 c1, C2 c2, C3 c3) { +Event EventQueue::event(const T *obj, R(T::*method)(B0, B1, B2, B3) const, C0 c0, C1 c1, C2 c2, C3 c3) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, B3) volatile, C0 c0, C1 c1, C2 c2, C3 c3) { +Event EventQueue::event(volatile T *obj, R(T::*method)(B0, B1, B2, B3) volatile, C0 c0, C1 c1, C2 c2, C3 c3) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); } template -Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, B2, B3) const volatile, C0 c0, C1 c1, C2 c2, C3 c3) { +Event EventQueue::event(const volatile T *obj, R(T::*method)(B0, B1, B2, B3) const volatile, C0 c0, C1 c1, C2 c2, C3 c3) +{ 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) { +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) { +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); } template -Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, B3, B4), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { +Event EventQueue::event(T *obj, R(T::*method)(B0, B1, B2, B3, B4), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); } template -Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, B3, B4) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { +Event EventQueue::event(const T *obj, R(T::*method)(B0, B1, B2, B3, B4) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4) volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { +Event EventQueue::event(volatile T *obj, R(T::*method)(B0, B1, B2, B3, B4) volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); } template -Event EventQueue::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) { +Event EventQueue::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) +{ 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) { +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)) { +Event EventQueue::event(R(*func)(A0)) +{ return Event(this, func); } template -Event EventQueue::event(T *obj, R (T::*method)(A0)) { +Event EventQueue::event(T *obj, R(T::*method)(A0)) +{ return Event(this, mbed::callback(obj, method)); } template -Event EventQueue::event(const T *obj, R (T::*method)(A0) const) { +Event EventQueue::event(const T *obj, R(T::*method)(A0) const) +{ return Event(this, mbed::callback(obj, method)); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(A0) volatile) { +Event EventQueue::event(volatile T *obj, R(T::*method)(A0) volatile) +{ return Event(this, mbed::callback(obj, method)); } template -Event EventQueue::event(const volatile T *obj, R (T::*method)(A0) const volatile) { +Event EventQueue::event(const volatile T *obj, R(T::*method)(A0) const volatile) +{ return Event(this, mbed::callback(obj, method)); } template -Event EventQueue::event(mbed::Callback cb) { +Event EventQueue::event(mbed::Callback cb) +{ return Event(this, cb); } template -Event EventQueue::event(R (*func)(B0, A0), C0 c0) { +Event EventQueue::event(R(*func)(B0, A0), C0 c0) +{ return Event(this, func, c0); } template -Event EventQueue::event(T *obj, R (T::*method)(B0, A0), C0 c0) { +Event EventQueue::event(T *obj, R(T::*method)(B0, A0), C0 c0) +{ return Event(this, mbed::callback(obj, method), c0); } template -Event EventQueue::event(const T *obj, R (T::*method)(B0, A0) const, C0 c0) { +Event EventQueue::event(const T *obj, R(T::*method)(B0, A0) const, C0 c0) +{ return Event(this, mbed::callback(obj, method), c0); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(B0, A0) volatile, C0 c0) { +Event EventQueue::event(volatile T *obj, R(T::*method)(B0, A0) volatile, C0 c0) +{ return Event(this, mbed::callback(obj, method), c0); } template -Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, A0) const volatile, C0 c0) { +Event EventQueue::event(const volatile T *obj, R(T::*method)(B0, A0) const volatile, C0 c0) +{ return Event(this, mbed::callback(obj, method), c0); } template -Event EventQueue::event(mbed::Callback cb, C0 c0) { +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) { +Event EventQueue::event(R(*func)(B0, B1, A0), C0 c0, C1 c1) +{ return Event(this, func, c0, c1); } template -Event EventQueue::event(T *obj, R (T::*method)(B0, B1, A0), C0 c0, C1 c1) { +Event EventQueue::event(T *obj, R(T::*method)(B0, B1, A0), C0 c0, C1 c1) +{ return Event(this, mbed::callback(obj, method), c0, c1); } template -Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, A0) const, C0 c0, C1 c1) { +Event EventQueue::event(const T *obj, R(T::*method)(B0, B1, A0) const, C0 c0, C1 c1) +{ return Event(this, mbed::callback(obj, method), c0, c1); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, A0) volatile, C0 c0, C1 c1) { +Event EventQueue::event(volatile T *obj, R(T::*method)(B0, B1, A0) volatile, C0 c0, C1 c1) +{ return Event(this, mbed::callback(obj, method), c0, c1); } template -Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, A0) const volatile, C0 c0, C1 c1) { +Event EventQueue::event(const volatile T *obj, R(T::*method)(B0, B1, A0) const volatile, C0 c0, C1 c1) +{ return Event(this, mbed::callback(obj, method), c0, c1); } template -Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1) { +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) { +Event EventQueue::event(R(*func)(B0, B1, B2, A0), C0 c0, C1 c1, C2 c2) +{ return Event(this, func, c0, c1, c2); } template -Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, A0), C0 c0, C1 c1, C2 c2) { +Event EventQueue::event(T *obj, R(T::*method)(B0, B1, B2, A0), C0 c0, C1 c1, C2 c2) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2); } template -Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, A0) const, C0 c0, C1 c1, C2 c2) { +Event EventQueue::event(const T *obj, R(T::*method)(B0, B1, B2, A0) const, C0 c0, C1 c1, C2 c2) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, A0) volatile, C0 c0, C1 c1, C2 c2) { +Event EventQueue::event(volatile T *obj, R(T::*method)(B0, B1, B2, A0) volatile, C0 c0, C1 c1, C2 c2) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2); } template -Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, B2, A0) const volatile, C0 c0, C1 c1, C2 c2) { +Event EventQueue::event(const volatile T *obj, R(T::*method)(B0, B1, B2, A0) const volatile, C0 c0, C1 c1, C2 c2) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2); } template -Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1, C2 c2) { +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) { +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); } template -Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, B3, A0), C0 c0, C1 c1, C2 c2, C3 c3) { +Event EventQueue::event(T *obj, R(T::*method)(B0, B1, B2, B3, A0), C0 c0, C1 c1, C2 c2, C3 c3) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); } template -Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, B3, A0) const, C0 c0, C1 c1, C2 c2, C3 c3) { +Event EventQueue::event(const T *obj, R(T::*method)(B0, B1, B2, B3, A0) const, C0 c0, C1 c1, C2 c2, C3 c3) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0) volatile, C0 c0, C1 c1, C2 c2, C3 c3) { +Event EventQueue::event(volatile T *obj, R(T::*method)(B0, B1, B2, B3, A0) volatile, C0 c0, C1 c1, C2 c2, C3 c3) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); } template -Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0) const volatile, C0 c0, C1 c1, C2 c2, C3 c3) { +Event EventQueue::event(const volatile T *obj, R(T::*method)(B0, B1, B2, B3, A0) const volatile, C0 c0, C1 c1, C2 c2, C3 c3) +{ 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) { +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) { +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); } template -Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { +Event EventQueue::event(T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); } template -Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { +Event EventQueue::event(const T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0) volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { +Event EventQueue::event(volatile T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0) volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); } template -Event EventQueue::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) { +Event EventQueue::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) +{ 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) { +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)) { +Event EventQueue::event(R(*func)(A0, A1)) +{ return Event(this, func); } template -Event EventQueue::event(T *obj, R (T::*method)(A0, A1)) { +Event EventQueue::event(T *obj, R(T::*method)(A0, A1)) +{ return Event(this, mbed::callback(obj, method)); } template -Event EventQueue::event(const T *obj, R (T::*method)(A0, A1) const) { +Event EventQueue::event(const T *obj, R(T::*method)(A0, A1) const) +{ return Event(this, mbed::callback(obj, method)); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(A0, A1) volatile) { +Event EventQueue::event(volatile T *obj, R(T::*method)(A0, A1) volatile) +{ return Event(this, mbed::callback(obj, method)); } template -Event EventQueue::event(const volatile T *obj, R (T::*method)(A0, A1) const volatile) { +Event EventQueue::event(const volatile T *obj, R(T::*method)(A0, A1) const volatile) +{ return Event(this, mbed::callback(obj, method)); } template -Event EventQueue::event(mbed::Callback cb) { +Event EventQueue::event(mbed::Callback cb) +{ return Event(this, cb); } template -Event EventQueue::event(R (*func)(B0, A0, A1), C0 c0) { +Event EventQueue::event(R(*func)(B0, A0, A1), C0 c0) +{ return Event(this, func, c0); } template -Event EventQueue::event(T *obj, R (T::*method)(B0, A0, A1), C0 c0) { +Event EventQueue::event(T *obj, R(T::*method)(B0, A0, A1), C0 c0) +{ return Event(this, mbed::callback(obj, method), c0); } template -Event EventQueue::event(const T *obj, R (T::*method)(B0, A0, A1) const, C0 c0) { +Event EventQueue::event(const T *obj, R(T::*method)(B0, A0, A1) const, C0 c0) +{ return Event(this, mbed::callback(obj, method), c0); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(B0, A0, A1) volatile, C0 c0) { +Event EventQueue::event(volatile T *obj, R(T::*method)(B0, A0, A1) volatile, C0 c0) +{ return Event(this, mbed::callback(obj, method), c0); } template -Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, A0, A1) const volatile, C0 c0) { +Event EventQueue::event(const volatile T *obj, R(T::*method)(B0, A0, A1) const volatile, C0 c0) +{ return Event(this, mbed::callback(obj, method), c0); } template -Event EventQueue::event(mbed::Callback cb, C0 c0) { +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) { +Event EventQueue::event(R(*func)(B0, B1, A0, A1), C0 c0, C1 c1) +{ return Event(this, func, c0, c1); } template -Event EventQueue::event(T *obj, R (T::*method)(B0, B1, A0, A1), C0 c0, C1 c1) { +Event EventQueue::event(T *obj, R(T::*method)(B0, B1, A0, A1), C0 c0, C1 c1) +{ return Event(this, mbed::callback(obj, method), c0, c1); } template -Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, A0, A1) const, C0 c0, C1 c1) { +Event EventQueue::event(const T *obj, R(T::*method)(B0, B1, A0, A1) const, C0 c0, C1 c1) +{ return Event(this, mbed::callback(obj, method), c0, c1); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, A0, A1) volatile, C0 c0, C1 c1) { +Event EventQueue::event(volatile T *obj, R(T::*method)(B0, B1, A0, A1) volatile, C0 c0, C1 c1) +{ return Event(this, mbed::callback(obj, method), c0, c1); } template -Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, A0, A1) const volatile, C0 c0, C1 c1) { +Event EventQueue::event(const volatile T *obj, R(T::*method)(B0, B1, A0, A1) const volatile, C0 c0, C1 c1) +{ return Event(this, mbed::callback(obj, method), c0, c1); } template -Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1) { +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) { +Event EventQueue::event(R(*func)(B0, B1, B2, A0, A1), C0 c0, C1 c1, C2 c2) +{ return Event(this, func, c0, c1, c2); } template -Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, A0, A1), C0 c0, C1 c1, C2 c2) { +Event EventQueue::event(T *obj, R(T::*method)(B0, B1, B2, A0, A1), C0 c0, C1 c1, C2 c2) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2); } template -Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, A0, A1) const, C0 c0, C1 c1, C2 c2) { +Event EventQueue::event(const T *obj, R(T::*method)(B0, B1, B2, A0, A1) const, C0 c0, C1 c1, C2 c2) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1) volatile, C0 c0, C1 c1, C2 c2) { +Event EventQueue::event(volatile T *obj, R(T::*method)(B0, B1, B2, A0, A1) volatile, C0 c0, C1 c1, C2 c2) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2); } template -Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1) const volatile, C0 c0, C1 c1, C2 c2) { +Event EventQueue::event(const volatile T *obj, R(T::*method)(B0, B1, B2, A0, A1) const volatile, C0 c0, C1 c1, C2 c2) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2); } template -Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1, C2 c2) { +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) { +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); } template -Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1), C0 c0, C1 c1, C2 c2, C3 c3) { +Event EventQueue::event(T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1), C0 c0, C1 c1, C2 c2, C3 c3) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); } template -Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1) const, C0 c0, C1 c1, C2 c2, C3 c3) { +Event EventQueue::event(const T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1) const, C0 c0, C1 c1, C2 c2, C3 c3) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1) volatile, C0 c0, C1 c1, C2 c2, C3 c3) { +Event EventQueue::event(volatile T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1) volatile, C0 c0, C1 c1, C2 c2, C3 c3) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); } template -Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1) const volatile, C0 c0, C1 c1, C2 c2, C3 c3) { +Event EventQueue::event(const volatile T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1) const volatile, C0 c0, C1 c1, C2 c2, C3 c3) +{ 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) { +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) { +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); } template -Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { +Event EventQueue::event(T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); } template -Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { +Event EventQueue::event(const T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1) volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { +Event EventQueue::event(volatile T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1) volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); } template -Event EventQueue::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) { +Event EventQueue::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) +{ 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) { +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)) { +Event EventQueue::event(R(*func)(A0, A1, A2)) +{ return Event(this, func); } template -Event EventQueue::event(T *obj, R (T::*method)(A0, A1, A2)) { +Event EventQueue::event(T *obj, R(T::*method)(A0, A1, A2)) +{ return Event(this, mbed::callback(obj, method)); } template -Event EventQueue::event(const T *obj, R (T::*method)(A0, A1, A2) const) { +Event EventQueue::event(const T *obj, R(T::*method)(A0, A1, A2) const) +{ return Event(this, mbed::callback(obj, method)); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(A0, A1, A2) volatile) { +Event EventQueue::event(volatile T *obj, R(T::*method)(A0, A1, A2) volatile) +{ return Event(this, mbed::callback(obj, method)); } template -Event EventQueue::event(const volatile T *obj, R (T::*method)(A0, A1, A2) const volatile) { +Event EventQueue::event(const volatile T *obj, R(T::*method)(A0, A1, A2) const volatile) +{ return Event(this, mbed::callback(obj, method)); } template -Event EventQueue::event(mbed::Callback cb) { +Event EventQueue::event(mbed::Callback cb) +{ return Event(this, cb); } template -Event EventQueue::event(R (*func)(B0, A0, A1, A2), C0 c0) { +Event EventQueue::event(R(*func)(B0, A0, A1, A2), C0 c0) +{ return Event(this, func, c0); } template -Event EventQueue::event(T *obj, R (T::*method)(B0, A0, A1, A2), C0 c0) { +Event EventQueue::event(T *obj, R(T::*method)(B0, A0, A1, A2), C0 c0) +{ return Event(this, mbed::callback(obj, method), c0); } template -Event EventQueue::event(const T *obj, R (T::*method)(B0, A0, A1, A2) const, C0 c0) { +Event EventQueue::event(const T *obj, R(T::*method)(B0, A0, A1, A2) const, C0 c0) +{ return Event(this, mbed::callback(obj, method), c0); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(B0, A0, A1, A2) volatile, C0 c0) { +Event EventQueue::event(volatile T *obj, R(T::*method)(B0, A0, A1, A2) volatile, C0 c0) +{ return Event(this, mbed::callback(obj, method), c0); } template -Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, A0, A1, A2) const volatile, C0 c0) { +Event EventQueue::event(const volatile T *obj, R(T::*method)(B0, A0, A1, A2) const volatile, C0 c0) +{ return Event(this, mbed::callback(obj, method), c0); } template -Event EventQueue::event(mbed::Callback cb, C0 c0) { +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) { +Event EventQueue::event(R(*func)(B0, B1, A0, A1, A2), C0 c0, C1 c1) +{ return Event(this, func, c0, c1); } template -Event EventQueue::event(T *obj, R (T::*method)(B0, B1, A0, A1, A2), C0 c0, C1 c1) { +Event EventQueue::event(T *obj, R(T::*method)(B0, B1, A0, A1, A2), C0 c0, C1 c1) +{ return Event(this, mbed::callback(obj, method), c0, c1); } template -Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, A0, A1, A2) const, C0 c0, C1 c1) { +Event EventQueue::event(const T *obj, R(T::*method)(B0, B1, A0, A1, A2) const, C0 c0, C1 c1) +{ return Event(this, mbed::callback(obj, method), c0, c1); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2) volatile, C0 c0, C1 c1) { +Event EventQueue::event(volatile T *obj, R(T::*method)(B0, B1, A0, A1, A2) volatile, C0 c0, C1 c1) +{ return Event(this, mbed::callback(obj, method), c0, c1); } template -Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2) const volatile, C0 c0, C1 c1) { +Event EventQueue::event(const volatile T *obj, R(T::*method)(B0, B1, A0, A1, A2) const volatile, C0 c0, C1 c1) +{ return Event(this, mbed::callback(obj, method), c0, c1); } template -Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1) { +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) { +Event EventQueue::event(R(*func)(B0, B1, B2, A0, A1, A2), C0 c0, C1 c1, C2 c2) +{ return Event(this, func, c0, c1, c2); } template -Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2), C0 c0, C1 c1, C2 c2) { +Event EventQueue::event(T *obj, R(T::*method)(B0, B1, B2, A0, A1, A2), C0 c0, C1 c1, C2 c2) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2); } template -Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2) const, C0 c0, C1 c1, C2 c2) { +Event EventQueue::event(const T *obj, R(T::*method)(B0, B1, B2, A0, A1, A2) const, C0 c0, C1 c1, C2 c2) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2) volatile, C0 c0, C1 c1, C2 c2) { +Event EventQueue::event(volatile T *obj, R(T::*method)(B0, B1, B2, A0, A1, A2) volatile, C0 c0, C1 c1, C2 c2) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2); } template -Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2) const volatile, C0 c0, C1 c1, C2 c2) { +Event EventQueue::event(const volatile T *obj, R(T::*method)(B0, B1, B2, A0, A1, A2) const volatile, C0 c0, C1 c1, C2 c2) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2); } template -Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1, C2 c2) { +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) { +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); } template -Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2), C0 c0, C1 c1, C2 c2, C3 c3) { +Event EventQueue::event(T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1, A2), C0 c0, C1 c1, C2 c2, C3 c3) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); } template -Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2) const, C0 c0, C1 c1, C2 c2, C3 c3) { +Event EventQueue::event(const T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1, A2) const, C0 c0, C1 c1, C2 c2, C3 c3) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2) volatile, C0 c0, C1 c1, C2 c2, C3 c3) { +Event EventQueue::event(volatile T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1, A2) volatile, C0 c0, C1 c1, C2 c2, C3 c3) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); } template -Event EventQueue::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) { +Event EventQueue::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) +{ 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) { +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) { +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); } template -Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { +Event EventQueue::event(T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1, A2), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); } template -Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { +Event EventQueue::event(const T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1, A2) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2) volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { +Event EventQueue::event(volatile T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1, A2) volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); } template -Event EventQueue::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) { +Event EventQueue::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) +{ 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) { +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)) { +Event EventQueue::event(R(*func)(A0, A1, A2, A3)) +{ return Event(this, func); } template -Event EventQueue::event(T *obj, R (T::*method)(A0, A1, A2, A3)) { +Event EventQueue::event(T *obj, R(T::*method)(A0, A1, A2, A3)) +{ return Event(this, mbed::callback(obj, method)); } template -Event EventQueue::event(const T *obj, R (T::*method)(A0, A1, A2, A3) const) { +Event EventQueue::event(const T *obj, R(T::*method)(A0, A1, A2, A3) const) +{ return Event(this, mbed::callback(obj, method)); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(A0, A1, A2, A3) volatile) { +Event EventQueue::event(volatile T *obj, R(T::*method)(A0, A1, A2, A3) volatile) +{ return Event(this, mbed::callback(obj, method)); } template -Event EventQueue::event(const volatile T *obj, R (T::*method)(A0, A1, A2, A3) const volatile) { +Event EventQueue::event(const volatile T *obj, R(T::*method)(A0, A1, A2, A3) const volatile) +{ return Event(this, mbed::callback(obj, method)); } template -Event EventQueue::event(mbed::Callback cb) { +Event EventQueue::event(mbed::Callback cb) +{ return Event(this, cb); } template -Event EventQueue::event(R (*func)(B0, A0, A1, A2, A3), C0 c0) { +Event EventQueue::event(R(*func)(B0, A0, A1, A2, A3), C0 c0) +{ return Event(this, func, c0); } template -Event EventQueue::event(T *obj, R (T::*method)(B0, A0, A1, A2, A3), C0 c0) { +Event EventQueue::event(T *obj, R(T::*method)(B0, A0, A1, A2, A3), C0 c0) +{ return Event(this, mbed::callback(obj, method), c0); } template -Event EventQueue::event(const T *obj, R (T::*method)(B0, A0, A1, A2, A3) const, C0 c0) { +Event EventQueue::event(const T *obj, R(T::*method)(B0, A0, A1, A2, A3) const, C0 c0) +{ return Event(this, mbed::callback(obj, method), c0); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(B0, A0, A1, A2, A3) volatile, C0 c0) { +Event EventQueue::event(volatile T *obj, R(T::*method)(B0, A0, A1, A2, A3) volatile, C0 c0) +{ return Event(this, mbed::callback(obj, method), c0); } template -Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, A0, A1, A2, A3) const volatile, C0 c0) { +Event EventQueue::event(const volatile T *obj, R(T::*method)(B0, A0, A1, A2, A3) const volatile, C0 c0) +{ return Event(this, mbed::callback(obj, method), c0); } template -Event EventQueue::event(mbed::Callback cb, C0 c0) { +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) { +Event EventQueue::event(R(*func)(B0, B1, A0, A1, A2, A3), C0 c0, C1 c1) +{ return Event(this, func, c0, c1); } template -Event EventQueue::event(T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3), C0 c0, C1 c1) { +Event EventQueue::event(T *obj, R(T::*method)(B0, B1, A0, A1, A2, A3), C0 c0, C1 c1) +{ return Event(this, mbed::callback(obj, method), c0, c1); } template -Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3) const, C0 c0, C1 c1) { +Event EventQueue::event(const T *obj, R(T::*method)(B0, B1, A0, A1, A2, A3) const, C0 c0, C1 c1) +{ return Event(this, mbed::callback(obj, method), c0, c1); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3) volatile, C0 c0, C1 c1) { +Event EventQueue::event(volatile T *obj, R(T::*method)(B0, B1, A0, A1, A2, A3) volatile, C0 c0, C1 c1) +{ return Event(this, mbed::callback(obj, method), c0, c1); } template -Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3) const volatile, C0 c0, C1 c1) { +Event EventQueue::event(const volatile T *obj, R(T::*method)(B0, B1, A0, A1, A2, A3) const volatile, C0 c0, C1 c1) +{ return Event(this, mbed::callback(obj, method), c0, c1); } template -Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1) { +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) { +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); } template -Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2) { +Event EventQueue::event(T *obj, R(T::*method)(B0, B1, B2, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2); } template -Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3) const, C0 c0, C1 c1, C2 c2) { +Event EventQueue::event(const T *obj, R(T::*method)(B0, B1, B2, A0, A1, A2, A3) const, C0 c0, C1 c1, C2 c2) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3) volatile, C0 c0, C1 c1, C2 c2) { +Event EventQueue::event(volatile T *obj, R(T::*method)(B0, B1, B2, A0, A1, A2, A3) volatile, C0 c0, C1 c1, C2 c2) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2); } template -Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3) const volatile, C0 c0, C1 c1, C2 c2) { +Event EventQueue::event(const volatile T *obj, R(T::*method)(B0, B1, B2, A0, A1, A2, A3) const volatile, C0 c0, C1 c1, C2 c2) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2); } template -Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1, C2 c2) { +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) { +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); } template -Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2, C3 c3) { +Event EventQueue::event(T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2, C3 c3) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); } template -Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3) const, C0 c0, C1 c1, C2 c2, C3 c3) { +Event EventQueue::event(const T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1, A2, A3) const, C0 c0, C1 c1, C2 c2, C3 c3) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3) volatile, C0 c0, C1 c1, C2 c2, C3 c3) { +Event EventQueue::event(volatile T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1, A2, A3) volatile, C0 c0, C1 c1, C2 c2, C3 c3) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); } template -Event EventQueue::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) { +Event EventQueue::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) +{ 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) { +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) { +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); } template -Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { +Event EventQueue::event(T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); } template -Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { +Event EventQueue::event(const T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3) volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { +Event EventQueue::event(volatile T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3) volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); } template -Event EventQueue::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) { +Event EventQueue::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) +{ 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) { +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)) { +Event EventQueue::event(R(*func)(A0, A1, A2, A3, A4)) +{ return Event(this, func); } template -Event EventQueue::event(T *obj, R (T::*method)(A0, A1, A2, A3, A4)) { +Event EventQueue::event(T *obj, R(T::*method)(A0, A1, A2, A3, A4)) +{ return Event(this, mbed::callback(obj, method)); } template -Event EventQueue::event(const T *obj, R (T::*method)(A0, A1, A2, A3, A4) const) { +Event EventQueue::event(const T *obj, R(T::*method)(A0, A1, A2, A3, A4) const) +{ return Event(this, mbed::callback(obj, method)); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(A0, A1, A2, A3, A4) volatile) { +Event EventQueue::event(volatile T *obj, R(T::*method)(A0, A1, A2, A3, A4) volatile) +{ return Event(this, mbed::callback(obj, method)); } template -Event EventQueue::event(const volatile T *obj, R (T::*method)(A0, A1, A2, A3, A4) const volatile) { +Event EventQueue::event(const volatile T *obj, R(T::*method)(A0, A1, A2, A3, A4) const volatile) +{ return Event(this, mbed::callback(obj, method)); } template -Event EventQueue::event(mbed::Callback cb) { +Event EventQueue::event(mbed::Callback cb) +{ return Event(this, cb); } template -Event EventQueue::event(R (*func)(B0, A0, A1, A2, A3, A4), C0 c0) { +Event EventQueue::event(R(*func)(B0, A0, A1, A2, A3, A4), C0 c0) +{ return Event(this, func, c0); } template -Event EventQueue::event(T *obj, R (T::*method)(B0, A0, A1, A2, A3, A4), C0 c0) { +Event EventQueue::event(T *obj, R(T::*method)(B0, A0, A1, A2, A3, A4), C0 c0) +{ return Event(this, mbed::callback(obj, method), c0); } template -Event EventQueue::event(const T *obj, R (T::*method)(B0, A0, A1, A2, A3, A4) const, C0 c0) { +Event EventQueue::event(const T *obj, R(T::*method)(B0, A0, A1, A2, A3, A4) const, C0 c0) +{ return Event(this, mbed::callback(obj, method), c0); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(B0, A0, A1, A2, A3, A4) volatile, C0 c0) { +Event EventQueue::event(volatile T *obj, R(T::*method)(B0, A0, A1, A2, A3, A4) volatile, C0 c0) +{ return Event(this, mbed::callback(obj, method), c0); } template -Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, A0, A1, A2, A3, A4) const volatile, C0 c0) { +Event EventQueue::event(const volatile T *obj, R(T::*method)(B0, A0, A1, A2, A3, A4) const volatile, C0 c0) +{ return Event(this, mbed::callback(obj, method), c0); } template -Event EventQueue::event(mbed::Callback cb, C0 c0) { +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) { +Event EventQueue::event(R(*func)(B0, B1, A0, A1, A2, A3, A4), C0 c0, C1 c1) +{ return Event(this, func, c0, c1); } template -Event EventQueue::event(T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3, A4), C0 c0, C1 c1) { +Event EventQueue::event(T *obj, R(T::*method)(B0, B1, A0, A1, A2, A3, A4), C0 c0, C1 c1) +{ return Event(this, mbed::callback(obj, method), c0, c1); } template -Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3, A4) const, C0 c0, C1 c1) { +Event EventQueue::event(const T *obj, R(T::*method)(B0, B1, A0, A1, A2, A3, A4) const, C0 c0, C1 c1) +{ return Event(this, mbed::callback(obj, method), c0, c1); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3, A4) volatile, C0 c0, C1 c1) { +Event EventQueue::event(volatile T *obj, R(T::*method)(B0, B1, A0, A1, A2, A3, A4) volatile, C0 c0, C1 c1) +{ return Event(this, mbed::callback(obj, method), c0, c1); } template -Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3, A4) const volatile, C0 c0, C1 c1) { +Event EventQueue::event(const volatile T *obj, R(T::*method)(B0, B1, A0, A1, A2, A3, A4) const volatile, C0 c0, C1 c1) +{ return Event(this, mbed::callback(obj, method), c0, c1); } template -Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1) { +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) { +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); } template -Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2) { +Event EventQueue::event(T *obj, R(T::*method)(B0, B1, B2, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2); } template -Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3, A4) const, C0 c0, C1 c1, C2 c2) { +Event EventQueue::event(const T *obj, R(T::*method)(B0, B1, B2, A0, A1, A2, A3, A4) const, C0 c0, C1 c1, C2 c2) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3, A4) volatile, C0 c0, C1 c1, C2 c2) { +Event EventQueue::event(volatile T *obj, R(T::*method)(B0, B1, B2, A0, A1, A2, A3, A4) volatile, C0 c0, C1 c1, C2 c2) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2); } template -Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3, A4) const volatile, C0 c0, C1 c1, C2 c2) { +Event EventQueue::event(const volatile T *obj, R(T::*method)(B0, B1, B2, A0, A1, A2, A3, A4) const volatile, C0 c0, C1 c1, C2 c2) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2); } template -Event EventQueue::event(mbed::Callback cb, C0 c0, C1 c1, C2 c2) { +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) { +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); } template -Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2, C3 c3) { +Event EventQueue::event(T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2, C3 c3) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); } template -Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3, A4) const, C0 c0, C1 c1, C2 c2, C3 c3) { +Event EventQueue::event(const T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1, A2, A3, A4) const, C0 c0, C1 c1, C2 c2, C3 c3) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3, A4) volatile, C0 c0, C1 c1, C2 c2, C3 c3) { +Event EventQueue::event(volatile T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1, A2, A3, A4) volatile, C0 c0, C1 c1, C2 c2, C3 c3) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); } template -Event EventQueue::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) { +Event EventQueue::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) +{ 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) { +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) { +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); } template -Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { +Event EventQueue::event(T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); } template -Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { +Event EventQueue::event(const T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); } template -Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4) volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { +Event EventQueue::event(volatile T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4) volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) +{ return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); } template -Event EventQueue::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) { +Event EventQueue::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) +{ 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) { +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); } diff --git a/events/EventQueue.cpp b/events/EventQueue.cpp index 3abe8d93e8ca..fae08f29578c 100644 --- a/events/EventQueue.cpp +++ b/events/EventQueue.cpp @@ -19,7 +19,8 @@ #include "mbed.h" -EventQueue::EventQueue(unsigned event_size, unsigned char *event_pointer) { +EventQueue::EventQueue(unsigned event_size, unsigned char *event_pointer) +{ if (!event_pointer) { equeue_create(&_equeue, event_size); } else { @@ -27,31 +28,38 @@ EventQueue::EventQueue(unsigned event_size, unsigned char *event_pointer) { } } -EventQueue::~EventQueue() { +EventQueue::~EventQueue() +{ equeue_destroy(&_equeue); } -void EventQueue::dispatch(int ms) { +void EventQueue::dispatch(int ms) +{ return equeue_dispatch(&_equeue, ms); } -void EventQueue::break_dispatch() { +void EventQueue::break_dispatch() +{ return equeue_break(&_equeue); } -unsigned EventQueue::tick() { +unsigned EventQueue::tick() +{ return equeue_tick(); } -void EventQueue::cancel(int id) { +void EventQueue::cancel(int id) +{ return equeue_cancel(&_equeue, id); } -int EventQueue::time_left(int id) { +int EventQueue::time_left(int id) +{ return equeue_timeleft(&_equeue, id); } -void EventQueue::background(Callback update) { +void EventQueue::background(Callback update) +{ _update = update; if (_update) { @@ -61,7 +69,8 @@ void EventQueue::background(Callback update) { } } -void EventQueue::chain(EventQueue *target) { +void EventQueue::chain(EventQueue *target) +{ if (target) { equeue_chain(&_equeue, &target->_equeue); } else { diff --git a/events/EventQueue.h b/events/EventQueue.h index 01ab02a6d530..3232327119cd 100644 --- a/events/EventQueue.h +++ b/events/EventQueue.h @@ -60,7 +60,7 @@ class EventQueue : private mbed::NonCopyable { * @param buffer Pointer to buffer to use for events * (default to NULL) */ - EventQueue(unsigned size=EVENTS_QUEUE_SIZE, unsigned char *buffer=NULL); + EventQueue(unsigned size = EVENTS_QUEUE_SIZE, unsigned char *buffer = NULL); /** Destroy an EventQueue */ @@ -80,16 +80,19 @@ class EventQueue : private mbed::NonCopyable { * value will dispatch events indefinitely * (default to -1) */ - void dispatch(int ms=-1); + void dispatch(int ms = -1); /** Dispatch events without a timeout * - * This is equivalent to EventQueue::dispatch with no arguments, but + * This is equivalent to EventQueue::dispatch with no arguments, but * avoids overload ambiguities when passed as a callback. * * @see EventQueue::dispatch */ - void dispatch_forever() { dispatch(); } + void dispatch_forever() + { + dispatch(); + } /** Break out of a running event loop * @@ -100,7 +103,7 @@ class EventQueue : private mbed::NonCopyable { /** Millisecond counter * - * Returns the underlying tick of the event queue represented as the + * Returns the underlying tick of the event queue represented as the * number of milliseconds that have passed since an arbitrary point in * time. Intentionally overflows to 0 after 2^32-1. * @@ -196,7 +199,8 @@ class EventQueue : private mbed::NonCopyable { * executing. */ template - int call(F f) { + int call(F f) + { void *p = equeue_alloc(&_equeue, sizeof(F)); if (!p) { return 0; @@ -213,7 +217,8 @@ class EventQueue : private mbed::NonCopyable { * @param a0 Argument to pass to the callback */ template - int call(F f, A0 a0) { + int call(F f, A0 a0) + { return call(context10(f, a0)); } @@ -223,7 +228,8 @@ class EventQueue : private mbed::NonCopyable { * @param a0,a1 Arguments to pass to the callback */ template - int call(F f, A0 a0, A1 a1) { + int call(F f, A0 a0, A1 a1) + { return call(context20(f, a0, a1)); } @@ -233,7 +239,8 @@ class EventQueue : private mbed::NonCopyable { * @param a0,a1,a2 Arguments to pass to the callback */ template - int call(F f, A0 a0, A1 a1, A2 a2) { + int call(F f, A0 a0, A1 a1, A2 a2) + { return call(context30(f, a0, a1, a2)); } @@ -243,7 +250,8 @@ class EventQueue : private mbed::NonCopyable { * @param a0,a1,a2,a3 Arguments to pass to the callback */ template - int call(F f, A0 a0, A1 a1, A2 a2, A3 a3) { + int call(F f, A0 a0, A1 a1, A2 a2, A3 a3) + { return call(context40(f, a0, a1, a2, a3)); } @@ -253,7 +261,8 @@ class EventQueue : private mbed::NonCopyable { * @param a0,a1,a2,a3,a4 Arguments to pass to the callback */ template - int call(F f, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + int call(F f, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) + { return call(context50(f, a0, a1, a2, a3, a4)); } @@ -261,7 +270,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call */ template - int call(T *obj, R (T::*method)()) { + int call(T *obj, R(T::*method)()) + { return call(mbed::callback(obj, method)); } @@ -269,7 +279,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call */ template - int call(const T *obj, R (T::*method)() const) { + int call(const T *obj, R(T::*method)() const) + { return call(mbed::callback(obj, method)); } @@ -277,7 +288,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call */ template - int call(volatile T *obj, R (T::*method)() volatile) { + int call(volatile T *obj, R(T::*method)() volatile) + { return call(mbed::callback(obj, method)); } @@ -285,7 +297,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call */ template - int call(const volatile T *obj, R (T::*method)() const volatile) { + int call(const volatile T *obj, R(T::*method)() const volatile) + { return call(mbed::callback(obj, method)); } @@ -293,7 +306,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call */ template - int call(T *obj, R (T::*method)(A0), A0 a0) { + int call(T *obj, R(T::*method)(A0), A0 a0) + { return call(mbed::callback(obj, method), a0); } @@ -301,7 +315,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call */ template - int call(const T *obj, R (T::*method)(A0) const, A0 a0) { + int call(const T *obj, R(T::*method)(A0) const, A0 a0) + { return call(mbed::callback(obj, method), a0); } @@ -309,7 +324,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call */ template - int call(volatile T *obj, R (T::*method)(A0) volatile, A0 a0) { + int call(volatile T *obj, R(T::*method)(A0) volatile, A0 a0) + { return call(mbed::callback(obj, method), a0); } @@ -317,7 +333,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call */ template - int call(const volatile T *obj, R (T::*method)(A0) const volatile, A0 a0) { + int call(const volatile T *obj, R(T::*method)(A0) const volatile, A0 a0) + { return call(mbed::callback(obj, method), a0); } @@ -325,7 +342,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call */ template - int call(T *obj, R (T::*method)(A0, A1), A0 a0, A1 a1) { + int call(T *obj, R(T::*method)(A0, A1), A0 a0, A1 a1) + { return call(mbed::callback(obj, method), a0, a1); } @@ -333,7 +351,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call */ template - int call(const T *obj, R (T::*method)(A0, A1) const, A0 a0, A1 a1) { + int call(const T *obj, R(T::*method)(A0, A1) const, A0 a0, A1 a1) + { return call(mbed::callback(obj, method), a0, a1); } @@ -341,7 +360,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call */ template - int call(volatile T *obj, R (T::*method)(A0, A1) volatile, A0 a0, A1 a1) { + int call(volatile T *obj, R(T::*method)(A0, A1) volatile, A0 a0, A1 a1) + { return call(mbed::callback(obj, method), a0, a1); } @@ -349,7 +369,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call */ template - int call(const volatile T *obj, R (T::*method)(A0, A1) const volatile, A0 a0, A1 a1) { + int call(const volatile T *obj, R(T::*method)(A0, A1) const volatile, A0 a0, A1 a1) + { return call(mbed::callback(obj, method), a0, a1); } @@ -357,7 +378,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call */ template - int call(T *obj, R (T::*method)(A0, A1, A2), A0 a0, A1 a1, A2 a2) { + int call(T *obj, R(T::*method)(A0, A1, A2), A0 a0, A1 a1, A2 a2) + { return call(mbed::callback(obj, method), a0, a1, a2); } @@ -365,7 +387,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call */ template - int call(const T *obj, R (T::*method)(A0, A1, A2) const, A0 a0, A1 a1, A2 a2) { + int call(const T *obj, R(T::*method)(A0, A1, A2) const, A0 a0, A1 a1, A2 a2) + { return call(mbed::callback(obj, method), a0, a1, a2); } @@ -373,7 +396,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call */ template - int call(volatile T *obj, R (T::*method)(A0, A1, A2) volatile, A0 a0, A1 a1, A2 a2) { + int call(volatile T *obj, R(T::*method)(A0, A1, A2) volatile, A0 a0, A1 a1, A2 a2) + { return call(mbed::callback(obj, method), a0, a1, a2); } @@ -381,7 +405,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call */ template - int call(const volatile T *obj, R (T::*method)(A0, A1, A2) const volatile, A0 a0, A1 a1, A2 a2) { + int call(const volatile T *obj, R(T::*method)(A0, A1, A2) const volatile, A0 a0, A1 a1, A2 a2) + { return call(mbed::callback(obj, method), a0, a1, a2); } @@ -389,7 +414,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call */ template - int call(T *obj, R (T::*method)(A0, A1, A2, A3), A0 a0, A1 a1, A2 a2, A3 a3) { + int call(T *obj, R(T::*method)(A0, A1, A2, A3), A0 a0, A1 a1, A2 a2, A3 a3) + { return call(mbed::callback(obj, method), a0, a1, a2, a3); } @@ -397,7 +423,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call */ template - int call(const T *obj, R (T::*method)(A0, A1, A2, A3) const, A0 a0, A1 a1, A2 a2, A3 a3) { + int call(const T *obj, R(T::*method)(A0, A1, A2, A3) const, A0 a0, A1 a1, A2 a2, A3 a3) + { return call(mbed::callback(obj, method), a0, a1, a2, a3); } @@ -405,7 +432,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call */ template - int call(volatile T *obj, R (T::*method)(A0, A1, A2, A3) volatile, A0 a0, A1 a1, A2 a2, A3 a3) { + int call(volatile T *obj, R(T::*method)(A0, A1, A2, A3) volatile, A0 a0, A1 a1, A2 a2, A3 a3) + { return call(mbed::callback(obj, method), a0, a1, a2, a3); } @@ -413,7 +441,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call */ template - int call(const volatile T *obj, R (T::*method)(A0, A1, A2, A3) const volatile, A0 a0, A1 a1, A2 a2, A3 a3) { + int call(const volatile T *obj, R(T::*method)(A0, A1, A2, A3) const volatile, A0 a0, A1 a1, A2 a2, A3 a3) + { return call(mbed::callback(obj, method), a0, a1, a2, a3); } @@ -421,7 +450,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call */ template - int call(T *obj, R (T::*method)(A0, A1, A2, A3, A4), A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + int call(T *obj, R(T::*method)(A0, A1, A2, A3, A4), A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) + { return call(mbed::callback(obj, method), a0, a1, a2, a3, a4); } @@ -429,7 +459,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call */ template - int call(const T *obj, R (T::*method)(A0, A1, A2, A3, A4) const, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + int call(const T *obj, R(T::*method)(A0, A1, A2, A3, A4) const, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) + { return call(mbed::callback(obj, method), a0, a1, a2, a3, a4); } @@ -437,7 +468,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call */ template - int call(volatile T *obj, R (T::*method)(A0, A1, A2, A3, A4) volatile, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + int call(volatile T *obj, R(T::*method)(A0, A1, A2, A3, A4) volatile, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) + { return call(mbed::callback(obj, method), a0, a1, a2, a3, a4); } @@ -445,7 +477,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call */ template - int call(const volatile T *obj, R (T::*method)(A0, A1, A2, A3, A4) const volatile, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + int call(const volatile T *obj, R(T::*method)(A0, A1, A2, A3, A4) const volatile, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) + { return call(mbed::callback(obj, method), a0, a1, a2, a3, a4); } @@ -464,7 +497,8 @@ class EventQueue : private mbed::NonCopyable { * enough memory to allocate the event. */ template - int call_in(int ms, F f) { + int call_in(int ms, F f) + { void *p = equeue_alloc(&_equeue, sizeof(F)); if (!p) { return 0; @@ -483,7 +517,8 @@ class EventQueue : private mbed::NonCopyable { * @param a0 Argument to pass to the callback */ template - int call_in(int ms, F f, A0 a0) { + int call_in(int ms, F f, A0 a0) + { return call_in(ms, context10(f, a0)); } @@ -494,7 +529,8 @@ class EventQueue : private mbed::NonCopyable { * @param a0,a1 Arguments to pass to the callback */ template - int call_in(int ms, F f, A0 a0, A1 a1) { + int call_in(int ms, F f, A0 a0, A1 a1) + { return call_in(ms, context20(f, a0, a1)); } @@ -505,7 +541,8 @@ class EventQueue : private mbed::NonCopyable { * @param a0,a1,a2 Arguments to pass to the callback */ template - int call_in(int ms, F f, A0 a0, A1 a1, A2 a2) { + int call_in(int ms, F f, A0 a0, A1 a1, A2 a2) + { return call_in(ms, context30(f, a0, a1, a2)); } @@ -516,7 +553,8 @@ class EventQueue : private mbed::NonCopyable { * @param a0,a1,a2,a3 Arguments to pass to the callback */ template - int call_in(int ms, F f, A0 a0, A1 a1, A2 a2, A3 a3) { + int call_in(int ms, F f, A0 a0, A1 a1, A2 a2, A3 a3) + { return call_in(ms, context40(f, a0, a1, a2, a3)); } @@ -527,7 +565,8 @@ class EventQueue : private mbed::NonCopyable { * @param a0,a1,a2,a3,a4 Arguments to pass to the callback */ template - int call_in(int ms, F f, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + int call_in(int ms, F f, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) + { return call_in(ms, context50(f, a0, a1, a2, a3, a4)); } @@ -535,7 +574,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_in */ template - int call_in(int ms, T *obj, R (T::*method)()) { + int call_in(int ms, T *obj, R(T::*method)()) + { return call_in(ms, mbed::callback(obj, method)); } @@ -543,7 +583,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_in */ template - int call_in(int ms, const T *obj, R (T::*method)() const) { + int call_in(int ms, const T *obj, R(T::*method)() const) + { return call_in(ms, mbed::callback(obj, method)); } @@ -551,7 +592,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_in */ template - int call_in(int ms, volatile T *obj, R (T::*method)() volatile) { + int call_in(int ms, volatile T *obj, R(T::*method)() volatile) + { return call_in(ms, mbed::callback(obj, method)); } @@ -559,7 +601,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_in */ template - int call_in(int ms, const volatile T *obj, R (T::*method)() const volatile) { + int call_in(int ms, const volatile T *obj, R(T::*method)() const volatile) + { return call_in(ms, mbed::callback(obj, method)); } @@ -567,7 +610,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_in */ template - int call_in(int ms, T *obj, R (T::*method)(A0), A0 a0) { + int call_in(int ms, T *obj, R(T::*method)(A0), A0 a0) + { return call_in(ms, mbed::callback(obj, method), a0); } @@ -575,7 +619,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_in */ template - int call_in(int ms, const T *obj, R (T::*method)(A0) const, A0 a0) { + int call_in(int ms, const T *obj, R(T::*method)(A0) const, A0 a0) + { return call_in(ms, mbed::callback(obj, method), a0); } @@ -583,7 +628,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_in */ template - int call_in(int ms, volatile T *obj, R (T::*method)(A0) volatile, A0 a0) { + int call_in(int ms, volatile T *obj, R(T::*method)(A0) volatile, A0 a0) + { return call_in(ms, mbed::callback(obj, method), a0); } @@ -591,7 +637,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_in */ template - int call_in(int ms, const volatile T *obj, R (T::*method)(A0) const volatile, A0 a0) { + int call_in(int ms, const volatile T *obj, R(T::*method)(A0) const volatile, A0 a0) + { return call_in(ms, mbed::callback(obj, method), a0); } @@ -599,7 +646,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_in */ template - int call_in(int ms, T *obj, R (T::*method)(A0, A1), A0 a0, A1 a1) { + int call_in(int ms, T *obj, R(T::*method)(A0, A1), A0 a0, A1 a1) + { return call_in(ms, mbed::callback(obj, method), a0, a1); } @@ -607,7 +655,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_in */ template - int call_in(int ms, const T *obj, R (T::*method)(A0, A1) const, A0 a0, A1 a1) { + int call_in(int ms, const T *obj, R(T::*method)(A0, A1) const, A0 a0, A1 a1) + { return call_in(ms, mbed::callback(obj, method), a0, a1); } @@ -615,7 +664,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_in */ template - int call_in(int ms, volatile T *obj, R (T::*method)(A0, A1) volatile, A0 a0, A1 a1) { + int call_in(int ms, volatile T *obj, R(T::*method)(A0, A1) volatile, A0 a0, A1 a1) + { return call_in(ms, mbed::callback(obj, method), a0, a1); } @@ -623,7 +673,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_in */ template - int call_in(int ms, const volatile T *obj, R (T::*method)(A0, A1) const volatile, A0 a0, A1 a1) { + int call_in(int ms, const volatile T *obj, R(T::*method)(A0, A1) const volatile, A0 a0, A1 a1) + { return call_in(ms, mbed::callback(obj, method), a0, a1); } @@ -631,7 +682,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_in */ template - int call_in(int ms, T *obj, R (T::*method)(A0, A1, A2), A0 a0, A1 a1, A2 a2) { + int call_in(int ms, T *obj, R(T::*method)(A0, A1, A2), A0 a0, A1 a1, A2 a2) + { return call_in(ms, mbed::callback(obj, method), a0, a1, a2); } @@ -639,7 +691,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_in */ template - int call_in(int ms, const T *obj, R (T::*method)(A0, A1, A2) const, A0 a0, A1 a1, A2 a2) { + int call_in(int ms, const T *obj, R(T::*method)(A0, A1, A2) const, A0 a0, A1 a1, A2 a2) + { return call_in(ms, mbed::callback(obj, method), a0, a1, a2); } @@ -647,7 +700,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_in */ template - int call_in(int ms, volatile T *obj, R (T::*method)(A0, A1, A2) volatile, A0 a0, A1 a1, A2 a2) { + int call_in(int ms, volatile T *obj, R(T::*method)(A0, A1, A2) volatile, A0 a0, A1 a1, A2 a2) + { return call_in(ms, mbed::callback(obj, method), a0, a1, a2); } @@ -655,7 +709,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_in */ template - int call_in(int ms, const volatile T *obj, R (T::*method)(A0, A1, A2) const volatile, A0 a0, A1 a1, A2 a2) { + int call_in(int ms, const volatile T *obj, R(T::*method)(A0, A1, A2) const volatile, A0 a0, A1 a1, A2 a2) + { return call_in(ms, mbed::callback(obj, method), a0, a1, a2); } @@ -663,7 +718,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_in */ template - int call_in(int ms, T *obj, R (T::*method)(A0, A1, A2, A3), A0 a0, A1 a1, A2 a2, A3 a3) { + int call_in(int ms, T *obj, R(T::*method)(A0, A1, A2, A3), A0 a0, A1 a1, A2 a2, A3 a3) + { return call_in(ms, mbed::callback(obj, method), a0, a1, a2, a3); } @@ -671,7 +727,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_in */ template - int call_in(int ms, const T *obj, R (T::*method)(A0, A1, A2, A3) const, A0 a0, A1 a1, A2 a2, A3 a3) { + int call_in(int ms, const T *obj, R(T::*method)(A0, A1, A2, A3) const, A0 a0, A1 a1, A2 a2, A3 a3) + { return call_in(ms, mbed::callback(obj, method), a0, a1, a2, a3); } @@ -679,7 +736,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_in */ template - int call_in(int ms, volatile T *obj, R (T::*method)(A0, A1, A2, A3) volatile, A0 a0, A1 a1, A2 a2, A3 a3) { + int call_in(int ms, volatile T *obj, R(T::*method)(A0, A1, A2, A3) volatile, A0 a0, A1 a1, A2 a2, A3 a3) + { return call_in(ms, mbed::callback(obj, method), a0, a1, a2, a3); } @@ -687,7 +745,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_in */ template - int call_in(int ms, const volatile T *obj, R (T::*method)(A0, A1, A2, A3) const volatile, A0 a0, A1 a1, A2 a2, A3 a3) { + int call_in(int ms, const volatile T *obj, R(T::*method)(A0, A1, A2, A3) const volatile, A0 a0, A1 a1, A2 a2, A3 a3) + { return call_in(ms, mbed::callback(obj, method), a0, a1, a2, a3); } @@ -695,7 +754,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_in */ template - int call_in(int ms, T *obj, R (T::*method)(A0, A1, A2, A3, A4), A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + int call_in(int ms, T *obj, R(T::*method)(A0, A1, A2, A3, A4), A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) + { return call_in(ms, mbed::callback(obj, method), a0, a1, a2, a3, a4); } @@ -703,7 +763,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_in */ template - int call_in(int ms, const T *obj, R (T::*method)(A0, A1, A2, A3, A4) const, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + int call_in(int ms, const T *obj, R(T::*method)(A0, A1, A2, A3, A4) const, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) + { return call_in(ms, mbed::callback(obj, method), a0, a1, a2, a3, a4); } @@ -711,7 +772,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_in */ template - int call_in(int ms, volatile T *obj, R (T::*method)(A0, A1, A2, A3, A4) volatile, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + int call_in(int ms, volatile T *obj, R(T::*method)(A0, A1, A2, A3, A4) volatile, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) + { return call_in(ms, mbed::callback(obj, method), a0, a1, a2, a3, a4); } @@ -719,7 +781,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_in */ template - int call_in(int ms, const volatile T *obj, R (T::*method)(A0, A1, A2, A3, A4) const volatile, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + int call_in(int ms, const volatile T *obj, R(T::*method)(A0, A1, A2, A3, A4) const volatile, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) + { return call_in(ms, mbed::callback(obj, method), a0, a1, a2, a3, a4); } @@ -741,7 +804,8 @@ class EventQueue : private mbed::NonCopyable { * enough memory to allocate the event. */ template - int call_every(int ms, F f) { + int call_every(int ms, F f) + { void *p = equeue_alloc(&_equeue, sizeof(F)); if (!p) { return 0; @@ -761,7 +825,8 @@ class EventQueue : private mbed::NonCopyable { * @param ms Period of the event in milliseconds */ template - int call_every(int ms, F f, A0 a0) { + int call_every(int ms, F f, A0 a0) + { return call_every(ms, context10(f, a0)); } @@ -772,7 +837,8 @@ class EventQueue : private mbed::NonCopyable { * @param ms Period of the event in milliseconds */ template - int call_every(int ms, F f, A0 a0, A1 a1) { + int call_every(int ms, F f, A0 a0, A1 a1) + { return call_every(ms, context20(f, a0, a1)); } @@ -783,7 +849,8 @@ class EventQueue : private mbed::NonCopyable { * @param ms Period of the event in milliseconds */ template - int call_every(int ms, F f, A0 a0, A1 a1, A2 a2) { + int call_every(int ms, F f, A0 a0, A1 a1, A2 a2) + { return call_every(ms, context30(f, a0, a1, a2)); } @@ -794,7 +861,8 @@ class EventQueue : private mbed::NonCopyable { * @param ms Period of the event in milliseconds */ template - int call_every(int ms, F f, A0 a0, A1 a1, A2 a2, A3 a3) { + int call_every(int ms, F f, A0 a0, A1 a1, A2 a2, A3 a3) + { return call_every(ms, context40(f, a0, a1, a2, a3)); } @@ -805,7 +873,8 @@ class EventQueue : private mbed::NonCopyable { * @param ms Period of the event in milliseconds */ template - int call_every(int ms, F f, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + int call_every(int ms, F f, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) + { return call_every(ms, context50(f, a0, a1, a2, a3, a4)); } @@ -813,7 +882,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_every */ template - int call_every(int ms, T *obj, R (T::*method)()) { + int call_every(int ms, T *obj, R(T::*method)()) + { return call_every(ms, mbed::callback(obj, method)); } @@ -821,7 +891,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_every */ template - int call_every(int ms, const T *obj, R (T::*method)() const) { + int call_every(int ms, const T *obj, R(T::*method)() const) + { return call_every(ms, mbed::callback(obj, method)); } @@ -829,7 +900,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_every */ template - int call_every(int ms, volatile T *obj, R (T::*method)() volatile) { + int call_every(int ms, volatile T *obj, R(T::*method)() volatile) + { return call_every(ms, mbed::callback(obj, method)); } @@ -837,7 +909,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_every */ template - int call_every(int ms, const volatile T *obj, R (T::*method)() const volatile) { + int call_every(int ms, const volatile T *obj, R(T::*method)() const volatile) + { return call_every(ms, mbed::callback(obj, method)); } @@ -845,7 +918,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_every */ template - int call_every(int ms, T *obj, R (T::*method)(A0), A0 a0) { + int call_every(int ms, T *obj, R(T::*method)(A0), A0 a0) + { return call_every(ms, mbed::callback(obj, method), a0); } @@ -853,7 +927,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_every */ template - int call_every(int ms, const T *obj, R (T::*method)(A0) const, A0 a0) { + int call_every(int ms, const T *obj, R(T::*method)(A0) const, A0 a0) + { return call_every(ms, mbed::callback(obj, method), a0); } @@ -861,7 +936,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_every */ template - int call_every(int ms, volatile T *obj, R (T::*method)(A0) volatile, A0 a0) { + int call_every(int ms, volatile T *obj, R(T::*method)(A0) volatile, A0 a0) + { return call_every(ms, mbed::callback(obj, method), a0); } @@ -869,7 +945,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_every */ template - int call_every(int ms, const volatile T *obj, R (T::*method)(A0) const volatile, A0 a0) { + int call_every(int ms, const volatile T *obj, R(T::*method)(A0) const volatile, A0 a0) + { return call_every(ms, mbed::callback(obj, method), a0); } @@ -877,7 +954,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_every */ template - int call_every(int ms, T *obj, R (T::*method)(A0, A1), A0 a0, A1 a1) { + int call_every(int ms, T *obj, R(T::*method)(A0, A1), A0 a0, A1 a1) + { return call_every(ms, mbed::callback(obj, method), a0, a1); } @@ -885,7 +963,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_every */ template - int call_every(int ms, const T *obj, R (T::*method)(A0, A1) const, A0 a0, A1 a1) { + int call_every(int ms, const T *obj, R(T::*method)(A0, A1) const, A0 a0, A1 a1) + { return call_every(ms, mbed::callback(obj, method), a0, a1); } @@ -893,7 +972,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_every */ template - int call_every(int ms, volatile T *obj, R (T::*method)(A0, A1) volatile, A0 a0, A1 a1) { + int call_every(int ms, volatile T *obj, R(T::*method)(A0, A1) volatile, A0 a0, A1 a1) + { return call_every(ms, mbed::callback(obj, method), a0, a1); } @@ -901,7 +981,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_every */ template - int call_every(int ms, const volatile T *obj, R (T::*method)(A0, A1) const volatile, A0 a0, A1 a1) { + int call_every(int ms, const volatile T *obj, R(T::*method)(A0, A1) const volatile, A0 a0, A1 a1) + { return call_every(ms, mbed::callback(obj, method), a0, a1); } @@ -909,7 +990,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_every */ template - int call_every(int ms, T *obj, R (T::*method)(A0, A1, A2), A0 a0, A1 a1, A2 a2) { + int call_every(int ms, T *obj, R(T::*method)(A0, A1, A2), A0 a0, A1 a1, A2 a2) + { return call_every(ms, mbed::callback(obj, method), a0, a1, a2); } @@ -917,7 +999,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_every */ template - int call_every(int ms, const T *obj, R (T::*method)(A0, A1, A2) const, A0 a0, A1 a1, A2 a2) { + int call_every(int ms, const T *obj, R(T::*method)(A0, A1, A2) const, A0 a0, A1 a1, A2 a2) + { return call_every(ms, mbed::callback(obj, method), a0, a1, a2); } @@ -925,7 +1008,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_every */ template - int call_every(int ms, volatile T *obj, R (T::*method)(A0, A1, A2) volatile, A0 a0, A1 a1, A2 a2) { + int call_every(int ms, volatile T *obj, R(T::*method)(A0, A1, A2) volatile, A0 a0, A1 a1, A2 a2) + { return call_every(ms, mbed::callback(obj, method), a0, a1, a2); } @@ -933,7 +1017,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_every */ template - int call_every(int ms, const volatile T *obj, R (T::*method)(A0, A1, A2) const volatile, A0 a0, A1 a1, A2 a2) { + int call_every(int ms, const volatile T *obj, R(T::*method)(A0, A1, A2) const volatile, A0 a0, A1 a1, A2 a2) + { return call_every(ms, mbed::callback(obj, method), a0, a1, a2); } @@ -941,7 +1026,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_every */ template - int call_every(int ms, T *obj, R (T::*method)(A0, A1, A2, A3), A0 a0, A1 a1, A2 a2, A3 a3) { + int call_every(int ms, T *obj, R(T::*method)(A0, A1, A2, A3), A0 a0, A1 a1, A2 a2, A3 a3) + { return call_every(ms, mbed::callback(obj, method), a0, a1, a2, a3); } @@ -949,7 +1035,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_every */ template - int call_every(int ms, const T *obj, R (T::*method)(A0, A1, A2, A3) const, A0 a0, A1 a1, A2 a2, A3 a3) { + int call_every(int ms, const T *obj, R(T::*method)(A0, A1, A2, A3) const, A0 a0, A1 a1, A2 a2, A3 a3) + { return call_every(ms, mbed::callback(obj, method), a0, a1, a2, a3); } @@ -957,7 +1044,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_every */ template - int call_every(int ms, volatile T *obj, R (T::*method)(A0, A1, A2, A3) volatile, A0 a0, A1 a1, A2 a2, A3 a3) { + int call_every(int ms, volatile T *obj, R(T::*method)(A0, A1, A2, A3) volatile, A0 a0, A1 a1, A2 a2, A3 a3) + { return call_every(ms, mbed::callback(obj, method), a0, a1, a2, a3); } @@ -965,7 +1053,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_every */ template - int call_every(int ms, const volatile T *obj, R (T::*method)(A0, A1, A2, A3) const volatile, A0 a0, A1 a1, A2 a2, A3 a3) { + int call_every(int ms, const volatile T *obj, R(T::*method)(A0, A1, A2, A3) const volatile, A0 a0, A1 a1, A2 a2, A3 a3) + { return call_every(ms, mbed::callback(obj, method), a0, a1, a2, a3); } @@ -973,7 +1062,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_every */ template - int call_every(int ms, T *obj, R (T::*method)(A0, A1, A2, A3, A4), A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + int call_every(int ms, T *obj, R(T::*method)(A0, A1, A2, A3, A4), A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) + { return call_every(ms, mbed::callback(obj, method), a0, a1, a2, a3, a4); } @@ -981,7 +1071,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_every */ template - int call_every(int ms, const T *obj, R (T::*method)(A0, A1, A2, A3, A4) const, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + int call_every(int ms, const T *obj, R(T::*method)(A0, A1, A2, A3, A4) const, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) + { return call_every(ms, mbed::callback(obj, method), a0, a1, a2, a3, a4); } @@ -989,7 +1080,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_every */ template - int call_every(int ms, volatile T *obj, R (T::*method)(A0, A1, A2, A3, A4) volatile, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + int call_every(int ms, volatile T *obj, R(T::*method)(A0, A1, A2, A3, A4) volatile, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) + { return call_every(ms, mbed::callback(obj, method), a0, a1, a2, a3, a4); } @@ -997,7 +1089,8 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::call_every */ template - int call_every(int ms, const volatile T *obj, R (T::*method)(A0, A1, A2, A3, A4) const volatile, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + int call_every(int ms, const volatile T *obj, R(T::*method)(A0, A1, A2, A3, A4) const volatile, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) + { return call_every(ms, mbed::callback(obj, method), a0, a1, a2, a3, a4); } @@ -1011,31 +1104,31 @@ class EventQueue : private mbed::NonCopyable { * @return Event that will dispatch on the specific queue */ template - Event event(R (*func)()); + Event event(R(*func)()); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)()); + Event event(T *obj, R(T::*method)()); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)() const); + Event event(const T *obj, R(T::*method)() const); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)() volatile); + Event event(volatile T *obj, R(T::*method)() volatile); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const volatile T *obj, R (T::*method)() const volatile); + Event event(const volatile T *obj, R(T::*method)() const volatile); /** Creates an event bound to the event queue * @see EventQueue::event @@ -1047,31 +1140,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(B0), C0 c0); + Event event(R(*func)(B0), C0 c0); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(B0), C0 c0); + Event event(T *obj, R(T::*method)(B0), C0 c0); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(B0) const, C0 c0); + Event event(const T *obj, R(T::*method)(B0) const, C0 c0); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(B0) volatile, C0 c0); + Event event(volatile T *obj, R(T::*method)(B0) volatile, C0 c0); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const volatile T *obj, R (T::*method)(B0) const volatile, C0 c0); + 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 @@ -1083,31 +1176,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(B0, B1), C0 c0, C1 c1); + Event event(R(*func)(B0, B1), C0 c0, C1 c1); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(B0, B1), C0 c0, C1 c1); + Event event(T *obj, R(T::*method)(B0, B1), C0 c0, C1 c1); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(B0, B1) const, C0 c0, C1 c1); + Event event(const T *obj, R(T::*method)(B0, B1) const, C0 c0, C1 c1); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(B0, B1) volatile, C0 c0, C1 c1); + Event event(volatile T *obj, R(T::*method)(B0, B1) volatile, C0 c0, C1 c1); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const volatile T *obj, R (T::*method)(B0, B1) const volatile, C0 c0, C1 c1); + 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 @@ -1119,31 +1212,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(B0, B1, B2), C0 c0, C1 c1, C2 c2); + Event event(R(*func)(B0, B1, B2), C0 c0, C1 c1, C2 c2); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(B0, B1, B2), C0 c0, C1 c1, C2 c2); + Event event(T *obj, R(T::*method)(B0, B1, B2), C0 c0, C1 c1, C2 c2); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(B0, B1, B2) const, C0 c0, C1 c1, C2 c2); + Event event(const T *obj, R(T::*method)(B0, B1, B2) const, C0 c0, C1 c1, C2 c2); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(B0, B1, B2) volatile, C0 c0, C1 c1, C2 c2); + Event event(volatile T *obj, R(T::*method)(B0, B1, B2) volatile, C0 c0, C1 c1, C2 c2); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const volatile T *obj, R (T::*method)(B0, B1, B2) const volatile, C0 c0, C1 c1, C2 c2); + 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 @@ -1155,31 +1248,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(B0, B1, B2, B3), C0 c0, C1 c1, C2 c2, C3 c3); + Event event(R(*func)(B0, B1, B2, B3), C0 c0, C1 c1, C2 c2, C3 c3); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(B0, B1, B2, B3), C0 c0, C1 c1, C2 c2, C3 c3); + Event event(T *obj, R(T::*method)(B0, B1, B2, B3), C0 c0, C1 c1, C2 c2, C3 c3); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(B0, B1, B2, B3) const, C0 c0, C1 c1, C2 c2, C3 c3); + Event event(const T *obj, R(T::*method)(B0, B1, B2, B3) const, C0 c0, C1 c1, C2 c2, C3 c3); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(B0, B1, B2, B3) volatile, C0 c0, C1 c1, C2 c2, C3 c3); + Event event(volatile T *obj, R(T::*method)(B0, B1, B2, B3) volatile, C0 c0, C1 c1, C2 c2, C3 c3); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const volatile T *obj, R (T::*method)(B0, B1, B2, B3) const volatile, C0 c0, C1 c1, C2 c2, C3 c3); + 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 @@ -1191,31 +1284,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(B0, B1, B2, B3, B4), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + Event event(R(*func)(B0, B1, B2, B3, B4), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(B0, B1, B2, B3, B4), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + Event event(T *obj, R(T::*method)(B0, B1, B2, B3, B4), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(B0, B1, B2, B3, B4) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + Event event(const T *obj, R(T::*method)(B0, B1, B2, B3, B4) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4) volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + Event event(volatile T *obj, R(T::*method)(B0, B1, B2, B3, B4) 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(const volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4) const volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + 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 @@ -1227,31 +1320,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(A0)); + Event event(R(*func)(A0)); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(A0)); + Event event(T *obj, R(T::*method)(A0)); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(A0) const); + Event event(const T *obj, R(T::*method)(A0) const); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(A0) volatile); + Event event(volatile T *obj, R(T::*method)(A0) volatile); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const volatile T *obj, R (T::*method)(A0) const volatile); + Event event(const volatile T *obj, R(T::*method)(A0) const volatile); /** Creates an event bound to the event queue * @see EventQueue::event @@ -1263,31 +1356,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(B0, A0), C0 c0); + Event event(R(*func)(B0, A0), C0 c0); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(B0, A0), C0 c0); + Event event(T *obj, R(T::*method)(B0, A0), C0 c0); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(B0, A0) const, C0 c0); + Event event(const T *obj, R(T::*method)(B0, A0) const, C0 c0); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(B0, A0) volatile, C0 c0); + Event event(volatile T *obj, R(T::*method)(B0, A0) volatile, C0 c0); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const volatile T *obj, R (T::*method)(B0, A0) const volatile, C0 c0); + 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 @@ -1299,31 +1392,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(B0, B1, A0), C0 c0, C1 c1); + Event event(R(*func)(B0, B1, A0), C0 c0, C1 c1); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(B0, B1, A0), C0 c0, C1 c1); + Event event(T *obj, R(T::*method)(B0, B1, A0), C0 c0, C1 c1); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(B0, B1, A0) const, C0 c0, C1 c1); + Event event(const T *obj, R(T::*method)(B0, B1, A0) const, C0 c0, C1 c1); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(B0, B1, A0) volatile, C0 c0, C1 c1); + Event event(volatile T *obj, R(T::*method)(B0, B1, A0) volatile, C0 c0, C1 c1); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const volatile T *obj, R (T::*method)(B0, B1, A0) const volatile, C0 c0, C1 c1); + 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 @@ -1335,31 +1428,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(B0, B1, B2, A0), C0 c0, C1 c1, C2 c2); + Event event(R(*func)(B0, B1, B2, A0), C0 c0, C1 c1, C2 c2); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(B0, B1, B2, A0), C0 c0, C1 c1, C2 c2); + Event event(T *obj, R(T::*method)(B0, B1, B2, A0), C0 c0, C1 c1, C2 c2); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(B0, B1, B2, A0) const, C0 c0, C1 c1, C2 c2); + Event event(const T *obj, R(T::*method)(B0, B1, B2, A0) const, C0 c0, C1 c1, C2 c2); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(B0, B1, B2, A0) volatile, C0 c0, C1 c1, C2 c2); + Event event(volatile T *obj, R(T::*method)(B0, B1, B2, A0) volatile, C0 c0, C1 c1, C2 c2); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const volatile T *obj, R (T::*method)(B0, B1, B2, A0) const volatile, C0 c0, C1 c1, C2 c2); + 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 @@ -1371,31 +1464,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(B0, B1, B2, B3, A0), C0 c0, C1 c1, C2 c2, C3 c3); + Event event(R(*func)(B0, B1, B2, B3, A0), C0 c0, C1 c1, C2 c2, C3 c3); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(B0, B1, B2, B3, A0), C0 c0, C1 c1, C2 c2, C3 c3); + Event event(T *obj, R(T::*method)(B0, B1, B2, B3, A0), C0 c0, C1 c1, C2 c2, C3 c3); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(B0, B1, B2, B3, A0) const, C0 c0, C1 c1, C2 c2, C3 c3); + Event event(const T *obj, R(T::*method)(B0, B1, B2, B3, A0) const, C0 c0, C1 c1, C2 c2, C3 c3); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0) volatile, C0 c0, C1 c1, C2 c2, C3 c3); + Event event(volatile T *obj, R(T::*method)(B0, B1, B2, B3, A0) volatile, C0 c0, C1 c1, C2 c2, C3 c3); /** Creates an event bound to the event queue * @see EventQueue::event */ 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); + 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 @@ -1407,31 +1500,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(B0, B1, B2, B3, B4, A0), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + Event event(R(*func)(B0, B1, B2, B3, B4, A0), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + Event event(T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + Event event(const T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0) volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + Event event(volatile T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0) 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(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); + 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 @@ -1443,31 +1536,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(A0, A1)); + Event event(R(*func)(A0, A1)); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(A0, A1)); + Event event(T *obj, R(T::*method)(A0, A1)); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(A0, A1) const); + Event event(const T *obj, R(T::*method)(A0, A1) const); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(A0, A1) volatile); + Event event(volatile T *obj, R(T::*method)(A0, A1) volatile); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const volatile T *obj, R (T::*method)(A0, A1) const volatile); + Event event(const volatile T *obj, R(T::*method)(A0, A1) const volatile); /** Creates an event bound to the event queue * @see EventQueue::event @@ -1479,31 +1572,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(B0, A0, A1), C0 c0); + Event event(R(*func)(B0, A0, A1), C0 c0); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(B0, A0, A1), C0 c0); + Event event(T *obj, R(T::*method)(B0, A0, A1), C0 c0); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(B0, A0, A1) const, C0 c0); + Event event(const T *obj, R(T::*method)(B0, A0, A1) const, C0 c0); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(B0, A0, A1) volatile, C0 c0); + Event event(volatile T *obj, R(T::*method)(B0, A0, A1) volatile, C0 c0); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const volatile T *obj, R (T::*method)(B0, A0, A1) const volatile, C0 c0); + 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 @@ -1515,31 +1608,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(B0, B1, A0, A1), C0 c0, C1 c1); + Event event(R(*func)(B0, B1, A0, A1), C0 c0, C1 c1); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(B0, B1, A0, A1), C0 c0, C1 c1); + Event event(T *obj, R(T::*method)(B0, B1, A0, A1), C0 c0, C1 c1); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(B0, B1, A0, A1) const, C0 c0, C1 c1); + Event event(const T *obj, R(T::*method)(B0, B1, A0, A1) const, C0 c0, C1 c1); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(B0, B1, A0, A1) volatile, C0 c0, C1 c1); + Event event(volatile T *obj, R(T::*method)(B0, B1, A0, A1) volatile, C0 c0, C1 c1); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const volatile T *obj, R (T::*method)(B0, B1, A0, A1) const volatile, C0 c0, C1 c1); + 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 @@ -1551,31 +1644,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(B0, B1, B2, A0, A1), C0 c0, C1 c1, C2 c2); + Event event(R(*func)(B0, B1, B2, A0, A1), C0 c0, C1 c1, C2 c2); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(B0, B1, B2, A0, A1), C0 c0, C1 c1, C2 c2); + Event event(T *obj, R(T::*method)(B0, B1, B2, A0, A1), C0 c0, C1 c1, C2 c2); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(B0, B1, B2, A0, A1) const, C0 c0, C1 c1, C2 c2); + Event event(const T *obj, R(T::*method)(B0, B1, B2, A0, A1) const, C0 c0, C1 c1, C2 c2); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1) volatile, C0 c0, C1 c1, C2 c2); + Event event(volatile T *obj, R(T::*method)(B0, B1, B2, A0, A1) volatile, C0 c0, C1 c1, C2 c2); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1) const volatile, C0 c0, C1 c1, C2 c2); + 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 @@ -1587,31 +1680,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(B0, B1, B2, B3, A0, A1), C0 c0, C1 c1, C2 c2, C3 c3); + Event event(R(*func)(B0, B1, B2, B3, A0, A1), C0 c0, C1 c1, C2 c2, C3 c3); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1), C0 c0, C1 c1, C2 c2, C3 c3); + Event event(T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1), C0 c0, C1 c1, C2 c2, C3 c3); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1) const, C0 c0, C1 c1, C2 c2, C3 c3); + Event event(const T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1) const, C0 c0, C1 c1, C2 c2, C3 c3); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1) volatile, C0 c0, C1 c1, C2 c2, C3 c3); + Event event(volatile T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1) volatile, C0 c0, C1 c1, C2 c2, C3 c3); /** Creates an event bound to the event queue * @see EventQueue::event */ 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); + 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 @@ -1623,31 +1716,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(B0, B1, B2, B3, B4, A0, A1), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + Event event(R(*func)(B0, B1, B2, B3, B4, A0, A1), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + Event event(T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + Event event(const T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1) volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + Event event(volatile T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1) 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(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); + 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 @@ -1659,31 +1752,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(A0, A1, A2)); + Event event(R(*func)(A0, A1, A2)); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(A0, A1, A2)); + Event event(T *obj, R(T::*method)(A0, A1, A2)); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(A0, A1, A2) const); + Event event(const T *obj, R(T::*method)(A0, A1, A2) const); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(A0, A1, A2) volatile); + Event event(volatile T *obj, R(T::*method)(A0, A1, A2) volatile); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const volatile T *obj, R (T::*method)(A0, A1, A2) const volatile); + 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 @@ -1695,31 +1788,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(B0, A0, A1, A2), C0 c0); + Event event(R(*func)(B0, A0, A1, A2), C0 c0); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(B0, A0, A1, A2), C0 c0); + Event event(T *obj, R(T::*method)(B0, A0, A1, A2), C0 c0); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(B0, A0, A1, A2) const, C0 c0); + Event event(const T *obj, R(T::*method)(B0, A0, A1, A2) const, C0 c0); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(B0, A0, A1, A2) volatile, C0 c0); + Event event(volatile T *obj, R(T::*method)(B0, A0, A1, A2) volatile, C0 c0); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const volatile T *obj, R (T::*method)(B0, A0, A1, A2) const volatile, C0 c0); + 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 @@ -1731,31 +1824,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(B0, B1, A0, A1, A2), C0 c0, C1 c1); + Event event(R(*func)(B0, B1, A0, A1, A2), C0 c0, C1 c1); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(B0, B1, A0, A1, A2), C0 c0, C1 c1); + Event event(T *obj, R(T::*method)(B0, B1, A0, A1, A2), C0 c0, C1 c1); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(B0, B1, A0, A1, A2) const, C0 c0, C1 c1); + Event event(const T *obj, R(T::*method)(B0, B1, A0, A1, A2) const, C0 c0, C1 c1); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2) volatile, C0 c0, C1 c1); + Event event(volatile T *obj, R(T::*method)(B0, B1, A0, A1, A2) volatile, C0 c0, C1 c1); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2) const volatile, C0 c0, C1 c1); + 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 @@ -1767,31 +1860,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(B0, B1, B2, A0, A1, A2), C0 c0, C1 c1, C2 c2); + Event event(R(*func)(B0, B1, B2, A0, A1, A2), C0 c0, C1 c1, C2 c2); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2), C0 c0, C1 c1, C2 c2); + Event event(T *obj, R(T::*method)(B0, B1, B2, A0, A1, A2), C0 c0, C1 c1, C2 c2); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2) const, C0 c0, C1 c1, C2 c2); + Event event(const T *obj, R(T::*method)(B0, B1, B2, A0, A1, A2) const, C0 c0, C1 c1, C2 c2); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2) volatile, C0 c0, C1 c1, C2 c2); + Event event(volatile T *obj, R(T::*method)(B0, B1, B2, A0, A1, A2) volatile, C0 c0, C1 c1, C2 c2); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2) const volatile, C0 c0, C1 c1, C2 c2); + 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 @@ -1803,31 +1896,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(B0, B1, B2, B3, A0, A1, A2), C0 c0, C1 c1, C2 c2, C3 c3); + Event event(R(*func)(B0, B1, B2, B3, A0, A1, A2), C0 c0, C1 c1, C2 c2, C3 c3); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2), C0 c0, C1 c1, C2 c2, C3 c3); + Event event(T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1, A2), C0 c0, C1 c1, C2 c2, C3 c3); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2) const, C0 c0, C1 c1, C2 c2, C3 c3); + Event event(const T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1, A2) const, C0 c0, C1 c1, C2 c2, C3 c3); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2) volatile, C0 c0, C1 c1, C2 c2, C3 c3); + Event event(volatile T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1, A2) volatile, C0 c0, C1 c1, C2 c2, C3 c3); /** Creates an event bound to the event queue * @see EventQueue::event */ 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); + 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 @@ -1839,31 +1932,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(B0, B1, B2, B3, B4, A0, A1, A2), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + Event event(R(*func)(B0, B1, B2, B3, B4, A0, A1, A2), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + Event event(T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1, A2), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + Event event(const T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1, A2) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2) volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + Event event(volatile T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1, A2) 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(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); + 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 @@ -1875,31 +1968,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(A0, A1, A2, A3)); + Event event(R(*func)(A0, A1, A2, A3)); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(A0, A1, A2, A3)); + Event event(T *obj, R(T::*method)(A0, A1, A2, A3)); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(A0, A1, A2, A3) const); + Event event(const T *obj, R(T::*method)(A0, A1, A2, A3) const); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(A0, A1, A2, A3) volatile); + Event event(volatile T *obj, R(T::*method)(A0, A1, A2, A3) volatile); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const volatile T *obj, R (T::*method)(A0, A1, A2, A3) const volatile); + 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 @@ -1911,31 +2004,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(B0, A0, A1, A2, A3), C0 c0); + Event event(R(*func)(B0, A0, A1, A2, A3), C0 c0); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(B0, A0, A1, A2, A3), C0 c0); + Event event(T *obj, R(T::*method)(B0, A0, A1, A2, A3), C0 c0); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(B0, A0, A1, A2, A3) const, C0 c0); + Event event(const T *obj, R(T::*method)(B0, A0, A1, A2, A3) const, C0 c0); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(B0, A0, A1, A2, A3) volatile, C0 c0); + Event event(volatile T *obj, R(T::*method)(B0, A0, A1, A2, A3) volatile, C0 c0); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const volatile T *obj, R (T::*method)(B0, A0, A1, A2, A3) const volatile, C0 c0); + 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 @@ -1947,31 +2040,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(B0, B1, A0, A1, A2, A3), C0 c0, C1 c1); + Event event(R(*func)(B0, B1, A0, A1, A2, A3), C0 c0, C1 c1); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3), C0 c0, C1 c1); + Event event(T *obj, R(T::*method)(B0, B1, A0, A1, A2, A3), C0 c0, C1 c1); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3) const, C0 c0, C1 c1); + Event event(const T *obj, R(T::*method)(B0, B1, A0, A1, A2, A3) const, C0 c0, C1 c1); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3) volatile, C0 c0, C1 c1); + Event event(volatile T *obj, R(T::*method)(B0, B1, A0, A1, A2, A3) volatile, C0 c0, C1 c1); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3) const volatile, C0 c0, C1 c1); + 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 @@ -1983,31 +2076,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(B0, B1, B2, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2); + Event event(R(*func)(B0, B1, B2, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2); + Event event(T *obj, R(T::*method)(B0, B1, B2, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3) const, C0 c0, C1 c1, C2 c2); + Event event(const T *obj, R(T::*method)(B0, B1, B2, A0, A1, A2, A3) const, C0 c0, C1 c1, C2 c2); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3) volatile, C0 c0, C1 c1, C2 c2); + Event event(volatile T *obj, R(T::*method)(B0, B1, B2, A0, A1, A2, A3) volatile, C0 c0, C1 c1, C2 c2); /** Creates an event bound to the event queue * @see EventQueue::event */ 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); + 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 @@ -2019,31 +2112,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(B0, B1, B2, B3, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2, C3 c3); + Event event(R(*func)(B0, B1, B2, B3, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2, C3 c3); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2, C3 c3); + Event event(T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2, C3 c3); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3) const, C0 c0, C1 c1, C2 c2, C3 c3); + Event event(const T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1, A2, A3) const, C0 c0, C1 c1, C2 c2, C3 c3); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3) volatile, C0 c0, C1 c1, C2 c2, C3 c3); + Event event(volatile T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1, A2, A3) volatile, C0 c0, C1 c1, C2 c2, C3 c3); /** Creates an event bound to the event queue * @see EventQueue::event */ 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); + 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 @@ -2055,31 +2148,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(B0, B1, B2, B3, B4, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + Event event(R(*func)(B0, B1, B2, B3, B4, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + Event event(T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + Event event(const T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3) volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + Event event(volatile T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3) 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(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); + 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 @@ -2091,31 +2184,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(A0, A1, A2, A3, A4)); + Event event(R(*func)(A0, A1, A2, A3, A4)); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(A0, A1, A2, A3, A4)); + Event event(T *obj, R(T::*method)(A0, A1, A2, A3, A4)); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(A0, A1, A2, A3, A4) const); + Event event(const T *obj, R(T::*method)(A0, A1, A2, A3, A4) const); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(A0, A1, A2, A3, A4) volatile); + Event event(volatile T *obj, R(T::*method)(A0, A1, A2, A3, A4) volatile); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const volatile T *obj, R (T::*method)(A0, A1, A2, A3, A4) const volatile); + 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 @@ -2127,31 +2220,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(B0, A0, A1, A2, A3, A4), C0 c0); + Event event(R(*func)(B0, A0, A1, A2, A3, A4), C0 c0); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(B0, A0, A1, A2, A3, A4), C0 c0); + Event event(T *obj, R(T::*method)(B0, A0, A1, A2, A3, A4), C0 c0); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(B0, A0, A1, A2, A3, A4) const, C0 c0); + Event event(const T *obj, R(T::*method)(B0, A0, A1, A2, A3, A4) const, C0 c0); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(B0, A0, A1, A2, A3, A4) volatile, C0 c0); + Event event(volatile T *obj, R(T::*method)(B0, A0, A1, A2, A3, A4) volatile, C0 c0); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const volatile T *obj, R (T::*method)(B0, A0, A1, A2, A3, A4) const volatile, C0 c0); + 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 @@ -2163,31 +2256,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(B0, B1, A0, A1, A2, A3, A4), C0 c0, C1 c1); + Event event(R(*func)(B0, B1, A0, A1, A2, A3, A4), C0 c0, C1 c1); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3, A4), C0 c0, C1 c1); + Event event(T *obj, R(T::*method)(B0, B1, A0, A1, A2, A3, A4), C0 c0, C1 c1); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3, A4) const, C0 c0, C1 c1); + Event event(const T *obj, R(T::*method)(B0, B1, A0, A1, A2, A3, A4) const, C0 c0, C1 c1); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3, A4) volatile, C0 c0, C1 c1); + Event event(volatile T *obj, R(T::*method)(B0, B1, A0, A1, A2, A3, A4) volatile, C0 c0, C1 c1); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3, A4) const volatile, C0 c0, C1 c1); + 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 @@ -2199,31 +2292,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(B0, B1, B2, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2); + Event event(R(*func)(B0, B1, B2, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2); + Event event(T *obj, R(T::*method)(B0, B1, B2, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3, A4) const, C0 c0, C1 c1, C2 c2); + Event event(const T *obj, R(T::*method)(B0, B1, B2, A0, A1, A2, A3, A4) const, C0 c0, C1 c1, C2 c2); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3, A4) volatile, C0 c0, C1 c1, C2 c2); + Event event(volatile T *obj, R(T::*method)(B0, B1, B2, A0, A1, A2, A3, A4) volatile, C0 c0, C1 c1, C2 c2); /** Creates an event bound to the event queue * @see EventQueue::event */ 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); + 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 @@ -2235,31 +2328,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(B0, B1, B2, B3, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2, C3 c3); + Event event(R(*func)(B0, B1, B2, B3, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2, C3 c3); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2, C3 c3); + Event event(T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2, C3 c3); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3, A4) const, C0 c0, C1 c1, C2 c2, C3 c3); + Event event(const T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1, A2, A3, A4) const, C0 c0, C1 c1, C2 c2, C3 c3); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3, A4) volatile, C0 c0, C1 c1, C2 c2, C3 c3); + Event event(volatile T *obj, R(T::*method)(B0, B1, B2, B3, A0, A1, A2, A3, A4) volatile, C0 c0, C1 c1, C2 c2, C3 c3); /** Creates an event bound to the event queue * @see EventQueue::event */ 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); + 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 @@ -2271,31 +2364,31 @@ class EventQueue : private mbed::NonCopyable { * @see EventQueue::event */ template - Event event(R (*func)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + Event event(R(*func)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + Event event(T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(const T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + Event event(const T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); /** Creates an event bound to the event queue * @see EventQueue::event */ template - Event event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4) volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + Event event(volatile T *obj, R(T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4) 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(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); + 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 @@ -2311,13 +2404,15 @@ class EventQueue : private mbed::NonCopyable { // Function attributes template - static void function_call(void *p) { - (*(F*)p)(); + static void function_call(void *p) + { + (*(F *)p)(); } template - static void function_dtor(void *p) { - ((F*)p)->~F(); + static void function_dtor(void *p) + { + ((F *)p)->~F(); } // Context structures @@ -2328,67 +2423,88 @@ class EventQueue : private mbed::NonCopyable { context00(F f) : f(f) {} - void operator()() { + void operator()() + { f(); } }; template struct context10 { - F f; C0 c0; + F f; + C0 c0; context10(F f, C0 c0) : f(f), c0(c0) {} - void operator()() { + void operator()() + { f(c0); } }; template struct context20 { - F f; C0 c0; C1 c1; + F f; + C0 c0; + C1 c1; context20(F f, C0 c0, C1 c1) : f(f), c0(c0), c1(c1) {} - void operator()() { + void operator()() + { f(c0, c1); } }; template struct context30 { - F f; C0 c0; C1 c1; C2 c2; + F f; + C0 c0; + C1 c1; + C2 c2; context30(F f, C0 c0, C1 c1, C2 c2) : f(f), c0(c0), c1(c1), c2(c2) {} - void operator()() { + void operator()() + { f(c0, c1, c2); } }; template struct context40 { - F f; C0 c0; C1 c1; C2 c2; C3 c3; + F f; + C0 c0; + C1 c1; + C2 c2; + C3 c3; context40(F f, C0 c0, C1 c1, C2 c2, C3 c3) : f(f), c0(c0), c1(c1), c2(c2), c3(c3) {} - void operator()() { + void operator()() + { f(c0, c1, c2, c3); } }; template struct context50 { - F f; C0 c0; C1 c1; C2 c2; C3 c3; C4 c4; + F f; + C0 c0; + C1 c1; + C2 c2; + C3 c3; + C4 c4; context50(F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) : f(f), c0(c0), c1(c1), c2(c2), c3(c3), c4(c4) {} - void operator()() { + void operator()() + { f(c0, c1, c2, c3, c4); } }; @@ -2400,67 +2516,88 @@ class EventQueue : private mbed::NonCopyable { context01(F f) : f(f) {} - void operator()(A0 a0) { + void operator()(A0 a0) + { f(a0); } }; template struct context11 { - F f; C0 c0; + F f; + C0 c0; context11(F f, C0 c0) : f(f), c0(c0) {} - void operator()(A0 a0) { + void operator()(A0 a0) + { f(c0, a0); } }; template struct context21 { - F f; C0 c0; C1 c1; + F f; + C0 c0; + C1 c1; context21(F f, C0 c0, C1 c1) : f(f), c0(c0), c1(c1) {} - void operator()(A0 a0) { + void operator()(A0 a0) + { f(c0, c1, a0); } }; template struct context31 { - F f; C0 c0; C1 c1; C2 c2; + F f; + C0 c0; + C1 c1; + C2 c2; context31(F f, C0 c0, C1 c1, C2 c2) : f(f), c0(c0), c1(c1), c2(c2) {} - void operator()(A0 a0) { + void operator()(A0 a0) + { f(c0, c1, c2, a0); } }; template struct context41 { - F f; C0 c0; C1 c1; C2 c2; C3 c3; + F f; + C0 c0; + C1 c1; + C2 c2; + C3 c3; context41(F f, C0 c0, C1 c1, C2 c2, C3 c3) : f(f), c0(c0), c1(c1), c2(c2), c3(c3) {} - void operator()(A0 a0) { + void operator()(A0 a0) + { f(c0, c1, c2, c3, a0); } }; template struct context51 { - F f; C0 c0; C1 c1; C2 c2; C3 c3; C4 c4; + F f; + C0 c0; + C1 c1; + C2 c2; + C3 c3; + C4 c4; context51(F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) : f(f), c0(c0), c1(c1), c2(c2), c3(c3), c4(c4) {} - void operator()(A0 a0) { + void operator()(A0 a0) + { f(c0, c1, c2, c3, c4, a0); } }; @@ -2472,67 +2609,88 @@ class EventQueue : private mbed::NonCopyable { context02(F f) : f(f) {} - void operator()(A0 a0, A1 a1) { + void operator()(A0 a0, A1 a1) + { f(a0, a1); } }; template struct context12 { - F f; C0 c0; + F f; + C0 c0; context12(F f, C0 c0) : f(f), c0(c0) {} - void operator()(A0 a0, A1 a1) { + void operator()(A0 a0, A1 a1) + { f(c0, a0, a1); } }; template struct context22 { - F f; C0 c0; C1 c1; + F f; + C0 c0; + C1 c1; context22(F f, C0 c0, C1 c1) : f(f), c0(c0), c1(c1) {} - void operator()(A0 a0, A1 a1) { + void operator()(A0 a0, A1 a1) + { f(c0, c1, a0, a1); } }; template struct context32 { - F f; C0 c0; C1 c1; C2 c2; + F f; + C0 c0; + C1 c1; + C2 c2; context32(F f, C0 c0, C1 c1, C2 c2) : f(f), c0(c0), c1(c1), c2(c2) {} - void operator()(A0 a0, A1 a1) { + void operator()(A0 a0, A1 a1) + { f(c0, c1, c2, a0, a1); } }; template struct context42 { - F f; C0 c0; C1 c1; C2 c2; C3 c3; + F f; + C0 c0; + C1 c1; + C2 c2; + C3 c3; context42(F f, C0 c0, C1 c1, C2 c2, C3 c3) : f(f), c0(c0), c1(c1), c2(c2), c3(c3) {} - void operator()(A0 a0, A1 a1) { + void operator()(A0 a0, A1 a1) + { f(c0, c1, c2, c3, a0, a1); } }; template struct context52 { - F f; C0 c0; C1 c1; C2 c2; C3 c3; C4 c4; + F f; + C0 c0; + C1 c1; + C2 c2; + C3 c3; + C4 c4; context52(F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) : f(f), c0(c0), c1(c1), c2(c2), c3(c3), c4(c4) {} - void operator()(A0 a0, A1 a1) { + void operator()(A0 a0, A1 a1) + { f(c0, c1, c2, c3, c4, a0, a1); } }; @@ -2544,67 +2702,88 @@ class EventQueue : private mbed::NonCopyable { context03(F f) : f(f) {} - void operator()(A0 a0, A1 a1, A2 a2) { + void operator()(A0 a0, A1 a1, A2 a2) + { f(a0, a1, a2); } }; template struct context13 { - F f; C0 c0; + F f; + C0 c0; context13(F f, C0 c0) : f(f), c0(c0) {} - void operator()(A0 a0, A1 a1, A2 a2) { + void operator()(A0 a0, A1 a1, A2 a2) + { f(c0, a0, a1, a2); } }; template struct context23 { - F f; C0 c0; C1 c1; + F f; + C0 c0; + C1 c1; context23(F f, C0 c0, C1 c1) : f(f), c0(c0), c1(c1) {} - void operator()(A0 a0, A1 a1, A2 a2) { + void operator()(A0 a0, A1 a1, A2 a2) + { f(c0, c1, a0, a1, a2); } }; template struct context33 { - F f; C0 c0; C1 c1; C2 c2; + F f; + C0 c0; + C1 c1; + C2 c2; context33(F f, C0 c0, C1 c1, C2 c2) : f(f), c0(c0), c1(c1), c2(c2) {} - void operator()(A0 a0, A1 a1, A2 a2) { + void operator()(A0 a0, A1 a1, A2 a2) + { f(c0, c1, c2, a0, a1, a2); } }; template struct context43 { - F f; C0 c0; C1 c1; C2 c2; C3 c3; + F f; + C0 c0; + C1 c1; + C2 c2; + C3 c3; context43(F f, C0 c0, C1 c1, C2 c2, C3 c3) : f(f), c0(c0), c1(c1), c2(c2), c3(c3) {} - void operator()(A0 a0, A1 a1, A2 a2) { + void operator()(A0 a0, A1 a1, A2 a2) + { f(c0, c1, c2, c3, a0, a1, a2); } }; template struct context53 { - F f; C0 c0; C1 c1; C2 c2; C3 c3; C4 c4; + F f; + C0 c0; + C1 c1; + C2 c2; + C3 c3; + C4 c4; context53(F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) : f(f), c0(c0), c1(c1), c2(c2), c3(c3), c4(c4) {} - void operator()(A0 a0, A1 a1, A2 a2) { + void operator()(A0 a0, A1 a1, A2 a2) + { f(c0, c1, c2, c3, c4, a0, a1, a2); } }; @@ -2616,67 +2795,88 @@ class EventQueue : private mbed::NonCopyable { context04(F f) : f(f) {} - void operator()(A0 a0, A1 a1, A2 a2, A3 a3) { + void operator()(A0 a0, A1 a1, A2 a2, A3 a3) + { f(a0, a1, a2, a3); } }; template struct context14 { - F f; C0 c0; + F f; + C0 c0; context14(F f, C0 c0) : f(f), c0(c0) {} - void operator()(A0 a0, A1 a1, A2 a2, A3 a3) { + void operator()(A0 a0, A1 a1, A2 a2, A3 a3) + { f(c0, a0, a1, a2, a3); } }; template struct context24 { - F f; C0 c0; C1 c1; + F f; + C0 c0; + C1 c1; context24(F f, C0 c0, C1 c1) : f(f), c0(c0), c1(c1) {} - void operator()(A0 a0, A1 a1, A2 a2, A3 a3) { + void operator()(A0 a0, A1 a1, A2 a2, A3 a3) + { f(c0, c1, a0, a1, a2, a3); } }; template struct context34 { - F f; C0 c0; C1 c1; C2 c2; + F f; + C0 c0; + C1 c1; + C2 c2; context34(F f, C0 c0, C1 c1, C2 c2) : f(f), c0(c0), c1(c1), c2(c2) {} - void operator()(A0 a0, A1 a1, A2 a2, A3 a3) { + void operator()(A0 a0, A1 a1, A2 a2, A3 a3) + { f(c0, c1, c2, a0, a1, a2, a3); } }; template struct context44 { - F f; C0 c0; C1 c1; C2 c2; C3 c3; + F f; + C0 c0; + C1 c1; + C2 c2; + C3 c3; context44(F f, C0 c0, C1 c1, C2 c2, C3 c3) : f(f), c0(c0), c1(c1), c2(c2), c3(c3) {} - void operator()(A0 a0, A1 a1, A2 a2, A3 a3) { + void operator()(A0 a0, A1 a1, A2 a2, A3 a3) + { f(c0, c1, c2, c3, a0, a1, a2, a3); } }; template struct context54 { - F f; C0 c0; C1 c1; C2 c2; C3 c3; C4 c4; + F f; + C0 c0; + C1 c1; + C2 c2; + C3 c3; + C4 c4; context54(F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) : f(f), c0(c0), c1(c1), c2(c2), c3(c3), c4(c4) {} - void operator()(A0 a0, A1 a1, A2 a2, A3 a3) { + void operator()(A0 a0, A1 a1, A2 a2, A3 a3) + { f(c0, c1, c2, c3, c4, a0, a1, a2, a3); } }; @@ -2688,67 +2888,88 @@ class EventQueue : private mbed::NonCopyable { context05(F f) : f(f) {} - void operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + void operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) + { f(a0, a1, a2, a3, a4); } }; template struct context15 { - F f; C0 c0; + F f; + C0 c0; context15(F f, C0 c0) : f(f), c0(c0) {} - void operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + void operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) + { f(c0, a0, a1, a2, a3, a4); } }; template struct context25 { - F f; C0 c0; C1 c1; + F f; + C0 c0; + C1 c1; context25(F f, C0 c0, C1 c1) : f(f), c0(c0), c1(c1) {} - void operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + void operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) + { f(c0, c1, a0, a1, a2, a3, a4); } }; template struct context35 { - F f; C0 c0; C1 c1; C2 c2; + F f; + C0 c0; + C1 c1; + C2 c2; context35(F f, C0 c0, C1 c1, C2 c2) : f(f), c0(c0), c1(c1), c2(c2) {} - void operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + void operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) + { f(c0, c1, c2, a0, a1, a2, a3, a4); } }; template struct context45 { - F f; C0 c0; C1 c1; C2 c2; C3 c3; + F f; + C0 c0; + C1 c1; + C2 c2; + C3 c3; context45(F f, C0 c0, C1 c1, C2 c2, C3 c3) : f(f), c0(c0), c1(c1), c2(c2), c3(c3) {} - void operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + void operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) + { f(c0, c1, c2, c3, a0, a1, a2, a3, a4); } }; template struct context55 { - F f; C0 c0; C1 c1; C2 c2; C3 c3; C4 c4; + F f; + C0 c0; + C1 c1; + C2 c2; + C3 c3; + C4 c4; context55(F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) : f(f), c0(c0), c1(c1), c2(c2), c3(c3), c4(c4) {} - void operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + void operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) + { f(c0, c1, c2, c3, c4, a0, a1, a2, a3, a4); } }; diff --git a/events/equeue/equeue_mbed.cpp b/events/equeue/equeue_mbed.cpp index 1b53a4ab6c80..79ca4c831823 100644 --- a/events/equeue/equeue_mbed.cpp +++ b/events/equeue/equeue_mbed.cpp @@ -154,7 +154,7 @@ bool equeue_sema_wait(equeue_sema_t *s, int ms) { if (ms == 0) { return false; } else if (ms > 0) { - timeout.attach_us(callback(equeue_sema_timeout, s), ms*1000); + timeout.attach_us(callback(equeue_sema_timeout, s), (us_timestamp_t)ms*1000); } core_util_critical_section_enter(); diff --git a/features/FEATURE_BLE/source/Gap.cpp b/features/FEATURE_BLE/source/Gap.cpp index 0ce6ebd62ed0..5da3f8fe8340 100644 --- a/features/FEATURE_BLE/source/Gap.cpp +++ b/features/FEATURE_BLE/source/Gap.cpp @@ -79,7 +79,7 @@ const Gap::PeripheralPrivacyConfiguration_t Gap::default_peripheral_privacy_conf const Gap::CentralPrivacyConfiguration_t Gap::default_central_privacy_configuration = { /* use_non_resolvable_random_address */ false, - /* resolution_strategy */ CentralPrivacyConfiguration_t::DO_NOT_RESOLVE + /* resolution_strategy */ CentralPrivacyConfiguration_t::RESOLVE_AND_FORWARD }; void Gap::processConnectionEvent( diff --git a/features/FEATURE_BLE/source/generic/GenericSecurityManager.cpp b/features/FEATURE_BLE/source/generic/GenericSecurityManager.cpp index 1af3521b442a..a444a573e686 100644 --- a/features/FEATURE_BLE/source/generic/GenericSecurityManager.cpp +++ b/features/FEATURE_BLE/source/generic/GenericSecurityManager.cpp @@ -1464,6 +1464,7 @@ void GenericSecurityManager::on_secure_connections_ltk_generated( flags->secure_connections_paired = true; _db->set_entry_peer_ltk(cb->db_entry, ltk); + _db->set_entry_local_ltk(cb->db_entry, ltk); } void GenericSecurityManager::on_keys_distributed_ltk( diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF52/source/nRF5xPalSecurityManager.cpp b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF52/source/nRF5xPalSecurityManager.cpp index 49ea2de83d7f..5eb1310bb47d 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF52/source/nRF5xPalSecurityManager.cpp +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF52/source/nRF5xPalSecurityManager.cpp @@ -760,6 +760,24 @@ nRF5xSecurityManager& nRF5xSecurityManager::get_security_manager() return _security_manager; } +/** + * EDIV and Rand are invalid if both are zero + */ +bool is_ediv_rand_valid(const uint16_t ediv, const uint8_t* rand) +{ + for (int i = 0; i < BLE_GAP_SEC_RAND_LEN; ++i) { + if (rand[i]) { + return true; + } + } + + if (ediv != 0) { + return true; + } + + return false; +} + bool nRF5xSecurityManager::sm_handler(const ble_evt_t *evt) { nRF5xSecurityManager& self = nRF5xSecurityManager::get_security_manager(); @@ -846,11 +864,17 @@ bool nRF5xSecurityManager::sm_handler(const ble_evt_t *evt) const ble_gap_evt_sec_info_request_t& req = gap_evt.params.sec_info_request; - handler->on_ltk_request( - connection, - ediv_t((uint8_t*)(&req.master_id.ediv)), - rand_t(req.master_id.rand) - ); + if (is_ediv_rand_valid(req.master_id.ediv, req.master_id.rand)) { + handler->on_ltk_request( + connection, + ediv_t((uint8_t*)(&req.master_id.ediv)), + rand_t(req.master_id.rand) + ); + } else { + /* no valid EDIV and Rand + * request ltk generated with secure connection */ + handler->on_ltk_request(connection); + } return true; } @@ -948,33 +972,46 @@ bool nRF5xSecurityManager::sm_handler(const ble_evt_t *evt) peer_dist = pairing_cb->initiator_dist; } - if (own_dist.get_encryption()) { - handler->on_keys_distributed_local_ltk( - connection, - ltk_t(pairing_cb->own_enc_key.enc_info.ltk) - ); - - handler->on_keys_distributed_local_ediv_rand( - connection, - ediv_t(reinterpret_cast( - &pairing_cb->own_enc_key.master_id.ediv - )), + if (is_ediv_rand_valid( + pairing_cb->own_enc_key.master_id.ediv, pairing_cb->own_enc_key.master_id.rand - ); - } - - if (peer_dist.get_encryption()) { - handler->on_keys_distributed_ltk( - connection, - ltk_t(pairing_cb->peer_enc_key.enc_info.ltk) - ); + ) + ) { + if (own_dist.get_encryption()) { + handler->on_keys_distributed_local_ltk( + connection, + ltk_t(pairing_cb->own_enc_key.enc_info.ltk) + ); + + handler->on_keys_distributed_local_ediv_rand( + connection, + ediv_t(reinterpret_cast( + &pairing_cb->own_enc_key.master_id.ediv + )), + pairing_cb->own_enc_key.master_id.rand + ); + } - handler->on_keys_distributed_ediv_rand( + if (peer_dist.get_encryption()) { + handler->on_keys_distributed_ltk( + connection, + ltk_t(pairing_cb->peer_enc_key.enc_info.ltk) + ); + + handler->on_keys_distributed_ediv_rand( + connection, + ediv_t(reinterpret_cast( + &pairing_cb->peer_enc_key.master_id.ediv + )), + pairing_cb->peer_enc_key.master_id.rand + ); + } + } else { + /* no valid EDIV and Rand meaning this is a + * Secure Connections key */ + handler->on_secure_connections_ltk_generated( connection, - ediv_t(reinterpret_cast( - &pairing_cb->peer_enc_key.master_id.ediv - )), - pairing_cb->peer_enc_key.master_id.rand + ltk_t(pairing_cb->own_enc_key.enc_info.ltk) ); } diff --git a/features/TESTS/filesystem/buffered_block_device/main.cpp b/features/TESTS/filesystem/buffered_block_device/main.cpp index fcf385701de4..dc25bdab7a29 100644 --- a/features/TESTS/filesystem/buffered_block_device/main.cpp +++ b/features/TESTS/filesystem/buffered_block_device/main.cpp @@ -30,6 +30,10 @@ static const bd_size_t num_blocks = 4; void functionality_test() { + uint8_t *dummy = new (std::nothrow) uint8_t[num_blocks * heap_erase_size + heap_prog_size]; + TEST_SKIP_UNLESS_MESSAGE(dummy, "Not enough memory for test"); + delete[] dummy; + HeapBlockDevice heap_bd(num_blocks * heap_erase_size, heap_read_size, heap_prog_size, heap_erase_size); BufferedBlockDevice bd(&heap_bd); @@ -37,8 +41,10 @@ void functionality_test() TEST_ASSERT_EQUAL(0, err); uint8_t *read_buf, *write_buf; - read_buf = new uint8_t[heap_prog_size]; - write_buf = new uint8_t[heap_prog_size]; + read_buf = new (std::nothrow) uint8_t[heap_prog_size]; + TEST_SKIP_UNLESS_MESSAGE(read_buf, "Not enough memory for test"); + write_buf = new (std::nothrow) uint8_t[heap_prog_size]; + TEST_SKIP_UNLESS_MESSAGE(write_buf, "Not enough memory for test"); TEST_ASSERT_EQUAL(1, bd.get_read_size()); TEST_ASSERT_EQUAL(1, bd.get_program_size()); diff --git a/features/TESTS/filesystem/heap_block_device/main.cpp b/features/TESTS/filesystem/heap_block_device/main.cpp index 20fbb8d8b94e..367e28d1552a 100644 --- a/features/TESTS/filesystem/heap_block_device/main.cpp +++ b/features/TESTS/filesystem/heap_block_device/main.cpp @@ -46,6 +46,10 @@ const struct { // Simple test that read/writes random set of blocks void test_read_write() { + uint8_t *dummy = new (std::nothrow) uint8_t[TEST_BLOCK_DEVICE_SIZE]; + TEST_SKIP_UNLESS_MESSAGE(dummy, "Not enough memory for test"); + delete[] dummy; + HeapBlockDevice bd(TEST_BLOCK_DEVICE_SIZE, TEST_BLOCK_SIZE); int err = bd.init(); @@ -63,12 +67,18 @@ void test_read_write() { } } - bd_size_t block_size = bd.get_erase_size(); - uint8_t *write_block = new uint8_t[block_size]; - uint8_t *read_block = new uint8_t[block_size]; - uint8_t *error_mask = new uint8_t[TEST_ERROR_MASK]; unsigned addrwidth = ceil(log(float(bd.size()-1)) / log(float(16)))+1; + bd_size_t block_size = bd.get_erase_size(); + uint8_t *write_block = new (std::nothrow) uint8_t[block_size]; + uint8_t *read_block = new (std::nothrow) uint8_t[block_size]; + uint8_t *error_mask = new (std::nothrow) uint8_t[TEST_ERROR_MASK]; + if (!write_block || !read_block || !error_mask) { + printf("Not enough memory for test"); + goto end; + } + + for (int b = 0; b < TEST_BLOCK_COUNT; b++) { // Find a random block bd_addr_t block = (rand()*block_size) % bd.size(); @@ -135,6 +145,12 @@ void test_read_write() { err = bd.deinit(); TEST_ASSERT_EQUAL(0, err); + +end: + delete[] write_block; + delete[] read_block; + delete[] error_mask; + } diff --git a/features/TESTS/filesystem/mbr_block_device/main.cpp b/features/TESTS/filesystem/mbr_block_device/main.cpp index 633e7463e2e2..87dcfa14f00b 100644 --- a/features/TESTS/filesystem/mbr_block_device/main.cpp +++ b/features/TESTS/filesystem/mbr_block_device/main.cpp @@ -37,6 +37,10 @@ HeapBlockDevice bd(BLOCK_COUNT*BLOCK_SIZE, BLOCK_SIZE); // Testing formatting of master boot record void test_mbr_format() { + uint8_t *dummy = new (std::nothrow) uint8_t[BLOCK_COUNT * BLOCK_SIZE]; + TEST_SKIP_UNLESS_MESSAGE(dummy, "Not enough memory for test"); + delete[] dummy; + // Create two partitions splitting device in ~half int err = MBRBlockDevice::partition(&bd, 1, 0x83, 0, (BLOCK_COUNT/2)*BLOCK_SIZE); TEST_ASSERT_EQUAL(0, err); @@ -68,6 +72,10 @@ void test_mbr_format() // Testing mbr attributes void test_mbr_attr() { + uint8_t *dummy = new (std::nothrow) uint8_t[BLOCK_COUNT * BLOCK_SIZE]; + TEST_SKIP_UNLESS_MESSAGE(dummy, "Not enough memory for test"); + delete[] dummy; + // Load partitions MBRBlockDevice part1(&bd, 1); int err = part1.init(); @@ -123,9 +131,15 @@ void test_mbr_attr() // Testing mbr read write void test_mbr_read_write() { + uint8_t *dummy = new (std::nothrow) uint8_t[BLOCK_COUNT * BLOCK_SIZE]; + TEST_SKIP_UNLESS_MESSAGE(dummy, "Not enough memory for test"); + delete[] dummy; + + int err; + // Load partitions MBRBlockDevice part1(&bd, 1); - int err = part1.init(); + err = part1.init(); TEST_ASSERT_EQUAL(0, err); MBRBlockDevice part2(&bd, 2); @@ -133,8 +147,12 @@ void test_mbr_read_write() TEST_ASSERT_EQUAL(0, err); // Test reading/writing the partitions - uint8_t *write_block = new uint8_t[BLOCK_SIZE]; - uint8_t *read_block = new uint8_t[BLOCK_SIZE]; + uint8_t *write_block = new (std::nothrow) uint8_t[BLOCK_SIZE]; + uint8_t *read_block = new (std::nothrow) uint8_t[BLOCK_SIZE]; + if (!write_block || !read_block) { + printf("Not enough memory for test"); + goto end; + } // Fill with random sequence srand(1); @@ -200,15 +218,16 @@ void test_mbr_read_write() TEST_ASSERT_EQUAL(0xff & rand(), read_block[i]); } - // Clean up - delete[] write_block; - delete[] read_block; - err = part1.deinit(); TEST_ASSERT_EQUAL(0, err); err = part2.deinit(); TEST_ASSERT_EQUAL(0, err); + +end: + // Clean up + delete[] write_block; + delete[] read_block; } diff --git a/features/TESTS/filesystem/util_block_device/main.cpp b/features/TESTS/filesystem/util_block_device/main.cpp index b4a104be0c14..f55186182411 100644 --- a/features/TESTS/filesystem/util_block_device/main.cpp +++ b/features/TESTS/filesystem/util_block_device/main.cpp @@ -37,20 +37,32 @@ using namespace utest::v1; // Simple test which read/writes blocks on a sliced block device void test_slicing() { + uint8_t *dummy = new (std::nothrow) uint8_t[BLOCK_COUNT * BLOCK_SIZE]; + TEST_SKIP_UNLESS_MESSAGE(dummy, "Not enough memory for test"); + delete[] dummy; + + int err; + HeapBlockDevice bd(BLOCK_COUNT*BLOCK_SIZE, BLOCK_SIZE); - uint8_t *write_block = new uint8_t[BLOCK_SIZE]; - uint8_t *read_block = new uint8_t[BLOCK_SIZE]; - // Test with first slice of block device SlicingBlockDevice slice1(&bd, 0, (BLOCK_COUNT/2)*BLOCK_SIZE); + SlicingBlockDevice slice2(&bd, -(BLOCK_COUNT/2)*BLOCK_SIZE); - int err = slice1.init(); + // Test with first slice of block device + err = slice1.init(); TEST_ASSERT_EQUAL(0, err); TEST_ASSERT_EQUAL(BLOCK_SIZE, slice1.get_program_size()); TEST_ASSERT_EQUAL(BLOCK_SIZE, slice1.get_erase_size(BLOCK_SIZE)); TEST_ASSERT_EQUAL((BLOCK_COUNT/2)*BLOCK_SIZE, slice1.size()); + uint8_t *write_block = new (std::nothrow) uint8_t[BLOCK_SIZE]; + uint8_t *read_block = new (std::nothrow) uint8_t[BLOCK_SIZE]; + if (!write_block || !read_block) { + printf("Not enough memory for test"); + goto end; + } + // Fill with random sequence srand(1); for (int i = 0; i < BLOCK_SIZE; i++) { @@ -80,13 +92,7 @@ void test_slicing() { TEST_ASSERT_EQUAL(0xff & rand(), read_block[i]); } - err = slice1.deinit(); - TEST_ASSERT_EQUAL(0, err); - - // Test with second slice of block device - SlicingBlockDevice slice2(&bd, -(BLOCK_COUNT/2)*BLOCK_SIZE); - err = slice2.init(); TEST_ASSERT_EQUAL(0, err); @@ -99,6 +105,10 @@ void test_slicing() { write_block[i] = 0xff & rand(); } + // Deinitialize slice1 here, to check whether init reference count works + err = slice1.deinit(); + TEST_ASSERT_EQUAL(0, err); + // Write, sync, and read the block err = slice2.program(write_block, 0, BLOCK_SIZE); TEST_ASSERT_EQUAL(0, err); @@ -122,24 +132,38 @@ void test_slicing() { TEST_ASSERT_EQUAL(0xff & rand(), read_block[i]); } - delete[] write_block; - delete[] read_block; err = slice2.deinit(); TEST_ASSERT_EQUAL(0, err); + +end: + delete[] write_block; + delete[] read_block; } // Simple test which read/writes blocks on a chain of block devices void test_chaining() { + uint8_t *dummy = new (std::nothrow) uint8_t[BLOCK_COUNT * BLOCK_SIZE]; + TEST_SKIP_UNLESS_MESSAGE(dummy, "Not enough memory for test"); + delete[] dummy; + + int err; + HeapBlockDevice bd1((BLOCK_COUNT/2)*BLOCK_SIZE, BLOCK_SIZE); HeapBlockDevice bd2((BLOCK_COUNT/2)*BLOCK_SIZE, BLOCK_SIZE); - uint8_t *write_block = new uint8_t[BLOCK_SIZE]; - uint8_t *read_block = new uint8_t[BLOCK_SIZE]; // Test with chain of block device BlockDevice *bds[] = {&bd1, &bd2}; ChainingBlockDevice chain(bds); - int err = chain.init(); + uint8_t *write_block = new (std::nothrow) uint8_t[BLOCK_SIZE]; + uint8_t *read_block = new (std::nothrow) uint8_t[BLOCK_SIZE]; + + if (!write_block || !read_block) { + printf("Not enough memory for test"); + goto end; + } + + err = chain.init(); TEST_ASSERT_EQUAL(0, err); TEST_ASSERT_EQUAL(BLOCK_SIZE, chain.get_program_size()); @@ -178,27 +202,41 @@ void test_chaining() { TEST_ASSERT_EQUAL(0xff & rand(), read_block[i]); } - delete[] write_block; - delete[] read_block; err = chain.deinit(); TEST_ASSERT_EQUAL(0, err); + +end: + delete[] write_block; + delete[] read_block; } // Simple test which read/writes blocks on a chain of block devices void test_profiling() { - HeapBlockDevice bd(BLOCK_COUNT*BLOCK_SIZE, BLOCK_SIZE); - uint8_t *write_block = new uint8_t[BLOCK_SIZE]; - uint8_t *read_block = new uint8_t[BLOCK_SIZE]; + uint8_t *dummy = new (std::nothrow) uint8_t[BLOCK_COUNT * BLOCK_SIZE]; + TEST_SKIP_UNLESS_MESSAGE(dummy, "Not enough memory for test"); + delete[] dummy; + int err; + bd_size_t read_count, program_count, erase_count; + + HeapBlockDevice bd(BLOCK_COUNT*BLOCK_SIZE, BLOCK_SIZE); // Test under profiling ProfilingBlockDevice profiler(&bd); - int err = profiler.init(); + err = profiler.init(); TEST_ASSERT_EQUAL(0, err); TEST_ASSERT_EQUAL(BLOCK_SIZE, profiler.get_erase_size()); TEST_ASSERT_EQUAL(BLOCK_COUNT*BLOCK_SIZE, profiler.size()); + uint8_t *write_block = new (std::nothrow) uint8_t[BLOCK_SIZE]; + uint8_t *read_block = new (std::nothrow) uint8_t[BLOCK_SIZE]; + + if (!write_block || !read_block) { + printf("Not enough memory for test"); + goto end; + } + // Fill with random sequence srand(1); for (int i = 0; i < BLOCK_SIZE; i++) { @@ -231,18 +269,20 @@ void test_profiling() { TEST_ASSERT_EQUAL(0xff & rand(), read_block[i]); } - delete[] write_block; - delete[] read_block; err = profiler.deinit(); TEST_ASSERT_EQUAL(0, err); // Check that profiled operations match expectations - bd_size_t read_count = profiler.get_read_count(); + read_count = profiler.get_read_count(); TEST_ASSERT_EQUAL(BLOCK_SIZE, read_count); - bd_size_t program_count = profiler.get_program_count(); + program_count = profiler.get_program_count(); TEST_ASSERT_EQUAL(BLOCK_SIZE, program_count); - bd_size_t erase_count = profiler.get_erase_count(); + erase_count = profiler.get_erase_count(); TEST_ASSERT_EQUAL(BLOCK_SIZE, erase_count); + +end: + delete[] write_block; + delete[] read_block; } diff --git a/features/cellular/TESTS/api/cellular_device/main.cpp b/features/cellular/TESTS/api/cellular_device/main.cpp index 3e2994e277f0..82ce6784440b 100644 --- a/features/cellular/TESTS/api/cellular_device/main.cpp +++ b/features/cellular/TESTS/api/cellular_device/main.cpp @@ -55,25 +55,25 @@ static void open_close_interfaces() nw = device->open_network(NULL); TEST_ASSERT(nw == NULL); - CellularSIM* sim = device->open_sim(&cellular_serial); + CellularSIM *sim = device->open_sim(&cellular_serial); TEST_ASSERT(sim != NULL); device->close_sim(); sim = device->open_sim(NULL); TEST_ASSERT(sim == NULL); - CellularInformation* info = device->open_information(&cellular_serial); + CellularInformation *info = device->open_information(&cellular_serial); TEST_ASSERT(info != NULL); device->close_information(); info = device->open_information(NULL); TEST_ASSERT(info == NULL); - CellularPower* power = device->open_power(&cellular_serial); + CellularPower *power = device->open_power(&cellular_serial); TEST_ASSERT(power != NULL); device->close_power(); power = device->open_power(NULL); TEST_ASSERT(power == NULL); - CellularSMS* sms = device->open_sms(&cellular_serial); + CellularSMS *sms = device->open_sms(&cellular_serial); TEST_ASSERT(sms != NULL); device->close_sms(); sms = device->open_sms(NULL); @@ -86,7 +86,7 @@ static void other_methods() device->set_timeout(5000); device->modem_debug_on(true); device->modem_debug_on(false); - NetworkStack* stack = device->get_stack(); + NetworkStack *stack = device->get_stack(); TEST_ASSERT(stack == NULL); CellularNetwork *nw = device->open_network(&cellular_serial); @@ -124,7 +124,7 @@ static Case cases[] = { static utest::v1::status_t test_setup(const size_t number_of_cases) { - GREENTEA_SETUP(10*60, "default_auto"); + GREENTEA_SETUP(10 * 60, "default_auto"); return verbose_test_setup_handler(number_of_cases); } diff --git a/features/cellular/TESTS/api/cellular_information/main.cpp b/features/cellular/TESTS/api/cellular_information/main.cpp index 947a8a2d64b9..48f6468fa425 100644 --- a/features/cellular/TESTS/api/cellular_information/main.cpp +++ b/features/cellular/TESTS/api/cellular_information/main.cpp @@ -76,7 +76,7 @@ static void test_information_interface() { CellularInformation *info = cellular.get_device()->open_information(&cellular_serial); const int kbuf_size = 100; - char *buf = (char*)malloc(sizeof(char) * kbuf_size); + char *buf = (char *)malloc(sizeof(char) * kbuf_size); TEST_ASSERT(info->get_manufacturer(buf, kbuf_size) == NSAPI_ERROR_OK); TEST_ASSERT(info->get_model(buf, kbuf_size) == NSAPI_ERROR_OK); @@ -112,7 +112,7 @@ static Case cases[] = { static utest::v1::status_t test_setup(const size_t number_of_cases) { - GREENTEA_SETUP(10*60, "default_auto"); + GREENTEA_SETUP(10 * 60, "default_auto"); return verbose_test_setup_handler(number_of_cases); } diff --git a/features/cellular/TESTS/api/cellular_network/main.cpp b/features/cellular/TESTS/api/cellular_network/main.cpp index bad4f268810e..355b99f039ab 100644 --- a/features/cellular/TESTS/api/cellular_network/main.cpp +++ b/features/cellular/TESTS/api/cellular_network/main.cpp @@ -51,7 +51,7 @@ static rtos::Semaphore network_semaphore(0); static CellularConnectionFSM cellular; static CellularConnectionFSM::CellularState cellular_target_state; static CELLULAR_DEVICE *device; -static CellularNetwork* nw; +static CellularNetwork *nw; static bool fsm_callback(int state, int next_state) @@ -73,7 +73,7 @@ static void test_network_interface_fsm() device = new CELLULAR_DEVICE(queue); TEST_ASSERT(device != NULL); - CellularNetwork* nw = device->open_network(&cellular_serial); + CellularNetwork *nw = device->open_network(&cellular_serial); TEST_ASSERT(nw != NULL); TEST_ASSERT(nw->init() == NSAPI_ERROR_OK); @@ -99,7 +99,7 @@ static void init_network_interface() static bool get_network_registration(CellularNetwork::RegistrationType type, - CellularNetwork::RegistrationStatus &status, bool &is_registered) + CellularNetwork::RegistrationStatus &status, bool &is_registered) { is_registered = false; nsapi_error_t err = nw->get_registration_status(type, status); @@ -147,7 +147,7 @@ static void nw_callback(nsapi_event_t ev, intptr_t intptr) static void test_network_registration() { - cellular.get_device()->set_timeout(10*1000); + cellular.get_device()->set_timeout(10 * 1000); nw = cellular.get_network(); TEST_ASSERT(nw != NULL); @@ -213,6 +213,7 @@ static void test_credentials() static void test_other() { + const char* devi = CELLULAR_STRINGIFY(CELLULAR_DEVICE); TEST_ASSERT(nw->get_3gpp_error() == 0); CellularNetwork::RateControlExceptionReports reports; @@ -220,23 +221,24 @@ static void test_other() int uplinkRate; // can't test values as they are optional nsapi_error_t err = nw->get_rate_control(reports, timeUnit, uplinkRate); - tr_error("get_rate_control: %d", err); TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR); -#if CELLULAR_DEVICE != QUECTEL_BG96 // QUECTEL_BG96 does not give any specific reason for device error - if (err == NSAPI_ERROR_DEVICE_ERROR) { - TEST_ASSERT(((AT_CellularNetwork*)nw)->get_device_error().errCode == 100 && // 100 == unknown command for modem - ((AT_CellularNetwork*)nw)->get_device_error().errType == 3); // 3 == CME error from the modem + if (strcmp(devi, "QUECTEL_BG96") != 0 && strcmp(devi, "TELIT_HE910") != 0) { // QUECTEL_BG96 does not give any specific reason for device error + if (err == NSAPI_ERROR_DEVICE_ERROR) { + TEST_ASSERT(((AT_CellularNetwork *)nw)->get_device_error().errCode == 100 && // 100 == unknown command for modem + ((AT_CellularNetwork *)nw)->get_device_error().errType == 3); // 3 == CME error from the modem + } } -#endif uplinkRate = -1; err = nw->get_apn_backoff_timer(uplinkRate); - TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR); + TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR || err == NSAPI_ERROR_PARAMETER); if (err == NSAPI_ERROR_DEVICE_ERROR) { -#if CELLULAR_DEVICE != QUECTEL_BG96 // QUECTEL_BG96 does not give any specific reason for device error - TEST_ASSERT(((AT_CellularNetwork*)nw)->get_device_error().errCode == 100 && // 100 == unknown command for modem - ((AT_CellularNetwork*)nw)->get_device_error().errType == 3); // 3 == CME error from the modem -#endif + if (strcmp(devi, "QUECTEL_BG96") != 0 && strcmp(devi, "TELIT_HE910") != 0) { // QUECTEL_BG96 does not give any specific reason for device error + TEST_ASSERT(((AT_CellularNetwork *)nw)->get_device_error().errCode == 100 && // 100 == unknown command for modem + ((AT_CellularNetwork *)nw)->get_device_error().errType == 3); // 3 == CME error from the modem + } + } else if (err == NSAPI_ERROR_PARAMETER) { + TEST_ASSERT(uplinkRate == -1); } else { TEST_ASSERT(uplinkRate >= 0); } @@ -245,10 +247,10 @@ static void test_other() TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_UNSUPPORTED); // scanning of operators might take a long time - cellular.get_device()->set_timeout(240*1000); + cellular.get_device()->set_timeout(240 * 1000); CellularNetwork::operList_t operators; TEST_ASSERT(nw->scan_plmn(operators, uplinkRate) == NSAPI_ERROR_OK); - cellular.get_device()->set_timeout(10*1000); + cellular.get_device()->set_timeout(10 * 1000); // all current targets support IPV4 @@ -261,14 +263,13 @@ static void test_other() TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR); if (err == NSAPI_ERROR_DEVICE_ERROR) { -#if CELLULAR_DEVICE != TELIT_HE910 // TELIT_HE910 just gives an error and no specific error number so we can't know is this real error or that modem/network does not support the command - TEST_ASSERT(((AT_CellularNetwork*)nw)->get_device_error().errCode == 100 && // 100 == unknown command for modem - ((AT_CellularNetwork*)nw)->get_device_error().errType == 3); // 3 == CME error from the modem -#endif + if (strcmp(devi, "TELIT_HE910") != 0) { // TELIT_HE910 just gives an error and no specific error number so we can't know is this real error or that modem/network does not support the command + TEST_ASSERT(((AT_CellularNetwork *)nw)->get_device_error().errCode == 100 && // 100 == unknown command for modem + ((AT_CellularNetwork *)nw)->get_device_error().errType == 3); // 3 == CME error from the modem + } } else { // should have some values, only not optional are apn and bearer id - CellularNetwork::pdpcontext_params_t* params = params_list.get_head(); - TEST_ASSERT(strlen(params->apn) > 0); + CellularNetwork::pdpcontext_params_t *params = params_list.get_head(); TEST_ASSERT(params->bearer_id >= 0) } @@ -276,10 +277,10 @@ static void test_other() err = nw->get_extended_signal_quality(rxlev, ber, rscp, ecno, rsrq, rsrp); TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR); if (err == NSAPI_ERROR_DEVICE_ERROR) { -#if CELLULAR_DEVICE != QUECTEL_BG96 // QUECTEL_BG96 does not give any specific reason for device error - TEST_ASSERT(((AT_CellularNetwork*)nw)->get_device_error().errCode == 100 && // 100 == unknown command for modem - ((AT_CellularNetwork*)nw)->get_device_error().errType == 3); // 3 == CME error from the modem -#endif + if (strcmp(devi, "QUECTEL_BG96") != 0 && strcmp(devi, "TELIT_HE910") != 0) {// QUECTEL_BG96 does not give any specific reason for device error + TEST_ASSERT(((AT_CellularNetwork *)nw)->get_device_error().errCode == 100 && // 100 == unknown command for modem + ((AT_CellularNetwork *)nw)->get_device_error().errType == 3); // 3 == CME error from the modem + } } else { // we should have some values which are not optional TEST_ASSERT(rxlev >= 0 && ber >= 0 && rscp >= 0 && ecno >= 0 && rsrq >= 0 && rsrp >= 0); @@ -290,8 +291,8 @@ static void test_other() err = nw->get_signal_quality(rssi, ber); TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR); if (err == NSAPI_ERROR_DEVICE_ERROR) { - TEST_ASSERT(((AT_CellularNetwork*)nw)->get_device_error().errCode == 100 && // 100 == unknown command for modem - ((AT_CellularNetwork*)nw)->get_device_error().errType == 3); // 3 == CME error from the modem + TEST_ASSERT(((AT_CellularNetwork *)nw)->get_device_error().errCode == 100 && // 100 == unknown command for modem + ((AT_CellularNetwork *)nw)->get_device_error().errType == 3); // 3 == CME error from the modem } else { // test for values TEST_ASSERT(rssi >= 0); @@ -305,53 +306,55 @@ static void test_other() int format = -1; CellularNetwork::operator_t operator_params; // all params are optional so can't test operator_params - TEST_ASSERT(nw->get_operator_params(format, operator_params) == NSAPI_ERROR_OK); + err = nw->get_operator_params(format, operator_params); + TEST_ASSERT(err == NSAPI_ERROR_OK); nsapi_connection_status_t st = nw->get_connection_status(); TEST_ASSERT(st == NSAPI_STATUS_DISCONNECTED); TEST_ASSERT(nw->set_blocking(true) == NSAPI_ERROR_OK); -#if CELLULAR_DEVICE != QUECTEL_BG96 - // QUECTEL_BG96 timeouts with this one, tested with 3 minute timeout - CellularNetwork::operator_names_list op_names; - err = nw->get_operator_names(op_names); - TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR); - if (err == NSAPI_ERROR_DEVICE_ERROR) { - // if device error then we must check was that really device error or that modem/network does not support the commands - TEST_ASSERT(((AT_CellularNetwork*)nw)->get_device_error().errCode == 4// 4 == NOT SUPPORTED BY THE MODEM - && ((AT_CellularNetwork*)nw)->get_device_error().errType == 3); // 3 == CME error from the modem - } else { - CellularNetwork::operator_names_t* opn = op_names.get_head(); - TEST_ASSERT(strlen(opn->numeric) > 0); - TEST_ASSERT(strlen(opn->alpha > 0)); + if (strcmp(devi, "QUECTEL_BG96") != 0) { + // QUECTEL_BG96 timeouts with this one, tested with 3 minute timeout + CellularNetwork::operator_names_list op_names; + err = nw->get_operator_names(op_names); + TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR); + if (err == NSAPI_ERROR_DEVICE_ERROR) { + // if device error then we must check was that really device error or that modem/network does not support the commands + TEST_ASSERT(((AT_CellularNetwork *)nw)->get_device_error().errCode == 4 // 4 == NOT SUPPORTED BY THE MODEM + && ((AT_CellularNetwork *)nw)->get_device_error().errType == 3); // 3 == CME error from the modem + } else { + CellularNetwork::operator_names_t *opn = op_names.get_head(); + TEST_ASSERT(strlen(opn->numeric) > 0); + TEST_ASSERT(strlen(opn->alpha) > 0); + } } -#endif -#if CELLULAR_DEVICE != TELIT_HE910 - // TELIT_HE910 just gives an error and no specific error number so we can't know is this real error or that modem/network does not support the command - CellularNetwork::Supported_UE_Opt supported_opt = SUPPORTED_UE_OPT_MAX; - CellularNetwork::Preferred_UE_Opt preferred_opt = PREFERRED_UE_OPT_MAX; + // TELIT_HE910 and QUECTEL_BG96 just gives an error and no specific error number so we can't know is this real error or that modem/network does not support the command + CellularNetwork::Supported_UE_Opt supported_opt = CellularNetwork::SUPPORTED_UE_OPT_MAX; + CellularNetwork::Preferred_UE_Opt preferred_opt = CellularNetwork::PREFERRED_UE_OPT_MAX; err = nw->get_ciot_optimization_config(supported_opt, preferred_opt); TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR); if (err == NSAPI_ERROR_DEVICE_ERROR) { // if device error then we must check was that really device error or that modem/network does not support the commands - TEST_ASSERT(((AT_CellularNetwork*)nw)->get_device_error().errCode == 100 && // 100 == unknown command for modem - ((AT_CellularNetwork*)nw)->get_device_error().errType == 3); // 3 == CME error from the modem + if (!(strcmp(devi, "TELIT_HE910") == 0 || strcmp(devi, "QUECTEL_BG96") == 0)) { + TEST_ASSERT(((AT_CellularNetwork *)nw)->get_device_error().errCode == 100 && // 100 == unknown command for modem + ((AT_CellularNetwork *)nw)->get_device_error().errType == 3); // 3 == CME error from the modem + } } else { - TEST_ASSERT(supported_opt != SUPPORTED_UE_OPT_MAX); - TEST_ASSERT(preferred_opt != PREFERRED_UE_OPT_MAX); + TEST_ASSERT(supported_opt != CellularNetwork::SUPPORTED_UE_OPT_MAX); + TEST_ASSERT(preferred_opt != CellularNetwork::PREFERRED_UE_OPT_MAX); } err = nw->set_ciot_optimization_config(supported_opt, preferred_opt); TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR); if (err == NSAPI_ERROR_DEVICE_ERROR) { // if device error then we must check was that really device error or that modem/network does not support the commands - TEST_ASSERT(((AT_CellularNetwork*)nw)->get_device_error().errCode == 100 && // 100 == unknown command for modem - ((AT_CellularNetwork*)nw)->get_device_error().errType == 3); // 3 == CME error from the modem + if (!(strcmp(devi, "TELIT_HE910") == 0 || strcmp(devi, "QUECTEL_BG96") == 0)) { + TEST_ASSERT(((AT_CellularNetwork *)nw)->get_device_error().errCode == 100 && // 100 == unknown command for modem + ((AT_CellularNetwork *)nw)->get_device_error().errType == 3); // 3 == CME error from the modem + } } -#endif - } static void test_disconnect() @@ -364,13 +367,15 @@ static void test_disconnect() static void test_detach() { // in PPP mode there is NO CARRIER waiting so flush it out - rtos::Thread::wait(6*1000); - ((AT_CellularNetwork*)nw)->get_at_handler().flush(); + rtos::Thread::wait(6 * 1000); + ((AT_CellularNetwork *)nw)->get_at_handler().flush(); nsapi_connection_status_t st = nw->get_connection_status(); TEST_ASSERT(st == NSAPI_STATUS_DISCONNECTED); TEST_ASSERT(nw->detach() == NSAPI_ERROR_OK); + // wait to process URC's, received after detach + rtos::Thread::wait(50); st = nw->get_connection_status(); TEST_ASSERT(st == NSAPI_STATUS_DISCONNECTED); } @@ -399,7 +404,7 @@ static Case cases[] = { static utest::v1::status_t test_setup(const size_t number_of_cases) { - GREENTEA_SETUP(10*60, "default_auto"); + GREENTEA_SETUP(10 * 60, "default_auto"); return verbose_test_setup_handler(number_of_cases); } diff --git a/features/cellular/TESTS/api/cellular_power/main.cpp b/features/cellular/TESTS/api/cellular_power/main.cpp index f21a8d92d597..f1d471e1833b 100644 --- a/features/cellular/TESTS/api/cellular_power/main.cpp +++ b/features/cellular/TESTS/api/cellular_power/main.cpp @@ -44,46 +44,68 @@ #define NETWORK_TIMEOUT (180*1000) static UARTSerial cellular_serial(MDMTXD, MDMRXD, MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE); -static CELLULAR_DEVICE* cellular_device; +static CELLULAR_DEVICE *cellular_device; static EventQueue queue(2 * EVENTS_EVENT_SIZE); static void urc_callback() { } -static void wait_for_power(CellularPower* pwr) +static void wait_for_power(CellularPower *pwr) { nsapi_error_t err = pwr->set_device_ready_urc_cb(&urc_callback); TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_UNSUPPORTED); int sanity_count = 0; - while (pwr->is_device_ready() != NSAPI_ERROR_OK) { + err = pwr->set_at_mode(); + while (err != NSAPI_ERROR_OK) { sanity_count++; wait(1); - TEST_ASSERT(sanity_count < 20); + TEST_ASSERT(sanity_count < 40); + err = pwr->set_at_mode(); } - err = pwr->set_at_mode(); - TEST_ASSERT(err == NSAPI_ERROR_OK); + TEST_ASSERT(pwr->is_device_ready() == NSAPI_ERROR_OK); pwr->remove_device_ready_urc_cb(&urc_callback); } static void test_power_interface() { + const char* devi = CELLULAR_STRINGIFY(CELLULAR_DEVICE); cellular_device = new CELLULAR_DEVICE(queue); - CellularPower* pwr = cellular_device->open_power(&cellular_serial); + cellular_device->set_timeout(5000); + CellularPower *pwr = cellular_device->open_power(&cellular_serial); + TEST_ASSERT(pwr != NULL); nsapi_error_t err = pwr->on(); TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_UNSUPPORTED); wait_for_power(pwr); - TEST_ASSERT(pwr->set_power_level(1,0) == NSAPI_ERROR_OK); + TEST_ASSERT(pwr->set_power_level(1, 0) == NSAPI_ERROR_OK); err = pwr->reset(); TEST_ASSERT(err == NSAPI_ERROR_OK); wait_for_power(pwr); + err = pwr->opt_power_save_mode(0,0); + TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR); + if (err == NSAPI_ERROR_DEVICE_ERROR) { + if (!(strcmp(devi, "TELIT_HE910") == 0 || strcmp(devi, "QUECTEL_BG96") == 0)) { // TELIT_HE910 and QUECTEL_BG96 just gives an error and no specific error number so we can't know is this real error or that modem/network does not support the command + TEST_ASSERT(((AT_CellularPower*)pwr)->get_device_error().errCode == 100 && // 100 == unknown command for modem + ((AT_CellularPower*)pwr)->get_device_error().errType == 3); // 3 == CME error from the modem + } + } + + err = pwr->opt_receive_period(0, CellularPower::EDRXEUTRAN_NB_S1_mode, 3); + TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR); + if (err == NSAPI_ERROR_DEVICE_ERROR) { + if (!(strcmp(devi, "TELIT_HE910") == 0 || strcmp(devi, "QUECTEL_BG96") == 0)) { // TELIT_HE910 and QUECTEL_BG96 just gives an error and no specific error number so we can't know is this real error or that modem/network does not support the command + TEST_ASSERT(((AT_CellularPower*)pwr)->get_device_error().errCode == 100 && // 100 == unknown command for modem + ((AT_CellularPower*)pwr)->get_device_error().errType == 3); // 3 == CME error from the modem + } + } + err = pwr->off(); TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_UNSUPPORTED); } @@ -102,7 +124,7 @@ static Case cases[] = { static utest::v1::status_t test_setup(const size_t number_of_cases) { - GREENTEA_SETUP(10*60, "default_auto"); + GREENTEA_SETUP(10 * 60, "default_auto"); return verbose_test_setup_handler(number_of_cases); } diff --git a/features/cellular/TESTS/api/cellular_sim/main.cpp b/features/cellular/TESTS/api/cellular_sim/main.cpp index 7a5b889008a6..9ffba9a0bf91 100644 --- a/features/cellular/TESTS/api/cellular_sim/main.cpp +++ b/features/cellular/TESTS/api/cellular_sim/main.cpp @@ -56,7 +56,7 @@ static char *get_rand_string(char *str, size_t size) if (size) { --size; for (size_t n = 0; n < size; n++) { - int key = rand() % (int) (sizeof charset - 1); + int key = rand() % (int)(sizeof charset - 1); str[n] = charset[key]; } str[size] = '\0'; @@ -92,6 +92,9 @@ static void test_sim_interface() CellularSIM *sim = cellular.get_sim(); TEST_ASSERT(sim != NULL); + // set SIM at time out to 3000 + cellular.get_device()->set_timeout(3000); + wait(4); // we need to wait for some time so that SIM interface is working in all modules. // 1. test set_pin nsapi_error_t err = sim->set_pin(MBED_CONF_APP_CELLULAR_SIM_PIN); MBED_ASSERT(err == NSAPI_ERROR_OK); @@ -105,23 +108,31 @@ static void test_sim_interface() }; // change pin and change it back + wait(1); err = sim->change_pin(MBED_CONF_APP_CELLULAR_SIM_PIN, pin); TEST_ASSERT(err == NSAPI_ERROR_OK); + + wait(1); err = sim->change_pin(pin, MBED_CONF_APP_CELLULAR_SIM_PIN); TEST_ASSERT(err == NSAPI_ERROR_OK); // 3. test set_pin_query + wait(1); err = sim->set_pin_query(MBED_CONF_APP_CELLULAR_SIM_PIN, false); TEST_ASSERT(err == NSAPI_ERROR_OK); + + wait(1); err = sim->set_pin_query(MBED_CONF_APP_CELLULAR_SIM_PIN, true); TEST_ASSERT(err == NSAPI_ERROR_OK); + wait(1); // 4. test get_sim_state CellularSIM::SimState state; err = sim->get_sim_state(state); TEST_ASSERT(err == NSAPI_ERROR_OK); TEST_ASSERT(state == CellularSIM::SimStateReady); + wait(1); // 5. test get_imsi char imsi[16] = {0}; err = sim->get_imsi(imsi); @@ -144,7 +155,7 @@ static Case cases[] = { static utest::v1::status_t test_setup(const size_t number_of_cases) { - GREENTEA_SETUP(10*60, "default_auto"); + GREENTEA_SETUP(10 * 60, "default_auto"); return verbose_test_setup_handler(number_of_cases); } diff --git a/features/cellular/TESTS/api/cellular_sms/main.cpp b/features/cellular/TESTS/api/cellular_sms/main.cpp new file mode 100644 index 000000000000..dd238c263156 --- /dev/null +++ b/features/cellular/TESTS/api/cellular_sms/main.cpp @@ -0,0 +1,280 @@ +/* + * Copyright (c) 2018, Arm Limited and affiliates. + * 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. + */ + + +#if !defined(MBED_CONF_NSAPI_PRESENT) +#error [NOT_SUPPORTED] A json configuration file is needed. Skipping this build. +#endif + +#include "CellularUtil.h" // for CELLULAR_ helper macros +#include "CellularTargets.h" + +#ifndef CELLULAR_DEVICE +#error [NOT_SUPPORTED] CELLULAR_DEVICE must be defined +#endif + +#ifndef MBED_CONF_APP_CELLULAR_SIM_PIN +#error [NOT_SUPPORTED] SIM pin code is needed. Skipping this build. +#endif + + + +#include "greentea-client/test_env.h" +#include "unity.h" +#include "utest.h" + +#include "mbed.h" + +#include "AT_CellularSMS.h" +#include "CellularConnectionFSM.h" +#include "CellularDevice.h" +#include "../../cellular_tests_common.h" +#include CELLULAR_STRINGIFY(CELLULAR_DEVICE.h) + +#define NETWORK_TIMEOUT (600*1000) + +static UARTSerial cellular_serial(MDMTXD, MDMRXD, MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE); +static EventQueue queue(8 * EVENTS_EVENT_SIZE); +static rtos::Semaphore network_semaphore(0); +static CellularConnectionFSM *cellularConnectionFSM; +static CellularConnectionFSM::CellularState cellular_target_state; +static CellularSMS* sms; +static char service_center_address[SMS_MAX_PHONE_NUMBER_SIZE]; +static int service_address_type; + +static bool cellular_status(int state, int next_state) +{ + if (cellular_target_state == state) { + (void)network_semaphore.release(); + return false; // return false -> state machine is halted + } + return true; +} + +static void createFSM() +{ +#if defined (MDMRTS) && defined (MDMCTS) + cellular_serial.set_flow_control(SerialBase::RTSCTS, MDMRTS, MDMCTS); +#endif + cellularConnectionFSM = new CellularConnectionFSM(); + cellularConnectionFSM->set_serial(&cellular_serial); + cellularConnectionFSM->set_callback(&cellular_status); + + TEST_ASSERT(cellularConnectionFSM->init() == NSAPI_ERROR_OK); + TEST_ASSERT(cellularConnectionFSM->start_dispatch() == NSAPI_ERROR_OK); + cellularConnectionFSM->set_sim_pin(MBED_CONF_APP_CELLULAR_SIM_PIN); + + CellularDevice *device = cellularConnectionFSM->get_device(); + TEST_ASSERT(device != NULL); + device->set_timeout(30000); + +} +static void store_service_center_address() +{ + // Frist we need to go SIM_PIN state to make sure that we can get service address and device ready to accept AT commands + createFSM(); + cellular_target_state = CellularConnectionFSM::STATE_SIM_PIN; + TEST_ASSERT(cellularConnectionFSM->continue_to_state(cellular_target_state) == NSAPI_ERROR_OK); + TEST_ASSERT(network_semaphore.wait(NETWORK_TIMEOUT) == 1); // cellular network searching may take several minutes + + delete cellularConnectionFSM; + cellularConnectionFSM = NULL; + + ATHandler *at_init = new ATHandler(&cellular_serial, queue, 30000, "\r"); + at_init->cmd_start("AT+CSCA?"); + at_init->cmd_stop(); + + TEST_ASSERT(at_init->get_last_error() == NSAPI_ERROR_OK); + + at_init->resp_start("+CSCA:"); + at_init->read_string(service_center_address, sizeof(service_center_address)); + service_address_type = at_init->read_int(); + at_init->resp_stop(); + + TEST_ASSERT(at_init->get_last_error() == NSAPI_ERROR_OK); + + delete at_init; +} + +static void init() +{ + // First store current service address + store_service_center_address(); + + createFSM(); + CellularNetwork *network = cellularConnectionFSM->get_network(); + + TEST_ASSERT(network != NULL); + TEST_ASSERT(network->set_credentials(MBED_CONF_APP_APN, NULL, NULL) == NSAPI_ERROR_OK); + + cellular_target_state = CellularConnectionFSM::STATE_REGISTERING_NETWORK; + TEST_ASSERT(cellularConnectionFSM->continue_to_state(cellular_target_state) == NSAPI_ERROR_OK); + TEST_ASSERT(network_semaphore.wait(NETWORK_TIMEOUT) == 1); // cellular network searching may take several minutes + + sms = cellularConnectionFSM->get_device()->open_sms(&cellular_serial); + TEST_ASSERT(sms != NULL); + + wait(3); +} + +static void test_sms_initialize_text_mode() +{ + TEST_ASSERT(sms->initialize(CellularSMS::CellularSMSMmodeText) == NSAPI_ERROR_OK); +} + +static void test_sms_initialize_pdu_mode() +{ + TEST_ASSERT(sms->initialize(CellularSMS::CellularSMSMmodePDU) == NSAPI_ERROR_OK); +} + +static void test_set_cscs() +{ + TEST_ASSERT(sms->set_cscs("IRA") == NSAPI_ERROR_OK); + TEST_ASSERT(sms->set_cscs("UCS2") == NSAPI_ERROR_OK); + TEST_ASSERT(sms->set_cscs("GSM") == NSAPI_ERROR_OK); +} + +static void test_set_csca() +{ + TEST_ASSERT(sms->set_csca("55555", 129) == NSAPI_ERROR_OK); + TEST_ASSERT(sms->set_csca("+35855555", 145) == NSAPI_ERROR_OK); + TEST_ASSERT(sms->set_csca(service_center_address, service_address_type) == NSAPI_ERROR_OK); +} + +static void test_set_cpms_me() +{ + TEST_ASSERT(sms->set_cpms("ME", "ME", "ME") == NSAPI_ERROR_OK); +} + +#ifdef MBED_CONF_APP_CELLULAR_PHONE_NUMBER +static const char TEST_MESSAGE[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; +static int callbacks_received = 0; + +static void sms_callback() +{ + callbacks_received++; +} + +static void test_set_sms_callback() +{ + sms->set_sms_callback(sms_callback); +} + + +static void test_set_cpms_sm() +{ + TEST_ASSERT(sms->set_cpms("SM", "SM", "SM") == NSAPI_ERROR_OK); +} + +static void test_sms_send() +{ + const int msg_len = strlen(TEST_MESSAGE); + TEST_ASSERT(sms->send_sms(MBED_CONF_APP_CELLULAR_PHONE_NUMBER, TEST_MESSAGE, msg_len) == msg_len); +} + +static void test_get_sms() +{ + uint16_t buf_len = sizeof(TEST_MESSAGE); + char buf[buf_len]; + + char phone_num[SMS_MAX_PHONE_NUMBER_SIZE]; + + char time_stamp[SMS_MAX_TIME_STAMP_SIZE]; + + int buf_size = 0; + + wait(7); + + TEST_ASSERT(sms->get_sms(buf, buf_len, phone_num, SMS_MAX_PHONE_NUMBER_SIZE, time_stamp, SMS_MAX_TIME_STAMP_SIZE, &buf_size) == buf_len-1); + TEST_ASSERT(strcmp(phone_num, MBED_CONF_APP_CELLULAR_PHONE_NUMBER) == 0); + TEST_ASSERT(strcmp(buf, TEST_MESSAGE) == 0); + TEST_ASSERT(buf_size == 0); + TEST_ASSERT(callbacks_received > 0); + callbacks_received = 0; + +} + +static void test_delete_all_messages() +{ + //send a message so that there is something to delete + test_sms_send(); + wait(7); + TEST_ASSERT(sms->delete_all_messages() == NSAPI_ERROR_OK); + callbacks_received = 0; +} + +static void test_set_extra_sim_wait_time_1000() +{ + sms->set_extra_sim_wait_time(1000); +} + +#endif + + +using namespace utest::v1; + +static utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) +{ + greentea_case_failure_abort_handler(source, reason); + return STATUS_ABORT; +} + + +static Case cases[] = { + Case("CellularSMS init", init, greentea_failure_handler), + Case("CellularSMS test ME for storage", test_set_cpms_me, greentea_failure_handler), + Case("CellularSMS test initialize to PDU mode", test_sms_initialize_pdu_mode, greentea_failure_handler), + Case("CellularSMS test character sets", test_set_cscs, greentea_failure_handler), + Case("CellularSMS test service center address", test_set_csca, greentea_failure_handler) +#ifdef MBED_CONF_APP_CELLULAR_PHONE_NUMBER + , + Case("CellularSMS test delete all messages", test_delete_all_messages, greentea_failure_handler), + Case("CellularSMS test sms callback", test_set_sms_callback, greentea_failure_handler), + Case("CellularSMS test sms send", test_sms_send, greentea_failure_handler), + Case("CellularSMS test get sms", test_get_sms, greentea_failure_handler), + Case("CellularSMS test set sim wait time 1s", test_set_extra_sim_wait_time_1000, greentea_failure_handler), + Case("CellularSMS test SM for storage", test_set_cpms_sm, greentea_failure_handler), + Case("CellularSMS test initialize to text mode", test_sms_initialize_text_mode, greentea_failure_handler), + Case("CellularSMS test delete all messages", test_delete_all_messages, greentea_failure_handler), + Case("CellularSMS test sms send", test_sms_send, greentea_failure_handler), + Case("CellularSMS test get sms", test_get_sms, greentea_failure_handler), + Case("CellularSMS test delete all messages", test_delete_all_messages, greentea_failure_handler) +#endif +}; + + + + +static utest::v1::status_t test_setup(const size_t number_of_cases) +{ + GREENTEA_SETUP(600, "default_auto"); + return verbose_test_setup_handler(number_of_cases); +} + +static Specification specification(test_setup, cases); + +int main() +{ +#if MBED_CONF_MBED_TRACE_ENABLE + trace_open(); +#endif + int ret = Harness::run(specification); +#if MBED_CONF_MBED_TRACE_ENABLE + trace_close(); +#endif + return ret; +} diff --git a/features/cellular/UNITTESTS/at/at_cellularbase/at_cellularbasetest.cpp b/features/cellular/UNITTESTS/at/at_cellularbase/at_cellularbasetest.cpp index f4074843ebb7..0c7ff37f60b8 100644 --- a/features/cellular/UNITTESTS/at/at_cellularbase/at_cellularbasetest.cpp +++ b/features/cellular/UNITTESTS/at/at_cellularbase/at_cellularbasetest.cpp @@ -18,20 +18,23 @@ #include "test_at_cellularbase.h" #include "AT_CellularBase.h" +// AStyle ignored as the definition is not clear due to preprocessor usage +// *INDENT-OFF* TEST_GROUP(AT_CellularBase) { - Test_AT_CellularBase* unit; + Test_AT_CellularBase *unit; - void setup() + void setup() { unit = new Test_AT_CellularBase(); } - void teardown() + void teardown() { delete unit; } }; +// *INDENT-ON* TEST(AT_CellularBase, Create) { diff --git a/features/cellular/UNITTESTS/at/at_cellularbase/main.cpp b/features/cellular/UNITTESTS/at/at_cellularbase/main.cpp index a7c8e49fd980..2c5e6a635600 100644 --- a/features/cellular/UNITTESTS/at/at_cellularbase/main.cpp +++ b/features/cellular/UNITTESTS/at/at_cellularbase/main.cpp @@ -19,7 +19,7 @@ #include "CppUTest/TestPlugin.h" #include "CppUTest/TestRegistry.h" #include "CppUTestExt/MockSupportPlugin.h" -int main(int ac, char** av) +int main(int ac, char **av) { return CommandLineTestRunner::RunAllTests(ac, av); } diff --git a/features/cellular/UNITTESTS/at/at_cellularbase/test_at_cellularbase.cpp b/features/cellular/UNITTESTS/at/at_cellularbase/test_at_cellularbase.cpp index f3685aef38d2..e69af7f28f4f 100644 --- a/features/cellular/UNITTESTS/at/at_cellularbase/test_at_cellularbase.cpp +++ b/features/cellular/UNITTESTS/at/at_cellularbase/test_at_cellularbase.cpp @@ -27,9 +27,11 @@ using namespace events; class my_base : public AT_CellularBase { public: - my_base(ATHandler &at) : AT_CellularBase(at) { + my_base(ATHandler &at) : AT_CellularBase(at) + { } - bool check_not_supported() { + bool check_not_supported() + { static const AT_CellularBase::SupportedFeature unsupported_features[] = { AT_CellularBase::AT_CGSN_WITH_TYPE, AT_CellularBase::SUPPORTED_FEATURE_END_MARK @@ -38,12 +40,14 @@ class my_base : public AT_CellularBase { return is_supported(AT_CGSN_WITH_TYPE); } - bool check_supported() { + bool check_supported() + { set_unsupported_features(NULL); return is_supported(AT_CGSN_WITH_TYPE); } - bool check_supported_not_found() { + bool check_supported_not_found() + { static const AT_CellularBase::SupportedFeature unsupported_features[] = { AT_CellularBase::AT_CGSN_WITH_TYPE, AT_CellularBase::SUPPORTED_FEATURE_END_MARK diff --git a/features/cellular/UNITTESTS/at/at_cellularbase/test_at_cellularbase.h b/features/cellular/UNITTESTS/at/at_cellularbase/test_at_cellularbase.h index 5ce75ac38579..57dab4ea2dda 100644 --- a/features/cellular/UNITTESTS/at/at_cellularbase/test_at_cellularbase.h +++ b/features/cellular/UNITTESTS/at/at_cellularbase/test_at_cellularbase.h @@ -17,8 +17,7 @@ #ifndef TEST_AT_CELLULARBASE_H #define TEST_AT_CELLULARBASE_H -class Test_AT_CellularBase -{ +class Test_AT_CellularBase { public: Test_AT_CellularBase(); diff --git a/features/cellular/UNITTESTS/at/at_cellulardevice/at_cellulardevicetest.cpp b/features/cellular/UNITTESTS/at/at_cellulardevice/at_cellulardevicetest.cpp index d2e0c035963e..8dae6677a049 100644 --- a/features/cellular/UNITTESTS/at/at_cellulardevice/at_cellulardevicetest.cpp +++ b/features/cellular/UNITTESTS/at/at_cellulardevice/at_cellulardevicetest.cpp @@ -19,15 +19,13 @@ TEST_GROUP(AT_CellularDevice) { - Test_AT_CellularDevice* unit; + Test_AT_CellularDevice *unit; - void setup() - { + void setup() { unit = new Test_AT_CellularDevice(); } - void teardown() - { + void teardown() { delete unit; } }; diff --git a/features/cellular/UNITTESTS/at/at_cellulardevice/main.cpp b/features/cellular/UNITTESTS/at/at_cellulardevice/main.cpp index c498759f38ae..827f00e9d43f 100644 --- a/features/cellular/UNITTESTS/at/at_cellulardevice/main.cpp +++ b/features/cellular/UNITTESTS/at/at_cellulardevice/main.cpp @@ -19,7 +19,7 @@ #include "CppUTest/TestPlugin.h" #include "CppUTest/TestRegistry.h" #include "CppUTestExt/MockSupportPlugin.h" -int main(int ac, char** av) +int main(int ac, char **av) { return CommandLineTestRunner::RunAllTests(ac, av); } diff --git a/features/cellular/UNITTESTS/at/at_cellulardevice/test_at_cellulardevice.h b/features/cellular/UNITTESTS/at/at_cellulardevice/test_at_cellulardevice.h index 5f6590d310b5..6bc72d20ada9 100644 --- a/features/cellular/UNITTESTS/at/at_cellulardevice/test_at_cellulardevice.h +++ b/features/cellular/UNITTESTS/at/at_cellulardevice/test_at_cellulardevice.h @@ -17,8 +17,7 @@ #ifndef TEST_AT_CELLULARDEVICE_H #define TEST_AT_CELLULARDEVICE_H -class Test_AT_CellularDevice -{ +class Test_AT_CellularDevice { public: Test_AT_CellularDevice(); diff --git a/features/cellular/UNITTESTS/at/at_cellularinformation/at_cellularinformationtest.cpp b/features/cellular/UNITTESTS/at/at_cellularinformation/at_cellularinformationtest.cpp index 728a987faa6b..25581e69b1f3 100644 --- a/features/cellular/UNITTESTS/at/at_cellularinformation/at_cellularinformationtest.cpp +++ b/features/cellular/UNITTESTS/at/at_cellularinformation/at_cellularinformationtest.cpp @@ -17,20 +17,23 @@ #include "CppUTest/TestHarness.h" #include "test_at_cellularinformation.h" +// AStyle ignored as the definition is not clear due to preprocessor usage +// *INDENT-OFF* TEST_GROUP(AT_CellularInformation) { - Test_AT_CellularInformation* unit; + Test_AT_CellularInformation *unit; - void setup() + void setup() { unit = new Test_AT_CellularInformation(); } - void teardown() + void teardown() { delete unit; } }; +// *INDENT-ON* TEST(AT_CellularInformation, Create) { diff --git a/features/cellular/UNITTESTS/at/at_cellularinformation/main.cpp b/features/cellular/UNITTESTS/at/at_cellularinformation/main.cpp index 48b9907f07da..bba3df884f48 100644 --- a/features/cellular/UNITTESTS/at/at_cellularinformation/main.cpp +++ b/features/cellular/UNITTESTS/at/at_cellularinformation/main.cpp @@ -19,7 +19,7 @@ #include "CppUTest/TestPlugin.h" #include "CppUTest/TestRegistry.h" #include "CppUTestExt/MockSupportPlugin.h" -int main(int ac, char** av) +int main(int ac, char **av) { return CommandLineTestRunner::RunAllTests(ac, av); } diff --git a/features/cellular/UNITTESTS/at/at_cellularinformation/test_at_cellularinformation.h b/features/cellular/UNITTESTS/at/at_cellularinformation/test_at_cellularinformation.h index 5a94d54be77e..64fabbb4d569 100644 --- a/features/cellular/UNITTESTS/at/at_cellularinformation/test_at_cellularinformation.h +++ b/features/cellular/UNITTESTS/at/at_cellularinformation/test_at_cellularinformation.h @@ -17,8 +17,7 @@ #ifndef TEST_AT_CELLULARINFORMATION_H #define TEST_AT_CELLULARINFORMATION_H -class Test_AT_CellularInformation -{ +class Test_AT_CellularInformation { public: Test_AT_CellularInformation(); diff --git a/features/cellular/UNITTESTS/at/at_cellularnetwork/at_cellularnetworktest.cpp b/features/cellular/UNITTESTS/at/at_cellularnetwork/at_cellularnetworktest.cpp index 9b5ebf136f67..538c527544ad 100644 --- a/features/cellular/UNITTESTS/at/at_cellularnetwork/at_cellularnetworktest.cpp +++ b/features/cellular/UNITTESTS/at/at_cellularnetwork/at_cellularnetworktest.cpp @@ -18,11 +18,13 @@ #include "test_at_cellularnetwork.h" #include "ATHandler_stub.h" +// AStyle ignored as the definition is not clear due to preprocessor usage +// *INDENT-OFF* TEST_GROUP(AT_CellularNetwork) { - Test_AT_CellularNetwork* unit; + Test_AT_CellularNetwork *unit; - void setup() + void setup() { unit = new Test_AT_CellularNetwork(); ATHandler_stub::int_count = kRead_int_table_size; @@ -30,11 +32,12 @@ TEST_GROUP(AT_CellularNetwork) ATHandler_stub::resp_stop_success_count = kResp_stop_count_default; } - void teardown() + void teardown() { delete unit; } }; +// *INDENT-ON* TEST(AT_CellularNetwork, Create) { diff --git a/features/cellular/UNITTESTS/at/at_cellularnetwork/main.cpp b/features/cellular/UNITTESTS/at/at_cellularnetwork/main.cpp index 2c45fb6cbf4a..aec2c257bdcd 100644 --- a/features/cellular/UNITTESTS/at/at_cellularnetwork/main.cpp +++ b/features/cellular/UNITTESTS/at/at_cellularnetwork/main.cpp @@ -19,7 +19,7 @@ #include "CppUTest/TestPlugin.h" #include "CppUTest/TestRegistry.h" #include "CppUTestExt/MockSupportPlugin.h" -int main(int ac, char** av) +int main(int ac, char **av) { return CommandLineTestRunner::RunAllTests(ac, av); } diff --git a/features/cellular/UNITTESTS/at/at_cellularnetwork/test_at_cellularnetwork.cpp b/features/cellular/UNITTESTS/at/at_cellularnetwork/test_at_cellularnetwork.cpp index a33b2c06d21d..a1998d5d9a87 100644 --- a/features/cellular/UNITTESTS/at/at_cellularnetwork/test_at_cellularnetwork.cpp +++ b/features/cellular/UNITTESTS/at/at_cellularnetwork/test_at_cellularnetwork.cpp @@ -29,38 +29,66 @@ using namespace mbed; using namespace events; -class my_stack :public AT_CellularStack { +class my_stack : public AT_CellularStack { public: my_stack(ATHandler &atHandler) : AT_CellularStack(atHandler, 1, IPV4_STACK) {} - virtual int get_max_socket_count() { return 1;} - virtual int get_max_packet_size() {return 200;} - virtual bool is_protocol_supported(nsapi_protocol_t protocol) {return true;} - virtual nsapi_error_t socket_close_impl(int sock_id) {return NSAPI_ERROR_OK;} - virtual nsapi_error_t create_socket_impl(CellularSocket *socket) {return NSAPI_ERROR_OK;} + virtual int get_max_socket_count() + { + return 1; + } + virtual int get_max_packet_size() + { + return 200; + } + virtual bool is_protocol_supported(nsapi_protocol_t protocol) + { + return true; + } + virtual nsapi_error_t socket_close_impl(int sock_id) + { + return NSAPI_ERROR_OK; + } + virtual nsapi_error_t create_socket_impl(CellularSocket *socket) + { + return NSAPI_ERROR_OK; + } virtual nsapi_size_or_error_t socket_sendto_impl(CellularSocket *socket, const SocketAddress &address, - const void *data, nsapi_size_t size) {return 100;} + const void *data, nsapi_size_t size) + { + return 100; + } virtual nsapi_size_or_error_t socket_recvfrom_impl(CellularSocket *socket, SocketAddress *address, - void *buffer, nsapi_size_t size) {return 100;} + void *buffer, nsapi_size_t size) + { + return 100; + } }; class my_AT_CN : public AT_CellularNetwork { public: my_AT_CN(ATHandler &atHandler) : AT_CellularNetwork(atHandler) {} virtual ~my_AT_CN() {} - NetworkStack *get_stack() { + NetworkStack *get_stack() + { if (!_stack) { return new my_stack(get_at_handler()); } else { return _stack; - }} - virtual bool has_registration(RegistrationType reg_type) { + } + } + virtual bool has_registration(RegistrationType reg_type) + { if (reg_type == C_GREG) { return false; } return true; } - virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology op_rat) { return NSAPI_ERROR_OK;} - virtual bool get_modem_stack_type(nsapi_ip_stack_t requested_stack) { + virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology op_rat) + { + return NSAPI_ERROR_OK; + } + virtual bool get_modem_stack_type(nsapi_ip_stack_t requested_stack) + { if (requested_stack == IPV4_STACK || requested_stack == DEFAULT_STACK) { return true; } @@ -72,20 +100,27 @@ class my_AT_CNipv6 : public AT_CellularNetwork { public: my_AT_CNipv6(ATHandler &atHandler) : AT_CellularNetwork(atHandler) {} virtual ~my_AT_CNipv6() {} - NetworkStack *get_stack() { + NetworkStack *get_stack() + { if (!_stack) { return new my_stack(get_at_handler()); } else { return _stack; - }} - virtual bool has_registration(RegistrationType reg_type) { + } + } + virtual bool has_registration(RegistrationType reg_type) + { if (reg_type == C_GREG) { return false; } return true; } - virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology op_rat) { return NSAPI_ERROR_OK;} - virtual bool get_modem_stack_type(nsapi_ip_stack_t requested_stack) { + virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology op_rat) + { + return NSAPI_ERROR_OK; + } + virtual bool get_modem_stack_type(nsapi_ip_stack_t requested_stack) + { if (requested_stack == IPV6_STACK || requested_stack == DEFAULT_STACK) { return true; } @@ -194,7 +229,7 @@ void Test_AT_CellularNetwork::test_AT_CellularNetwork_activate_context() CHECK(NSAPI_ERROR_OK == my_cn.set_credentials("apn", CellularNetwork::CHAP, "user", "passwd")); CHECK(NSAPI_ERROR_OK == my_cn.activate_context()); - // get_context return true and new context created, test delete context + // get_context return true and new context created, test delete context ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; ATHandler_stub::bool_value = false; ATHandler_stub::resp_stop_success_count = kResp_stop_count_default; @@ -264,7 +299,7 @@ void Test_AT_CellularNetwork::test_AT_CellularNetwork_activate_context() ATHandler_stub::read_string_table[0] = "internet"; ATHandler_stub::read_string_table[1] = "IPV4V6"; ATHandler_stub::int_value = 1; - CHECK(NSAPI_ERROR_OK ==my_cn.set_stack_type(DEFAULT_STACK)); + CHECK(NSAPI_ERROR_OK == my_cn.set_stack_type(DEFAULT_STACK)); CHECK(NSAPI_ERROR_OK == my_cn.set_credentials("internet")); CHECK(NSAPI_ERROR_OK == my_cn.activate_context()); @@ -276,7 +311,7 @@ void Test_AT_CellularNetwork::test_AT_CellularNetwork_activate_context() ATHandler_stub::read_string_table[0] = "internet"; ATHandler_stub::read_string_table[1] = "IPV4V6"; ATHandler_stub::int_value = 1; - CHECK(NSAPI_ERROR_OK ==my_cnipv6.set_stack_type(DEFAULT_STACK)); + CHECK(NSAPI_ERROR_OK == my_cnipv6.set_stack_type(DEFAULT_STACK)); CHECK(NSAPI_ERROR_OK == my_cnipv6.set_credentials("internet")); CHECK(NSAPI_ERROR_OK == my_cnipv6.activate_context()); @@ -288,7 +323,7 @@ void Test_AT_CellularNetwork::test_AT_CellularNetwork_activate_context() ATHandler_stub::read_string_table[0] = "internet"; ATHandler_stub::read_string_table[1] = "IPV6"; ATHandler_stub::int_value = 1; - CHECK(NSAPI_ERROR_OK ==my_cnipv6.set_stack_type(DEFAULT_STACK)); + CHECK(NSAPI_ERROR_OK == my_cnipv6.set_stack_type(DEFAULT_STACK)); CHECK(NSAPI_ERROR_OK == my_cnipv6.set_credentials("internet")); CHECK(NSAPI_ERROR_OK == my_cnipv6.activate_context()); @@ -300,7 +335,7 @@ void Test_AT_CellularNetwork::test_AT_CellularNetwork_activate_context() ATHandler_stub::read_string_table[0] = "internet"; ATHandler_stub::read_string_table[1] = "IP"; ATHandler_stub::int_value = 1; - CHECK(NSAPI_ERROR_OK ==my_cn.set_stack_type(DEFAULT_STACK)); + CHECK(NSAPI_ERROR_OK == my_cn.set_stack_type(DEFAULT_STACK)); CHECK(NSAPI_ERROR_OK == my_cn.set_credentials("internet")); CHECK(NSAPI_ERROR_OK == my_cn.activate_context()); @@ -366,7 +401,7 @@ void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_stack() ATHandler at(&fh1, que, 0, ","); my_AT_CN my_cn(at); - my_stack* mystack = (my_stack*)my_cn.get_stack(); + my_stack *mystack = (my_stack *)my_cn.get_stack(); CHECK(mystack); delete mystack; } @@ -763,7 +798,7 @@ void Test_AT_CellularNetwork::test_AT_CellularNetwork_scan_plmn() CHECK(NSAPI_ERROR_OK == cn.scan_plmn(ops, c)); CHECK(c == 1); CHECK(ops.get_head() != NULL); - CellularNetwork::operator_t* op = ops.get_head(); + CellularNetwork::operator_t *op = ops.get_head(); CHECK(op->op_status == CellularNetwork::operator_t::Available); CHECK(strcmp(op->op_long, "12345") == 0); CHECK(strcmp(op->op_short, "33333") == 0); @@ -921,12 +956,12 @@ void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_extended_signal_qualit AT_CellularNetwork cn(at); ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR; int rx = -1, be = -1, rs = -1, ec = -1, rsrq = -1, rsrp = -1; - CHECK(NSAPI_ERROR_DEVICE_ERROR == cn.get_extended_signal_quality(rx, be,rs,ec,rsrq, rsrp)); + CHECK(NSAPI_ERROR_DEVICE_ERROR == cn.get_extended_signal_quality(rx, be, rs, ec, rsrq, rsrp)); CHECK(rx == -1 && be == -1 && rs == -1 && ec == -1 && rsrq == -1 && rsrp == -1); ATHandler_stub::int_value = 5; ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; - CHECK(NSAPI_ERROR_OK == cn.get_extended_signal_quality(rx, be,rs,ec,rsrq, rsrp)); + CHECK(NSAPI_ERROR_OK == cn.get_extended_signal_quality(rx, be, rs, ec, rsrq, rsrp)); CHECK(rx == 5 && be == 5 && rs == 5 && ec == 5 && rsrq == 5 && rsrp == 5); } @@ -939,12 +974,12 @@ void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_signal_quality() AT_CellularNetwork cn(at); int rs = -1, ber = -1; ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR; - CHECK(NSAPI_ERROR_DEVICE_ERROR == cn.get_signal_quality(rs,ber)); + CHECK(NSAPI_ERROR_DEVICE_ERROR == cn.get_signal_quality(rs, ber)); CHECK(rs == -1 && ber == -1); ATHandler_stub::int_value = 1; ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; - CHECK(NSAPI_ERROR_OK == cn.get_signal_quality(rs,ber)); + CHECK(NSAPI_ERROR_OK == cn.get_signal_quality(rs, ber)); CHECK(rs == 1 && ber == 1); } diff --git a/features/cellular/UNITTESTS/at/at_cellularnetwork/test_at_cellularnetwork.h b/features/cellular/UNITTESTS/at/at_cellularnetwork/test_at_cellularnetwork.h index 02f0468a878e..2327a3097970 100644 --- a/features/cellular/UNITTESTS/at/at_cellularnetwork/test_at_cellularnetwork.h +++ b/features/cellular/UNITTESTS/at/at_cellularnetwork/test_at_cellularnetwork.h @@ -17,8 +17,7 @@ #ifndef TEST_AT_CELLULARNETWORK_H #define TEST_AT_CELLULARNETWORK_H -class Test_AT_CellularNetwork -{ +class Test_AT_CellularNetwork { public: Test_AT_CellularNetwork(); diff --git a/features/cellular/UNITTESTS/at/at_cellularpower/at_cellularpowertest.cpp b/features/cellular/UNITTESTS/at/at_cellularpower/at_cellularpowertest.cpp index 4a56c99b3f7c..2ce7b6dd023b 100644 --- a/features/cellular/UNITTESTS/at/at_cellularpower/at_cellularpowertest.cpp +++ b/features/cellular/UNITTESTS/at/at_cellularpower/at_cellularpowertest.cpp @@ -17,20 +17,21 @@ #include "CppUTest/TestHarness.h" #include "test_at_cellularpower.h" +// AStyle ignored as the definition is not clear due to preprocessor usage +// *INDENT-OFF* TEST_GROUP(AT_CellularPower) { - Test_AT_CellularPower* unit; + Test_AT_CellularPower *unit; - void setup() - { + void setup() { unit = new Test_AT_CellularPower(); } - void teardown() - { + void teardown() { delete unit; } }; +// *INDENT-ON* TEST(AT_CellularPower, Create) { diff --git a/features/cellular/UNITTESTS/at/at_cellularpower/main.cpp b/features/cellular/UNITTESTS/at/at_cellularpower/main.cpp index a610f2976be8..5580d261667f 100644 --- a/features/cellular/UNITTESTS/at/at_cellularpower/main.cpp +++ b/features/cellular/UNITTESTS/at/at_cellularpower/main.cpp @@ -19,7 +19,7 @@ #include "CppUTest/TestPlugin.h" #include "CppUTest/TestRegistry.h" #include "CppUTestExt/MockSupportPlugin.h" -int main(int ac, char** av) +int main(int ac, char **av) { return CommandLineTestRunner::RunAllTests(ac, av); } diff --git a/features/cellular/UNITTESTS/at/at_cellularpower/test_at_cellularpower.cpp b/features/cellular/UNITTESTS/at/at_cellularpower/test_at_cellularpower.cpp index 6cfad08c1c4f..593f4c447b7f 100644 --- a/features/cellular/UNITTESTS/at/at_cellularpower/test_at_cellularpower.cpp +++ b/features/cellular/UNITTESTS/at/at_cellularpower/test_at_cellularpower.cpp @@ -90,8 +90,8 @@ void Test_AT_CellularPower::test_AT_CellularPower_set_power_level() AT_CellularPower pow(at); ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; CHECK(NSAPI_ERROR_OK == pow.set_power_level(6)); - CHECK(NSAPI_ERROR_OK == pow.set_power_level(1,1)); - CHECK(NSAPI_ERROR_OK == pow.set_power_level(1,0)); + CHECK(NSAPI_ERROR_OK == pow.set_power_level(1, 1)); + CHECK(NSAPI_ERROR_OK == pow.set_power_level(1, 0)); ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR; CHECK(NSAPI_ERROR_DEVICE_ERROR == pow.set_power_level(6)); @@ -119,24 +119,24 @@ void Test_AT_CellularPower::test_AT_CellularPower_opt_power_save_mode() AT_CellularPower pow(at); ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK; - CHECK(NSAPI_ERROR_OK == pow.opt_power_save_mode(0,0)); + CHECK(NSAPI_ERROR_OK == pow.opt_power_save_mode(0, 0)); - CHECK(NSAPI_ERROR_OK == pow.opt_power_save_mode(10,0)); + CHECK(NSAPI_ERROR_OK == pow.opt_power_save_mode(10, 0)); - CHECK(NSAPI_ERROR_OK == pow.opt_power_save_mode(912,0)); + CHECK(NSAPI_ERROR_OK == pow.opt_power_save_mode(912, 0)); - CHECK(NSAPI_ERROR_OK == pow.opt_power_save_mode(1834,1834)); + CHECK(NSAPI_ERROR_OK == pow.opt_power_save_mode(1834, 1834)); - CHECK(NSAPI_ERROR_OK == pow.opt_power_save_mode(18345,18345)); + CHECK(NSAPI_ERROR_OK == pow.opt_power_save_mode(18345, 18345)); - CHECK(NSAPI_ERROR_OK == pow.opt_power_save_mode(101234,101234)); + CHECK(NSAPI_ERROR_OK == pow.opt_power_save_mode(101234, 101234)); - CHECK(NSAPI_ERROR_OK == pow.opt_power_save_mode(1012345,1012345)); + CHECK(NSAPI_ERROR_OK == pow.opt_power_save_mode(1012345, 1012345)); - CHECK(NSAPI_ERROR_OK == pow.opt_power_save_mode(39612345,39612345)); + CHECK(NSAPI_ERROR_OK == pow.opt_power_save_mode(39612345, 39612345)); ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR; - CHECK(NSAPI_ERROR_DEVICE_ERROR == pow.opt_power_save_mode(0,0)); + CHECK(NSAPI_ERROR_DEVICE_ERROR == pow.opt_power_save_mode(0, 0)); } void Test_AT_CellularPower::test_AT_CellularPower_opt_receive_period() diff --git a/features/cellular/UNITTESTS/at/at_cellularpower/test_at_cellularpower.h b/features/cellular/UNITTESTS/at/at_cellularpower/test_at_cellularpower.h index ab70cbcabb9c..c24f7809e622 100644 --- a/features/cellular/UNITTESTS/at/at_cellularpower/test_at_cellularpower.h +++ b/features/cellular/UNITTESTS/at/at_cellularpower/test_at_cellularpower.h @@ -17,8 +17,7 @@ #ifndef TEST_AT_CELLULARPOWER_H #define TEST_AT_CELLULARPOWER_H -class Test_AT_CellularPower -{ +class Test_AT_CellularPower { public: Test_AT_CellularPower(); diff --git a/features/cellular/UNITTESTS/at/at_cellularsim/at_cellularsimtest.cpp b/features/cellular/UNITTESTS/at/at_cellularsim/at_cellularsimtest.cpp index bf4f3e4a9db3..2d4c2c70eccd 100644 --- a/features/cellular/UNITTESTS/at/at_cellularsim/at_cellularsimtest.cpp +++ b/features/cellular/UNITTESTS/at/at_cellularsim/at_cellularsimtest.cpp @@ -18,21 +18,24 @@ #include "test_at_cellularsim.h" #include "ATHandler_stub.h" +// AStyle ignored as the definition is not clear due to preprocessor usage +// *INDENT-OFF* TEST_GROUP(AT_CellularSIM) { - Test_AT_CellularSIM* unit; + Test_AT_CellularSIM *unit; - void setup() + void setup() { unit = new Test_AT_CellularSIM(); ATHandler_stub::read_string_index = kRead_string_table_size; } - void teardown() + void teardown() { delete unit; } }; +// *INDENT-ON* TEST(AT_CellularSIM, Create) { diff --git a/features/cellular/UNITTESTS/at/at_cellularsim/main.cpp b/features/cellular/UNITTESTS/at/at_cellularsim/main.cpp index 0566c80f3367..394a1f7d6d10 100644 --- a/features/cellular/UNITTESTS/at/at_cellularsim/main.cpp +++ b/features/cellular/UNITTESTS/at/at_cellularsim/main.cpp @@ -19,7 +19,7 @@ #include "CppUTest/TestPlugin.h" #include "CppUTest/TestRegistry.h" #include "CppUTestExt/MockSupportPlugin.h" -int main(int ac, char** av) +int main(int ac, char **av) { return CommandLineTestRunner::RunAllTests(ac, av); } diff --git a/features/cellular/UNITTESTS/at/at_cellularsim/test_at_cellularsim.h b/features/cellular/UNITTESTS/at/at_cellularsim/test_at_cellularsim.h index e8c5d23c4aaf..5c78cdbd403d 100644 --- a/features/cellular/UNITTESTS/at/at_cellularsim/test_at_cellularsim.h +++ b/features/cellular/UNITTESTS/at/at_cellularsim/test_at_cellularsim.h @@ -17,8 +17,7 @@ #ifndef TEST_AT_CELLULARSIM_H #define TEST_AT_CELLULARSIM_H -class Test_AT_CellularSIM -{ +class Test_AT_CellularSIM { public: Test_AT_CellularSIM(); diff --git a/features/cellular/UNITTESTS/at/at_cellularsms/at_cellularsmstest.cpp b/features/cellular/UNITTESTS/at/at_cellularsms/at_cellularsmstest.cpp index 88754bfc4abf..d207cc82912f 100644 --- a/features/cellular/UNITTESTS/at/at_cellularsms/at_cellularsmstest.cpp +++ b/features/cellular/UNITTESTS/at/at_cellularsms/at_cellularsmstest.cpp @@ -17,20 +17,23 @@ #include "CppUTest/TestHarness.h" #include "test_at_cellularsms.h" +// AStyle ignored as the definition is not clear due to preprocessor usage +// *INDENT-OFF* TEST_GROUP(AT_CellularSMS) { - Test_AT_CellularSMS* unit; + Test_AT_CellularSMS *unit; - void setup() + void setup() { unit = new Test_AT_CellularSMS(); } - void teardown() + void teardown() { delete unit; } }; +// *INDENT-ON* TEST(AT_CellularSMS, Create) { diff --git a/features/cellular/UNITTESTS/at/at_cellularsms/main.cpp b/features/cellular/UNITTESTS/at/at_cellularsms/main.cpp index a1fc31e69af2..04d6d690b0aa 100644 --- a/features/cellular/UNITTESTS/at/at_cellularsms/main.cpp +++ b/features/cellular/UNITTESTS/at/at_cellularsms/main.cpp @@ -19,7 +19,7 @@ #include "CppUTest/TestPlugin.h" #include "CppUTest/TestRegistry.h" #include "CppUTestExt/MockSupportPlugin.h" -int main(int ac, char** av) +int main(int ac, char **av) { return CommandLineTestRunner::RunAllTests(ac, av); } diff --git a/features/cellular/UNITTESTS/at/at_cellularsms/test_at_cellularsms.h b/features/cellular/UNITTESTS/at/at_cellularsms/test_at_cellularsms.h index 43eb7ebdf584..c83d312fa1dc 100644 --- a/features/cellular/UNITTESTS/at/at_cellularsms/test_at_cellularsms.h +++ b/features/cellular/UNITTESTS/at/at_cellularsms/test_at_cellularsms.h @@ -17,8 +17,7 @@ #ifndef TEST_AT_CELLULARSMS_H #define TEST_AT_CELLULARSMS_H -class Test_AT_CellularSMS -{ +class Test_AT_CellularSMS { public: Test_AT_CellularSMS(); diff --git a/features/cellular/UNITTESTS/at/at_cellularstack/at_cellularstacktest.cpp b/features/cellular/UNITTESTS/at/at_cellularstack/at_cellularstacktest.cpp index d4815f92ae69..60a5ab666476 100644 --- a/features/cellular/UNITTESTS/at/at_cellularstack/at_cellularstacktest.cpp +++ b/features/cellular/UNITTESTS/at/at_cellularstack/at_cellularstacktest.cpp @@ -17,20 +17,23 @@ #include "CppUTest/TestHarness.h" #include "test_at_cellularstack.h" +// AStyle ignored as the definition is not clear due to preprocessor usage +// *INDENT-OFF* TEST_GROUP(AT_CellularStack) { - Test_AT_CellularStack* unit; + Test_AT_CellularStack *unit; void setup() { unit = new Test_AT_CellularStack(); } - void teardown() + void teardown() { delete unit; } }; +// *INDENT-ON* TEST(AT_CellularStack, Create) { diff --git a/features/cellular/UNITTESTS/at/at_cellularstack/main.cpp b/features/cellular/UNITTESTS/at/at_cellularstack/main.cpp index 46520ddd58ec..ee45007ddea7 100644 --- a/features/cellular/UNITTESTS/at/at_cellularstack/main.cpp +++ b/features/cellular/UNITTESTS/at/at_cellularstack/main.cpp @@ -19,7 +19,7 @@ #include "CppUTest/TestPlugin.h" #include "CppUTest/TestRegistry.h" #include "CppUTestExt/MockSupportPlugin.h" -int main(int ac, char** av) +int main(int ac, char **av) { return CommandLineTestRunner::RunAllTests(ac, av); } diff --git a/features/cellular/UNITTESTS/at/at_cellularstack/test_at_cellularstack.cpp b/features/cellular/UNITTESTS/at/at_cellularstack/test_at_cellularstack.cpp index 973b3fdd0814..0e4eefca2c1c 100644 --- a/features/cellular/UNITTESTS/at/at_cellularstack/test_at_cellularstack.cpp +++ b/features/cellular/UNITTESTS/at/at_cellularstack/test_at_cellularstack.cpp @@ -43,46 +43,97 @@ class MyStack : public AT_CellularStack { create_error = NSAPI_ERROR_OK; } - virtual int get_max_socket_count(){return max_sock_value;} + virtual int get_max_socket_count() + { + return max_sock_value; + } - virtual bool is_protocol_supported(nsapi_protocol_t protocol){return bool_value;} + virtual bool is_protocol_supported(nsapi_protocol_t protocol) + { + return bool_value; + } - virtual nsapi_error_t socket_close_impl(int sock_id){return NSAPI_ERROR_OK;} + virtual nsapi_error_t socket_close_impl(int sock_id) + { + return NSAPI_ERROR_OK; + } - virtual nsapi_error_t create_socket_impl(CellularSocket *socket){return create_error;} + virtual nsapi_error_t create_socket_impl(CellularSocket *socket) + { + return create_error; + } virtual nsapi_size_or_error_t socket_sendto_impl(CellularSocket *socket, const SocketAddress &address, - const void *data, nsapi_size_t size){return NSAPI_ERROR_OK;} + const void *data, nsapi_size_t size) + { + return NSAPI_ERROR_OK; + } virtual nsapi_size_or_error_t socket_recvfrom_impl(CellularSocket *socket, SocketAddress *address, - void *buffer, nsapi_size_t size) {return NSAPI_ERROR_OK;} + void *buffer, nsapi_size_t size) + { + return NSAPI_ERROR_OK; + } - virtual nsapi_error_t socket_open(nsapi_socket_t *handle, nsapi_protocol_t proto) {return AT_CellularStack::socket_open(handle, proto);} + virtual nsapi_error_t socket_open(nsapi_socket_t *handle, nsapi_protocol_t proto) + { + return AT_CellularStack::socket_open(handle, proto); + } - virtual nsapi_error_t socket_close(nsapi_socket_t handle) {return AT_CellularStack::socket_close(handle);} + virtual nsapi_error_t socket_close(nsapi_socket_t handle) + { + return AT_CellularStack::socket_close(handle); + } - virtual nsapi_error_t socket_bind(nsapi_socket_t handle, const SocketAddress &address) {return AT_CellularStack::socket_bind(handle, address);} + virtual nsapi_error_t socket_bind(nsapi_socket_t handle, const SocketAddress &address) + { + return AT_CellularStack::socket_bind(handle, address); + } - virtual nsapi_error_t socket_listen(nsapi_socket_t handle, int backlog) {return AT_CellularStack::socket_listen(handle, backlog);} + virtual nsapi_error_t socket_listen(nsapi_socket_t handle, int backlog) + { + return AT_CellularStack::socket_listen(handle, backlog); + } - virtual nsapi_error_t socket_connect(nsapi_socket_t handle, const SocketAddress &address) {return AT_CellularStack::socket_connect(handle, address);} + virtual nsapi_error_t socket_connect(nsapi_socket_t handle, const SocketAddress &address) + { + return AT_CellularStack::socket_connect(handle, address); + } virtual nsapi_error_t socket_accept(nsapi_socket_t server, - nsapi_socket_t *handle, SocketAddress *address=0) {return AT_CellularStack::socket_accept(server, handle, address);} + nsapi_socket_t *handle, SocketAddress *address = 0) + { + return AT_CellularStack::socket_accept(server, handle, address); + } virtual nsapi_size_or_error_t socket_send(nsapi_socket_t handle, - const void *data, nsapi_size_t size) {return AT_CellularStack::socket_send(handle, data, size);} + const void *data, nsapi_size_t size) + { + return AT_CellularStack::socket_send(handle, data, size); + } virtual nsapi_size_or_error_t socket_recv(nsapi_socket_t handle, - void *data, nsapi_size_t size) {return AT_CellularStack::socket_recv(handle, data, size);} + void *data, nsapi_size_t size) + { + return AT_CellularStack::socket_recv(handle, data, size); + } virtual nsapi_size_or_error_t socket_sendto(nsapi_socket_t handle, const SocketAddress &address, - const void *data, nsapi_size_t size) {return AT_CellularStack::socket_sendto(handle, address, data, size);} + const void *data, nsapi_size_t size) + { + return AT_CellularStack::socket_sendto(handle, address, data, size); + } virtual nsapi_size_or_error_t socket_recvfrom(nsapi_socket_t handle, SocketAddress *address, - void *buffer, nsapi_size_t size) {return AT_CellularStack::socket_recvfrom(handle, address, buffer, size);} + void *buffer, nsapi_size_t size) + { + return AT_CellularStack::socket_recvfrom(handle, address, buffer, size); + } - virtual void socket_attach(nsapi_socket_t handle, void (*callback)(void *), void *data) {return AT_CellularStack::socket_attach(handle, callback, data);} + virtual void socket_attach(nsapi_socket_t handle, void (*callback)(void *), void *data) + { + return AT_CellularStack::socket_attach(handle, callback, data); + } }; Test_AT_CellularStack::Test_AT_CellularStack() diff --git a/features/cellular/UNITTESTS/at/at_cellularstack/test_at_cellularstack.h b/features/cellular/UNITTESTS/at/at_cellularstack/test_at_cellularstack.h index 1c77553618ff..b86a6d761c0a 100644 --- a/features/cellular/UNITTESTS/at/at_cellularstack/test_at_cellularstack.h +++ b/features/cellular/UNITTESTS/at/at_cellularstack/test_at_cellularstack.h @@ -17,8 +17,7 @@ #ifndef TEST_AT_CELLULARSTACK_H #define TEST_AT_CELLULARSTACK_H -class Test_AT_CellularStack -{ +class Test_AT_CellularStack { public: Test_AT_CellularStack(); diff --git a/features/cellular/UNITTESTS/at/athandler/athandlertest.cpp b/features/cellular/UNITTESTS/at/athandler/athandlertest.cpp index 6ca301477eac..b8b46b2ca872 100644 --- a/features/cellular/UNITTESTS/at/athandler/athandlertest.cpp +++ b/features/cellular/UNITTESTS/at/athandler/athandlertest.cpp @@ -17,20 +17,23 @@ #include "CppUTest/TestHarness.h" #include "test_athandler.h" +// AStyle ignored as the definition is not clear due to preprocessor usage +// *INDENT-OFF* TEST_GROUP(ATHandler) { - Test_ATHandler* unit; + Test_ATHandler *unit; - void setup() + void setup() { unit = new Test_ATHandler(); } - void teardown() + void teardown() { delete unit; } }; +// *INDENT-ON* TEST(ATHandler, Create) { diff --git a/features/cellular/UNITTESTS/at/athandler/main.cpp b/features/cellular/UNITTESTS/at/athandler/main.cpp index beac7f7f3700..3f7505ccbbbd 100644 --- a/features/cellular/UNITTESTS/at/athandler/main.cpp +++ b/features/cellular/UNITTESTS/at/athandler/main.cpp @@ -19,7 +19,7 @@ #include "CppUTest/TestPlugin.h" #include "CppUTest/TestRegistry.h" #include "CppUTestExt/MockSupportPlugin.h" -int main(int ac, char** av) +int main(int ac, char **av) { return CommandLineTestRunner::RunAllTests(ac, av); } diff --git a/features/cellular/UNITTESTS/at/athandler/test_athandler.cpp b/features/cellular/UNITTESTS/at/athandler/test_athandler.cpp index 8df922101777..3d01ad0cad63 100644 --- a/features/cellular/UNITTESTS/at/athandler/test_athandler.cpp +++ b/features/cellular/UNITTESTS/at/athandler/test_athandler.cpp @@ -314,7 +314,7 @@ void Test_ATHandler::test_ATHandler_write_int() at.write_int(2147483647); - at.write_int(2147483647+1); + at.write_int(2147483647 + 1); // at.at_error(0, DeviceErrorType(0)); // at.write_int(4); @@ -562,7 +562,7 @@ void Test_ATHandler::test_ATHandler_read_string() CHECK(NSAPI_ERROR_OK == at.get_last_error()); // To read 0 bytes from: s\r\n CHECK(0 == at.read_string(buf3, 0 + 1/*for NULL*/)); - // To read 1 byte from: s\r\n -> read s + // To read 1 byte from: s\r\n -> read s CHECK(1 == at.read_string(buf3, 1 + 1/*for NULL*/)); // *** Reading more than available in buffer *** @@ -780,7 +780,7 @@ void Test_ATHandler::test_ATHandler_read_int() ATHandler at(&fh1, que, 0, ","); - int32_t ret= at.read_int(); + int32_t ret = at.read_int(); CHECK(-1 == ret); at.clear_error(); @@ -792,7 +792,7 @@ void Test_ATHandler::test_ATHandler_read_int() at.resp_start(); - ret= at.read_int(); + ret = at.read_int(); CHECK(-1 == ret); at.flush(); at.clear_error(); @@ -805,7 +805,7 @@ void Test_ATHandler::test_ATHandler_read_int() at.resp_start(); - ret= at.read_int(); + ret = at.read_int(); CHECK(2 == ret); } diff --git a/features/cellular/UNITTESTS/at/athandler/test_athandler.h b/features/cellular/UNITTESTS/at/athandler/test_athandler.h index a1ee7dba550b..3d74fb0afd8a 100644 --- a/features/cellular/UNITTESTS/at/athandler/test_athandler.h +++ b/features/cellular/UNITTESTS/at/athandler/test_athandler.h @@ -17,8 +17,7 @@ #ifndef TEST_ATHANDLER_H #define TEST_ATHANDLER_H -class Test_ATHandler -{ +class Test_ATHandler { public: Test_ATHandler(); diff --git a/features/cellular/UNITTESTS/common/util/main.cpp b/features/cellular/UNITTESTS/common/util/main.cpp index 4438de28a823..6ebe32913338 100644 --- a/features/cellular/UNITTESTS/common/util/main.cpp +++ b/features/cellular/UNITTESTS/common/util/main.cpp @@ -19,7 +19,7 @@ #include "CppUTest/TestPlugin.h" #include "CppUTest/TestRegistry.h" #include "CppUTestExt/MockSupportPlugin.h" -int main(int ac, char** av) +int main(int ac, char **av) { return CommandLineTestRunner::RunAllTests(ac, av); } diff --git a/features/cellular/UNITTESTS/common/util/test_util.cpp b/features/cellular/UNITTESTS/common/util/test_util.cpp index 30459e02d0aa..a8078dcf5b44 100644 --- a/features/cellular/UNITTESTS/common/util/test_util.cpp +++ b/features/cellular/UNITTESTS/common/util/test_util.cpp @@ -116,7 +116,7 @@ void Test_util::test_util_prefer_ipv6() void Test_util::test_util_separate_ip_addresses() { - char* s = (char*)malloc(128); + char *s = (char *)malloc(128); char ip[64] = {0}; char subnet[64] = {0}; diff --git a/features/cellular/UNITTESTS/common/util/test_util.h b/features/cellular/UNITTESTS/common/util/test_util.h index 1a343db25621..7f6b28ee5f58 100644 --- a/features/cellular/UNITTESTS/common/util/test_util.h +++ b/features/cellular/UNITTESTS/common/util/test_util.h @@ -17,8 +17,7 @@ #ifndef TEST_UTIL_H #define TEST_UTIL_H -class Test_util -{ +class Test_util { public: Test_util(); diff --git a/features/cellular/UNITTESTS/common/util/utiltest.cpp b/features/cellular/UNITTESTS/common/util/utiltest.cpp index dff7b105add9..52a6db6c0747 100644 --- a/features/cellular/UNITTESTS/common/util/utiltest.cpp +++ b/features/cellular/UNITTESTS/common/util/utiltest.cpp @@ -17,20 +17,23 @@ #include "CppUTest/TestHarness.h" #include "test_util.h" +// AStyle ignored as the definition is not clear due to preprocessor usage +// *INDENT-OFF* TEST_GROUP(util) { - Test_util* unit; + Test_util *unit; - void setup() + void setup() { unit = new Test_util(); } - void teardown() + void teardown() { delete unit; } }; +// *INDENT-ON* TEST(util, Create) { diff --git a/features/cellular/UNITTESTS/stubs/ATCmdParser.cpp b/features/cellular/UNITTESTS/stubs/ATCmdParser.cpp index 8bee7b9d1fad..d9157ec84815 100644 --- a/features/cellular/UNITTESTS/stubs/ATCmdParser.cpp +++ b/features/cellular/UNITTESTS/stubs/ATCmdParser.cpp @@ -76,7 +76,7 @@ void ATCmdParser::flush() int ATCmdParser::write(const char *data, int size) { int i = 0; - for ( ; i < size; i++) { + for (; i < size; i++) { if (putc(data[i]) < 0) { return -1; } @@ -87,7 +87,7 @@ int ATCmdParser::write(const char *data, int size) int ATCmdParser::read(char *data, int size) { int i = 0; - for ( ; i < size; i++) { + for (; i < size; i++) { int c = getc(); if (c < 0) { return -1; @@ -107,7 +107,7 @@ int ATCmdParser::vprintf(const char *format, va_list args) } int i = 0; - for ( ; _buffer[i]; i++) { + for (; _buffer[i]; i++) { if (putc(_buffer[i]) < 0) { return -1; } @@ -125,7 +125,7 @@ int ATCmdParser::vscanf(const char *format, va_list args) int offset = 0; while (format[i]) { - if (format[i] == '%' && format[i+1] != '%' && format[i+1] != '*') { + if (format[i] == '%' && format[i + 1] != '%' && format[i + 1] != '*') { _buffer[offset++] = '%'; _buffer[offset++] = '*'; i++; @@ -152,7 +152,7 @@ int ATCmdParser::vscanf(const char *format, va_list args) while (true) { // Ran out of space - if (j+1 >= _buffer_size - offset) { + if (j + 1 >= _buffer_size - offset) { return false; } // Recieve next character @@ -165,12 +165,12 @@ int ATCmdParser::vscanf(const char *format, va_list args) // Check for match int count = -1; - sscanf(_buffer+offset, _buffer, &count); + sscanf(_buffer + offset, _buffer, &count); // We only succeed if all characters in the response are matched if (count == j) { // Store the found results - vsscanf(_buffer+offset, format, args); + vsscanf(_buffer + offset, format, args); return j; } } @@ -217,14 +217,14 @@ bool ATCmdParser::vrecv(const char *response, va_list args) bool whole_line_wanted = false; while (response[i]) { - if (response[i] == '%' && response[i+1] != '%' && response[i+1] != '*') { + if (response[i] == '%' && response[i + 1] != '%' && response[i + 1] != '*') { _buffer[offset++] = '%'; _buffer[offset++] = '*'; i++; } else { _buffer[offset++] = response[i++]; // Find linebreaks, taking care not to be fooled if they're in a %[^\n] conversion specification - if (response[i - 1] == '\n' && !(i >= 3 && response[i-3] == '[' && response[i-2] == '^')) { + if (response[i - 1] == '\n' && !(i >= 3 && response[i - 3] == '[' && response[i - 2] == '^')) { whole_line_wanted = true; break; } @@ -257,7 +257,7 @@ bool ATCmdParser::vrecv(const char *response, va_list args) } // Simplify newlines (borrowed from retarget.cpp) if ((c == CR && _in_prev != LF) || - (c == LF && _in_prev != CR)) { + (c == LF && _in_prev != CR)) { _in_prev = c; c = '\n'; } else if ((c == CR && _in_prev == LF) || @@ -274,7 +274,7 @@ bool ATCmdParser::vrecv(const char *response, va_list args) // Check for oob data for (struct oob *oob = _oobs; oob; oob = oob->next) { if ((unsigned)j == oob->len && memcmp( - oob->prefix, _buffer+offset, oob->len) == 0) { + oob->prefix, _buffer + offset, oob->len) == 0) { debug_if(_dbg_on, "AT! %s\n", oob->prefix); oob->cb(); @@ -295,18 +295,18 @@ bool ATCmdParser::vrecv(const char *response, va_list args) // This allows recv("Foo: %s\n") to work, and not match with just the first character of a string // (scanf does not itself match whitespace in its format string, so \n is not significant to it) } else { - sscanf(_buffer+offset, _buffer, &count); + sscanf(_buffer + offset, _buffer, &count); } // We only succeed if all characters in the response are matched if (count == j) { - debug_if(_dbg_on, "AT= %s\n", _buffer+offset); + debug_if(_dbg_on, "AT= %s\n", _buffer + offset); // Reuse the front end of the buffer memcpy(_buffer, response, i); _buffer[i] = 0; // Store the found results - vsscanf(_buffer+offset, _buffer, args); + vsscanf(_buffer + offset, _buffer, args); // Jump to next line and continue parsing response += i; @@ -315,8 +315,8 @@ bool ATCmdParser::vrecv(const char *response, va_list args) // Clear the buffer when we hit a newline or ran out of space // running out of space usually means we ran into binary data - if (c == '\n' || j+1 >= _buffer_size - offset) { - debug_if(_dbg_on, "AT< %s", _buffer+offset); + if (c == '\n' || j + 1 >= _buffer_size - offset) { + debug_if(_dbg_on, "AT< %s", _buffer + offset); j = 0; } } @@ -398,18 +398,18 @@ bool ATCmdParser::process_oob() struct oob *oob = _oobs; while (oob) { if (i == (int)oob->len && memcmp( - oob->prefix, _buffer, oob->len) == 0) { + oob->prefix, _buffer, oob->len) == 0) { debug_if(_dbg_on, "AT! %s\r\n", oob->prefix); oob->cb(); return true; } oob = oob->next; } - + // Clear the buffer when we hit a newline or ran out of space // running out of space usually means we ran into binary data - if (i+1 >= _buffer_size || - strcmp(&_buffer[i-_output_delim_size], _output_delimiter) == 0) { + if (i + 1 >= _buffer_size || + strcmp(&_buffer[i - _output_delim_size], _output_delimiter) == 0) { debug_if(_dbg_on, "AT< %s", _buffer); i = 0; diff --git a/features/cellular/UNITTESTS/stubs/ATHandler_stub.cpp b/features/cellular/UNITTESTS/stubs/ATHandler_stub.cpp index 8112dee82d84..3daf8da11541 100644 --- a/features/cellular/UNITTESTS/stubs/ATHandler_stub.cpp +++ b/features/cellular/UNITTESTS/stubs/ATHandler_stub.cpp @@ -36,7 +36,7 @@ int ATHandler_stub::timeout = 0; bool ATHandler_stub::default_timeout = 0; bool ATHandler_stub::debug_on = 0; ssize_t ATHandler_stub::ssize_value = 0; -char* ATHandler_stub::read_string_value = NULL; +char *ATHandler_stub::read_string_value = NULL; size_t ATHandler_stub::size_value = 0; size_t ATHandler_stub::return_given_size = false; bool ATHandler_stub::bool_value = false; @@ -50,7 +50,7 @@ int ATHandler_stub::int_valid_count_table[kRead_int_table_size]; int ATHandler_stub::int_count = kRead_int_table_size; int ATHandler_stub::read_string_index = kRead_string_table_size; -char* ATHandler_stub::read_string_table[kRead_string_table_size]; +char *ATHandler_stub::read_string_table[kRead_string_table_size]; int ATHandler_stub::resp_stop_success_count = kResp_stop_count_default; ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, int timeout, const char *output_delimiter, uint16_t send_delay) : @@ -146,7 +146,8 @@ void ATHandler::clear_error() ATHandler_stub::nsapi_error_ok_counter++; } -void ATHandler::skip_param(uint32_t count) { +void ATHandler::skip_param(uint32_t count) +{ } @@ -164,16 +165,16 @@ ssize_t ATHandler::read_string(char *buf, size_t size, bool read_even_stop_tag) if (ATHandler_stub::read_string_index == kRead_string_table_size) { if (ATHandler_stub::read_string_value && ATHandler_stub::ssize_value >= 0) { - memcpy(buf, ATHandler_stub::read_string_value, ATHandler_stub::ssize_value+1); + memcpy(buf, ATHandler_stub::read_string_value, ATHandler_stub::ssize_value + 1); } return ATHandler_stub::ssize_value; } ATHandler_stub::read_string_index--; if (ATHandler_stub::read_string_index >= 0) { - char* tmp = ATHandler_stub::read_string_table[ATHandler_stub::read_string_index]; + char *tmp = ATHandler_stub::read_string_table[ATHandler_stub::read_string_index]; ssize_t len = strlen(tmp); - memcpy(buf, tmp, len+1); + memcpy(buf, tmp, len + 1); return len; } @@ -254,7 +255,7 @@ void ATHandler::resp_stop() ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR; } -void ATHandler::cmd_start(const char* cmd) +void ATHandler::cmd_start(const char *cmd) { } @@ -262,11 +263,11 @@ void ATHandler::write_int(int32_t param) { } -void ATHandler::write_string(const char* param, bool useQuotations) +void ATHandler::write_string(const char *param, bool useQuotations) { } -size_t ATHandler::write_bytes(const uint8_t* param, size_t len) +size_t ATHandler::write_bytes(const uint8_t *param, size_t len) { if (ATHandler_stub::return_given_size) { return len; diff --git a/features/cellular/UNITTESTS/stubs/ATHandler_stub.h b/features/cellular/UNITTESTS/stubs/ATHandler_stub.h index 0d5b3e820b0a..497a4928dabe 100644 --- a/features/cellular/UNITTESTS/stubs/ATHandler_stub.h +++ b/features/cellular/UNITTESTS/stubs/ATHandler_stub.h @@ -28,27 +28,27 @@ static const int kRead_int_table_size = 100; static const int kResp_stop_count_default = 100; namespace ATHandler_stub { - extern nsapi_error_t nsapi_error_value; - extern uint8_t nsapi_error_ok_counter; - extern int int_value; - extern int ref_count; - extern int timeout; - extern bool default_timeout; - extern bool debug_on; - extern ssize_t ssize_value; - extern char *read_string_value; - extern size_t size_value; - extern size_t return_given_size; - extern bool bool_value; - extern uint8_t resp_info_true_counter; - extern uint8_t info_elem_true_counter; - extern uint8_t uint8_value; - extern mbed::FileHandle_stub *fh_value; - extern mbed::device_err_t device_err_value; - extern mbed::Callback callback; - extern char *read_string_table[kRead_string_table_size]; - extern int read_string_index; - extern int int_valid_count_table[kRead_int_table_size]; - extern int int_count; - extern int resp_stop_success_count; +extern nsapi_error_t nsapi_error_value; +extern uint8_t nsapi_error_ok_counter; +extern int int_value; +extern int ref_count; +extern int timeout; +extern bool default_timeout; +extern bool debug_on; +extern ssize_t ssize_value; +extern char *read_string_value; +extern size_t size_value; +extern size_t return_given_size; +extern bool bool_value; +extern uint8_t resp_info_true_counter; +extern uint8_t info_elem_true_counter; +extern uint8_t uint8_value; +extern mbed::FileHandle_stub *fh_value; +extern mbed::device_err_t device_err_value; +extern mbed::Callback callback; +extern char *read_string_table[kRead_string_table_size]; +extern int read_string_index; +extern int int_valid_count_table[kRead_int_table_size]; +extern int int_count; +extern int resp_stop_success_count; } diff --git a/features/cellular/UNITTESTS/stubs/AT_CellularBase_stub.cpp b/features/cellular/UNITTESTS/stubs/AT_CellularBase_stub.cpp index 41ecca465634..e1f8526f5fd1 100644 --- a/features/cellular/UNITTESTS/stubs/AT_CellularBase_stub.cpp +++ b/features/cellular/UNITTESTS/stubs/AT_CellularBase_stub.cpp @@ -27,12 +27,12 @@ ATHandler *AT_CellularBase_stub::handler_at_constructor_value = NULL; device_err_t AT_CellularBase_stub::device_err_value; bool AT_CellularBase_stub::supported_bool = true; -AT_CellularBase::AT_CellularBase(ATHandler& at) : _at(at) +AT_CellularBase::AT_CellularBase(ATHandler &at) : _at(at) { AT_CellularBase_stub::handler_at_constructor_value = &_at; } -ATHandler& AT_CellularBase::get_at_handler() +ATHandler &AT_CellularBase::get_at_handler() { return *AT_CellularBase_stub::handler_value; } diff --git a/features/cellular/UNITTESTS/stubs/AT_CellularBase_stub.h b/features/cellular/UNITTESTS/stubs/AT_CellularBase_stub.h index 971fac848bb4..f7d117d192c3 100644 --- a/features/cellular/UNITTESTS/stubs/AT_CellularBase_stub.h +++ b/features/cellular/UNITTESTS/stubs/AT_CellularBase_stub.h @@ -18,8 +18,8 @@ #include "ATHandler.h" namespace AT_CellularBase_stub { - extern mbed::ATHandler *handler_value; - extern mbed::ATHandler *handler_at_constructor_value; - extern mbed::device_err_t device_err_value; - extern bool supported_bool; +extern mbed::ATHandler *handler_value; +extern mbed::ATHandler *handler_at_constructor_value; +extern mbed::device_err_t device_err_value; +extern bool supported_bool; } diff --git a/features/cellular/UNITTESTS/stubs/AT_CellularDevice_stub.cpp b/features/cellular/UNITTESTS/stubs/AT_CellularDevice_stub.cpp index 7051910e0c59..2010018ced26 100644 --- a/features/cellular/UNITTESTS/stubs/AT_CellularDevice_stub.cpp +++ b/features/cellular/UNITTESTS/stubs/AT_CellularDevice_stub.cpp @@ -26,14 +26,14 @@ AT_CellularDevice::~AT_CellularDevice() { } -ATHandler* AT_CellularDevice::get_at_handler(FileHandle *fileHandle) +ATHandler *AT_CellularDevice::get_at_handler(FileHandle *fileHandle) { return NULL; } -void AT_CellularDevice::release_at_handler(ATHandler* at_handler) +void AT_CellularDevice::release_at_handler(ATHandler *at_handler) { - + } CellularNetwork *AT_CellularDevice::open_network(FileHandle *fh) diff --git a/features/cellular/UNITTESTS/stubs/AT_CellularNetwork_stub.cpp b/features/cellular/UNITTESTS/stubs/AT_CellularNetwork_stub.cpp index c39de1c50427..4dba182f8b98 100644 --- a/features/cellular/UNITTESTS/stubs/AT_CellularNetwork_stub.cpp +++ b/features/cellular/UNITTESTS/stubs/AT_CellularNetwork_stub.cpp @@ -39,19 +39,19 @@ nsapi_error_t AT_CellularNetwork::init() } nsapi_error_t AT_CellularNetwork::set_credentials(const char *apn, - const char *username, const char *password) + const char *username, const char *password) { return NSAPI_ERROR_OK; } nsapi_error_t AT_CellularNetwork::set_credentials(const char *apn, - AuthenticationType type, const char *username, const char *password) + AuthenticationType type, const char *username, const char *password) { return NSAPI_ERROR_OK; } nsapi_error_t AT_CellularNetwork::connect(const char *apn, - const char *username, const char *password) + const char *username, const char *password) { return connect(); } @@ -90,7 +90,7 @@ nsapi_error_t AT_CellularNetwork::set_blocking(bool blocking) return NSAPI_ERROR_OK;; } -nsapi_ip_stack_t AT_CellularNetwork::string_to_stack_type(const char* pdp_type) +nsapi_ip_stack_t AT_CellularNetwork::string_to_stack_type(const char *pdp_type) { return IPV4_STACK; } @@ -100,7 +100,7 @@ nsapi_error_t AT_CellularNetwork::set_registration_urc(RegistrationType type, bo return NSAPI_ERROR_OK; } -nsapi_error_t AT_CellularNetwork::get_network_registering_mode(NWRegisteringMode& mode) +nsapi_error_t AT_CellularNetwork::get_network_registering_mode(NWRegisteringMode &mode) { mode = NWModeAutomatic; return NSAPI_ERROR_OK; @@ -186,7 +186,7 @@ nsapi_error_t AT_CellularNetwork::set_access_technology(RadioAccessTechnology op return NSAPI_ERROR_OK; } -nsapi_error_t AT_CellularNetwork::get_access_technology(RadioAccessTechnology& rat) +nsapi_error_t AT_CellularNetwork::get_access_technology(RadioAccessTechnology &rat) { rat = RAT_CATM1; return NSAPI_ERROR_OK; @@ -203,21 +203,21 @@ nsapi_error_t AT_CellularNetwork::set_ciot_optimization_config(Supported_UE_Opt return NSAPI_ERROR_OK; } -nsapi_error_t AT_CellularNetwork::get_ciot_optimization_config(Supported_UE_Opt& supported_opt, - Preferred_UE_Opt& preferred_opt) +nsapi_error_t AT_CellularNetwork::get_ciot_optimization_config(Supported_UE_Opt &supported_opt, + Preferred_UE_Opt &preferred_opt) { return NSAPI_ERROR_OK; } nsapi_error_t AT_CellularNetwork::get_rate_control( - CellularNetwork::RateControlExceptionReports &reports, - CellularNetwork::RateControlUplinkTimeUnit &timeUnit, int &uplinkRate) + CellularNetwork::RateControlExceptionReports &reports, + CellularNetwork::RateControlUplinkTimeUnit &timeUnit, int &uplinkRate) { return NSAPI_ERROR_OK; } -nsapi_error_t AT_CellularNetwork::get_pdpcontext_params(pdpContextList_t& params_list) +nsapi_error_t AT_CellularNetwork::get_pdpcontext_params(pdpContextList_t ¶ms_list) { return NSAPI_ERROR_OK; } diff --git a/features/cellular/UNITTESTS/stubs/AT_CellularPower_stub.cpp b/features/cellular/UNITTESTS/stubs/AT_CellularPower_stub.cpp index 8dc3f0aa4c76..3459088ce554 100644 --- a/features/cellular/UNITTESTS/stubs/AT_CellularPower_stub.cpp +++ b/features/cellular/UNITTESTS/stubs/AT_CellularPower_stub.cpp @@ -70,7 +70,8 @@ nsapi_error_t AT_CellularPower::set_device_ready_urc_cb(mbed::Callback c return NSAPI_ERROR_OK; } -void AT_CellularPower::remove_device_ready_urc_cb(mbed::Callback callback){ +void AT_CellularPower::remove_device_ready_urc_cb(mbed::Callback callback) +{ } diff --git a/features/cellular/UNITTESTS/stubs/AT_CellularSIM_stub.cpp b/features/cellular/UNITTESTS/stubs/AT_CellularSIM_stub.cpp index ee06161aaad7..fc4be35b9470 100644 --- a/features/cellular/UNITTESTS/stubs/AT_CellularSIM_stub.cpp +++ b/features/cellular/UNITTESTS/stubs/AT_CellularSIM_stub.cpp @@ -48,7 +48,7 @@ nsapi_error_t AT_CellularSIM::set_pin_query(const char *sim_pin, bool query_pin) return NSAPI_ERROR_OK; } -nsapi_error_t AT_CellularSIM::get_imsi(char* imsi) +nsapi_error_t AT_CellularSIM::get_imsi(char *imsi) { return NSAPI_ERROR_OK; } diff --git a/features/cellular/UNITTESTS/stubs/AT_CellularSMS_stub.cpp b/features/cellular/UNITTESTS/stubs/AT_CellularSMS_stub.cpp index 5f9461c1a3b2..66456d72952a 100644 --- a/features/cellular/UNITTESTS/stubs/AT_CellularSMS_stub.cpp +++ b/features/cellular/UNITTESTS/stubs/AT_CellularSMS_stub.cpp @@ -35,7 +35,7 @@ const uint16_t SMS_MAX_GSM7_CONCATENATED_SINGLE_SMS_SIZE = 153; AT_CellularSMS::AT_CellularSMS(ATHandler &at) : AT_CellularBase(at), _cb(0), _mode(CellularSMSMmodeText), - _use_8bit_encoding(false), _sim_wait_time(0), _sms_message_ref_number(1), _sms_info(NULL) + _use_8bit_encoding(false), _sim_wait_time(0), _sms_message_ref_number(1), _sms_info(NULL) { } @@ -80,13 +80,13 @@ void AT_CellularSMS::set_extra_sim_wait_time(int sim_wait_time) { } -char* AT_CellularSMS::create_pdu(const char* phone_number, const char* message, uint8_t message_length, uint8_t msg_parts, - uint8_t msg_part_number, uint8_t& header_size) +char *AT_CellularSMS::create_pdu(const char *phone_number, const char *message, uint8_t message_length, uint8_t msg_parts, + uint8_t msg_part_number, uint8_t &header_size) { return NULL; } -nsapi_size_or_error_t AT_CellularSMS::send_sms(const char* phone_number, const char* message, int msg_len) +nsapi_size_or_error_t AT_CellularSMS::send_sms(const char *phone_number, const char *message, int msg_len) { return NSAPI_ERROR_OK; } @@ -115,7 +115,7 @@ nsapi_size_or_error_t AT_CellularSMS::set_cscs(const char *chr_set) // return NSAPI_ERROR_OK; //} -nsapi_error_t AT_CellularSMS::delete_sms(sms_info_t* sms) +nsapi_error_t AT_CellularSMS::delete_sms(sms_info_t *sms) { return NSAPI_ERROR_OK; } @@ -125,35 +125,35 @@ nsapi_error_t AT_CellularSMS::delete_all_messages() return NSAPI_ERROR_OK; } -nsapi_size_or_error_t AT_CellularSMS::read_sms_from_index(int msg_index, char* buf, uint16_t len, char* phone_num, char* time_stamp) +nsapi_size_or_error_t AT_CellularSMS::read_sms_from_index(int msg_index, char *buf, uint16_t len, char *phone_num, char *time_stamp) { return NSAPI_ERROR_OK; } // read msg in PDU mode -nsapi_size_or_error_t AT_CellularSMS::read_sms(sms_info_t* sms, char* buf, char* phone_num, char* time_stamp) +nsapi_size_or_error_t AT_CellularSMS::read_sms(sms_info_t *sms, char *buf, char *phone_num, char *time_stamp) { return NSAPI_ERROR_OK; } -nsapi_size_or_error_t AT_CellularSMS::get_sms(char* buf, uint16_t len, char* phone_num, uint16_t phone_len, - char* time_stamp, uint16_t time_len, int *buf_size) +nsapi_size_or_error_t AT_CellularSMS::get_sms(char *buf, uint16_t len, char *phone_num, uint16_t phone_len, + char *time_stamp, uint16_t time_len, int *buf_size) { return NSAPI_ERROR_OK; } -nsapi_size_or_error_t AT_CellularSMS::get_data_from_pdu(const char* pdu, sms_info_t *info, int *part_number, char *phone_number, char *msg) +nsapi_size_or_error_t AT_CellularSMS::get_data_from_pdu(const char *pdu, sms_info_t *info, int *part_number, char *phone_number, char *msg) { return NSAPI_ERROR_OK; } - // read params from User DEfined Header -int AT_CellularSMS::read_udh_from_pdu(const char* pdu, sms_info_t *info, int &part_number, int &padding_bits) +// read params from User DEfined Header +int AT_CellularSMS::read_udh_from_pdu(const char *pdu, sms_info_t *info, int &part_number, int &padding_bits) { return 0; } -nsapi_size_or_error_t AT_CellularSMS::read_pdu_payload(const char* pdu, int msg_len, int scheme, char *msg, int padding_bits) +nsapi_size_or_error_t AT_CellularSMS::read_pdu_payload(const char *pdu, int msg_len, int scheme, char *msg, int padding_bits) { return NSAPI_ERROR_OK; } @@ -162,7 +162,7 @@ void AT_CellularSMS::free_linked_list() { } -void AT_CellularSMS::add_info(sms_info_t* info, int index, int part_number) +void AT_CellularSMS::add_info(sms_info_t *info, int index, int part_number) { } @@ -172,18 +172,18 @@ nsapi_error_t AT_CellularSMS::list_messages() return NSAPI_ERROR_OK; } -AT_CellularSMS::sms_info_t* AT_CellularSMS::get_oldest_sms_index() +AT_CellularSMS::sms_info_t *AT_CellularSMS::get_oldest_sms_index() { return NULL; } // if time_string_1 is greater (more fresh date) then return 1, same 0, smaller -1. Error -2 -int AT_CellularSMS::compare_time_strings(const char* time_string_1, const char* time_string_2) +int AT_CellularSMS::compare_time_strings(const char *time_string_1, const char *time_string_2) { return 0; } -bool AT_CellularSMS::create_time(const char* time_string, time_t* time) +bool AT_CellularSMS::create_time(const char *time_string, time_t *time) { return 0; } diff --git a/features/cellular/UNITTESTS/stubs/CellularUtil_stub.cpp b/features/cellular/UNITTESTS/stubs/CellularUtil_stub.cpp index d6c9a1658f33..d4bcaf491666 100644 --- a/features/cellular/UNITTESTS/stubs/CellularUtil_stub.cpp +++ b/features/cellular/UNITTESTS/stubs/CellularUtil_stub.cpp @@ -31,39 +31,39 @@ void str_remove_char(char *src, char c) { } -void uint_to_binary_str(uint32_t num, char* str, uint8_t str_size, uint8_t bit_cnt) +void uint_to_binary_str(uint32_t num, char *str, uint8_t str_size, uint8_t bit_cnt) { } // converts the given str to hex string to buf -uint16_t char_str_to_hex(const char* str, uint16_t len, char *buf, bool omit_leading_zero) +uint16_t char_str_to_hex(const char *str, uint16_t len, char *buf, bool omit_leading_zero) { return 0; } -void convert_ipv6(char* ip) +void convert_ipv6(char *ip) { } -char* find_dot_number(char* str, int dot_number) +char *find_dot_number(char *str, int dot_number) { return NULL; } -void separate_ip4like_addresses(char* orig, char* ip, size_t ip_size, char* ip2, size_t ip2_size) +void separate_ip4like_addresses(char *orig, char *ip, size_t ip_size, char *ip2, size_t ip2_size) { } -void separate_ip_addresses(char* orig, char* ip, size_t ip_size, char* ip2, size_t ip2_size) +void separate_ip_addresses(char *orig, char *ip, size_t ip_size, char *ip2, size_t ip2_size) { } -void prefer_ipv6(char* ip, size_t ip_size, char* ip2, size_t ip2_size) +void prefer_ipv6(char *ip, size_t ip_size, char *ip2, size_t ip2_size) { } -void int_to_hex_str(uint8_t num, char* buf) +void int_to_hex_str(uint8_t num, char *buf) { buf[0] = '0'; buf[1] = '2'; @@ -74,17 +74,17 @@ int hex_str_to_int(const char *hex_string, int hex_string_length) return 0; } -int hex_str_to_char_str(const char* str, uint16_t len, char *buf) +int hex_str_to_char_str(const char *str, uint16_t len, char *buf) { return 0; } -void uint_to_binary_str(uint32_t num, char* str, int str_size, int bit_cnt) +void uint_to_binary_str(uint32_t num, char *str, int str_size, int bit_cnt) { } -int char_str_to_hex_str(const char* str, uint16_t len, char *buf, bool omit_leading_zero) +int char_str_to_hex_str(const char *str, uint16_t len, char *buf, bool omit_leading_zero) { //The code is dependent on this, so this is easiest just to put here if (!str || !buf) { @@ -92,17 +92,17 @@ int char_str_to_hex_str(const char* str, uint16_t len, char *buf, bool omit_lead } char *ptr = buf; - int i=0; + int i = 0; while (i < len) { - if (omit_leading_zero == true && i == 0 && !(str[i]>>4 & 0x0F)) { + if (omit_leading_zero == true && i == 0 && !(str[i] >> 4 & 0x0F)) { *ptr++ = hex_values[(str[i]) & 0x0F]; } else { - *ptr++ = hex_values[((str[i])>>4) & 0x0F]; + *ptr++ = hex_values[((str[i]) >> 4) & 0x0F]; *ptr++ = hex_values[(str[i]) & 0x0F]; } i++; } - return ptr-buf; + return ptr - buf; } uint16_t get_dynamic_ip_port() diff --git a/features/cellular/UNITTESTS/stubs/EventQueue_stub.cpp b/features/cellular/UNITTESTS/stubs/EventQueue_stub.cpp index 235e69b6c584..2df602897712 100644 --- a/features/cellular/UNITTESTS/stubs/EventQueue_stub.cpp +++ b/features/cellular/UNITTESTS/stubs/EventQueue_stub.cpp @@ -22,29 +22,37 @@ using namespace mbed; namespace events { -EventQueue::EventQueue(unsigned event_size, unsigned char *event_pointer) { +EventQueue::EventQueue(unsigned event_size, unsigned char *event_pointer) +{ } -EventQueue::~EventQueue() { +EventQueue::~EventQueue() +{ } -void EventQueue::dispatch(int ms) { +void EventQueue::dispatch(int ms) +{ } -void EventQueue::break_dispatch() { +void EventQueue::break_dispatch() +{ } -unsigned EventQueue::tick() { +unsigned EventQueue::tick() +{ return 0; } -void EventQueue::cancel(int id) { +void EventQueue::cancel(int id) +{ } -void EventQueue::background(Callback update) { +void EventQueue::background(Callback update) +{ } -void EventQueue::chain(EventQueue *target) { +void EventQueue::chain(EventQueue *target) +{ } } diff --git a/features/cellular/UNITTESTS/stubs/FileHandle_stub.h b/features/cellular/UNITTESTS/stubs/FileHandle_stub.h index 5972a9a89eeb..e1548f232234 100644 --- a/features/cellular/UNITTESTS/stubs/FileHandle_stub.h +++ b/features/cellular/UNITTESTS/stubs/FileHandle_stub.h @@ -26,14 +26,17 @@ static uint8_t filehandle_stub_short_value_counter = 0; static char *filehandle_stub_table = NULL; static uint8_t filehandle_stub_table_pos = 0; -class FileHandle_stub : public FileHandle -{ +class FileHandle_stub : public FileHandle { public: ssize_t size_value; - FileHandle_stub() {size_value = 0;} + FileHandle_stub() + { + size_value = 0; + } - virtual ssize_t read(void *buffer, size_t size){ + virtual ssize_t read(void *buffer, size_t size) + { if (filehandle_stub_table) { ssize_t ret = strlen(filehandle_stub_table) - filehandle_stub_table_pos; if (ret >= 0 && size < ret) { @@ -49,7 +52,8 @@ class FileHandle_stub : public FileHandle return 0; } - virtual ssize_t write(const void *buffer, size_t size){ + virtual ssize_t write(const void *buffer, size_t size) + { if (size_value > 0) { size_value--; return size; @@ -59,11 +63,15 @@ class FileHandle_stub : public FileHandle return 0; } - virtual off_t seek(off_t offset, int whence = SEEK_SET){return 0;} + virtual off_t seek(off_t offset, int whence = SEEK_SET) + { + return 0; + } - virtual int close(){} + virtual int close() {} - virtual short poll(short events) const{ + virtual short poll(short events) const + { if (filehandle_stub_short_value_counter) { filehandle_stub_short_value_counter--; return short_value; @@ -71,7 +79,10 @@ class FileHandle_stub : public FileHandle return 0; } - virtual void sigio(Callback func){func();} + virtual void sigio(Callback func) + { + func(); + } short short_value; }; diff --git a/features/cellular/UNITTESTS/stubs/NetworkInterface_stub.cpp b/features/cellular/UNITTESTS/stubs/NetworkInterface_stub.cpp index 6933b3dff460..0e8eaa15a984 100644 --- a/features/cellular/UNITTESTS/stubs/NetworkInterface_stub.cpp +++ b/features/cellular/UNITTESTS/stubs/NetworkInterface_stub.cpp @@ -77,7 +77,7 @@ nsapi_error_t NetworkInterface::set_blocking(bool blocking) return NSAPI_ERROR_UNSUPPORTED; } -nsapi_value_or_error_t NetworkInterface::gethostbyname_async(char const*, mbed::Callback, nsapi_version) +nsapi_value_or_error_t NetworkInterface::gethostbyname_async(char const *, mbed::Callback, nsapi_version) { return NSAPI_ERROR_UNSUPPORTED; } diff --git a/features/cellular/UNITTESTS/stubs/NetworkStack_stub.cpp b/features/cellular/UNITTESTS/stubs/NetworkStack_stub.cpp index 873728179a8d..372812effba5 100644 --- a/features/cellular/UNITTESTS/stubs/NetworkStack_stub.cpp +++ b/features/cellular/UNITTESTS/stubs/NetworkStack_stub.cpp @@ -68,16 +68,16 @@ NetworkStack *nsapi_create_stack(NetworkStack *stack) return NULL; } - nsapi_value_or_error_t NetworkStack::gethostbyname_async(const char *host, hostbyname_cb_t callback, - nsapi_version_t version) - { - return NSAPI_ERROR_UNSUPPORTED; - } +nsapi_value_or_error_t NetworkStack::gethostbyname_async(const char *host, hostbyname_cb_t callback, + nsapi_version_t version) +{ + return NSAPI_ERROR_UNSUPPORTED; +} - nsapi_error_t NetworkStack::gethostbyname_async_cancel(int id) - { - return NSAPI_ERROR_UNSUPPORTED; - } +nsapi_error_t NetworkStack::gethostbyname_async_cancel(int id) +{ + return NSAPI_ERROR_UNSUPPORTED; +} call_in_callback_cb_t NetworkStack::get_call_in_callback() { diff --git a/features/cellular/UNITTESTS/stubs/Semaphore_stub.cpp b/features/cellular/UNITTESTS/stubs/Semaphore_stub.cpp index 3782b77f8cab..ada09df114c8 100644 --- a/features/cellular/UNITTESTS/stubs/Semaphore_stub.cpp +++ b/features/cellular/UNITTESTS/stubs/Semaphore_stub.cpp @@ -19,37 +19,37 @@ namespace rtos { -Semaphore::Semaphore(int32_t count) +Semaphore::Semaphore(int32_t count) { } -Semaphore::Semaphore(int32_t count, uint16_t max_count) +Semaphore::Semaphore(int32_t count, uint16_t max_count) { } -void Semaphore::constructor(int32_t count, uint16_t max_count) +void Semaphore::constructor(int32_t count, uint16_t max_count) { - + } -int32_t Semaphore::wait(uint32_t millisec) +int32_t Semaphore::wait(uint32_t millisec) { return 0; } -int32_t Semaphore::wait_until(uint64_t millisec) +int32_t Semaphore::wait_until(uint64_t millisec) { return 0; } -osStatus Semaphore::release(void) +osStatus Semaphore::release(void) { return 0; } -Semaphore::~Semaphore() +Semaphore::~Semaphore() { } diff --git a/features/cellular/UNITTESTS/stubs/Thread_stub.cpp b/features/cellular/UNITTESTS/stubs/Thread_stub.cpp index c76f87a193c3..8eed1e7f2a3a 100644 --- a/features/cellular/UNITTESTS/stubs/Thread_stub.cpp +++ b/features/cellular/UNITTESTS/stubs/Thread_stub.cpp @@ -19,7 +19,8 @@ namespace rtos { -osStatus Thread::wait_until(uint64_t millisec) { +osStatus Thread::wait_until(uint64_t millisec) +{ return 0; } diff --git a/features/cellular/UNITTESTS/stubs/Timer_stub.cpp b/features/cellular/UNITTESTS/stubs/Timer_stub.cpp index db3ba4cd9572..2e20c161aee3 100644 --- a/features/cellular/UNITTESTS/stubs/Timer_stub.cpp +++ b/features/cellular/UNITTESTS/stubs/Timer_stub.cpp @@ -20,35 +20,45 @@ namespace mbed { -Timer::Timer() { +Timer::Timer() +{ } -Timer::Timer(const ticker_data_t *data) { +Timer::Timer(const ticker_data_t *data) +{ } -Timer::~Timer() { +Timer::~Timer() +{ } -void Timer::start() { +void Timer::start() +{ } -void Timer::stop() {; +void Timer::stop() +{ + ; } -int Timer::read_us() { +int Timer::read_us() +{ return 0; } -float Timer::read() { +float Timer::read() +{ return 0; } -int Timer::read_ms() { +int Timer::read_ms() +{ timer_stub_value += timer_stub_step; return timer_stub_value; } -us_timestamp_t Timer::read_high_resolution_us() { +us_timestamp_t Timer::read_high_resolution_us() +{ return 0; } @@ -56,7 +66,8 @@ void Timer::reset() { } -Timer::operator float() { +Timer::operator float() +{ return 0; } diff --git a/features/cellular/UNITTESTS/stubs/equeue_stub.c b/features/cellular/UNITTESTS/stubs/equeue_stub.c index cc5c267df13d..55a52174e71d 100644 --- a/features/cellular/UNITTESTS/stubs/equeue_stub.c +++ b/features/cellular/UNITTESTS/stubs/equeue_stub.c @@ -93,7 +93,7 @@ void equeue_cancel(equeue_t *queue, int id) } void equeue_background(equeue_t *queue, - void (*update)(void *timer, int ms), void *timer) + void (*update)(void *timer, int ms), void *timer) { } diff --git a/features/cellular/UNITTESTS/stubs/mbed_poll_stub.h b/features/cellular/UNITTESTS/stubs/mbed_poll_stub.h index 4d92b60b8eb2..6c0a4327a928 100644 --- a/features/cellular/UNITTESTS/stubs/mbed_poll_stub.h +++ b/features/cellular/UNITTESTS/stubs/mbed_poll_stub.h @@ -20,8 +20,8 @@ #include namespace mbed_poll_stub { - extern int revents_value; - extern int int_value; +extern int revents_value; +extern int int_value; } #endif diff --git a/features/cellular/UNITTESTS/stubs/mbed_wait_api_stub.cpp b/features/cellular/UNITTESTS/stubs/mbed_wait_api_stub.cpp index 5e4873be3881..f8b240544d80 100644 --- a/features/cellular/UNITTESTS/stubs/mbed_wait_api_stub.cpp +++ b/features/cellular/UNITTESTS/stubs/mbed_wait_api_stub.cpp @@ -17,11 +17,14 @@ #include "mbed_wait_api.h" -void wait(float s) { +void wait(float s) +{ } -void wait_ms(int ms) { +void wait_ms(int ms) +{ } -void wait_us(int us) { +void wait_us(int us) +{ } diff --git a/features/cellular/UNITTESTS/stubs/us_ticker_stub.cpp b/features/cellular/UNITTESTS/stubs/us_ticker_stub.cpp index 3727e1f618ce..69c96accee03 100644 --- a/features/cellular/UNITTESTS/stubs/us_ticker_stub.cpp +++ b/features/cellular/UNITTESTS/stubs/us_ticker_stub.cpp @@ -19,7 +19,7 @@ #include "stdlib.h" #include "us_ticker_api.h" -const ticker_data_t* get_us_ticker_data(void) +const ticker_data_t *get_us_ticker_data(void) { return NULL; } diff --git a/features/cellular/UNITTESTS/target_h/ATCmdParser.h b/features/cellular/UNITTESTS/target_h/ATCmdParser.h index 9e5628170279..c1994cc2afc3 100644 --- a/features/cellular/UNITTESTS/target_h/ATCmdParser.h +++ b/features/cellular/UNITTESTS/target_h/ATCmdParser.h @@ -21,13 +21,12 @@ #include #include "FileHandle.h" -class ATCmdParser -{ +class ATCmdParser { public: ATCmdParser(mbed::FileHandle *fh, const char *output_delimiter = "\r", - int buffer_size = 256, int timeout = 8000, bool debug = false){} + int buffer_size = 256, int timeout = 8000, bool debug = false) {} - ~ATCmdParser(){} + ~ATCmdParser() {} }; #endif //__AT_CMD_PARSER_H__ diff --git a/features/cellular/UNITTESTS/target_h/cmsis_os2.h b/features/cellular/UNITTESTS/target_h/cmsis_os2.h index 8c060847d118..dcd0c20c611e 100644 --- a/features/cellular/UNITTESTS/target_h/cmsis_os2.h +++ b/features/cellular/UNITTESTS/target_h/cmsis_os2.h @@ -29,15 +29,15 @@ typedef int32_t osStatus; typedef void *osSemaphoreId_t; typedef struct { - const char *name; ///< name of the semaphore - uint32_t attr_bits; ///< attribute bits - void *cb_mem; ///< memory for control block - uint32_t cb_size; ///< size of provided memory for control block + const char *name; ///< name of the semaphore + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block } osSemaphoreAttr_t; //Thread typedef enum { - osPriorityNormal = 24 ///< Priority: normal + osPriorityNormal = 24 ///< Priority: normal } osPriority_t; typedef void *osThreadId_t; diff --git a/features/cellular/UNITTESTS/target_h/rtos/Mutex.h b/features/cellular/UNITTESTS/target_h/rtos/Mutex.h index d67b376ccab8..68d797d3eba9 100644 --- a/features/cellular/UNITTESTS/target_h/rtos/Mutex.h +++ b/features/cellular/UNITTESTS/target_h/rtos/Mutex.h @@ -15,4 +15,4 @@ * limitations under the License. */ -typedef void* Mutex; +typedef void *Mutex; diff --git a/features/cellular/UNITTESTS/target_h/rtos/Semaphore.h b/features/cellular/UNITTESTS/target_h/rtos/Semaphore.h index c0ca4c7c9956..34e472dea61f 100644 --- a/features/cellular/UNITTESTS/target_h/rtos/Semaphore.h +++ b/features/cellular/UNITTESTS/target_h/rtos/Semaphore.h @@ -15,4 +15,4 @@ * limitations under the License. */ -typedef void* Semaphore; +typedef void *Semaphore; diff --git a/features/cellular/UNITTESTS/target_h/rtx_os.h b/features/cellular/UNITTESTS/target_h/rtx_os.h index 93415e9fd87b..bb29a2164cf2 100644 --- a/features/cellular/UNITTESTS/target_h/rtx_os.h +++ b/features/cellular/UNITTESTS/target_h/rtx_os.h @@ -21,40 +21,40 @@ #include "inttypes.h" typedef struct osRtxSemaphore_s { - uint8_t id; ///< Object Identifier - uint8_t state; ///< Object State - uint8_t flags; ///< Object Flags - uint8_t reserved; - const char *name; ///< Object Name - uint16_t tokens; ///< Current number of tokens - uint16_t max_tokens; ///< Maximum number of tokens + uint8_t id; ///< Object Identifier + uint8_t state; ///< Object State + uint8_t flags; ///< Object Flags + uint8_t reserved; + const char *name; ///< Object Name + uint16_t tokens; ///< Current number of tokens + uint16_t max_tokens; ///< Maximum number of tokens } osRtxSemaphore_t; typedef struct osRtxThread_s { - uint8_t id; ///< Object Identifier - uint8_t state; ///< Object State - uint8_t flags; ///< Object Flags - uint8_t attr; ///< Object Attributes - const char *name; ///< Object Name - struct osRtxThread_s *thread_next; ///< Link pointer to next Thread in Object list - struct osRtxThread_s *thread_prev; ///< Link pointer to previous Thread in Object list - struct osRtxThread_s *delay_next; ///< Link pointer to next Thread in Delay list - struct osRtxThread_s *delay_prev; ///< Link pointer to previous Thread in Delay list - struct osRtxThread_s *thread_join; ///< Thread waiting to Join - uint32_t delay; ///< Delay Time - int8_t priority; ///< Thread Priority - int8_t priority_base; ///< Base Priority - uint8_t stack_frame; ///< Stack Frame (EXC_RETURN[7..0]) - uint8_t flags_options; ///< Thread/Event Flags Options - uint32_t wait_flags; ///< Waiting Thread/Event Flags - uint32_t thread_flags; ///< Thread Flags - struct osRtxMutex_s *mutex_list; ///< Link pointer to list of owned Mutexes - void *stack_mem; ///< Stack Memory - uint32_t stack_size; ///< Stack Size - uint32_t sp; ///< Current Stack Pointer - uint32_t thread_addr; ///< Thread entry address - uint32_t tz_memory; ///< TrustZone Memory Identifier - void *context; ///< Context for OsEventObserver objects + uint8_t id; ///< Object Identifier + uint8_t state; ///< Object State + uint8_t flags; ///< Object Flags + uint8_t attr; ///< Object Attributes + const char *name; ///< Object Name + struct osRtxThread_s *thread_next; ///< Link pointer to next Thread in Object list + struct osRtxThread_s *thread_prev; ///< Link pointer to previous Thread in Object list + struct osRtxThread_s *delay_next; ///< Link pointer to next Thread in Delay list + struct osRtxThread_s *delay_prev; ///< Link pointer to previous Thread in Delay list + struct osRtxThread_s *thread_join; ///< Thread waiting to Join + uint32_t delay; ///< Delay Time + int8_t priority; ///< Thread Priority + int8_t priority_base; ///< Base Priority + uint8_t stack_frame; ///< Stack Frame (EXC_RETURN[7..0]) + uint8_t flags_options; ///< Thread/Event Flags Options + uint32_t wait_flags; ///< Waiting Thread/Event Flags + uint32_t thread_flags; ///< Thread Flags + struct osRtxMutex_s *mutex_list; ///< Link pointer to list of owned Mutexes + void *stack_mem; ///< Stack Memory + uint32_t stack_size; ///< Stack Size + uint32_t sp; ///< Current Stack Pointer + uint32_t thread_addr; ///< Thread entry address + uint32_t tz_memory; ///< TrustZone Memory Identifier + void *context; ///< Context for OsEventObserver objects } osRtxThread_t; -#endif +#endif diff --git a/features/cellular/UNITTESTS/target_h/sys/syslimits.h b/features/cellular/UNITTESTS/target_h/sys/syslimits.h index bd27d352d561..5c90b373f140 100644 --- a/features/cellular/UNITTESTS/target_h/sys/syslimits.h +++ b/features/cellular/UNITTESTS/target_h/sys/syslimits.h @@ -14,4 +14,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#define NAME_MAX 255 +#define NAME_MAX 255 diff --git a/features/cellular/easy_cellular/APN_db.h b/features/cellular/easy_cellular/APN_db.h index 040cb2bf4224..1056192b6af7 100644 --- a/features/cellular/easy_cellular/APN_db.h +++ b/features/cellular/easy_cellular/APN_db.h @@ -16,17 +16,17 @@ /* ---------------------------------------------------------------- APN stands for Access Point Name, a setting on your modem or phone - that identifies an external network your phone can access for data - (e.g. 3G or 4G Internet service on your phone). - + that identifies an external network your phone can access for data + (e.g. 3G or 4G Internet service on your phone). + The APN settings can be forced when calling the join function. - Below is a list of known APNs that us used if no apn config + Below is a list of known APNs that us used if no apn config is forced. This list could be extended by other settings. - + For further reading: wiki apn: http://en.wikipedia.org/wiki/Access_Point_Name wiki mcc/mnc: http://en.wikipedia.org/wiki/Mobile_country_code - google: https://www.google.de/search?q=APN+list + google: https://www.google.de/search?q=APN+list ---------------------------------------------------------------- */ /** @@ -44,15 +44,15 @@ /** * APN lookup struct */ -typedef struct { - const char* mccmnc; /**< mobile country code (MCC) and mobile network code MNC */ - const char* cfg; /**< APN configuartion string, use _APN macro to generate */ +typedef struct { + const char *mccmnc; /**< mobile country code (MCC) and mobile network code MNC */ + const char *cfg; /**< APN configuartion string, use _APN macro to generate */ } APN_t; /** * Default APN settings used by many networks */ -static const char* apndef = _APN("internet",,); +static const char *apndef = _APN("internet",,); /** * List of special APNs for different network operators. @@ -73,14 +73,17 @@ static const APN_t apnlut[] = { // 460 China - CN { /* CN Mobile */"460-00", _APN("cmnet",,) - _APN("cmwap",,) }, + _APN("cmwap",,) + }, { /* Unicom */ "460-01", _APN("3gnet",,) - _APN("uninet","uninet","uninet") }, - + _APN("uninet", "uninet", "uninet") + }, + // 262 Germany - DE - { /* T-Mobile */ "262-01", _APN("internet.t-mobile","t-mobile","tm") }, - { /* T-Mobile */ "262-02,06", - _APN("m2m.business",,) }, + { /* T-Mobile */ "262-01", _APN("internet.t-mobile", "t-mobile", "tm") }, + { /* T-Mobile */ "262-02,06", + _APN("m2m.business",,) + }, // 222 Italy - IT { /* TIM */ "222-01", _APN("ibox.tim.it",,) }, @@ -89,15 +92,17 @@ static const APN_t apnlut[] = { // 440 Japan - JP { /* Softbank */ "440-04,06,20,40,41,42,43,44,45,46,47,48,90,91,92,93,94,95" - ",96,97,98" - _APN("open.softbank.ne.jp","opensoftbank","ebMNuX1FIHg9d3DA") - _APN("smile.world","dna1trop","so2t3k3m2a") }, + ",96,97,98" + _APN("open.softbank.ne.jp", "opensoftbank", "ebMNuX1FIHg9d3DA") + _APN("smile.world", "dna1trop", "so2t3k3m2a") + }, { /* NTTDoCoMo */"440-09,10,11,12,13,14,15,16,17,18,19,21,22,23,24,25,26,27," - "28,29,30,31,32,33,34,35,36,37,38,39,58,59,60,61,62,63," - "64,65,66,67,68,69,87,99", - _APN("bmobilewap",,) /*BMobile*/ - _APN("mpr2.bizho.net","Mopera U",) /* DoCoMo */ - _APN("bmobile.ne.jp","bmobile@wifi2","bmobile") /*BMobile*/ }, + "28,29,30,31,32,33,34,35,36,37,38,39,58,59,60,61,62,63," + "64,65,66,67,68,69,87,99", + _APN("bmobilewap",,) /*BMobile*/ + _APN("mpr2.bizho.net", "Mopera U",) /* DoCoMo */ + _APN("bmobile.ne.jp", "bmobile@wifi2", "bmobile") /*BMobile*/ + }, // 204 Netherlands - NL { /* Vodafone */ "204-04", _APN("public4.m2minternet.com",,) }, @@ -106,38 +111,44 @@ static const APN_t apnlut[] = { { /* Si.mobil */ "293-40", _APN("internet.simobil.si",,) }, { /* Tusmobil */ "293-70", _APN("internet.tusmobil.si",,) }, -// 240 Sweden SE +// 240 Sweden SE { /* Telia */ "240-01", _APN("online.telia.se",,) }, { /* Telenor */ "240-06,08", - _APN("services.telenor.se",,) }, + _APN("services.telenor.se",,) + }, { /* Tele2 */ "240-07", _APN("mobileinternet.tele2.se",,) }, - + // 228 Switzerland - CH { /* Swisscom */ "228-01", _APN("gprs.swisscom.ch",,) }, { /* Orange */ "228-03", _APN("internet",,) /* contract */ - _APN("click",,) /* pre-pay */ }, + _APN("click",,) /* pre-pay */ + }, // 234 United Kingdom - GB { /* O2 */ "234-02,10,11", - _APN("mobile.o2.co.uk","faster","web") /* contract */ - _APN("mobile.o2.co.uk","bypass","web") /* pre-pay */ - _APN("payandgo.o2.co.uk","payandgo","payandgo") }, - { /* Vodafone */ "234-15", _APN("internet","web","web") /* contract */ - _APN("pp.vodafone.co.uk","wap","wap") /* pre-pay */ }, + _APN("mobile.o2.co.uk", "faster", "web") /* contract */ + _APN("mobile.o2.co.uk", "bypass", "web") /* pre-pay */ + _APN("payandgo.o2.co.uk", "payandgo", "payandgo") + }, + { /* Vodafone */ "234-15", _APN("internet", "web", "web") /* contract */ + _APN("pp.vodafone.co.uk", "wap", "wap") /* pre-pay */ + }, { /* Three */ "234-20", _APN("three.co.uk",,) }, { /* Jersey */ "234-50", _APN("jtm2m",,) /* as used on u-blox C030 U201 boards */ }, // 310 United States of America - US { /* T-Mobile */ "310-026,260,490", - _APN("epc.tmobile.com",,) - _APN("fast.tmobile.com",,) /* LTE */ }, + _APN("epc.tmobile.com",,) + _APN("fast.tmobile.com",,) /* LTE */ + }, { /* AT&T */ "310-030,150,170,260,410,560,680", - _APN("phone",,) - _APN("wap.cingular","WAP@CINGULARGPRS.COM","CINGULAR1") - _APN("isp.cingular","ISP@CINGULARGPRS.COM","CINGULAR1") }, + _APN("phone",,) + _APN("wap.cingular", "WAP@CINGULARGPRS.COM", "CINGULAR1") + _APN("isp.cingular", "ISP@CINGULARGPRS.COM", "CINGULAR1") + }, // 901 International - INT - { /* Transatel */ "901-37", _APN("netgprs.com","tsl","tsl") }, + { /* Transatel */ "901-37", _APN("netgprs.com", "tsl", "tsl") }, }; /** @@ -145,26 +156,27 @@ static const APN_t apnlut[] = { * * @param imsi strinf containing IMSI */ -inline const char* apnconfig(const char* imsi) +inline const char *apnconfig(const char *imsi) { - const char* config = NULL; + const char *config = NULL; if (imsi && *imsi) { // many carriers use internet without username and password, os use this as default // now try to lookup the setting for our table - for (size_t i = 0; i < sizeof(apnlut)/sizeof(*apnlut) && !config; i ++) { - const char* p = apnlut[i].mccmnc; + for (size_t i = 0; i < sizeof(apnlut) / sizeof(*apnlut) && !config; i ++) { + const char *p = apnlut[i].mccmnc; // check the MCC if ((0 == memcmp(imsi, p, 3))) { p += 3; // check all the MNC, MNC length can be 2 or 3 digits - while (((p[0] == '-') || (p[0] == ',')) && - (p[1] >= '0') && (p[1] <= '9') && + while (((p[0] == '-') || (p[0] == ',')) && + (p[1] >= '0') && (p[1] <= '9') && (p[2] >= '0') && (p[2] <= '9') && !config) { int l = ((p[3] >= '0') && (p[3] <= '9')) ? 3 : 2; - if (0 == memcmp(imsi+3,p+1,l)) + if (0 == memcmp(imsi + 3, p + 1, l)) { config = apnlut[i].cfg; + } p += 1 + l; - } + } } } } diff --git a/features/cellular/easy_cellular/CellularConnectionFSM.cpp b/features/cellular/easy_cellular/CellularConnectionFSM.cpp index 88ac53a2a078..657b734ae34a 100644 --- a/features/cellular/easy_cellular/CellularConnectionFSM.cpp +++ b/features/cellular/easy_cellular/CellularConnectionFSM.cpp @@ -37,13 +37,12 @@ #define RETRY_COUNT_DEFAULT 3 -namespace mbed -{ +namespace mbed { CellularConnectionFSM::CellularConnectionFSM() : - _serial(0), _state(STATE_INIT), _next_state(_state), _status_callback(0), _event_status_cb(0), _network(0), _power(0), _sim(0), - _queue(8 * EVENTS_EVENT_SIZE), _queue_thread(0), _cellularDevice(0), _retry_count(0), _event_timeout(-1), - _at_queue(8 * EVENTS_EVENT_SIZE), _event_id(0), _plmn(0), _command_success(false), _plmn_network_found(false) + _serial(0), _state(STATE_INIT), _next_state(_state), _status_callback(0), _event_status_cb(0), _network(0), _power(0), _sim(0), + _queue(8 * EVENTS_EVENT_SIZE), _queue_thread(0), _cellularDevice(0), _retry_count(0), _event_timeout(-1), + _at_queue(8 * EVENTS_EVENT_SIZE), _event_id(0), _plmn(0), _command_success(false), _plmn_network_found(false) { memset(_sim_pin, 0, sizeof(_sim_pin)); #if MBED_CONF_CELLULAR_RANDOM_MAX_START_DELAY == 0 @@ -147,7 +146,7 @@ bool CellularConnectionFSM::power_on() void CellularConnectionFSM::set_sim_pin(const char *sim_pin) { strncpy(_sim_pin, sim_pin, sizeof(_sim_pin)); - _sim_pin[sizeof(_sim_pin)-1] = '\0'; + _sim_pin[sizeof(_sim_pin) - 1] = '\0'; } void CellularConnectionFSM::set_plmn(const char *plmn) @@ -202,7 +201,7 @@ bool CellularConnectionFSM::is_registered() } bool CellularConnectionFSM::get_network_registration(CellularNetwork::RegistrationType type, - CellularNetwork::RegistrationStatus &status, bool &is_registered) + CellularNetwork::RegistrationStatus &status, bool &is_registered) { is_registered = false; bool is_roaming = false; @@ -395,8 +394,11 @@ void CellularConnectionFSM::state_power_on() } } -void CellularConnectionFSM::device_ready() +bool CellularConnectionFSM::device_ready() { + if (_cellularDevice->init_module(_serial) != NSAPI_ERROR_OK) { + return false; + } tr_info("Cellular device ready"); if (_event_status_cb) { _event_status_cb((nsapi_event_t)CellularDeviceReady, 0); @@ -404,14 +406,16 @@ void CellularConnectionFSM::device_ready() _power->remove_device_ready_urc_cb(mbed::callback(this, &CellularConnectionFSM::ready_urc_cb)); _cellularDevice->close_power(); _power = NULL; + return true; } void CellularConnectionFSM::state_device_ready() { _cellularDevice->set_timeout(TIMEOUT_POWER_ON); if (_power->set_at_mode() == NSAPI_ERROR_OK) { - device_ready(); - enter_to_state(STATE_SIM_PIN); + if (device_ready()) { + enter_to_state(STATE_SIM_PIN); + } } else { if (_retry_count == 0) { (void)_power->set_device_ready_urc_cb(mbed::callback(this, &CellularConnectionFSM::ready_urc_cb)); @@ -581,7 +585,7 @@ void CellularConnectionFSM::event() if (_event_timeout == -1) { _event_timeout = 0; } - _event_id = _queue.call_in(_event_timeout*1000, callback(this, &CellularConnectionFSM::event)); + _event_id = _queue.call_in(_event_timeout * 1000, callback(this, &CellularConnectionFSM::event)); if (!_event_id) { report_failure("Cellular event failure!"); return; @@ -659,9 +663,10 @@ void CellularConnectionFSM::ready_urc_cb() tr_debug("Device ready URC func called"); if (_state == STATE_DEVICE_READY && _power->set_at_mode() == NSAPI_ERROR_OK) { tr_debug("State was STATE_DEVICE_READY and at mode ready, cancel state and move to next"); - _queue.cancel(_event_id); - device_ready(); - continue_from_state(STATE_SIM_PIN); + if (device_ready()) { + _queue.cancel(_event_id); + continue_from_state(STATE_SIM_PIN); + } } } diff --git a/features/cellular/easy_cellular/CellularConnectionFSM.h b/features/cellular/easy_cellular/CellularConnectionFSM.h index f8fd21a20c4f..ba9f4cf21842 100644 --- a/features/cellular/easy_cellular/CellularConnectionFSM.h +++ b/features/cellular/easy_cellular/CellularConnectionFSM.h @@ -43,8 +43,7 @@ const int MAX_RETRY_ARRAY_SIZE = 10; * * Finite State Machine for connecting to cellular network */ -class CellularConnectionFSM -{ +class CellularConnectionFSM { public: CellularConnectionFSM(); virtual ~CellularConnectionFSM(); @@ -148,7 +147,7 @@ class CellularConnectionFSM * * @param plmn operator in numeric format. See more from 3GPP TS 27.007 chapter 7.3. */ - void set_plmn(const char* plmn); + void set_plmn(const char *plmn); /** returns readable format of the given state. Used for printing states while debugging. * @@ -162,7 +161,7 @@ class CellularConnectionFSM bool open_sim(); bool get_network_registration(CellularNetwork::RegistrationType type, CellularNetwork::RegistrationStatus &status, bool &is_registered); bool is_registered(); - void device_ready(); + bool device_ready(); // state functions to keep state machine simple void state_init(); @@ -186,7 +185,7 @@ class CellularConnectionFSM NetworkStack *get_stack(); private: - void report_failure(const char* msg); + void report_failure(const char *msg); void event(); void ready_urc_cb(); @@ -203,7 +202,7 @@ class CellularConnectionFSM events::EventQueue _queue; rtos::Thread *_queue_thread; CellularDevice *_cellularDevice; - char _sim_pin[PIN_SIZE+1]; + char _sim_pin[PIN_SIZE + 1]; int _retry_count; int _start_time; int _event_timeout; diff --git a/features/cellular/easy_cellular/EasyCellularConnection.cpp b/features/cellular/easy_cellular/EasyCellularConnection.cpp index 63bb930d41bf..79a8fd3c8788 100644 --- a/features/cellular/easy_cellular/EasyCellularConnection.cpp +++ b/features/cellular/easy_cellular/EasyCellularConnection.cpp @@ -63,9 +63,9 @@ void EasyCellularConnection::network_callback(nsapi_event_t ev, intptr_t ptr) } EasyCellularConnection::EasyCellularConnection(bool debug) : - _is_connected(false), _is_initialized(false), _target_state(CellularConnectionFSM::STATE_POWER_ON), _cellularSerial( - MDMTXD, MDMRXD, MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE), _cellularSemaphore(0), _cellularConnectionFSM(0), _credentials_err( - NSAPI_ERROR_OK), _status_cb(0) + _is_connected(false), _is_initialized(false), _target_state(CellularConnectionFSM::STATE_POWER_ON), _cellularSerial( + MDMTXD, MDMRXD, MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE), _cellularSemaphore(0), _cellularConnectionFSM(0), _credentials_err( + NSAPI_ERROR_OK), _status_cb(0) { tr_info("EasyCellularConnection()"); #if USE_APN_LOOKUP @@ -203,9 +203,9 @@ nsapi_error_t EasyCellularConnection::connect() if (err == NSAPI_ERROR_OK) { const char *apn_config = apnconfig(imsi); if (apn_config) { - const char* apn = _APN_GET(apn_config); - const char* uname = _APN_GET(apn_config); - const char* pwd = _APN_GET(apn_config); + const char *apn = _APN_GET(apn_config); + const char *uname = _APN_GET(apn_config); + const char *pwd = _APN_GET(apn_config); tr_info("Looked up APN %s", apn); err = _cellularConnectionFSM->get_network()->set_credentials(apn, uname, pwd); } diff --git a/features/cellular/easy_cellular/EasyCellularConnection.h b/features/cellular/easy_cellular/EasyCellularConnection.h index 52c6a681bb05..396be5c5b894 100644 --- a/features/cellular/easy_cellular/EasyCellularConnection.h +++ b/features/cellular/easy_cellular/EasyCellularConnection.h @@ -25,15 +25,13 @@ #define USE_APN_LOOKUP (MBED_CONF_CELLULAR_USE_APN_LOOKUP || (NSAPI_PPP_AVAILABLE && MBED_CONF_PPP_CELL_IFACE_APN_LOOKUP)) -namespace mbed -{ +namespace mbed { /** EasyCellularConnection class * * Simplified adapter for cellular connection */ -class EasyCellularConnection: public CellularBase -{ +class EasyCellularConnection: public CellularBase { public: EasyCellularConnection(bool debug = false); @@ -136,7 +134,7 @@ class EasyCellularConnection: public CellularBase * * @param plmn operator in numeric format. See more from 3GPP TS 27.007 chapter 7.3. */ - void set_plmn(const char* plmn); + void set_plmn(const char *plmn); protected: /** Provide access to the NetworkStack object diff --git a/features/cellular/framework/API/CellularDevice.h b/features/cellular/framework/API/CellularDevice.h index 5bfa921304ed..46b6f9d731cb 100644 --- a/features/cellular/framework/API/CellularDevice.h +++ b/features/cellular/framework/API/CellularDevice.h @@ -27,8 +27,7 @@ #include "CellularInformation.h" #include "NetworkStack.h" -namespace mbed -{ +namespace mbed { /** * Class CellularDevice @@ -36,8 +35,7 @@ namespace mbed * An abstract interface that defines opening and closing of cellular interfaces. * Deleting/Closing of opened interfaces can be done only via this class. */ -class CellularDevice -{ +class CellularDevice { public: /** virtual Destructor */ @@ -116,6 +114,16 @@ class CellularDevice * @return network stack */ virtual NetworkStack *get_stack() = 0; + + /** Initialize cellular module must be called right after module is ready. + * For example, when multiple modules are supported in a single AT driver this function detects + * and adapts to an actual module at runtime. + * + * @param fh file handle used in communication to modem. + * + * @return 0 on success + */ + virtual nsapi_error_t init_module(FileHandle *fh) = 0; }; } // namespace mbed diff --git a/features/cellular/framework/API/CellularInformation.h b/features/cellular/framework/API/CellularInformation.h index 63cc24f9e9e2..ce30f52e5fce 100644 --- a/features/cellular/framework/API/CellularInformation.h +++ b/features/cellular/framework/API/CellularInformation.h @@ -42,7 +42,8 @@ class CellularInformation { * * @param buf manufacturer identification as zero terminated string * @param buf_size max length of manufacturer identification is 2048 characters - * @return zero on success, on failure negative error code + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_DEVICE_ERROR on failure */ virtual nsapi_error_t get_manufacturer(char *buf, size_t buf_size) = 0; @@ -50,7 +51,8 @@ class CellularInformation { * * @param buf model identification as zero terminated string * @param buf_size max length of model identification is 2048 characters - * @return zero on success, on failure negative error code + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_DEVICE_ERROR on failure */ virtual nsapi_error_t get_model(char *buf, size_t buf_size) = 0; @@ -58,7 +60,8 @@ class CellularInformation { * * @param buf revision identification as zero terminated string * @param buf_size max length of revision identification is 2048 characters - * @return zero on success, on failure negative error code + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_DEVICE_ERROR on failure */ virtual nsapi_error_t get_revision(char *buf, size_t buf_size) = 0; @@ -67,7 +70,9 @@ class CellularInformation { * @param buf serial number as zero terminated string * @param buf_size max length of serial number is 2048 characters * @param type serial number type to read - * @return zero on success, on failure negative error code + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_UNSUPPORTED if the modem does not support SerialNumberType + * NSAPI_ERROR_DEVICE_ERROR on other failures */ enum SerialNumberType { SN = 0, // Serial Number diff --git a/features/cellular/framework/API/CellularNetwork.h b/features/cellular/framework/API/CellularNetwork.h index d84367f696de..fed04d257eb2 100644 --- a/features/cellular/framework/API/CellularNetwork.h +++ b/features/cellular/framework/API/CellularNetwork.h @@ -35,8 +35,7 @@ const int MAX_OPERATOR_NAME_SHORT = 8; * * An abstract interface for connecting to a network and getting information from it. */ -class CellularNetwork : public NetworkInterface -{ +class CellularNetwork : public NetworkInterface { protected: // friend of CellularDevice so that it's the only way to close/delete this class. friend class CellularDevice; @@ -117,18 +116,18 @@ class CellularNetwork : public NetworkInterface }; enum RadioAccessTechnology { - RAT_GSM, - RAT_GSM_COMPACT, - RAT_UTRAN, - RAT_EGPRS, - RAT_HSDPA, - RAT_HSUPA, - RAT_HSDPA_HSUPA, - RAT_E_UTRAN, - RAT_CATM1, - RAT_NB1, - RAT_UNKNOWN - }; + RAT_GSM, + RAT_GSM_COMPACT, + RAT_UTRAN, + RAT_EGPRS, + RAT_HSDPA, + RAT_HSUPA, + RAT_HSDPA_HSUPA, + RAT_E_UTRAN, + RAT_CATM1, + RAT_NB1, + RAT_UNKNOWN + }; // 3GPP TS 27.007 - 7.3 PLMN selection +COPS struct operator_t { @@ -140,13 +139,14 @@ class CellularNetwork : public NetworkInterface }; Status op_status; - char op_long[MAX_OPERATOR_NAME_LONG+1]; - char op_short[MAX_OPERATOR_NAME_SHORT+1]; - char op_num[MAX_OPERATOR_NAME_SHORT+1]; + char op_long[MAX_OPERATOR_NAME_LONG + 1]; + char op_short[MAX_OPERATOR_NAME_SHORT + 1]; + char op_num[MAX_OPERATOR_NAME_SHORT + 1]; RadioAccessTechnology op_rat; operator_t *next; - operator_t() { + operator_t() + { op_status = Unknown; op_rat = RAT_UNKNOWN; next = NULL; @@ -157,14 +157,14 @@ class CellularNetwork : public NetworkInterface /* PDP Context information */ struct pdpcontext_params_t { - char apn[MAX_ACCESSPOINT_NAME_LENGTH+1]; - char local_addr[MAX_IPV6_ADDR_IN_IPV4LIKE_DOTTED_FORMAT+1]; - char local_subnet_mask[MAX_IPV6_ADDR_IN_IPV4LIKE_DOTTED_FORMAT+1]; - char gateway_addr[MAX_IPV6_ADDR_IN_IPV4LIKE_DOTTED_FORMAT+1]; - char dns_primary_addr[MAX_IPV6_ADDR_IN_IPV4LIKE_DOTTED_FORMAT+1]; - char dns_secondary_addr[MAX_IPV6_ADDR_IN_IPV4LIKE_DOTTED_FORMAT+1]; - char p_cscf_prim_addr[MAX_IPV6_ADDR_IN_IPV4LIKE_DOTTED_FORMAT+1]; - char p_cscf_sec_addr[MAX_IPV6_ADDR_IN_IPV4LIKE_DOTTED_FORMAT+1]; + char apn[MAX_ACCESSPOINT_NAME_LENGTH + 1]; + char local_addr[MAX_IPV6_ADDR_IN_IPV4LIKE_DOTTED_FORMAT + 1]; + char local_subnet_mask[MAX_IPV6_ADDR_IN_IPV4LIKE_DOTTED_FORMAT + 1]; + char gateway_addr[MAX_IPV6_ADDR_IN_IPV4LIKE_DOTTED_FORMAT + 1]; + char dns_primary_addr[MAX_IPV6_ADDR_IN_IPV4LIKE_DOTTED_FORMAT + 1]; + char dns_secondary_addr[MAX_IPV6_ADDR_IN_IPV4LIKE_DOTTED_FORMAT + 1]; + char p_cscf_prim_addr[MAX_IPV6_ADDR_IN_IPV4LIKE_DOTTED_FORMAT + 1]; + char p_cscf_sec_addr[MAX_IPV6_ADDR_IN_IPV4LIKE_DOTTED_FORMAT + 1]; int cid; int bearer_id; int im_signalling_flag; @@ -174,9 +174,10 @@ class CellularNetwork : public NetworkInterface int local_addr_ind; int non_ip_mtu; int serving_plmn_rate_control_value; - pdpcontext_params_t* next; + pdpcontext_params_t *next; - pdpcontext_params_t() { + pdpcontext_params_t() + { apn[0] = '\0'; local_addr[0] = '\0'; local_subnet_mask[0] = '\0'; @@ -200,10 +201,11 @@ class CellularNetwork : public NetworkInterface typedef CellularList pdpContextList_t; struct operator_names_t { - char numeric[MAX_OPERATOR_NAME_SHORT+1]; - char alpha[MAX_OPERATOR_NAME_LONG+1]; - operator_names_t* next; - operator_names_t() { + char numeric[MAX_OPERATOR_NAME_SHORT + 1]; + char alpha[MAX_OPERATOR_NAME_LONG + 1]; + operator_names_t *next; + operator_names_t() + { numeric[0] = '\0'; alpha[0] = '\0'; next = NULL; @@ -224,40 +226,47 @@ class CellularNetwork : public NetworkInterface /** Does all the needed initializations that can fail * * @remark must be called immediately after constructor. - * @return zero on success + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_NO_MEMORY on memory failure */ virtual nsapi_error_t init() = 0; /** Request registering to network. * * @param plmn format is in numeric format or 0 for automatic network registration - * @return zero on success + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_DEVICE_ERROR on failure */ virtual nsapi_error_t set_registration(const char *plmn = 0) = 0; /** Get the current network registering mode * - * @param mode on successful return contains the current network registering mode - * @return zero on success + * @param mode on successful return contains the current network registering mode + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_DEVICE_ERROR on failure */ - virtual nsapi_error_t get_network_registering_mode(NWRegisteringMode& mode) = 0; + virtual nsapi_error_t get_network_registering_mode(NWRegisteringMode &mode) = 0; /** Activate/deactivate listening of network events for the given RegistrationType. * This should be called after network class is created and ready to receive AT commands. * After successful call network class starts to get information about network changes like * registration statue, access technology, cell id... * - * @param type RegistrationType to set urc on/off - * @param on Controls are urc' active or not - * @return zero on success + * @param type RegistrationType to set urc on/off + * @param on Controls are urc active or not + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_UNSUPPORTED if the modem does not support RegistrationType + * NSAPI_ERROR_DEVICE_ERROR on failure */ virtual nsapi_error_t set_registration_urc(RegistrationType type, bool on) = 0; /** Gets the network registration status. * - * @param type see RegistrationType values - * @param status see RegistrationStatus values - * @return zero on success + * @param type see RegistrationType values + * @param status see RegistrationStatus values + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_UNSUPPORTED if the modem does not support RegistrationType + * NSAPI_ERROR_DEVICE_ERROR on failure */ virtual nsapi_error_t get_registration_status(RegistrationType type, RegistrationStatus &status) = 0; @@ -266,7 +275,8 @@ class CellularNetwork : public NetworkInterface * @param apn Optional name of the network to connect to * @param username Optional username for the APN * @param password Optional password fot the APN - * @return 0 on success, negative error code on failure + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_NO_MEMORY on memory failure */ virtual nsapi_error_t set_credentials(const char *apn, const char *username = 0, const char *password = 0) = 0; @@ -277,30 +287,34 @@ class CellularNetwork : public NetworkInterface * @param type Authentication type to use * @param username Optional username for the APN * @param password Optional password fot the APN - * @return 0 on success, negative error code on failure + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_NO_MEMORY on memory failure */ virtual nsapi_error_t set_credentials(const char *apn, AuthenticationType type, - const char *username = 0, const char *password = 0) = 0; + const char *username = 0, const char *password = 0) = 0; /** Request attach to network. * * @deprecated Parameter timeout will be deprecated. Use mbed-os/features/cellular/framework/API/CellularDevice.h set_timeout instead. - * @param timeout milliseconds to wait for attach response - * @return zero on success + * @param timeout milliseconds to wait for attach response + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_DEVICE_ERROR on failure */ MBED_DEPRECATED_SINCE("mbed-os-5.9", "Parameter timeout will be deprecated. Use mbed-os/features/cellular/framework/API/CellularDevice.h set_timeout instead.") - virtual nsapi_error_t set_attach(int timeout = 10*1000) = 0; + virtual nsapi_error_t set_attach(int timeout = 10 * 1000) = 0; /** Request attach status from network. * - * @param status see AttachStatus values - * @return zero on success + * @param status see AttachStatus values + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_DEVICE_ERROR on failure */ virtual nsapi_error_t get_attach(AttachStatus &status) = 0; /** Request detach from a network. * - * @return zero on success + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_DEVICE_ERROR on failure */ virtual nsapi_error_t detach() = 0; @@ -310,37 +324,45 @@ class CellularNetwork : public NetworkInterface * @param reports Additional exception reports at maximum rate reached are allowed to be sent [optional] * @param time_unit Uplink time unit with values 0=unrestricted, 1=minute, 2=hour, 3=day, 4=week [optional] * @param uplink_rate Maximum number of messages per timeUnit [optional] - * @return zero on success + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_DEVICE_ERROR on case of failure */ virtual nsapi_error_t get_rate_control(CellularNetwork::RateControlExceptionReports &reports, - CellularNetwork::RateControlUplinkTimeUnit &time_unit, int &uplink_rate) = 0; + CellularNetwork::RateControlUplinkTimeUnit &time_unit, int &uplink_rate) = 0; /** Get backoff timer value * * @param backoff_timer Backoff timer value associated with PDP APN in seconds - * @return zero on success + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_PARAMETER if no access point is set or found when activating context + * NSAPI_ERROR_DEVICE_ERROR on failure */ virtual nsapi_error_t get_apn_backoff_timer(int &backoff_timer) = 0; /** Sets radio access technology. * - * @param rat Radio access technology - * @return zero on success + * @param rat Radio access technology + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_UNSUPPORTED if the given rat is RAT_UNKNOWN or inheriting target class + * has not implemented method set_access_technology_impl(...) + * OR return value of the inheriting target class set_access_technology_impl(...) */ virtual nsapi_error_t set_access_technology(RadioAccessTechnology rat) = 0; /** Get current radio access technology. * - * @param rat Radio access technology - * @return zero on success + * @param rat Radio access technology + * @return NSAPI_ERROR_OK */ - virtual nsapi_error_t get_access_technology(RadioAccessTechnology& rat) = 0; + virtual nsapi_error_t get_access_technology(RadioAccessTechnology &rat) = 0; /** Scans for operators module can reach. * - * @param operators Container of reachable operators and their access technologies - * @param ops_count Number of found operators - * @return zero on success + * @param operators Container of reachable operators and their access technologies + * @param ops_count Number of found operators + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_NO_MEMORY on memory failure + * NSAPI_ERROR_DEVICE_ERROR on other failures */ virtual nsapi_error_t scan_plmn(operList_t &operators, int &ops_count) = 0; @@ -348,7 +370,8 @@ class CellularNetwork : public NetworkInterface * * @param supported_opt Supported CIoT EPS optimizations. * @param preferred_opt Preferred CIoT EPS optimizations. - * @return zero on success + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_DEVICE_ERROR on failure */ virtual nsapi_error_t set_ciot_optimization_config(Supported_UE_Opt supported_opt, Preferred_UE_Opt preferred_opt) = 0; @@ -357,14 +380,20 @@ class CellularNetwork : public NetworkInterface * * @param supported_opt Supported CIoT EPS optimizations. * @param preferred_opt Preferred CIoT EPS optimizations. - * @return zero on success + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_DEVICE_ERROR on failure */ - virtual nsapi_error_t get_ciot_optimization_config(Supported_UE_Opt& supported_opt, - Preferred_UE_Opt& preferred_opt) = 0; + virtual nsapi_error_t get_ciot_optimization_config(Supported_UE_Opt &supported_opt, + Preferred_UE_Opt &preferred_opt) = 0; /** Start the interface. Attempts to connect to a cellular network. * - * @return 0 on success, negative error code on failure + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_NO_CONNECTION if fails to find suitable context to activate or activation failed (if not already activated) + * NSAPI_ERROR_UNSUPPORTED if NetworkStack was not found + * NSAPI_ERROR_AUTH_FAILURE if password and username were provided and authentication to network failed + * Also if PPP mode + * NSAPI_ERROR_DEVICE_ERROR on failure and check more error from nsapi_ppp_connect(...) */ virtual nsapi_error_t connect() = 0; @@ -373,7 +402,13 @@ class CellularNetwork : public NetworkInterface * @param apn Optional name of the network to connect to * @param username Optional username for your APN * @param password Optional password for your APN - * @return 0 on success, negative error code on failure + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_NO_CONNECTION if fails to find suitable context to activate or activation failed (if not already activated) + * NSAPI_ERROR_UNSUPPORTED if NetworkStack was not found + * NSAPI_ERROR_AUTH_FAILURE if password and username were provided and authentication to network failed + * NSAPI_ERROR_NO_MEMORY on memory failure + * Also if PPP mode + * NSAPI_ERROR_DEVICE_ERROR on failure and check more error from nsapi_ppp_connect(...) */ virtual nsapi_error_t connect(const char *apn, const char *username = 0, const char *password = 0) = 0; @@ -381,7 +416,10 @@ class CellularNetwork : public NetworkInterface /** Finds the correct PDP context and activates it. If correct PDP context is not found, one is created. * Given APN (or not given) and stack type (IPv4/IPv6/dual) are influencing when finding the PDP context. * - * @return zero on success + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_NO_CONNECTION if fails to find suitable context to activate or activation failed (if not already activated) + * NSAPI_ERROR_UNSUPPORTED if NetworkStack was not found + * NSAPI_ERROR_AUTH_FAILURE if password and username were provided and authentication to network failed */ virtual nsapi_error_t activate_context() = 0; @@ -390,7 +428,8 @@ class CellularNetwork : public NetworkInterface * * @param stack_type the stack type to be used. * - * @return NSAPI_ERROR_OK on success + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_PARAMETER if modem does not support the given stack_type */ virtual nsapi_error_t set_stack_type(nsapi_ip_stack_t stack_type) = 0; @@ -404,35 +443,39 @@ class CellularNetwork : public NetworkInterface /** Get the relevant information for an active non secondary PDP context. * * @remark optional params are not updated if not received from network. - * @param params_list reference to linked list which is filled on successful call - * @return 0 on success, negative error code on failure + * @param params_list reference to linked list, which is filled on successful call + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_NO_MEMORY on memory failure + * NSAPI_ERROR_DEVICE_ERROR on other failures */ - virtual nsapi_error_t get_pdpcontext_params(pdpContextList_t& params_list) = 0; + virtual nsapi_error_t get_pdpcontext_params(pdpContextList_t ¶ms_list) = 0; /** Get extended signal quality parameters. * - * @param rxlev signal strength level - * @param ber bit error rate - * @param rscp signal code power - * @param ecno ratio of the received energy per PN chip to the total received power spectral density - * @param rsrq signal received quality - * @param rsrp signal received power - * @return NSAPI_ERROR_OK on success, negative error code on failure + * @param rxlev signal strength level + * @param ber bit error rate + * @param rscp signal code power + * @param ecno ratio of the received energy per PN chip to the total received power spectral density + * @param rsrq signal received quality + * @param rsrp signal received power + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_DEVICE_ERROR on other failures */ virtual nsapi_error_t get_extended_signal_quality(int &rxlev, int &ber, int &rscp, int &ecno, int &rsrq, int &rsrp) = 0; /** Get signal quality parameters. * - * @param rssi signal strength level - * @param ber bit error rate - * @return NSAPI_ERROR_OK on success, negative error code on failure + * @param rssi signal strength level + * @param ber bit error rate + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_DEVICE_ERROR on other failures */ virtual nsapi_error_t get_signal_quality(int &rssi, int &ber) = 0; /** Get cell id. * - * @param cell_id cell id - * @return NSAPI_ERROR_OK on success, negative error code on failure + * @param cell_id cell ID + * @return NSAPI_ERROR_OK */ virtual nsapi_error_t get_cell_id(int &cell_id) = 0; @@ -443,9 +486,10 @@ class CellularNetwork : public NetworkInterface /** Get the operator parameters. * - * @param format format of the operator field - * @param operator_params applicable operator param fields filled - * @return NSAPI_ERROR_OK on success, negative error code on failure + * @param format format of the operator field + * @param operator_params applicable operator param fields filled + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_DEVICE_ERROR on case of other failures */ virtual nsapi_error_t get_operator_params(int &format, operator_t &operator_params) = 0; @@ -468,14 +512,17 @@ class CellularNetwork : public NetworkInterface /** Set blocking status of connect() which by default should be blocking * * @param blocking true if connect is blocking - * @return 0 on success, negative error code on failure + * @return NSAPI_ERROR_OK + * if PPP mode check errors from nsapi_ppp_set_blocking(...) */ virtual nsapi_error_t set_blocking(bool blocking) = 0; /** Read operator names * - * @param op_names on successful return will contain linked list of operator names. - * @return zero on success + * @param op_names on successful return contains linked list of operator names. + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_NO_MEMORY on memory failure + * NSAPI_ERROR_DEVICE_ERROR on other failures */ virtual nsapi_error_t get_operator_names(operator_names_list &op_names) = 0; }; diff --git a/features/cellular/framework/API/CellularPower.h b/features/cellular/framework/API/CellularPower.h index b72470e3653f..8fea860fd4f8 100644 --- a/features/cellular/framework/API/CellularPower.h +++ b/features/cellular/framework/API/CellularPower.h @@ -20,16 +20,14 @@ #include "nsapi_types.h" #include "Callback.h" -namespace mbed -{ +namespace mbed { /** * Class CellularPower * * An interface that provides power handling functions for modem/module. */ -class CellularPower -{ +class CellularPower { protected: // friend of CellularDevice so that it's the only way to close/delete this class. friend class CellularDevice; @@ -55,7 +53,8 @@ class CellularPower * * @remark set_at_mode must be called to initialise modem * - * @return zero on success + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_UNSUPPORTED if not overridden by the target modem */ virtual nsapi_error_t on() = 0; @@ -63,8 +62,8 @@ class CellularPower * Device power on/off is modem/board specific behavior and must be done on inherited class if needed. * Power off is done by toggling power pin/button. * - * - * @return zero on success + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_UNSUPPORTED if not overridden by the target modem */ virtual nsapi_error_t off() = 0; @@ -72,7 +71,8 @@ class CellularPower * * @remark must be called after power on to prepare correct AT mode * - * @return zero on success + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_DEVICE_ERROR on failure */ virtual nsapi_error_t set_at_mode() = 0; @@ -90,23 +90,27 @@ class CellularPower * * @remark See 3GPP TS 27.007 CFUN for more details * - * @return zero on success + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_DEVICE_ERROR on failure */ virtual nsapi_error_t set_power_level(int func_level, int do_reset = 0) = 0; /** Reset and wake-up cellular device. * - * @return zero on success + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_DEVICE_ERROR on failure */ virtual nsapi_error_t reset() = 0; - /** Opt for power save setting on cellular device. If both parameters are zero then disables PSM. + /** Opt for power save setting on cellular device. If both parameters are zero, this disables PSM. * * @remark See 3GPP TS 27.007 PSM for details * * @param periodic_time Timeout in seconds IoT subsystem is not expecting messaging * @param active_time Timeout in seconds IoT subsystem waits for response - * @return zero on success + * + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_DEVICE_ERROR on failure */ virtual nsapi_error_t opt_power_save_mode(int periodic_time, int active_time) = 0; @@ -118,13 +122,15 @@ class CellularPower * @param act_type type of access technology * @param edrx_value requested edxr value. Extended DRX parameters information element. * - * @return zero on success + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_DEVICE_ERROR on failure */ virtual nsapi_error_t opt_receive_period(int mode, EDRXAccessTechnology act_type, uint8_t edrx_value) = 0; /** Check whether the device is ready to accept commands. * - * @return zero on success + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_DEVICE_ERROR on failure */ virtual nsapi_error_t is_device_ready() = 0; @@ -133,7 +139,10 @@ class CellularPower * for using at commands and possible sim. * * @param callback Callback function called when urc received - * @return zero on success + * + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_NO_MEMORY on memory failure + * NSAPI_ERROR_UNSUPPORTED if not overridden by the target modem */ virtual nsapi_error_t set_device_ready_urc_cb(mbed::Callback callback) = 0; diff --git a/features/cellular/framework/API/CellularSIM.h b/features/cellular/framework/API/CellularSIM.h index 238782fba6b3..13ff7d37009d 100644 --- a/features/cellular/framework/API/CellularSIM.h +++ b/features/cellular/framework/API/CellularSIM.h @@ -54,30 +54,34 @@ class CellularSIM { /** Open the SIM card by setting the pin code for SIM. * * @param sim_pin PIN for the SIM card - * @return zero on success + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_DEVICE_ERROR on failure */ virtual nsapi_error_t set_pin(const char *sim_pin) = 0; - /** Change sim pin code. + /** Change SIM pin code. * - * @param sim_pin Current PIN for sim - * @param new_pin New PIN for sim - * @return zero on success + * @param sim_pin Current PIN for SIM + * @param new_pin New PIN for SIM + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_DEVICE_ERROR on failure */ virtual nsapi_error_t change_pin(const char *sim_pin, const char *new_pin) = 0; /** Change is pin query needed after boot * * @param sim_pin Valid PIN for SIM card - * @param query_pin False is PIN query not needed, True if PIN query needed after boot. - * @return zero on success + * @param query_pin False if PIN query not needed, True if PIN query needed after boot. + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_DEVICE_ERROR on failure */ virtual nsapi_error_t set_pin_query(const char *sim_pin, bool query_pin) = 0; - /** Get sim card's state + /** Get SIM card's state * * @param state current state of SIM - * @return zero on success + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_DEVICE_ERROR on failure */ virtual nsapi_error_t get_sim_state(SimState &state) = 0; @@ -85,7 +89,9 @@ class CellularSIM { * @remark Given imsi buffer length must be 16 or more as imsi max length is 15! * * @param imsi preallocated char* which after successful request contains imsi - * @return zero on success + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_PARAMETER if imsi if null + * NSAPI_ERROR_DEVICE_ERROR on other failures */ virtual nsapi_error_t get_imsi(char *imsi) = 0; @@ -93,7 +99,8 @@ class CellularSIM { * * @param buf SIM ICCID as zero terminated string * @param buf_size max length of SIM ICCID is MAX_ICCID_LENGTH - * @return zero on success, on failure negative error code + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_DEVICE_ERROR on failure */ virtual nsapi_error_t get_iccid(char *buf, size_t buf_size) = 0; }; diff --git a/features/cellular/framework/API/CellularSMS.h b/features/cellular/framework/API/CellularSMS.h index 35dbfc3c9cd5..3d91635b58b6 100644 --- a/features/cellular/framework/API/CellularSMS.h +++ b/features/cellular/framework/API/CellularSMS.h @@ -40,8 +40,7 @@ const int SMS_ERROR_MULTIPART_ALL_PARTS_NOT_READ = -5001; * * An abstract interface for SMS sending, reading and deleting. */ -class CellularSMS -{ +class CellularSMS { protected: // friend of CellularDevice so that it's the only way to close/delete this class. friend class CellularDevice; @@ -58,44 +57,53 @@ class CellularSMS CellularSMSMmodeText }; - /** Does all the necessary initializations needed for receiving and sending sms. + /** Does all the necessary initializations needed for receiving and sending SMS. * * @param mode enumeration for choosing the correct mode: text/pdu - * @return zero on success + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_NO_MEMORY on memory failure + * NSAPI_ERROR_DEVICE_ERROR on other failures */ virtual nsapi_error_t initialize(CellularSMSMmode mode) = 0; /** Send the SMS with the given parameters * - * @param phone_number Phone number where to send sms + * @param phone_number Phone number where to send SMS * @param message SMS message content * @param msg_len Length of the message - * @return possible error code or length of the sent sms + * @return On success, length of the sent SMS (positive value) + * NSAPI_ERROR_PARAMETER if invalid parameters + * NSAPI_ERROR_NO_MEMORY on memory failure + * NSAPI_ERROR_DEVICE_ERROR on other failures */ - virtual nsapi_size_or_error_t send_sms(const char* phone_number, const char* message, int msg_len) = 0; + virtual nsapi_size_or_error_t send_sms(const char *phone_number, const char *message, int msg_len) = 0; /** Gets the oldest received sms. * - * @param buf preallocated buffer for sms message content + * @param buf preallocated buffer for SMS message content * @param buf_len length of allocated buf - * @param phone_num preallocated buffer for phone number where sms was sent + * @param phone_num preallocated buffer for phone number where SMS was sent * @param phone_len length of allocated phone_num buffer * @param time_stamp preallocated buffer for TP-Service Centre Time Stamp (format: yy/MM/dd,hh:mm:ss-+zz). +-zz is timezone. * The unit of time zone is a quarter of an hour relative to GMT. For example +32 would be GMT+8. * @param time_len length of allocated time_stamp buffer - * @param buf_size if method return error NSAPI_ERROR_NO_MEMORY because the given buf was not big enough this will - * hold the size which is enough. Otherwise zero. - * @return possible error code or size of buf. Will return SMS_ERROR_MULTIPART_ALL_PARTS_NOT_READ - * if sms was multipart but not all parts are present/failed to read. + * @param buf_size if method return error NSAPI_ERROR_NO_MEMORY because the given buf was not big enough, this + * holds the size which is enough. Otherwise zero. + * @return On success, length of the received SMS, (length of the buf, positive value) + * NSAPI_ERROR_PARAMETER if invalid parameters + * NSAPI_ERROR_NO_MEMORY on memory failure + * SMS_ERROR_MULTIPART_ALL_PARTS_NOT_READ if SMS was multipart but not all parts are present/failed to read. + * -1 if no SMS was found + * NSAPI_ERROR_DEVICE_ERROR on other failures */ - virtual nsapi_size_or_error_t get_sms(char* buf, uint16_t buf_len, char* phone_num, uint16_t phone_len, - char* time_stamp, uint16_t time_len, int *buf_size) = 0; + virtual nsapi_size_or_error_t get_sms(char *buf, uint16_t buf_len, char *phone_num, uint16_t phone_len, + char *time_stamp, uint16_t time_len, int *buf_size) = 0; - /** Callback which is called when new sms is received. SMS can be fetched via method get_sms(). + /** Callback that is called when new SMS is received. SMS can be fetched using method get_sms(). * - * @remark In PDU mode there can be multipart sms and callback is called for every received part. + * @remark In PDU mode, there can be multipart SMS, and callback is called for every received part. * - * @param func Callback function which is called when new sms is received. + * @param func Callback function that is called when new SMS is received. */ virtual void set_sms_callback(Callback func) = 0; @@ -111,7 +119,8 @@ class CellularSMS * "SM" - SIM SMS memory storage (default) * "ME" - NVM SMS storage * - * @return 1 for success, 0 for failure + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_DEVICE_ERROR on failure */ virtual nsapi_error_t set_cpms(const char *memr, const char *memw, const char *mems) = 0; @@ -120,7 +129,8 @@ class CellularSMS * @param sca Service Center Address to be used for mobile originated SMS transmissions. * @param type 129 - national numbering scheme, 145 - international numbering scheme (contains the character "+") * - * @return 1 for success, 0 for failure + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_DEVICE_ERROR on failure */ virtual nsapi_error_t set_csca(const char *sca, int type) = 0; @@ -128,22 +138,24 @@ class CellularSMS * * @remark Current implementation support only ASCII so choose the correct character set. * - * @param chr_set preferred character set list (comma separated). Modem might not support the wanted character set + * @param chr_set preferred character set list (comma separated). Modem might not support the wanted character set, * so chr_set list is looped from start until supported set is found. Used character set index is returned. * See more from 3GPP TS 27.005. - * @return Used character set index from the given list in case of success. Otherwise negative errorcode. + * @return Used character set index from the given list in case of success. + * NSAPI_ERROR_DEVICE_ERROR on failure */ virtual nsapi_size_or_error_t set_cscs(const char *chr_set) = 0; /** Deletes all messages from the currently set memory/SIM * - * @return possible error code + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_DEVICE_ERROR on failure */ virtual nsapi_error_t delete_all_messages() = 0; - /** Some modems need extra time between AT commands and responses or there will be error -314, SIM busy. - * If SIM busy errors are an issue this time should be increased. It can also be set to zero to make - * operations faster and more energy efficient if no errors will follow. By default wait time is zero. + /** Some modems need extra time between AT commands and responses, or there will be error -314, SIM busy. + * If SIM busy errors are an issue, this time should be increased. It can also be set to zero to make + * operations faster and more energy efficient if no errors will follow. By default, wait time is zero. * * @param sim_wait_time */ diff --git a/features/cellular/framework/AT/ATHandler.cpp b/features/cellular/framework/AT/ATHandler.cpp index eaba46dfdc3b..b52cece0bbbd 100644 --- a/features/cellular/framework/AT/ATHandler.cpp +++ b/features/cellular/framework/AT/ATHandler.cpp @@ -1013,8 +1013,8 @@ void ATHandler::set_string(char *dest, const char *src, size_t src_len) const char *ATHandler::mem_str(const char *dest, size_t dest_len, const char *src, size_t src_len) { if (dest_len > src_len) { - for(size_t i = 0; i < dest_len - src_len + 1; ++i) { - if(memcmp(dest + i, src, src_len) == 0) { + for (size_t i = 0; i < dest_len - src_len + 1; ++i) { + if (memcmp(dest + i, src, src_len) == 0) { return dest + i; } } diff --git a/features/cellular/framework/AT/ATHandler.h b/features/cellular/framework/AT/ATHandler.h index 6ae417a3d683..17bb4d33a6c0 100644 --- a/features/cellular/framework/AT/ATHandler.h +++ b/features/cellular/framework/AT/ATHandler.h @@ -75,7 +75,7 @@ class ATHandler { * @param send_delay the minimum delay in ms between the end of last response and the beginning of a new command */ ATHandler(FileHandle *fh, events::EventQueue &queue, int timeout, const char *output_delimiter, uint16_t send_delay = 0); - ~ATHandler(); + virtual ~ATHandler(); /** Return used file handle. * @@ -226,7 +226,7 @@ class ATHandler { * * @param cmd AT command to be written to modem */ - void cmd_start(const char *cmd); + virtual void cmd_start(const char *cmd); /** Writes integer type AT command subparameter. Starts with the delimiter if not the first param after cmd_start. * In case of failure when writing, the last error is set to NSAPI_ERROR_DEVICE_ERROR. diff --git a/features/cellular/framework/AT/AT_CellularDevice.cpp b/features/cellular/framework/AT/AT_CellularDevice.cpp index f1c7874b45fe..0d8477e2735a 100644 --- a/features/cellular/framework/AT/AT_CellularDevice.cpp +++ b/features/cellular/framework/AT/AT_CellularDevice.cpp @@ -246,3 +246,8 @@ NetworkStack *AT_CellularDevice::get_stack() } return _network->get_stack(); } + +nsapi_error_t AT_CellularDevice::init_module(FileHandle *fh) +{ + return NSAPI_ERROR_OK; +} diff --git a/features/cellular/framework/AT/AT_CellularDevice.h b/features/cellular/framework/AT/AT_CellularDevice.h index 25616697f1cb..1a5bea3f5573 100644 --- a/features/cellular/framework/AT/AT_CellularDevice.h +++ b/features/cellular/framework/AT/AT_CellularDevice.h @@ -28,8 +28,7 @@ #include "ATHandler.h" -namespace mbed -{ +namespace mbed { /** * Class AT_CellularDevice @@ -37,8 +36,7 @@ namespace mbed * A class defines opening and closing of cellular interfaces. * Deleting/Closing of opened interfaces can be done only through this class. */ -class AT_CellularDevice : public CellularDevice -{ +class AT_CellularDevice : public CellularDevice { public: AT_CellularDevice(events::EventQueue &queue); virtual ~AT_CellularDevice(); @@ -52,7 +50,7 @@ class AT_CellularDevice : public CellularDevice * * @param at_handler */ - void release_at_handler(ATHandler* at_handler); + void release_at_handler(ATHandler *at_handler); public: // CellularDevice virtual CellularNetwork *open_network(FileHandle *fh); @@ -83,12 +81,14 @@ class AT_CellularDevice : public CellularDevice virtual NetworkStack *get_stack(); + virtual nsapi_error_t init_module(FileHandle *fh); + protected: AT_CellularNetwork *_network; AT_CellularSMS *_sms; AT_CellularSIM *_sim; - AT_CellularPower* _power; - AT_CellularInformation* _information; + AT_CellularPower *_power; + AT_CellularInformation *_information; protected: events::EventQueue &_queue; diff --git a/features/cellular/framework/AT/AT_CellularNetwork.cpp b/features/cellular/framework/AT/AT_CellularNetwork.cpp index 02a2d08c4f08..22dc766b1d7b 100644 --- a/features/cellular/framework/AT/AT_CellularNetwork.cpp +++ b/features/cellular/framework/AT/AT_CellularNetwork.cpp @@ -195,7 +195,7 @@ void AT_CellularNetwork::urc_cgreg() } nsapi_error_t AT_CellularNetwork::set_credentials(const char *apn, - const char *username, const char *password) + const char *username, const char *password) { free_credentials(); @@ -231,7 +231,7 @@ nsapi_error_t AT_CellularNetwork::set_credentials(const char *apn, } nsapi_error_t AT_CellularNetwork::set_credentials(const char *apn, - AuthenticationType type, const char *username, const char *password) + AuthenticationType type, const char *username, const char *password) { nsapi_error_t err = set_credentials(apn, username, password); if (err) { @@ -244,7 +244,7 @@ nsapi_error_t AT_CellularNetwork::set_credentials(const char *apn, } nsapi_error_t AT_CellularNetwork::connect(const char *apn, - const char *username, const char *password) + const char *username, const char *password) { nsapi_error_t err = set_credentials(apn, username, password); if (err) { @@ -1012,7 +1012,7 @@ nsapi_error_t AT_CellularNetwork::scan_plmn(operList_t &operators, int &opsCount } nsapi_error_t AT_CellularNetwork::set_ciot_optimization_config(Supported_UE_Opt supported_opt, - Preferred_UE_Opt preferred_opt) + Preferred_UE_Opt preferred_opt) { _at.lock(); @@ -1029,7 +1029,7 @@ nsapi_error_t AT_CellularNetwork::set_ciot_optimization_config(Supported_UE_Opt } nsapi_error_t AT_CellularNetwork::get_ciot_optimization_config(Supported_UE_Opt &supported_opt, - Preferred_UE_Opt &preferred_opt) + Preferred_UE_Opt &preferred_opt) { _at.lock(); diff --git a/features/cellular/framework/AT/AT_CellularNetwork.h b/features/cellular/framework/AT/AT_CellularNetwork.h index 51d18178165f..575b529e9db8 100644 --- a/features/cellular/framework/AT/AT_CellularNetwork.h +++ b/features/cellular/framework/AT/AT_CellularNetwork.h @@ -31,8 +31,7 @@ namespace mbed { * * Class for connecting to a network and getting information from it. */ -class AT_CellularNetwork : public CellularNetwork, public AT_CellularBase -{ +class AT_CellularNetwork : public CellularNetwork, public AT_CellularBase { public: @@ -47,7 +46,7 @@ class AT_CellularNetwork : public CellularNetwork, public AT_CellularBase const char *username = 0, const char *password = 0); virtual nsapi_error_t set_credentials(const char *apn, AuthenticationType type, - const char *username = 0, const char *password = 0); + const char *username = 0, const char *password = 0); virtual nsapi_error_t connect(const char *apn, const char *username = 0, const char *password = 0); @@ -66,18 +65,18 @@ class AT_CellularNetwork : public CellularNetwork, public AT_CellularBase virtual nsapi_error_t set_registration(const char *plmn = 0); - virtual nsapi_error_t get_network_registering_mode(NWRegisteringMode& mode); + virtual nsapi_error_t get_network_registering_mode(NWRegisteringMode &mode); virtual nsapi_error_t get_registration_status(RegistrationType type, RegistrationStatus &status); - virtual nsapi_error_t set_attach(int timeout = 10*1000); + virtual nsapi_error_t set_attach(int timeout = 10 * 1000); virtual nsapi_error_t get_attach(AttachStatus &status); virtual nsapi_error_t detach(); virtual nsapi_error_t get_rate_control(CellularNetwork::RateControlExceptionReports &reports, - CellularNetwork::RateControlUplinkTimeUnit &time_unit, int &uplink_rate); + CellularNetwork::RateControlUplinkTimeUnit &time_unit, int &uplink_rate); virtual nsapi_error_t get_apn_backoff_timer(int &backoff_timer); @@ -90,21 +89,21 @@ class AT_CellularNetwork : public CellularNetwork, public AT_CellularBase virtual const char *get_ip_address(); virtual nsapi_error_t set_access_technology(RadioAccessTechnology rat); - virtual nsapi_error_t get_access_technology(RadioAccessTechnology& rat); + virtual nsapi_error_t get_access_technology(RadioAccessTechnology &rat); virtual nsapi_error_t scan_plmn(operList_t &operators, int &ops_count); virtual nsapi_error_t set_ciot_optimization_config(Supported_UE_Opt supported_opt, Preferred_UE_Opt preferred_opt); - virtual nsapi_error_t get_ciot_optimization_config(Supported_UE_Opt& supported_opt, - Preferred_UE_Opt& preferred_opt); + virtual nsapi_error_t get_ciot_optimization_config(Supported_UE_Opt &supported_opt, + Preferred_UE_Opt &preferred_opt); virtual nsapi_error_t set_stack_type(nsapi_ip_stack_t stack_type); virtual nsapi_ip_stack_t get_stack_type(); - virtual nsapi_error_t get_pdpcontext_params(pdpContextList_t& params_list); + virtual nsapi_error_t get_pdpcontext_params(pdpContextList_t ¶ms_list); virtual nsapi_error_t get_extended_signal_quality(int &rxlev, int &ber, int &rscp, int &ecno, int &rsrq, int &rsrp); @@ -151,7 +150,7 @@ class AT_CellularNetwork : public CellularNetwork, public AT_CellularBase void urc_cgreg(); void urc_cgev(); - nsapi_ip_stack_t string_to_stack_type(const char* pdp_type); + nsapi_ip_stack_t string_to_stack_type(const char *pdp_type); void free_credentials(); diff --git a/features/cellular/framework/AT/AT_CellularPower.cpp b/features/cellular/framework/AT/AT_CellularPower.cpp index 2850b9903b9b..7a30c6053929 100644 --- a/features/cellular/framework/AT/AT_CellularPower.cpp +++ b/features/cellular/framework/AT/AT_CellularPower.cpp @@ -112,34 +112,34 @@ nsapi_error_t AT_CellularPower::opt_power_save_mode(int periodic_time, int activ 1 1 0 value is incremented in multiples of 320 hours (NOTE 1) 1 1 1 value indicates that the timer is deactivated (NOTE 2). */ - char pt[8+1];// timer value encoded as 3GPP IE + char pt[8 + 1]; // timer value encoded as 3GPP IE const int ie_value_max = 0x1f; uint32_t periodic_timer = 0; - if (periodic_time <= 2*ie_value_max) { // multiples of 2 seconds - periodic_timer = periodic_time/2; + if (periodic_time <= 2 * ie_value_max) { // multiples of 2 seconds + periodic_timer = periodic_time / 2; strcpy(pt, "01100000"); } else { - if (periodic_time <= 30*ie_value_max) { // multiples of 30 seconds - periodic_timer = periodic_time/30; + if (periodic_time <= 30 * ie_value_max) { // multiples of 30 seconds + periodic_timer = periodic_time / 30; strcpy(pt, "10000000"); } else { - if (periodic_time <= 60*ie_value_max) { // multiples of 1 minute - periodic_timer = periodic_time/60; + if (periodic_time <= 60 * ie_value_max) { // multiples of 1 minute + periodic_timer = periodic_time / 60; strcpy(pt, "10100000"); } else { - if (periodic_time <= 10*60*ie_value_max) { // multiples of 10 minutes - periodic_timer = periodic_time/(10*60); + if (periodic_time <= 10 * 60 * ie_value_max) { // multiples of 10 minutes + periodic_timer = periodic_time / (10 * 60); strcpy(pt, "00000000"); } else { - if (periodic_time <= 60*60*ie_value_max) { // multiples of 1 hour - periodic_timer = periodic_time/(60*60); + if (periodic_time <= 60 * 60 * ie_value_max) { // multiples of 1 hour + periodic_timer = periodic_time / (60 * 60); strcpy(pt, "00100000"); } else { - if (periodic_time <= 10*60*60*ie_value_max) { // multiples of 10 hours - periodic_timer = periodic_time/(10*60*60); + if (periodic_time <= 10 * 60 * 60 * ie_value_max) { // multiples of 10 hours + periodic_timer = periodic_time / (10 * 60 * 60); strcpy(pt, "01000000"); } else { // multiples of 320 hours - int t = periodic_time / (320*60*60); + int t = periodic_time / (320 * 60 * 60); if (t > ie_value_max) { t = ie_value_max; } @@ -152,7 +152,7 @@ nsapi_error_t AT_CellularPower::opt_power_save_mode(int periodic_time, int activ } } - uint_to_binary_str(periodic_timer, &pt[3], sizeof(pt)-3, PSMTimerBits); + uint_to_binary_str(periodic_timer, &pt[3], sizeof(pt) - 3, PSMTimerBits); pt[8] = '\0'; /** @@ -170,17 +170,17 @@ nsapi_error_t AT_CellularPower::opt_power_save_mode(int periodic_time, int activ Other values shall be interpreted as multiples of 1 minute in this version of the protocol. */ - char at[8+1]; + char at[8 + 1]; uint32_t active_timer; // timer value encoded as 3GPP IE - if (active_time <= 2*ie_value_max) { // multiples of 2 seconds - active_timer = active_time/2; + if (active_time <= 2 * ie_value_max) { // multiples of 2 seconds + active_timer = active_time / 2; strcpy(at, "00000000"); } else { - if (active_time <= 60*ie_value_max) { // multiples of 1 minute - active_timer = (1<<5) | (active_time/60); + if (active_time <= 60 * ie_value_max) { // multiples of 1 minute + active_timer = (1 << 5) | (active_time / 60); strcpy(at, "00100000"); } else { // multiples of decihours - int t = active_time / (6*60); + int t = active_time / (6 * 60); if (t > ie_value_max) { t = ie_value_max; } @@ -189,7 +189,7 @@ nsapi_error_t AT_CellularPower::opt_power_save_mode(int periodic_time, int activ } } - uint_to_binary_str(active_timer, &at[3], sizeof(at)-3, PSMTimerBits); + uint_to_binary_str(active_timer, &at[3], sizeof(at) - 3, PSMTimerBits); pt[8] = '\0'; // request for both GPRS and LTE diff --git a/features/cellular/framework/AT/AT_CellularPower.h b/features/cellular/framework/AT/AT_CellularPower.h index eb4b2e9ab996..4e27abe5b459 100644 --- a/features/cellular/framework/AT/AT_CellularPower.h +++ b/features/cellular/framework/AT/AT_CellularPower.h @@ -28,8 +28,7 @@ namespace mbed { * * Class that provides power handling functions for modem/module. */ -class AT_CellularPower : public CellularPower, public AT_CellularBase -{ +class AT_CellularPower : public CellularPower, public AT_CellularBase { public: AT_CellularPower(ATHandler &atHandler); virtual ~AT_CellularPower(); diff --git a/features/cellular/framework/AT/AT_CellularSMS.cpp b/features/cellular/framework/AT/AT_CellularSMS.cpp index c905a4b2e294..7605566cbb3c 100644 --- a/features/cellular/framework/AT/AT_CellularSMS.cpp +++ b/features/cellular/framework/AT/AT_CellularSMS.cpp @@ -172,10 +172,10 @@ static const int gsm_to_ascii[] = { 224 // 127 }; -const int GSM_TO_ASCII_TABLE_SIZE = sizeof(gsm_to_ascii)/sizeof(gsm_to_ascii[0]); +const int GSM_TO_ASCII_TABLE_SIZE = sizeof(gsm_to_ascii) / sizeof(gsm_to_ascii[0]); AT_CellularSMS::AT_CellularSMS(ATHandler &at) : AT_CellularBase(at), _cb(0), _mode(CellularSMSMmodeText), - _use_8bit_encoding(false), _sim_wait_time(0), _sms_message_ref_number(1), _sms_info(NULL) + _use_8bit_encoding(false), _sim_wait_time(0), _sms_message_ref_number(1), _sms_info(NULL) { } @@ -281,14 +281,14 @@ void AT_CellularSMS::set_extra_sim_wait_time(int sim_wait_time) _sim_wait_time = sim_wait_time; } -char* AT_CellularSMS::create_pdu(const char* phone_number, const char* message, uint8_t message_length, uint8_t msg_parts, - uint8_t msg_part_number, uint8_t& header_size) +char *AT_CellularSMS::create_pdu(const char *phone_number, const char *message, uint8_t message_length, uint8_t msg_parts, + uint8_t msg_part_number, uint8_t &header_size) { int totalPDULength = 0; int number_len = strlen(phone_number); totalPDULength += number_len; - if (number_len&0x01) {// if phone number length is not even length we must pad it and so +1 + if (number_len & 0x01) { // if phone number length is not even length we must pad it and so +1 totalPDULength += 1; } @@ -297,12 +297,12 @@ char* AT_CellularSMS::create_pdu(const char* phone_number, const char* message, totalPDULength += 12; } // there might be need for padding so some more space - totalPDULength +=2; + totalPDULength += 2; // message 7-bit padded and it will be converted to hex so it will take twice as much space - totalPDULength += (message_length - (message_length/8))*2; + totalPDULength += (message_length - (message_length / 8)) * 2; - char* pdu = (char*)calloc(totalPDULength, sizeof(char)); + char *pdu = (char *)calloc(totalPDULength, sizeof(char)); if (!pdu) { return NULL; } @@ -324,8 +324,8 @@ char* AT_CellularSMS::create_pdu(const char* phone_number, const char* message, pdu[x++] = '0'; pdu[x++] = '0'; // [6] and [7] Length of the Destination Phone Number - int_to_hex_str(number_len, pdu+x); - x+=2; + int_to_hex_str(number_len, pdu + x); + x += 2; // Type of the Destination Phone Number pdu[x++] = '8'; pdu[x++] = '1'; @@ -333,10 +333,10 @@ char* AT_CellularSMS::create_pdu(const char* phone_number, const char* message, // phone number as reverse nibble encoded int i = 0; for (; i < number_len; i += 2) { - if (i+1 == number_len) { + if (i + 1 == number_len) { pdu[x++] = 'f'; } else { - pdu[x++] = phone_number[i+1]; + pdu[x++] = phone_number[i + 1]; } pdu[x++] = phone_number[i]; } @@ -356,7 +356,7 @@ char* AT_CellularSMS::create_pdu(const char* phone_number, const char* message, uint8_t udhlen = 0; // Length can be update after we have created PDU, store position for later use. int lengthPos = x; - x +=2; + x += 2; int paddingBits = 0; if (msg_parts > 1) { // concatenated, must use UDH @@ -371,17 +371,17 @@ char* AT_CellularSMS::create_pdu(const char* phone_number, const char* message, pdu[x++] = '0'; pdu[x++] = '3'; // A reference number (must be the same for all parts of the same larger messages) - int_to_hex_str(_sms_message_ref_number&0xFF, pdu+x); - x +=2; + int_to_hex_str(_sms_message_ref_number & 0xFF, pdu + x); + x += 2; // How many parts does this message have? - int_to_hex_str(msg_parts, pdu+x); - x +=2; + int_to_hex_str(msg_parts, pdu + x); + x += 2; // this is a part number - int_to_hex_str(msg_part_number, pdu+x); - x +=2; + int_to_hex_str(msg_part_number, pdu + x); + x += 2; // if there is padding bits then udhlen is octet bigger as we need to keep septet boundary - paddingBits = (udhlen * 8 ) % 7; + paddingBits = (udhlen * 8) % 7; if (paddingBits) { paddingBits = 7 - paddingBits; udhlen += 1; @@ -389,11 +389,11 @@ char* AT_CellularSMS::create_pdu(const char* phone_number, const char* message, } if (_use_8bit_encoding) { - char_str_to_hex_str(message, message_length, pdu+x); + char_str_to_hex_str(message, message_length, pdu + x); } else { // we might need to send zero length sms if (message_length) { - if (pack_7_bit_gsm_and_hex(message, message_length, pdu+x, paddingBits) == 0) { + if (pack_7_bit_gsm_and_hex(message, message_length, pdu + x, paddingBits) == 0) { free(pdu); return NULL; } @@ -401,16 +401,16 @@ char* AT_CellularSMS::create_pdu(const char* phone_number, const char* message, } // now we know the correct length of the UDL (User Data Length) - int_to_hex_str(message_length + udhlen, pdu+lengthPos); + int_to_hex_str(message_length + udhlen, pdu + lengthPos); header_size = x; return pdu; } -nsapi_size_or_error_t AT_CellularSMS::send_sms(const char* phone_number, const char* message, int msg_len) +nsapi_size_or_error_t AT_CellularSMS::send_sms(const char *phone_number, const char *message, int msg_len) { int single_sms_max_length = _use_8bit_encoding ? SMS_MAX_SIZE_8BIT_SINGLE_SMS_SIZE : - SMS_MAX_SIZE_GSM7_SINGLE_SMS_SIZE; + SMS_MAX_SIZE_GSM7_SINGLE_SMS_SIZE; if ((_mode == CellularSMSMmodeText && msg_len > single_sms_max_length) || !phone_number) { return NSAPI_ERROR_PARAMETER; } @@ -424,14 +424,14 @@ nsapi_size_or_error_t AT_CellularSMS::send_sms(const char* phone_number, const c if (_mode == CellularSMSMmodeText) { _at.cmd_start("AT+CMGS="); - _at.write_string(phone_number+remove_plus_sign); + _at.write_string(phone_number + remove_plus_sign); _at.cmd_stop(); wait_ms(_sim_wait_time); _at.resp_start("> ", true); if (_at.get_last_error() == NSAPI_ERROR_OK) { - write_size = _at.write_bytes((uint8_t*)message, msg_len); + write_size = _at.write_bytes((uint8_t *)message, msg_len); if (write_size < msg_len) { // sending can be cancelled by giving character (IRA 27). _at.cmd_start(ESC); @@ -450,15 +450,15 @@ nsapi_size_or_error_t AT_CellularSMS::send_sms(const char* phone_number, const c // GSM 7 bit default but support is done for 8 bit data. int sms_count; int concatenated_sms_length = _use_8bit_encoding ? SMS_MAX_8BIT_CONCATENATED_SINGLE_SMS_SIZE : - SMS_MAX_GSM7_CONCATENATED_SINGLE_SMS_SIZE; + SMS_MAX_GSM7_CONCATENATED_SINGLE_SMS_SIZE; if (msg_len <= single_sms_max_length) { // single message sms_count = 1; } else { // concatenated message - sms_count = msg_len/concatenated_sms_length; - if (msg_len%concatenated_sms_length != 0) { + sms_count = msg_len / concatenated_sms_length; + if (msg_len % concatenated_sms_length != 0) { sms_count++; } } @@ -477,8 +477,8 @@ nsapi_size_or_error_t AT_CellularSMS::send_sms(const char* phone_number, const c pdu_len = remaining_len > concatenated_sms_length ? concatenated_sms_length : remaining_len; } - pdu_str = create_pdu(phone_number+remove_plus_sign, message + i*concatenated_sms_length, pdu_len, - sms_count, i+1, header_len); + pdu_str = create_pdu(phone_number + remove_plus_sign, message + i * concatenated_sms_length, pdu_len, + sms_count, i + 1, header_len); if (!pdu_str) { _at.unlock(); return NSAPI_ERROR_NO_MEMORY; @@ -487,21 +487,21 @@ nsapi_size_or_error_t AT_CellularSMS::send_sms(const char* phone_number, const c // specification says that service center number should not be included so we subtract -2 from pdu_len as we use '00' for automatic service center number _at.cmd_start("AT+CMGS="); - _at.write_int((pdu_len-2)/2); + _at.write_int((pdu_len - 2) / 2); _at.cmd_stop(); wait_ms(_sim_wait_time); _at.resp_start("> ", true); if (_at.get_last_error() == NSAPI_ERROR_OK) { - write_size = _at.write_bytes((uint8_t*)pdu_str, pdu_len); + write_size = _at.write_bytes((uint8_t *)pdu_str, pdu_len); if (write_size < pdu_len) { // calculate exact size of what we have send if (write_size <= header_len) { // managed only to write header or some of it so actual msg write size in this iteration is 0 write_size = 0; } else { - write_size = (write_size - header_len)/2; // as hex encoded so divide by two + write_size = (write_size - header_len) / 2; // as hex encoded so divide by two } msg_write_len += write_size; @@ -578,7 +578,7 @@ nsapi_size_or_error_t AT_CellularSMS::set_cscs(const char *chr_set) return _at.unlock_return_error(); } -nsapi_error_t AT_CellularSMS::delete_sms(sms_info_t* sms) +nsapi_error_t AT_CellularSMS::delete_sms(sms_info_t *sms) { _at.lock(); for (int i = 0; i < sms->parts; i++) { @@ -607,8 +607,8 @@ nsapi_error_t AT_CellularSMS::delete_all_messages() } // read msg in text mode -nsapi_size_or_error_t AT_CellularSMS::read_sms_from_index(int msg_index, char* buf, uint16_t len, char* phone_num, - char* time_stamp) +nsapi_size_or_error_t AT_CellularSMS::read_sms_from_index(int msg_index, char *buf, uint16_t len, char *phone_num, + char *time_stamp) { /* * +CMGR: ,,,[,,,,,,,]OK @@ -635,13 +635,16 @@ nsapi_size_or_error_t AT_CellularSMS::read_sms_from_index(int msg_index, char* b // Received message if (phone_num) { _at.read_string(phone_num, SMS_MAX_PHONE_NUMBER_SIZE); - } - else { + } else { _at.skip_param(); // , } _at.skip_param(); // if (time_stamp) { - _at.read_string(time_stamp, SMS_MAX_TIME_STAMP_SIZE); + int len = _at.read_string(time_stamp, SMS_MAX_TIME_STAMP_SIZE); + if (len < (SMS_MAX_TIME_STAMP_SIZE - 2)) { + time_stamp[len++] = ','; + _at.read_string(&time_stamp[len], SMS_MAX_TIME_STAMP_SIZE-len); + } } (void)_at.consume_to_stop_tag(); // consume until if (buf) { @@ -657,7 +660,7 @@ nsapi_size_or_error_t AT_CellularSMS::read_sms_from_index(int msg_index, char* b } // read msg in PDU mode -nsapi_size_or_error_t AT_CellularSMS::read_sms(sms_info_t* sms, char* buf, char* phone_num, char* time_stamp) +nsapi_size_or_error_t AT_CellularSMS::read_sms(sms_info_t *sms, char *buf, char *phone_num, char *time_stamp) { // +CMGR: ,[], int index; @@ -681,15 +684,15 @@ nsapi_size_or_error_t AT_CellularSMS::read_sms(sms_info_t* sms, char* buf, char* if ((_at.get_last_error() == NSAPI_ERROR_OK) && (status == 0 || status == 1)) { msg_len = _at.read_int(); if (msg_len > 0) { - pduSize = msg_len*2 + 20;// *2 as it's hex encoded and +20 as service center number is not included in size given by CMGR - pdu = (char*)calloc(pduSize, sizeof(char)); + pduSize = msg_len * 2 + 20; // *2 as it's hex encoded and +20 as service center number is not included in size given by CMGR + pdu = (char *)calloc(pduSize, sizeof(char)); if (!pdu) { _at.resp_stop(); return NSAPI_ERROR_NO_MEMORY; } _at.read_string(pdu, pduSize, true); if (_at.get_last_error() == NSAPI_ERROR_OK) { - msg_len = get_data_from_pdu(pdu, NULL, NULL, phone_num, buf+index); + msg_len = get_data_from_pdu(pdu, NULL, NULL, phone_num, buf + index); if (msg_len >= 0) { // we need to allow zero length messages index += msg_len; } else { @@ -711,8 +714,7 @@ nsapi_size_or_error_t AT_CellularSMS::read_sms(sms_info_t* sms, char* buf, char* } buf[index] = '\0'; } - } - else { + } else { tr_warn("NOT all concatenated parts were received..."); index = SMS_ERROR_MULTIPART_ALL_PARTS_NOT_READ; } @@ -720,8 +722,8 @@ nsapi_size_or_error_t AT_CellularSMS::read_sms(sms_info_t* sms, char* buf, char* return index; } -nsapi_size_or_error_t AT_CellularSMS::get_sms(char* buf, uint16_t len, char* phone_num, uint16_t phone_len, - char* time_stamp, uint16_t time_len, int *buf_size) +nsapi_size_or_error_t AT_CellularSMS::get_sms(char *buf, uint16_t len, char *phone_num, uint16_t phone_len, + char *time_stamp, uint16_t time_len, int *buf_size) { // validate buffer sizes already here to avoid any necessary function calls and locking of _at if ((phone_num && phone_len < SMS_MAX_PHONE_NUMBER_SIZE) || (time_stamp && time_len < SMS_MAX_TIME_STAMP_SIZE) || @@ -734,10 +736,10 @@ nsapi_size_or_error_t AT_CellularSMS::get_sms(char* buf, uint16_t len, char* pho nsapi_size_or_error_t err = list_messages(); if (err == NSAPI_ERROR_OK) { // we return the oldest sms and delete it after successful read - sms_info_t* info = get_oldest_sms_index(); + sms_info_t *info = get_oldest_sms_index(); if (info) { - if (info->msg_size+1 > len) { // +1 for '\0' + if (info->msg_size > len) { tr_warn("Given buf too small, len is: %d but is must be: %d", len, info->msg_size); if (buf_size) { *buf_size = info->msg_size; @@ -776,8 +778,8 @@ nsapi_size_or_error_t AT_CellularSMS::get_sms(char* buf, uint16_t len, char* pho return err; } - nsapi_size_or_error_t AT_CellularSMS::get_data_from_pdu(const char* pdu, sms_info_t *info, int *part_number, - char *phone_number, char *msg) +nsapi_size_or_error_t AT_CellularSMS::get_data_from_pdu(const char *pdu, sms_info_t *info, int *part_number, + char *phone_number, char *msg) { int index = 0; int tmp; @@ -789,81 +791,93 @@ nsapi_size_or_error_t AT_CellularSMS::get_sms(char* buf, uint16_t len, char* pho // read Length of the SMSC information oaLength = hex_str_to_int(pdu, 2); index += 2; // length we just read - index += oaLength*2; // skip service center number + index += oaLength * 2; // skip service center number // read first the lower part of first octet as there is message type index++; - tmp = hex_str_to_int(pdu+index, 1); + tmp = hex_str_to_int(pdu + index, 1); //wait_ms(200); if ((tmp & 0x03) == 0) {// SMS-DELIVER type, last two bits should be zero // UDH present? Check from first octets higher part tmp = hex_str_to_int(pdu + (--index), 1); userDataHeader = ((tmp & 0x04) == 0) ? false : true; - index +=2; // we just read the high bits of first octet so move +2 + index += 2; // we just read the high bits of first octet so move +2 // originating address length - oaLength = hex_str_to_int(pdu+index, 2); - index +=2; // add index over address length - index +=2; // skip number type + oaLength = hex_str_to_int(pdu + index, 2); + index += 2; // add index over address length + int type = hex_str_to_int(pdu + index, 1); + index += 2; // add index over type if (phone_number) { // phone number as reverse nibble encoded - int a = 0; - for (; a < oaLength; a +=2) { - if (a+1 == oaLength) { - phone_number[a] = pdu[index+a+1]; + int a = 0, field_length = oaLength; + + if (type == 9) { + //add the plus sign in case of international number (23.040 chapter address fields) + phone_number[a++] = '+'; + field_length++; + } + + for (; a < field_length; a += 2) { + if ((a + 1) == field_length) { + phone_number[a] = pdu[index + 1]; + index++; } else { - phone_number[a] = pdu[index+a+1]; - phone_number[a+1] = pdu[index+a]; + phone_number[a] = pdu[index + 1]; + phone_number[a + 1] = pdu[index]; + index += 2; } } - phone_number[oaLength] = '\0'; + phone_number[field_length] = '\0'; + } else { + index += oaLength; } - index += oaLength; - if (oaLength&0x01) { // if phone number length is odd then it has padded F so skip that + + if (oaLength & 0x01) { // if phone number length is odd then it has padded F so skip that index++; } - index +=2; // skip TP-Protocol identifier + index += 2; // skip TP-Protocol identifier - dataScheme = hex_str_to_int(pdu+index, 2); - index +=2; // skip TP-Data-Coding-Scheme + dataScheme = hex_str_to_int(pdu + index, 2); + index += 2; // skip TP-Data-Coding-Scheme // next one is date, it's length is 7 octets according to 3GPP TS 23.040 // create time string if (info) { int i = 0; // year - info->date[i++] = pdu[index+1]; + info->date[i++] = pdu[index + 1]; info->date[i++] = pdu[index]; - index+=2; + index += 2; info->date[i++] = '/'; // month - info->date[i++] = pdu[index+1]; + info->date[i++] = pdu[index + 1]; info->date[i++] = pdu[index]; - index+=2; + index += 2; info->date[i++] = '/'; // Day - info->date[i++] = pdu[index+1]; + info->date[i++] = pdu[index + 1]; info->date[i++] = pdu[index]; - index+=2; + index += 2; info->date[i++] = ','; // Hour - info->date[i++] = pdu[index+1]; + info->date[i++] = pdu[index + 1]; info->date[i++] = pdu[index]; - index+=2; + index += 2; info->date[i++] = ':'; // Minute - info->date[i++] = pdu[index+1]; + info->date[i++] = pdu[index + 1]; info->date[i++] = pdu[index]; - index+=2; + index += 2; info->date[i++] = ':'; // Second - info->date[i++] = pdu[index+1]; + info->date[i++] = pdu[index + 1]; info->date[i++] = pdu[index]; - index+=2; + index += 2; // timezone related to GMT. pdu[index+1] most significant bit indicates the sign related to gmt - tmp = hex_str_to_int(pdu+index+1, 1); - if (tmp&0x08) { + tmp = hex_str_to_int(pdu + index + 1, 1); + if (tmp & 0x08) { info->date[i++] = '-'; } else { info->date[i++] = '+'; @@ -874,19 +888,19 @@ nsapi_size_or_error_t AT_CellularSMS::get_sms(char* buf, uint16_t len, char* pho info->date[i++] = '0' + (tmp & 0x07); info->date[i++] = pdu[index]; info->date[i] = '\0'; - index+=2; + index += 2; } else { - index+=14; + index += 14; } - int udl = hex_str_to_int(pdu+index, 2); - index +=2; + int udl = hex_str_to_int(pdu + index, 2); + index += 2; int paddingBits = 0; int partnro = 1; if (userDataHeader) { // we need to read User Defined Header to know what part number this message is. - index += read_udh_from_pdu(pdu+index, info, partnro, paddingBits); + index += read_udh_from_pdu(pdu + index, info, partnro, paddingBits); } if (part_number) { @@ -895,38 +909,37 @@ nsapi_size_or_error_t AT_CellularSMS::get_sms(char* buf, uint16_t len, char* pho if (msg) { // we are reading the message - err = read_pdu_payload(pdu+index, udl, dataScheme, msg, paddingBits); - } - else { + err = read_pdu_payload(pdu + index, udl, dataScheme, msg, paddingBits); + } else { if (dataScheme == 0x00) { // when listing messages we need to calculated length. Other way would be unpacking the whole message. - err = strlen(pdu+index) >> 1; + err = strlen(pdu + index) >> 1; err *= 8; err /= 7; } else if (dataScheme == 0x04) { - err = strlen(pdu+index) >> 1; + err = strlen(pdu + index) >> 1; } else { return NSAPI_ERROR_UNSUPPORTED; } } return err; - } - else { + } else { // message was not DELIVER so discard it return NSAPI_ERROR_UNSUPPORTED; } } - // read params from User Defined Header -int AT_CellularSMS::read_udh_from_pdu(const char* pdu, sms_info_t *info, int &part_number, int &padding_bits) { +// read params from User Defined Header +int AT_CellularSMS::read_udh_from_pdu(const char *pdu, sms_info_t *info, int &part_number, int &padding_bits) +{ int index = 0; int udhLength = hex_str_to_int(pdu, 2); - index +=2; + index += 2; // if there is padding bits then udhlen is octet bigger as we need to keep septet boundary - padding_bits = ((udhLength+1) * 8 ) % 7; // +1 is for udhLength itself + padding_bits = ((udhLength + 1) * 8) % 7; // +1 is for udhLength itself if (padding_bits) { padding_bits = 7 - padding_bits; @@ -934,39 +947,39 @@ int AT_CellularSMS::read_udh_from_pdu(const char* pdu, sms_info_t *info, int &pa padding_bits = 0; } - int tmp = hex_str_to_int(pdu+index, 2); - index +=4; + int tmp = hex_str_to_int(pdu + index, 2); + index += 4; if (tmp == 0) { // 8-bit reference number if (info) { - info->msg_ref_number = (uint16_t)hex_str_to_int(pdu+index, 2); + info->msg_ref_number = (uint16_t)hex_str_to_int(pdu + index, 2); } - index +=2; + index += 2; } else { // 16-bit reference number if (info) { - info->msg_ref_number = (uint16_t)hex_str_to_int(pdu+index+2, 2); - tmp = hex_str_to_int(pdu+index, 2); + info->msg_ref_number = (uint16_t)hex_str_to_int(pdu + index + 2, 2); + tmp = hex_str_to_int(pdu + index, 2); info->msg_ref_number |= (tmp << 8); } - index +=4; + index += 4; } if (info) { - info->parts = hex_str_to_int(pdu+index, 2); + info->parts = hex_str_to_int(pdu + index, 2); } - index +=2; + index += 2; - part_number = hex_str_to_int(pdu+index, 2); - index +=2; + part_number = hex_str_to_int(pdu + index, 2); + index += 2; - return (udhLength*2 + 2); // udh in hex and udhl + return (udhLength * 2 + 2); // udh in hex and udhl } -nsapi_size_or_error_t AT_CellularSMS::read_pdu_payload(const char* pdu, int msg_len, int scheme, char *msg, int padding_bits) +nsapi_size_or_error_t AT_CellularSMS::read_pdu_payload(const char *pdu, int msg_len, int scheme, char *msg, int padding_bits) { if (scheme == 0x00) { // 7 bit gsm encoding, must do the conversions from hex to 7-bit encoding and to ascii - return unpack_7_bit_gsm_to_str(pdu, strlen(pdu)/2, msg, padding_bits, msg_len); + return unpack_7_bit_gsm_to_str(pdu, strlen(pdu) / 2, msg, padding_bits, msg_len); } else if (scheme == 0x04) { // 8bit scheme so just convert hexstring to charstring return hex_str_to_char_str(pdu, strlen(pdu), msg); @@ -978,8 +991,8 @@ nsapi_size_or_error_t AT_CellularSMS::read_pdu_payload(const char* pdu, int msg_ void AT_CellularSMS::free_linked_list() { - sms_info_t* info = _sms_info; - sms_info_t* old; + sms_info_t *info = _sms_info; + sms_info_t *old; while (info) { old = info; info = info->next_info; @@ -988,17 +1001,18 @@ void AT_CellularSMS::free_linked_list() _sms_info = NULL; } -void AT_CellularSMS::add_info(sms_info_t* info, int index, int part_number) { +void AT_CellularSMS::add_info(sms_info_t *info, int index, int part_number) +{ // check for same message reference id. If found, update it and delete the given info. // if NOT found then add to the end of the list. if (!_sms_info) { - info->msg_index[part_number-1] = index; // part numbering starts from 1 so -1 to put to right index + info->msg_index[part_number - 1] = index; // part numbering starts from 1 so -1 to put to right index _sms_info = info; return; } - sms_info_t* current = _sms_info; - sms_info_t* prev; + sms_info_t *current = _sms_info; + sms_info_t *prev; bool found_msg = false; while (current) { prev = current; @@ -1008,7 +1022,7 @@ void AT_CellularSMS::add_info(sms_info_t* info, int index, int part_number) { info->parts > info->parts_added) { // multipart sms, update msg size and index current->msg_size += info->msg_size; - current->msg_index[part_number-1] = index; // part numbering starts from 1 so -1 to put to right index + current->msg_index[part_number - 1] = index; // part numbering starts from 1 so -1 to put to right index current->parts_added++; // update oldest part as date if (compare_time_strings(info->date, current->date) == -1) { @@ -1025,7 +1039,7 @@ void AT_CellularSMS::add_info(sms_info_t* info, int index, int part_number) { delete info; } else { // message not found, add to linked list - info->msg_index[part_number-1] = index; + info->msg_index[part_number - 1] = index; prev->next_info = info; } } @@ -1043,7 +1057,7 @@ nsapi_error_t AT_CellularSMS::list_messages() } _at.cmd_stop(); - sms_info_t* info = NULL; + sms_info_t *info = NULL; // init for 1 so that in text mode we will add to the correct place without any additional logic in addInfo() in text mode int part_number = 1; int index = 0; @@ -1065,8 +1079,8 @@ nsapi_error_t AT_CellularSMS::list_messages() index = _at.read_int(); _at.skip_param(2); // ,[] length = _at.read_int(); - length = length*2 + 20;// *2 as it's hex encoded and +20 as service center number is not included in size given by CMGL - pdu = (char*)calloc(length, sizeof(char)); + length = length * 2 + 20; // *2 as it's hex encoded and +20 as service center number is not included in size given by CMGL + pdu = (char *)calloc(length, sizeof(char)); if (!pdu) { delete info; _at.resp_stop(); @@ -1100,7 +1114,7 @@ nsapi_error_t AT_CellularSMS::list_messages() return _at.get_last_error(); } -AT_CellularSMS::sms_info_t* AT_CellularSMS::get_oldest_sms_index() +AT_CellularSMS::sms_info_t *AT_CellularSMS::get_oldest_sms_index() { /* * Different scenarios when finding the oldest concatenated sms @@ -1114,8 +1128,8 @@ AT_CellularSMS::sms_info_t* AT_CellularSMS::get_oldest_sms_index() */ // if text mode we need to read sms with +CMGR because time stamp is optional while looping with +CMGL - sms_info_t* retVal = NULL; - sms_info_t* current = _sms_info; + sms_info_t *retVal = NULL; + sms_info_t *current = _sms_info; nsapi_size_or_error_t err = 0; while (current) { if (_mode == CellularSMSMmodeText) { @@ -1139,7 +1153,7 @@ AT_CellularSMS::sms_info_t* AT_CellularSMS::get_oldest_sms_index() } // if time_string_1 is greater (more fresh date) then return 1, same 0, smaller -1. Error -2 -int AT_CellularSMS::compare_time_strings(const char* time_string_1, const char* time_string_2) +int AT_CellularSMS::compare_time_strings(const char *time_string_1, const char *time_string_2) { time_t t1; time_t t2; @@ -1162,7 +1176,7 @@ int AT_CellularSMS::compare_time_strings(const char* time_string_1, const char* return retVal; } -bool AT_CellularSMS::create_time(const char* time_string, time_t* time) +bool AT_CellularSMS::create_time(const char *time_string, time_t *time) { const int kNumberOfElements = 8; tm time_struct = { 0 }; @@ -1186,8 +1200,8 @@ bool AT_CellularSMS::create_time(const char* time_string, time_t* time) return retVal; } -uint16_t AT_CellularSMS::pack_7_bit_gsm_and_hex(const char* str, uint16_t len, char *buf, - int number_of_padding_bit) +uint16_t AT_CellularSMS::pack_7_bit_gsm_and_hex(const char *str, uint16_t len, char *buf, + int number_of_padding_bit) { uint16_t strCnt = 0; uint16_t i = 0; @@ -1198,12 +1212,12 @@ uint16_t AT_CellularSMS::pack_7_bit_gsm_and_hex(const char* str, uint16_t len, c return 0; } // convert to 7bit gsm first - char* gsm_str = (char*)malloc(len); + char *gsm_str = (char *)malloc(len); if (!gsm_str) { return 0; } for (uint16_t y = 0; y < len; y++) { - for (int x=0; x < GSM_TO_ASCII_TABLE_SIZE; x++) { + for (int x = 0; x < GSM_TO_ASCII_TABLE_SIZE; x++) { if (gsm_to_ascii[x] == str[y]) { gsm_str[y] = x; } @@ -1212,26 +1226,26 @@ uint16_t AT_CellularSMS::pack_7_bit_gsm_and_hex(const char* str, uint16_t len, c // then packing and converting to hex if (number_of_padding_bit) { - tmp = gsm_str[strCnt]<>shift); + if (strCnt + 1 == len) { + tmp = (gsm_str[strCnt] >> shift); } else { - tmp = (gsm_str[strCnt]>>shift) | (gsm_str[strCnt+1] <<(7-shift)); + tmp = (gsm_str[strCnt] >> shift) | (gsm_str[strCnt + 1] << (7 - shift)); } - char_str_to_hex_str(&tmp, 1, buf+(i*2)); + char_str_to_hex_str(&tmp, 1, buf + (i * 2)); if (shift == 6) { strCnt++; @@ -1245,8 +1259,8 @@ uint16_t AT_CellularSMS::pack_7_bit_gsm_and_hex(const char* str, uint16_t len, c return i; } - uint16_t AT_CellularSMS::unpack_7_bit_gsm_to_str(const char* str, int len, char *buf, int padding_bits, - int msg_len) +uint16_t AT_CellularSMS::unpack_7_bit_gsm_to_str(const char *str, int len, char *buf, int padding_bits, + int msg_len) { int strCount = 0; uint16_t decodedCount = 0; @@ -1256,27 +1270,27 @@ uint16_t AT_CellularSMS::pack_7_bit_gsm_and_hex(const char* str, uint16_t len, c if (padding_bits) { hex_str_to_char_str(str, 2, &tmp); - buf[decodedCount] = gsm_to_ascii[(tmp>>padding_bits) & 0x7F]; + buf[decodedCount] = gsm_to_ascii[(tmp >> padding_bits) & 0x7F]; strCount++; decodedCount++; } while (strCount < len) { - shift = (strCount-padding_bits)%7; - hex_str_to_char_str(str + strCount*2, 2, &tmp); + shift = (strCount - padding_bits) % 7; + hex_str_to_char_str(str + strCount * 2, 2, &tmp); if (shift == 0) { buf[decodedCount] = gsm_to_ascii[tmp & 0x7F]; } else if (shift == 6) { - hex_str_to_char_str(str + (strCount-1)*2, 2, &tmp1); - buf[decodedCount] = gsm_to_ascii[(((tmp1>>2)) | (tmp << 6)) & 0x7F]; - if (decodedCount+1 < msg_len) { - hex_str_to_char_str(str + strCount*2, 2, &tmp); + hex_str_to_char_str(str + (strCount - 1) * 2, 2, &tmp1); + buf[decodedCount] = gsm_to_ascii[(((tmp1 >> 2)) | (tmp << 6)) & 0x7F]; + if (decodedCount + 1 < msg_len) { + hex_str_to_char_str(str + strCount * 2, 2, &tmp); decodedCount++; - buf[decodedCount] = gsm_to_ascii[(tmp>>1) & 0x7F]; + buf[decodedCount] = gsm_to_ascii[(tmp >> 1) & 0x7F]; } } else { - hex_str_to_char_str(str + (strCount-1)*2, 2, &tmp1); - buf[decodedCount] = gsm_to_ascii[(((tmp1>>(8- shift))) | ((tmp << shift))) & 0x7F]; + hex_str_to_char_str(str + (strCount - 1) * 2, 2, &tmp1); + buf[decodedCount] = gsm_to_ascii[(((tmp1 >> (8 - shift))) | ((tmp << shift))) & 0x7F]; } strCount++; diff --git a/features/cellular/framework/AT/AT_CellularSMS.h b/features/cellular/framework/AT/AT_CellularSMS.h index 46080518e846..04501b279ae6 100644 --- a/features/cellular/framework/AT/AT_CellularSMS.h +++ b/features/cellular/framework/AT/AT_CellularSMS.h @@ -30,8 +30,7 @@ namespace mbed { * * Class for SMS sending, reading and deleting. */ -class AT_CellularSMS: public CellularSMS, public AT_CellularBase -{ +class AT_CellularSMS: public CellularSMS, public AT_CellularBase { public: AT_CellularSMS(ATHandler &atHandler); @@ -42,10 +41,10 @@ class AT_CellularSMS: public CellularSMS, public AT_CellularBase virtual nsapi_error_t initialize(CellularSMSMmode mode); - virtual nsapi_size_or_error_t send_sms(const char* phone_number, const char* message, int msg_len); + virtual nsapi_size_or_error_t send_sms(const char *phone_number, const char *message, int msg_len); - virtual nsapi_size_or_error_t get_sms(char* buf, uint16_t buf_len, char* phone_num, uint16_t phone_len, - char* time_stamp, uint16_t time_len, int *buf_size); + virtual nsapi_size_or_error_t get_sms(char *buf, uint16_t buf_len, char *phone_num, uint16_t phone_len, + char *time_stamp, uint16_t time_len, int *buf_size); virtual void set_sms_callback(Callback func); @@ -69,7 +68,7 @@ class AT_CellularSMS: public CellularSMS, public AT_CellularBase uint8_t parts_added; uint16_t msg_ref_number; struct sms_info_t *next_info; - sms_info_t() : msg_size(0), parts(1), parts_added(1), msg_ref_number(0), next_info(0){}; + sms_info_t() : msg_size(0), parts(1), parts_added(1), msg_ref_number(0), next_info(0) {}; }; // application callback function for received sms @@ -119,7 +118,7 @@ class AT_CellularSMS: public CellularSMS, public AT_CellularBase * @param sms struct containing index array to delete * @return zero for success */ - nsapi_error_t delete_sms(sms_info_t* sms); + nsapi_error_t delete_sms(sms_info_t *sms); /** * Internal helper methods @@ -127,19 +126,19 @@ class AT_CellularSMS: public CellularSMS, public AT_CellularBase nsapi_error_t list_messages(); int read_sms_params(char *, char *); void free_linked_list(); - void add_info(sms_info_t* info, int index, int part_number); - int read_udh_from_pdu(const char* pdu, sms_info_t *info, int &part_number, int &padding_bits); - nsapi_size_or_error_t get_data_from_pdu(const char* pdu, sms_info_t *info, int *part_number, + void add_info(sms_info_t *info, int index, int part_number); + int read_udh_from_pdu(const char *pdu, sms_info_t *info, int &part_number, int &padding_bits); + nsapi_size_or_error_t get_data_from_pdu(const char *pdu, sms_info_t *info, int *part_number, char *phone_number = NULL, char *msg = NULL); - nsapi_size_or_error_t read_pdu_payload(const char* pdu, int msg_len, int scheme, char *msg, int padding_bits); - sms_info_t* get_oldest_sms_index(); - bool create_time(const char* time_string, time_t* time); - int compare_time_strings(const char* time_string_1, const char* time_string_2); - char* create_pdu(const char* phone_number, const char* message, uint8_t message_length, uint8_t msg_parts, - uint8_t msg_part_number, uint8_t& header_size); - nsapi_size_or_error_t read_sms_from_index(int msg_index, char* buf, uint16_t len, char* phone_num, - char* time_stamp); - nsapi_size_or_error_t read_sms(sms_info_t* sms, char* buf, char* phone_num, char* time_stamp); + nsapi_size_or_error_t read_pdu_payload(const char *pdu, int msg_len, int scheme, char *msg, int padding_bits); + sms_info_t *get_oldest_sms_index(); + bool create_time(const char *time_string, time_t *time); + int compare_time_strings(const char *time_string_1, const char *time_string_2); + char *create_pdu(const char *phone_number, const char *message, uint8_t message_length, uint8_t msg_parts, + uint8_t msg_part_number, uint8_t &header_size); + nsapi_size_or_error_t read_sms_from_index(int msg_index, char *buf, uint16_t len, char *phone_num, + char *time_stamp); + nsapi_size_or_error_t read_sms(sms_info_t *sms, char *buf, char *phone_num, char *time_stamp); /** Packs the given str from ascii to 7bit gsm format and converts it to hex to the given buf. * @@ -149,7 +148,7 @@ class AT_CellularSMS: public CellularSMS, public AT_CellularBase * @param number_of_padding_bit padding bits needed to keep the octet boundary * @return length of buffer buf or zero on failure */ - uint16_t pack_7_bit_gsm_and_hex(const char* str, uint16_t len, char *buf, int number_of_padding_bit); + uint16_t pack_7_bit_gsm_and_hex(const char *str, uint16_t len, char *buf, int number_of_padding_bit); /** Unpacks the given hex- and 7-bit gsm encoded str to ascii string * @@ -161,8 +160,8 @@ class AT_CellularSMS: public CellularSMS, public AT_CellularBase * @return length of the destination buffer buf * */ - uint16_t unpack_7_bit_gsm_to_str(const char* str, int len, char *buf, int padding_bits, - int msg_len); + uint16_t unpack_7_bit_gsm_to_str(const char *str, int len, char *buf, int padding_bits, + int msg_len); }; } // namespace mbed diff --git a/features/cellular/framework/AT/AT_CellularStack.cpp b/features/cellular/framework/AT/AT_CellularStack.cpp index df6f1c9348e5..ea906f8d8364 100644 --- a/features/cellular/framework/AT/AT_CellularStack.cpp +++ b/features/cellular/framework/AT/AT_CellularStack.cpp @@ -22,9 +22,9 @@ using namespace mbed_cellular_util; using namespace mbed; -AT_CellularStack::AT_CellularStack(ATHandler &at, int cid, nsapi_ip_stack_t stack_type) : AT_CellularBase(at), _socket(NULL),_socket_count(0),_cid(cid), _stack_type(stack_type) +AT_CellularStack::AT_CellularStack(ATHandler &at, int cid, nsapi_ip_stack_t stack_type) : AT_CellularBase(at), _socket(NULL), _socket_count(0), _cid(cid), _stack_type(stack_type) { - memset(_ip,0, PDP_IPV6_SIZE); + memset(_ip, 0, PDP_IPV6_SIZE); } AT_CellularStack::~AT_CellularStack() @@ -44,7 +44,7 @@ AT_CellularStack::~AT_CellularStack() /** NetworkStack */ -const char * AT_CellularStack::get_ip_address() +const char *AT_CellularStack::get_ip_address() { _at.lock(); @@ -58,9 +58,10 @@ const char * AT_CellularStack::get_ip_address() _at.skip_param(); - int len = _at.read_string(_ip, NSAPI_IPv4_SIZE-1); + int len = _at.read_string(_ip, NSAPI_IPv4_SIZE - 1); if (len == -1) { _ip[0] = '\0'; + _at.resp_stop(); _at.unlock(); // no IPV4 address, return return NULL; @@ -68,7 +69,7 @@ const char * AT_CellularStack::get_ip_address() // in case stack type is not IPV4 only, try to look also for IPV6 address if (_stack_type != IPV4_STACK) { - (void)_at.read_string(_ip, PDP_IPV6_SIZE-1); + (void)_at.read_string(_ip, PDP_IPV6_SIZE - 1); } } @@ -143,7 +144,7 @@ nsapi_error_t AT_CellularStack::socket_close(nsapi_socket_t handle) int err = NSAPI_ERROR_DEVICE_ERROR; struct CellularSocket *socket = (struct CellularSocket *)handle; - if (!socket){ + if (!socket) { return err; } int sock_id = socket->id; @@ -265,7 +266,7 @@ nsapi_size_or_error_t AT_CellularStack::socket_sendto(nsapi_socket_t handle, con _at.lock(); ret_val = socket_sendto_impl(socket, addr, data, size); - + if (ret_val <= 0) { tr_error("Error sending to: %s error code: %d", addr.get_ip_address(), ret_val); } else { diff --git a/features/cellular/framework/AT/AT_CellularStack.h b/features/cellular/framework/AT/AT_CellularStack.h index 5f3cf5e1d313..9b927d6267ad 100644 --- a/features/cellular/framework/AT/AT_CellularStack.h +++ b/features/cellular/framework/AT/AT_CellularStack.h @@ -34,8 +34,7 @@ namespace mbed { * * Implements NetworkStack and introduces interface for modem specific stack implementations. */ -class AT_CellularStack : public NetworkStack, public AT_CellularBase -{ +class AT_CellularStack : public NetworkStack, public AT_CellularBase { public: AT_CellularStack(ATHandler &at, int cid, nsapi_ip_stack_t stack_type); @@ -64,26 +63,25 @@ class AT_CellularStack : public NetworkStack, public AT_CellularBase virtual nsapi_error_t socket_connect(nsapi_socket_t handle, const SocketAddress &address); virtual nsapi_error_t socket_accept(nsapi_socket_t server, - nsapi_socket_t *handle, SocketAddress *address=0); + nsapi_socket_t *handle, SocketAddress *address = 0); virtual nsapi_size_or_error_t socket_send(nsapi_socket_t handle, - const void *data, nsapi_size_t size); + const void *data, nsapi_size_t size); virtual nsapi_size_or_error_t socket_recv(nsapi_socket_t handle, - void *data, nsapi_size_t size); + void *data, nsapi_size_t size); virtual nsapi_size_or_error_t socket_sendto(nsapi_socket_t handle, const SocketAddress &address, - const void *data, nsapi_size_t size); + const void *data, nsapi_size_t size); virtual nsapi_size_or_error_t socket_recvfrom(nsapi_socket_t handle, SocketAddress *address, - void *buffer, nsapi_size_t size); + void *buffer, nsapi_size_t size); virtual void socket_attach(nsapi_socket_t handle, void (*callback)(void *), void *data); protected: - class CellularSocket - { + class CellularSocket { public: // Socket id from cellular device int id; @@ -98,6 +96,7 @@ class AT_CellularStack : public NetworkStack, public AT_CellularBase bool started; // socket has been opened on modem stack bool tx_ready; // socket is ready for sending on modem stack bool rx_avail; // socket has data for reading on modem stack + nsapi_size_t pending_bytes; // The number of received bytes pending }; /** @@ -137,7 +136,7 @@ class AT_CellularStack : public NetworkStack, public AT_CellularBase * code on failure */ virtual nsapi_size_or_error_t socket_sendto_impl(CellularSocket *socket, const SocketAddress &address, - const void *data, nsapi_size_t size) = 0; + const void *data, nsapi_size_t size) = 0; /** * Implements modem specific AT command set for receiving data @@ -150,7 +149,7 @@ class AT_CellularStack : public NetworkStack, public AT_CellularBase * code on failure */ virtual nsapi_size_or_error_t socket_recvfrom_impl(CellularSocket *socket, SocketAddress *address, - void *buffer, nsapi_size_t size) = 0; + void *buffer, nsapi_size_t size) = 0; // socket container CellularSocket **_socket; diff --git a/features/cellular/framework/common/CellularList.h b/features/cellular/framework/common/CellularList.h index d07ef3377fa8..d8ee8660fc9a 100644 --- a/features/cellular/framework/common/CellularList.h +++ b/features/cellular/framework/common/CellularList.h @@ -27,18 +27,17 @@ namespace mbed { * Templated linked list class for common usage. * */ -template class CellularList -{ +template class CellularList { private: T *_head, *_tail; public: CellularList() { - _head=NULL; - _tail=NULL; + _head = NULL; + _tail = NULL; } - ~CellularList() + ~CellularList() { T *temp = _head; while (temp) { @@ -48,40 +47,40 @@ template class CellularList } } - T* add_new() + T *add_new() { - T *temp=new T; - if (!temp) { - return NULL; - } - temp->next = NULL; - if (_head == NULL) { - _head = temp; - } else { - _tail->next=temp; - } - _tail = temp; - - return _tail; + T *temp = new T; + if (!temp) { + return NULL; + } + temp->next = NULL; + if (_head == NULL) { + _head = temp; + } else { + _tail->next = temp; + } + _tail = temp; + + return _tail; } void delete_last() { - T* previous = NULL; - T *current=_head; + T *previous = NULL; + T *current = _head; if (!current) { return; } while (current->next != NULL) { - previous=current; - current=current->next; + previous = current; + current = current->next; } if (previous) { - _tail=previous; - previous->next=NULL; + _tail = previous; + previous->next = NULL; } else { _head = NULL; _tail = NULL; @@ -98,7 +97,7 @@ template class CellularList delete temp; temp = _head; } - _tail=NULL; + _tail = NULL; } diff --git a/features/cellular/framework/common/CellularTargets.h b/features/cellular/framework/common/CellularTargets.h index 22cbc5ae6a25..5bfb1b45c1af 100644 --- a/features/cellular/framework/common/CellularTargets.h +++ b/features/cellular/framework/common/CellularTargets.h @@ -30,7 +30,11 @@ namespace mbed { #elif TARGET_MTB_MTS_DRAGONFLY #define CELLULAR_DEVICE TELIT_HE910 #elif TARGET_UBLOX_C030 +#ifdef TARGET_UBLOX_C030_N211 +#define CELLULAR_DEVICE UBLOX_AT +#else #define CELLULAR_DEVICE UBLOX_PPP +#endif #elif TARGET_UBLOX_C027 #define CELLULAR_DEVICE UBLOX_PPP #else diff --git a/features/cellular/framework/common/CellularUtil.cpp b/features/cellular/framework/common/CellularUtil.cpp index b342cf8b9fd4..b6262996d7e1 100644 --- a/features/cellular/framework/common/CellularUtil.cpp +++ b/features/cellular/framework/common/CellularUtil.cpp @@ -28,7 +28,7 @@ namespace mbed_cellular_util { -void convert_ipv6(char* ip) +void convert_ipv6(char *ip) { if (!ip) { return; @@ -56,21 +56,21 @@ void convert_ipv6(char* ip) bool set_colon = false; for (i = 0; i < len; i++) { if (ip[i] == '.') { - b = (char)strtol (ip+ip_pos, NULL, 10); // convert to char to int so we can change it to hex string - pos += char_str_to_hex_str(&b, 1, ip+pos, !set_colon); // omit leading zeroes with using set_colon flag + b = (char)strtol(ip + ip_pos, NULL, 10); // convert to char to int so we can change it to hex string + pos += char_str_to_hex_str(&b, 1, ip + pos, !set_colon); // omit leading zeroes with using set_colon flag if (set_colon) { ip[pos++] = ':'; set_colon = false; } else { set_colon = true; } - ip_pos = i+1; // skip the '.' + ip_pos = i + 1; // skip the '.' } // handle the last part which does not end with '.' but '\0' - if (i == len -1) { - b = (char)strtol(ip+ip_pos, NULL, 10); - pos += char_str_to_hex_str(&b, 1, ip+pos, !set_colon); + if (i == len - 1) { + b = (char)strtol(ip + ip_pos, NULL, 10); + pos += char_str_to_hex_str(&b, 1, ip + pos, !set_colon); ip[pos] = '\0'; } } @@ -78,7 +78,7 @@ void convert_ipv6(char* ip) } // For example "32.1.13.184.0.0.205.48.0.0.0.0.0.0.0.0" -void separate_ip4like_addresses(char* orig, char* ip, size_t ip_size, char* ip2, size_t ip2_size) +void separate_ip4like_addresses(char *orig, char *ip, size_t ip_size, char *ip2, size_t ip2_size) { // ipv4-like notation int len = strlen(orig); @@ -108,9 +108,9 @@ void separate_ip4like_addresses(char* orig, char* ip, size_t ip_size, char* ip2, } } else if (count == 7) { // ipv4 and subnet mask. Need to separate those. temp = &orig[pos]; - if ((uint8_t)ip_size > temp-orig) { - memcpy(ip, orig, temp-orig); - ip[temp-orig] = '\0'; + if ((uint8_t)ip_size > temp - orig) { + memcpy(ip, orig, temp - orig); + ip[temp - orig] = '\0'; } temp++; // skip the '.' if (ip2 && (ip2_size > strlen(temp))) { @@ -128,11 +128,11 @@ void separate_ip4like_addresses(char* orig, char* ip, size_t ip_size, char* ip2, if (ip2) { ip2[0] = '\0'; } - } else if (count == 31){ // ipv6 + ipv6subnet mask in ipv4-like notation separated by dot '.' + } else if (count == 31) { // ipv6 + ipv6subnet mask in ipv4-like notation separated by dot '.' temp = &orig[pos]; - if ((uint8_t)ip_size > temp-orig) { - memcpy(ip, orig, temp-orig); - ip[temp-orig] = '\0'; + if ((uint8_t)ip_size > temp - orig) { + memcpy(ip, orig, temp - orig); + ip[temp - orig] = '\0'; convert_ipv6(ip); } temp++; // skip the '.' @@ -144,7 +144,7 @@ void separate_ip4like_addresses(char* orig, char* ip, size_t ip_size, char* ip2, } } -void separate_ip_addresses(char* orig, char* ip, size_t ip_size, char* ip2, size_t ip2_size) +void separate_ip_addresses(char *orig, char *ip, size_t ip_size, char *ip2, size_t ip2_size) { // orig can include ipv4, ipv6, both or two ip4/ipv6 addresses. // also format depends on possible AT+CGPIAF @@ -166,9 +166,9 @@ void separate_ip_addresses(char* orig, char* ip, size_t ip_size, char* ip2, size temp = strstr(orig, " "); // found space as separator and it wasn't in beginning --> contains 2 ip addresses if (temp && temp != orig) { - if ((uint8_t)ip_size > temp-orig) { - memcpy(ip, orig, temp-orig); - ip[temp-orig] = '\0'; + if ((uint8_t)ip_size > temp - orig) { + memcpy(ip, orig, temp - orig); + ip[temp - orig] = '\0'; } else { ip[0] = '\0'; } @@ -201,17 +201,16 @@ void separate_ip_addresses(char* orig, char* ip, size_t ip_size, char* ip2, size // found space as separator and it wasn't in beginning --> contains 2 ip addresses if (temp && temp != orig) { separate_ip4like_addresses(temp++, ip2, ip2_size, NULL, 0); - orig[temp-orig-1] = '\0'; + orig[temp - orig - 1] = '\0'; separate_ip4like_addresses(orig, ip, ip_size, NULL, 0); - orig[temp-orig-1] = ' '; // put space back to keep orig as original - } - else { + orig[temp - orig - 1] = ' '; // put space back to keep orig as original + } else { separate_ip4like_addresses(orig, ip, ip_size, ip2, ip2_size); } } } -void prefer_ipv6(char* ip, size_t ip_size, char* ip2, size_t ip2_size) +void prefer_ipv6(char *ip, size_t ip_size, char *ip2, size_t ip2_size) { if (!ip || !ip2) { return; @@ -242,7 +241,7 @@ void prefer_ipv6(char* ip, size_t ip_size, char* ip2, size_t ip2_size) } } -void int_to_hex_str(uint8_t num, char* buf) +void int_to_hex_str(uint8_t num, char *buf) { char charNum = num; char_str_to_hex_str(&charNum, 1, buf); @@ -253,7 +252,7 @@ int hex_str_to_int(const char *hex_string, int hex_string_length) const int base = 16; int character_as_integer, integer_output = 0; - for (int i=0;i= '0' && hex_string[i] <= '9') { character_as_integer = hex_string[i] - '0'; } else if (hex_string[i] >= 'A' && hex_string[i] <= 'F') { @@ -268,20 +267,20 @@ int hex_str_to_int(const char *hex_string, int hex_string_length) return integer_output; } -int hex_str_to_char_str(const char* str, uint16_t len, char *buf) +int hex_str_to_char_str(const char *str, uint16_t len, char *buf) { int strcount = 0; - for (int i = 0; i+1 < len; i += 2) { - int upper = hex_str_to_int(str+i, 1); - int lower = hex_str_to_int(str+i+1, 1); - buf[strcount] = ((upper<<4) & 0xF0) | (lower & 0x0F); + for (int i = 0; i + 1 < len; i += 2) { + int upper = hex_str_to_int(str + i, 1); + int lower = hex_str_to_int(str + i + 1, 1); + buf[strcount] = ((upper << 4) & 0xF0) | (lower & 0x0F); strcount++; } return strcount; } -void uint_to_binary_str(uint32_t num, char* str, int str_size, int bit_cnt) +void uint_to_binary_str(uint32_t num, char *str, int str_size, int bit_cnt) { if (!str || str_size < bit_cnt) { return; @@ -291,7 +290,7 @@ void uint_to_binary_str(uint32_t num, char* str, int str_size, int bit_cnt) for (int i = 31; i >= 0; i--) { tmp = num >> i; if (i < bit_cnt) { - if (tmp&1) { + if (tmp & 1) { str[pos] = 1 + '0'; } else { str[pos] = 0 + '0'; @@ -301,24 +300,24 @@ void uint_to_binary_str(uint32_t num, char* str, int str_size, int bit_cnt) } } -int char_str_to_hex_str(const char* str, uint16_t len, char *buf, bool omit_leading_zero) +int char_str_to_hex_str(const char *str, uint16_t len, char *buf, bool omit_leading_zero) { if (!str || !buf) { return 0; } char *ptr = buf; - int i=0; + int i = 0; while (i < len) { - if (omit_leading_zero == true && i == 0 && !(str[i]>>4 & 0x0F)) { + if (omit_leading_zero == true && i == 0 && !(str[i] >> 4 & 0x0F)) { *ptr++ = hex_values[(str[i]) & 0x0F]; } else { - *ptr++ = hex_values[((str[i])>>4) & 0x0F]; + *ptr++ = hex_values[((str[i]) >> 4) & 0x0F]; *ptr++ = hex_values[(str[i]) & 0x0F]; } i++; } - return ptr-buf; + return ptr - buf; } uint16_t get_dynamic_ip_port() diff --git a/features/cellular/framework/common/CellularUtil.h b/features/cellular/framework/common/CellularUtil.h index 28fa52be3cb7..46f66162e732 100644 --- a/features/cellular/framework/common/CellularUtil.h +++ b/features/cellular/framework/common/CellularUtil.h @@ -38,7 +38,7 @@ static const char hex_values[] = "0123456789ABCDEF"; * * @param ip IP address that can be IPv4 or IPv6 in different formats from AT command +CGPADDR. Converted result uses same buffer. */ -void convert_ipv6(char* ip); +void convert_ipv6(char *ip); /** Separates IP addresses from the given 'orig' string. 'orig' may contain zero, one or two IP addresses in various formats. * See AT command +CGPIAF from 3GPP TS 27.007 for details. Does also needed conversions for IPv6 addresses. @@ -50,7 +50,7 @@ void convert_ipv6(char* ip); * @param ip2_size size of preallocated buffer ip2 * */ -void separate_ip_addresses(char* orig, char* ip, size_t ip_size, char* ip2, size_t ip2_size); +void separate_ip_addresses(char *orig, char *ip, size_t ip_size, char *ip2, size_t ip2_size); /** Swaps the arrays if param IP does not contain IPv6 address but param ip2 does. * @@ -59,14 +59,14 @@ void separate_ip_addresses(char* orig, char* ip, size_t ip_size, char* ip2, size * @param ip2 IP address * @param ip2_size size of buffer ip2 */ -void prefer_ipv6(char* ip, size_t ip_size, char* ip2, size_t ip2_size); +void prefer_ipv6(char *ip, size_t ip_size, char *ip2, size_t ip2_size); /** Converts the given int to two hex characters * * @param num number to be converted to hex string * @param buf preallocated buffer that will contain 2 char length hex value */ -void int_to_hex_str(uint8_t num, char* buf); +void int_to_hex_str(uint8_t num, char *buf); /** Converts the given buffer 'str' to hex buffer 'buf. First 'len' char's are converted to two hex bytes. * @@ -75,7 +75,7 @@ void int_to_hex_str(uint8_t num, char* buf); * @param buf destination buffer for hex converted chars. Buffer should be double the size of str to fit hex-encoded string. * @param omit_leading_zero if true then possible leading zeroes are omitted */ -int char_str_to_hex_str(const char* str, uint16_t len, char *buf, bool omit_leading_zero = false); +int char_str_to_hex_str(const char *str, uint16_t len, char *buf, bool omit_leading_zero = false); /** Converts the given hex string to integer * @@ -92,7 +92,7 @@ int hex_str_to_int(const char *hex_string, int hex_string_length); * @param buf preallocated buffer where result conversion is stored * @return length of the buf */ -int hex_str_to_char_str(const char* str, uint16_t len, char *buf); +int hex_str_to_char_str(const char *str, uint16_t len, char *buf); /** Converts the given uint to binary string. Fills the given str starting from [0] with the number of bits defined by bit_cnt * For example uint_to_binary_string(9, str, 10) would fill str "0000001001" @@ -103,7 +103,7 @@ int hex_str_to_char_str(const char* str, uint16_t len, char *buf); * @param str_size size of the str buffer * @param bit_cnt defines how many bits are filled to buffer started from lsb */ -void uint_to_binary_str(uint32_t num, char* str, int str_size, int bit_cnt); +void uint_to_binary_str(uint32_t num, char *str, int str_size, int bit_cnt); /** Get dynamic port for socket * diff --git a/features/cellular/framework/targets/QUECTEL/BC95/QUECTEL_BC95.h b/features/cellular/framework/targets/QUECTEL/BC95/QUECTEL_BC95.h index adfa1ccc61a7..aaa9a8afc2af 100644 --- a/features/cellular/framework/targets/QUECTEL/BC95/QUECTEL_BC95.h +++ b/features/cellular/framework/targets/QUECTEL/BC95/QUECTEL_BC95.h @@ -22,8 +22,7 @@ namespace mbed { -class QUECTEL_BC95 : public AT_CellularDevice -{ +class QUECTEL_BC95 : public AT_CellularDevice { public: QUECTEL_BC95(events::EventQueue &queue); diff --git a/features/cellular/framework/targets/QUECTEL/BC95/QUECTEL_BC95_CellularNetwork.h b/features/cellular/framework/targets/QUECTEL/BC95/QUECTEL_BC95_CellularNetwork.h index 1c6ff19f1a59..c6bd3b4f4976 100644 --- a/features/cellular/framework/targets/QUECTEL/BC95/QUECTEL_BC95_CellularNetwork.h +++ b/features/cellular/framework/targets/QUECTEL/BC95/QUECTEL_BC95_CellularNetwork.h @@ -22,8 +22,7 @@ namespace mbed { -class QUECTEL_BC95_CellularNetwork : public AT_CellularNetwork -{ +class QUECTEL_BC95_CellularNetwork : public AT_CellularNetwork { public: QUECTEL_BC95_CellularNetwork(ATHandler &atHandler); virtual ~QUECTEL_BC95_CellularNetwork(); diff --git a/features/cellular/framework/targets/QUECTEL/BC95/QUECTEL_BC95_CellularPower.h b/features/cellular/framework/targets/QUECTEL/BC95/QUECTEL_BC95_CellularPower.h index 1f0bfee80940..a10ab3e5d365 100644 --- a/features/cellular/framework/targets/QUECTEL/BC95/QUECTEL_BC95_CellularPower.h +++ b/features/cellular/framework/targets/QUECTEL/BC95/QUECTEL_BC95_CellularPower.h @@ -22,8 +22,7 @@ namespace mbed { -class QUECTEL_BC95_CellularPower : public AT_CellularPower -{ +class QUECTEL_BC95_CellularPower : public AT_CellularPower { public: QUECTEL_BC95_CellularPower(ATHandler &atHandler); virtual ~QUECTEL_BC95_CellularPower(); diff --git a/features/cellular/framework/targets/QUECTEL/BC95/QUECTEL_BC95_CellularStack.cpp b/features/cellular/framework/targets/QUECTEL/BC95/QUECTEL_BC95_CellularStack.cpp index b8c3bcc13cab..ff49bcd41a4f 100644 --- a/features/cellular/framework/targets/QUECTEL/BC95/QUECTEL_BC95_CellularStack.cpp +++ b/features/cellular/framework/targets/QUECTEL/BC95/QUECTEL_BC95_CellularStack.cpp @@ -43,7 +43,7 @@ nsapi_error_t QUECTEL_BC95_CellularStack::socket_accept(void *server, void **soc void QUECTEL_BC95_CellularStack::urc_nsonmi() { - int sock_id =_at.read_int(); + int sock_id = _at.read_int(); for (int i = 0; i < get_max_socket_count(); i++) { CellularSocket *sock = _socket[i]; @@ -137,12 +137,12 @@ nsapi_error_t QUECTEL_BC95_CellularStack::create_socket_impl(CellularSocket *soc } nsapi_size_or_error_t QUECTEL_BC95_CellularStack::socket_sendto_impl(CellularSocket *socket, const SocketAddress &address, - const void *data, nsapi_size_t size) + const void *data, nsapi_size_t size) { int sent_len = 0; - char *hexstr = new char[size*2+1]; - int hexlen = char_str_to_hex_str((const char*)data, size, hexstr); + char *hexstr = new char[size * 2 + 1]; + int hexlen = char_str_to_hex_str((const char *)data, size, hexstr); // NULL terminated for write_string hexstr[hexlen] = 0; _at.cmd_start("AT+NSOST="); @@ -168,9 +168,9 @@ nsapi_size_or_error_t QUECTEL_BC95_CellularStack::socket_sendto_impl(CellularSoc } nsapi_size_or_error_t QUECTEL_BC95_CellularStack::socket_recvfrom_impl(CellularSocket *socket, SocketAddress *address, - void *buffer, nsapi_size_t size) + void *buffer, nsapi_size_t size) { - nsapi_size_or_error_t recv_len=0; + nsapi_size_or_error_t recv_len = 0; int port; char ip_address[NSAPI_IP_SIZE]; @@ -184,7 +184,7 @@ nsapi_size_or_error_t QUECTEL_BC95_CellularStack::socket_recvfrom_impl(CellularS _at.read_string(ip_address, sizeof(ip_address)); port = _at.read_int(); recv_len = _at.read_int(); - int hexlen = _at.read_hex_string((char*)buffer, size); + int hexlen = _at.read_hex_string((char *)buffer, size); // remaining length _at.skip_param(); _at.resp_stop(); diff --git a/features/cellular/framework/targets/QUECTEL/BC95/QUECTEL_BC95_CellularStack.h b/features/cellular/framework/targets/QUECTEL/BC95/QUECTEL_BC95_CellularStack.h index 91dc7499a93e..b4967edd373a 100644 --- a/features/cellular/framework/targets/QUECTEL/BC95/QUECTEL_BC95_CellularStack.h +++ b/features/cellular/framework/targets/QUECTEL/BC95/QUECTEL_BC95_CellularStack.h @@ -24,8 +24,7 @@ namespace mbed { -class QUECTEL_BC95_CellularStack : public AT_CellularStack -{ +class QUECTEL_BC95_CellularStack : public AT_CellularStack { public: QUECTEL_BC95_CellularStack(ATHandler &atHandler, int cid, nsapi_ip_stack_t stack_type); virtual ~QUECTEL_BC95_CellularStack(); @@ -35,7 +34,7 @@ class QUECTEL_BC95_CellularStack : public AT_CellularStack virtual nsapi_error_t socket_listen(nsapi_socket_t handle, int backlog); virtual nsapi_error_t socket_accept(nsapi_socket_t server, - nsapi_socket_t *handle, SocketAddress *address=0); + nsapi_socket_t *handle, SocketAddress *address = 0); protected: // AT_CellularStack @@ -48,10 +47,10 @@ class QUECTEL_BC95_CellularStack : public AT_CellularStack virtual nsapi_error_t create_socket_impl(CellularSocket *socket); virtual nsapi_size_or_error_t socket_sendto_impl(CellularSocket *socket, const SocketAddress &address, - const void *data, nsapi_size_t size); + const void *data, nsapi_size_t size); virtual nsapi_size_or_error_t socket_recvfrom_impl(CellularSocket *socket, SocketAddress *address, - void *buffer, nsapi_size_t size); + void *buffer, nsapi_size_t size); private: // URC handlers diff --git a/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96.h b/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96.h index 99a8b2d36492..725b14c2a134 100644 --- a/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96.h +++ b/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96.h @@ -20,11 +20,9 @@ #include "AT_CellularDevice.h" -namespace mbed -{ +namespace mbed { -class QUECTEL_BG96 : public AT_CellularDevice -{ +class QUECTEL_BG96 : public AT_CellularDevice { public: QUECTEL_BG96(events::EventQueue &queue); diff --git a/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularNetwork.h b/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularNetwork.h index 991799aaedb4..1504b9d1c543 100644 --- a/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularNetwork.h +++ b/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularNetwork.h @@ -22,8 +22,7 @@ namespace mbed { -class QUECTEL_BG96_CellularNetwork : public AT_CellularNetwork -{ +class QUECTEL_BG96_CellularNetwork : public AT_CellularNetwork { public: QUECTEL_BG96_CellularNetwork(ATHandler &atHandler); virtual ~QUECTEL_BG96_CellularNetwork(); diff --git a/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularPower.h b/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularPower.h index 014e4fe714d0..ec7368cbfe53 100644 --- a/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularPower.h +++ b/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularPower.h @@ -20,11 +20,9 @@ #include "AT_CellularPower.h" -namespace mbed -{ +namespace mbed { -class QUECTEL_BG96_CellularPower : public AT_CellularPower -{ +class QUECTEL_BG96_CellularPower : public AT_CellularPower { public: QUECTEL_BG96_CellularPower(ATHandler &atHandler); diff --git a/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularStack.cpp b/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularStack.cpp index deb03b55e851..bc570afa12b1 100644 --- a/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularStack.cpp +++ b/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularStack.cpp @@ -41,11 +41,11 @@ nsapi_error_t QUECTEL_BG96_CellularStack::socket_accept(void *server, void **soc void QUECTEL_BG96_CellularStack::urc_qiurc() { - int sock_id=0; + int sock_id = 0; _at.lock(); (void) _at.skip_param(); - sock_id = _at.read_int(); + sock_id = _at.read_int(); _at.unlock(); for (int i = 0; i < get_max_socket_count(); i++) { @@ -178,7 +178,7 @@ nsapi_error_t QUECTEL_BG96_CellularStack::create_socket_impl(CellularSocket *soc } nsapi_size_or_error_t QUECTEL_BG96_CellularStack::socket_sendto_impl(CellularSocket *socket, const SocketAddress &address, - const void *data, nsapi_size_t size) + const void *data, nsapi_size_t size) { int sent_len = 0; int sent_len_before = 0; @@ -203,7 +203,7 @@ nsapi_size_or_error_t QUECTEL_BG96_CellularStack::socket_sendto_impl(CellularSoc _at.cmd_stop(); _at.resp_start(">"); - _at.write_bytes((uint8_t*)data, size); + _at.write_bytes((uint8_t *)data, size); _at.resp_start(); _at.set_stop_tag("\r\n"); _at.resp_stop(); @@ -227,9 +227,9 @@ nsapi_size_or_error_t QUECTEL_BG96_CellularStack::socket_sendto_impl(CellularSoc } nsapi_size_or_error_t QUECTEL_BG96_CellularStack::socket_recvfrom_impl(CellularSocket *socket, SocketAddress *address, - void *buffer, nsapi_size_t size) + void *buffer, nsapi_size_t size) { - nsapi_size_or_error_t recv_len=0; + nsapi_size_or_error_t recv_len = 0; int port; char ip_address[NSAPI_IP_SIZE + 1]; @@ -242,7 +242,7 @@ nsapi_size_or_error_t QUECTEL_BG96_CellularStack::socket_recvfrom_impl(CellularS _at.read_string(ip_address, sizeof(ip_address)); port = _at.read_int(); if (recv_len > 0) { - _at.read_bytes((uint8_t*)buffer, recv_len); + _at.read_bytes((uint8_t *)buffer, recv_len); } _at.resp_stop(); diff --git a/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularStack.h b/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularStack.h index 1553e00153c8..cbc870f69509 100644 --- a/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularStack.h +++ b/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularStack.h @@ -25,8 +25,7 @@ namespace mbed { #define BG96_SOCKET_MAX 12 #define BG96_CREATE_SOCKET_TIMEOUT 150000 //150 seconds -class QUECTEL_BG96_CellularStack : public AT_CellularStack -{ +class QUECTEL_BG96_CellularStack : public AT_CellularStack { public: QUECTEL_BG96_CellularStack(ATHandler &atHandler, int cid, nsapi_ip_stack_t stack_type); virtual ~QUECTEL_BG96_CellularStack(); @@ -36,7 +35,7 @@ class QUECTEL_BG96_CellularStack : public AT_CellularStack virtual nsapi_error_t socket_listen(nsapi_socket_t handle, int backlog); virtual nsapi_error_t socket_accept(nsapi_socket_t server, - nsapi_socket_t *handle, SocketAddress *address=0); + nsapi_socket_t *handle, SocketAddress *address = 0); protected: // AT_CellularStack @@ -49,10 +48,10 @@ class QUECTEL_BG96_CellularStack : public AT_CellularStack virtual nsapi_error_t create_socket_impl(CellularSocket *socket); virtual nsapi_size_or_error_t socket_sendto_impl(CellularSocket *socket, const SocketAddress &address, - const void *data, nsapi_size_t size); + const void *data, nsapi_size_t size); virtual nsapi_size_or_error_t socket_recvfrom_impl(CellularSocket *socket, SocketAddress *address, - void *buffer, nsapi_size_t size); + void *buffer, nsapi_size_t size); private: // URC handlers diff --git a/features/cellular/framework/targets/QUECTEL/UG96/QUECTEL_UG96.h b/features/cellular/framework/targets/QUECTEL/UG96/QUECTEL_UG96.h index 7c87575d2f86..0a130f1e60d0 100644 --- a/features/cellular/framework/targets/QUECTEL/UG96/QUECTEL_UG96.h +++ b/features/cellular/framework/targets/QUECTEL/UG96/QUECTEL_UG96.h @@ -30,8 +30,7 @@ namespace mbed { #define CELLULAR_SERIAL_RX PC_0 #endif -class QUECTEL_UG96 : public AT_CellularDevice -{ +class QUECTEL_UG96 : public AT_CellularDevice { public: QUECTEL_UG96(events::EventQueue &queue); diff --git a/features/cellular/framework/targets/QUECTEL/UG96/QUECTEL_UG96_CellularNetwork.h b/features/cellular/framework/targets/QUECTEL/UG96/QUECTEL_UG96_CellularNetwork.h index 5a0cd56a1f2b..bf5e223c97db 100644 --- a/features/cellular/framework/targets/QUECTEL/UG96/QUECTEL_UG96_CellularNetwork.h +++ b/features/cellular/framework/targets/QUECTEL/UG96/QUECTEL_UG96_CellularNetwork.h @@ -22,8 +22,7 @@ namespace mbed { -class QUECTEL_UG96_CellularNetwork : public AT_CellularNetwork -{ +class QUECTEL_UG96_CellularNetwork : public AT_CellularNetwork { public: QUECTEL_UG96_CellularNetwork(ATHandler &atHandler); virtual ~QUECTEL_UG96_CellularNetwork(); diff --git a/features/cellular/framework/targets/QUECTEL/UG96/QUECTEL_UG96_CellularPower.h b/features/cellular/framework/targets/QUECTEL/UG96/QUECTEL_UG96_CellularPower.h index f9bb4511904f..f28943c97df9 100644 --- a/features/cellular/framework/targets/QUECTEL/UG96/QUECTEL_UG96_CellularPower.h +++ b/features/cellular/framework/targets/QUECTEL/UG96/QUECTEL_UG96_CellularPower.h @@ -22,8 +22,7 @@ namespace mbed { -class QUECTEL_UG96_CellularPower : public AT_CellularPower -{ +class QUECTEL_UG96_CellularPower : public AT_CellularPower { public: QUECTEL_UG96_CellularPower(ATHandler &atHandler); virtual ~QUECTEL_UG96_CellularPower(); diff --git a/features/cellular/framework/targets/TELIT/HE910/TELIT_HE910.h b/features/cellular/framework/targets/TELIT/HE910/TELIT_HE910.h index efba7204956a..72a71102b980 100644 --- a/features/cellular/framework/targets/TELIT/HE910/TELIT_HE910.h +++ b/features/cellular/framework/targets/TELIT/HE910/TELIT_HE910.h @@ -25,8 +25,7 @@ namespace mbed { -class TELIT_HE910 : public AT_CellularDevice -{ +class TELIT_HE910 : public AT_CellularDevice { public: TELIT_HE910(events::EventQueue &queue); diff --git a/features/cellular/framework/targets/TELIT/HE910/TELIT_HE910_CellularNetwork.h b/features/cellular/framework/targets/TELIT/HE910/TELIT_HE910_CellularNetwork.h index 74cb44bf9561..ce33b5f728b0 100644 --- a/features/cellular/framework/targets/TELIT/HE910/TELIT_HE910_CellularNetwork.h +++ b/features/cellular/framework/targets/TELIT/HE910/TELIT_HE910_CellularNetwork.h @@ -22,8 +22,7 @@ namespace mbed { -class TELIT_HE910_CellularNetwork : public AT_CellularNetwork -{ +class TELIT_HE910_CellularNetwork : public AT_CellularNetwork { public: TELIT_HE910_CellularNetwork(ATHandler &atHandler); virtual ~TELIT_HE910_CellularNetwork(); diff --git a/features/cellular/framework/targets/TELIT/HE910/TELIT_HE910_CellularPower.h b/features/cellular/framework/targets/TELIT/HE910/TELIT_HE910_CellularPower.h index 885746a1e1ba..e60f1620cecc 100644 --- a/features/cellular/framework/targets/TELIT/HE910/TELIT_HE910_CellularPower.h +++ b/features/cellular/framework/targets/TELIT/HE910/TELIT_HE910_CellularPower.h @@ -22,8 +22,7 @@ namespace mbed { -class TELIT_HE910_CellularPower : public AT_CellularPower -{ +class TELIT_HE910_CellularPower : public AT_CellularPower { public: TELIT_HE910_CellularPower(ATHandler &atHandler); virtual ~TELIT_HE910_CellularPower(); diff --git a/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT.cpp b/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT.cpp new file mode 100644 index 000000000000..c525557050d7 --- /dev/null +++ b/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2018, Arm Limited and affiliates. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "UBLOX_AT.h" +#include "UBLOX_AT_CellularNetwork.h" +#include "UBLOX_AT_CellularPower.h" + +using namespace mbed; +using namespace events; + +UBLOX_AT::UBLOX_AT(EventQueue &queue) : AT_CellularDevice(queue) +{ +} + +UBLOX_AT::~UBLOX_AT() +{ +} + +CellularNetwork *UBLOX_AT::open_network(FileHandle *fh) +{ + if (!_network) { + ATHandler *atHandler = get_at_handler(fh); + if (atHandler) { + _network = new UBLOX_AT_CellularNetwork(*atHandler); + if (!_network) { + release_at_handler(atHandler); + } + } + } + return _network; +} + +CellularPower *UBLOX_AT::open_power(FileHandle *fh) +{ + if (!_power) { + ATHandler *atHandler = get_at_handler(fh); + if (atHandler) { + _power = new UBLOX_AT_CellularPower(*atHandler); + if (!_power) { + release_at_handler(atHandler); + } + } + } + return _power; +} diff --git a/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT.h b/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT.h new file mode 100644 index 000000000000..1f47e249fc29 --- /dev/null +++ b/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2018, Arm Limited and affiliates. + * 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 UBLOX_AT_H_ +#define UBLOX_AT_H_ + +#include "AT_CellularDevice.h" + +namespace mbed +{ + +class UBLOX_AT : public AT_CellularDevice +{ + +public: + UBLOX_AT(events::EventQueue &queue); + virtual ~UBLOX_AT(); + +public: // CellularDevice + virtual CellularNetwork *open_network(FileHandle *fh); + virtual CellularPower *open_power(FileHandle *fh); + +public: // NetworkInterface + void handle_urc(FileHandle *fh); +}; + +} // namespace mbed + +#endif // UBLOX_AT_H_ diff --git a/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT_CellularNetwork.cpp b/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT_CellularNetwork.cpp new file mode 100644 index 000000000000..6fd9c6523f34 --- /dev/null +++ b/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT_CellularNetwork.cpp @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2018, Arm Limited and affiliates. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "UBLOX_AT_CellularNetwork.h" +#include "UBLOX_AT_CellularStack.h" + +using namespace mbed; + +UBLOX_AT_CellularNetwork::UBLOX_AT_CellularNetwork(ATHandler &atHandler) : AT_CellularNetwork(atHandler) +{ + _op_act = RAT_UNKNOWN; + // The authentication to use + _auth = NSAPI_SECURITY_UNKNOWN; +} + +UBLOX_AT_CellularNetwork::~UBLOX_AT_CellularNetwork() +{ + if (_connection_status_cb) { + _connection_status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_ERROR_CONNECTION_LOST); + } +} + +NetworkStack *UBLOX_AT_CellularNetwork::get_stack() +{ + if (!_stack) { + _stack = new UBLOX_AT_CellularStack(_at, _cid, _ip_stack_type); + } + return _stack; +} + +bool UBLOX_AT_CellularNetwork::get_modem_stack_type(nsapi_ip_stack_t requested_stack) +{ + return requested_stack == IPV4_STACK ? true : false; +} + +bool UBLOX_AT_CellularNetwork::has_registration(RegistrationType reg_type) +{ + return (reg_type == C_REG || reg_type == C_GREG); +} + +nsapi_error_t UBLOX_AT_CellularNetwork::set_access_technology_impl(RadioAccessTechnology opRat) +{ + switch(opRat) { +#if defined(TARGET_UBLOX_C030_U201) || defined(TARGET_UBLOX_C027) + case RAT_GSM: + case RAT_GSM_COMPACT: + break; + case RAT_EGPRS: + break; +#elif defined(TARGET_UBLOX_C030_U201) + case RAT_UTRAN: + break; + case RAT_HSDPA: + break; + case RAT_HSUPA: + break; + case RAT_HSDPA_HSUPA: + break; +#elif defined(TARGET_UBLOX_C030_R410M) + case RAT_CATM1: + break; +#elif defined(TARGET_UBLOX_C030_R410M) || defined(TARGET_UBLOX_C030_N211) + case RAT_NB1: + break; +#endif + default: { + _op_act = RAT_UNKNOWN; + return NSAPI_ERROR_UNSUPPORTED; + } + } + + return NSAPI_ERROR_OK; +} + +nsapi_error_t UBLOX_AT_CellularNetwork::connect() +{ + _at.lock(); + nsapi_error_t err = NSAPI_ERROR_NO_CONNECTION; + + // Attempt to establish a connection +#ifdef TARGET_UBLOX_C030_R410M + err = NSAPI_ERROR_OK; +#else + err = open_data_channel(); +#endif + if (err != NSAPI_ERROR_OK) { + // If new PSD context was created and failed to activate, delete it + if (_new_context_set) { + disconnect_modem_stack(); + } + _connect_status = NSAPI_STATUS_DISCONNECTED; + } else { + _connect_status = NSAPI_STATUS_GLOBAL_UP; + } + _at.unlock(); + + if (_connection_status_cb) { + _connection_status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, _connect_status); + } + + return err; +} + +nsapi_error_t UBLOX_AT_CellularNetwork::open_data_channel() +{ + bool success = false; + int active = 0; + char * config = NULL; + nsapi_error_t err = NSAPI_ERROR_NO_CONNECTION; + char imsi[MAX_IMSI_LENGTH+1]; + + // do check for stack to validate that we have support for stack + _stack = get_stack(); + if (!_stack) { + return err; + } + + _at.cmd_start("AT+UPSND=" PROFILE ",8"); + _at.cmd_stop(); + _at.resp_start("+UPSND:"); + _at.read_int(); + _at.read_int(); + active = _at.read_int(); + _at.resp_stop(); + + if (active == 0) { + // If the caller hasn't entered an APN, try to find it + if (_apn == NULL) { + err = get_imsi(imsi); + if (err == NSAPI_ERROR_OK) { + config = (char*)apnconfig(imsi); + } + } + + // Attempt to connect + do { + get_next_credentials(&config); + if(_uname && _pwd) { + _auth = (*_uname && *_pwd) ? _auth : NSAPI_SECURITY_NONE; + } else { + _auth = NSAPI_SECURITY_NONE; + } + success = activate_profile(_apn, _uname, _pwd); + } while (!success && config && *config); + } else { + // If the profile is already active, we're good + success = true; + } + + err = (_at.get_last_error() == NSAPI_ERROR_OK) ? NSAPI_ERROR_OK : NSAPI_ERROR_NO_CONNECTION; + + return err; +} + +bool UBLOX_AT_CellularNetwork::activate_profile(const char* apn, + const char* username, + const char* password) +{ + bool activated = false; + bool success = false; + + // Set up the APN + if (apn) { + success = false; + _at.cmd_start("AT+UPSD=0,1,"); + _at.write_string(apn); + _at.cmd_stop(); + _at.resp_start(); + _at.resp_stop(); + + if (_at.get_last_error() == NSAPI_ERROR_OK) { + success = true; + } + } + // Set up the UserName + if (success && username) { + success = false; + _at.cmd_start("AT+UPSD=" PROFILE ",2,"); + _at.write_string(username); + _at.cmd_stop(); + _at.resp_start(); + _at.resp_stop(); + + if (_at.get_last_error() == NSAPI_ERROR_OK) { + success = true; + } + } + // Set up the Password + if (success && password) { + success = false; + _at.cmd_start("AT+UPSD=" PROFILE ",3,"); + _at.write_string(password); + _at.cmd_stop(); + _at.resp_start(); + _at.resp_stop(); + + if (_at.get_last_error() == NSAPI_ERROR_OK) { + success = true; + } + } + + if (success) { + _at.cmd_start("AT+UPSD=" PROFILE ",7,\"0.0.0.0\""); + _at.cmd_stop(); + _at.resp_start(); + _at.resp_stop(); + + // Set up the authentication protocol + // 0 = none + // 1 = PAP (Password Authentication Protocol) + // 2 = CHAP (Challenge Handshake Authentication Protocol) + for (int protocol = nsapi_security_to_modem_security(NSAPI_SECURITY_NONE); + success && (protocol <= nsapi_security_to_modem_security(NSAPI_SECURITY_CHAP)); protocol++) { + if ((_auth == NSAPI_SECURITY_UNKNOWN) || (nsapi_security_to_modem_security(_auth) == protocol)) { + _at.cmd_start("AT+UPSD=0,6,"); + _at.write_int(protocol); + _at.cmd_stop(); + _at.resp_start(); + _at.resp_stop(); + + if (_at.get_last_error() == NSAPI_ERROR_OK) { + // Activate, wait upto 30 seconds for the connection to be made + _at.set_at_timeout(30000); + _at.cmd_start("AT+UPSDA=0,3"); + _at.cmd_stop(); + _at.resp_start(); + _at.resp_stop(); + _at.restore_at_timeout(); + + if (_at.get_last_error() == NSAPI_ERROR_OK) { + activated = true; + } + } + } + } + } + + return activated; +} + +// Convert nsapi_security_t to the modem security numbers +int UBLOX_AT_CellularNetwork::nsapi_security_to_modem_security(nsapi_security_t nsapi_security) +{ + int modem_security = 3; + + switch (nsapi_security) { + case NSAPI_SECURITY_NONE: + modem_security = 0; + break; + case NSAPI_SECURITY_PAP: + modem_security = 1; + break; + case NSAPI_SECURITY_CHAP: + modem_security = 2; + break; + case NSAPI_SECURITY_UNKNOWN: + modem_security = 3; + break; + default: + modem_security = 3; + break; + } + + return modem_security; +} + +// Disconnect the on board IP stack of the modem. +bool UBLOX_AT_CellularNetwork::disconnect_modem_stack() +{ + bool success = false; + + if (get_ip_address() != NULL) { + _at.cmd_start("AT+UPSDA=" PROFILE ",4"); + _at.cmd_stop(); + _at.resp_start(); + _at.resp_stop(); + + if (_at.get_last_error() == NSAPI_ERROR_OK) { + success = true; + } + } + + return success; +} + +nsapi_error_t UBLOX_AT_CellularNetwork::get_imsi(char* imsi) +{ + _at.lock(); + _at.cmd_start("AT+CIMI"); + _at.cmd_stop(); + _at.resp_start(); + int len = _at.read_string(imsi, MAX_IMSI_LENGTH); + if (len > 0) { + imsi[len] = '\0'; + } + _at.resp_stop(); + + return _at.unlock_return_error(); +} + +// Get the next set of credentials, based on IMSI. +void UBLOX_AT_CellularNetwork::get_next_credentials(char ** config) +{ + if (*config) { + _apn = _APN_GET(*config); + _uname = _APN_GET(*config); + _pwd = _APN_GET(*config); + } +} + +const char *UBLOX_AT_CellularNetwork::get_gateway() +{ + return get_ip_address(); +} diff --git a/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT_CellularNetwork.h b/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT_CellularNetwork.h new file mode 100644 index 000000000000..dde417a80d2b --- /dev/null +++ b/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT_CellularNetwork.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2018, Arm Limited and affiliates. + * 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 UBLOX_AT_CELLULAR_NETWORK_H_ +#define UBLOX_AT_CELLULAR_NETWORK_H_ + +#include "AT_CellularNetwork.h" +#include "APN_db.h" + +namespace mbed +{ + +class UBLOX_AT_CellularNetwork : public AT_CellularNetwork +{ +public: + UBLOX_AT_CellularNetwork(ATHandler &atHandler); + virtual ~UBLOX_AT_CellularNetwork(); + + virtual nsapi_error_t connect(); + + virtual const char *get_gateway(); + +protected: + virtual NetworkStack *get_stack(); + + virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology opRat); + + virtual bool get_modem_stack_type(nsapi_ip_stack_t requested_stack); + + virtual bool has_registration(RegistrationType rat); + +private: + + /** Length of IMSI buffer. + */ + static const int MAX_IMSI_LENGTH = 15; + + /** The type of authentication to use. + */ + nsapi_security_t _auth; + + /** Connect the on board IP stack of the modem. + * + * @return True if successful, otherwise false. + */ + nsapi_error_t open_data_channel(); + + /** Activate one of the on-board modem's connection profiles. + * + * @param apn The APN to use. + * @param username The user name to use. + * @param password The password to use. + * @param auth The authentication method to use + * (NSAPI_SECURITY_NONE, NSAPI_SECURITY_PAP, + * NSAPI_SECURITY_CHAP or NSAPI_SECURITY_UNKNOWN). + * @return True if successful, otherwise false. + */ + bool activate_profile(const char* apn, const char* username, const char* password); + + /** Convert nsapi_security_t to the modem security numbers. + * + * @param nsapi_security Security protocol. + * @return Modem security numbers. + */ + int nsapi_security_to_modem_security(nsapi_security_t nsapi_security); + + /** Disconnect the on board IP stack of the modem. + * + * @return True if successful, otherwise false. + */ + bool disconnect_modem_stack(); + + /** Read IMSI of modem. + */ + nsapi_error_t get_imsi(char* imsi); + + /** Get the next set of credentials from the database. + */ + void get_next_credentials(char ** config); +}; + +} // namespace mbed + +#endif // UBLOX_AT_CELLULAR_NETWORK_H_ diff --git a/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT_CellularPower.cpp b/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT_CellularPower.cpp new file mode 100644 index 000000000000..aaec18f084ec --- /dev/null +++ b/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT_CellularPower.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2018, Arm Limited and affiliates. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "UBLOX_AT_CellularPower.h" + +#include "onboard_modem_api.h" + +using namespace mbed; + +UBLOX_AT_CellularPower::UBLOX_AT_CellularPower(ATHandler &atHandler) : AT_CellularPower(atHandler) +{ +} + +UBLOX_AT_CellularPower::~UBLOX_AT_CellularPower() +{ +} + +nsapi_error_t UBLOX_AT_CellularPower::on() +{ +#if MODEM_ON_BOARD + ::onboard_modem_init(); + ::onboard_modem_power_up(); +#endif + return NSAPI_ERROR_OK; +} + +nsapi_error_t UBLOX_AT_CellularPower::off() +{ +#if MODEM_ON_BOARD + ::onboard_modem_power_down(); +#endif + return NSAPI_ERROR_OK; +} diff --git a/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT_CellularPower.h b/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT_CellularPower.h new file mode 100644 index 000000000000..7ac016a1bfea --- /dev/null +++ b/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT_CellularPower.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2018, Arm Limited and affiliates. + * 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 UBLOX_AT_CELLULARPOWER_H_ +#define UBLOX_AT_CELLULARPOWER_H_ + +#include "AT_CellularPower.h" + +namespace mbed +{ + +class UBLOX_AT_CellularPower : public AT_CellularPower +{ +public: + UBLOX_AT_CellularPower(ATHandler &atHandler); + virtual ~UBLOX_AT_CellularPower(); + +public: //from CellularPower + + virtual nsapi_error_t on(); + + virtual nsapi_error_t off(); +}; + +} // namespace mbed + +#endif // UBLOX_AT_CELLULARPOWER_H_ diff --git a/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT_CellularStack.cpp b/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT_CellularStack.cpp new file mode 100644 index 000000000000..e35c49046cc0 --- /dev/null +++ b/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT_CellularStack.cpp @@ -0,0 +1,501 @@ +/* + * Copyright (c) 2018, Arm Limited and affiliates. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "UBLOX_AT_CellularStack.h" +#include "mbed_poll.h" + +using namespace mbed; +using namespace mbed_cellular_util; + +UBLOX_AT_CellularStack::UBLOX_AT_CellularStack(ATHandler &atHandler, int cid, nsapi_ip_stack_t stack_type) : AT_CellularStack(atHandler, cid, stack_type) +{ + // URC handlers for sockets + _at.set_urc_handler("+UUSORD:", callback(this, &UBLOX_AT_CellularStack::UUSORD_URC)); + _at.set_urc_handler("+UUSORF:", callback(this, &UBLOX_AT_CellularStack::UUSORF_URC)); + _at.set_urc_handler("+UUSOCL:", callback(this, &UBLOX_AT_CellularStack::UUSOCL_URC)); + _at.set_urc_handler("+UUPSDD:", callback(this, &UBLOX_AT_CellularStack::UUPSDD_URC)); +} + +UBLOX_AT_CellularStack::~UBLOX_AT_CellularStack() +{ +} + +nsapi_error_t UBLOX_AT_CellularStack::socket_listen(nsapi_socket_t handle, int backlog) +{ + return NSAPI_ERROR_UNSUPPORTED; +} + +nsapi_error_t UBLOX_AT_CellularStack::socket_accept(void *server, void **socket, SocketAddress *addr) +{ + return NSAPI_ERROR_UNSUPPORTED; +} + +// Callback for Socket Read URC. +void UBLOX_AT_CellularStack::UUSORD_URC() +{ + int a,b; + CellularSocket *socket; + + a =_at.read_int(); + b =_at.read_int(); + + socket = find_socket(a); + if (socket != NULL) { + socket->pending_bytes = b; + // No debug prints here as they can affect timing + // and cause data loss in UARTSerial + if (socket->_cb != NULL) { + socket->_cb(socket->_data); + } + } +} + +// Callback for Socket Read From URC. +void UBLOX_AT_CellularStack::UUSORF_URC() +{ + int a,b; + CellularSocket *socket; + + a =_at.read_int(); + b =_at.read_int(); + + socket = find_socket(a); + if (socket != NULL) { + socket->pending_bytes = b; + // No debug prints here as they can affect timing + // and cause data loss in UARTSerial + if (socket->_cb != NULL) { + socket->_cb(socket->_data); + } + } +} + +// Callback for Socket Close URC. +void UBLOX_AT_CellularStack::UUSOCL_URC() +{ + int a; + CellularSocket *socket; + + a =_at.read_int(); + socket = find_socket(a); + clear_socket(socket); +} + +// Callback for UUPSDD. +void UBLOX_AT_CellularStack::UUPSDD_URC() +{ + int a; + CellularSocket *socket; + + a =_at.read_int(); + socket = find_socket(a); + clear_socket(socket); +} + +int UBLOX_AT_CellularStack::get_max_socket_count() +{ + return UBLOX_MAX_SOCKET; +} + +bool UBLOX_AT_CellularStack::is_protocol_supported(nsapi_protocol_t protocol) +{ + return (protocol == NSAPI_UDP || protocol == NSAPI_TCP); +} + +nsapi_error_t UBLOX_AT_CellularStack::create_socket_impl(CellularSocket *socket) +{ + int sock_id = 0; + bool socketOpenWorking = false; + + _at.lock(); + if (socket->proto == NSAPI_UDP) { + _at.cmd_start("AT+USOCR=17"); + _at.cmd_stop(); + + _at.resp_start("+USOCR:"); + sock_id = _at.read_int(); + _at.resp_stop(); + } else if(socket->proto == NSAPI_TCP) { + _at.cmd_start("AT+USOCR=6"); + _at.cmd_stop(); + + _at.resp_start("+USOCR:"); + sock_id = _at.read_int(); + _at.resp_stop(); + } // Unsupported protocol is checked in "is_protocol_supported" function + _at.unlock(); + + socketOpenWorking = (_at.get_last_error() == NSAPI_ERROR_OK); + if (!socketOpenWorking) { + return NSAPI_ERROR_NO_SOCKET; + } + + // Check for duplicate socket id delivered by modem + for (int i = 0; i < UBLOX_MAX_SOCKET; i++) { + CellularSocket *sock = _socket[i]; + if (sock && sock->created && sock->id == sock_id) { + return NSAPI_ERROR_NO_SOCKET; + } + } + + socket->id = sock_id; + socket->created = true; + + return NSAPI_ERROR_OK; +} + +nsapi_error_t UBLOX_AT_CellularStack::socket_connect(nsapi_socket_t handle, const SocketAddress &addr) +{ + CellularSocket *socket = (CellularSocket *)handle; + + if (!socket->created) { + create_socket_impl(socket); + } + + _at.lock(); + _at.cmd_start("AT+USOCO="); + _at.write_int(socket->id); + _at.write_string(addr.get_ip_address()); + _at.write_int(addr.get_port()); + _at.cmd_stop(); + _at.resp_start(); + _at.resp_stop(); + _at.unlock(); + + if (_at.get_last_error() == NSAPI_ERROR_OK) { + socket->remoteAddress = addr; + socket->connected = true; + return NSAPI_ERROR_OK; + } + + return NSAPI_ERROR_NO_CONNECTION; +} + +nsapi_size_or_error_t UBLOX_AT_CellularStack::socket_sendto_impl(CellularSocket *socket, const SocketAddress &address, + const void *data, nsapi_size_t size) +{ + int sent_len = 0; + uint8_t ch = 0, cont = 50; + + pollfh fhs; + fhs.fh = _at.get_file_handle(); + fhs.events = POLLIN; + int pollCount; + + if (socket->proto == NSAPI_UDP) { + if (size > UBLOX_MAX_PACKET_SIZE) { + return NSAPI_ERROR_PARAMETER; + } + _at.cmd_start("AT+USOST="); + _at.write_int(socket->id); + _at.write_string(address.get_ip_address()); + _at.write_int(address.get_port()); + _at.write_int(size); + _at.cmd_stop(); + pollCount = poll(&fhs, 1, 50); + _at.write_bytes((uint8_t *)data, size); + + _at.resp_start("+USOST:"); + _at.skip_param(); // skip socket id + sent_len = _at.read_int(); + _at.resp_stop(); + + if ((_at.get_last_error() == NSAPI_ERROR_OK)) { + return sent_len; + } + } else if (socket->proto == NSAPI_TCP) { + bool success = true; + const char *buf = (const char *) data; + nsapi_size_t blk = UBLOX_MAX_PACKET_SIZE; + nsapi_size_t count = size; + + while ((count > 0) && success) { + if (count < blk) { + blk = count; + } + _at.cmd_start("AT+USOWR="); + _at.write_int(socket->id); + _at.write_int(blk); + _at.cmd_stop(); + pollCount = poll(&fhs, 1, 50); + _at.write_bytes((uint8_t *)buf, blk); + + _at.resp_start("+USOWR:"); + _at.skip_param(); // skip socket id + sent_len = _at.read_int(); + _at.resp_stop(); + + if ((sent_len >= (int) blk) && + (_at.get_last_error() == NSAPI_ERROR_OK)) { + } else { + success = false; + } + + buf += blk; + count -= blk; + } + + if (success && _at.get_last_error() == NSAPI_ERROR_OK) { + return size - count; + } + } + + return _at.get_last_error(); +} + +nsapi_size_or_error_t UBLOX_AT_CellularStack::socket_recvfrom_impl(CellularSocket *socket, SocketAddress *address, + void *buffer, nsapi_size_t size) +{ + nsapi_size_or_error_t nsapi_error_size = NSAPI_ERROR_DEVICE_ERROR; + bool success = true; + nsapi_size_t read_blk; + nsapi_size_t count = 0; + nsapi_size_t usorf_sz; + char ipAddress[NSAPI_IP_SIZE]; + uint8_t ch = 0; + int port = 0; + Timer timer; + + if (socket->pending_bytes == 0) { + _at.process_oob(); + if (socket->pending_bytes == 0) { + return NSAPI_ERROR_WOULD_BLOCK; + } + } + + timer.start(); + if (socket->proto == NSAPI_UDP) { + while (success && (size > 0)) { + read_blk = UBLOX_MAX_PACKET_SIZE; + if (read_blk > size) { + read_blk = size; + } + if (socket->pending_bytes > 0) { + _at.cmd_start("AT+USORF="); + _at.write_int(socket->id); + _at.write_int(read_blk); + _at.cmd_stop(); + + _at.resp_start("+USORF:"); + _at.skip_param(); // receiving socket id + _at.read_string(ipAddress, sizeof(ipAddress)); + port = _at.read_int(); + usorf_sz = _at.read_int(); + + // Must use what +USORF returns here as it may be less or more than we asked for + if (usorf_sz > socket->pending_bytes) { + socket->pending_bytes = 0; + } else { + socket->pending_bytes -= usorf_sz; + } + + if (usorf_sz > size) { + usorf_sz = size; + } + _at.read_bytes(&ch, 1); + _at.read_bytes((uint8_t *)buffer + count, usorf_sz); + _at.resp_stop(); + + if (usorf_sz > 0) { + count += usorf_sz; + size -= usorf_sz; + } else { + // read() should not fail + success = false; + } + } else if (timer.read_ms() < SOCKET_TIMEOUT) { + // Wait for URCs + _at.process_oob(); + } else { + if (count == 0) { + // Timeout with nothing received + nsapi_error_size = NSAPI_ERROR_WOULD_BLOCK; + success = false; + } + size = 0; // This simply to cause an exit + } + } + } else if (socket->proto == NSAPI_TCP) { + while (success && (size > 0)) { + read_blk = UBLOX_MAX_PACKET_SIZE; + if (read_blk > size) { + read_blk = size; + } + if (socket->pending_bytes > 0) { + _at.cmd_start("AT+USORD="); + _at.write_int(socket->id); + _at.write_int(read_blk); + _at.cmd_stop(); + + _at.resp_start("+USORD:"); + _at.skip_param(); // receiving socket id + usorf_sz = _at.read_int(); + + // Must use what +USORD returns here as it may be less or more than we asked for + if (usorf_sz > socket->pending_bytes) { + socket->pending_bytes = 0; + } else { + socket->pending_bytes -= usorf_sz; + } + + if (usorf_sz > size) { + usorf_sz = size; + } + _at.read_bytes(&ch, 1); + _at.read_bytes((uint8_t *)buffer + count, usorf_sz); + _at.resp_stop(); + + if (usorf_sz > 0) { + count += usorf_sz; + size -= usorf_sz; + } else { + success = false; + } + } else if (timer.read_ms() < SOCKET_TIMEOUT) { + // Wait for URCs + _at.process_oob(); + } else { + if (count == 0) { + // Timeout with nothing received + nsapi_error_size = NSAPI_ERROR_WOULD_BLOCK; + success = false; + } + size = 0; // This simply to cause an exit + } + } + } + timer.stop(); + + socket->pending_bytes = 0; + if (!count || (_at.get_last_error() != NSAPI_ERROR_OK)) { + return NSAPI_ERROR_WOULD_BLOCK; + } else { + nsapi_error_size = count; + } + + if (success && socket->proto == NSAPI_UDP && address) { + address->set_ip_address(ipAddress); + address->get_ip_address(); + address->set_port(port); + } + + return nsapi_error_size; +} + +nsapi_error_t UBLOX_AT_CellularStack::socket_close_impl(int sock_id) +{ + _at.lock(); + _at.cmd_start("AT+USOCL="); + _at.write_int(sock_id); + _at.cmd_stop(); + _at.resp_start(); + _at.resp_stop(); + + return _at.unlock_return_error(); +} + +// Find or create a socket from the list. +UBLOX_AT_CellularStack::CellularSocket * UBLOX_AT_CellularStack::find_socket(int id) +{ + CellularSocket *socket = NULL; + + for (unsigned int x = 0; (socket == NULL) && (x < UBLOX_MAX_SOCKET); x++) { + if (_socket) { + if (_socket[x]->id == id) { + socket = (_socket[x]); + } + } + } + + return socket; +} + + +// Clear out the storage for a socket +void UBLOX_AT_CellularStack::clear_socket(CellularSocket * socket) +{ + if (socket != NULL) { + socket->id = SOCKET_UNUSED; + socket->pending_bytes = 0; + socket->_cb = NULL; + socket->_data = NULL; + socket->created = false; + } +} + +const char * UBLOX_AT_CellularStack::get_ip_address() +{ + _at.lock(); + _at.cmd_start("AT+UPSND=" PROFILE ",0"); + _at.cmd_stop(); + + _at.resp_start("+UPSND:"); + if (_at.info_resp()) { + _at.skip_param(); + _at.skip_param(); + int len = _at.read_string(_ip, NSAPI_IPv4_SIZE-1); + if (len == -1) { + _ip[0] = '\0'; + _at.unlock(); + // no IPV4 address, return + return NULL; + } + + // in case stack type is not IPV4 only, try to look also for IPV6 address + if (_stack_type != IPV4_STACK) { + len = _at.read_string(_ip, PDP_IPV6_SIZE-1); + } + } + _at.resp_stop(); + _at.unlock(); + + // we have at least IPV4 address + convert_ipv6(_ip); + + return _ip; +} + +nsapi_error_t UBLOX_AT_CellularStack::gethostbyname(const char *host, SocketAddress *address, nsapi_version_t version) +{ + char ipAddress[NSAPI_IP_SIZE]; + nsapi_error_t err = NSAPI_ERROR_NO_CONNECTION; + + _at.lock(); + if (address->set_ip_address(host)) { + err = NSAPI_ERROR_OK; + } else { + // This interrogation can sometimes take longer than the usual 8 seconds + _at.cmd_start("AT+UDNSRN=0,"); + _at.write_string(host); + _at.cmd_stop(); + + _at.set_at_timeout(60000); + _at.resp_start("+UDNSRN:"); + if (_at.info_resp()) { + _at.read_string(ipAddress, sizeof(ipAddress)); + + if (address->set_ip_address(ipAddress)) { + err = NSAPI_ERROR_OK; + } + } + _at.resp_stop(); + _at.restore_at_timeout(); + } + _at.unlock(); + + return err; +} diff --git a/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT_CellularStack.h b/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT_CellularStack.h new file mode 100644 index 000000000000..45d5b3846cd8 --- /dev/null +++ b/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT_CellularStack.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2018, Arm Limited and affiliates. + * 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 UBLOX_AT_CELLULARSTACK_H_ +#define UBLOX_AT_CELLULARSTACK_H_ + +#include "AT_CellularStack.h" +#include "CellularUtil.h" +#include "mbed_wait_api.h" +#include "drivers/Timer.h" + + +namespace mbed +{ + +class UBLOX_AT_CellularStack : public AT_CellularStack +{ +public: + UBLOX_AT_CellularStack(ATHandler &atHandler, int cid, nsapi_ip_stack_t stack_type); + virtual ~UBLOX_AT_CellularStack(); + + virtual const char *get_ip_address(); + + virtual nsapi_error_t gethostbyname(const char *host, + SocketAddress *address, nsapi_version_t version = NSAPI_UNSPEC); + +protected: + virtual nsapi_error_t socket_listen(nsapi_socket_t handle, int backlog); + + virtual nsapi_error_t socket_accept(nsapi_socket_t server, + nsapi_socket_t *handle, SocketAddress *address=0); + +protected: // AT_CellularStack + + /** The profile to use (on board the modem). + */ +#define PROFILE "0" + + /** Socket "unused" value. + */ + static const int SOCKET_UNUSED = -1; + + /** Socket timeout value in milliseconds. + * Note: the sockets layer above will retry the + * call to the functions here when they return NSAPI_ERROR_WOULD_BLOCK + * and the user has set a larger timeout or full blocking. + */ + static const int SOCKET_TIMEOUT = 1000; + + /** Maximum allowed sockets. + */ + static const int UBLOX_MAX_SOCKET = 7; + + /** The maximum number of bytes in a packet that can be write/read from + * the AT interface in one go. + */ + static const int UBLOX_MAX_PACKET_SIZE = 1024; + + virtual int get_max_socket_count(); + + virtual bool is_protocol_supported(nsapi_protocol_t protocol); + + virtual nsapi_error_t create_socket_impl(CellularSocket *socket); + + virtual nsapi_error_t socket_connect(nsapi_socket_t handle, const SocketAddress &address); + + virtual nsapi_size_or_error_t socket_sendto_impl(CellularSocket *socket, const SocketAddress &address, + const void *data, nsapi_size_t size); + + virtual nsapi_size_or_error_t socket_recvfrom_impl(CellularSocket *socket, SocketAddress *address, + void *buffer, nsapi_size_t size); + + virtual nsapi_error_t socket_close_impl(int sock_id); + +private: + // URC handlers + void UUSORD_URC(); + void UUSORF_URC(); + void UUSOCL_URC(); + void UUPSDD_URC(); + + /** Find a socket from the list. + * + * @param id Socket ID. + * @return Socket if True, otherwise NULL. + */ + CellularSocket * find_socket(int id = SOCKET_UNUSED); + + /** Clear out the storage for a socket. + * + * @param id Cellular Socket. + * @return None + */ + void clear_socket(CellularSocket * socket); +}; +} // namespace mbed +#endif /* UBLOX_AT_CELLULARSTACK_H_ */ diff --git a/features/cellular/framework/targets/UBLOX/PPP/UBLOX_PPP.h b/features/cellular/framework/targets/UBLOX/PPP/UBLOX_PPP.h index e07d78940a66..4164ba8adb74 100644 --- a/features/cellular/framework/targets/UBLOX/PPP/UBLOX_PPP.h +++ b/features/cellular/framework/targets/UBLOX/PPP/UBLOX_PPP.h @@ -22,8 +22,7 @@ namespace mbed { -class UBLOX_PPP : public AT_CellularDevice -{ +class UBLOX_PPP : public AT_CellularDevice { public: UBLOX_PPP(events::EventQueue &queue); @@ -35,8 +34,7 @@ class UBLOX_PPP : public AT_CellularDevice }; MBED_DEPRECATED_SINCE("mbed-os-5.9", "This API will be deprecated, Use UBLOX_PPP instead of UBLOX_LISA_U.") -class UBLOX_LISA_U : public UBLOX_PPP -{ +class UBLOX_LISA_U : public UBLOX_PPP { }; } // namespace mbed diff --git a/features/cellular/framework/targets/UBLOX/PPP/UBLOX_PPP_CellularNetwork.h b/features/cellular/framework/targets/UBLOX/PPP/UBLOX_PPP_CellularNetwork.h index a1e5db11597d..e6cef58ece17 100644 --- a/features/cellular/framework/targets/UBLOX/PPP/UBLOX_PPP_CellularNetwork.h +++ b/features/cellular/framework/targets/UBLOX/PPP/UBLOX_PPP_CellularNetwork.h @@ -22,8 +22,7 @@ namespace mbed { -class UBLOX_PPP_CellularNetwork : public AT_CellularNetwork -{ +class UBLOX_PPP_CellularNetwork : public AT_CellularNetwork { public: UBLOX_PPP_CellularNetwork(ATHandler &atHandler); virtual ~UBLOX_PPP_CellularNetwork(); @@ -37,8 +36,7 @@ class UBLOX_PPP_CellularNetwork : public AT_CellularNetwork }; MBED_DEPRECATED_SINCE("mbed-os-5.9", "This API will be deprecated, Use UBLOX_PPP_CellularNetwork instead of UBLOX_LISA_U_CellularNetwork.") -class UBLOX_LISA_U_CellularNetwork : public UBLOX_PPP_CellularNetwork -{ +class UBLOX_LISA_U_CellularNetwork : public UBLOX_PPP_CellularNetwork { }; } // namespace mbed diff --git a/features/cellular/framework/targets/UBLOX/PPP/UBLOX_PPP_CellularPower.h b/features/cellular/framework/targets/UBLOX/PPP/UBLOX_PPP_CellularPower.h index dac700a83a0f..1067cb7bd366 100644 --- a/features/cellular/framework/targets/UBLOX/PPP/UBLOX_PPP_CellularPower.h +++ b/features/cellular/framework/targets/UBLOX/PPP/UBLOX_PPP_CellularPower.h @@ -22,8 +22,7 @@ namespace mbed { -class UBLOX_PPP_CellularPower : public AT_CellularPower -{ +class UBLOX_PPP_CellularPower : public AT_CellularPower { public: UBLOX_PPP_CellularPower(ATHandler &atHandler); virtual ~UBLOX_PPP_CellularPower(); @@ -36,8 +35,7 @@ class UBLOX_PPP_CellularPower : public AT_CellularPower }; MBED_DEPRECATED_SINCE("mbed-os-5.9", "This API will be deprecated, Use UBLOX_PPP_CellularPower instead of UBLOX_LISA_U_CellularPower.") -class UBLOX_LISA_U_CellularPower : public UBLOX_PPP_CellularPower -{ +class UBLOX_LISA_U_CellularPower : public UBLOX_PPP_CellularPower { }; } // namespace mbed diff --git a/features/filesystem/Dir.cpp b/features/filesystem/Dir.cpp index 17014e3bae5b..689c070232d9 100644 --- a/features/filesystem/Dir.cpp +++ b/features/filesystem/Dir.cpp @@ -15,9 +15,9 @@ */ #include "Dir.h" -#include "mbed.h" #include +namespace mbed { Dir::Dir() : _fs(0), _dir(0) @@ -92,3 +92,5 @@ size_t Dir::size() MBED_ASSERT(_fs); return _fs->dir_size(_dir); } + +} // namespace mbed diff --git a/features/filesystem/File.cpp b/features/filesystem/File.cpp index e061aedd3018..76bf66aebbd2 100644 --- a/features/filesystem/File.cpp +++ b/features/filesystem/File.cpp @@ -15,9 +15,9 @@ */ #include "File.h" -#include "mbed.h" #include +namespace mbed { File::File() : _fs(0), _file(0) @@ -110,3 +110,4 @@ off_t File::size() return _fs->file_size(_file); } +} // namespace mbed diff --git a/features/filesystem/FileSystem.cpp b/features/filesystem/FileSystem.cpp index 99f98d2fe99a..047f3d7eb082 100644 --- a/features/filesystem/FileSystem.cpp +++ b/features/filesystem/FileSystem.cpp @@ -14,12 +14,12 @@ * limitations under the License. */ -#include "mbed.h" #include "filesystem/Dir.h" #include "filesystem/File.h" #include "filesystem/FileSystem.h" #include +namespace mbed { FileSystem::FileSystem(const char *name) : FileSystemLike(name) @@ -170,3 +170,5 @@ int FileSystem::open(DirHandle **dir, const char *path) { *dir = d; return 0; } + +} // namespace mbed diff --git a/features/filesystem/bd/BufferedBlockDevice.cpp b/features/filesystem/bd/BufferedBlockDevice.cpp index 7fba7c7f7e84..996f2c0bcb39 100644 --- a/features/filesystem/bd/BufferedBlockDevice.cpp +++ b/features/filesystem/bd/BufferedBlockDevice.cpp @@ -16,6 +16,7 @@ #include "BufferedBlockDevice.h" #include "mbed_assert.h" +#include "mbed_critical.h" #include #include @@ -25,7 +26,7 @@ static inline uint32_t align_down(bd_size_t val, bd_size_t size) } BufferedBlockDevice::BufferedBlockDevice(BlockDevice *bd) - : _bd(bd), _bd_program_size(0), _curr_aligned_addr(0), _flushed(true), _cache(0) + : _bd(bd), _bd_program_size(0), _curr_aligned_addr(0), _flushed(true), _cache(0), _init_ref_count(0) { } @@ -36,6 +37,12 @@ BufferedBlockDevice::~BufferedBlockDevice() int BufferedBlockDevice::init() { + uint32_t val = core_util_atomic_incr_u32(&_init_ref_count, 1); + + if (val != 1) { + return BD_ERROR_OK; + } + int err = _bd->init(); if (err) { return err; @@ -55,6 +62,12 @@ int BufferedBlockDevice::init() int BufferedBlockDevice::deinit() { + uint32_t val = core_util_atomic_decr_u32(&_init_ref_count, 1); + + if (val) { + return BD_ERROR_OK; + } + delete[] _cache; _cache = 0; return _bd->deinit(); diff --git a/features/filesystem/bd/BufferedBlockDevice.h b/features/filesystem/bd/BufferedBlockDevice.h index 85aa11766233..52742f78ceb2 100644 --- a/features/filesystem/bd/BufferedBlockDevice.h +++ b/features/filesystem/bd/BufferedBlockDevice.h @@ -153,6 +153,7 @@ class BufferedBlockDevice : public BlockDevice { bd_size_t _curr_aligned_addr; bool _flushed; uint8_t *_cache; + uint32_t _init_ref_count; /** Flush data in cache * diff --git a/features/filesystem/bd/ChainingBlockDevice.cpp b/features/filesystem/bd/ChainingBlockDevice.cpp index f0be36b3145e..fd00fea47366 100644 --- a/features/filesystem/bd/ChainingBlockDevice.cpp +++ b/features/filesystem/bd/ChainingBlockDevice.cpp @@ -15,12 +15,13 @@ */ #include "ChainingBlockDevice.h" +#include "mbed_critical.h" ChainingBlockDevice::ChainingBlockDevice(BlockDevice **bds, size_t bd_count) : _bds(bds), _bd_count(bd_count) , _read_size(0), _program_size(0), _erase_size(0), _size(0) - , _erase_value(-1) + , _erase_value(-1), _init_ref_count(0) { } @@ -31,6 +32,12 @@ static bool is_aligned(uint64_t x, uint64_t alignment) int ChainingBlockDevice::init() { + uint32_t val = core_util_atomic_incr_u32(&_init_ref_count, 1); + + if (val != 1) { + return BD_ERROR_OK; + } + _read_size = 0; _program_size = 0; _erase_size = 0; @@ -83,6 +90,12 @@ int ChainingBlockDevice::init() int ChainingBlockDevice::deinit() { + uint32_t val = core_util_atomic_decr_u32(&_init_ref_count, 1); + + if (val) { + return BD_ERROR_OK; + } + for (size_t i = 0; i < _bd_count; i++) { int err = _bds[i]->deinit(); if (err) { diff --git a/features/filesystem/bd/ChainingBlockDevice.h b/features/filesystem/bd/ChainingBlockDevice.h index ad3c6e884adc..d1d1085e8f2d 100644 --- a/features/filesystem/bd/ChainingBlockDevice.h +++ b/features/filesystem/bd/ChainingBlockDevice.h @@ -64,7 +64,7 @@ class ChainingBlockDevice : public BlockDevice template ChainingBlockDevice(BlockDevice *(&bds)[Size]) : _bds(bds), _bd_count(sizeof(bds) / sizeof(bds[0])) - , _read_size(0), _program_size(0), _erase_size(0), _size(0) + , _read_size(0), _program_size(0), _erase_size(0), _size(0), _init_ref_count(0) { } @@ -175,6 +175,7 @@ class ChainingBlockDevice : public BlockDevice bd_size_t _erase_size; bd_size_t _size; int _erase_value; + uint32_t _init_ref_count; }; diff --git a/features/filesystem/bd/ExhaustibleBlockDevice.cpp b/features/filesystem/bd/ExhaustibleBlockDevice.cpp index 2c5ed3d104a5..a7bb0bc05db9 100644 --- a/features/filesystem/bd/ExhaustibleBlockDevice.cpp +++ b/features/filesystem/bd/ExhaustibleBlockDevice.cpp @@ -16,10 +16,11 @@ #include "ExhaustibleBlockDevice.h" #include "mbed.h" +#include "mbed_critical.h" ExhaustibleBlockDevice::ExhaustibleBlockDevice(BlockDevice *bd, uint32_t erase_cycles) - : _bd(bd), _erase_array(NULL), _erase_cycles(erase_cycles) + : _bd(bd), _erase_array(NULL), _erase_cycles(erase_cycles), _init_ref_count(0) { } @@ -30,6 +31,12 @@ ExhaustibleBlockDevice::~ExhaustibleBlockDevice() int ExhaustibleBlockDevice::init() { + uint32_t val = core_util_atomic_incr_u32(&_init_ref_count, 1); + + if (val != 1) { + return BD_ERROR_OK; + } + int err = _bd->init(); if (err) { return err; @@ -48,6 +55,12 @@ int ExhaustibleBlockDevice::init() int ExhaustibleBlockDevice::deinit() { + core_util_atomic_decr_u32(&_init_ref_count, 1); + + if (_init_ref_count) { + return BD_ERROR_OK; + } + // _erase_array is lazily cleaned up in destructor to allow // data to live across de/reinitialization return _bd->deinit(); diff --git a/features/filesystem/bd/ExhaustibleBlockDevice.h b/features/filesystem/bd/ExhaustibleBlockDevice.h index e55f662fe945..55b0041a7ccf 100644 --- a/features/filesystem/bd/ExhaustibleBlockDevice.h +++ b/features/filesystem/bd/ExhaustibleBlockDevice.h @@ -154,6 +154,7 @@ class ExhaustibleBlockDevice : public BlockDevice BlockDevice *_bd; uint32_t *_erase_array; uint32_t _erase_cycles; + uint32_t _init_ref_count; }; diff --git a/features/filesystem/bd/FlashSimBlockDevice.cpp b/features/filesystem/bd/FlashSimBlockDevice.cpp index 35bb8b69f4c1..631ea42b7c14 100644 --- a/features/filesystem/bd/FlashSimBlockDevice.cpp +++ b/features/filesystem/bd/FlashSimBlockDevice.cpp @@ -16,6 +16,7 @@ #include "FlashSimBlockDevice.h" #include "mbed_assert.h" +#include "mbed_critical.h" #include #include #include @@ -29,7 +30,7 @@ static inline uint32_t align_up(bd_size_t val, bd_size_t size) FlashSimBlockDevice::FlashSimBlockDevice(BlockDevice *bd, uint8_t erase_value) : _erase_value(erase_value), _blank_buf_size(0), - _blank_buf(0), _bd(bd) + _blank_buf(0), _bd(bd), _init_ref_count(0) { } @@ -41,6 +42,12 @@ FlashSimBlockDevice::~FlashSimBlockDevice() int FlashSimBlockDevice::init() { + uint32_t val = core_util_atomic_incr_u32(&_init_ref_count, 1); + + if (val != 1) { + return BD_ERROR_OK; + } + int ret = _bd->init(); if (ret) { return ret; @@ -55,6 +62,12 @@ int FlashSimBlockDevice::init() int FlashSimBlockDevice::deinit() { + uint32_t val = core_util_atomic_decr_u32(&_init_ref_count, 1); + + if (val) { + return BD_ERROR_OK; + } + return _bd->deinit(); } diff --git a/features/filesystem/bd/FlashSimBlockDevice.h b/features/filesystem/bd/FlashSimBlockDevice.h index 6ee7cc4abe01..832374ab8251 100644 --- a/features/filesystem/bd/FlashSimBlockDevice.h +++ b/features/filesystem/bd/FlashSimBlockDevice.h @@ -135,6 +135,7 @@ class FlashSimBlockDevice : public BlockDevice { bd_size_t _blank_buf_size; uint8_t *_blank_buf; BlockDevice *_bd; + uint32_t _init_ref_count; }; #endif diff --git a/features/filesystem/bd/HeapBlockDevice.cpp b/features/filesystem/bd/HeapBlockDevice.cpp index 379fea8c75e5..70de3f4730cc 100644 --- a/features/filesystem/bd/HeapBlockDevice.cpp +++ b/features/filesystem/bd/HeapBlockDevice.cpp @@ -15,18 +15,19 @@ */ #include "HeapBlockDevice.h" +#include "mbed_critical.h" HeapBlockDevice::HeapBlockDevice(bd_size_t size, bd_size_t block) : _read_size(block), _program_size(block), _erase_size(block) - , _count(size / block), _blocks(0) + , _count(size / block), _blocks(0), _init_ref_count(0) { MBED_ASSERT(_count * _erase_size == size); } HeapBlockDevice::HeapBlockDevice(bd_size_t size, bd_size_t read, bd_size_t program, bd_size_t erase) : _read_size(read), _program_size(program), _erase_size(erase) - , _count(size / erase), _blocks(0) + , _count(size / erase), _blocks(0), _init_ref_count(0) { MBED_ASSERT(_count * _erase_size == size); } @@ -45,6 +46,12 @@ HeapBlockDevice::~HeapBlockDevice() int HeapBlockDevice::init() { + uint32_t val = core_util_atomic_incr_u32(&_init_ref_count, 1); + + if (val != 1) { + return BD_ERROR_OK; + } + if (!_blocks) { _blocks = new uint8_t*[_count]; for (size_t i = 0; i < _count; i++) { @@ -57,6 +64,12 @@ int HeapBlockDevice::init() int HeapBlockDevice::deinit() { + uint32_t val = core_util_atomic_decr_u32(&_init_ref_count, 1); + + if (val) { + return BD_ERROR_OK; + } + MBED_ASSERT(_blocks != NULL); // Memory is lazily cleaned up in destructor to allow // data to live across de/reinitialization diff --git a/features/filesystem/bd/HeapBlockDevice.h b/features/filesystem/bd/HeapBlockDevice.h index 8d65e82b3dca..874661b8f847 100644 --- a/features/filesystem/bd/HeapBlockDevice.h +++ b/features/filesystem/bd/HeapBlockDevice.h @@ -150,6 +150,7 @@ class HeapBlockDevice : public BlockDevice bd_size_t _erase_size; bd_size_t _count; uint8_t **_blocks; + uint32_t _init_ref_count; }; diff --git a/features/filesystem/bd/MBRBlockDevice.cpp b/features/filesystem/bd/MBRBlockDevice.cpp index bcea66f69b22..9a841bbcc293 100644 --- a/features/filesystem/bd/MBRBlockDevice.cpp +++ b/features/filesystem/bd/MBRBlockDevice.cpp @@ -15,6 +15,7 @@ */ #include "MBRBlockDevice.h" +#include "mbed_critical.h" #include @@ -194,13 +195,19 @@ int MBRBlockDevice::partition(BlockDevice *bd, int part, uint8_t type, } MBRBlockDevice::MBRBlockDevice(BlockDevice *bd, int part) - : _bd(bd), _part(part) + : _bd(bd), _part(part), _init_ref_count(0) { MBED_ASSERT(_part >= 1 && _part <= 4); } int MBRBlockDevice::init() { + uint32_t val = core_util_atomic_incr_u32(&_init_ref_count, 1); + + if (val != 1) { + return BD_ERROR_OK; + } + int err = _bd->init(); if (err) { return err; @@ -252,6 +259,12 @@ int MBRBlockDevice::init() int MBRBlockDevice::deinit() { + uint32_t val = core_util_atomic_decr_u32(&_init_ref_count, 1); + + if (val) { + return BD_ERROR_OK; + } + return _bd->deinit(); } diff --git a/features/filesystem/bd/MBRBlockDevice.h b/features/filesystem/bd/MBRBlockDevice.h index c2ad5d5082d1..ef2e12233ab2 100644 --- a/features/filesystem/bd/MBRBlockDevice.h +++ b/features/filesystem/bd/MBRBlockDevice.h @@ -252,6 +252,7 @@ class MBRBlockDevice : public BlockDevice bd_size_t _size; uint8_t _type; uint8_t _part; + uint32_t _init_ref_count; }; diff --git a/features/filesystem/fat/FATFileSystem.cpp b/features/filesystem/fat/FATFileSystem.cpp index 48871cd9bf5b..38916ba2ba85 100644 --- a/features/filesystem/fat/FATFileSystem.cpp +++ b/features/filesystem/fat/FATFileSystem.cpp @@ -19,17 +19,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#include "mbed.h" - #include "diskio.h" #include "ffconf.h" -#include "mbed_debug.h" -#include "mbed_critical.h" -#include - +#include "platform/mbed_debug.h" +#include "platform/mbed_critical.h" +#include "filesystem/mbed_filesystem.h" #include "FATFileSystem.h" - +#include ////// Error handling ///// static int fat_error_remap(FRESULT res) @@ -464,7 +461,6 @@ int FATFileSystem::remove(const char *path) if (res != FR_OK) { debug_if(FFS_DBG, "f_unlink() failed: %d\n", res); if (res == FR_DENIED) { - printf("hi %d -> %d\n", FR_DENIED, -ENOTEMPTY); return -ENOTEMPTY; } } diff --git a/features/filesystem/fat/FATFileSystem.h b/features/filesystem/fat/FATFileSystem.h index 29afb9109a48..ed9fedaef441 100644 --- a/features/filesystem/fat/FATFileSystem.h +++ b/features/filesystem/fat/FATFileSystem.h @@ -29,12 +29,11 @@ #include #include "PlatformMutex.h" -using namespace mbed; /** * FATFileSystem based on ChaN's Fat Filesystem library v0.8 */ -class FATFileSystem : public FileSystem { +class FATFileSystem : public mbed::FileSystem { public: /** Lifetime of the FATFileSystem * @@ -156,14 +155,14 @@ class FATFileSystem : public FileSystem { * bitwise or'd with one of O_CREAT, O_TRUNC, O_APPEND * @return 0 on success, negative error code on failure */ - virtual int file_open(fs_file_t *file, const char *path, int flags); + virtual int file_open(mbed::fs_file_t *file, const char *path, int flags); /** Close a file * * @param file File handle * @return 0 on success, negative error code on failure */ - virtual int file_close(fs_file_t file); + virtual int file_close(mbed::fs_file_t file); /** Read the contents of a file into a buffer * @@ -172,7 +171,7 @@ class FATFileSystem : public FileSystem { * @param len The number of bytes to read * @return The number of bytes read, 0 at end of file, negative error on failure */ - virtual ssize_t file_read(fs_file_t file, void *buffer, size_t len); + virtual ssize_t file_read(mbed::fs_file_t file, void *buffer, size_t len); /** Write the contents of a buffer to a file * @@ -181,14 +180,14 @@ class FATFileSystem : public FileSystem { * @param len The number of bytes to write * @return The number of bytes written, negative error on failure */ - virtual ssize_t file_write(fs_file_t file, const void *buffer, size_t len); + virtual ssize_t file_write(mbed::fs_file_t file, const void *buffer, size_t len); /** Flush any buffers associated with the file * * @param file File handle * @return 0 on success, negative error code on failure */ - virtual int file_sync(fs_file_t file); + virtual int file_sync(mbed::fs_file_t file); /** Move the file position to a given offset from from a given location * @@ -200,21 +199,21 @@ class FATFileSystem : public FileSystem { * SEEK_END to start from end of file * @return The new offset of the file */ - virtual off_t file_seek(fs_file_t file, off_t offset, int whence); + virtual off_t file_seek(mbed::fs_file_t file, off_t offset, int whence); /** Get the file position of the file * * @param file File handle * @return The current offset in the file */ - virtual off_t file_tell(fs_file_t file); + virtual off_t file_tell(mbed::fs_file_t file); /** Get the size of the file * * @param file File handle * @return Size of the file in bytes */ - virtual off_t file_size(fs_file_t file); + virtual off_t file_size(mbed::fs_file_t file); /** Open a directory on the filesystem * @@ -222,14 +221,14 @@ class FATFileSystem : public FileSystem { * @param path Name of the directory to open * @return 0 on success, negative error code on failure */ - virtual int dir_open(fs_dir_t *dir, const char *path); + virtual int dir_open(mbed::fs_dir_t *dir, const char *path); /** Close a directory * * @param dir Dir handle * @return 0 on success, negative error code on failure */ - virtual int dir_close(fs_dir_t dir); + virtual int dir_close(mbed::fs_dir_t dir); /** Read the next directory entry * @@ -237,7 +236,7 @@ class FATFileSystem : public FileSystem { * @param ent The directory entry to fill out * @return 1 on reading a filename, 0 at end of directory, negative error on failure */ - virtual ssize_t dir_read(fs_dir_t dir, struct dirent *ent); + virtual ssize_t dir_read(mbed::fs_dir_t dir, struct dirent *ent); /** Set the current position of the directory * @@ -245,20 +244,20 @@ class FATFileSystem : public FileSystem { * @param offset Offset of the location to seek to, * must be a value returned from dir_tell */ - virtual void dir_seek(fs_dir_t dir, off_t offset); + virtual void dir_seek(mbed::fs_dir_t dir, off_t offset); /** Get the current position of the directory * * @param dir Dir handle * @return Position of the directory that can be passed to dir_rewind */ - virtual off_t dir_tell(fs_dir_t dir); + virtual off_t dir_tell(mbed::fs_dir_t dir); /** Rewind the current position to the beginning of the directory * * @param dir Dir handle */ - virtual void dir_rewind(fs_dir_t dir); + virtual void dir_rewind(mbed::fs_dir_t dir); private: FATFS _fs; // Work area (file system object) for logical drive diff --git a/features/filesystem/littlefs/LICENSE.md b/features/filesystem/littlefs/LICENSE.md deleted file mode 100644 index 59cd3f8a3206..000000000000 --- a/features/filesystem/littlefs/LICENSE.md +++ /dev/null @@ -1,165 +0,0 @@ -Apache License -Version 2.0, January 2004 -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and -distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright -owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities -that control, are controlled by, or are under common control with that entity. -For the purposes of this definition, "control" means (i) the power, direct or -indirect, to cause the direction or management of such entity, whether by -contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the -outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising -permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including -but not limited to software source code, documentation source, and configuration -files. - -"Object" form shall mean any form resulting from mechanical transformation or -translation of a Source form, including but not limited to compiled object code, -generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made -available under the License, as indicated by a copyright notice that is included -in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that -is based on (or derived from) the Work and for which the editorial revisions, -annotations, elaborations, or other modifications represent, as a whole, an -original work of authorship. For the purposes of this License, Derivative Works -shall not include works that remain separable from, or merely link (or bind by -name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version -of the Work and any modifications or additions to that Work or Derivative Works -thereof, that is intentionally submitted to Licensor for inclusion in the Work -by the copyright owner or by an individual or Legal Entity authorized to submit -on behalf of the copyright owner. For the purposes of this definition, -"submitted" means any form of electronic, verbal, or written communication sent -to the Licensor or its representatives, including but not limited to -communication on electronic mailing lists, source code control systems, and -issue tracking systems that are managed by, or on behalf of, the Licensor for -the purpose of discussing and improving the Work, but excluding communication -that is conspicuously marked or otherwise designated in writing by the copyright -owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf -of whom a Contribution has been received by Licensor and subsequently -incorporated within the Work. - -2. Grant of Copyright License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable copyright license to reproduce, prepare Derivative Works of, -publicly display, publicly perform, sublicense, and distribute the Work and such -Derivative Works in Source or Object form. - -3. Grant of Patent License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable (except as stated in this section) patent license to make, have -made, use, offer to sell, sell, import, and otherwise transfer the Work, where -such license applies only to those patent claims licensable by such Contributor -that are necessarily infringed by their Contribution(s) alone or by combination -of their Contribution(s) with the Work to which such Contribution(s) was -submitted. If You institute patent litigation against any entity (including a -cross-claim or counterclaim in a lawsuit) alleging that the Work or a -Contribution incorporated within the Work constitutes direct or contributory -patent infringement, then any patent licenses granted to You under this License -for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. - -You may reproduce and distribute copies of the Work or Derivative Works thereof -in any medium, with or without modifications, and in Source or Object form, -provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of -this License; and -You must cause any modified files to carry prominent notices stating that You -changed the files; and -You must retain, in the Source form of any Derivative Works that You distribute, -all copyright, patent, trademark, and attribution notices from the Source form -of the Work, excluding those notices that do not pertain to any part of the -Derivative Works; and -If the Work includes a "NOTICE" text file as part of its distribution, then any -Derivative Works that You distribute must include a readable copy of the -attribution notices contained within such NOTICE file, excluding those notices -that do not pertain to any part of the Derivative Works, in at least one of the -following places: within a NOTICE text file distributed as part of the -Derivative Works; within the Source form or documentation, if provided along -with the Derivative Works; or, within a display generated by the Derivative -Works, if and wherever such third-party notices normally appear. The contents of -the NOTICE file are for informational purposes only and do not modify the -License. You may add Your own attribution notices within Derivative Works that -You distribute, alongside or as an addendum to the NOTICE text from the Work, -provided that such additional attribution notices cannot be construed as -modifying the License. -You may add Your own copyright statement to Your modifications and may provide -additional or different license terms and conditions for use, reproduction, or -distribution of Your modifications, or for any such Derivative Works as a whole, -provided Your use, reproduction, and distribution of the Work otherwise complies -with the conditions stated in this License. - -5. Submission of Contributions. - -Unless You explicitly state otherwise, any Contribution intentionally submitted -for inclusion in the Work by You to the Licensor shall be under the terms and -conditions of this License, without any additional terms or conditions. -Notwithstanding the above, nothing herein shall supersede or modify the terms of -any separate license agreement you may have executed with Licensor regarding -such Contributions. - -6. Trademarks. - -This License does not grant permission to use the trade names, trademarks, -service marks, or product names of the Licensor, except as required for -reasonable and customary use in describing the origin of the Work and -reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. - -Unless required by applicable law or agreed to in writing, Licensor provides the -Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, -including, without limitation, any warranties or conditions of TITLE, -NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are -solely responsible for determining the appropriateness of using or -redistributing the Work and assume any risks associated with Your exercise of -permissions under this License. - -8. Limitation of Liability. - -In no event and under no legal theory, whether in tort (including negligence), -contract, or otherwise, unless required by applicable law (such as deliberate -and grossly negligent acts) or agreed to in writing, shall any Contributor be -liable to You for damages, including any direct, indirect, special, incidental, -or consequential damages of any character arising as a result of this License or -out of the use or inability to use the Work (including but not limited to -damages for loss of goodwill, work stoppage, computer failure or malfunction, or -any and all other commercial damages or losses), even if such Contributor has -been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. - -While redistributing the Work or Derivative Works thereof, You may choose to -offer, and charge a fee for, acceptance of support, warranty, indemnity, or -other liability obligations and/or rights consistent with this License. However, -in accepting such obligations, You may act only on Your own behalf and on Your -sole responsibility, not on behalf of any other Contributor, and only if You -agree to indemnify, defend, and hold each Contributor harmless for any liability -incurred by, or claims asserted against, such Contributor by reason of your -accepting any such warranty or additional liability. diff --git a/features/filesystem/littlefs/LittleFileSystem.cpp b/features/filesystem/littlefs/LittleFileSystem.cpp index b1bb93b6b503..74f52f327805 100644 --- a/features/filesystem/littlefs/LittleFileSystem.cpp +++ b/features/filesystem/littlefs/LittleFileSystem.cpp @@ -13,13 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "mbed.h" +#include "filesystem/mbed_filesystem.h" #include "LittleFileSystem.h" #include "errno.h" -extern "C" { #include "lfs.h" #include "lfs_util.h" -} ////// Conversion functions ////// @@ -136,6 +134,7 @@ int LittleFileSystem::mount(BlockDevice *bd) _bd = bd; int err = _bd->init(); if (err) { + _bd = NULL; LFS_INFO("mount -> %d", err); _mutex.unlock(); return err; @@ -166,36 +165,40 @@ int LittleFileSystem::mount(BlockDevice *bd) } err = lfs_mount(&_lfs, &_config); - LFS_INFO("mount -> %d", lfs_toerror(err)); + if (err) { + _bd = NULL; + LFS_INFO("mount -> %d", lfs_toerror(err)); + _mutex.unlock(); + return lfs_toerror(err); + } + _mutex.unlock(); - return lfs_toerror(err); + LFS_INFO("mount -> %d", 0); + return 0; } int LittleFileSystem::unmount() { _mutex.lock(); LFS_INFO("unmount(%s)", ""); + int res = 0; if (_bd) { int err = lfs_unmount(&_lfs); - if (err) { - LFS_INFO("unmount -> %d", lfs_toerror(err)); - _mutex.unlock(); - return lfs_toerror(err); + if (err && !res) { + res = lfs_toerror(err); } err = _bd->deinit(); - if (err) { - LFS_INFO("unmount -> %d", err); - _mutex.unlock(); - return err; + if (err && !res) { + res = err; } _bd = NULL; } - LFS_INFO("unmount -> %d", 0); + LFS_INFO("unmount -> %d", res); _mutex.unlock(); - return 0; + return res; } int LittleFileSystem::format(BlockDevice *bd, diff --git a/features/filesystem/littlefs/LittleFileSystem.h b/features/filesystem/littlefs/LittleFileSystem.h index 6f15a423ba06..57cd676563ca 100644 --- a/features/filesystem/littlefs/LittleFileSystem.h +++ b/features/filesystem/littlefs/LittleFileSystem.h @@ -19,9 +19,7 @@ #include "FileSystem.h" #include "BlockDevice.h" #include "PlatformMutex.h" -extern "C" { #include "lfs.h" -} /** diff --git a/features/filesystem/littlefs/TESTS/filesystem_integration/format/main.cpp b/features/filesystem/littlefs/TESTS/filesystem_integration/format/main.cpp new file mode 100644 index 000000000000..b841daec5223 --- /dev/null +++ b/features/filesystem/littlefs/TESTS/filesystem_integration/format/main.cpp @@ -0,0 +1,199 @@ +/* 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 "mbed.h" +#include "greentea-client/test_env.h" +#include "unity.h" +#include "utest.h" +#include +#include + +using namespace utest::v1; + +// test configuration +#ifndef MBED_TEST_FILESYSTEM +#define MBED_TEST_FILESYSTEM LittleFileSystem +#endif + +#ifndef MBED_TEST_FILESYSTEM_DECL +#define MBED_TEST_FILESYSTEM_DECL MBED_TEST_FILESYSTEM fs("fs") +#endif + +#ifndef MBED_TEST_BLOCKDEVICE +#error [NOT_SUPPORTED] Non-volatile block device required +#endif + +#ifndef MBED_TEST_BLOCKDEVICE_DECL +#define MBED_TEST_BLOCKDEVICE_DECL MBED_TEST_BLOCKDEVICE bd +#endif + +#ifndef MBED_TEST_FILES +#define MBED_TEST_FILES 4 +#endif + +#ifndef MBED_TEST_DIRS +#define MBED_TEST_DIRS 4 +#endif + +#ifndef MBED_TEST_BUFFER +#define MBED_TEST_BUFFER 8192 +#endif + +#ifndef MBED_TEST_TIMEOUT +#define MBED_TEST_TIMEOUT 480 +#endif + + +// declarations +#define STRINGIZE(x) STRINGIZE2(x) +#define STRINGIZE2(x) #x +#define INCLUDE(x) STRINGIZE(x.h) + +#include INCLUDE(MBED_TEST_FILESYSTEM) +#include INCLUDE(MBED_TEST_BLOCKDEVICE) + +MBED_TEST_FILESYSTEM_DECL; +MBED_TEST_BLOCKDEVICE_DECL; + +Dir dir[MBED_TEST_DIRS]; +File file[MBED_TEST_FILES]; +DIR *dd[MBED_TEST_DIRS]; +FILE *fd[MBED_TEST_FILES]; +struct dirent ent; +struct dirent *ed; +size_t size; +uint8_t buffer[MBED_TEST_BUFFER]; +uint8_t rbuffer[MBED_TEST_BUFFER]; +uint8_t wbuffer[MBED_TEST_BUFFER]; + + +// tests for integration level format operations + +void test_format() +{ + int res = bd.init(); + TEST_ASSERT_EQUAL(0, res); + + { + res = MBED_TEST_FILESYSTEM::format(&bd); + TEST_ASSERT_EQUAL(0, res); + } + + res = bd.deinit(); + TEST_ASSERT_EQUAL(0, res); +} + +void test_mount() +{ + int res = bd.init(); + TEST_ASSERT_EQUAL(0, res); + + { + res = fs.mount(&bd); + TEST_ASSERT_EQUAL(0, res); + res = fs.unmount(); + TEST_ASSERT_EQUAL(0, res); + } + + res = bd.deinit(); + TEST_ASSERT_EQUAL(0, res); +} + +void test_bad_mount() +{ + int res = bd.init(); + TEST_ASSERT_EQUAL(0, res); + + { + res = bd.erase(0, 2*bd.get_erase_size()); + TEST_ASSERT_EQUAL(0, res); + memset(buffer, 0, bd.get_program_size()); + for (int i = 0; i < 2*bd.get_erase_size(); i += bd.get_program_size()) { + res = bd.program(buffer, i, bd.get_program_size()); + TEST_ASSERT_EQUAL(0, res); + } + } + + { + res = fs.mount(&bd); + TEST_ASSERT_NOT_EQUAL(0, res); + } + + res = bd.deinit(); + TEST_ASSERT_EQUAL(0, res); +} + +void test_bad_mount_then_reformat() +{ + int res = bd.init(); + TEST_ASSERT_EQUAL(0, res); + + { + res = fs.mount(&bd); + TEST_ASSERT_NOT_EQUAL(0, res); + + res = fs.reformat(&bd); + TEST_ASSERT_EQUAL(0, res); + + res = fs.unmount(); + TEST_ASSERT_EQUAL(0, res); + } + + res = bd.deinit(); + TEST_ASSERT_EQUAL(0, res); +} + +void test_good_mount_then_reformat() +{ + int res = bd.init(); + TEST_ASSERT_EQUAL(0, res); + + { + res = fs.mount(&bd); + TEST_ASSERT_EQUAL(0, res); + + res = fs.reformat(&bd); + TEST_ASSERT_EQUAL(0, res); + + res = fs.unmount(); + TEST_ASSERT_EQUAL(0, res); + } + + res = bd.deinit(); + TEST_ASSERT_EQUAL(0, res); +} + + +// test setup +utest::v1::status_t test_setup(const size_t number_of_cases) +{ + GREENTEA_SETUP(MBED_TEST_TIMEOUT, "default_auto"); + return verbose_test_setup_handler(number_of_cases); +} + +Case cases[] = { + Case("Test format", test_format), + Case("Test mount", test_mount), + Case("Test bad mount", test_bad_mount), + Case("Test bad mount than reformat", test_bad_mount_then_reformat), + Case("Test good mount than reformat", test_good_mount_then_reformat), +}; + +Specification specification(test_setup, cases); + +int main() +{ + return !Harness::run(specification); +} diff --git a/features/filesystem/littlefs/littlefs/.travis.yml b/features/filesystem/littlefs/littlefs/.travis.yml index 2c6139fefce1..3714f7c84e6a 100644 --- a/features/filesystem/littlefs/littlefs/.travis.yml +++ b/features/filesystem/littlefs/littlefs/.travis.yml @@ -27,7 +27,7 @@ script: # compile and find the code size with the smallest configuration - make clean size OBJ="$(ls lfs*.o | tr '\n' ' ')" - CFLAGS+="-DLFS_NO{ASSERT,DEBUG,WARN,ERROR}" + CFLAGS+="-DLFS_NO_ASSERT -DLFS_NO_DEBUG -DLFS_NO_WARN -DLFS_NO_ERROR" | tee sizes # update status if we succeeded, compare with master if possible @@ -35,7 +35,7 @@ script: if [ "$TRAVIS_TEST_RESULT" -eq 0 ] then CURR=$(tail -n1 sizes | awk '{print $1}') - PREV=$(curl https://api.github.com/repos/$TRAVIS_REPO_SLUG/status/master \ + PREV=$(curl -u $GEKY_BOT_STATUSES https://api.github.com/repos/$TRAVIS_REPO_SLUG/status/master \ | jq -re "select(.sha != \"$TRAVIS_COMMIT\") | .statuses[] | select(.context == \"$STAGE/$NAME\").description | capture(\"code size is (?[0-9]+)\").size" \ @@ -134,52 +134,44 @@ jobs: - STAGE=deploy - NAME=deploy script: - # Update tag for version defined in lfs.h + # Find version defined in lfs.h - LFS_VERSION=$(grep -ox '#define LFS_VERSION .*' lfs.h | cut -d ' ' -f3) - LFS_VERSION_MAJOR=$((0xffff & ($LFS_VERSION >> 16))) - LFS_VERSION_MINOR=$((0xffff & ($LFS_VERSION >> 0))) - - LFS_VERSION="v$LFS_VERSION_MAJOR.$LFS_VERSION_MINOR" - - echo "littlefs version $LFS_VERSION" + # Grab latests patch from repo tags, default to 0 + - LFS_VERSION_PATCH=$(curl -f -u "$GEKY_BOT_RELEASES" + https://api.github.com/repos/$TRAVIS_REPO_SLUG/git/refs + | jq 'map(.ref | match( + "refs/tags/v'"$LFS_VERSION_MAJOR"'\\.'"$LFS_VERSION_MINOR"'\\.(.*)$") + .captures[].string | tonumber + 1) | max // 0') + # We have our new version + - LFS_VERSION="v$LFS_VERSION_MAJOR.$LFS_VERSION_MINOR.$LFS_VERSION_PATCH" + - echo "VERSION $LFS_VERSION" - | - curl -u $GEKY_BOT_RELEASES -X POST \ - https://api.github.com/repos/$TRAVIS_REPO_SLUG/git/refs \ - -d "{ - \"ref\": \"refs/tags/$LFS_VERSION\", - \"sha\": \"$TRAVIS_COMMIT\" - }" - - | - curl -f -u $GEKY_BOT_RELEASES -X PATCH \ - https://api.github.com/repos/$TRAVIS_REPO_SLUG/git/refs/tags/$LFS_VERSION \ - -d "{ - \"sha\": \"$TRAVIS_COMMIT\" - }" - # Create release notes from commits - - LFS_PREV_VERSION="v$LFS_VERSION_MAJOR.$(($LFS_VERSION_MINOR-1))" - - | - if [ $(git tag -l "$LFS_PREV_VERSION") ] + # Check that we're the most recent commit + CURRENT_COMMIT=$(curl -f -u "$GEKY_BOT_RELEASES" \ + https://api.github.com/repos/$TRAVIS_REPO_SLUG/commits/master \ + | jq -re '.sha') + if [ "$TRAVIS_COMMIT" == "$CURRENT_COMMIT" ] then - curl -u $GEKY_BOT_RELEASES -X POST \ + # Build release notes + PREV=$(git tag --sort=-v:refname -l "v*" | head -1) + if [ ! -z "$PREV" ] + then + echo "PREV $PREV" + CHANGES=$'### Changes\n\n'$( \ + git log --oneline $PREV.. --grep='^Merge' --invert-grep) + printf "CHANGES\n%s\n\n" "$CHANGES" + fi + # Create the release + curl -f -u "$GEKY_BOT_RELEASES" -X POST \ https://api.github.com/repos/$TRAVIS_REPO_SLUG/releases \ -d "{ \"tag_name\": \"$LFS_VERSION\", - \"name\": \"$LFS_VERSION\" + \"target_commitish\": \"$TRAVIS_COMMIT\", + \"name\": \"${LFS_VERSION%.0}\", + \"body\": $(jq -sR '.' <<< "$CHANGES") }" - RELEASE=$( - curl -f https://api.github.com/repos/$TRAVIS_REPO_SLUG/releases/tags/$LFS_VERSION - ) - CHANGES=$( - git log --oneline $LFS_PREV_VERSION.. --grep='^Merge' --invert-grep - ) - curl -f -u $GEKY_BOT_RELEASES -X PATCH \ - https://api.github.com/repos/$TRAVIS_REPO_SLUG/releases/$( - jq -r '.id' <<< "$RELEASE" - ) \ - -d "$( - jq -s '{ - "body": ((.[0] // "" | sub("(?<=\n)#+ Changes.*"; ""; "mi")) - + "### Changes\n\n" + .[1]) - }' <(jq '.body' <<< "$RELEASE") <(jq -sR '.' <<< "$CHANGES") - )" fi # Manage statuses @@ -220,4 +212,4 @@ after_success: stages: - name: test - name: deploy - if: branch = master + if: branch = master AND type = push diff --git a/features/filesystem/littlefs/littlefs/LICENSE.md b/features/filesystem/littlefs/littlefs/LICENSE.md index 59cd3f8a3206..ed69bea4743c 100644 --- a/features/filesystem/littlefs/littlefs/LICENSE.md +++ b/features/filesystem/littlefs/littlefs/LICENSE.md @@ -1,165 +1,24 @@ -Apache License -Version 2.0, January 2004 -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and -distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright -owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities -that control, are controlled by, or are under common control with that entity. -For the purposes of this definition, "control" means (i) the power, direct or -indirect, to cause the direction or management of such entity, whether by -contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the -outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising -permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including -but not limited to software source code, documentation source, and configuration -files. - -"Object" form shall mean any form resulting from mechanical transformation or -translation of a Source form, including but not limited to compiled object code, -generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made -available under the License, as indicated by a copyright notice that is included -in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that -is based on (or derived from) the Work and for which the editorial revisions, -annotations, elaborations, or other modifications represent, as a whole, an -original work of authorship. For the purposes of this License, Derivative Works -shall not include works that remain separable from, or merely link (or bind by -name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version -of the Work and any modifications or additions to that Work or Derivative Works -thereof, that is intentionally submitted to Licensor for inclusion in the Work -by the copyright owner or by an individual or Legal Entity authorized to submit -on behalf of the copyright owner. For the purposes of this definition, -"submitted" means any form of electronic, verbal, or written communication sent -to the Licensor or its representatives, including but not limited to -communication on electronic mailing lists, source code control systems, and -issue tracking systems that are managed by, or on behalf of, the Licensor for -the purpose of discussing and improving the Work, but excluding communication -that is conspicuously marked or otherwise designated in writing by the copyright -owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf -of whom a Contribution has been received by Licensor and subsequently -incorporated within the Work. - -2. Grant of Copyright License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable copyright license to reproduce, prepare Derivative Works of, -publicly display, publicly perform, sublicense, and distribute the Work and such -Derivative Works in Source or Object form. - -3. Grant of Patent License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable (except as stated in this section) patent license to make, have -made, use, offer to sell, sell, import, and otherwise transfer the Work, where -such license applies only to those patent claims licensable by such Contributor -that are necessarily infringed by their Contribution(s) alone or by combination -of their Contribution(s) with the Work to which such Contribution(s) was -submitted. If You institute patent litigation against any entity (including a -cross-claim or counterclaim in a lawsuit) alleging that the Work or a -Contribution incorporated within the Work constitutes direct or contributory -patent infringement, then any patent licenses granted to You under this License -for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. - -You may reproduce and distribute copies of the Work or Derivative Works thereof -in any medium, with or without modifications, and in Source or Object form, -provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of -this License; and -You must cause any modified files to carry prominent notices stating that You -changed the files; and -You must retain, in the Source form of any Derivative Works that You distribute, -all copyright, patent, trademark, and attribution notices from the Source form -of the Work, excluding those notices that do not pertain to any part of the -Derivative Works; and -If the Work includes a "NOTICE" text file as part of its distribution, then any -Derivative Works that You distribute must include a readable copy of the -attribution notices contained within such NOTICE file, excluding those notices -that do not pertain to any part of the Derivative Works, in at least one of the -following places: within a NOTICE text file distributed as part of the -Derivative Works; within the Source form or documentation, if provided along -with the Derivative Works; or, within a display generated by the Derivative -Works, if and wherever such third-party notices normally appear. The contents of -the NOTICE file are for informational purposes only and do not modify the -License. You may add Your own attribution notices within Derivative Works that -You distribute, alongside or as an addendum to the NOTICE text from the Work, -provided that such additional attribution notices cannot be construed as -modifying the License. -You may add Your own copyright statement to Your modifications and may provide -additional or different license terms and conditions for use, reproduction, or -distribution of Your modifications, or for any such Derivative Works as a whole, -provided Your use, reproduction, and distribution of the Work otherwise complies -with the conditions stated in this License. - -5. Submission of Contributions. - -Unless You explicitly state otherwise, any Contribution intentionally submitted -for inclusion in the Work by You to the Licensor shall be under the terms and -conditions of this License, without any additional terms or conditions. -Notwithstanding the above, nothing herein shall supersede or modify the terms of -any separate license agreement you may have executed with Licensor regarding -such Contributions. - -6. Trademarks. - -This License does not grant permission to use the trade names, trademarks, -service marks, or product names of the Licensor, except as required for -reasonable and customary use in describing the origin of the Work and -reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. - -Unless required by applicable law or agreed to in writing, Licensor provides the -Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, -including, without limitation, any warranties or conditions of TITLE, -NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are -solely responsible for determining the appropriateness of using or -redistributing the Work and assume any risks associated with Your exercise of -permissions under this License. - -8. Limitation of Liability. - -In no event and under no legal theory, whether in tort (including negligence), -contract, or otherwise, unless required by applicable law (such as deliberate -and grossly negligent acts) or agreed to in writing, shall any Contributor be -liable to You for damages, including any direct, indirect, special, incidental, -or consequential damages of any character arising as a result of this License or -out of the use or inability to use the Work (including but not limited to -damages for loss of goodwill, work stoppage, computer failure or malfunction, or -any and all other commercial damages or losses), even if such Contributor has -been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. - -While redistributing the Work or Derivative Works thereof, You may choose to -offer, and charge a fee for, acceptance of support, warranty, indemnity, or -other liability obligations and/or rights consistent with this License. However, -in accepting such obligations, You may act only on Your own behalf and on Your -sole responsibility, not on behalf of any other Contributor, and only if You -agree to indemnify, defend, and hold each Contributor harmless for any liability -incurred by, or claims asserted against, such Contributor by reason of your -accepting any such warranty or additional liability. +Copyright (c) 2017, Arm Limited. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +- Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +- 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. +- Neither the name of ARM 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. diff --git a/features/filesystem/littlefs/littlefs/Makefile b/features/filesystem/littlefs/littlefs/Makefile index ee717936bd47..99a3c0cc9ccd 100644 --- a/features/filesystem/littlefs/littlefs/Makefile +++ b/features/filesystem/littlefs/littlefs/Makefile @@ -1,4 +1,7 @@ -TARGET = lfs +TARGET = lfs.a +ifneq ($(wildcard test.c main.c),) +override TARGET = lfs +endif CC ?= gcc AR ?= ar @@ -22,7 +25,7 @@ ifdef WORD override CFLAGS += -m$(WORD) endif override CFLAGS += -I. -override CFLAGS += -std=c99 -Wall -pedantic +override CFLAGS += -std=c99 -Wall -pedantic -Wshadow -Wunused-parameter all: $(TARGET) @@ -33,9 +36,11 @@ size: $(OBJ) $(SIZE) -t $^ .SUFFIXES: -test: test_format test_dirs test_files test_seek test_truncate test_parallel \ - test_alloc test_paths test_orphan test_move test_corrupt +test: test_format test_dirs test_files test_seek test_truncate \ + test_interspersed test_alloc test_paths test_orphan test_move test_corrupt + @rm test.c test_%: tests/test_%.sh + ifdef QUIET @./$< | sed -n '/^[-=]/p' else @@ -44,7 +49,7 @@ endif -include $(DEP) -$(TARGET): $(OBJ) +lfs: $(OBJ) $(CC) $(CFLAGS) $^ $(LFLAGS) -o $@ %.a: $(OBJ) diff --git a/features/filesystem/littlefs/littlefs/README.md b/features/filesystem/littlefs/littlefs/README.md index 0512e146f139..d7b39dd5c7bb 100644 --- a/features/filesystem/littlefs/littlefs/README.md +++ b/features/filesystem/littlefs/littlefs/README.md @@ -115,10 +115,17 @@ All littlefs have the potential to return a negative error code. The errors can be either one of those found in the `enum lfs_error` in [lfs.h](lfs.h), or an error returned by the user's block device operations. -It should also be noted that the current implementation of littlefs doesn't -really do anything to ensure that the data written to disk is machine portable. -This is fine as long as all of the involved machines share endianness -(little-endian) and don't have strange padding requirements. +In the configuration struct, the `prog` and `erase` function provided by the +user may return a `LFS_ERR_CORRUPT` error if the implementation already can +detect corrupt blocks. However, the wear leveling does not depend on the return +code of these functions, instead all data is read back and checked for +integrity. + +If your storage caches writes, make sure that the provided `sync` function +flushes all the data to memory and ensures that the next read fetches the data +from memory, otherwise data integrity can not be guaranteed. If the `write` +function does not perform caching, and therefore each `read` or `write` call +hits the memory, the `sync` function can simply return 0. ## Reference material @@ -139,6 +146,19 @@ The tests assume a Linux environment and can be started with make: make test ``` +## License + +The littlefs is provided under the [BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html) +license. See [LICENSE.md](LICENSE.md) for more information. Contributions to +this project are accepted under the same license. + +Individual files contain the following tag instead of the full license text. + + SPDX-License-Identifier: BSD-3-Clause + +This enables machine processing of license information based on the SPDX +License Identifiers that are here available: http://spdx.org/licenses/ + ## Related projects [Mbed OS](https://github.com/ARMmbed/mbed-os/tree/master/features/filesystem/littlefs) - diff --git a/features/filesystem/littlefs/littlefs/emubd/lfs_emubd.c b/features/filesystem/littlefs/littlefs/emubd/lfs_emubd.c index b1595963dd97..682ad925e262 100644 --- a/features/filesystem/littlefs/littlefs/emubd/lfs_emubd.c +++ b/features/filesystem/littlefs/littlefs/emubd/lfs_emubd.c @@ -1,19 +1,8 @@ /* * Block device emulated on standard files * - * 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. + * Copyright (c) 2017, Arm Limited. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause */ #include "emubd/lfs_emubd.h" @@ -27,6 +16,7 @@ #include #include #include +#include // Block device emulated on existing filesystem @@ -96,7 +86,7 @@ int lfs_emubd_read(const struct lfs_config *cfg, lfs_block_t block, memset(data, 0, size); // Read data - snprintf(emu->child, LFS_NAME_MAX, "%x", block); + snprintf(emu->child, LFS_NAME_MAX, "%" PRIx32, block); FILE *f = fopen(emu->path, "rb"); if (!f && errno != ENOENT) { @@ -135,7 +125,7 @@ int lfs_emubd_prog(const struct lfs_config *cfg, lfs_block_t block, assert(block < cfg->block_count); // Program data - snprintf(emu->child, LFS_NAME_MAX, "%x", block); + snprintf(emu->child, LFS_NAME_MAX, "%" PRIx32, block); FILE *f = fopen(emu->path, "r+b"); if (!f) { @@ -182,7 +172,7 @@ int lfs_emubd_erase(const struct lfs_config *cfg, lfs_block_t block) { assert(block < cfg->block_count); // Erase the block - snprintf(emu->child, LFS_NAME_MAX, "%x", block); + snprintf(emu->child, LFS_NAME_MAX, "%" PRIx32, block); struct stat st; int err = stat(emu->path, &st); if (err && errno != ENOENT) { @@ -250,4 +240,3 @@ int lfs_emubd_sync(const struct lfs_config *cfg) { return 0; } - diff --git a/features/filesystem/littlefs/littlefs/emubd/lfs_emubd.h b/features/filesystem/littlefs/littlefs/emubd/lfs_emubd.h index 4f87ccecf10b..0fd43875fdf5 100644 --- a/features/filesystem/littlefs/littlefs/emubd/lfs_emubd.h +++ b/features/filesystem/littlefs/littlefs/emubd/lfs_emubd.h @@ -1,19 +1,8 @@ /* * Block device emulated on standard files * - * 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. + * Copyright (c) 2017, Arm Limited. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause */ #ifndef LFS_EMUBD_H #define LFS_EMUBD_H @@ -21,6 +10,11 @@ #include "lfs.h" #include "lfs_util.h" +#ifdef __cplusplus +extern "C" +{ +#endif + // Config options #ifndef LFS_EMUBD_READ_SIZE @@ -86,4 +80,8 @@ int lfs_emubd_erase(const struct lfs_config *cfg, lfs_block_t block); int lfs_emubd_sync(const struct lfs_config *cfg); +#ifdef __cplusplus +} /* extern "C" */ +#endif + #endif diff --git a/features/filesystem/littlefs/littlefs/lfs.c b/features/filesystem/littlefs/littlefs/lfs.c index f12e9ccf9218..c6b5870395ce 100644 --- a/features/filesystem/littlefs/littlefs/lfs.c +++ b/features/filesystem/littlefs/littlefs/lfs.c @@ -1,23 +1,14 @@ /* * The little filesystem * - * 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. + * Copyright (c) 2017, Arm Limited. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause */ #include "lfs.h" #include "lfs_util.h" +#include + /// Caching block device operations /// static int lfs_cache_read(lfs_t *lfs, lfs_cache_t *rcache, @@ -118,6 +109,19 @@ static int lfs_cache_crc(lfs_t *lfs, lfs_cache_t *rcache, return 0; } +static inline void lfs_cache_drop(lfs_t *lfs, lfs_cache_t *rcache) { + // do not zero, cheaper if cache is readonly or only going to be + // written with identical data (during relocates) + (void)lfs; + rcache->block = 0xffffffff; +} + +static inline void lfs_cache_zero(lfs_t *lfs, lfs_cache_t *pcache) { + // zero to avoid information leak + memset(pcache->buffer, 0xff, lfs->cfg->prog_size); + pcache->block = 0xffffffff; +} + static int lfs_cache_flush(lfs_t *lfs, lfs_cache_t *pcache, lfs_cache_t *rcache) { if (pcache->block != 0xffffffff) { @@ -139,7 +143,7 @@ static int lfs_cache_flush(lfs_t *lfs, } } - pcache->block = 0xffffffff; + lfs_cache_zero(lfs, pcache); } return 0; @@ -244,7 +248,7 @@ static int lfs_bd_erase(lfs_t *lfs, lfs_block_t block) { } static int lfs_bd_sync(lfs_t *lfs) { - lfs->rcache.block = 0xffffffff; + lfs_cache_drop(lfs, &lfs->rcache); int err = lfs_cache_flush(lfs, &lfs->pcache, NULL); if (err) { @@ -282,9 +286,9 @@ static int lfs_alloc_lookahead(void *p, lfs_block_t block) { static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) { while (true) { - while (lfs->free.index != lfs->free.size) { - lfs_block_t off = lfs->free.index; - lfs->free.index += 1; + while (lfs->free.i != lfs->free.size) { + lfs_block_t off = lfs->free.i; + lfs->free.i += 1; lfs->free.ack -= 1; if (!(lfs->free.buffer[off / 32] & (1U << (off % 32)))) { @@ -293,10 +297,10 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) { // eagerly find next off so an alloc ack can // discredit old lookahead blocks - while (lfs->free.index != lfs->free.size && - (lfs->free.buffer[lfs->free.index / 32] - & (1U << (lfs->free.index % 32)))) { - lfs->free.index += 1; + while (lfs->free.i != lfs->free.size && + (lfs->free.buffer[lfs->free.i / 32] + & (1U << (lfs->free.i % 32)))) { + lfs->free.i += 1; lfs->free.ack -= 1; } @@ -306,14 +310,15 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) { // check if we have looked at all blocks since last ack if (lfs->free.ack == 0) { - LFS_WARN("No more free space %ld", lfs->free.index+lfs->free.off); + LFS_WARN("No more free space %" PRIu32, + lfs->free.i + lfs->free.off); return LFS_ERR_NOSPC; } lfs->free.off = (lfs->free.off + lfs->free.size) % lfs->cfg->block_count; lfs->free.size = lfs_min(lfs->cfg->lookahead, lfs->free.ack); - lfs->free.index = 0; + lfs->free.i = 0; // find mask of free blocks from tree memset(lfs->free.buffer, 0, lfs->cfg->lookahead/8); @@ -412,11 +417,14 @@ static int lfs_dir_alloc(lfs_t *lfs, lfs_dir_t *dir) { // rather than clobbering one of the blocks we just pretend // the revision may be valid int err = lfs_bd_read(lfs, dir->pair[0], 0, &dir->d.rev, 4); - dir->d.rev = lfs_fromle32(dir->d.rev); - if (err) { + if (err && err != LFS_ERR_CORRUPT) { return err; } + if (err != LFS_ERR_CORRUPT) { + dir->d.rev = lfs_fromle32(dir->d.rev); + } + // set defaults dir->d.rev += 1; dir->d.size = sizeof(dir->d)+4; @@ -440,6 +448,9 @@ static int lfs_dir_fetch(lfs_t *lfs, int err = lfs_bd_read(lfs, tpair[i], 0, &test, sizeof(test)); lfs_dir_fromle32(&test); if (err) { + if (err == LFS_ERR_CORRUPT) { + continue; + } return err; } @@ -459,6 +470,9 @@ static int lfs_dir_fetch(lfs_t *lfs, err = lfs_bd_crc(lfs, tpair[i], sizeof(test), (0x7fffffff & test.size) - sizeof(test), &crc); if (err) { + if (err == LFS_ERR_CORRUPT) { + continue; + } return err; } @@ -476,7 +490,8 @@ static int lfs_dir_fetch(lfs_t *lfs, } if (!valid) { - LFS_ERROR("Corrupted dir pair at %ld %ld", tpair[0], tpair[1]); + LFS_ERROR("Corrupted dir pair at %" PRIu32 " %" PRIu32 , + tpair[0], tpair[1]); return LFS_ERR_CORRUPT; } @@ -599,15 +614,16 @@ static int lfs_dir_commit(lfs_t *lfs, lfs_dir_t *dir, break; relocate: //commit was corrupted - LFS_DEBUG("Bad block at %ld", dir->pair[0]); + LFS_DEBUG("Bad block at %" PRIu32, dir->pair[0]); // drop caches and prepare to relocate block relocated = true; - lfs->pcache.block = 0xffffffff; + lfs_cache_drop(lfs, &lfs->pcache); // can't relocate superblock, filesystem is now frozen if (lfs_paircmp(oldpair, (const lfs_block_t[2]){0, 1}) == 0) { - LFS_WARN("Superblock %ld has become unwritable", oldpair[0]); + LFS_WARN("Superblock %" PRIu32 " has become unwritable", + oldpair[0]); return LFS_ERR_CORRUPT; } @@ -620,7 +636,7 @@ static int lfs_dir_commit(lfs_t *lfs, lfs_dir_t *dir, if (relocated) { // update references if we relocated - LFS_DEBUG("Relocating %ld %ld to %ld %ld", + LFS_DEBUG("Relocating %" PRIu32 " %" PRIu32 " to %" PRIu32 " %" PRIu32, oldpair[0], oldpair[1], dir->pair[0], dir->pair[1]); int err = lfs_relocate(lfs, oldpair, dir->pair); if (err) { @@ -847,7 +863,7 @@ static int lfs_dir_find(lfs_t *lfs, lfs_dir_t *dir, // find entry matching name while (true) { - int err = lfs_dir_next(lfs, dir, entry); + err = lfs_dir_next(lfs, dir, entry); if (err) { return err; } @@ -1225,10 +1241,10 @@ static int lfs_ctz_extend(lfs_t *lfs, } relocate: - LFS_DEBUG("Bad block at %ld", nblock); + LFS_DEBUG("Bad block at %" PRIu32, nblock); // just clear cache and try a new block - pcache->block = 0xffffffff; + lfs_cache_drop(lfs, &lfs->pcache); } } @@ -1275,8 +1291,9 @@ static int lfs_ctz_traverse(lfs_t *lfs, /// Top level file operations /// -int lfs_file_open(lfs_t *lfs, lfs_file_t *file, - const char *path, int flags) { +int lfs_file_opencfg(lfs_t *lfs, lfs_file_t *file, + const char *path, int flags, + const struct lfs_file_config *cfg) { // deorphan if we haven't yet, needed at most once after poweron if ((flags & 3) != LFS_O_RDONLY && !lfs->deorphaned) { int err = lfs_deorphan(lfs); @@ -1316,6 +1333,7 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file, } // setup file struct + file->cfg = cfg; file->pair[0] = cwd.pair[0]; file->pair[1] = cwd.pair[1]; file->poff = entry.off; @@ -1334,7 +1352,13 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file, // allocate buffer if needed file->cache.block = 0xffffffff; - if (lfs->cfg->file_buffer) { + if (file->cfg && file->cfg->buffer) { + file->cache.buffer = file->cfg->buffer; + } else if (lfs->cfg->file_buffer) { + if (lfs->files) { + // already in use + return LFS_ERR_NOMEM; + } file->cache.buffer = lfs->cfg->file_buffer; } else if ((file->flags & 3) == LFS_O_RDONLY) { file->cache.buffer = lfs_malloc(lfs->cfg->read_size); @@ -1348,6 +1372,9 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file, } } + // zero to avoid information leak + lfs_cache_zero(lfs, &file->cache); + // add to list of files file->next = lfs->files; lfs->files = file; @@ -1355,6 +1382,11 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file, return 0; } +int lfs_file_open(lfs_t *lfs, lfs_file_t *file, + const char *path, int flags) { + return lfs_file_opencfg(lfs, file, path, flags, NULL); +} + int lfs_file_close(lfs_t *lfs, lfs_file_t *file) { int err = lfs_file_sync(lfs, file); @@ -1367,7 +1399,7 @@ int lfs_file_close(lfs_t *lfs, lfs_file_t *file) { } // clean up memory - if (!lfs->cfg->file_buffer) { + if (!(file->cfg && file->cfg->buffer) && !lfs->cfg->file_buffer) { lfs_free(file->cache.buffer); } @@ -1376,7 +1408,7 @@ int lfs_file_close(lfs_t *lfs, lfs_file_t *file) { static int lfs_file_relocate(lfs_t *lfs, lfs_file_t *file) { relocate: - LFS_DEBUG("Bad block at %ld", file->block); + LFS_DEBUG("Bad block at %" PRIu32, file->block); // just relocate what exists into new block lfs_block_t nblock; @@ -1416,7 +1448,7 @@ static int lfs_file_relocate(lfs_t *lfs, lfs_file_t *file) { memcpy(file->cache.buffer, lfs->pcache.buffer, lfs->cfg->prog_size); file->cache.block = lfs->pcache.block; file->cache.off = lfs->pcache.off; - lfs->pcache.block = 0xffffffff; + lfs_cache_zero(lfs, &lfs->pcache); file->block = nblock; return 0; @@ -1425,7 +1457,7 @@ static int lfs_file_relocate(lfs_t *lfs, lfs_file_t *file) { static int lfs_file_flush(lfs_t *lfs, lfs_file_t *file) { if (file->flags & LFS_F_READING) { // just drop read cache - file->cache.block = 0xffffffff; + lfs_cache_drop(lfs, &file->cache); file->flags &= ~LFS_F_READING; } @@ -1440,7 +1472,7 @@ static int lfs_file_flush(lfs_t *lfs, lfs_file_t *file) { .pos = file->pos, .cache = lfs->rcache, }; - lfs->rcache.block = 0xffffffff; + lfs_cache_drop(lfs, &lfs->rcache); while (file->pos < file->size) { // copy over a byte at a time, leave it up to caching @@ -1458,8 +1490,8 @@ static int lfs_file_flush(lfs_t *lfs, lfs_file_t *file) { // keep our reference to the rcache in sync if (lfs->rcache.block != 0xffffffff) { - orig.cache.block = 0xffffffff; - lfs->rcache.block = 0xffffffff; + lfs_cache_drop(lfs, &orig.cache); + lfs_cache_drop(lfs, &lfs->rcache); } } @@ -1637,7 +1669,7 @@ lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file, } // mark cache as dirty since we may have read data into it - file->cache.block = 0xffffffff; + lfs_cache_zero(lfs, &file->cache); } // extend file with new blocks @@ -1984,31 +2016,48 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) { /// Filesystem operations /// +static void lfs_deinit(lfs_t *lfs) { + // free allocated memory + if (!lfs->cfg->read_buffer) { + lfs_free(lfs->rcache.buffer); + } + + if (!lfs->cfg->prog_buffer) { + lfs_free(lfs->pcache.buffer); + } + + if (!lfs->cfg->lookahead_buffer) { + lfs_free(lfs->free.buffer); + } +} + static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) { lfs->cfg = cfg; // setup read cache - lfs->rcache.block = 0xffffffff; if (lfs->cfg->read_buffer) { lfs->rcache.buffer = lfs->cfg->read_buffer; } else { lfs->rcache.buffer = lfs_malloc(lfs->cfg->read_size); if (!lfs->rcache.buffer) { - return LFS_ERR_NOMEM; + goto cleanup; } } // setup program cache - lfs->pcache.block = 0xffffffff; if (lfs->cfg->prog_buffer) { lfs->pcache.buffer = lfs->cfg->prog_buffer; } else { lfs->pcache.buffer = lfs_malloc(lfs->cfg->prog_size); if (!lfs->pcache.buffer) { - return LFS_ERR_NOMEM; + goto cleanup; } } + // zero to avoid information leaks + lfs_cache_zero(lfs, &lfs->rcache); + lfs_cache_zero(lfs, &lfs->pcache); + // setup lookahead, round down to nearest 32-bits LFS_ASSERT(lfs->cfg->lookahead % 32 == 0); LFS_ASSERT(lfs->cfg->lookahead > 0); @@ -2017,7 +2066,7 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) { } else { lfs->free.buffer = lfs_malloc(lfs->cfg->lookahead/8); if (!lfs->free.buffer) { - return LFS_ERR_NOMEM; + goto cleanup; } } @@ -2037,23 +2086,10 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) { lfs->deorphaned = false; return 0; -} - -static int lfs_deinit(lfs_t *lfs) { - // free allocated memory - if (!lfs->cfg->read_buffer) { - lfs_free(lfs->rcache.buffer); - } - - if (!lfs->cfg->prog_buffer) { - lfs_free(lfs->pcache.buffer); - } - - if (!lfs->cfg->lookahead_buffer) { - lfs_free(lfs->free.buffer); - } - return 0; +cleanup: + lfs_deinit(lfs); + return LFS_ERR_NOMEM; } int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) { @@ -2066,26 +2102,26 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) { memset(lfs->free.buffer, 0, lfs->cfg->lookahead/8); lfs->free.off = 0; lfs->free.size = lfs_min(lfs->cfg->lookahead, lfs->cfg->block_count); - lfs->free.index = 0; + lfs->free.i = 0; lfs_alloc_ack(lfs); // create superblock dir lfs_dir_t superdir; err = lfs_dir_alloc(lfs, &superdir); if (err) { - return err; + goto cleanup; } // write root directory lfs_dir_t root; err = lfs_dir_alloc(lfs, &root); if (err) { - return err; + goto cleanup; } err = lfs_dir_commit(lfs, &root, NULL, 0); if (err) { - return err; + goto cleanup; } lfs->root[0] = root.pair[0]; @@ -2116,24 +2152,28 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) { &superblock.d, sizeof(superblock.d)} }, 1); if (err && err != LFS_ERR_CORRUPT) { - return err; + goto cleanup; } valid = valid || !err; } if (!valid) { - return LFS_ERR_CORRUPT; + err = LFS_ERR_CORRUPT; + goto cleanup; } // sanity check that fetch works err = lfs_dir_fetch(lfs, &superdir, (const lfs_block_t[2]){0, 1}); if (err) { - return err; + goto cleanup; } lfs_alloc_ack(lfs); - return lfs_deinit(lfs); + +cleanup: + lfs_deinit(lfs); + return err; } int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) { @@ -2145,7 +2185,7 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) { // setup free lookahead lfs->free.off = 0; lfs->free.size = 0; - lfs->free.index = 0; + lfs->free.i = 0; lfs_alloc_ack(lfs); // load superblock @@ -2153,7 +2193,7 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) { lfs_superblock_t superblock; err = lfs_dir_fetch(lfs, &dir, (const lfs_block_t[2]){0, 1}); if (err && err != LFS_ERR_CORRUPT) { - return err; + goto cleanup; } if (!err) { @@ -2161,7 +2201,7 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) { &superblock.d, sizeof(superblock.d)); lfs_superblock_fromle32(&superblock.d); if (err) { - return err; + goto cleanup; } lfs->root[0] = superblock.d.root[0]; @@ -2169,23 +2209,31 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) { } if (err || memcmp(superblock.d.magic, "littlefs", 8) != 0) { - LFS_ERROR("Invalid superblock at %ld %ld", dir.pair[0], dir.pair[1]); - return LFS_ERR_CORRUPT; + LFS_ERROR("Invalid superblock at %d %d", 0, 1); + err = LFS_ERR_CORRUPT; + goto cleanup; } uint16_t major_version = (0xffff & (superblock.d.version >> 16)); uint16_t minor_version = (0xffff & (superblock.d.version >> 0)); if ((major_version != LFS_DISK_VERSION_MAJOR || minor_version > LFS_DISK_VERSION_MINOR)) { - LFS_ERROR("Invalid version %ld.%ld", major_version, minor_version); - return LFS_ERR_INVAL; + LFS_ERROR("Invalid version %d.%d", major_version, minor_version); + err = LFS_ERR_INVAL; + goto cleanup; } return 0; + +cleanup: + + lfs_deinit(lfs); + return err; } int lfs_unmount(lfs_t *lfs) { - return lfs_deinit(lfs); + lfs_deinit(lfs); + return 0; } @@ -2385,7 +2433,8 @@ static int lfs_relocate(lfs_t *lfs, // update internal root if (lfs_paircmp(oldpair, lfs->root) == 0) { - LFS_DEBUG("Relocating root %ld %ld", newpair[0], newpair[1]); + LFS_DEBUG("Relocating root %" PRIu32 " %" PRIu32, + newpair[0], newpair[1]); lfs->root[0] = newpair[0]; lfs->root[1] = newpair[1]; } @@ -2441,7 +2490,7 @@ int lfs_deorphan(lfs_t *lfs) { if (!res) { // we are an orphan - LFS_DEBUG("Found orphan %ld %ld", + LFS_DEBUG("Found orphan %" PRIu32 " %" PRIu32, pdir.d.tail[0], pdir.d.tail[1]); pdir.d.tail[0] = cwd.d.tail[0]; @@ -2457,7 +2506,7 @@ int lfs_deorphan(lfs_t *lfs) { if (!lfs_pairsync(entry.d.u.dir, pdir.d.tail)) { // we have desynced - LFS_DEBUG("Found desync %ld %ld", + LFS_DEBUG("Found desync %" PRIu32 " %" PRIu32, entry.d.u.dir[0], entry.d.u.dir[1]); pdir.d.tail[0] = entry.d.u.dir[0]; @@ -2492,14 +2541,14 @@ int lfs_deorphan(lfs_t *lfs) { } if (moved) { - LFS_DEBUG("Found move %ld %ld", + LFS_DEBUG("Found move %" PRIu32 " %" PRIu32, entry.d.u.dir[0], entry.d.u.dir[1]); err = lfs_dir_remove(lfs, &cwd, &entry); if (err) { return err; } } else { - LFS_DEBUG("Found partial move %ld %ld", + LFS_DEBUG("Found partial move %" PRIu32 " %" PRIu32, entry.d.u.dir[0], entry.d.u.dir[1]); entry.d.type &= ~0x80; err = lfs_dir_update(lfs, &cwd, &entry, NULL); @@ -2515,4 +2564,3 @@ int lfs_deorphan(lfs_t *lfs) { return 0; } - diff --git a/features/filesystem/littlefs/littlefs/lfs.h b/features/filesystem/littlefs/littlefs/lfs.h index 68310f1542a3..f0c5839bec61 100644 --- a/features/filesystem/littlefs/littlefs/lfs.h +++ b/features/filesystem/littlefs/littlefs/lfs.h @@ -1,19 +1,8 @@ /* * The little filesystem * - * 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. + * Copyright (c) 2017, Arm Limited. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause */ #ifndef LFS_H #define LFS_H @@ -21,13 +10,18 @@ #include #include +#ifdef __cplusplus +extern "C" +{ +#endif + /// Version info /// // Software library version // Major (top-nibble), incremented on backwards incompatible changes // Minor (bottom-nibble), incremented on feature additions -#define LFS_VERSION 0x00010003 +#define LFS_VERSION 0x00010006 #define LFS_VERSION_MAJOR (0xffff & (LFS_VERSION >> 16)) #define LFS_VERSION_MINOR (0xffff & (LFS_VERSION >> 0)) @@ -173,6 +167,12 @@ struct lfs_config { void *file_buffer; }; +// Optional configuration provided during lfs_file_opencfg +struct lfs_file_config { + // Optional, statically allocated buffer for files. Must be program sized. + // If NULL, malloc will be used by default. + void *buffer; +}; // File info structure struct lfs_info { @@ -220,6 +220,7 @@ typedef struct lfs_file { lfs_block_t head; lfs_size_t size; + const struct lfs_file_config *cfg; uint32_t flags; lfs_off_t pos; lfs_block_t block; @@ -261,7 +262,7 @@ typedef struct lfs_superblock { typedef struct lfs_free { lfs_block_t off; lfs_block_t size; - lfs_block_t index; + lfs_block_t i; lfs_block_t ack; uint32_t *buffer; } lfs_free_t; @@ -287,7 +288,8 @@ typedef struct lfs { // Format a block device with the littlefs // // Requires a littlefs object and config struct. This clobbers the littlefs -// object, and does not leave the filesystem mounted. +// object, and does not leave the filesystem mounted. The config struct must +// be zeroed for defaults and backwards compatibility. // // Returns a negative error code on failure. int lfs_format(lfs_t *lfs, const struct lfs_config *config); @@ -296,7 +298,8 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *config); // // Requires a littlefs object and config struct. Multiple filesystems // may be mounted simultaneously with multiple littlefs objects. Both -// lfs and config must be allocated while mounted. +// lfs and config must be allocated while mounted. The config struct must +// be zeroed for defaults and backwards compatibility. // // Returns a negative error code on failure. int lfs_mount(lfs_t *lfs, const struct lfs_config *config); @@ -320,10 +323,6 @@ int lfs_remove(lfs_t *lfs, const char *path); // If the destination exists, it must match the source in type. // If the destination is a directory, the directory must be empty. // -// Note: If power loss occurs, it is possible that the file or directory -// will exist in both the oldpath and newpath simultaneously after the -// next mount. -// // Returns a negative error code on failure. int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath); @@ -338,14 +337,27 @@ int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info); // Open a file // -// The mode that the file is opened in is determined -// by the flags, which are values from the enum lfs_open_flags -// that are bitwise-ored together. +// The mode that the file is opened in is determined by the flags, which +// are values from the enum lfs_open_flags that are bitwise-ored together. // // Returns a negative error code on failure. int lfs_file_open(lfs_t *lfs, lfs_file_t *file, const char *path, int flags); +// Open a file with extra configuration +// +// The mode that the file is opened in is determined by the flags, which +// are values from the enum lfs_open_flags that are bitwise-ored together. +// +// The config struct provides additional config options per file as described +// above. The config struct must be allocated while the file is open, and the +// config struct must be zeroed for defaults and backwards compatibility. +// +// Returns a negative error code on failure. +int lfs_file_opencfg(lfs_t *lfs, lfs_file_t *file, + const char *path, int flags, + const struct lfs_file_config *config); + // Close a file // // Any pending writes are written out to storage as though @@ -475,4 +487,8 @@ int lfs_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data); int lfs_deorphan(lfs_t *lfs); +#ifdef __cplusplus +} /* extern "C" */ +#endif + #endif diff --git a/features/filesystem/littlefs/littlefs/lfs_util.c b/features/filesystem/littlefs/littlefs/lfs_util.c index 567977bae461..9ca0756d96b4 100644 --- a/features/filesystem/littlefs/littlefs/lfs_util.c +++ b/features/filesystem/littlefs/littlefs/lfs_util.c @@ -1,23 +1,16 @@ /* * lfs util functions * - * 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. + * Copyright (c) 2017, Arm Limited. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause */ #include "lfs_util.h" +// Only compile if user does not provide custom config +#ifndef LFS_CONFIG + +// Software CRC implementation with small lookup table void lfs_crc(uint32_t *restrict crc, const void *buffer, size_t size) { static const uint32_t rtable[16] = { 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, @@ -34,3 +27,5 @@ void lfs_crc(uint32_t *restrict crc, const void *buffer, size_t size) { } } + +#endif diff --git a/features/filesystem/littlefs/littlefs/lfs_util.h b/features/filesystem/littlefs/littlefs/lfs_util.h index e70e96ce443f..50e25daa7faf 100644 --- a/features/filesystem/littlefs/littlefs/lfs_util.h +++ b/features/filesystem/littlefs/littlefs/lfs_util.h @@ -1,23 +1,25 @@ /* * lfs utility functions * - * 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. + * Copyright (c) 2017, Arm Limited. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause */ #ifndef LFS_UTIL_H #define LFS_UTIL_H +// Users can override lfs_util.h with their own configuration by defining +// LFS_CONFIG as a header file to include (-DLFS_CONFIG=lfs_config.h). +// +// If LFS_CONFIG is used, none of the default utils will be emitted and must be +// provided by the config file. To start I would suggest copying lfs_util.h and +// modifying as needed. +#ifdef LFS_CONFIG +#define LFS_STRINGIZE(x) LFS_STRINGIZE2(x) +#define LFS_STRINGIZE2(x) #x +#include LFS_STRINGIZE(LFS_CONFIG) +#else + +// System includes #include #include #include @@ -32,6 +34,11 @@ #include #endif +#ifdef __cplusplus +extern "C" +{ +#endif + // Macros, may be replaced by system specific wrappers. Arguments to these // macros must not have side-effects as the macros can be removed for a smaller @@ -184,6 +191,7 @@ static inline void *lfs_malloc(size_t size) { #ifndef LFS_NO_MALLOC return malloc(size); #else + (void)size; return NULL; #endif } @@ -192,8 +200,15 @@ static inline void *lfs_malloc(size_t size) { static inline void lfs_free(void *p) { #ifndef LFS_NO_MALLOC free(p); +#else + (void)p; #endif } +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif #endif diff --git a/features/filesystem/littlefs/littlefs/tests/test_files.sh b/features/filesystem/littlefs/littlefs/tests/test_files.sh index b2039a7b1e27..bbecea9285b4 100755 --- a/features/filesystem/littlefs/littlefs/tests/test_files.sh +++ b/features/filesystem/littlefs/littlefs/tests/test_files.sh @@ -30,7 +30,7 @@ TEST w_test() { tests/test.py << TEST - lfs_size_t size = $1; + size = $1; lfs_size_t chunk = 31; srand(0); lfs_mount(&lfs, &cfg) => 0; @@ -50,7 +50,7 @@ TEST r_test() { tests/test.py << TEST - lfs_size_t size = $1; + size = $1; lfs_size_t chunk = 29; srand(0); lfs_mount(&lfs, &cfg) => 0; diff --git a/features/filesystem/littlefs/littlefs/tests/test_parallel.sh b/features/filesystem/littlefs/littlefs/tests/test_interspersed.sh similarity index 98% rename from features/filesystem/littlefs/littlefs/tests/test_parallel.sh rename to features/filesystem/littlefs/littlefs/tests/test_interspersed.sh index 71c9c1f3b9c1..52e24bc689b2 100755 --- a/features/filesystem/littlefs/littlefs/tests/test_parallel.sh +++ b/features/filesystem/littlefs/littlefs/tests/test_interspersed.sh @@ -1,13 +1,13 @@ #!/bin/bash set -eu -echo "=== Parallel tests ===" +echo "=== Interspersed tests ===" rm -rf blocks tests/test.py << TEST lfs_format(&lfs, &cfg) => 0; TEST -echo "--- Parallel file test ---" +echo "--- Interspersed file test ---" tests/test.py << TEST lfs_mount(&lfs, &cfg) => 0; lfs_file_open(&lfs, &file[0], "a", LFS_O_WRONLY | LFS_O_CREAT) => 0; @@ -77,7 +77,7 @@ tests/test.py << TEST lfs_unmount(&lfs) => 0; TEST -echo "--- Parallel remove file test ---" +echo "--- Interspersed remove file test ---" tests/test.py << TEST lfs_mount(&lfs, &cfg) => 0; lfs_file_open(&lfs, &file[0], "e", LFS_O_WRONLY | LFS_O_CREAT) => 0; diff --git a/features/filesystem/littlefs/littlefs/tests/test_seek.sh b/features/filesystem/littlefs/littlefs/tests/test_seek.sh index 3b46892b6ea7..0084d42f1670 100755 --- a/features/filesystem/littlefs/littlefs/tests/test_seek.sh +++ b/features/filesystem/littlefs/littlefs/tests/test_seek.sh @@ -153,7 +153,7 @@ tests/test.py << TEST lfs_file_read(&lfs, &file[0], buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0; - lfs_size_t size = lfs_file_size(&lfs, &file[0]); + size = lfs_file_size(&lfs, &file[0]); lfs_file_seek(&lfs, &file[0], 0, LFS_SEEK_CUR) => size; lfs_file_close(&lfs, &file[0]) => 0; @@ -202,7 +202,7 @@ tests/test.py << TEST lfs_file_read(&lfs, &file[0], buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0; - lfs_size_t size = lfs_file_size(&lfs, &file[0]); + size = lfs_file_size(&lfs, &file[0]); lfs_file_seek(&lfs, &file[0], 0, LFS_SEEK_CUR) => size; lfs_file_close(&lfs, &file[0]) => 0; @@ -243,7 +243,7 @@ tests/test.py << TEST lfs_file_read(&lfs, &file[0], buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0; - lfs_size_t size = lfs_file_size(&lfs, &file[0]); + size = lfs_file_size(&lfs, &file[0]); lfs_file_seek(&lfs, &file[0], 0, LFS_SEEK_CUR) => size; lfs_file_close(&lfs, &file[0]) => 0; @@ -286,7 +286,7 @@ tests/test.py << TEST lfs_file_read(&lfs, &file[0], buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0; - lfs_size_t size = lfs_file_size(&lfs, &file[0]); + size = lfs_file_size(&lfs, &file[0]); lfs_file_seek(&lfs, &file[0], 0, LFS_SEEK_CUR) => size; lfs_file_close(&lfs, &file[0]) => 0; diff --git a/features/frameworks/mbed-coap/CHANGELOG.md b/features/frameworks/mbed-coap/CHANGELOG.md index ca4755366c1c..7b874b354c8f 100644 --- a/features/frameworks/mbed-coap/CHANGELOG.md +++ b/features/frameworks/mbed-coap/CHANGELOG.md @@ -1,5 +1,25 @@ # Change Log +## [v4.6.1](https://github.com/ARMmbed/mbed-coap/releases/tag/v4.6.1) +**Closed issues:** +- IOTCLT-2900 - Blockwise handling leaking memory in some error cases + +Fix unused parameter compiler warning when blockwise is not used. + +-[Full Changelog](https://github.com/ARMmbed/mbed-coap/compare/v4.6.0...v4.6.1) + +## [v4.6.0](https://github.com/ARMmbed/mbed-coap/releases/tag/v4.6.0) +**New feature:** +- Add new API which clears one item from the resend queue based on token + +-[Full Changelog](https://github.com/ARMmbed/mbed-coap/compare/v4.5.1...v4.6.0) + +## [v4.5.1](https://github.com/ARMmbed/mbed-coap/releases/tag/v4.5.1) +**Closed issues:** + - IOTCLT-2883 - Blockwise observations not completing + +-[Full Changelog](https://github.com/ARMmbed/mbed-coap/compare/v4.5.0...v4.5.1) + ## [v4.5.0](https://github.com/ARMmbed/mbed-coap/releases/tag/v4.5.0) **Closed issues:** - IIOTCLT-2769 - mbed-coap: extra response received after registration diff --git a/features/frameworks/mbed-coap/mbed-coap/sn_coap_protocol.h b/features/frameworks/mbed-coap/mbed-coap/sn_coap_protocol.h index a2f91bf0d589..7bc83419d228 100644 --- a/features/frameworks/mbed-coap/mbed-coap/sn_coap_protocol.h +++ b/features/frameworks/mbed-coap/mbed-coap/sn_coap_protocol.h @@ -224,6 +224,18 @@ extern void sn_coap_protocol_remove_sent_blockwise_message(struct coap_s *handle */ extern int8_t sn_coap_protocol_delete_retransmission(struct coap_s *handle, uint16_t msg_id); +/** + * \fn void sn_coap_protocol_delete_retransmission_by_token(struct coap_s *handle) + * + * \param *handle Pointer to CoAP library handle + * \token Token to be removed + * \token_len Length of the token + * \return returns 0 when success, -1 for invalid parameter, -2 if message was not found + * + * \brief If re-transmissions are enabled, this function removes message from retransmission buffer. + */ +extern int8_t sn_coap_protocol_delete_retransmission_by_token(struct coap_s *handle, uint8_t *token, uint8_t token_len); + /** * \fn int8_t sn_coap_convert_block_size(uint16_t block_size) * diff --git a/features/frameworks/mbed-coap/module.json b/features/frameworks/mbed-coap/module.json index bf488b5c0e99..eead179054b3 100644 --- a/features/frameworks/mbed-coap/module.json +++ b/features/frameworks/mbed-coap/module.json @@ -1,6 +1,6 @@ { "name": "mbed-coap", - "version": "4.5.0", + "version": "4.6.1", "description": "COAP library", "keywords": [ "coap", diff --git a/features/frameworks/mbed-coap/source/sn_coap_protocol.c b/features/frameworks/mbed-coap/source/sn_coap_protocol.c index 1aaaaa68f7c9..9dc46f1b26ec 100644 --- a/features/frameworks/mbed-coap/source/sn_coap_protocol.c +++ b/features/frameworks/mbed-coap/source/sn_coap_protocol.c @@ -120,30 +120,17 @@ int8_t sn_coap_protocol_destroy(struct coap_s *handle) ns_list_foreach_safe(coap_blockwise_msg_s, tmp, &handle->linked_list_blockwise_sent_msgs) { if (tmp->coap == handle) { if (tmp->coap_msg_ptr) { - if (tmp->coap_msg_ptr->payload_ptr) { - handle->sn_coap_protocol_free(tmp->coap_msg_ptr->payload_ptr); - tmp->coap_msg_ptr->payload_ptr = 0; - } + handle->sn_coap_protocol_free(tmp->coap_msg_ptr->payload_ptr); sn_coap_parser_release_allocated_coap_msg_mem(tmp->coap, tmp->coap_msg_ptr); } ns_list_remove(&handle->linked_list_blockwise_sent_msgs, tmp); handle->sn_coap_protocol_free(tmp); - tmp = 0; } } + ns_list_foreach_safe(coap_blockwise_payload_s, tmp, &handle->linked_list_blockwise_received_payloads) { if (tmp->coap == handle) { - if (tmp->addr_ptr) { - handle->sn_coap_protocol_free(tmp->addr_ptr); - tmp->addr_ptr = 0; - } - if (tmp->payload_ptr) { - handle->sn_coap_protocol_free(tmp->payload_ptr); - tmp->payload_ptr = 0; - } - ns_list_remove(&handle->linked_list_blockwise_received_payloads, tmp); - handle->sn_coap_protocol_free(tmp); - tmp = 0; + sn_coap_protocol_linked_list_blockwise_payload_remove(handle, tmp); } } #endif @@ -363,9 +350,42 @@ int8_t sn_coap_protocol_delete_retransmission(struct coap_s *handle, uint16_t ms return -2; } +int8_t sn_coap_protocol_delete_retransmission_by_token(struct coap_s *handle, uint8_t *token, uint8_t token_len) +{ +#if ENABLE_RESENDINGS /* If Message resending is not used at all, this part of code will not be compiled */ + if (handle == NULL || token == NULL || token_len == 0) { + tr_error("sn_coap_protocol_delete_retransmission_by_token NULL"); + return -1; + } + + ns_list_foreach(coap_send_msg_s, stored_msg, &handle->linked_list_resent_msgs) { + uint8_t stored_token_len = (stored_msg->send_msg_ptr->packet_ptr[0] & 0x0F); + if (stored_token_len == token_len) { + uint8_t stored_token[8]; + memcpy(stored_token, &stored_msg->send_msg_ptr->packet_ptr[4], stored_token_len); + if (memcmp(stored_token, token, stored_token_len) == 0) { + uint16_t temp_msg_id = (stored_msg->send_msg_ptr->packet_ptr[2] << 8); + temp_msg_id += (uint16_t)stored_msg->send_msg_ptr->packet_ptr[3]; + tr_debug("sn_coap_protocol_delete_retransmission_by_token - removed msg_id: %d", temp_msg_id); + ns_list_remove(&handle->linked_list_resent_msgs, stored_msg); + --handle->count_resent_msgs; + + /* Free memory of stored message */ + sn_coap_protocol_release_allocated_send_msg_mem(handle, stored_msg); + return 0; + } + } + } +#endif + return -2; +} + int8_t prepare_blockwise_message(struct coap_s *handle, sn_coap_hdr_s *src_coap_msg_ptr) { + (void) handle; + (void) src_coap_msg_ptr; + #if SN_COAP_BLOCKWISE_ENABLED || SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE /* If Message blockwising is not enabled, this part of code will not be compiled */ if ((src_coap_msg_ptr->payload_len > SN_COAP_MAX_NONBLOCKWISE_PAYLOAD_SIZE) && (src_coap_msg_ptr->payload_len > handle->sn_coap_block_data_size) && @@ -1723,7 +1743,7 @@ static coap_blockwise_msg_s *sn_coap_stored_blockwise_msg_get(struct coap_s *han } } - return NULL; + return ns_list_get_first(&handle->linked_list_blockwise_sent_msgs); } /**************************************************************************//** diff --git a/features/lorawan/LoRaWANBase.h b/features/lorawan/LoRaWANBase.h index 959f43d6dd9a..a57a6398067d 100644 --- a/features/lorawan/LoRaWANBase.h +++ b/features/lorawan/LoRaWANBase.h @@ -31,261 +31,351 @@ class LoRaWANBase { * * @param queue A pointer to EventQueue provided by the application. * - * @return LORAWAN_STATUS_OK on success, a negative error code on - * failure. + * @return LORAWAN_STATUS_OK on success, a negative error code on failure: + * LORAWAN_STATUS_PARAMETER_INVALID is NULL queue is given. */ virtual lorawan_status_t initialize(events::EventQueue *queue) = 0; - /** Connect OTAA or ABP by setup. + /** Connect OTAA or ABP using the Mbed OS config system * * Connect by Over The Air Activation or Activation By Personalization. - * The connection type is selected at the setup. - * - * @return For ABP: If everything goes well, LORAWAN_STATUS_OK is returned for first call followed by - * a 'CONNECTED' event. Otherwise a negative error code is returned. + * You need to configure the connection properly using the Mbed OS configuration system. + * + * When connecting through OTAA, the return code for success (LORAWAN_STATUS_CONNECT_IN_PROGRESS) + * is negative. However, this is not a real error. It tells you that the connection is in progress, + * and an event will notify you of the completion. By default, after the Join Accept message is + * received, base stations may provide the node with a CF-List that replaces all user-configured + * channels except the Join/Default channels. A CF-List can configure a maximum of five channels + * other than the default channels. + * + * To configure more channels, we recommend that you use the `set_channel_plan()` API after the connection. + * By default, the PHY layers configure only the mandatory Join channels. The retransmission back-off + * restrictions on these channels are severe, and you may experience long delays or even failures + * in the confirmed traffic. If you add more channels, the aggregated duty cycle becomes much more + * relaxed as compared to the Join (default) channels only. + * + * **NOTES ON RECONNECTION:** + * Currently, the Mbed OS LoRaWAN implementation does not support non-volatile memory storage. + * Therefore, the state and frame counters cannot be restored after a power cycle. However, + * if you use the `disconnect()` API to shut down the LoRaWAN protocol, the state and frame + * counters are saved. Connecting again restores the previous session. According to the LoRaWAN + * 1.0.2 specification, the frame counters are always reset to 0 for OTAA, and a new Join request + * lets the network server know that the counters need a reset. The same is said about the ABP, + * but there is no way to convey this information to the network server. For a network server, + * an ABP device is always connected. That's why storing the frame counters is important for ABP. + * That's why we restore frame counters from session information after a disconnection. + * + * @return Common: LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), + * LORAWAN_STATUS_PARAMETER_INVALID if connection parameters are invalid. + * + * For ABP: If everything goes well, LORAWAN_STATUS_OK is returned for first call + * followed by a 'CONNECTED' event. Otherwise a negative error code is returned: * Any subsequent call will return LORAWAN_STATUS_ALREADY_CONNECTED and no event follows. * - * For OTAA: When a JoinRequest is sent, LORAWAN_STATUS_CONNECT_IN_PROGRESS is returned for the first call. - * Any subsequent call will return either LORAWAN_STATUS_BUSY (if the previous request for connection - * is still underway) or LORAWAN_STATUS_ALREADY_CONNECTED (if a network was already joined successfully). + * For OTAA: When a JoinRequest is sent, LORAWAN_STATUS_CONNECT_IN_PROGRESS is returned for + * the first call. Any subsequent call will return either LORAWAN_STATUS_BUSY + * (if the previous request for connection is still underway) or + * LORAWAN_STATUS_ALREADY_CONNECTED (if a network was already joined successfully). * A 'CONNECTED' event is sent to the application when the JoinAccept is received. */ virtual lorawan_status_t connect() = 0; - /** Connect OTAA or ABP by parameters - * - * Connect by Over The Air Activation or Activation By Personalization. - * The connection type is selected using the parameters. - * You need to define the parameters in the main application. - * - * @param connect Options how end-device will connect to gateway - * - * @return For ABP: If everything goes well, LORAWAN_STATUS_OK is returned for first call followed by - * a 'CONNECTED' event. Otherwise a negative error code is returned. + /** Connect OTAA or ABP with parameters + * + * All connection parameters are chosen by you and provided in the data structure passed down. + * + * When connecting using OTAA, the return code for success (LORAWAN_STATUS_CONNECT_IN_PROGRESS) + * is negative. However, this is not a real error. It tells you that connection is in progress, + * and an event will notify you of completion. By default, after Join Accept message is received, + * base stations may provide the node with a CF-List that replaces all user-configured channels + * except the Join/Default channels. A CF-List can configure a maximum of five channels other + * than the default channels. + * + * To configure more channels, we recommend that you use the `set_channel_plan()` API after + * the connection. By default, the PHY layers configure only the mandatory Join channels. + * The retransmission back-off restrictions on these channels are severe, and you may experience + * long delays or even failures in the confirmed traffic. If you add more channels, the aggregated + * duty cycle becomes much more relaxed as compared to the Join (default) channels only. + * + * **NOTES ON RECONNECTION:** + * Currently, the Mbed OS LoRaWAN implementation does not support non-volatile memory storage. + * Therefore, the state and frame counters cannot be restored after a power cycle. However, + * if you use the `disconnect()` API to shut down the LoRaWAN protocol, the state and frame + * counters are saved. Connecting again restores the previous session. According to the LoRaWAN + * 1.0.2 specification, the frame counters are always reset to zero for OTAA, and a new Join + * request lets the network server know that the counters need a reset. The same is said about + * the ABP, but there is no way to convey this information to the network server. For a network + * server, an ABP device is always connected. That's why storing the frame counters is important + * for ABP. That's why we restore frame counters from session information after a disconnection. + * + * @param connect Options for an end device connection to the gateway. + * + * @return Common: LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), + * LORAWAN_STATUS_PARAMETER_INVALID if connection parameters are invalid. + * + * For ABP: If everything goes well, LORAWAN_STATUS_OK is returned for first call followed + * by a 'CONNECTED' event. Otherwise a negative error code is returned. * Any subsequent call will return LORAWAN_STATUS_ALREADY_CONNECTED and no event follows. * - * For OTAA: When a JoinRequest is sent, LORAWAN_STATUS_CONNECT_IN_PROGRESS is returned for the first call. - * Any subsequent call will return either LORAWAN_STATUS_BUSY (if the previous request for connection - * is still underway) or LORAWAN_STATUS_ALREADY_CONNECTED (if a network was already joined successfully). + * For OTAA: When a JoinRequest is sent, LORAWAN_STATUS_CONNECT_IN_PROGRESS is returned for the + * first call. Any subsequent call will return either LORAWAN_STATUS_BUSY + * (if the previous request for connection is still underway) or LORAWAN_STATUS_ALREADY_CONNECTED + * (if a network was already joined successfully). * A 'CONNECTED' event is sent to the application when the JoinAccept is received. */ virtual lorawan_status_t connect(const lorawan_connect_t &connect) = 0; - /** Disconnects the current session. + /** Disconnect the current session. * - * @return LORAWAN_STATUS_OK on success, a negative error code on failure. + * @return LORAWAN_STATUS_DEVICE_OFF on success, a negative error code on failure: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), */ virtual lorawan_status_t disconnect() = 0; /** Validate the connectivity with the network. * - * Application may use this API to submit a request to the stack for - * validation of its connectivity to a Network Server. Under the hood, this - * API schedules a Link Check Request command (LinkCheckReq) for the network - * server and once the response, i.e., LinkCheckAns MAC command is received - * from the Network Server, user provided method is called. + * Application may use this API to submit a request to the stack for validation of its connectivity + * to a Network Server. Under the hood, this API schedules a Link Check Request command (LinkCheckReq) + * for the network server and once the response, i.e., LinkCheckAns MAC command is received from + * the Network Server, user provided method is called. * - * This API is usable only when the link check response is callback set by - * the application. See add_lora_app_callbacks API. If the above mentioned - * callback is not set, a LORAWAN_STATUS_PARAMETER_INVALID error is thrown. + * One way to use this API may be the validation of connectivity after a long deep sleep. + * Mbed LoRaWANStack follows the MAC commands with data frame payload, so the application needs + * to send something, and the Network Server may respond during the RX slots. * - * First parameter to callback function is the demodulation margin and - * the second parameter is the number of gateways that successfully received - * the last request. + * This API is usable only when the application sets the 'link_check_resp' callback. + * See add_lora_app_callbacks API. If the above mentioned callback is not set, + * a LORAWAN_STATUS_PARAMETER_INVALID error is thrown. * - * A 'Link Check Request' MAC command remains set for every subsequent - * transmission, until/unless application explicitly turns it off using - * remove_link_check_request() API. + * The first parameter to callback function is the demodulation margin, and the second parameter + * is the number of gateways that successfully received the last request. + * + * A 'Link Check Request' MAC command remains set for every subsequent transmission, until/unless + * the application explicitly turns it off using the remove_link_check_request() API. * * @return LORAWAN_STATUS_OK on successfully queuing a request, or - * a negative error code on failure. + * a negative error code on failure: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), + * LORAWAN_STATUS_PARAMETER_INVALID if link_check_resp callback method is not set. * */ virtual lorawan_status_t add_link_check_request() = 0; - /** Detaches Link Request MAC command. + /** Removes link check request sticky MAC command. * - * Removes sticky MAC command for link check request. + * Any already queued request may still be completed. However, no new requests will be made. */ virtual void remove_link_check_request() = 0; - /** Sets up a particular data rate of choice + /** Sets up a particular data rate * - * @param data_rate Intended data rate e.g., DR_0, DR_1 etc. - * Caution is advised as the macro DR_* can mean different - * things while being in a different region. - * @return LORAWAN_STATUS_OK if everything goes well, otherwise - * a negative error code. + * @param data_rate The intended data rate, for example DR_0 or DR_1. + * Please note that the macro DR_* can mean different things in different regions. + * @return LORAWAN_STATUS_OK if everything goes well, otherwise a negative error code: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), + * LORAWAN_STATUS_PARAMETER_INVALID if ADR is enabled or invalid data rate is given */ virtual lorawan_status_t set_datarate(uint8_t data_rate) = 0; /** Enables adaptive data rate (ADR) * - * Underlying LoRaPHY and LoRaMac layers handle the data rate automatically - * for the user based upon radio conditions (network congestion). + * The underlying LoRaPHY and LoRaMac layers handle the data rate automatically + * based on the radio conditions (network congestion). * - * @return LORAWAN_STATUS_OK on success, negative error code - * on failure. + * @return LORAWAN_STATUS_OK on success, negative error code on failure: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize() */ virtual lorawan_status_t enable_adaptive_datarate() = 0; /** Disables adaptive data rate * - * When adaptive data rate (ADR) is disabled, user can either set a certain - * data rate or the Mac layer will choose a default value. + * When adaptive data rate (ADR) is disabled, either you can set a certain + * data rate, or the MAC layer selects a default value. * - * @return LORAWAN_STATUS_OK on success, negative error code - * on failure. + * @return LORAWAN_STATUS_OK on success, negative error code on failure: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize() */ virtual lorawan_status_t disable_adaptive_datarate() = 0; - /** Sets up retry counter for confirmed messages + /** Sets up the retry counter for confirmed messages. * - * Valid only for confirmed messages. + * Valid for confirmed messages only. * - * Number of trials to transmit the frame, if the LoRaMAC layer did not - * receive an acknowledgment. The MAC performs a data-rate adaptation, - * according to the LoRaWAN Specification V1.0.2, chapter 18.4, according - * to the table on page 64. + * The number of trials to transmit the frame, if the LoRaMAC layer did not receive an + * acknowledgment. The MAC performs a data rate adaptation as in the LoRaWAN Specification + * V1.0.2, chapter 18.4, table on page 64. * - * Note, that if the number of trials is set to 1 or 2, the MAC will not decrease - * the datarate, in case the LoRaMAC layer did not receive an acknowledgment. + * Note that if the number of retries is set to 1 or 2, MAC does not decrease the data rate, + * if the LoRaMAC layer did not receive an acknowledgment. * - * @param count number of retries for confirmed messages + * @param count The number of retries for confirmed messages. * - * @return LORAWAN_STATUS_OK or a negative error code + * @return LORAWAN_STATUS_OK or a negative error code on failure: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize() + * LORAWAN_STATUS_PARAMETER_INVALID if count >= 255 */ virtual lorawan_status_t set_confirmed_msg_retries(uint8_t count) = 0; - /** Sets channel plan - * - * @param channel_plan The defined channel plans to be set. - * @return 0 on success, a negative error code on failure. + /** Sets the channel plan. + * + * You can provide a list of channels with appropriate parameters filled in. However, + * this list is not absolute. The stack applies a CF-List whenever available, which means + * that the network can overwrite your channel frequency settings right after Join Accept + * is received. You may try to set up any channel or channels after that, and if the channel + * requested is already active, the request is silently ignored. A negative error code is + * returned if there is any problem with parameters. + * + * Please note that you can also use this API to add a single channel to the existing channel plan. + * + * There is no reverse mechanism in the 1.0.2 specification for a node to request a particular + * channel. Only the network server can initiate such a request. + * You need to ensure that the corresponding base station supports the channel or channels being added. + * + * If your list includes a default channel (a channel where Join Requests are received), + * you cannot fully configure the channel parameters. Either leave the channel settings to default, + * or check your corresponding PHY layer implementation. For example, LoRaPHYE868. + * + * @param channel_plan The channel plan to set. + * + * @return LORAWAN_STATUS_OK on success, a negative error code on failure: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), + * LORAWAN_STATUS_PARAMETER_INVALID if number of channels is exceeding the PHY limit, + * LORAWAN_STATUS_DATARATE_INVALID if invalid data rate is given, + * LORAWAN_STATUS_FREQUENCY_INVALID if invalid frequency is given, + * LORAWAN_STATUS_FREQ_AND_DR_INVALID if invalid data rate and freqency are given, + * LORAWAN_STATUS_BUSY if TX currently ongoing, + * LORAWAN_STATUS_SERVICE_UNKNOWN if custom channel plans are disabled in PHY */ virtual lorawan_status_t set_channel_plan(const lorawan_channelplan_t &channel_plan) = 0; - /** Gets the current channel plan. + /** Gets the channel plans from the LoRa stack. + * + * Once you have selected a particular PHY layer, a set of channels is automatically activated. + * Right after connecting, you can use this API to see the current plan. Otherwise, this API + * returns the channel plan that you have set using `set_channel_plan()`. * - * @param channel_plan The current channel information. + * @param channel_plan The current channel plan information. * - * @return LORAWAN_STATUS_OK on success, a negative error - * code on failure. + * @return LORAWAN_STATUS_OK on success, a negative error code on failure: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), + * LORAWAN_STATUS_SERVICE_UNKNOWN if custom channel plans are disabled in PHY */ virtual lorawan_status_t get_channel_plan(lorawan_channelplan_t &channel_plan) = 0; - /** Removes currently active channel plan + /** Removes an active channel plan. * - * Default channels (channels where Base Stations are listening) are not - * allowed to be removed. So when a plan is abolished, only non-default - * channels are removed. + * You cannot remove default channels (the channels the base stations are listening to). + * When a plan is abolished, only the non-default channels are removed. * - * @return LORAWAN_STATUS_OK on success, negative error - * code on failure + * @return LORAWAN_STATUS_OK on success, negative error code on failure + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), + * LORAWAN_STATUS_BUSY if TX currently ongoing, + * LORAWAN_STATUS_SERVICE_UNKNOWN if custom channel plans are disabled in PHY */ virtual lorawan_status_t remove_channel_plan() = 0; - /** Removes a given single channel + /** Removes a single channel. * - * Default channels (channels where Base Stations are listening) are not - * allowed to be removed. + * You cannot remove default channels (the channels the base stations are listening to). * - * @param index The channel index + * @param index The channel index. * - * @return LORAWAN_STATUS_OK on success, negative error - * code on failure + * @return LORAWAN_STATUS_OK on success, negative error code on failure: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), + * LORAWAN_STATUS_PARAMETER_INVALID if invalid channel index is given, + * LORAWAN_STATUS_BUSY if TX currently ongoing, + * LORAWAN_STATUS_SERVICE_UNKNOWN if custom channel plans are disabled in PHY */ virtual lorawan_status_t remove_channel(uint8_t index) = 0; /** Send message to gateway * - * @param port The application port number. Port numbers 0 and 224 - * are reserved, whereas port numbers from 1 to 223 - * (0x01 to 0xDF) are valid port numbers. - * Anything out of this range is illegal. + * @param port The application port number. Port numbers 0 and 224 are reserved, + * whereas port numbers from 1 to 223 (0x01 to 0xDF) are valid port numbers. + * Anything out of this range is illegal. * - * @param data A pointer to the data being sent. The ownership of the - * buffer is not transferred. The data is copied to the - * internal buffers. + * @param data A pointer to the data being sent. The ownership of the buffer is not transferred. + * The data is copied to the internal buffers. * - * @param length The size of data in bytes. + * @param length The size of data in bytes. * - * @param flags A flag used to determine what type of - * message is being sent, for example: + * @param flags A flag used to determine what type of message is being sent, for example: * - * MSG_UNCONFIRMED_FLAG = 0x01 - * MSG_CONFIRMED_FLAG = 0x02 - * MSG_MULTICAST_FLAG = 0x04 - * MSG_PROPRIETARY_FLAG = 0x08 + * MSG_UNCONFIRMED_FLAG = 0x01 + * MSG_CONFIRMED_FLAG = 0x02 + * MSG_MULTICAST_FLAG = 0x04 + * MSG_PROPRIETARY_FLAG = 0x08 * - * All flags are mutually exclusive, and MSG_MULTICAST_FLAG - * cannot be set. + * All flags are mutually exclusive, and MSG_MULTICAST_FLAG cannot be set. * - * @return The number of bytes sent, or - * LORAWAN_STATUS_WOULD_BLOCK if another TX is - * ongoing, or a negative error code on failure. + * @return The number of bytes sent, or a negative error code on failure: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), + * LORAWAN_STATUS_NO_ACTIVE_SESSIONS if connection is not open, + * LORAWAN_STATUS_WOULD_BLOCK if another TX is ongoing, + * LORAWAN_STATUS_PORT_INVALID if trying to send to an invalid port (e.g. to 0) + * LORAWAN_STATUS_PARAMETER_INVALID if NULL data pointer is given or flags are invalid. */ virtual int16_t send(uint8_t port, const uint8_t *data, uint16_t length, int flags) = 0; /** Receives a message from the Network Server on a specific port. * - * @param port The application port number. Port numbers 0 and 224 - * are reserved, whereas port numbers from 1 to 223 - * (0x01 to 0xDF) are valid port numbers. - * Anything out of this range is illegal. + * @param port The application port number. Port numbers 0 and 224 are reserved, + * whereas port numbers from 1 to 223 (0x01 to 0xDF) are valid port numbers. + * Anything out of this range is illegal. * - * @param data A pointer to buffer where the received data will be - * stored. + * @param data A pointer to buffer where the received data will be stored. * - * @param length The size of data in bytes. + * @param length The size of data in bytes. * - * @param flags A flag is used to determine what type of - * message is being sent, for example: + * @param flags A flag is used to determine what type of message is being sent, for example: * - * MSG_UNCONFIRMED_FLAG = 0x01, - * MSG_CONFIRMED_FLAG = 0x02 - * MSG_MULTICAST_FLAG = 0x04, - * MSG_PROPRIETARY_FLAG = 0x08 + * MSG_UNCONFIRMED_FLAG = 0x01 + * MSG_CONFIRMED_FLAG = 0x02 + * MSG_MULTICAST_FLAG = 0x04 + * MSG_PROPRIETARY_FLAG = 0x08 * - * All flags can be used in conjunction with - * one another depending on the intended use case or reception - * expectation. + * All flags can be used in conjunction with one another depending on the intended + * use case or reception expectation. * - * e.g., MSG_CONFIRMED_FLAG and MSG_UNCONFIRMED_FLAG are - * not mutually exclusive, i.e., the user can subscribe to - * receive both CONFIRMED AND UNCONFIRMED messages at - * the same time. + * For example, MSG_CONFIRMED_FLAG and MSG_UNCONFIRMED_FLAG are + * not mutually exclusive. In other words, the user can subscribe to + * receive both CONFIRMED AND UNCONFIRMED messages at the same time. * - * @return It could be one of these: - * i) 0 if there is nothing else to read. - * ii) Number of bytes written to user buffer. - * iii) LORAWAN_STATUS_WOULD_BLOCK if there is - * nothing available to read at the moment. - * iv) A negative error code on failure. + * @return It could be one of these: + * i) 0 if there is nothing else to read. + * ii) Number of bytes written to user buffer. + * iii) A negative error code on failure: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), + * LORAWAN_STATUS_NO_ACTIVE_SESSIONS if connection is not open, + * LORAWAN_STATUS_WOULD_BLOCK if there is nothing available to read at the moment, + * LORAWAN_STATUS_PARAMETER_INVALID if NULL data or length is given, + * LORAWAN_STATUS_WOULD_BLOCK if incorrect port or flags are given, */ virtual int16_t receive(uint8_t port, uint8_t *data, uint16_t length, int flags) = 0; - /** Receives a message from the Network Server from any port. + /** Receives a message from the Network Server on any port. * - * @param data A pointer to buffer where the received data will be - * stored. + * @param data A pointer to buffer where the received data will be stored. * - * @param length The size of data in bytes + * @param length The size of data in bytes * - * @param port Return the number of port to which message was received. + * @param port Return the number of port from which message was received. * - * @param flags Return flags to determine what type of message was received. - * MSG_UNCONFIRMED_FLAG = 0x01 - * MSG_CONFIRMED_FLAG = 0x02 - * MSG_MULTICAST_FLAG = 0x04 - * MSG_PROPRIETARY_FLAG = 0x08 + * @param flags Return flags to determine what type of message was received. + * MSG_UNCONFIRMED_FLAG = 0x01 + * MSG_CONFIRMED_FLAG = 0x02 + * MSG_MULTICAST_FLAG = 0x04 + * MSG_PROPRIETARY_FLAG = 0x08 * - * @return It could be one of these: - * i) 0 if there is nothing else to read. - * ii) Number of bytes written to user buffer. - * iii) LORAWAN_STATUS_WOULD_BLOCK if there is - * nothing available to read at the moment. - * iv) A negative error code on failure. + * @return It could be one of these: + * i) 0 if there is nothing else to read. + * ii) Number of bytes written to user buffer. + * iii) A negative error code on failure: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), + * LORAWAN_STATUS_NO_ACTIVE_SESSIONS if connection is not open, + * LORAWAN_STATUS_PARAMETER_INVALID if NULL data or length is given, + * LORAWAN_STATUS_WOULD_BLOCK if there is nothing available to read at the moment. */ virtual int16_t receive(uint8_t *data, uint16_t length, uint8_t &port, int &flags) = 0; @@ -299,15 +389,15 @@ class LoRaWANBase { * * int main() * { - * lorawan.initialize(); - * cbs.lorawan_events = mbed::callback(my_event_handler); - * lorawan.add_app_callbacks(&cbs); - * lorawan.connect(); + * lorawan.initialize(); + * cbs.lorawan_events = mbed::callback(my_event_handler); + * lorawan.add_app_callbacks(&cbs); + * lorawan.connect(); * } * * static void my_event_handler(lorawan_event_t event) * { - * switch(event) { + * switch(event) { * case CONNECTED: * //do something * break; @@ -319,14 +409,14 @@ class LoRaWANBase { * break; * default: * break; - * } + * } * } * - * @param callbacks A pointer to the structure containing application - * callbacks. + * @param callbacks A pointer to the structure containing application callbacks. * - * @return LORAWAN_STATUS_OK on success, a negative error - * code on failure. + * @return LORAWAN_STATUS_OK on success, a negative error code on failure: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), + * LORAWAN_STATUS_PARAMETER_INVALID if events callback is not set */ virtual lorawan_status_t add_app_callbacks(lorawan_app_callbacks_t *callbacks) = 0; @@ -336,61 +426,58 @@ class LoRaWANBase { * * @param device_class The device class * - * @return LORAWAN_STATUS_OK on success, - * LORAWAN_STATUS_UNSUPPORTED is requested class is not supported, - * or other negative error code if request failed. + * @return LORAWAN_STATUS_OK on success or other negative error code if request failed: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), + * LORAWAN_STATUS_UNSUPPORTED if requested class is not supported */ virtual lorawan_status_t set_device_class(device_class_t device_class) = 0; /** Get hold of TX meta-data * - * Use this method to acquire any TX meta-data related to previous - * transmission. + * Use this method to acquire any TX meta-data related to previous transmission. * TX meta-data is only available right after the transmission is completed. - * In other words, you can check for TX meta-data right after receiving the - * TX_DONE event. + * In other words, you can check for TX meta-data right after receiving the TX_DONE event. * - * @param metadata the inbound structure that will be filled if the meta-data - * is available. + * @param metadata the inbound structure that will be filled if the meta-data is available. * - * @return LORAWAN_STATUS_OK if the meta-data is available, otherwise - * LORAWAN_STATUS_METADATA_NOT_AVAILABLE is returned. + * @return LORAWAN_STATUS_OK if the meta-data is available, + * otherwise other negative error code if request failed: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), + * LORAWAN_STATUS_METADATA_NOT_AVAILABLE if the meta-data is not available */ virtual lorawan_status_t get_tx_metadata(lorawan_tx_metadata &metadata) = 0; /** Get hold of RX meta-data * - * Use this method to acquire any RX meta-data related to current - * reception. + * Use this method to acquire any RX meta-data related to current reception. * RX meta-data is only available right after the reception is completed. - * In other words, you can check for RX meta-data right after receiving the - * RX_DONE event. + * In other words, you can check for RX meta-data right after receiving the RX_DONE event. * - * @param metadata the inbound structure that will be filled if the meta-data - * is available. + * @param metadata the inbound structure that will be filled if the meta-data is available. * - * @return LORAWAN_STATUS_OK if the meta-data is available, otherwise - * LORAWAN_STATUS_METADATA_NOT_AVAILABLE is returned. + * @return LORAWAN_STATUS_OK if the meta-data is available, + * otherwise other negative error code if request failed: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), + * LORAWAN_STATUS_METADATA_NOT_AVAILABLE if the meta-data is not available */ virtual lorawan_status_t get_rx_metadata(lorawan_rx_metadata &metadata) = 0; /** Get hold of backoff time * - * In the TX path, because of automatic duty cycling, the transmission is delayed - * by a certain amount of time which is the backoff time. While the system schedules - * application data to be sent, the application can inquire about how much time is - * left in the actual transmission to happen. + * In the TX path, because of automatic duty cycling, the transmission is delayed by a certain + * amount of time, which is the backoff time. While the system schedules application data to be sent, + * the application can inquire about how much time is left in the actual transmission to happen. * - * The system will provide you with a backoff time only if the application data is - * in the TX pipe. If however, the event is already queued for the transmission, this - * API returns a LORAWAN_STATUS_METADATA_NOT_AVAILABLE error code. + * The system will provide you with a backoff time only if the application data is in the TX pipe. + * If however, the event is already queued for the transmission, this API returns a + * LORAWAN_STATUS_METADATA_NOT_AVAILABLE error code. * - * @param backoff the inbound integer that will be carry the backoff time if it - * is available. - * - * @return LORAWAN_STATUS_OK if the meta-data regarding backoff is available, - * otherwise LORAWAN_STATUS_METADATA_NOT_AVAILABLE is returned. + * @param backoff the inbound integer that will carry the backoff time if it is available. * + * @return LORAWAN_STATUS_OK if the meta-data is available, + * otherwise other negative error code if request failed: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), + * LORAWAN_STATUS_METADATA_NOT_AVAILABLE if the meta-data is not available */ virtual lorawan_status_t get_backoff_metadata(int &backoff) = 0; @@ -399,11 +486,13 @@ class LoRaWANBase { * This API is used to cancel any outstanding transmission in the TX pipe. * If an event for transmission is not already queued at the end of backoff timer, * the system can cancel the outstanding outgoing packet. Otherwise, the system is - * busy sending and can't be held back. - * - * @return LORAWAN_STATUS_OK if the sending is cancelled. - * LORAWAN_STATUS_BUSY otherwise. + * busy sending and can't be held back. The system will not try to resend if the + * outgoing message was a CONFIRMED message even if the ack is not received. * + * @return LORAWAN_STATUS_OK if the sending is canceled, otherwise + * other negative error code if request failed: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), + * LORAWAN_STATUS_BUSY if the send cannot be canceled */ virtual lorawan_status_t cancel_sending(void) = 0; }; diff --git a/features/lorawan/LoRaWANInterface.h b/features/lorawan/LoRaWANInterface.h index d79c905acdd9..d2880d033f10 100644 --- a/features/lorawan/LoRaWANInterface.h +++ b/features/lorawan/LoRaWANInterface.h @@ -50,470 +50,29 @@ class LoRaWANInterface: public LoRaWANBase { virtual ~LoRaWANInterface(); - /** Initialize the LoRa stack. - * - * You must call this first to be able to use the LoRa stack. - * - * @param ev_queue A pointer to EventQueue provided by the application. - * - * @return 0 on success, a negative error code on failure. - */ - virtual lorawan_status_t initialize(events::EventQueue *ev_queue); - - /** Connect OTAA or ABP using Mbed-OS config system - * - * Connect by Over The Air Activation or Activation By Personalization. - * You need to configure the connection properly via the Mbed OS configuration - * system. - * - * When connecting via OTAA, the return code for success (LORAWAN_STATUS_CONNECT_IN_PROGRESS) is negative. - * However, this is not a real error. It tells you that the connection is in progress and you will - * be notified of the completion via an event. By default, after the Join Accept message - * is received, base stations may provide the node with a CF-List that replaces - * all user-configured channels except the Join/Default channels. A CF-List can - * configure a maximum of five channels other than the default channels. - * - * To configure more channels, we recommend that you use the `set_channel_plan()` API after the connection. - * By default, the PHY layers configure only the mandatory Join channels. The retransmission back-off restrictions - * on these channels are severe and you may experience long delays or even failures in the confirmed traffic. - * If you add more channels, the aggregated duty cycle becomes much more relaxed as compared to the Join (default) channels only. - * - * **NOTES ON RECONNECTION:** - * Currently, the Mbed OS LoRaWAN implementation does not support non-volatile - * memory storage. Therefore, the state and frame counters cannot be restored after - * a power cycle. However, if you use the `disconnect()` API to shut down the LoRaWAN - * protocol, the state and frame counters are saved. Connecting again would try to - * restore the previous session. According to the LoRaWAN 1.0.2 specification, the frame counters are always reset - * to zero for OTAA and a new Join request lets the network server know - * that the counters need a reset. The same is said about the ABP but there - * is no way to convey this information to the network server. For a network - * server, an ABP device is always connected. That's why storing the frame counters - * is important, at least for ABP. That's why we try to restore frame counters from - * session information after a disconnection. - * - * @return For ABP: If everything goes well, LORAWAN_STATUS_OK is returned for first call followed by - * a 'CONNECTED' event. Otherwise a negative error code is returned. - * Any subsequent call will return LORAWAN_STATUS_ALREADY_CONNECTED and no event follows. - * - * For OTAA: When a JoinRequest is sent, LORAWAN_STATUS_CONNECT_IN_PROGRESS is returned for the first call. - * Any subsequent call will return either LORAWAN_STATUS_BUSY (if the previous request for connection - * is still underway) or LORAWAN_STATUS_ALREADY_CONNECTED (if a network was already joined successfully). - * A 'CONNECTED' event is sent to the application when the JoinAccept is received. - */ + // From LoRaWANBase: + virtual lorawan_status_t initialize(events::EventQueue *queue); virtual lorawan_status_t connect(); - - /** Connect OTAA or ABP with parameters - * - * All connection parameters are chosen by the user and provided in the - * data structure passed down. - * - * When connecting via OTAA, the return code for success (LORAWAN_STATUS_CONNECT_IN_PROGRESS) is negative. - * However, this is not a real error. It tells you that connection is in progress and you will - * be notified of completion via an event. By default, after Join Accept message - * is received, base stations may provide the node with a CF-List which replaces - * all user-configured channels except the Join/Default channels. A CF-List can - * configure a maximum of five channels other than the default channels. - * - * To configure more channels, we recommend that you use the `set_channel_plan()` API after the connection. - * By default, the PHY layers configure only the mandatory Join - * channels. The retransmission back-off restrictions on these channels - * are severe and you may experience long delays or even - * failures in the confirmed traffic. If you add more channels, the aggregated duty - * cycle becomes much more relaxed as compared to the Join (default) channels only. - * - * **NOTES ON RECONNECTION:** - * Currently, the Mbed OS LoRaWAN implementation does not support non-volatile - * memory storage. Therefore, the state and frame counters cannot be restored after - * a power cycle. However, if you use the `disconnect()` API to shut down the LoRaWAN - * protocol, the state and frame counters are saved. Connecting again would try to - * restore the previous session. According to the LoRaWAN 1.0.2 specification, the frame counters are always reset - * to zero for OTAA and a new Join request lets the network server know - * that the counters need a reset. The same is said about the ABP but there - * is no way to convey this information to the network server. For a network - * server, an ABP device is always connected. That's why storing the frame counters - * is important, at least for ABP. That's why we try to restore frame counters from - * session information after a disconnection. - * - * @param connect Options for an end device connection to the gateway. - * - * @return For ABP: If everything goes well, LORAWAN_STATUS_OK is returned for first call followed by - * a 'CONNECTED' event. Otherwise a negative error code is returned. - * Any subsequent call will return LORAWAN_STATUS_ALREADY_CONNECTED and no event follows. - * - * For OTAA: When a JoinRequest is sent, LORAWAN_STATUS_CONNECT_IN_PROGRESS is returned for the first call. - * Any subsequent call will return either LORAWAN_STATUS_BUSY (if the previous request for connection - * is still underway) or LORAWAN_STATUS_ALREADY_CONNECTED (if a network was already joined successfully). - * A 'CONNECTED' event is sent to the application when the JoinAccept is received. - */ virtual lorawan_status_t connect(const lorawan_connect_t &connect); - - /** Disconnect the current session. - * - * @return LORAWAN_STATUS_DEVICE_OFF on successfully shutdown. - */ virtual lorawan_status_t disconnect(); - - /** Validate the connectivity with the network. - * - * Application may use this API to submit a request to the stack for - * validation of its connectivity to a Network Server. Under the hood, this - * API schedules a Link Check Request command (LinkCheckReq) for the network - * server and once the response, i.e., LinkCheckAns MAC command is received - * from the Network Server, user provided method is called. - * - * One way to use this API may be the validation of connectivity after a long - * deep sleep. Mbed LoRaWANStack piggy-backs the MAC commands with data - * frame payload so the application needs to try sending something and the Network - * Server may respond during the RX slots. - * - * This API is usable only when the 'link_check_resp' callback is set by - * the application. See add_lora_app_callbacks API. If the above mentioned - * callback is not set, a LORAWAN_STATUS_PARAMETER_INVALID error is thrown. - * - * First parameter to callback function is the demodulation margin and - * the second parameter is the number of gateways that successfully received - * the last request. - * - * A 'Link Check Request' MAC command remains set for every subsequent - * transmission, until/unless application explicitly turns it off using - * remove_link_check_request() API. - * - * @return LORAWAN_STATUS_OK on successfully queuing a request, or - * a negative error code on failure. - * - */ virtual lorawan_status_t add_link_check_request(); - - /** Removes link check request sticky MAC command. - * - * Any already queued request may still get entertained. However, no new - * requests will be made. - */ virtual void remove_link_check_request(); - - /** Sets up a particular data rate - * - * `set_datarate()` first verifies whether the data rate given is valid or not. - * If it is valid, the system sets the given data rate to the channel. - * - * @param data_rate The intended data rate, for example DR_0 or DR_1. - * Please note, that the macro DR_* can mean different - * things in different regions. - * @return LORAWAN_STATUS_OK if everything goes well, otherwise - * a negative error code. - */ virtual lorawan_status_t set_datarate(uint8_t data_rate); - - /** Enables adaptive data rate (ADR). - * - * The underlying LoRaPHY and LoRaMac layers handle the data rate automatically - * for the user, based upon the radio conditions (network congestion). - * - * @return LORAWAN_STATUS_OK or negative error code otherwise. - */ virtual lorawan_status_t enable_adaptive_datarate(); - - /** Disables adaptive data rate. - * - * When adaptive data rate (ADR) is disabled, you can either set a certain - * data rate or the MAC layer selects a default value. - * - * @return LORAWAN_STATUS_OK or negative error code otherwise. - */ virtual lorawan_status_t disable_adaptive_datarate(); - - /** Sets up the retry counter for confirmed messages. - * - * Valid for confirmed messages only. - * - * The number of trials to transmit the frame, if the LoRaMAC layer did not - * receive an acknowledgment. The MAC performs a data rate adaptation as in - * the LoRaWAN Specification V1.0.2, chapter 18.4, table on page 64. - * - * Note, that if number of retries is set to 1 or 2, MAC will not decrease - * the datarate, if the LoRaMAC layer did not receive an acknowledgment. - * - * @param count The number of retries for confirmed messages. - * - * @return LORAWAN_STATUS_OK or a negative error code. - */ virtual lorawan_status_t set_confirmed_msg_retries(uint8_t count); - - /** Sets the channel plan. - * - * You can provide a list of channels with appropriate parameters filled - * in. However, this list is not absolute. The stack applies a CF-List whenever - * available, which means that the network can overwrite your channel - * frequency settings right after Join Accept is received. You may try - * to set up any channel or channels after that, and if the channel requested - * is already active, the request is silently ignored. A negative error - * code is returned if there is any problem with parameters. - * - * Please note that this API can also be used to add a single channel to the - * existing channel plan. - * - * There is no reverse mechanism in the 1.0.2 specification for a node to request - * a particular channel. Only the network server can initiate such a request. - * You need to ensure that the corresponding base station supports the channel or channels being added. - * - * If your list includes a default channel (a channel where Join Requests - * are received) you cannot fully configure the channel parameters. - * Either leave the channel settings to default or check your - * corresponding PHY layer implementation. For example, LoRaPHYE868. - * - * @param channel_plan The channel plan to set. - * - * @return LORAWAN_STATUS_OK on success, a negative error - * code on failure. - */ virtual lorawan_status_t set_channel_plan(const lorawan_channelplan_t &channel_plan); - - /** Gets the channel plans from the LoRa stack. - * - * Once you have selected a particular PHY layer, a set of channels - * is automatically activated. Right after connecting, you can use this API - * to see the current plan. Otherwise, this API returns the channel - * plan that you have set using `set_channel_plan()`. - * - * @param channel_plan The current channel plan information. - * - * @return LORAWAN_STATUS_OK on success, a negative error - * code on failure. - */ virtual lorawan_status_t get_channel_plan(lorawan_channelplan_t &channel_plan); - - /** Removes an active channel plan. - * - * You cannot remove default channels (the channels the base stations are listening to). - * When a plan is abolished, only the non-default channels are removed. - * - * @return LORAWAN_STATUS_OK on success, a negative error - * code on failure. - */ virtual lorawan_status_t remove_channel_plan(); - - /** Removes a single channel. - * - * You cannot remove default channels (the channels the base stations are listening to). - * - * @param index The channel index. - * - * @return LORAWAN_STATUS_OK on success, a negative error - * code on failure. - */ virtual lorawan_status_t remove_channel(uint8_t index); - - /** Send message to gateway - * - * @param port The application port number. Port numbers 0 and 224 - * are reserved, whereas port numbers from 1 to 223 - * (0x01 to 0xDF) are valid port numbers. - * Anything out of this range is illegal. - * - * @param data A pointer to the data being sent. The ownership of the - * buffer is not transferred. The data is copied to the - * internal buffers. - * - * @param length The size of data in bytes. - * - * @param flags A flag used to determine what type of - * message is being sent, for example: - * - * MSG_UNCONFIRMED_FLAG = 0x01 - * MSG_CONFIRMED_FLAG = 0x02 - * MSG_MULTICAST_FLAG = 0x04 - * MSG_PROPRIETARY_FLAG = 0x08 - * - * All flags are mutually exclusive, and MSG_MULTICAST_FLAG - * cannot be set. - * - * - * @return The number of bytes sent, or - * LORAWAN_STATUS_WOULD_BLOCK if another TX is - * ongoing, or a negative error code on failure. - */ - virtual int16_t send(uint8_t port, const uint8_t *data, uint16_t length, - int flags); - - /** Receives a message from the Network Server on a specific port. - * - * @param port The application port number. Port numbers 0 and 224 - * are reserved, whereas port numbers from 1 to 223 - * (0x01 to 0xDF) are valid port numbers. - * Anything out of this range is illegal. - * - * @param data A pointer to buffer where the received data will be - * stored. - * - * @param length The size of data in bytes - * - * @param flags A flag is used to determine what type of - * message is being sent, for example: - * - * MSG_UNCONFIRMED_FLAG = 0x01, - * MSG_CONFIRMED_FLAG = 0x02 - * MSG_MULTICAST_FLAG = 0x04, - * MSG_PROPRIETARY_FLAG = 0x08 - * - * All flags can be used in conjunction with - * one another depending on the intended use case or reception - * expectation. - * - * e.g., MSG_CONFIRMED_FLAG and MSG_UNCONFIRMED_FLAG are - * not mutually exclusive, i.e., the user can subscribe to - * receive both CONFIRMED AND UNCONFIRMED messages at - * the same time. - * - * @return It could be one of these: - * i) 0 if there is nothing else to read. - * ii) Number of bytes written to user buffer. - * iii) LORAWAN_STATUS_WOULD_BLOCK if there is - * nothing available to read at the moment. - * iv) A negative error code on failure. - */ + virtual int16_t send(uint8_t port, const uint8_t *data, uint16_t length, int flags); virtual int16_t receive(uint8_t port, uint8_t *data, uint16_t length, int flags); - - /** Receives a message from the Network Server on any port. - * - * @param data A pointer to buffer where the received data will be - * stored. - * - * @param length The size of data in bytes - * - * @param port Return the number of port to which message was received. - * - * @param flags Return flags to determine what type of message was received. - * MSG_UNCONFIRMED_FLAG = 0x01 - * MSG_CONFIRMED_FLAG = 0x02 - * MSG_MULTICAST_FLAG = 0x04 - * MSG_PROPRIETARY_FLAG = 0x08 - * - * @return It could be one of these: - * i) 0 if there is nothing else to read. - * ii) Number of bytes written to user buffer. - * iii) LORAWAN_STATUS_WOULD_BLOCK if there is - * nothing available to read at the moment. - * iv) A negative error code on failure. - */ virtual int16_t receive(uint8_t *data, uint16_t length, uint8_t &port, int &flags); - - /** Add application callbacks to the stack. - * - * An example of using this API with a latch onto 'lorawan_events' could be: - * - * LoRaWANInterface lorawan(radio); - * lorawan_app_callbacks_t cbs; - * static void my_event_handler(); - * - * int main() - * { - * lorawan.initialize(); - * cbs.lorawan_events = mbed::callback(my_event_handler); - * lorawan.add_app_callbacks(&cbs); - * lorawan.connect(); - * } - * - * static void my_event_handler(lorawan_event_t event) - * { - * switch(event) { - * case CONNECTED: - * //do something - * break; - * case DISCONNECTED: - * //do something - * break; - * case TX_DONE: - * //do something - * break; - * default: - * break; - * } - * } - * - * @param callbacks A pointer to the structure containing application - * callbacks. - * - * @return LORAWAN_STATUS_OK on success, a negative error - * code on failure. - */ virtual lorawan_status_t add_app_callbacks(lorawan_app_callbacks_t *callbacks); - - /** Change device class - * - * Change current device class. - * - * @param device_class The device class - * - * @return LORAWAN_STATUS_OK on success, - * LORAWAN_STATUS_UNSUPPORTED is requested class is not supported, - * or other negative error code if request failed. - */ virtual lorawan_status_t set_device_class(const device_class_t device_class); - - /** Get hold of TX meta-data - * - * Use this method to acquire any TX meta-data related to previous - * transmission. - * TX meta-data is only available right after the transmission is completed. - * In other words, you can check for TX meta-data right after receiving the - * TX_DONE event. - * - * @param metadata the inbound structure that will be filled if the meta-data - * is available. - * - * @return LORAWAN_STATUS_OK if the meta-data is available, otherwise - * LORAWAN_STATUS_METADATA_NOT_AVAILABLE is returned. - */ virtual lorawan_status_t get_tx_metadata(lorawan_tx_metadata &metadata); - - /** Get hold of RX meta-data - * - * Use this method to acquire any RX meta-data related to current - * reception. - * RX meta-data is only available right after the reception is completed. - * In other words, you can check for RX meta-data right after receiving the - * RX_DONE event. - * - * @param metadata the inbound structure that will be filled if the meta-data - * is available. - * - * @return LORAWAN_STATUS_OK if the meta-data is available, otherwise - * LORAWAN_STATUS_METADATA_NOT_AVAILABLE is returned. - */ virtual lorawan_status_t get_rx_metadata(lorawan_rx_metadata &metadata); - - /** Get hold of backoff time - * - * In the TX path, because of automatic duty cycling, the transmission is delayed - * by a certain amount of time which is the backoff time. While the system schedules - * application data to be sent, the application can inquire about how much time is - * left in the actual transmission to happen. - * - * The system will provide you with a backoff time only if the application data is - * in the TX pipe. If however, the event is already queued for the transmission, this - * API returns a LORAWAN_STATUS_METADATA_NOT_AVAILABLE error code. - * - * @param backoff the inbound integer that will be carry the backoff time if it - * is available. - * - * @return LORAWAN_STATUS_OK if the meta-data regarding backoff is available, - * otherwise LORAWAN_STATUS_METADATA_NOT_AVAILABLE is returned. - * - */ virtual lorawan_status_t get_backoff_metadata(int &backoff); - - /** Cancel outgoing transmission - * - * This API is used to cancel any outstanding transmission in the TX pipe. - * If an event for transmission is not already queued at the end of backoff timer, - * the system can cancel the outstanding outgoing packet. Otherwise, the system is - * busy sending and can't be held back. The system will not try to re-send if the - * outgoing message was a CONFIRMED message even if the ack is not received. - * - * @return LORAWAN_STATUS_OK if the sending is cancelled. - * LORAWAN_STATUS_BUSY otherwise. - * - */ virtual lorawan_status_t cancel_sending(void); void lock(void) diff --git a/features/lorawan/LoRaWANStack.cpp b/features/lorawan/LoRaWANStack.cpp index ece5aed9f87e..65a76968517b 100644 --- a/features/lorawan/LoRaWANStack.cpp +++ b/features/lorawan/LoRaWANStack.cpp @@ -277,14 +277,16 @@ lorawan_status_t LoRaWANStack::enable_adaptive_datarate(bool adr_enabled) lorawan_status_t LoRaWANStack::stop_sending(void) { + if (_device_current_state == DEVICE_STATE_NOT_INITIALIZED) { + return LORAWAN_STATUS_NOT_INITIALIZED; + } + if (_loramac.clear_tx_pipe() == LORAWAN_STATUS_OK) { - if (_device_current_state == DEVICE_STATE_SENDING) { - _ctrl_flags &= ~TX_DONE_FLAG; - _ctrl_flags &= ~TX_ONGOING_FLAG; - _loramac.set_tx_ongoing(false); - _device_current_state = DEVICE_STATE_IDLE; - return LORAWAN_STATUS_OK; - } + _ctrl_flags &= ~TX_DONE_FLAG; + _ctrl_flags &= ~TX_ONGOING_FLAG; + _loramac.set_tx_ongoing(false); + _device_current_state = DEVICE_STATE_IDLE; + return LORAWAN_STATUS_OK; } return LORAWAN_STATUS_BUSY; @@ -294,6 +296,10 @@ int16_t LoRaWANStack::handle_tx(const uint8_t port, const uint8_t *data, uint16_t length, uint8_t flags, bool null_allowed, bool allow_port_0) { + if (_device_current_state == DEVICE_STATE_NOT_INITIALIZED) { + return LORAWAN_STATUS_NOT_INITIALIZED; + } + if (!null_allowed && !data) { return LORAWAN_STATUS_PARAMETER_INVALID; } @@ -330,7 +336,7 @@ int16_t LoRaWANStack::handle_tx(const uint8_t port, const uint8_t *data, return status; } - // All the flags mutually exclusive. In addition to that MSG_MULTICAST_FLAG cannot be + // All the flags are mutually exclusive. In addition to that MSG_MULTICAST_FLAG cannot be // used for uplink. switch (flags & MSG_FLAG_MASK) { case MSG_UNCONFIRMED_FLAG: @@ -354,6 +360,10 @@ int16_t LoRaWANStack::handle_tx(const uint8_t port, const uint8_t *data, int16_t LoRaWANStack::handle_rx(uint8_t *data, uint16_t length, uint8_t &port, int &flags, bool validate_params) { + if (_device_current_state == DEVICE_STATE_NOT_INITIALIZED) { + return LORAWAN_STATUS_NOT_INITIALIZED; + } + if (!_lw_session.active) { return LORAWAN_STATUS_NO_ACTIVE_SESSIONS; } @@ -603,17 +613,14 @@ void LoRaWANStack::process_transmission(void) _ctrl_flags &= ~TX_DONE_FLAG; tr_debug("Awaiting ACK"); _device_current_state = DEVICE_STATE_AWAITING_ACK; - return; - } - - // Class A unconfirmed message sent, TX_DONE event will be sent to - // application when RX2 windows is elapsed, i.e., in process_reception_timeout() - _ctrl_flags &= ~TX_ONGOING_FLAG; - _ctrl_flags |= TX_DONE_FLAG; - - // In Class C, reception timeout never happens, so we handle the state - // progression for TX_DONE in UNCONFIRMED case here - if (_loramac.get_device_class() == CLASS_C) { + } else if (_loramac.get_device_class() == CLASS_A) { + // Class A unconfirmed message sent, TX_DONE event will be sent to + // application when RX2 windows is elapsed, i.e., in process_reception_timeout() + _ctrl_flags &= ~TX_ONGOING_FLAG; + _ctrl_flags |= TX_DONE_FLAG; + } else if (_loramac.get_device_class() == CLASS_C) { + // In Class C, reception timeout never happens, so we handle the state + // progression for TX_DONE in UNCONFIRMED case here _loramac.post_process_mcps_req(); state_controller(DEVICE_STATE_STATUS_CHECK); state_machine_run_to_completion(); @@ -629,6 +636,13 @@ void LoRaWANStack::handle_ack_expiry_for_class_c(void) state_controller(DEVICE_STATE_STATUS_CHECK); } +void LoRaWANStack::handle_scheduling_failure(void) +{ + tr_error("Failed to schedule transmission"); + state_controller(DEVICE_STATE_STATUS_CHECK); + state_machine_run_to_completion(); +} + void LoRaWANStack::process_reception(const uint8_t *const payload, uint16_t size, int16_t rssi, int8_t snr) { @@ -645,6 +659,7 @@ void LoRaWANStack::process_reception(const uint8_t *const payload, uint16_t size } if (!_loramac.nwk_joined()) { + _ready_for_rx = true; return; } @@ -662,16 +677,18 @@ void LoRaWANStack::process_reception(const uint8_t *const payload, uint16_t size _ctrl_flags &= ~TX_ONGOING_FLAG; state_controller(DEVICE_STATE_STATUS_CHECK); } else { - if (!_loramac.continue_sending_process()) { + if (!_loramac.continue_sending_process() && + _loramac.get_current_slot() != RX_SLOT_WIN_1) { tr_error("Retries exhausted for Class A device"); _ctrl_flags &= ~TX_DONE_FLAG; _ctrl_flags |= TX_ONGOING_FLAG; state_controller(DEVICE_STATE_STATUS_CHECK); } } - } else { + } else if (_loramac.get_device_class() == CLASS_A) { // handle UNCONFIRMED case here, RX slots were turned off due to - // valid packet reception + // valid packet reception. For Class C, an outgoing UNCONFIRMED message + // gets its handling in process_transmission. _loramac.post_process_mcps_req(); _ctrl_flags |= TX_DONE_FLAG; state_controller(DEVICE_STATE_STATUS_CHECK); @@ -805,8 +822,12 @@ void LoRaWANStack::send_event_to_application(const lorawan_event_t event) const void LoRaWANStack::send_automatic_uplink_message(const uint8_t port) { + // we will silently ignore the automatic uplink event if the user is already + // sending something const int16_t ret = handle_tx(port, NULL, 0, MSG_CONFIRMED_FLAG, true, true); - if (ret < 0) { + if (ret == LORAWAN_STATUS_WOULD_BLOCK) { + _automatic_uplink_ongoing = false; + } else if (ret < 0) { tr_debug("Failed to generate AUTOMATIC UPLINK, error code = %d", ret); send_event_to_application(AUTOMATIC_UPLINK_ERROR); } @@ -946,22 +967,26 @@ void LoRaWANStack::mlme_confirm_handler() void LoRaWANStack::mcps_confirm_handler() { - // success case - if (_loramac.get_mcps_confirmation()->status == LORAMAC_EVENT_INFO_STATUS_OK) { - _lw_session.uplink_counter = _loramac.get_mcps_confirmation()->ul_frame_counter; - send_event_to_application(TX_DONE); - return; - } + switch (_loramac.get_mcps_confirmation()->status) { - // failure case - if (_loramac.get_mcps_confirmation()->status == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT) { - tr_error("Fatal Error, Radio failed to transmit"); - send_event_to_application(TX_TIMEOUT); - return; - } + case LORAMAC_EVENT_INFO_STATUS_OK: + _lw_session.uplink_counter = _loramac.get_mcps_confirmation()->ul_frame_counter; + send_event_to_application(TX_DONE); + break; + + case LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT: + tr_error("Fatal Error, Radio failed to transmit"); + send_event_to_application(TX_TIMEOUT); + break; + + case LORAMAC_EVENT_INFO_STATUS_TX_DR_PAYLOAD_SIZE_ERROR: + send_event_to_application(TX_SCHEDULING_ERROR); + break; - // if no ack was received, send TX_ERROR - send_event_to_application(TX_ERROR); + default: + // if no ack was received after enough retries, send TX_ERROR + send_event_to_application(TX_ERROR); + } } void LoRaWANStack::mcps_indication_handler() @@ -1080,6 +1105,7 @@ void LoRaWANStack::process_shutdown_state(lorawan_status_t &op_status) _device_current_state = DEVICE_STATE_SHUTDOWN; op_status = LORAWAN_STATUS_DEVICE_OFF; _ctrl_flags &= ~CONNECTED_FLAG; + _ctrl_flags &= ~CONN_IN_PROGRESS_FLAG; send_event_to_application(DISCONNECTED); } @@ -1087,11 +1113,13 @@ void LoRaWANStack::process_status_check_state() { if (_device_current_state == DEVICE_STATE_SENDING || _device_current_state == DEVICE_STATE_AWAITING_ACK) { - // this happens after RX2 slot is exhausted - // we may or may not have a successful UNCONFIRMED transmission + // If there was a successful transmission, this block gets a kick after + // RX2 slot is exhausted. We may or may not have a successful UNCONFIRMED transmission // here. In CONFIRMED case this block is invoked only // when the MAX number of retries are exhausted, i.e., only error // case will fall here. Moreover, it will happen for Class A only. + // Another possibility is the case when the stack fails to schedule a + // deferred transmission and a scheduling failure handler is invoked. _ctrl_flags &= ~TX_DONE_FLAG; _ctrl_flags &= ~TX_ONGOING_FLAG; _loramac.set_tx_ongoing(false); @@ -1154,12 +1182,14 @@ void LoRaWANStack::process_joining_state(lorawan_status_t &op_status) return; } - if (_device_current_state == DEVICE_STATE_AWAITING_JOIN_ACCEPT) { + if (_device_current_state == DEVICE_STATE_AWAITING_JOIN_ACCEPT && + _loramac.get_current_slot() != RX_SLOT_WIN_1) { _device_current_state = DEVICE_STATE_JOINING; // retry join bool can_continue = _loramac.continue_joining_process(); if (!can_continue) { + _ctrl_flags &= ~CONN_IN_PROGRESS_FLAG; send_event_to_application(JOIN_FAILURE); _device_current_state = DEVICE_STATE_IDLE; return; @@ -1213,7 +1243,8 @@ void LoRaWANStack::process_idle_state(lorawan_status_t &op_status) void LoRaWANStack::process_uninitialized_state(lorawan_status_t &op_status) { - op_status = _loramac.initialize(_queue); + op_status = _loramac.initialize(_queue, mbed::callback(this, + &LoRaWANStack::handle_scheduling_failure)); if (op_status == LORAWAN_STATUS_OK) { _device_current_state = DEVICE_STATE_IDLE; diff --git a/features/lorawan/LoRaWANStack.h b/features/lorawan/LoRaWANStack.h index 6c57b4296711..4f052d9d1cde 100644 --- a/features/lorawan/LoRaWANStack.h +++ b/features/lorawan/LoRaWANStack.h @@ -484,6 +484,7 @@ class LoRaWANStack: private mbed::NonCopyable { void make_rx_metadata_available(void); void handle_ack_expiry_for_class_c(void); + void handle_scheduling_failure(void); private: LoRaMac _loramac; diff --git a/features/lorawan/lorastack/mac/LoRaMac.cpp b/features/lorawan/lorastack/mac/LoRaMac.cpp index 6d7ed946bd78..9aceccd52951 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.cpp +++ b/features/lorawan/lorastack/mac/LoRaMac.cpp @@ -65,12 +65,6 @@ using namespace mbed; */ #define DOWN_LINK 1 -/** - * A mask for the network ID. - */ -#define LORAWAN_NETWORK_ID_MASK ( uint32_t )0xFE000000 - - LoRaMac::LoRaMac() : _lora_time(), _lora_phy(NULL), @@ -170,6 +164,8 @@ void LoRaMac::post_process_mcps_req() if (_params.is_ul_frame_counter_fixed == false) { _params.ul_frame_counter++; } + } else { + _mcps_confirmation.status = LORAMAC_EVENT_INFO_STATUS_ERROR; } } else { //UNCONFIRMED or PROPRIETARY @@ -671,7 +667,7 @@ void LoRaMac::on_radio_rx_done(const uint8_t *const payload, uint16_t size, { if (_device_class == CLASS_C && !_continuous_rx2_window_open) { open_rx2_window(); - } else { + } else if (_device_class != CLASS_C){ _lora_time.stop(_params.timers.rx_window1_timer); _lora_phy->put_radio_to_sleep(); } @@ -784,6 +780,7 @@ bool LoRaMac::continue_sending_process() if (_params.ack_timeout_retry_counter > _params.max_ack_timeout_retries) { _mac_commands.clear_command_buffer(); _params.adr_ack_counter++; + _lora_time.stop(_params.timers.ack_timeout_timer); return false; } @@ -845,9 +842,12 @@ lorawan_status_t LoRaMac::handle_retransmission() void LoRaMac::on_backoff_timer_expiry(void) { Lock lock(*this); - lorawan_status_t status = schedule_tx(); - MBED_ASSERT(status == LORAWAN_STATUS_OK); - (void) status; + + _lora_time.stop(_params.timers.backoff_timer); + + if ((schedule_tx() != LORAWAN_STATUS_OK) && nwk_joined()) { + _scheduling_failure_handler.call(); + } } void LoRaMac::open_rx1_window(void) @@ -932,8 +932,12 @@ void LoRaMac::on_ack_timeout_timer_event(void) _mcps_confirmation.nb_retries = _params.ack_timeout_retry_counter; + // Schedule a retry - if (handle_retransmission() != LORAWAN_STATUS_OK) { + lorawan_status_t status = handle_retransmission(); + + if (status == LORAWAN_STATUS_NO_CHANNEL_FOUND || + status == LORAWAN_STATUS_NO_FREE_CHANNEL_FOUND) { // In a case when enabled channels are not found, PHY layer // resorts to default channels. Next attempt should go forward as the // default channels are always available if there is a base station in the @@ -944,10 +948,24 @@ void LoRaMac::on_ack_timeout_timer_event(void) _mcps_confirmation.ack_received = false; _mcps_confirmation.nb_retries = _params.ack_timeout_retry_counter; - // now that is a critical failure - lorawan_status_t status = handle_retransmission(); + // For the next attempt we need to make sure that we do not incur length error + // which would mean that the datarate changed during retransmissions and + // the original packet doesn't fit into allowed payload buffer anymore. + status = handle_retransmission(); + + if (status == LORAWAN_STATUS_LENGTH_ERROR) { + _scheduling_failure_handler.call(); + return; + } + + // if we did not incur a length error and still the status is not OK, + // it is a critical failure + status = handle_retransmission(); MBED_ASSERT(status == LORAWAN_STATUS_OK); (void) status; + } else if (status != LORAWAN_STATUS_OK) { + _scheduling_failure_handler.call(); + return; } _params.ack_timeout_retry_counter++; @@ -1018,7 +1036,13 @@ int LoRaMac::get_backoff_timer_event_id(void) lorawan_status_t LoRaMac::clear_tx_pipe(void) { // check if the event is not already queued - if (_ev_queue->time_left(get_backoff_timer_event_id()) > 0) { + const int id = get_backoff_timer_event_id(); + if (id == 0) { + // No queued send request + return LORAWAN_STATUS_OK; + } + + if (_ev_queue->time_left(id) > 0) { _lora_time.stop(_params.timers.backoff_timer); _lora_time.stop(_params.timers.ack_timeout_timer); memset(_params.tx_buffer, 0, sizeof _params.tx_buffer); @@ -1026,9 +1050,10 @@ lorawan_status_t LoRaMac::clear_tx_pipe(void) reset_ongoing_tx(true); tr_debug("Sending Cancelled"); return LORAWAN_STATUS_OK; + } else { + // Event is already being dispatched so it cannot be cancelled + return LORAWAN_STATUS_BUSY; } - - return LORAWAN_STATUS_BUSY; } lorawan_status_t LoRaMac::schedule_tx() @@ -1045,11 +1070,16 @@ lorawan_status_t LoRaMac::schedule_tx() _params.timers.aggregated_timeoff = 0; } + if (MBED_CONF_LORA_DUTY_CYCLE_ON && _lora_phy->verify_duty_cycle(true)) { + _params.is_dutycycle_on = true; + } else { + _params.is_dutycycle_on = false; + } + calculate_backOff(_params.last_channel_idx); next_channel.aggregate_timeoff = _params.timers.aggregated_timeoff; next_channel.current_datarate = _params.sys_params.channel_data_rate; - _params.is_dutycycle_on = MBED_CONF_LORA_DUTY_CYCLE_ON; next_channel.dc_enabled = _params.is_dutycycle_on; next_channel.joined = _is_nwk_joined; next_channel.last_aggregate_tx_time = _params.timers.aggregated_last_tx_time; @@ -1062,6 +1092,7 @@ lorawan_status_t LoRaMac::schedule_tx() switch (status) { case LORAWAN_STATUS_NO_CHANNEL_FOUND: case LORAWAN_STATUS_NO_FREE_CHANNEL_FOUND: + _mcps_confirmation.status = LORAMAC_EVENT_INFO_STATUS_ERROR; return status; case LORAWAN_STATUS_DUTYCYCLE_RESTRICTED: if (backoff_time != 0) { @@ -1078,13 +1109,13 @@ lorawan_status_t LoRaMac::schedule_tx() uint8_t dr_offset = _lora_phy->apply_DR_offset(_params.sys_params.channel_data_rate, _params.sys_params.rx1_dr_offset); - _lora_phy->compute_rx_win_params(dr_offset, _params.sys_params.min_rx_symb, - _params.sys_params.max_sys_rx_error, + _lora_phy->compute_rx_win_params(dr_offset, MBED_CONF_LORA_DOWNLINK_PREAMBLE_LENGTH, + MBED_CONF_LORA_MAX_SYS_RX_ERROR, &_params.rx_window1_config); _lora_phy->compute_rx_win_params(_params.sys_params.rx2_channel.datarate, - _params.sys_params.min_rx_symb, - _params.sys_params.max_sys_rx_error, + MBED_CONF_LORA_DOWNLINK_PREAMBLE_LENGTH, + MBED_CONF_LORA_MAX_SYS_RX_ERROR, &_params.rx_window2_config); if (!_is_nwk_joined) { @@ -1132,9 +1163,6 @@ lorawan_status_t LoRaMac::schedule_tx() void LoRaMac::calculate_backOff(uint8_t channel) { lorawan_time_t elapsed_time = _lora_time.get_elapsed_time(_params.timers.mac_init_time); - - _params.is_dutycycle_on = MBED_CONF_LORA_DUTY_CYCLE_ON; - _lora_phy->calculate_backoff(_is_nwk_joined, _params.is_last_tx_join_request, _params.is_dutycycle_on, channel, elapsed_time, _params.timers.tx_toa); @@ -1353,8 +1381,8 @@ void LoRaMac::set_device_class(const device_class_t &device_class, _params.is_node_ack_requested = false; _lora_phy->put_radio_to_sleep(); _lora_phy->compute_rx_win_params(_params.sys_params.rx2_channel.datarate, - _params.sys_params.min_rx_symb, - _params.sys_params.max_sys_rx_error, + MBED_CONF_LORA_DOWNLINK_PREAMBLE_LENGTH, + MBED_CONF_LORA_MAX_SYS_RX_ERROR, &_params.rx_window2_config); } @@ -1394,6 +1422,11 @@ lorawan_status_t LoRaMac::prepare_join(const lorawan_connect_t *params, bool is_ } // Reset variable JoinRequestTrials _params.join_request_trial_counter = 0; + + reset_mac_parameters(); + + _params.sys_params.channel_data_rate = + _lora_phy->get_alternate_DR(_params.join_request_trial_counter + 1); } else { if ((params->connection_u.abp.dev_addr == 0) || (params->connection_u.abp.nwk_id == 0) @@ -1434,7 +1467,7 @@ lorawan_status_t LoRaMac::prepare_join(const lorawan_connect_t *params, bool is_ const static uint8_t nwk_skey[] = MBED_CONF_LORA_NWKSKEY; const static uint8_t app_skey[] = MBED_CONF_LORA_APPSKEY; - _params.net_id = (MBED_CONF_LORA_DEVICE_ADDRESS & LORAWAN_NETWORK_ID_MASK); + _params.net_id = (MBED_CONF_LORA_DEVICE_ADDRESS & LORAWAN_NETWORK_ID_MASK) >> 25; _params.dev_addr = MBED_CONF_LORA_DEVICE_ADDRESS; memcpy(_params.keys.nwk_skey, nwk_skey, sizeof(_params.keys.nwk_skey)); @@ -1711,12 +1744,14 @@ void LoRaMac::set_tx_continuous_wave(uint8_t channel, int8_t datarate, int8_t tx _lora_phy->set_tx_cont_mode(&continuous_wave); } -lorawan_status_t LoRaMac::initialize(EventQueue *queue) +lorawan_status_t LoRaMac::initialize(EventQueue *queue, + mbed::Callbackscheduling_failure_handler) { _lora_time.activate_timer_subsystem(queue); _lora_phy->initialize(&_lora_time); _ev_queue = queue; + _scheduling_failure_handler = scheduling_failure_handler; _channel_plan.activate_channelplan_subsystem(_lora_phy); @@ -1730,9 +1765,6 @@ lorawan_status_t LoRaMac::initialize(EventQueue *queue) _params.timers.aggregated_timeoff = 0; _lora_phy->reset_to_default_values(&_params, true); - - _params.sys_params.max_sys_rx_error = 10; - _params.sys_params.min_rx_symb = 6; _params.sys_params.retry_num = 1; reset_mac_parameters(); @@ -1755,9 +1787,7 @@ lorawan_status_t LoRaMac::initialize(EventQueue *queue) _params.timers.mac_init_time = _lora_time.get_current_time(); _params.sys_params.adr_on = MBED_CONF_LORA_ADR_ON; - - _params.is_nwk_public = MBED_CONF_LORA_PUBLIC_NETWORK; - _lora_phy->setup_public_network_mode(MBED_CONF_LORA_PUBLIC_NETWORK); + _params.sys_params.channel_data_rate = _lora_phy->get_default_max_tx_datarate(); return LORAWAN_STATUS_OK; } diff --git a/features/lorawan/lorastack/mac/LoRaMac.h b/features/lorawan/lorastack/mac/LoRaMac.h index 81d560624ff1..9f1837e28396 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.h +++ b/features/lorawan/lorastack/mac/LoRaMac.h @@ -78,11 +78,15 @@ class LoRaMac { * * @param queue [in] A pointer to the application provided EventQueue. * + * @param scheduling_failure_handler A callback to inform upper layer if a deferred + * transmission (after backoff or retry) fails to schedule. + * * @return `lorawan_status_t` The status of the operation. The possible values are: * \ref LORAWAN_STATUS_OK * \ref LORAWAN_STATUS_PARAMETER_INVALID */ - lorawan_status_t initialize(events::EventQueue *queue); + lorawan_status_t initialize(events::EventQueue *queue, + mbed::Callbackscheduling_failure_handler); /** * @brief Disconnect LoRaMac layer @@ -471,11 +475,13 @@ class LoRaMac { { osStatus status = _mutex.lock(); MBED_ASSERT(status == osOK); + (void) status; } void unlock(void) { osStatus status = _mutex.unlock(); MBED_ASSERT(status == osOK); + (void) status; } #else void lock(void) { } @@ -666,6 +672,14 @@ class LoRaMac { */ mbed::Callback _ack_expiry_handler_for_class_c; + /** + * Transmission is async, i.e., a call to schedule_tx() may be deferred to + * a time after a certain back off. We use this callback to inform the + * controller layer that a specific TX transaction failed to schedule after + * backoff or retry. + */ + mbed::Callback _scheduling_failure_handler; + /** * Structure to hold MCPS indication data. */ diff --git a/features/lorawan/lorastack/phy/LoRaPHY.cpp b/features/lorawan/lorastack/phy/LoRaPHY.cpp index f889a0916101..b6131db844e4 100644 --- a/features/lorawan/lorastack/phy/LoRaPHY.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHY.cpp @@ -270,8 +270,7 @@ lorawan_time_t LoRaPHY::update_band_timeoff(bool joined, bool duty_cycle, // Update bands Time OFF for (uint8_t i = 0; i < nb_bands; i++) { - - if (joined == false) { + if (MBED_CONF_LORA_DUTY_CYCLE_ON_JOIN && joined == false) { uint32_t txDoneTime = MAX(_lora_time->get_elapsed_time(bands[i].last_join_tx_time), (duty_cycle == true) ? _lora_time->get_elapsed_time(bands[i].last_tx_time) : 0); @@ -283,7 +282,6 @@ lorawan_time_t LoRaPHY::update_band_timeoff(bool joined, bool duty_cycle, if (bands[i].off_time != 0) { next_tx_delay = MIN(bands[i].off_time - txDoneTime, next_tx_delay); } - } else { // if network has been joined if (duty_cycle == true) { @@ -451,7 +449,7 @@ uint8_t LoRaPHY::get_bandwidth(uint8_t dr) } } -uint8_t LoRaPHY::enabled_channel_count(bool joined, uint8_t datarate, +uint8_t LoRaPHY::enabled_channel_count(uint8_t datarate, const uint16_t *channel_mask, uint8_t *channel_indices, uint8_t *delayTx) @@ -514,7 +512,9 @@ void LoRaPHY::reset_to_default_values(loramac_protocol_params *params, bool init params->sys_params.channel_tx_power = get_default_tx_power(); - params->sys_params.channel_data_rate = get_default_tx_datarate(); + // We shall always start with highest achievable data rate. + // Subsequent decrease in data rate will mean increase in range henceforth. + params->sys_params.channel_data_rate = get_default_max_tx_datarate(); params->sys_params.rx1_dr_offset = phy_params.default_rx1_dr_offset; @@ -560,6 +560,11 @@ uint8_t LoRaPHY::get_default_tx_datarate() return phy_params.default_datarate; } +uint8_t LoRaPHY::get_default_max_tx_datarate() +{ + return phy_params.default_max_datarate; +} + uint8_t LoRaPHY::get_default_tx_power() { return phy_params.default_tx_power; @@ -845,7 +850,8 @@ bool LoRaPHY::rx_config(rx_config_params_t *rx_conf) false, rx_conf->is_rx_continuous); } else { modem = MODEM_LORA; - _radio->set_rx_config(modem, rx_conf->bandwidth, phy_dr, 1, 0, 8, + _radio->set_rx_config(modem, rx_conf->bandwidth, phy_dr, 1, 0, + MBED_CONF_LORA_DOWNLINK_PREAMBLE_LENGTH, rx_conf->window_timeout, false, 0, false, 0, 0, true, rx_conf->is_rx_continuous); } @@ -895,7 +901,8 @@ bool LoRaPHY::tx_config(tx_config_params_t *tx_conf, int8_t *tx_power, 3000); } else { modem = MODEM_LORA; - _radio->set_tx_config(modem, phy_tx_power, 0, bandwidth, phy_dr, 1, 8, + _radio->set_tx_config(modem, phy_tx_power, 0, bandwidth, phy_dr, 1, + MBED_CONF_LORA_UPLINK_PREAMBLE_LENGTH, false, true, 0, 0, false, 3000); } @@ -1173,7 +1180,7 @@ void LoRaPHY::calculate_backoff(bool joined, bool last_tx_was_join_req, bool dc_ // Reset time-off to initial value. band_table[band_idx].off_time = 0; - if (joined == false) { + if (MBED_CONF_LORA_DUTY_CYCLE_ON_JOIN && joined == false) { // Get the join duty cycle if (elapsed_time < 3600000) { join_duty_cycle = BACKOFF_DC_1_HOUR; @@ -1236,7 +1243,7 @@ lorawan_status_t LoRaPHY::set_next_channel(channel_selection_params_t *params, band_table, phy_params.bands.size); // Search how many channels are enabled - channel_count = enabled_channel_count(params->joined, params->current_datarate, + channel_count = enabled_channel_count(params->current_datarate, phy_params.channels.mask, enabled_channels, &delay_tx); } else { diff --git a/features/lorawan/lorastack/phy/LoRaPHY.h b/features/lorawan/lorastack/phy/LoRaPHY.h index 2302064b8ca4..21885298e10d 100644 --- a/features/lorawan/lorastack/phy/LoRaPHY.h +++ b/features/lorawan/lorastack/phy/LoRaPHY.h @@ -423,6 +423,14 @@ class LoRaPHY : private mbed::NonCopyable { */ uint8_t get_default_tx_datarate(); + /** + * @brief get_default_max_tx_datarate Gets the maximum achievable data rate for + * LoRa modulation. This will always be the highest data rate achievable with + * LoRa as defined in the regional specifications. + * @return Maximum achievable data rate with LoRa modulation. + */ + uint8_t get_default_max_tx_datarate(); + /** * @brief get_default_tx_power Gets the default TX power * @return Default TX power @@ -624,7 +632,7 @@ class LoRaPHY : private mbed::NonCopyable { */ uint8_t get_bandwidth(uint8_t dr_index); - uint8_t enabled_channel_count(bool joined, uint8_t datarate, + uint8_t enabled_channel_count(uint8_t datarate, const uint16_t *mask, uint8_t* enabledChannels, uint8_t* delayTx); diff --git a/features/lorawan/lorastack/phy/LoRaPHYAS923.cpp b/features/lorawan/lorastack/phy/LoRaPHYAS923.cpp index dc0d6b336887..a5be66ac66a4 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYAS923.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYAS923.cpp @@ -67,7 +67,7 @@ */ #define AS923_DEFAULT_DATARATE DR_2 -#define AS923_DEFAULT_MAX_DATARATE DR_7 +#define AS923_DEFAULT_MAX_DATARATE DR_5 /*! * The minimum datarate which is used when the @@ -361,8 +361,7 @@ lorawan_status_t LoRaPHYAS923::set_next_channel(channel_selection_params_t* next bands, AS923_MAX_NB_BANDS); // Search how many channels are enabled - nb_enabled_channels = enabled_channel_count(next_channel_prams->joined, - next_channel_prams->current_datarate, + nb_enabled_channels = enabled_channel_count(next_channel_prams->current_datarate, channel_mask, enabled_channels, &delay_tx); } else { diff --git a/features/lorawan/lorastack/phy/LoRaPHYAU915.cpp b/features/lorawan/lorastack/phy/LoRaPHYAU915.cpp index b0708bb786aa..0c779b39f7db 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYAU915.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYAU915.cpp @@ -593,10 +593,9 @@ lorawan_status_t LoRaPHYAU915::set_next_channel(channel_selection_params_t* next bands, AU915_MAX_NB_BANDS); // Search how many channels are enabled - nb_enabled_channels = enabled_channel_count(next_chan_params->joined, - next_chan_params->current_datarate, - current_channel_mask, - enabled_channels, &delay_tx); + nb_enabled_channels = enabled_channel_count(next_chan_params->current_datarate, + current_channel_mask, + enabled_channels, &delay_tx); } else { delay_tx++; next_tx_delay = next_chan_params->aggregate_timeoff - _lora_time->get_elapsed_time(next_chan_params->last_aggregate_tx_time); diff --git a/features/lorawan/lorastack/phy/LoRaPHYKR920.cpp b/features/lorawan/lorastack/phy/LoRaPHYKR920.cpp index 97d6b6a814cf..3bba5e11f256 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYKR920.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYKR920.cpp @@ -430,9 +430,9 @@ lorawan_status_t LoRaPHYKR920::set_next_channel(channel_selection_params_t* para bands, KR920_MAX_NB_BANDS); // Search how many channels are enabled - nb_enabled_channels = enabled_channel_count(params->joined, params->current_datarate, - channel_mask, - enabled_channels, &delay_tx); + nb_enabled_channels = enabled_channel_count(params->current_datarate, + channel_mask, + enabled_channels, &delay_tx); } else { delay_tx++; nextTxDelay = params->aggregate_timeoff - _lora_time->get_elapsed_time(params->last_aggregate_tx_time); diff --git a/features/lorawan/lorastack/phy/LoRaPHYUS915.cpp b/features/lorawan/lorastack/phy/LoRaPHYUS915.cpp index a0ef187caa49..c4a565d88b18 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYUS915.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYUS915.cpp @@ -631,8 +631,7 @@ lorawan_status_t LoRaPHYUS915::set_next_channel(channel_selection_params_t* para next_tx_delay = update_band_timeoff(params->joined, params->dc_enabled, bands, US915_MAX_NB_BANDS); // Search how many channels are enabled - nb_enabled_channels = enabled_channel_count(params->joined, - params->current_datarate, + nb_enabled_channels = enabled_channel_count(params->current_datarate, current_channel_mask, enabled_channels, &delay_tx); } else { diff --git a/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.cpp b/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.cpp index cc07e469686a..ed35e3b0bb92 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.cpp @@ -631,8 +631,7 @@ lorawan_status_t LoRaPHYUS915Hybrid::set_next_channel(channel_selection_params_t US915_HYBRID_MAX_NB_BANDS); // Search how many channels are enabled - nb_enabled_channels = enabled_channel_count(params->joined, - params->current_datarate, + nb_enabled_channels = enabled_channel_count(params->current_datarate, current_channel_mask, enabled_channels, &delay_tx); } else { diff --git a/features/lorawan/lorawan_types.h b/features/lorawan/lorawan_types.h index 72fb199fdd81..eef09f2d6250 100644 --- a/features/lorawan/lorawan_types.h +++ b/features/lorawan/lorawan_types.h @@ -34,6 +34,11 @@ #include "platform/Callback.h" +/** + * A mask for the network ID. + */ +#define LORAWAN_NETWORK_ID_MASK (uint32_t) 0xFE000000 + /** * Option Flags for send(), receive() APIs * diff --git a/features/lorawan/mbed_lib.json b/features/lorawan/mbed_lib.json index a1003264dacc..a233118d3b95 100644 --- a/features/lorawan/mbed_lib.json +++ b/features/lorawan/mbed_lib.json @@ -57,6 +57,10 @@ "help": "Enables/disables duty cycling. NOTE: Disable only for testing. Mandatory in many regions.", "value": true }, + "duty-cycle-on-join": { + "help": "Enables/disables duty cycling for JOIN requests (disabling requires duty-cycle-on to be disabled). NOTE: Disable only for testing!", + "value": true + }, "lbt-on": { "help": "Enables/disables LBT. NOTE: [This feature is not yet integrated].", "value": false @@ -64,6 +68,18 @@ "automatic-uplink-message": { "help": "Stack will automatically send an uplink message when lora server requires immediate response", "value": true + }, + "max-sys-rx-error": { + "help": "Maximum timing error of the receiver in ms. The receiver will turn on in [-RxError : + RxError]", + "value": 10 + }, + "downlink-preamble-length": { + "help": "Number of preamble symbols need to be captured (out of 8) for successful demodulation", + "value": 5 + }, + "uplink-preamble-length": { + "help": "Number of preamble symbols to transmit. Must be <= 8", + "value": 8 } } } diff --git a/features/lorawan/system/lorawan_data_structures.h b/features/lorawan/system/lorawan_data_structures.h index e43cb85f9d53..038248fa8dfd 100644 --- a/features/lorawan/system/lorawan_data_structures.h +++ b/features/lorawan/system/lorawan_data_structures.h @@ -166,17 +166,6 @@ typedef struct { * The data rate in channels. */ int8_t channel_data_rate; - /*! - * The system overall timing error in milliseconds. - * [-SystemMaxRxError : +SystemMaxRxError] - * Default: +/-10 ms - */ - uint32_t max_sys_rx_error; - /*! - * The minimum number of symbols required to detect an RX frame. - * Default: 6 symbols - */ - uint8_t min_rx_symb; /*! * LoRaMac maximum time a reception window stays open. */ diff --git a/features/lwipstack/lwip-sys/arch/lwip_sys_arch.c b/features/lwipstack/lwip-sys/arch/lwip_sys_arch.c index 2804b399d677..20ad0b53804c 100644 --- a/features/lwipstack/lwip-sys/arch/lwip_sys_arch.c +++ b/features/lwipstack/lwip-sys/arch/lwip_sys_arch.c @@ -123,7 +123,7 @@ u32_t sys_now(void) { *---------------------------------------------------------------------------*/ err_t sys_mbox_new(sys_mbox_t *mbox, int queue_sz) { if (queue_sz > MB_SIZE) - error("sys_mbox_new size error\n"); + MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_INVALID_SIZE), "sys_mbox_new size error\n", queue_sz); memset(mbox, 0, sizeof(*mbox)); @@ -131,7 +131,7 @@ err_t sys_mbox_new(sys_mbox_t *mbox, int queue_sz) { mbox->attr.cb_size = sizeof(mbox->data); mbox->id = osEventFlagsNew(&mbox->attr); if (mbox->id == NULL) - error("sys_mbox_new create error\n"); + MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_FAILED_OPERATION), "sys_mbox_new create error\n", (u32_t)mbox); osEventFlagsSet(mbox->id, SYS_MBOX_POST_EVENT); @@ -150,7 +150,7 @@ err_t sys_mbox_new(sys_mbox_t *mbox, int queue_sz) { *---------------------------------------------------------------------------*/ void sys_mbox_free(sys_mbox_t *mbox) { if (mbox->post_idx != mbox->fetch_idx) - error("sys_mbox_free error\n"); + MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_INVALID_INDEX), "sys_mbox_free error\n", (u32_t)mbox->fetch_idx); } /*---------------------------------------------------------------------------* @@ -194,8 +194,10 @@ void sys_mbox_post(sys_mbox_t *mbox, void *msg) { err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) { uint32_t flags = osEventFlagsWait(mbox->id, SYS_MBOX_POST_EVENT, osFlagsWaitAny | osFlagsNoClear, 0); - if ((flags & osFlagsError) || !(flags & SYS_MBOX_POST_EVENT)) + if ((flags & osFlagsError) || !(flags & SYS_MBOX_POST_EVENT)) { + MBED_WARNING1(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_FAILED_OPERATION), "sys_mbox_trypost error\n", flags); return ERR_MEM; + } int state = osKernelLock(); @@ -239,8 +241,10 @@ u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) { uint32_t start = osKernelGetTickCount(); uint32_t flags = osEventFlagsWait(mbox->id, SYS_MBOX_FETCH_EVENT, osFlagsWaitAny | osFlagsNoClear, (timeout ? timeout : osWaitForever)); - if ((flags & osFlagsError) || !(flags & SYS_MBOX_FETCH_EVENT)) + if ((flags & osFlagsError) || !(flags & SYS_MBOX_FETCH_EVENT)) { + MBED_WARNING1(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_TIME_OUT), "sys_arch_mbox_fetch time-out\n", flags); return SYS_ARCH_TIMEOUT; + } int state = osKernelLock(); @@ -273,8 +277,10 @@ u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) { u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) { uint32_t flags = osEventFlagsWait(mbox->id, SYS_MBOX_FETCH_EVENT, osFlagsWaitAny | osFlagsNoClear, 0); - if ((flags & osFlagsError) || !(flags & SYS_MBOX_FETCH_EVENT)) + if ((flags & osFlagsError) || !(flags & SYS_MBOX_FETCH_EVENT)) { + MBED_WARNING1(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_FAILED_OPERATION), "sys_arch_mbox_tryfetch empty\n", flags); return SYS_MBOX_EMPTY; + } int state = osKernelLock(); @@ -309,7 +315,7 @@ err_t sys_sem_new(sys_sem_t *sem, u8_t count) { sem->attr.cb_size = sizeof(sem->data); sem->id = osSemaphoreNew(UINT16_MAX, count, &sem->attr); if (sem->id == NULL) - error("sys_sem_new create error\n"); + MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_FAILED_OPERATION), "sys_sem_new create error\n", (u32_t)sem); return ERR_OK; } @@ -340,8 +346,10 @@ err_t sys_sem_new(sys_sem_t *sem, u8_t count) { u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) { u32_t start = osKernelGetTickCount(); - if (osSemaphoreAcquire(sem->id, (timeout != 0)?(timeout):(osWaitForever)) != osOK) + if (osSemaphoreAcquire(sem->id, (timeout != 0)?(timeout):(osWaitForever)) != osOK) { + MBED_WARNING1(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_TIME_OUT), "sys_arch_sem_wait time out\n", (u32_t)sem); return SYS_ARCH_TIMEOUT; + } return osKernelGetTickCount() - start; } @@ -356,7 +364,7 @@ u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) { *---------------------------------------------------------------------------*/ void sys_sem_signal(sys_sem_t *data) { if (osSemaphoreRelease(data->id) != osOK) - mbed_die(); /* Can be called by ISR do not use printf */ + MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_SEMAPHORE_UNLOCK_FAILED), "sys_sem_signal error\n", (u32_t)data->id); } /*---------------------------------------------------------------------------* @@ -378,8 +386,10 @@ err_t sys_mutex_new(sys_mutex_t *mutex) { mutex->attr.cb_mem = &mutex->data; mutex->attr.cb_size = sizeof(mutex->data); mutex->id = osMutexNew(&mutex->attr); - if (mutex->id == NULL) + if (mutex->id == NULL) { + MBED_WARNING1(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_FAILED_OPERATION), "sys_mutex_new error\n", (u32_t)mutex); return ERR_MEM; + } return ERR_OK; } @@ -388,14 +398,14 @@ err_t sys_mutex_new(sys_mutex_t *mutex) { * @param mutex the mutex to lock */ void sys_mutex_lock(sys_mutex_t *mutex) { if (osMutexAcquire(mutex->id, osWaitForever) != osOK) - error("sys_mutex_lock error\n"); + MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_MUTEX_LOCK_FAILED), "sys_mutex_lock error\n", (u32_t)mutex); } /** Unlock a mutex * @param mutex the mutex to unlock */ void sys_mutex_unlock(sys_mutex_t *mutex) { if (osMutexRelease(mutex->id) != osOK) - error("sys_mutex_unlock error\n"); + MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_MUTEX_UNLOCK_FAILED), "sys_mutex_unlock error\n", (u32_t)mutex); } /** Delete a mutex @@ -418,7 +428,7 @@ void sys_init(void) { lwip_sys_mutex_attr.cb_size = sizeof(lwip_sys_mutex_data); lwip_sys_mutex = osMutexNew(&lwip_sys_mutex_attr); if (lwip_sys_mutex == NULL) - error("sys_init error\n"); + MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_INITIALIZATION_FAILED), "sys_init error, mutex initialization failed\n"); } /*---------------------------------------------------------------------------* @@ -452,7 +462,7 @@ u32_t sys_jiffies(void) { *---------------------------------------------------------------------------*/ sys_prot_t sys_arch_protect(void) { if (osMutexAcquire(lwip_sys_mutex, osWaitForever) != osOK) - error("sys_arch_protect error\n"); + MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_MUTEX_LOCK_FAILED), "sys_arch_protect error\n"); return (sys_prot_t) 1; } @@ -469,7 +479,7 @@ sys_prot_t sys_arch_protect(void) { *---------------------------------------------------------------------------*/ void sys_arch_unprotect(sys_prot_t p) { if (osMutexRelease(lwip_sys_mutex) != osOK) - error("sys_arch_unprotect error\n"); + MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_MUTEX_UNLOCK_FAILED), "sys_arch_unprotect error\n"); } u32_t sys_now(void) { @@ -524,7 +534,7 @@ static sys_thread_data_t thread_pool[SYS_THREAD_POOL_N]; LWIP_DEBUGF(SYS_DEBUG, ("New Thread: %s\n", pcName)); if (thread_pool_index >= SYS_THREAD_POOL_N) - error("sys_thread_new number error\n"); + MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_THREAD_CREATE_FAILED), "sys_thread_new number error\n", thread_pool_index); sys_thread_t t = (sys_thread_t)&thread_pool[thread_pool_index]; thread_pool_index++; @@ -537,11 +547,11 @@ static sys_thread_data_t thread_pool[SYS_THREAD_POOL_N]; t->attr.stack_mem = malloc(stacksize); t->attr.tz_module = MBED_TZ_DEFAULT_ACCESS; if (t->attr.stack_mem == NULL) { - error("Error allocating the stack memory"); + MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_OUT_OF_MEMORY), "unable to allocate thread stack\n", stacksize); } t->id = osThreadNew((osThreadFunc_t)thread, arg, &t->attr); if (t->id == NULL) - error("sys_thread_new create error\n"); + MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_THREAD_CREATE_FAILED), "sys_thread_new create error\n"); return t; } diff --git a/features/lwipstack/mbed_lib.json b/features/lwipstack/mbed_lib.json index 610de76827bc..64a0c7045dff 100644 --- a/features/lwipstack/mbed_lib.json +++ b/features/lwipstack/mbed_lib.json @@ -125,7 +125,7 @@ "LPC546XX": { "mem-size": 36496 }, - "EFM32GG11-STK3701": { + "EFM32GG11_STK3701": { "mem-size": 36560 }, "RZ_A1_EMAC": { diff --git a/features/nanostack/coap-service/coap-service/coap_service_api.h b/features/nanostack/coap-service/coap-service/coap_service_api.h index a21ff1d5914b..623c381744a0 100644 --- a/features/nanostack/coap-service/coap-service/coap_service_api.h +++ b/features/nanostack/coap-service/coap-service/coap_service_api.h @@ -353,6 +353,19 @@ extern int8_t coap_service_set_duplicate_message_buffer(int8_t service_id, uint8 */ extern int8_t coap_service_certificate_set(int8_t service_id, const unsigned char *cert, uint16_t cert_len, const unsigned char *priv_key, uint8_t priv_key_len); + +/** + * \brief Set CoAP blockwise payload size + * + * Set CoAP blockwise payload limit. If payload is bigger than configured limit, CoAP message will use blockwise option when sending. + * + * \param service_id Id number of the current service. + * \param size Blockwise size. Valid sizes are 16, 32, 64, 128, 256, 512 and 1024 bytes + * + * \return -1 For failure + *- 0 For success + */ +extern int8_t coap_service_blockwise_size_set(int8_t service_id, uint16_t size); #ifdef __cplusplus } #endif diff --git a/features/nanostack/coap-service/source/coap_connection_handler.c b/features/nanostack/coap-service/source/coap_connection_handler.c index fcb622d52b2f..8c6f094eb96d 100644 --- a/features/nanostack/coap-service/source/coap_connection_handler.c +++ b/features/nanostack/coap-service/source/coap_connection_handler.c @@ -175,6 +175,7 @@ static secure_session_t *secure_session_create(internal_socket_t *parent, const } } if(!to_be_removed){ + tr_err("max session count exceeded"); return NULL; } @@ -188,6 +189,7 @@ static secure_session_t *secure_session_create(internal_socket_t *parent, const } } if(handshakes >= max_handshakes) { + tr_err("ongoing handshakes exceeded"); return NULL; } @@ -215,6 +217,7 @@ static secure_session_t *secure_session_create(internal_socket_t *parent, const this->sec_handler = coap_security_create(parent->socket, this->timer.id, this, secure_mode, &secure_session_sendto, &secure_session_recvfrom, &start_timer, &timer_status); if( !this->sec_handler ){ + tr_err("security create failed"); ns_dyn_mem_free(this); return NULL; } @@ -401,7 +404,6 @@ static int send_to_real_socket(int8_t socket_id, const ns_address_t *address, co ns_cmsghdr_t *cmsg; ns_in6_pktinfo_t *pktinfo; - tr_debug("send from source address %s", trace_array(source_address, 16)); msghdr.msg_control = ancillary_databuffer; msghdr.msg_controllen = sizeof(ancillary_databuffer); @@ -647,9 +649,11 @@ static void secure_recv_sckt_msg(void *cb_res) session->last_contact_time = coap_service_get_internal_timer_ticks(); // Start handshake if (!coap_security_handler_is_started(session->sec_handler)) { - coap_security_handler_connect_non_blocking(session->sec_handler, true, DTLS, keys, sock->timeout_min, sock->timeout_max); + if(-1 == coap_security_handler_connect_non_blocking(session->sec_handler, true, DTLS, keys, sock->timeout_min, sock->timeout_max)) { + tr_err("Connection start failed"); + secure_session_delete(session); + } ns_dyn_mem_free(keys._key); - } } else { //Continue handshake @@ -742,11 +746,16 @@ int coap_connection_handler_virtual_recv(coap_conn_handler_t *handler, uint8_t a if (sock->parent->_get_password_cb && 0 == sock->parent->_get_password_cb(sock->socket, address, port, &keys)) { session = secure_session_create(sock, address, port, keys.mode); if (!session) { - tr_err("coap_connection_handler_virtual_recv session creation failed - OOM"); + tr_err("coap_connection_handler_virtual_recv session creation failed"); ns_dyn_mem_free(keys._key); return -1; } - coap_security_handler_connect_non_blocking(session->sec_handler, true, DTLS, keys, handler->socket->timeout_min, handler->socket->timeout_max); + if (-1 == coap_security_handler_connect_non_blocking(session->sec_handler, true, DTLS, keys, handler->socket->timeout_min, handler->socket->timeout_max)) { + tr_err("Connection start failed"); + ns_dyn_mem_free(keys._key); + secure_session_delete(session); + return -1; + } ns_dyn_mem_free(keys._key); return 0; } else { diff --git a/features/nanostack/coap-service/source/coap_message_handler.c b/features/nanostack/coap-service/source/coap_message_handler.c index eaa9f78caefa..db2cc14ef667 100644 --- a/features/nanostack/coap-service/source/coap_message_handler.c +++ b/features/nanostack/coap-service/source/coap_message_handler.c @@ -20,6 +20,7 @@ #include "coap_service_api_internal.h" #include "coap_message_handler.h" #include "mbed-coap/sn_coap_protocol.h" +#include "source/include/sn_coap_protocol_internal.h" #include "socket_api.h" #include "ns_types.h" #include "ns_list.h" @@ -138,7 +139,6 @@ void transaction_delete(coap_transaction_t *this) if (!coap_message_handler_transaction_valid(this)) { return; } - ns_list_remove(&request_list, this); transaction_free(this); @@ -163,11 +163,14 @@ void transactions_delete_all(uint8_t *address_ptr, uint16_t port) static int8_t coap_rx_function(sn_coap_hdr_s *resp_ptr, sn_nsdl_addr_s *address_ptr, void *param) { coap_transaction_t *this = NULL; - (void)address_ptr; (void)param; + if (resp_ptr->coap_status == COAP_STATUS_BUILDER_BLOCK_SENDING_DONE) { + return 0; + } + tr_warn("transaction was not handled %d", resp_ptr->msg_id); - if (!resp_ptr) { + if (!resp_ptr || !address_ptr) { return -1; } if(resp_ptr->token_ptr){ @@ -193,7 +196,7 @@ coap_msg_handler_t *coap_message_handler_init(void *(*used_malloc_func_ptr)(uint } coap_msg_handler_t *handle; - handle = used_malloc_func_ptr(sizeof(coap_msg_handler_t)); + handle = ns_dyn_mem_alloc(sizeof(coap_msg_handler_t)); if (handle == NULL) { return NULL; } @@ -207,13 +210,16 @@ coap_msg_handler_t *coap_message_handler_init(void *(*used_malloc_func_ptr)(uint handle->coap = sn_coap_protocol_init(used_malloc_func_ptr, used_free_func_ptr, used_tx_callback_ptr, &coap_rx_function); if( !handle->coap ){ - used_free_func_ptr(handle); + ns_dyn_mem_free(handle); return NULL; } /* Set default buffer size for CoAP duplicate message detection */ sn_coap_protocol_set_duplicate_buffer_size(handle->coap, DUPLICATE_MESSAGE_BUFFER_SIZE); + /* Set default blockwise message size. */ + sn_coap_protocol_set_block_size(handle->coap, DEFAULT_BLOCKWISE_DATA_SIZE); + /* Set default CoAP retransmission paramters */ sn_coap_protocol_set_retransmission_parameters(handle->coap, COAP_RESENDING_COUNT, COAP_RESENDING_INTERVAL); @@ -263,6 +269,7 @@ int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t sn_nsdl_addr_s src_addr; sn_coap_hdr_s *coap_message; int16_t ret_val = 0; + coap_transaction_t *this = NULL; if (!cb || !handle) { return -1; @@ -273,8 +280,19 @@ int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t src_addr.type = SN_NSDL_ADDRESS_TYPE_IPV6; src_addr.port = port; - coap_message = sn_coap_protocol_parse(handle->coap, &src_addr, data_len, data_ptr, NULL); + coap_transaction_t *transaction_ptr = transaction_create(); + if (!transaction_ptr) { + return -1; + } + transaction_ptr->service_id = coap_service_id_find_by_socket(socket_id); + transaction_ptr->client_request = false;// this is server transaction + memcpy(transaction_ptr->local_address, *(dst_addr_ptr) == 0xFF ? ns_in6addr_any : dst_addr_ptr, 16); + memcpy(transaction_ptr->remote_address, source_addr_ptr, 16); + transaction_ptr->remote_port = port; + + coap_message = sn_coap_protocol_parse(handle->coap, &src_addr, data_len, data_ptr, transaction_ptr); if (coap_message == NULL) { + transaction_delete(transaction_ptr); tr_err("CoAP Parsing failed"); return -1; } @@ -284,36 +302,26 @@ int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t /* Check, if coap itself sends response, or block receiving is ongoing... */ if (coap_message->coap_status != COAP_STATUS_OK && coap_message->coap_status != COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED) { tr_debug("CoAP library responds"); + transaction_delete(transaction_ptr); ret_val = -1; goto exit; } /* Request received */ if (coap_message->msg_code > 0 && coap_message->msg_code < 32) { - coap_transaction_t *transaction_ptr = transaction_create(); - if (transaction_ptr) { - transaction_ptr->service_id = coap_service_id_find_by_socket(socket_id); - transaction_ptr->msg_id = coap_message->msg_id; - transaction_ptr->client_request = false;// this is server transaction - transaction_ptr->req_msg_type = coap_message->msg_type; - memcpy(transaction_ptr->local_address, *(dst_addr_ptr) == 0xFF ? ns_in6addr_any : dst_addr_ptr, 16); - memcpy(transaction_ptr->remote_address, source_addr_ptr, 16); - if (coap_message->token_len) { - memcpy(transaction_ptr->token, coap_message->token_ptr, coap_message->token_len); - transaction_ptr->token_len = coap_message->token_len; - } - transaction_ptr->remote_port = port; - if (cb(socket_id, coap_message, transaction_ptr) < 0) { - // negative return value = message ignored -> delete transaction - transaction_delete(transaction_ptr); - } - goto exit; - } else { - ret_val = -1; + transaction_ptr->msg_id = coap_message->msg_id; + transaction_ptr->req_msg_type = coap_message->msg_type; + if (coap_message->token_len) { + memcpy(transaction_ptr->token, coap_message->token_ptr, coap_message->token_len); + transaction_ptr->token_len = coap_message->token_len; } + if (cb(socket_id, coap_message, transaction_ptr) < 0) { + // negative return value = message ignored -> delete transaction + transaction_delete(transaction_ptr); + } + goto exit; /* Response received */ } else { - coap_transaction_t *this = NULL; if (coap_message->token_ptr) { this = transaction_find_client_by_token(coap_message->token_ptr, coap_message->token_len, source_addr_ptr, port); } @@ -331,6 +339,10 @@ int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t } exit: + if (coap_message->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED) { + handle->sn_coap_service_free(coap_message->payload_ptr); + } + sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_message); return ret_val; @@ -350,7 +362,7 @@ uint16_t coap_message_handler_request_send(coap_msg_handler_t *handle, int8_t se tr_debug("Service %d, send CoAP request payload_len %d", service_id, payload_len); transaction_ptr = transaction_create(); - if (!uri || !transaction_ptr) { + if (!uri || !transaction_ptr || !handle) { return 0; } @@ -383,7 +395,10 @@ uint16_t coap_message_handler_request_send(coap_msg_handler_t *handle, int8_t se request.payload_len = payload_len; request.payload_ptr = (uint8_t *) payload_ptr; // Cast away const and trust that nsdl doesn't modify... - data_len = sn_coap_builder_calc_needed_packet_data_size(&request); + + prepare_blockwise_message(handle->coap, &request); + + data_len = sn_coap_builder_calc_needed_packet_data_size_2(&request, sn_coap_protocol_get_configured_blockwise_size(handle->coap)); data_ptr = own_alloc(data_len); if(data_len > 0 && !data_ptr){ transaction_delete(transaction_ptr); @@ -408,6 +423,10 @@ uint16_t coap_message_handler_request_send(coap_msg_handler_t *handle, int8_t se // Free allocated data own_free(data_ptr); + if(request.options_list_ptr) { + own_free(request.options_list_ptr); + } + if(request_response_cb == NULL){ //No response expected return 0; @@ -426,8 +445,10 @@ static int8_t coap_message_handler_resp_build_and_send(coap_msg_handler_t *handl dst_addr.addr_len = 16; dst_addr.type = SN_NSDL_ADDRESS_TYPE_IPV6; dst_addr.port = transaction_ptr->remote_port; - - data_len = sn_coap_builder_calc_needed_packet_data_size(coap_msg_ptr); +#if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE + prepare_blockwise_message(handle->coap, coap_msg_ptr); +#endif + data_len = sn_coap_builder_calc_needed_packet_data_size_2(coap_msg_ptr, sn_coap_protocol_get_configured_blockwise_size(handle->coap)); data_ptr = own_alloc(data_len); if (data_len > 0 && !data_ptr) { return -1; diff --git a/features/nanostack/coap-service/source/coap_service_api.c b/features/nanostack/coap-service/source/coap_service_api.c index 9adcee212a4e..16e646dda968 100644 --- a/features/nanostack/coap-service/source/coap_service_api.c +++ b/features/nanostack/coap-service/source/coap_service_api.c @@ -606,3 +606,14 @@ int8_t coap_service_certificate_set(int8_t service_id, const unsigned char *cert return 0; } + +int8_t coap_service_blockwise_size_set(int8_t service_id, uint16_t size) +{ + (void) service_id; + + if (!coap_service_handle) { + return -1; + } + + return sn_coap_protocol_set_block_size(coap_service_handle->coap, size); +} diff --git a/features/nanostack/coap-service/source/include/coap_message_handler.h b/features/nanostack/coap-service/source/include/coap_message_handler.h index b4e51c54ba6a..9b54619ca792 100644 --- a/features/nanostack/coap-service/source/include/coap_message_handler.h +++ b/features/nanostack/coap-service/source/include/coap_message_handler.h @@ -23,9 +23,13 @@ #include "ns_list.h" #define TRANSACTION_LIFETIME 180 + /* Default value for CoAP duplicate message buffer (0 = disabled) */ #define DUPLICATE_MESSAGE_BUFFER_SIZE 0 +/* Default value for CoAP blockwise data size (0 = disabled) */ +#define DEFAULT_BLOCKWISE_DATA_SIZE 0 + /* Default values for CoAP resendings */ #define COAP_RESENDING_COUNT 3 #define COAP_RESENDING_INTERVAL 10 diff --git a/features/nanostack/coap-service/test/coap-service/unittest/coap_message_handler/test_coap_message_handler.c b/features/nanostack/coap-service/test/coap-service/unittest/coap_message_handler/test_coap_message_handler.c index 91af9de1e406..c00067fa49d8 100644 --- a/features/nanostack/coap-service/test/coap-service/unittest/coap_message_handler/test_coap_message_handler.c +++ b/features/nanostack/coap-service/test/coap-service/unittest/coap_message_handler/test_coap_message_handler.c @@ -81,6 +81,7 @@ bool test_coap_message_handler_init() retCounter = 1; sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s)); memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s)); + nsdynmemlib_stub.returnCounter = 1; coap_msg_handler_t *handle = coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function); if( NULL == handle ) return false; @@ -97,6 +98,7 @@ bool test_coap_message_handler_destroy() retCounter = 1; sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s)); memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s)); + nsdynmemlib_stub.returnCounter = 1; coap_msg_handler_t *handle = coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function); if( 0 != coap_message_handler_destroy(handle) ) @@ -113,6 +115,7 @@ bool test_coap_message_handler_find_transaction() retCounter = 1; sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s)); memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s)); + nsdynmemlib_stub.returnCounter = 1; coap_msg_handler_t *handle = coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function); uint8_t buf[16]; @@ -140,26 +143,29 @@ bool test_coap_message_handler_coap_msg_process() { uint8_t buf[16]; memset(&buf, 1, 16); + bool ret_val = false; /*Handler is null*/ if( -1 != coap_message_handler_coap_msg_process(NULL, 0, buf, 22, ns_in6addr_any, NULL, 0, NULL)) - return false; + goto exit; retCounter = 1; sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s)); memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s)); + nsdynmemlib_stub.returnCounter = 1; coap_msg_handler_t *handle = coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function); sn_coap_protocol_stub.expectedHeader = NULL; /* Coap parse returns null */ if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb)) - return false; + goto exit; sn_coap_protocol_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s)); memset(sn_coap_protocol_stub.expectedHeader, 0, sizeof(sn_coap_hdr_s)); sn_coap_protocol_stub.expectedHeader->coap_status = 66; + nsdynmemlib_stub.returnCounter = 1; /* Coap library responds */ if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb)) - return false; + goto exit; sn_coap_protocol_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s)); memset(sn_coap_protocol_stub.expectedHeader, 0, sizeof(sn_coap_hdr_s)); @@ -167,8 +173,9 @@ bool test_coap_message_handler_coap_msg_process() sn_coap_protocol_stub.expectedHeader->msg_code = 1; retValue = 0; /* request received */ + nsdynmemlib_stub.returnCounter = 1; if( 0 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb)) - return false; + goto exit; sn_coap_protocol_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s)); memset(sn_coap_protocol_stub.expectedHeader, 0, sizeof(sn_coap_hdr_s)); @@ -177,15 +184,16 @@ bool test_coap_message_handler_coap_msg_process() nsdynmemlib_stub.returnCounter = 1; retValue = -1; if( 0 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb)) - return false; + goto exit; sn_coap_protocol_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s)); memset(sn_coap_protocol_stub.expectedHeader, 0, sizeof(sn_coap_hdr_s)); sn_coap_protocol_stub.expectedHeader->coap_status = COAP_STATUS_OK; sn_coap_protocol_stub.expectedHeader->msg_code = 333; + nsdynmemlib_stub.returnCounter = 1; if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb)) - return false; + goto exit; sn_coap_protocol_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s)); memset(sn_coap_protocol_stub.expectedHeader, 0, sizeof(sn_coap_hdr_s)); @@ -200,20 +208,19 @@ bool test_coap_message_handler_coap_msg_process() sn_coap_builder_stub.expectedUint16 = 1; nsdynmemlib_stub.returnCounter = 3; if( 2 != coap_message_handler_request_send(handle, 3, 0, buf, 24, 1, 2, &uri, 4, NULL, 0, &resp_recv)) - return false; + goto exit; sn_coap_protocol_stub.expectedHeader->msg_id = 2; -// sn_coap_protocol_stub.expectedHeader->token_ptr = (uint8_t*)malloc(4); -// memset(sn_coap_protocol_stub.expectedHeader->token_ptr, 1, 4); - if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb)) - return false; -// free(sn_coap_protocol_stub.expectedHeader->token_ptr); + if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb)) + goto exit; + ret_val = true; +exit: free(sn_coap_protocol_stub.expectedCoap); sn_coap_protocol_stub.expectedCoap = NULL; coap_message_handler_destroy(handle); - return true; + return ret_val; } bool test_coap_message_handler_request_send() @@ -221,6 +228,7 @@ bool test_coap_message_handler_request_send() retCounter = 1; sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s)); memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s)); + nsdynmemlib_stub.returnCounter = 1; coap_msg_handler_t *handle = coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function); uint8_t buf[16]; @@ -293,6 +301,7 @@ bool test_coap_message_handler_request_delete() retCounter = 1; sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s)); memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s)); + nsdynmemlib_stub.returnCounter = 1; coap_msg_handler_t *handle = coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function); uint8_t buf[16]; @@ -329,6 +338,7 @@ bool test_coap_message_handler_response_send() retCounter = 1; sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s)); memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s)); + nsdynmemlib_stub.returnCounter = 1; coap_msg_handler_t *handle = coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function); sn_coap_hdr_s *header = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s)); memset(header, 0, sizeof(sn_coap_hdr_s)); @@ -385,6 +395,7 @@ bool test_coap_message_handler_exec() retCounter = 1; sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s)); memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s)); + nsdynmemlib_stub.returnCounter = 1; coap_msg_handler_t *handle = coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function); if( 0 != coap_message_handler_exec(handle, 0)) diff --git a/features/nanostack/coap-service/test/coap-service/unittest/stub/nsdynmemLIB_stub.c b/features/nanostack/coap-service/test/coap-service/unittest/stub/nsdynmemLIB_stub.c index 70f800948247..c3883d61cce7 100644 --- a/features/nanostack/coap-service/test/coap-service/unittest/stub/nsdynmemLIB_stub.c +++ b/features/nanostack/coap-service/test/coap-service/unittest/stub/nsdynmemLIB_stub.c @@ -30,7 +30,7 @@ void ns_dyn_mem_init(uint8_t *heap, uint16_t h_size, void (*passed_fptr)(heap_fa { } #else -void ns_dyn_mem_init(void *heap, uint16_t h_size, void (*passed_fptr)(heap_fail_t), mem_stat_t *info_ptr) +void ns_dyn_mem_init(void *heap, ns_mem_heap_size_t h_size, void (*passed_fptr)(heap_fail_t), mem_stat_t *info_ptr) { } #endif diff --git a/features/nanostack/coap-service/test/coap-service/unittest/stub/sn_coap_builder_stub.c b/features/nanostack/coap-service/test/coap-service/unittest/stub/sn_coap_builder_stub.c index 99c010d5bd13..0aa5f2199d17 100644 --- a/features/nanostack/coap-service/test/coap-service/unittest/stub/sn_coap_builder_stub.c +++ b/features/nanostack/coap-service/test/coap-service/unittest/stub/sn_coap_builder_stub.c @@ -49,6 +49,11 @@ uint16_t sn_coap_builder_calc_needed_packet_data_size(sn_coap_hdr_s *src_coap_ms return sn_coap_builder_stub.expectedUint16; } +uint16_t sn_coap_builder_calc_needed_packet_data_size_2(sn_coap_hdr_s *src_coap_msg_ptr, uint16_t blockwise_payload_size) +{ + return sn_coap_builder_stub.expectedUint16; +} + int16_t sn_coap_builder_options_build_add_zero_length_option(uint8_t **dst_packet_data_pptr, uint8_t option_length, uint8_t option_exist, sn_coap_option_numbers_e option_number) { return sn_coap_builder_stub.expectedInt16; diff --git a/features/nanostack/coap-service/test/coap-service/unittest/stub/sn_coap_protocol_stub.c b/features/nanostack/coap-service/test/coap-service/unittest/stub/sn_coap_protocol_stub.c index e12c2cbf92d6..fcab0aa2d850 100644 --- a/features/nanostack/coap-service/test/coap-service/unittest/stub/sn_coap_protocol_stub.c +++ b/features/nanostack/coap-service/test/coap-service/unittest/stub/sn_coap_protocol_stub.c @@ -110,3 +110,13 @@ int8_t sn_coap_protocol_delete_retransmission(struct coap_s *handle, uint16_t ms { return 0; } + +uint16_t sn_coap_protocol_get_configured_blockwise_size(struct coap_s *handle) +{ + return 0; +} + +int8_t prepare_blockwise_message(struct coap_s *handle, sn_coap_hdr_s *src_coap_msg_ptr) +{ + return 0; +} diff --git a/features/nanostack/mbed-mesh-api/source/mesh_system.c b/features/nanostack/mbed-mesh-api/source/mesh_system.c index 3772f64cda03..3081d8daa2b2 100644 --- a/features/nanostack/mbed-mesh-api/source/mesh_system.c +++ b/features/nanostack/mbed-mesh-api/source/mesh_system.c @@ -24,6 +24,7 @@ #include "ns_hal_init.h" #include "include/mesh_system.h" #include "mbed_assert.h" +#include "mbed_error.h" // For tracing we need to define flag, have include and define group #define HAVE_DEBUG 1 #include "ns_trace.h" @@ -46,19 +47,7 @@ MBED_CONF_MBED_MESH_API_HEAP_STAT_INFO_DEFINITION; */ static void mesh_system_heap_error_handler(heap_fail_t event) { - tr_error("Heap error, mesh_system_heap_error_handler() %d", event); - switch (event) { - case NS_DYN_MEM_NULL_FREE: - case NS_DYN_MEM_DOUBLE_FREE: - case NS_DYN_MEM_ALLOCATE_SIZE_NOT_VALID: - case NS_DYN_MEM_POINTER_NOT_VALID: - case NS_DYN_MEM_HEAP_SECTOR_CORRUPTED: - case NS_DYN_MEM_HEAP_SECTOR_UNITIALIZED: - break; - default: - break; - } - while (1); + MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STACK, MBED_ERROR_CODE_OUT_OF_MEMORY), "Heap error, mesh_system_heap_error_handler()", event); } void mesh_system_init(void) diff --git a/features/nanostack/nanostack-interface/Nanostack.cpp b/features/nanostack/nanostack-interface/Nanostack.cpp index d85ad96d4a6c..c76a567d31c6 100644 --- a/features/nanostack/nanostack-interface/Nanostack.cpp +++ b/features/nanostack/nanostack-interface/Nanostack.cpp @@ -552,8 +552,8 @@ nsapi_error_t Nanostack::socket_open(void **handle, nsapi_protocol_t protocol) } if (!socket->open()) { delete socket; - tr_debug("socket_open() ret=%i", NSAPI_ERROR_DEVICE_ERROR); - return NSAPI_ERROR_DEVICE_ERROR; + tr_debug("socket_open() ret=%i", NSAPI_ERROR_NO_MEMORY); + return NSAPI_ERROR_NO_MEMORY; } *handle = (void*)socket; @@ -793,12 +793,15 @@ nsapi_error_t Nanostack::setsockopt(void *handle, int level, int optname, const break; } default: - return NSAPI_ERROR_PARAMETER; + return NSAPI_ERROR_UNSUPPORTED; } } - if (::socket_setsockopt(socket->socket_id, level, optname, optval, optlen) == 0) { + int retcode = ::socket_setsockopt(socket->socket_id, level, optname, optval, optlen); + if (retcode == 0) { return NSAPI_ERROR_OK; + } else if (retcode == -2) { + return NSAPI_ERROR_UNSUPPORTED; } else { return NSAPI_ERROR_PARAMETER; } @@ -812,19 +815,19 @@ nsapi_error_t Nanostack::getsockopt(void *handle, int level, int optname, void * 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; + + int retcode = ::socket_getsockopt(socket->socket_id, level, optname, optval, &optlen16); + if (retcode == 0) { *optlen = optlen16; + return NSAPI_ERROR_OK; + } else if (retcode == -2) { + return NSAPI_ERROR_UNSUPPORTED; } else { - ret = NSAPI_ERROR_PARAMETER; + return NSAPI_ERROR_PARAMETER; } - - return ret; } nsapi_error_t Nanostack::socket_listen(void *handle, int backlog) diff --git a/features/nanostack/sal-stack-nanostack/nanostack/ccmLIB.h b/features/nanostack/sal-stack-nanostack/nanostack/ccmLIB.h index ff4e2b5a4f74..50fa8872e24e 100644 --- a/features/nanostack/sal-stack-nanostack/nanostack/ccmLIB.h +++ b/features/nanostack/sal-stack-nanostack/nanostack/ccmLIB.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,6 +18,7 @@ #define CCMLIB_H_ #include "ns_types.h" +#include "platform/arm_hal_aes.h" /** * @@ -25,11 +26,11 @@ * \brief CCM Library API. * * \section ccm-api CCM Library API: - * - ccm_sec_init(), A function to init CCM library. + * - ccm_sec_init(), A function to init CCM context. * - ccm_process_run(), A function to run configured CCM process. * * \section ccm-instruction CCM process sequence: - * 1. Init CCM library by, ccm key, ccm_sec_init() + * 1. Init CCM context by, ccm key, ccm_sec_init() * - security level * - 128-bit CCM key * - mode: AES_CCM_ENCRYPT or AES_CCM_DECRYPT @@ -41,11 +42,6 @@ * -If 0 Process ok * -< 0 MIC fail or parameter fail * - * \section ccm-mutex CCM Mutex for Multi Thread System - * If you are running a multi thread system and the CCM library will be used for multiple thread, do the following: - * 1. Add compiler flag to library build process CCM_USE_MUTEX. - * 2. Define OS-specific mutex at the application. - * 3. Implement arm_ccm_mutex_lock() arm_ccm_mutex_unlock() function for using the generated and initialized mutex. */ #ifdef __cplusplus extern "C" { @@ -63,41 +59,39 @@ extern "C" { #define AES_CCM_DECRYPT 0x01 /**< Decryption mode */ -/** - * \brief A function for locking CCM mutex if the OS is multi thread. If you are using single thread create an empty function. - */ -extern void arm_ccm_mutex_lock(void); -/** - * \brief A function for unlocking CCM mutex if the OS is multi thread. If you are using single thread create an empty function - */ -extern void arm_ccm_mutex_unlock(void); - /*! * \struct ccm_globals_t * \brief CCM global structure. * The structure is used for configuring NONCE, adata and data before calling ccm_process_run(). */ typedef struct { - uint8_t exp_nonce[15]; /**< CCM NONCE buffer Nonce. */ - uint8_t *data_ptr; /**< Pointer to data IN. */ - uint16_t data_len; /**< Length of data IN. */ + uint8_t exp_nonce[15]; /**< CCM NONCE buffer Nonce. */ + uint8_t *data_ptr; /**< Pointer to data IN. */ + uint16_t data_len; /**< Length of data IN. */ const uint8_t *adata_ptr; /**< Pointer to authentication data. */ - uint16_t adata_len; /**< Length of authentication data. */ - uint8_t mic_len; /**< ccm_sec_init() sets here the length of MIC. */ - uint8_t *mic; /**< Encrypt process writes MIC. Decrypt reads it and compares it with the MIC obtained from data. */ + uint16_t adata_len; /**< Length of authentication data. */ + unsigned ccm_encode_mode:1; /**< Encryption modeAES_CCM_ENCRYPT or AES_CCM_DECRYPT. */ + unsigned ccm_sec_level:3; /**< Encryption operation security level 0-7. */ + unsigned ccm_l_param:4; /**< Can be 2 or 3. 2 when NONCE length is 13 and 3 when 12*/ + uint8_t mic_len; /**< ccm_sec_init() sets here the length of MIC. */ + uint8_t *mic; /**< Encrypt process writes MIC. Decrypt reads it and compares it with the MIC obtained from data. */ + const uint8_t *key_ptr; /**< Encyption key pointer to 128-bit key. */ + arm_aes_context_t *aes_context; /**< Allocated AES context. */ } ccm_globals_t; + /** - * \brief A function to initialize the CCM library. + * \brief A function to initialize the CCM context. + * \param ccm_context pointer to initialized XXM context * \param sec_level Used CCM security level (0-7). * \param ccm_key Pointer to 128-key. * \param mode AES_CCM_ENCRYPT or AES_CCM_DECRYPT. * \param ccm_l Can be 2 or 3. 2 when NONCE length is 13 and 3 when 12. (NONCE length = (15-ccm_l)) * - * \return Pointer to Global CCM parameter buffer. - * \return 0 When parameter fails or CCM is busy. + * \return true when AES context allocation is OK and given parameters. + * \return false CCM parameters or AES context allocation fail. */ -extern ccm_globals_t *ccm_sec_init(uint8_t sec_level, const uint8_t *ccm_key, uint8_t mode, uint8_t ccm_l); +extern bool ccm_sec_init(ccm_globals_t *ccm_context, uint8_t sec_level, const uint8_t *ccm_key, uint8_t mode, uint8_t ccm_l); /** * \brief A function to run the configured CCM process. @@ -109,6 +103,14 @@ extern ccm_globals_t *ccm_sec_init(uint8_t sec_level, const uint8_t *ccm_key, ui * \return -2 Null pointer given to function. */ extern int8_t ccm_process_run(ccm_globals_t *ccm_params); + +/** + * \brief A function to free aes context. Call only if ccm_process_run() is not called + * \param ccm_params CCM parameters + * + */ +extern void ccm_free(ccm_globals_t *ccm_params); + #ifdef __cplusplus } #endif diff --git a/features/nanostack/sal-stack-nanostack/nanostack/fhss_api.h b/features/nanostack/sal-stack-nanostack/nanostack/fhss_api.h index 7f16f0cc05c0..16820aeaaeec 100644 --- a/features/nanostack/sal-stack-nanostack/nanostack/fhss_api.h +++ b/features/nanostack/sal-stack-nanostack/nanostack/fhss_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, Arm Limited and affiliates. + * Copyright (c) 2016-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -74,17 +74,16 @@ typedef bool fhss_use_broadcast_queue(const fhss_api_t *api, bool is_broadcast_a * @param is_broadcast_addr Destination address type of packet (true if broadcast address). * @param destination_address Destination MAC address. * @param frame_type Frame type of packet (Frames types are defined by FHSS api). - * @param synch_info Pointer to where FHSS synchronization info is written (if synch frame). * @param frame_length MSDU length of the frame. * @param phy_header_length PHY header length. * @param phy_tail_length PHY tail length. + * @param tx_time TX time. * @return 0 Success. * @return -1 Transmission of the packet is currently not allowed, try again. * @return -2 Invalid api. * @return -3 Broadcast packet on Unicast channel (not allowed), push packet back to queue. - * @return -4 Synchronization info missing. */ -typedef int fhss_tx_handle(const fhss_api_t *api, bool is_broadcast_addr, uint8_t *destination_address, int frame_type, uint8_t *synch_info, uint16_t frame_length, uint8_t phy_header_length, uint8_t phy_tail_length); +typedef int fhss_tx_handle(const fhss_api_t *api, bool is_broadcast_addr, uint8_t *destination_address, int frame_type, uint16_t frame_length, uint8_t phy_header_length, uint8_t phy_tail_length, uint32_t tx_time); /** * @brief Check TX permission. @@ -152,6 +151,17 @@ typedef uint32_t fhss_read_timestamp(const fhss_api_t *api); */ typedef uint16_t fhss_get_retry_period(const fhss_api_t *api, uint8_t *destination_address, uint16_t phy_mtu); +/** + * @brief Write synchronization info to given pointer. + * @param api FHSS instance. + * @param ptr Pointer to data. Start of written data for Synch frame. Start of IE header for Data frame. + * @param length Length of IE header. Ignored when Synch frame. + * @param frame_type Frame type of packet (Frames types are defined by FHSS api). + * @param tx_time TX time must be referenced to the first symbol following the SFD of the transmitted frame. + * @return -1 on fail, write length otherwise. + */ +typedef int16_t fhss_write_synch_info(const fhss_api_t *api, uint8_t *ptr, uint8_t length, int frame_type, uint32_t tx_time); + /** * @brief Initialize MAC functions. * @param api FHSS instance. @@ -177,6 +187,7 @@ struct fhss_api { fhss_synch_state_set *synch_state_set; /**< Change synchronization state. */ fhss_read_timestamp *read_timestamp; /**< Read timestamp. */ fhss_get_retry_period *get_retry_period; /**< Get retransmission period. */ + fhss_write_synch_info *write_synch_info; /**< Write synchronization info to TX frame*/ fhss_init_callbacks *init_callbacks; /**< Initialize MAC functions. */ }; @@ -256,6 +267,18 @@ typedef int mac_broadcast_notify(const fhss_api_t *fhss_api, uint32_t broadcast_ */ typedef int mac_read_coordinator_mac_address(const fhss_api_t *fhss_api, uint8_t *mac_address); +/** + * @brief Read synchronization info for a specific peer. + * @param fhss_api FHSS instance. + * @param info_ptr Pointer to info data. + * @param mac_address MAC address pointer. + * @param info_type Type of the read info (UTT-IE, BT-IE, US-IE, BS-IE). + * @param rx_timestamp Time of reception of the element. + * @return >=0 Length of the info. + * @return -1 Fail. + */ +typedef int mac_read_synch_info(const fhss_api_t *fhss_api, uint8_t *info_ptr, uint8_t *mac_address, int info_type, uint32_t rx_timestamp); + /** * \brief Struct fhss_callback defines functions that software MAC needs to implement. * Function pointers are passed to FHSS using fhss_init_callbacks function. @@ -270,6 +293,7 @@ struct fhss_callback { mac_tx_poll *tx_poll; /**< Poll TX queue. */ mac_broadcast_notify *broadcast_notify; /**< Broadcast channel notification from FHSS. */ mac_read_coordinator_mac_address *read_coord_mac_address; /**< Read coordinator MAC address. */ + mac_read_synch_info *read_synch_info; /**< Read information element for a specific MAC address. */ }; #ifdef __cplusplus diff --git a/features/nanostack/sal-stack-nanostack/nanostack/fhss_config.h b/features/nanostack/sal-stack-nanostack/nanostack/fhss_config.h index 5cfad5dd1fca..5695367659fe 100644 --- a/features/nanostack/sal-stack-nanostack/nanostack/fhss_config.h +++ b/features/nanostack/sal-stack-nanostack/nanostack/fhss_config.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -28,6 +28,23 @@ extern "C" { #endif +#include "fhss_ws_extension.h" + +/** + * @brief WS channel functions. + */ +typedef enum +{ + /** Fixed channel. */ + WS_FIXED_CHANNEL, + /** TR51 channel function. */ + WS_TR51CF, + /** Direct Hash channel function. */ + WS_DH1CF, + /** Vendor Defined channel function. */ + WS_VENDOR_DEF_CF +} fhss_ws_channel_functions; + /** * \brief Struct fhss_tuning_parameter defines FHSS tuning parameters. * All delays are given in microseconds. @@ -63,20 +80,59 @@ typedef struct fhss_configuration } fhss_configuration_t; +/** + * @brief Get channel using vendor defined channel function. + * @param api FHSS instance. + * @param slot Slot number in channel schedule. + * @param eui64 EUI-64 address of node for which the (unicast) schedule is calculated. NULL for broadcast schedule. + * @param bsi Broadcast schedule identifier used in (broadcast) schedule calculation. + * @param number_of_channels Number of channels in schedule. + * @return Channel. + */ +typedef int32_t fhss_vendor_defined_cf(const fhss_api_t *api, uint16_t slot, uint8_t eui64[8], uint16_t bsi, uint16_t number_of_channels); + +/** + * \brief Struct fhss_ws_configuration defines configuration of WS FHSS. + */ +typedef struct fhss_ws_configuration +{ + /** WS channel function. */ + fhss_ws_channel_functions ws_channel_function; + + /** Broadcast schedule identifier. */ + uint16_t bsi; + + /** Unicast dwell interval. Range: 15-250 milliseconds. */ + uint8_t fhss_uc_dwell_interval; + + /** Broadcast interval. Duration between broadcast dwell intervals. Range: 0-16777216 milliseconds. */ + uint32_t fhss_broadcast_interval; + + /** Broadcast dwell interval. Range: 15-250 milliseconds. */ + uint8_t fhss_bc_dwell_interval; + + /** Channel mask. */ + uint32_t channel_mask[8]; + + /** Vendor defined channel function. */ + fhss_vendor_defined_cf *vendor_defined_cf; + +} fhss_ws_configuration_t; + /** * \brief Struct fhss_timer defines interface between FHSS and FHSS platform timer. * Application must implement FHSS timer driver which is then used by FHSS with this interface. */ typedef struct fhss_timer { - /** Start timeout (1us) */ + /** Start timeout (1us). Timer must support multiple simultaneous timeouts */ int (*fhss_timer_start)(uint32_t, void (*fhss_timer_callback)(const fhss_api_t *fhss_api, uint16_t), const fhss_api_t *fhss_api); /** Stop timeout */ - int (*fhss_timer_stop)(const fhss_api_t *fhss_api); + int (*fhss_timer_stop)(void (*fhss_timer_callback)(const fhss_api_t *fhss_api, uint16_t), const fhss_api_t *fhss_api); /** Get remaining time of started timeout*/ - uint32_t (*fhss_get_remaining_slots)(const fhss_api_t *fhss_api); + uint32_t (*fhss_get_remaining_slots)(void (*fhss_timer_callback)(const fhss_api_t *fhss_api, uint16_t), const fhss_api_t *fhss_api); /** Get timestamp since initialization of driver. Overflow of 32-bit counter is allowed (1us) */ uint32_t (*fhss_get_timestamp)(const fhss_api_t *fhss_api); diff --git a/features/nanostack/sal-stack-nanostack/nanostack/fhss_ws_extension.h b/features/nanostack/sal-stack-nanostack/nanostack/fhss_ws_extension.h new file mode 100644 index 000000000000..c440451204da --- /dev/null +++ b/features/nanostack/sal-stack-nanostack/nanostack/fhss_ws_extension.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2018, Arm Limited and affiliates. + * 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. + */ + +/** + * \file fhss_ws_extension.h + * \brief + */ + +#ifndef FHSS_WS_EXT_H +#define FHSS_WS_EXT_H + +#include "ns_types.h" +#include "fhss_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief unicast_timing_info Unicast timing/hopping schedule information structure. + */ +typedef struct unicast_timing_info { + unsigned unicast_channel_function:3; /**< Unicast schedule channel function */ + uint8_t unicast_dwell_interval; /**< Unicast dwell interval */ + uint16_t unicast_number_of_channels; /**< Unicast number of channels */ + uint_fast24_t ufsi; /**< Unicast fractional sequence interval */ + uint32_t utt_rx_timestamp; /**< UTT-IE reception timestamp */ +} unicast_timing_info_t; + +/** + * @brief broadcast_timing_info Broadcast timing/hopping schedule information structure. + */ +typedef struct broadcast_timing_info { + unsigned broadcast_channel_function:3; /**< Broadcast schedule channel function */ + uint8_t broadcast_dwell_interval; /**< Broadcast dwell interval */ + uint16_t broadcast_slot; /**< Broadcast slot number */ + uint16_t broadcast_schedule_id; /**< Broadcast schedule identifier */ + uint_fast24_t broadcast_interval_offset; /**< Broadcast interval offset */ + uint32_t broadcast_interval; /**< Broadcast interval */ + uint32_t bt_rx_timestamp; /**< BT-IE reception timestamp */ +} broadcast_timing_info_t; + +/** + * @brief fhss_ws_neighbor_timing_info Neighbor timing/hopping schedule information structure. + */ +typedef struct fhss_ws_neighbor_timing_info { + uint8_t clock_drift; /**< Neighbor clock drift */ + uint8_t timing_accuracy; /**< Neighbor timing accuracy */ + unicast_timing_info_t uc_timing_info; /**< Neighbor unicast timing info */ + broadcast_timing_info_t bc_timing_info; /**< Neighbor broadcast timing info */ + uint32_t *excluded_channels; /**< Neighbor excluded channels (bit mask) */ +} fhss_ws_neighbor_timing_info_t; + +/** + * @brief Get neighbor timing/hopping schedule. + * @param api FHSS instance. + * @param eui64 EUI-64 address of node for which the info is requested. + * @return Neighbor timing/hopping schedule. + */ +typedef fhss_ws_neighbor_timing_info_t *fhss_get_neighbor_info(const fhss_api_t *api, uint8_t eui64[8]); + +/** + * @brief Set parent which broadcast channels must be listened by FHSS. + * @param fhss_api FHSS instance. + * @param eui64 EUI-64 address of parent. + * @param bc_timing_info Pointer to parent broadcast timing/hopping schedule info. + * @return 0 on success, -1 on fail. + */ +extern int ns_fhss_ws_set_parent(const fhss_api_t *fhss_api, const uint8_t eui64[8], const broadcast_timing_info_t *bc_timing_info); + +/** + * @brief Remove parent which was set by ns_fhss_ws_set_parent function. + * @param fhss_api FHSS instance. + * @param eui64 EUI-64 address of parent. + * @return 0 on success, -1 on fail. + */ +extern int ns_fhss_ws_remove_parent(const fhss_api_t *fhss_api, const uint8_t eui64[8]); + +/** + * @brief Set neighbor timing/hopping schedule request function. + * @param fhss_api FHSS instance. + * @param get_neighbor_info Neighbor info function pointer. + * @return 0 on success, -1 on fail. + */ +extern int ns_fhss_set_neighbor_info_fp(const fhss_api_t *fhss_api, fhss_get_neighbor_info *get_neighbor_info); + +/** + * @brief Set node hop count. Hop count is used to specify TX/RX slot. When hop count is set to 0xFF, TX/RX slots are ignored. + * @param fhss_api FHSS instance. + * @param hop_count Hop count to be set. + * @return 0 on success, -1 on fail. + */ +extern int ns_fhss_ws_set_hop_count(const fhss_api_t *fhss_api, const uint8_t hop_count); + +#ifdef __cplusplus +} +#endif + +#endif // FHSS_WS_EXT_H diff --git a/features/nanostack/sal-stack-nanostack/nanostack/mac_api.h b/features/nanostack/sal-stack-nanostack/nanostack/mac_api.h index 079d533de9cb..b889ee25a732 100644 --- a/features/nanostack/sal-stack-nanostack/nanostack/mac_api.h +++ b/features/nanostack/sal-stack-nanostack/nanostack/mac_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, Arm Limited and affiliates. + * Copyright (c) 2016-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -32,6 +32,8 @@ extern "C" { #endif +struct channel_list_s; + typedef struct mac_api_s mac_api_t; /** @@ -120,6 +122,17 @@ typedef void mlme_request(const mac_api_t* api, mlme_primitive id, const void *d */ typedef void mcps_data_request(const mac_api_t* api, const mcps_data_req_t *data); +/** + * @brief mcps_request MCPS_DATA with IE extions request call + * @param api API to handle the request + * @param data MCPS-DATA.request specific values + * @param ie_ext Information element list to MCPS-DATA.request + * @param asynch_channel_list Optional channel list to asynch data request. Give NULL when normal data request. + * + * Asynch data request is mac standard extension. asynch_channel_list include channel mask which channel message is requested to send. + */ +typedef void mcps_data_request_ext(const mac_api_t* api, const mcps_data_req_t *data, const mcps_data_req_ie_list_t *ie_ext, const struct channel_list_s *asynch_channel_list); + /** * @brief mcps_purge_request MCPS_PURGE request call * @param api API to handle the request @@ -136,6 +149,14 @@ typedef void mcps_purge_request(const mac_api_t* api, const mcps_purge_t *data); */ typedef void mcps_data_confirm(const mac_api_t* api, const mcps_data_conf_t *data); +/** + * @brief mcps_data_confirm_ext MCPS-DATA confirm with Enhanced ACK payload is called as a response to MCPS-DATA request + * @param api The API which handled the response + * @param data MCPS-DATA.confirm specific values + * @param conf_data Possible Confirmation Data + */ +typedef void mcps_data_confirm_ext(const mac_api_t* api, const mcps_data_conf_t *data, const mcps_data_conf_payload_t *conf_data); + /** * @brief mcps_data_indication MCPS-DATA indication is called when MAC layer has received data * @param api The API which handled the response @@ -143,6 +164,24 @@ typedef void mcps_data_confirm(const mac_api_t* api, const mcps_data_conf_t *dat */ typedef void mcps_data_indication(const mac_api_t* api, const mcps_data_ind_t *data); +/** + * @brief mcps_data_indication MCPS-DATA indication is called when MAC layer has received data + * @param api The API which handled the response + * @param data MCPS-DATA.indication specific values + * @param ie_ext Information element list + */ +typedef void mcps_data_indication_ext(const mac_api_t* api, const mcps_data_ind_t *data, const mcps_data_ie_list_t *ie_ext); + +/** + * @brief mcps_ack_data_req_ext Callback for request IE elements and payload to enhanced ACK + * @param api The API which handled the response + * @param data Pointer where MAC user set Payload and IE element pointers and length + * @param rssi Signal strength for received packet + * @param lqi Link quality to neighbor + */ +typedef void mcps_ack_data_req_ext(const mac_api_t* api, mcps_ack_data_payload_t *data, int8_t rssi, uint8_t lqi); + + /** * @brief mcps_purge_confirm MCPS-PURGE confirm is called as a response to MCPS-PURGE request * @param api The API which handled the request @@ -201,6 +240,19 @@ typedef int8_t mac_api_initialize(mac_api_t *api, mcps_data_confirm *data_conf_c mcps_data_indication *data_ind_cb, mcps_purge_confirm *purge_conf_cb, mlme_confirm *mlme_conf_cb, mlme_indication *mlme_ind_cb, int8_t parent_id); +/** + * @brief mac_api_enable_mcps_ext Initialises MAC 2015 extension for MCPS layer into use, callbacks must be non-NULL. + * @param api mac_api_t pointer, which is created by application. + * @param data_ind_cb Upper layer function to handle MCPS indications + * @param data_cnf_cb Upper layer function to handle MCPS confirmation + * @param ack_data_req_cb Upper layer function for set Enhanced ACK payload + * @return -1 if error, -2 if OOM, 0 otherwise + */ +typedef int8_t mac_api_enable_mcps_ext(mac_api_t *api, + mcps_data_indication_ext *data_ind_cb, + mcps_data_confirm_ext *data_cnf_cb, + mcps_ack_data_req_ext *ack_data_req_cb); + /** * \brief Struct mac_api_s defines functions for two-way communications between external MAC and Upper layer. * Application creates mac_api_t object by calling external MAC's creator function. @@ -209,14 +261,19 @@ typedef int8_t mac_api_initialize(mac_api_t *api, mcps_data_confirm *data_conf_c */ struct mac_api_s { mac_api_initialize *mac_initialize; /**< MAC initialize function to use */ + mac_api_enable_mcps_ext *mac_mcps_extension_enable; /**< MAC MCPS IE extension enable function, optional feature */ //External MAC callbacks mlme_request *mlme_req; /**< MAC MLME request function to use */ mcps_data_request *mcps_data_req; /**< MAC MCPS data request function to use */ + mcps_data_request_ext *mcps_data_req_ext; /**< MAC MCPS data request with Information element extension function to use */ mcps_purge_request *mcps_purge_req; /**< MAC MCPS purge request function to use */ //Upper layer callbacksMLME_ASSOCIATE mcps_data_confirm *data_conf_cb; /**< MAC MCPS data confirm callback function */ + mcps_data_confirm_ext *data_conf_ext_cb; /**< MAC MCPS data confirm with payload callback function */ mcps_data_indication *data_ind_cb; /**< MAC MCPS data indication callback function */ + mcps_data_indication_ext *data_ind_ext_cb; /**< MAC MCPS data indication with IE extension's callback function */ + mcps_ack_data_req_ext *enhanced_ack_data_req_cb; /**< Enhanced ACK IE element and payload request from MAC user */ mcps_purge_confirm *purge_conf_cb; /**< MAC MCPS purge confirm callback function */ mlme_confirm *mlme_conf_cb; /**< MAC MLME confirm callback function */ mlme_indication *mlme_ind_cb; /**< MAC MLME indication callback function */ diff --git a/features/nanostack/sal-stack-nanostack/nanostack/mac_common_defines.h b/features/nanostack/sal-stack-nanostack/nanostack/mac_common_defines.h index 2cb970662dd1..dfa8d0f6cc30 100644 --- a/features/nanostack/sal-stack-nanostack/nanostack/mac_common_defines.h +++ b/features/nanostack/sal-stack-nanostack/nanostack/mac_common_defines.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, Arm Limited and affiliates. + * Copyright (c) 2016-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -30,6 +30,7 @@ #define MAC_FRAME_VERSION_2003 0 /**< FCF - IEEE 802.15.4-2003 compatible */ #define MAC_FRAME_VERSION_2006 1 /**< FCF - IEEE 802.15.4-2006 (big payload or new security) */ +#define MAC_FRAME_VERSION_2015 2 /**< FCF - IEEE 802.15.4-2015 (IE element support) */ //See IEEE standard 802.15.4-2006 (table 96) for more details about identifiers #define MAC_KEY_ID_MODE_IMPLICIT 0 /**< Key identifier mode implicit */ @@ -66,4 +67,36 @@ typedef struct mlme_security_s { uint8_t Keysource[8]; /**< Key source */ } mlme_security_t; +#define MAC_HEADER_VENDOR_SPESIFIC_IE_ID 0x00 /**< Vendor specific Header IE element */ +#define MAC_HEADER_ASSIGNED_EXTERNAL_ORG_IE_ID 0x2a /**< External organisation defined Header IE element */ +#define MAC_HEADER_TERMINATION1_IE_ID 0x7e /**< Header IE element termination when Payload element is following Header IE */ +#define MAC_HEADER_TERMINATION2_IE_ID 0x7f /**< Header IE element termination when no Payload element is following Header IE but normal payload is */ + + +/** + * @brief struct mac_header_IE_t Mac Header information element structure for parsing or write operation + * This structure encapsulates security related variables, + */ +typedef struct mac_header_IE_s { + uint8_t *content_ptr; /**< Content data */ + unsigned length:7; /**< Element length 0- 127 */ + uint8_t id; /**< Element ID */ +} mac_header_IE_t; + +#define MAC_PAYLOAD_IE_ESDU_GROUP_ID 0x00 /**< Encapsulated Service Data Unit (ESDU) Payload IE element's */ +#define MAC_PAYLOAD_MLME_IE_GROUP_ID 0x01 /**< MLME nested Payload IE element's */ +#define MAC_PAYLOAD_VENDOR_IE_GROUP_ID 0x02 /**< Vendor specific nested Payload IE element's */ +#define MAC_PAYLOAD_MPX_IE_GROUP_ID 0x03 /**< MPX Payload IE element, IEEE 802.15.9 defined */ +#define MAC_PAYLOAD_TERMINATION_IE_GROUP_ID 0x0f /**< Payload IE element terminator. Mandatory when normal payload is coming after IE element part */ + +/** + * @brief struct mac_header_IE_t Mac Payload information element structure for parsing or write operation + * This structure encapsulates security related variables, + */ +typedef struct mac_payload_IE_s { + uint8_t *content_ptr; /**< Content data */ + unsigned length:11; /**< Element length 0- 2047 */ + unsigned id:4; /**< Group ID */ +} mac_payload_IE_t; + #endif /* MAC_COMMON_DEFINES_H_ */ diff --git a/features/nanostack/sal-stack-nanostack/nanostack/mac_mcps.h b/features/nanostack/sal-stack-nanostack/nanostack/mac_mcps.h index 629f8a145104..fab3f2abdffe 100644 --- a/features/nanostack/sal-stack-nanostack/nanostack/mac_mcps.h +++ b/features/nanostack/sal-stack-nanostack/nanostack/mac_mcps.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, Arm Limited and affiliates. + * Copyright (c) 2016-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -25,6 +25,7 @@ #include #include "mac_common_defines.h" + /** * @brief struct mcps_data_req_t Data request structure * @@ -41,6 +42,8 @@ typedef struct mcps_data_req_s { bool TxAckReq: 1; /**< Specifies whether ACK is needed or not */ bool InDirectTx:1; /**< Specifies whether indirect or direct transmission is used */ bool PendingBit: 1; /**< Specifies whether more fragments are to be sent or not */ + bool SeqNumSuppressed:1; /**< True suppress sequence number from frame. This will be only checked when 2015 extension is enabled */ + bool PanIdSuppressed:1; /**< True suppress PAN-id is done when possible from frame. This will be only checked when 2015 extension is enabled */ mlme_security_t Key; /**< Security key */ } mcps_data_req_t; @@ -58,6 +61,21 @@ typedef struct mcps_data_conf_s { uint8_t tx_retries; /**< Number of retries done during sending, 0 means no retries */ } mcps_data_conf_t; + +/** + * @brief struct mcps_data_conf_payload_t Data confirmatio IE extension list and payload from enhanced ACK + * + */ +typedef struct mcps_data_conf_payload_s { + uint8_t *headerIeList; /**< Header information IE's list without terminator*/ + uint8_t *payloadIeList; /**< Payload information IE's list without terminator*/ + uint8_t *payloadPtr; /**< Ack payload pointer */ + uint16_t headerIeListLength; /**< Header information IE's list length in bytes */ + uint16_t payloadIeListLength; /**< Payload information IE's list length in bytes */ + uint16_t payloadLength; /**< Payload length in bytes */ +} mcps_data_conf_payload_t; + + /** * @brief struct mcps_data_ind_t Data indication structure * @@ -79,6 +97,54 @@ typedef struct mcps_data_ind_s { uint8_t *msdu_ptr; /**< Data unit */ } mcps_data_ind_t; +/** + * @brief struct mcps_data_ie_list_t MCPS data Information element list stucture + * + * Structure for IEEE 802.15.4-2015 MCPS data extension to Indication + */ +typedef struct mcps_data_ie_list { + uint8_t *headerIeList; /**< Header information IE's list without terminator*/ + uint8_t *payloadIeList; /**< Payload information IE's list without terminator*/ + uint16_t headerIeListLength; /**< Header information IE's list length in bytes */ + uint16_t payloadIeListLength; /**< Payload information IE's list length in bytes */ +} mcps_data_ie_list_t; + +/** \brief Scatter-gather descriptor for MCPS request IE Element list + * + * Slightly optimised for small platforms - we assume we won't need any + * element bigger than 64K. + */ +typedef struct ns_ie_iovec { + void *ieBase; /**< IE element pointer */ + uint_fast16_t iovLen; /**< IE element length */ +} ns_ie_iovec_t; + + +/** + * @brief struct mcps_data_req_ie_list MCPS data Information element list stuctrure + * + * Structure for IEEE 802.15.4-2015 MCPS data extension to Request + * + * IE element could be divided to multiple vector which MAC just write to message direct. + */ +typedef struct mcps_data_req_ie_list { + ns_ie_iovec_t *headerIeVectorList; /**< Header IE element list */ + ns_ie_iovec_t *payloadIeVectorList; /**< Payload IE element list */ + uint16_t headerIovLength; /**< Header IE element list size, set 0 when no elements */ + uint16_t payloadIovLength; /**< Payload IE element list size, set 0 when no elements */ +} mcps_data_req_ie_list_t; + + +/** + * @brief struct mcps_ack_data_payload_t IE extension list and payload for enhanced ACK + * + */ +typedef struct mcps_ack_data_payload { + struct mcps_data_req_ie_list ie_elements; /**< IE hader and payload's elements */ + uint8_t *payloadPtr; /**< Ack payload pointer */ + uint16_t payloadLength; /**< Payload length in bytes */ +} mcps_ack_data_payload_t; + /** * @brief struct mcps_purge_t Purge request structure * diff --git a/features/nanostack/sal-stack-nanostack/nanostack/mlme.h b/features/nanostack/sal-stack-nanostack/nanostack/mlme.h index 04fac1576409..111963019223 100644 --- a/features/nanostack/sal-stack-nanostack/nanostack/mlme.h +++ b/features/nanostack/sal-stack-nanostack/nanostack/mlme.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017, Arm Limited and affiliates. + * Copyright (c) 2013-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -264,6 +264,7 @@ typedef enum { macAutoRequestKeyIndex = 0x7b, /*lowpan_info &= ~(INTERFACE_NWK_ROUTER_DEVICE | INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE); - mle_class_mode_set(cur->id, MLE_CLASS_END_DEVICE); mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, true); mac_data_poll_init(cur); arm_nwk_6lowpan_borderrouter_data_free(cur); @@ -358,7 +360,6 @@ void protocol_6lowpan_router_init(protocol_interface_info_entry_t *cur) cur->bootsrap_mode = ARM_NWK_BOOTSRAP_MODE_6LoWPAN_ROUTER; cur->lowpan_info |= INTERFACE_NWK_ROUTER_DEVICE; cur->lowpan_info &= ~INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE; - mle_class_mode_set(cur->id, MLE_CLASS_ROUTER); mac_data_poll_init(cur); arm_nwk_6lowpan_borderrouter_data_free(cur); } @@ -398,6 +399,7 @@ void protocol_6lowpan_register_handlers(protocol_interface_info_entry_t *cur) * for routers, as RPL doesn't deal with it) */ cur->ipv6_neighbour_cache.send_addr_reg = true; cur->ipv6_neighbour_cache.recv_na_aro = true; + cur->ipv6_neighbour_cache.use_eui64_as_slla_in_aro = false; } void protocol_6lowpan_release_short_link_address_from_neighcache(protocol_interface_info_entry_t *cur, uint16_t shortAddress) { @@ -430,28 +432,27 @@ void protocol_6lowpan_release_long_link_address_from_neighcache(protocol_interfa } #ifdef HAVE_6LOWPAN_ND -static int8_t mle_set_link_priority(int8_t interface_id, const uint8_t *address, bool priority) +static int8_t mle_set_link_priority(protocol_interface_info_entry_t *cur, const uint8_t *address, bool priority) { uint8_t mac64[8]; - mle_neigh_table_entry_t *mle_entry; - + mac_neighbor_table_entry_t *entry; if (!memcmp(address, ADDR_SHORT_ADR_SUFFIC, 6)) { - mle_entry = mle_class_get_by_link_address(interface_id, address + 6, ADDR_802_15_4_SHORT); + entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), address + 6, ADDR_802_15_4_SHORT); } else { memcpy(mac64, address, 8); mac64[0] ^= 2; - mle_entry = mle_class_get_by_link_address(interface_id, mac64, ADDR_802_15_4_LONG); + entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), mac64, ADDR_802_15_4_LONG); } - if (!mle_entry) { + if (!entry) { return -1; } if (priority) { - mle_entry->priorityFlag = 1; + entry->link_role = PRIORITY_PARENT_NEIGHBOUR; } else { - mle_entry->priorityFlag = 0; + entry->link_role = NORMAL_NEIGHBOUR; } return 0; } @@ -461,11 +462,11 @@ void protocol_6lowpan_neighbor_priority_update(protocol_interface_info_entry_t * if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) { #ifndef NO_MLE if (removed_priority) { - mle_set_link_priority(cur->id,removed_priority, false); + mle_set_link_priority(cur,removed_priority, false); } if (updated_priority) { - mle_set_link_priority(cur->id, updated_priority, true); + mle_set_link_priority(cur, updated_priority, true); } #endif } @@ -476,30 +477,30 @@ void protocol_6lowpan_neighbor_priority_update(protocol_interface_info_entry_t * uint16_t protocol_6lowpan_neighbor_priority_set(int8_t interface_id, addrtype_t addr_type, const uint8_t *addr_ptr) { - mle_neigh_table_entry_t *neigh_table_ptr; + protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); - if (!addr_ptr) { + if (!cur || !addr_ptr) { return 0; } - neigh_table_ptr = mle_class_get_by_link_address(interface_id, addr_ptr + PAN_ID_LEN, addr_type); + mac_neighbor_table_entry_t * entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), addr_ptr + PAN_ID_LEN, addr_type); - if (neigh_table_ptr) { + if (entry) { + etx_storage_t *etx_entry = etx_storage_entry_get(interface_id, entry->index); // If primary parent has changed clears priority from previous parent - if (!neigh_table_ptr->priorityFlag) { + if (entry->link_role != PRIORITY_PARENT_NEIGHBOUR) { protocol_6lowpan_neighbor_priority_clear_all(interface_id, PRIORITY_1ST); } - neigh_table_ptr->priorityFlag = 1; - - protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); - if (cur) { - uint8_t temp[2]; - common_write_16_bit(neigh_table_ptr->short_adr, temp); - mac_helper_coordinator_address_set(cur, ADDR_802_15_4_SHORT, temp); - mac_helper_coordinator_address_set(cur, ADDR_802_15_4_LONG, neigh_table_ptr->mac64); - } + entry->link_role = PRIORITY_PARENT_NEIGHBOUR; + - protocol_stats_update(STATS_ETX_1ST_PARENT, neigh_table_ptr->etx >> 4); + uint8_t temp[2]; + common_write_16_bit(entry->mac16, temp); + mac_helper_coordinator_address_set(cur, ADDR_802_15_4_SHORT, temp); + mac_helper_coordinator_address_set(cur, ADDR_802_15_4_LONG, entry->mac64); + if (etx_entry) { + protocol_stats_update(STATS_ETX_1ST_PARENT, etx_entry->etx >> 4); + } return 1; } else { return 0; @@ -508,21 +509,26 @@ uint16_t protocol_6lowpan_neighbor_priority_set(int8_t interface_id, addrtype_t uint16_t protocol_6lowpan_neighbor_second_priority_set(int8_t interface_id, addrtype_t addr_type, const uint8_t *addr_ptr) { - mle_neigh_table_entry_t *neigh_table_ptr; - if (!addr_ptr) { + protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); + + if (!cur || !addr_ptr) { return 0; } - neigh_table_ptr = mle_class_get_by_link_address(interface_id, addr_ptr + PAN_ID_LEN, addr_type); + mac_neighbor_table_entry_t * entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), addr_ptr + PAN_ID_LEN, addr_type); - if (neigh_table_ptr) { + if (entry) { + etx_storage_t *etx_entry = etx_storage_entry_get(interface_id, entry->index); // If secondary parent has changed clears priority from previous parent - if (neigh_table_ptr->second_priority_flag == 0) { + if (entry->link_role != SECONDARY_PARENT_NEIGHBOUR) { protocol_6lowpan_neighbor_priority_clear_all(interface_id, PRIORITY_2ND); } - neigh_table_ptr->second_priority_flag = 1; - protocol_stats_update(STATS_ETX_2ND_PARENT, neigh_table_ptr->etx >> 4); + entry->link_role = SECONDARY_PARENT_NEIGHBOUR; + + if (etx_entry) { + protocol_stats_update(STATS_ETX_2ND_PARENT, etx_entry->etx >> 4); + } return 1; } else { return 0; @@ -531,21 +537,22 @@ uint16_t protocol_6lowpan_neighbor_second_priority_set(int8_t interface_id, addr void protocol_6lowpan_neighbor_priority_clear_all(int8_t interface_id, neighbor_priority priority) { - mle_neigh_table_list_t *mle_neigh_table; + protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); - mle_neigh_table = mle_class_active_list_get(interface_id); - if (!mle_neigh_table) { + if (!cur) { return; } + mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list; - ns_list_foreach(mle_neigh_table_entry_t, entry, mle_neigh_table) { - if (priority == PRIORITY_1ST) { - entry->priorityFlag = 0; + ns_list_foreach(mac_neighbor_table_entry_t, entry, mac_table_list) { + if (priority == PRIORITY_1ST && entry->link_role == PRIORITY_PARENT_NEIGHBOUR) { + entry->link_role = NORMAL_NEIGHBOUR; } else { - if (entry->second_priority_flag) { + if (entry->link_role == SECONDARY_PARENT_NEIGHBOUR) { protocol_stats_update(STATS_ETX_2ND_PARENT, 0); + entry->link_role = NORMAL_NEIGHBOUR; } - entry->second_priority_flag = 0; + } } } @@ -558,43 +565,33 @@ void protocol_6lowpan_neighbor_priority_clear_all(int8_t interface_id, neighbor_ int8_t protocol_6lowpan_neighbor_address_state_synch(protocol_interface_info_entry_t *cur, const uint8_t eui64[8], const uint8_t iid[8]) { int8_t ret_val = -1; - if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) { -#ifndef NO_MLE - mle_neigh_table_entry_t *mle_entry = 0; - mle_entry = mle_class_get_by_link_address(cur->id, eui64, ADDR_802_15_4_LONG); - if (mle_entry && !mle_entry->threadNeighbor) { - if (memcmp(iid, ADDR_SHORT_ADR_SUFFIC, 6) == 0) { - iid += 6; - //Set Short Address to MLE - mle_entry->short_adr = common_read_16_bit(iid); - } - if ((mle_entry->mode & MLE_DEV_MASK) == MLE_RFD_DEV) { - if (mle_entry->handshakeReady) { - mle_entry_timeout_refresh(mle_entry); - } - ret_val = 1; - } else { - ret_val = 0; + + mac_neighbor_table_entry_t * entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), eui64, ADDR_802_15_4_LONG); + if (entry) { + if (memcmp(iid, ADDR_SHORT_ADR_SUFFIC, 6) == 0) { + iid += 6; + //Set Short Address to MLE + entry->mac16 = common_read_16_bit(iid); + } + if (!entry->ffd_device) { + if (entry->connected_device) { + mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry, entry->link_lifetime); } + ret_val = 1; + } else { + ret_val = 0; } -#endif - } else { - ret_val = 0; } return ret_val; } int8_t protocol_6lowpan_neighbor_remove(protocol_interface_info_entry_t *cur, uint8_t *address_ptr, addrtype_t type) { - int8_t ret_val = 0; - if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) { -#ifndef NO_MLE - mle_class_remove_neighbour(cur->id, address_ptr, type); -#endif - } else { - //REMOVE Something else + mac_neighbor_table_entry_t * entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), address_ptr, type); + if (entry) { + mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry); } - return ret_val; + return 0; } void protocol_6lowpan_allocate_mac16(protocol_interface_info_entry_t *cur) @@ -739,7 +736,7 @@ uint8_t protocol_6lowpan_beacon_join_priority_tx(int8_t interface_id) mle_6lowpan_data_t *mle_6lowpan_data = protocol_6lowpan_mle_data_get(); if (mle_6lowpan_data && mle_6lowpan_data->nbr_of_neigh_max != 0) { - uint16_t mle_neigh_cnt = mle_class_active_neigh_counter(interface_id); + uint16_t mle_neigh_cnt = mle_class_active_neigh_counter(cur); if (mle_neigh_cnt > mle_6lowpan_data->nbr_of_neigh_lower_threshold) { uint16_t mle_neigh_limit; diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Bootstraps/Generic/protocol_6lowpan_bootstrap.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Bootstraps/Generic/protocol_6lowpan_bootstrap.c index 4be6abcc2811..e8f4fe957712 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Bootstraps/Generic/protocol_6lowpan_bootstrap.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Bootstraps/Generic/protocol_6lowpan_bootstrap.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -69,7 +69,9 @@ #include "mac_api.h" #include "6LoWPAN/MAC/mac_data_poll.h" #include "libNET/src/net_load_balance_internal.h" +#include "6LoWPAN/lowpan_adaptation_interface.h" #include "6LoWPAN/NVM/nwk_nvm.h" +#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h" /* Fixed-point randomisation limits for randlib_randomise_base() - RFC 3315 @@ -90,15 +92,16 @@ static void protocol_6lowpan_bootstrap_rpl_callback(rpl_event_t event, void *han #endif static void protocol_6lowpan_mle_purge_neighbors(struct protocol_interface_info_entry *cur_interface, uint8_t entry_count, uint8_t force_priority); -static uint8_t protocol_6lowpan_mle_order_last_entries(mle_neigh_table_list_t *mle_neigh_table, uint8_t entry_count); +static uint8_t protocol_6lowpan_mle_order_last_entries(int8_t interface_id,mac_neighbor_table_list_t *mac_neigh_table, uint8_t entry_count); static uint8_t protocol_6lowpan_mle_data_allocate(void); static bool mle_accept_request_cb(int8_t interface_id, uint16_t msgId, bool usedAllRetries); static void lowpan_comm_status_indication_cb(int8_t if_id, const mlme_comm_status_t* status); -static void protocol_6lowpan_priority_neighbor_remove(protocol_interface_info_entry_t *cur_interface, mle_neigh_table_entry_t *cur); -static void protocol_6lowpan_neighbor_information_remove(int8_t interface_id, mle_neigh_table_entry_t *cur); -static int8_t protocol_6lowpan_host_challenge(int8_t interface_id, const uint8_t *mac64); -static int8_t protocol_6lowpan_router_challenge(int8_t interface_id, const uint8_t *mac64); +static void protocol_6lowpan_priority_neighbor_remove(protocol_interface_info_entry_t *cur_interface, mac_neighbor_table_entry_t *cur); +static void lowpan_neighbor_entry_remove_notify(mac_neighbor_table_entry_t *entry_ptr, void *user_data); +static bool lowpan_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr, void *user_data); +static bool protocol_6lowpan_router_challenge(protocol_interface_info_entry_t *cur_interface, const uint8_t *mac64); +static bool protocol_6lowpan_host_challenge(protocol_interface_info_entry_t *cur, const uint8_t *mac64); static void protocol_6lowpan_address_reg_ready(protocol_interface_info_entry_t *cur_interface); static void coordinator_black_list(protocol_interface_info_entry_t *cur); @@ -158,9 +161,9 @@ uint8_t *mle_general_write_timeout(uint8_t *ptr, protocol_interface_info_entry_t } -static void protocol_6lowpan_priority_neighbor_remove(protocol_interface_info_entry_t *cur_interface, mle_neigh_table_entry_t *cur) +static void protocol_6lowpan_priority_neighbor_remove(protocol_interface_info_entry_t *cur_interface, mac_neighbor_table_entry_t *cur) { - if (!cur->priorityFlag || + if (cur->link_role != PRIORITY_PARENT_NEIGHBOUR || !(cur_interface->lowpan_info & INTERFACE_NWK_ACTIVE) || cur_interface->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) { return; @@ -176,9 +179,9 @@ static void protocol_6lowpan_priority_neighbor_remove(protocol_interface_info_en } } else { //Call Priority parent loose - if (cur->short_adr != 0xffff) { + if (cur->mac16 != 0xffff) { memcpy(mac64, ADDR_SHORT_ADR_SUFFIC, 6); - common_write_16_bit(cur->short_adr, &mac64[6]); + common_write_16_bit(cur->mac16, &mac64[6]); } else { memcpy(mac64,cur->mac64 , 8); mac64[0] ^= 2; @@ -192,64 +195,42 @@ static void protocol_6lowpan_priority_neighbor_remove(protocol_interface_info_en } } -static void protocol_6lowpan_neighbor_information_remove(int8_t interface_id, mle_neigh_table_entry_t *cur) +static bool protocol_6lowpan_challenge_callback(int8_t interface_id, uint16_t msgId, bool usedAllRetries) { protocol_interface_info_entry_t *cur_interface = protocol_stack_interface_info_get_by_id(interface_id); if (!cur_interface) { - return; - } - - // Sleepy host - if (cur_interface->lowpan_info & INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE) { - mac_data_poll_protocol_poll_mode_decrement(cur_interface); - } - - protocol_6lowpan_priority_neighbor_remove(cur_interface, cur); - - if (cur->mode & MLE_FFD_DEV) { - protocol_6lowpan_release_short_link_address_from_neighcache(cur_interface, cur->short_adr); - protocol_6lowpan_release_long_link_address_from_neighcache(cur_interface, cur->mac64); + return false; } - mac_helper_devicetable_remove(cur_interface->mac_api, cur->attribute_index); -} -static bool protocol_6lowpan_challenge_callback(int8_t interface_id, uint16_t msgId, bool usedAllRetries) -{ uint8_t mac64[8]; uint8_t *ll64_ptr = mle_service_get_msg_destination_address_pointer(msgId); memcpy(mac64, ll64_ptr + 8, 8); mac64[0] ^= 2; - mle_neigh_table_entry_t *neig_info = mle_class_get_by_link_address(interface_id, mac64, ADDR_802_15_4_LONG); + mac_neighbor_table_entry_t * neig_info = mac_neighbor_table_address_discover(mac_neighbor_info(cur_interface), mac64, ADDR_802_15_4_LONG); if (!neig_info) { return false;//Why entry is removed before timeout?? } - if (neig_info->ttl > MLE_TABLE_CHALLENGE_TIMER) { + if (!neig_info->nud_active) { return false; } if (usedAllRetries) { //GET entry - mle_class_remove_entry(interface_id, neig_info); + mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur_interface), neig_info); return false; } return true; } -static int8_t protocol_6lowpan_host_challenge(int8_t interface_id, const uint8_t *mac64) +static bool protocol_6lowpan_host_challenge(protocol_interface_info_entry_t *cur, const uint8_t *mac64) { - protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); - if (!cur) { - return false; - } - - uint16_t bufId; mle_message_timeout_params_t timeout; uint8_t ll64[16]; @@ -261,7 +242,7 @@ static int8_t protocol_6lowpan_host_challenge(int8_t interface_id, const uint8_t tr_debug("Link REQUEST"); bufId = mle_service_msg_allocate(cur->id, 32, true,MLE_COMMAND_REQUEST); if (bufId == 0) { - return -1; + return false; } uint8_t *ptr = mle_service_get_data_pointer(bufId); @@ -293,16 +274,11 @@ static int8_t protocol_6lowpan_host_challenge(int8_t interface_id, const uint8_t mle_service_set_msg_timeout_parameters(bufId, &timeout); mle_service_send_message(bufId); - return 0; + return true; } -static int8_t protocol_6lowpan_router_challenge(int8_t interface_id, const uint8_t *mac64) +static bool protocol_6lowpan_router_challenge(protocol_interface_info_entry_t *cur, const uint8_t *mac64) { - protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); - if (!cur) { - return false; - } - uint16_t bufId; mle_message_timeout_params_t timeout; @@ -315,7 +291,7 @@ static int8_t protocol_6lowpan_router_challenge(int8_t interface_id, const uint8 tr_debug("Link REQUEST"); bufId = mle_service_msg_allocate(cur->id, 32, true,MLE_COMMAND_REQUEST); if (bufId == 0) { - return -1; + return false; } uint8_t *ptr = mle_service_get_data_pointer(bufId); @@ -342,16 +318,16 @@ static int8_t protocol_6lowpan_router_challenge(int8_t interface_id, const uint8 mle_service_set_msg_timeout_parameters(bufId, &timeout); mle_service_send_message(bufId); - return 0; + return true; } -static uint8_t mle_advert_neigh_cnt(int8_t interface_id, bool short_adr) { +static uint8_t mle_advert_neigh_cnt(protocol_interface_info_entry_t *cur_interface, bool short_adr) { uint8_t advert_neigh_cnt; uint8_t neighb_max; - uint8_t mle_neigh_cnt = mle_class_active_neigh_counter(interface_id); + uint8_t mle_neigh_cnt = mle_class_active_neigh_counter(cur_interface); if (short_adr == true) { neighb_max = 16; @@ -413,88 +389,94 @@ static uint8_t mle_link_quality_tlv_parse(uint8_t *mac64, uint16_t short_address return 0; } -static uint8_t *mle_table_set_neighbours(int8_t interface_id, uint8_t *ptr) +static bool neighbor_list_short_address_available(mac_neighbor_table_t *table_class) +{ + ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, &table_class->neighbour_list) { + if (cur_entry->connected_device && cur_entry->mac16 == 0xffff) { + return false; + } + } + return true; +} + + +static uint8_t *mle_table_set_neighbours(protocol_interface_info_entry_t *cur, uint8_t *ptr) { uint8_t *len_ptr = 0; - uint8_t short_temp[2] = {0xff,0xff}; uint8_t neigh_count = 0; uint8_t neigh_count_max = 0; uint8_t *link_flags_ptr; - mle_neigh_table_entry_t *first_entry_ptr = NULL; - bool loop_list = false; + mac_neighbor_table_entry_t *first_entry_ptr = NULL; - mle_neigh_table_list_t * neigh_list = mle_class_active_list_get(interface_id); - if (!neigh_list) { - return ptr; - } + mac_neighbor_table_list_t * neigh_list = &cur->mac_parameters->mac_neighbor_table->neighbour_list; *ptr++ = MLE_TYPE_LINK_QUALITY; len_ptr = ptr++; *len_ptr = 1; - // defaults: complete, 2 bytes long link-layer address - link_flags_ptr = ptr++; - *link_flags_ptr = 0x81; - if (mle_class_get_by_link_address(interface_id, short_temp,ADDR_802_15_4_SHORT)) { - *link_flags_ptr |= 0x07; - neigh_count_max = mle_advert_neigh_cnt(interface_id, false); + link_flags_ptr = ptr++; + //*link_flags_ptr = 0x81; + bool use_short_address_compression = neighbor_list_short_address_available(mac_neighbor_info(cur)); + if (use_short_address_compression) { + //complete, 2 bytes long link-layer address + *link_flags_ptr = 0x81; } else { - neigh_count_max = mle_advert_neigh_cnt(interface_id, true); - } + //complete, 8 bytes long link-layer address + *link_flags_ptr = 0x87; - do { - ns_list_foreach(mle_neigh_table_entry_t, cur, neigh_list) - { + } + neigh_count_max = mle_advert_neigh_cnt(cur, use_short_address_compression); - loop_list = false; + bool clean_entries = false; + ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, neigh_list) + { - if ((cur->handshakeReady) && (cur->link_q_adv_sent == false)) { + if ((cur_entry->connected_device) && (cur_entry->advertisment == false)) { - // If looping list, stops adding entries when at first sent entry again - if (first_entry_ptr == cur) { - break; - } else if (first_entry_ptr == NULL) { - first_entry_ptr = cur; - } + // If looping list, stops adding entries when at first sent entry again + if (first_entry_ptr == cur_entry) { + break; + } else if (first_entry_ptr == NULL) { + first_entry_ptr = cur_entry; + } - // Limits the number of entries that are sent - if (++neigh_count > neigh_count_max) { - *link_flags_ptr &= 0x7f; - break; - } + // Limits the number of entries that are sent + if (++neigh_count > neigh_count_max) { + *link_flags_ptr &= 0x7f; + break; + } - if (cur->priorityFlag) { - *ptr++ = MLE_NEIGHBOR_PRIORITY_LINK | MLE_NEIGHBOR_INCOMING_LINK | MLE_NEIGHBOR_OUTGOING_LINK; - } else { - *ptr++ = MLE_NEIGHBOR_INCOMING_LINK | MLE_NEIGHBOR_OUTGOING_LINK; - } + if (cur_entry->link_role == PRIORITY_PARENT_NEIGHBOUR) { + *ptr++ = MLE_NEIGHBOR_PRIORITY_LINK | MLE_NEIGHBOR_INCOMING_LINK | MLE_NEIGHBOR_OUTGOING_LINK; + } else { + *ptr++ = MLE_NEIGHBOR_INCOMING_LINK | MLE_NEIGHBOR_OUTGOING_LINK; + } - *ptr++ = etx_local_incoming_idr_read(interface_id, cur) >> 3; + *ptr++ = etx_local_incoming_idr_read(cur->id, cur_entry->index) >> 3; - if ((*link_flags_ptr & 0x07) == 1) { - ptr = common_write_16_bit(cur->short_adr, ptr); - *len_ptr += 4; - } else { - memcpy(ptr, cur->mac64, 8); - ptr += 8; - *len_ptr += 10; - } + if (use_short_address_compression) { + ptr = common_write_16_bit(cur_entry->mac16, ptr); + *len_ptr += 4; + } else { + memcpy(ptr, cur_entry->mac64, 8); + ptr += 8; + *len_ptr += 10; + } - // If end of the neighbor list, start adding entries from start again - if (cur->link.next == 0) { - loop_list = true; - mle_neigh_table_list_t * neigh_temp = mle_class_active_list_get(interface_id); - ns_list_foreach(mle_neigh_table_entry_t, temp, neigh_temp) - { - // Marks entries not sent - temp->link_q_adv_sent = false; - } - } else { - cur->link_q_adv_sent = true; - } + // If end of the neighbor list, Mark a clean advertisment from the list + if (cur_entry->link.next == 0) { + clean_entries = true; } + cur_entry->advertisment = true; + } + } + + if (clean_entries) { + ns_list_foreach(mac_neighbor_table_entry_t, temp, neigh_list) { + // Marks entries not sent + temp->advertisment = false; } - } while (loop_list); + } return ptr; } @@ -515,10 +497,10 @@ static int protocol_6lowpan_mle_neigh_advertise(protocol_interface_info_entry_t return 0; } - if (mle_class_get_by_link_address(cur->id, short_temp,ADDR_802_15_4_SHORT)) { - neig_cache_size += mle_advert_neigh_cnt(cur->id, false) * 10; + if (mac_neighbor_table_address_discover(mac_neighbor_info(cur), short_temp,ADDR_802_15_4_SHORT)) { + neig_cache_size += mle_advert_neigh_cnt(cur, false) * 10; } else { - neig_cache_size += mle_advert_neigh_cnt(cur->id, true) << 2; + neig_cache_size += mle_advert_neigh_cnt(cur, true) << 2; } uint16_t bufId = mle_service_msg_allocate(cur->id, neig_cache_size, false, MLE_COMMAND_ADVERTISEMENT); @@ -539,7 +521,7 @@ static int protocol_6lowpan_mle_neigh_advertise(protocol_interface_info_entry_t ptr = mle_service_get_data_pointer(bufId); ptr = mle_general_write_source_address(ptr, cur); ptr = mle_tlv_write_mode(ptr, lowpan_mode_get_by_interface_ptr(cur)); - ptr = mle_table_set_neighbours(cur->id, ptr); + ptr = mle_table_set_neighbours(cur, ptr); if (mle_service_update_length_by_ptr(bufId,ptr)!= 0) { tr_debug("Buffer overflow at message write"); @@ -549,15 +531,6 @@ static int protocol_6lowpan_mle_neigh_advertise(protocol_interface_info_entry_t } #endif -static uint8_t compute_link_margin(int8_t rssi) -{ - if (rssi < -94) { - return 0; - } - - return (rssi + 94); -} - static int mle_validate_6lowpan_link_request_message(uint8_t *ptr, uint16_t data_len, mle_tlv_info_t *tlv_info) { /** @@ -571,8 +544,11 @@ static int mle_validate_6lowpan_link_request_message(uint8_t *ptr, uint16_t data return 0; } -static void mle_neigh_time_and_mode_update(mle_neigh_table_entry_t *entry_temp, uint8_t *tlv_ptr, uint16_t tlv_length) +static void mle_neigh_time_and_mode_update(mac_neighbor_table_entry_t *entry_temp, mle_message_t *mle_msg) { + uint8_t *tlv_ptr = mle_msg->data_ptr; + uint16_t tlv_length = mle_msg->data_length; + mle_tlv_info_t mle_tlv_info; uint32_t timeout_tlv; @@ -580,42 +556,44 @@ static void mle_neigh_time_and_mode_update(mle_neigh_table_entry_t *entry_temp, return; } + protocol_interface_info_entry_t *cur = mle_msg->interface_ptr; + if (mle_tlv_option_discover(tlv_ptr, tlv_length, MLE_TYPE_MODE, &mle_tlv_info) > 0) { uint8_t *t_ptr = mle_tlv_info.dataPtr; - entry_temp->mode = *t_ptr; + mle_mode_parse_to_mac_entry(entry_temp, *t_ptr); } if (mle_tlv_option_discover(tlv_ptr, tlv_length, MLE_TYPE_TIMEOUT, &mle_tlv_info) > 0) { timeout_tlv = common_read_32_bit(mle_tlv_info.dataPtr); } else { - if (entry_temp->mode & MLE_FFD_DEV) { + if (entry_temp->ffd_device) { timeout_tlv = mle_6lowpan_data->router_lifetime; } else { timeout_tlv = mle_6lowpan_data->host_lifetime; } } - mle_entry_timeout_update(entry_temp, timeout_tlv); + mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, timeout_tlv); } -static void mle_neigh_entry_update_by_mle_tlv_list(int8_t interface_id, mle_neigh_table_entry_t *entry_temp, uint8_t *tlv_ptr, uint16_t tlv_length, uint8_t *mac64, uint16_t short_address) +static void mle_neigh_entry_update_by_mle_tlv_list(int8_t interface_id, mac_neighbor_table_entry_t *entry_temp, uint8_t *tlv_ptr, uint16_t tlv_length, uint8_t *mac64, uint16_t short_address) { mle_tlv_info_t mle_tlv_info; if (tlv_length) { if (mle_tlv_option_discover(tlv_ptr, tlv_length, MLE_TYPE_SRC_ADDRESS, &mle_tlv_info) > 0) { - entry_temp->short_adr = common_read_16_bit(mle_tlv_info.dataPtr); + entry_temp->mac16 = common_read_16_bit(mle_tlv_info.dataPtr); } if (mle_tlv_option_discover(tlv_ptr, tlv_length, MLE_TYPE_LINK_QUALITY, &mle_tlv_info) > 0) { uint8_t link_idr; uint8_t iop_flags; if (mle_link_quality_tlv_parse(mac64, short_address, mle_tlv_info.dataPtr, mle_tlv_info.tlvLen, &iop_flags, &link_idr)) { - etx_remote_incoming_idr_update(interface_id, link_idr, entry_temp); + etx_remote_incoming_idr_update(interface_id, link_idr, entry_temp->index); if ((iop_flags & MLE_NEIGHBOR_PRIORITY_LINK) == MLE_NEIGHBOR_PRIORITY_LINK) { - entry_temp->priority_child_flag = true; - } else { - entry_temp->priority_child_flag = false; + entry_temp->link_role = CHILD_NEIGHBOUR; + } else if (entry_temp->link_role == CHILD_NEIGHBOUR) { + entry_temp->link_role = NORMAL_NEIGHBOUR; } } } @@ -758,10 +736,10 @@ static int mle_router_accept_request_build(protocol_interface_info_entry_t *cur, static void protocol_6lowpan_link_reject_handler(protocol_interface_info_entry_t *cur, uint8_t *ll64) { - mle_neigh_table_entry_t *entry_temp = mle_class_get_entry_by_ll64(cur->id, 0, ll64, false, NULL); + mac_neighbor_table_entry_t *mac_entry = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), ll64, false, NULL); tr_debug("MLE link reject"); - if (entry_temp) { - mle_class_remove_entry(cur->id, entry_temp); + if (mac_entry) { + mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), mac_entry); } } @@ -984,14 +962,16 @@ int protocol_6lowpan_router_synch_to_new_router(protocol_interface_info_entry_t } -static uint8_t mle_calculate_idr(int8_t interface_id, mle_message_t *mle_msg, mle_neigh_table_entry_t *entry_temp) +static uint8_t mle_calculate_idr(int8_t interface_id, mle_message_t *mle_msg, mac_neighbor_table_entry_t *entry_temp) { - - return etx_lqi_dbm_update(interface_id, mle_msg->lqi, mle_msg->dbm, entry_temp) >> 3; + if (!entry_temp) { + return etx_lqi_dbm_update(-2, mle_msg->lqi, mle_msg->dbm, 0) >> 3; + } + return etx_lqi_dbm_update(interface_id, mle_msg->lqi, mle_msg->dbm, entry_temp->index) >> 3; } -static bool mle_6lowpan_neighbor_limit_check(int8_t interface_id, mle_message_t *mle_msg, uint8_t only_max_limit_chk) +static bool mle_6lowpan_neighbor_limit_check(mle_message_t *mle_msg, uint8_t only_max_limit_chk) { uint16_t mle_neigh_cnt; bool link_quality = false; @@ -1000,7 +980,7 @@ static bool mle_6lowpan_neighbor_limit_check(int8_t interface_id, mle_message_t return true; } - mle_neigh_cnt = mle_class_active_neigh_counter(interface_id); + mle_neigh_cnt = mle_class_active_neigh_counter(mle_msg->interface_ptr); // Neighbor max limit if (mle_neigh_cnt >= mle_6lowpan_data->nbr_of_neigh_max) { @@ -1048,17 +1028,11 @@ void mle_6lowpan_message_handler(int8_t interface_id, mle_message_t *mle_msg, ml uint8_t mode = 0x0a; mle_tlv_info_t mle_tlv_info; mle_tlv_info_t mle_challenge; - mle_neigh_table_entry_t *entry_temp; - uint8_t linkMargin; + mac_neighbor_table_entry_t *entry_temp; uint8_t incoming_idr; uint16_t responseId, own_mac16; - protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); - if (!cur) { - return; - } + protocol_interface_info_entry_t *cur = mle_msg->interface_ptr; - //Calculate link margin - linkMargin = compute_link_margin(mle_msg->dbm); own_mac16 = mac_helper_mac16_address_get(cur); @@ -1081,13 +1055,13 @@ void mle_6lowpan_message_handler(int8_t interface_id, mle_message_t *mle_msg, ml mle_6lowpan_data->link_req_token_bucket--; } else { //Update only old information based on link request - entry_temp = mle_class_get_entry_by_ll64(interface_id, linkMargin, mle_msg->packet_src_address, false, NULL); + entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL); if (entry_temp) { - mle_neigh_time_and_mode_update(entry_temp,mle_msg->data_ptr, mle_msg->data_length); + mle_neigh_time_and_mode_update(entry_temp,mle_msg); mle_neigh_entry_update_by_mle_tlv_list(interface_id, entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur->mac, own_mac16); mle_neigh_entry_frame_counter_update(entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur, security_headers->KeyIndex); } else { - if (!mle_6lowpan_neighbor_limit_check(interface_id, mle_msg, false)) { + if (!mle_6lowpan_neighbor_limit_check(mle_msg, false)) { return; } } @@ -1095,7 +1069,7 @@ void mle_6lowpan_message_handler(int8_t interface_id, mle_message_t *mle_msg, ml incoming_idr = mle_calculate_idr(interface_id, mle_msg, entry_temp); - if (entry_temp && entry_temp->handshakeReady) { + if (entry_temp && entry_temp->connected_device) { response_type = MLE_COMMAND_ACCEPT; } else { response_type = MLE_COMMAND_ACCEPT_AND_REQUEST; @@ -1117,13 +1091,11 @@ void mle_6lowpan_message_handler(int8_t interface_id, mle_message_t *mle_msg, ml } tr_debug("Accept & Request"); - - entry_temp = mle_class_get_entry_by_ll64(interface_id, linkMargin, mle_msg->packet_src_address, false, NULL); - + entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL); if (!entry_temp) { // If there is space for neighbors try to allocate new entry - if (mle_6lowpan_neighbor_limit_check(interface_id, mle_msg, true)) { - entry_temp = mle_class_get_entry_by_ll64(interface_id, linkMargin, mle_msg->packet_src_address, true, NULL); + if (mle_6lowpan_neighbor_limit_check(mle_msg, true)) { + entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, true, NULL); } } @@ -1137,23 +1109,22 @@ void mle_6lowpan_message_handler(int8_t interface_id, mle_message_t *mle_msg, ml //Response state set now timeout know positive state mle_service_set_msg_response_true(responseId); - - entry_temp->threadNeighbor = false; - entry_temp->handshakeReady = 1; + entry_temp->connected_device = 1; mac_data_poll_protocol_poll_mode_decrement(cur); //Read Source address and Challenge - mle_neigh_time_and_mode_update(entry_temp,mle_msg->data_ptr, mle_msg->data_length); + mle_neigh_time_and_mode_update(entry_temp,mle_msg); if (mle_msg->message_type == MLE_COMMAND_ACCEPT_AND_REQUEST) { // If no global address set priority (bootstrap ongoing) if (!cur->global_address_available) { - entry_temp->priorityFlag = true; + entry_temp->link_role = PRIORITY_PARENT_NEIGHBOUR; } mle_neigh_entry_update_by_mle_tlv_list(cur->id, entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur->mac, own_mac16); incoming_idr = mle_calculate_idr(cur->id, mle_msg, entry_temp); - mle_router_accept_request_build(cur, mle_msg, mle_challenge.dataPtr, mle_challenge.tlvLen, MLE_COMMAND_ACCEPT, incoming_idr, entry_temp->priorityFlag); + uint8_t priority = (entry_temp->link_role == PRIORITY_PARENT_NEIGHBOUR); + mle_router_accept_request_build(cur, mle_msg, mle_challenge.dataPtr, mle_challenge.tlvLen, MLE_COMMAND_ACCEPT, incoming_idr, priority); } else { mle_neigh_entry_update_by_mle_tlv_list(cur->id, entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur->mac, own_mac16); incoming_idr = mle_calculate_idr(cur->id, mle_msg, entry_temp); @@ -1161,7 +1132,7 @@ void mle_6lowpan_message_handler(int8_t interface_id, mle_message_t *mle_msg, ml mle_neigh_entry_frame_counter_update(entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur, security_headers->KeyIndex); // If MLE frame counter was invalid update its value since three way handshake is complete if (security_headers->invalid_frame_counter) { - entry_temp->mle_frame_counter = security_headers->frameCounter; + mle_service_frame_counter_entry_add(interface_id, entry_temp->index, security_headers->frameCounter); } break; @@ -1184,12 +1155,11 @@ void mle_6lowpan_message_handler(int8_t interface_id, mle_message_t *mle_msg, ml t_ptr = mle_tlv_info.dataPtr; mode = *t_ptr; } - - entry_temp = mle_class_get_entry_by_ll64(interface_id, linkMargin, mle_msg->packet_src_address, false, NULL); + entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL); if (!entry_temp) { if ((mode & MLE_DEV_MASK) == MLE_FFD_DEV) { // If there is space for neighbors synchronizes to new router - if (mle_6lowpan_neighbor_limit_check(interface_id, mle_msg, false)) { + if (mle_6lowpan_neighbor_limit_check(mle_msg, false)) { // Checks blacklist if (blacklist_reject(mle_msg->packet_src_address)) { return; @@ -1220,7 +1190,7 @@ void mle_6lowpan_message_handler(int8_t interface_id, mle_message_t *mle_msg, ml //Possible remove if ((mode & MLE_DEV_MASK) == MLE_RFD_DEV) { //Remove Entry - mle_class_remove_entry(cur->id, entry_temp); + mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry_temp); tr_error("MLE adv: Own address not found"); return; } @@ -1232,8 +1202,8 @@ void mle_6lowpan_message_handler(int8_t interface_id, mle_message_t *mle_msg, ml //UPDATE mle_neigh_entry_update_by_mle_tlv_list(cur->id,entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur->mac, own_mac16); mle_neigh_entry_frame_counter_update(entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur, security_headers->KeyIndex); - if (entry_temp->handshakeReady) { - mle_entry_timeout_refresh(entry_temp); + if (entry_temp->connected_device) { + mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, entry_temp->link_lifetime); } } break; @@ -1250,7 +1220,7 @@ int8_t arm_6lowpan_mle_service_ready_for_security_init(protocol_interface_info_e //validate MLE service if (!mle_service_interface_registeration_validate(cur->id)) { //Register - if (mle_service_interface_register(cur->id,mle_6lowpan_message_handler, cur->mac,8) != 0) { + if (mle_service_interface_register(cur->id,cur, mle_6lowpan_message_handler, cur->mac,8) != 0) { tr_error("Mle Service init Fail"); return -1; } @@ -1301,29 +1271,24 @@ mle_6lowpan_data_t *protocol_6lowpan_mle_data_get(void) static void protocol_6lowpan_mle_purge_neighbors(struct protocol_interface_info_entry *cur_interface, uint8_t entry_count, uint8_t force_priority) { - mle_neigh_table_list_t *mle_neigh_table; + uint8_t count = 0; uint8_t ll64[16]; if (!cur_interface) { return; } + mac_neighbor_table_list_t *mac_table_list = &cur_interface->mac_parameters->mac_neighbor_table->neighbour_list; - mle_neigh_table = mle_class_active_list_get(cur_interface->id); + entry_count = protocol_6lowpan_mle_order_last_entries(cur_interface->id, mac_table_list, entry_count); - if (!mle_neigh_table) { - return; - } - - entry_count = protocol_6lowpan_mle_order_last_entries(mle_neigh_table, entry_count); - - ns_list_foreach_reverse_safe(mle_neigh_table_entry_t, entry, mle_neigh_table) { + ns_list_foreach_reverse_safe(mac_neighbor_table_entry_t, entry, mac_table_list) { if (++count > entry_count) { break; } if (!force_priority) { - if (entry->priorityFlag || entry->priority_child_flag) { + if (entry->link_role == PRIORITY_PARENT_NEIGHBOUR || entry->link_role == CHILD_NEIGHBOUR) { break; } } @@ -1336,23 +1301,23 @@ static void protocol_6lowpan_mle_purge_neighbors(struct protocol_interface_info_ // Sends REJECT mle_service_reject_message_build(cur_interface->id, ll64, false); - mle_class_remove_entry(cur_interface->id, entry); + mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur_interface), entry); // Adds purged neighbor to blacklist so that it is not added right away back from advertisement blacklist_update(ll64, false); } } -static uint8_t protocol_6lowpan_mle_order_last_entries(mle_neigh_table_list_t *mle_neigh_table, uint8_t entry_count) +static uint8_t protocol_6lowpan_mle_order_last_entries(int8_t interface_id, mac_neighbor_table_list_t *mac_neigh_table, uint8_t entry_count) { - mle_neigh_table_entry_t *last; - mle_neigh_table_entry_t *first_ordered = NULL; + mac_neighbor_table_entry_t *last; + mac_neighbor_table_entry_t *first_ordered = NULL; + etx_storage_t * etx_last, *etx_cur; uint8_t count = 0; - do { last = NULL; - ns_list_foreach(mle_neigh_table_entry_t, entry, mle_neigh_table) { + ns_list_foreach(mac_neighbor_table_entry_t, entry, mac_neigh_table) { if (entry == first_ordered) { break; @@ -1363,37 +1328,27 @@ static uint8_t protocol_6lowpan_mle_order_last_entries(mle_neigh_table_list_t *m continue; } - // Primary parent (parent selected for bootstrap or RPL primary parent) - if (entry->priorityFlag && !last->priorityFlag) { - continue; - } - - // Secondary parent (RPL secondary parent) - if (entry->second_priority_flag && !last->second_priority_flag) { - continue; - } - - // Uses this node as parent - if (entry->priority_child_flag && !last->priority_child_flag) { - continue; - } - - // Better ETX - if (entry->etx <= last->etx) { + if (entry->link_role > last->link_role) { //Bigger link role is allways better continue; + } else if (entry->link_role == last->link_role) { + // Compare ETX when Link role is same + etx_cur = etx_storage_entry_get(interface_id, entry->index); + etx_last = etx_storage_entry_get(interface_id, last->index); + if (etx_cur && etx_last && etx_cur->etx <= etx_last->etx) { + continue; + } } - last = entry; } // Sets last to end of list if (last) { - ns_list_remove(mle_neigh_table, last); + ns_list_remove(mac_neigh_table, last); if (first_ordered) { - ns_list_add_before(mle_neigh_table, first_ordered, last); + ns_list_add_before(mac_neigh_table, first_ordered, last); } else { - ns_list_add_to_end(mle_neigh_table, last); + ns_list_add_to_end(mac_neigh_table, last); } first_ordered = last; @@ -1431,10 +1386,11 @@ static int8_t arm_6lowpan_bootstrap_down(protocol_interface_info_entry_t *cur) static void lowpan_mle_receive_security_bypass_cb(int8_t interface_id, mle_message_t *mle_msg) { + (void) interface_id; #ifdef PANA - protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id); + protocol_interface_info_entry_t *interface = mle_msg->interface_ptr; //Accept Only Link Reject - if (interface && mle_msg->message_type == MLE_COMMAND_REJECT) { + if (mle_msg->message_type == MLE_COMMAND_REJECT) { if ((interface->lowpan_info & (INTERFACE_NWK_BOOTSRAP_ACTIVE | INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION)) != (INTERFACE_NWK_BOOTSRAP_ACTIVE | INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION)) { return; @@ -1508,7 +1464,7 @@ static int8_t arm_6lowpan_bootstrap_up(protocol_interface_info_entry_t *cur) if (!mle_service_interface_registeration_validate(cur->id)) { //Register - if (mle_service_interface_register(cur->id,mle_6lowpan_message_handler, cur->mac,8) != 0) { + if (mle_service_interface_register(cur->id, cur, mle_6lowpan_message_handler, cur->mac,8) != 0) { tr_error("Mle Service init Fail"); return -1; } @@ -1594,7 +1550,6 @@ int8_t arm_network_processor_up(protocol_interface_info_entry_t *cur) } else { protocol_6lowpan_register_handlers(cur); mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, true); - mle_class_mode_set(cur->id, MLE_CLASS_ROUTER); mac_helper_default_security_level_set(cur, SEC_NONE); if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_RF_SNIFFER) { @@ -1621,15 +1576,6 @@ int8_t arm_network_processor_up(protocol_interface_info_entry_t *cur) return ret_val; } -static bool lowpan_interface_is_active(int8_t interface_id) { - protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); - if (!cur || !(cur->lowpan_info & INTERFACE_NWK_ACTIVE)) { - return false; - } - - return true; -} - static void arm_6lowpan_security_key_update_cb(protocol_interface_info_entry_t *cur, const mlme_security_t *security_params) { if (cur->mac_parameters->mac_next_key_index && (security_params->KeyIndex == cur->mac_parameters->mac_next_key_index)) { @@ -1641,6 +1587,66 @@ static void arm_6lowpan_security_key_update_cb(protocol_interface_info_entry_t * } } } + +static void lowpan_neighbor_entry_remove_notify(mac_neighbor_table_entry_t *entry_ptr, void *user_data) +{ + + protocol_interface_info_entry_t *cur_interface = user_data; + lowpan_adaptation_remove_free_indirect_table(cur_interface, entry_ptr); + // Sleepy host + if (cur_interface->lowpan_info & INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE) { + mac_data_poll_protocol_poll_mode_decrement(cur_interface); + } + + protocol_6lowpan_priority_neighbor_remove(cur_interface, entry_ptr); + + if (entry_ptr->ffd_device) { + protocol_6lowpan_release_short_link_address_from_neighcache(cur_interface, entry_ptr->mac16); + protocol_6lowpan_release_long_link_address_from_neighcache(cur_interface, entry_ptr->mac64); + } + mac_helper_devicetable_remove(cur_interface->mac_api, entry_ptr->index); + //Removes ETX neighbor + etx_neighbor_remove(cur_interface->id, entry_ptr->index); + //Remove MLE frame counter info + mle_service_frame_counter_entry_delete(cur_interface->id, entry_ptr->index); + +} + + +static bool lowpan_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr, void *user_data) +{ + + // Sleepy host + protocol_interface_info_entry_t *cur_interface = user_data; + + if (cur_interface->lowpan_info & INTERFACE_NWK_ROUTER_DEVICE) { + //Trig middle way challenge if Broadcast message have been missed + if (!entry_ptr->ffd_device) { + return false; //End device must do this + } + + if (entry_ptr->lifetime > (entry_ptr->link_lifetime / 2)) { + return false; //Trig only when midway is overed + } + return protocol_6lowpan_router_challenge(cur_interface, entry_ptr->mac64); + } + + if (entry_ptr->link_role != PRIORITY_PARENT_NEIGHBOUR) { + return false; //Do not never challenge than priority parent + } + + if (cur_interface->lowpan_info & INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE) { + return false; //Sleepy end device should not never challenge + } + + if (entry_ptr->lifetime > MLE_TABLE_CHALLENGE_TIMER) { + return false; + } + + return protocol_6lowpan_host_challenge(cur_interface, entry_ptr->mac64); +} + + int8_t arm_6lowpan_bootstarp_bootstrap_set(int8_t interface_id, net_6lowpan_mode_e bootstrap_mode, net_6lowpan_mode_extension_e net_6lowpan_mode_extension) { int8_t ret_val = -1; @@ -1665,20 +1671,29 @@ int8_t arm_6lowpan_bootstarp_bootstrap_set(int8_t interface_id, net_6lowpan_mode cur->mac_security_key_usage_update_cb = arm_6lowpan_security_key_update_cb; //Allocate MLE class here //Deallocate old here + mac_neighbor_table_delete(mac_neighbor_info(cur)); + mac_description_storage_size_t buffer; + //Read MAC device table sizes + if (cur->mac_api->mac_storage_sizes_get(cur->mac_api, &buffer) != 0) { + return -1; + } - mle_class_deallocate(interface_id); + mac_neighbor_info(cur) = mac_neighbor_table_create(buffer.device_decription_table_size, lowpan_neighbor_entry_remove_notify + , lowpan_neighbor_entry_nud_notify, cur); + if (!mac_neighbor_info(cur)) { + return -1; + } if (enable_mle_protocol) { - - mac_description_storage_size_t buffer; - //Read MAC device table sizes - if (cur->mac_api->mac_storage_sizes_get(cur->mac_api, &buffer) != 0) { + if (mle_service_frame_counter_table_allocate(interface_id, buffer.device_decription_table_size)) { return -1; } - if (mle_class_init(interface_id, buffer.device_decription_table_size, &protocol_6lowpan_neighbor_information_remove, &protocol_6lowpan_host_challenge, &lowpan_interface_is_active) != 0) { + + if (!etx_storage_list_allocate(cur->id, buffer.device_decription_table_size)) { return -1; } - mle_class_router_challenge(interface_id, protocol_6lowpan_router_challenge); + + lowpan_adaptation_interface_etx_update_enable(cur->id); } mle_service_interface_unregister(cur->id); @@ -1704,7 +1719,7 @@ int8_t arm_6lowpan_bootstarp_bootstrap_set(int8_t interface_id, net_6lowpan_mode return -2; #else cur->comm_status_ind_cb = lowpan_comm_status_indication_cb; - if (mle_service_interface_register(cur->id,mle_6lowpan_message_handler, cur->mac,8) != 0) { + if (mle_service_interface_register(cur->id, cur, mle_6lowpan_message_handler, cur->mac,8) != 0) { tr_error("Mle Service init Fail"); return -1; } @@ -1906,7 +1921,7 @@ void protocol_6lowpan_link_advertise_handle(nd_router_t *cur, protocol_interface cur->mle_purge_timer -= 1; } else { if (mle_6lowpan_data && mle_6lowpan_data->nbr_of_neigh_max != 0) { - uint16_t mle_neigh_cnt = mle_class_active_neigh_counter(cur_interface->id); + uint16_t mle_neigh_cnt = mle_class_active_neigh_counter(cur_interface); if (mle_neigh_cnt > (mle_6lowpan_data->nbr_of_neigh_max - MLE_NEIGHBOR_PURGE_NBR)) { protocol_6lowpan_mle_purge_neighbors(cur_interface, MLE_NEIGHBOR_PURGE_NBR, true); } @@ -1946,15 +1961,15 @@ static void protocol_6lowpan_nd_ready(protocol_interface_info_entry_t *cur) if ((cur->lowpan_info & (INTERFACE_NWK_ROUTER_DEVICE | INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE | INTERFACE_NWK_BOOTSRAP_MLE)) == INTERFACE_NWK_BOOTSRAP_MLE) { //TRIG Only Normal Host #ifndef NO_MLE - //GET Cordinaotor MLE Entry + //GET Cordinator MLE Entry addrtype_t addrType; uint8_t tempAddr[8]; addrType = mac_helper_coordinator_address_get(cur, tempAddr); + mac_neighbor_table_entry_t * neig_info = mac_neighbor_table_address_discover(mac_neighbor_info(cur), tempAddr, addrType); - mle_neigh_table_entry_t *entry_t = mle_class_get_by_link_address(cur->id, tempAddr, addrType); - if (entry_t) { - if (entry_t->ttl > MLE_TABLE_CHALLENGE_TIMER) { - entry_t->ttl = (MLE_TABLE_CHALLENGE_TIMER + 1); + if (neig_info) { + if (neig_info->lifetime > MLE_TABLE_CHALLENGE_TIMER) { + neig_info->lifetime = (MLE_TABLE_CHALLENGE_TIMER + 1); } } #endif @@ -2175,7 +2190,6 @@ void nwk_6lowpan_nd_address_registartion_ready(protocol_interface_info_entry_t * if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_SLEEPY_HOST) { cur->lowpan_info |= INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE; tr_debug("Enable Poll state"); - mle_class_mode_set(cur->id, MLE_CLASS_SLEEPY_END_DEVICE); mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, false); mac_data_poll_init(cur); mac_data_poll_init_protocol_poll(cur); @@ -2753,12 +2767,13 @@ static void protocol_6lowpan_generate_link_reject(protocol_interface_info_entry_ static void lowpan_comm_status_indication_cb(int8_t if_id, const mlme_comm_status_t* status) { -#ifndef NO_MLE protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(if_id); if (!cur) { return; } + mac_neighbor_table_entry_t * entry_ptr; + switch (status->status) { case MLME_UNSUPPORTED_SECURITY: case MLME_UNAVAILABLE_KEY: @@ -2775,29 +2790,33 @@ static void lowpan_comm_status_indication_cb(int8_t if_id, const mlme_comm_statu break; case MLME_DATA_POLL_NOTIFICATION: - mle_refresh_entry_timeout(if_id, status->SrcAddr, (addrtype_t)status->SrcAddrMode, false); + entry_ptr = mac_neighbor_table_address_discover(mac_neighbor_info(cur), status->SrcAddr, status->SrcAddrMode); + if (entry_ptr) { + // Refresh Timeout + mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_ptr, entry_ptr->link_lifetime); + } break; default: break; } -#endif } bool lowpan_neighbour_data_clean(int8_t interface_id, const uint8_t *link_local_address) { + + protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); + if (!cur) { + return false; + } bool return_value = false; -#ifndef NO_MLE - mle_neigh_table_entry_t * neigh_entry = mle_class_get_entry_by_ll64(interface_id, 0, link_local_address, false, NULL); + mac_neighbor_table_entry_t *neigh_entry = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), link_local_address, false, NULL); if (neigh_entry) { //Remove entry - if (neigh_entry->priorityFlag) { - return_value = true; - } else if (neigh_entry->second_priority_flag) { + if (neigh_entry->link_role == PRIORITY_PARENT_NEIGHBOUR || neigh_entry->link_role == SECONDARY_PARENT_NEIGHBOUR) { return_value = true; } - mle_class_remove_entry(interface_id, neigh_entry); + mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), neigh_entry); } -#endif return return_value; } diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Bootstraps/Generic/protocol_6lowpan_interface.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Bootstraps/Generic/protocol_6lowpan_interface.c index 478d86ecafbe..d3b0d16520be 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Bootstraps/Generic/protocol_6lowpan_interface.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Bootstraps/Generic/protocol_6lowpan_interface.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -37,6 +37,7 @@ #include "6LoWPAN/Bootstraps/protocol_6lowpan_bootstrap.h" #include "Service_Libs/blacklist/blacklist.h" #include "6LoWPAN/MAC/mac_helper.h" +#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h" #include "mac_api.h" #ifdef HAVE_RPL @@ -66,6 +67,7 @@ #include "platform/arm_hal_interrupt.h" #include "common_functions.h" #include "mac_api.h" +#include "6LoWPAN/MAC/mpx_api.h" #include "6LoWPAN/lowpan_adaptation_interface.h" #include "6LoWPAN/Fragmentation/cipv6_fragmenter.h" #include "libNET/src/net_load_balance_internal.h" @@ -80,12 +82,14 @@ static int8_t set_6lowpan_nwk_down(protocol_interface_info_entry_t *cur) /* Change Active -> Idle */ /* Disable Protocols Timers */ if (!thread_info(cur)) { - if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) { + mac_neighbor_table_neighbor_list_clean(mac_neighbor_info(cur)); #ifndef NO_MLE - mle_class_list_clean(cur->id); + if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) { + blacklist_clear(); -#endif + } +#endif } if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION) { pana_reset_values(cur->mac_parameters->pan_id); diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Bootstraps/protocol_6lowpan.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Bootstraps/protocol_6lowpan.h index a27c6d2e2648..ebd3ccf5b8fe 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Bootstraps/protocol_6lowpan.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Bootstraps/protocol_6lowpan.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -35,13 +35,11 @@ extern struct rpl_domain *protocol_6lowpan_rpl_domain; extern struct rpl_dodag *protocol_6lowpan_rpl_root_dodag; #ifdef HAVE_RPL -#ifndef NO_MLE typedef enum { PRIORITY_1ST, PRIORITY_2ND, } neighbor_priority; #endif -#endif void protocol_6lowpan_interface_common_init(struct protocol_interface_info_entry *cur); void protocol_6lowpan_host_init(struct protocol_interface_info_entry *cur, bool sleepy_host); @@ -53,12 +51,10 @@ int protocol_6lowpan_child_update(struct protocol_interface_info_entry *cur); void protocol_6lowpan_neighbor_priority_update(struct protocol_interface_info_entry *cur, uint8_t *removed_priority, uint8_t *updated_priority); #ifdef HAVE_RPL -#ifndef NO_MLE uint16_t protocol_6lowpan_neighbor_priority_set(int8_t interface_id, addrtype_t addr_type, const uint8_t *addr_ptr); uint16_t protocol_6lowpan_neighbor_second_priority_set(int8_t interface_id, addrtype_t addr_type, const uint8_t *addr_ptr); void protocol_6lowpan_neighbor_priority_clear_all(int8_t interface_id, neighbor_priority priority); #endif -#endif #else #define protocol_6lowpan_child_update(cur) (-1) diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Bootstraps/protocol_6lowpan_bootstrap.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Bootstraps/protocol_6lowpan_bootstrap.h index e1b6e3cdc78b..14bb8284960a 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Bootstraps/protocol_6lowpan_bootstrap.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Bootstraps/protocol_6lowpan_bootstrap.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -27,7 +27,6 @@ struct protocol_interface_info_entry; struct nd_router; -struct mle_neigh_table_entry_t; #define MLE_NEIGHBOR_PURGE_NBR 3 #define MLE_NEIGHBOR_PURGE_TIMER_TIMEOUT 4 // Times advertisement timeout diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/IPHC_Decode/6lowpan_iphc.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/IPHC_Decode/6lowpan_iphc.c index 10473ab58551..b02b372fc1fd 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/IPHC_Decode/6lowpan_iphc.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/IPHC_Decode/6lowpan_iphc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017, Arm Limited and affiliates. + * Copyright (c) 2013-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -77,12 +77,7 @@ buffer_t *lowpan_down(buffer_t *buf) return NULL; } if (thread_info(cur)) { - mle_neigh_table_entry_t *mle_entry; - mle_entry = mle_class_get_by_link_address(cur->id, buf->dst_sa.address + 2, buf->dst_sa.addr_type); - if (mle_entry && thread_addr_is_child(mac_helper_mac16_address_get(cur), mle_entry->short_adr)) { - /* Check if the child can handle only stable network data (e.g. sleepy device) */ - stable_only = !(mle_entry->mode & MLE_THREAD_REQ_FULL_DATA_SET); - } + stable_only = thread_stable_context_check(cur, buf); } } @@ -169,7 +164,7 @@ buffer_t *lowpan_down(buffer_t *buf) /* RFC 6282+4944 require that we limit compression to the first fragment. * This check is slightly conservative - always allow 4 for first-fragment header */ - uint_fast8_t overhead = mac_helper_frame_overhead(cur, buf); + uint_fast16_t overhead = mac_helper_frame_overhead(cur, buf); uint_fast16_t max_iphc_size = mac_helper_max_payload_size(cur, overhead) - mesh_size - 4; buf = iphc_compress(&cur->lowpan_contexts, buf, max_iphc_size, stable_only); diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/MAC/mac_data_poll.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/MAC/mac_data_poll.c index 340716bffb6e..bb1f90e25916 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/MAC/mac_data_poll.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/MAC/mac_data_poll.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -45,6 +45,7 @@ #endif #include "6LoWPAN/MAC/mac_helper.h" #include "6LoWPAN/MAC/mac_data_poll.h" +#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h" #define TRACE_GROUP "mPol" @@ -281,6 +282,23 @@ void mac_poll_timer_trig(uint32_t poll_time, protocol_interface_info_entry_t *cu } } } +static mac_neighbor_table_entry_t *neighbor_data_poll_referesh(protocol_interface_info_entry_t *cur, uint8_t *address, addrtype_t type) +{ + mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), address, type); + + if (!entry) { + return NULL; + } + + if (!entry->connected_device) { + return NULL; + } + + if (!entry->nud_active) { + entry->lifetime = entry->link_lifetime; + } + return entry; +} void mac_mlme_poll_confirm(protocol_interface_info_entry_t *cur, const mlme_poll_conf_t *confirm) { @@ -295,20 +313,21 @@ void mac_mlme_poll_confirm(protocol_interface_info_entry_t *cur, const mlme_poll } rf_ptr->pollActive = false; + mac_neighbor_table_entry_t *entry = NULL; switch (confirm->status) { case MLME_SUCCESS: //tr_debug("Poll Confirm: Data with Data"); rf_ptr->nwk_parent_poll_fail = 0; //Trig new Data Poll immediately - mle_refresh_entry_timeout(cur->id, rf_ptr->poll_req.CoordAddress, (addrtype_t)rf_ptr->poll_req.CoordAddrMode, true); + entry = neighbor_data_poll_referesh(cur, rf_ptr->poll_req.CoordAddress, (addrtype_t)rf_ptr->poll_req.CoordAddrMode); poll_time = 1; break; case MLME_NO_DATA: //Start next case timer rf_ptr->nwk_parent_poll_fail = 0; - mle_refresh_entry_timeout(cur->id, rf_ptr->poll_req.CoordAddress, (addrtype_t)rf_ptr->poll_req.CoordAddrMode, true); + entry = neighbor_data_poll_referesh(cur, rf_ptr->poll_req.CoordAddress, (addrtype_t)rf_ptr->poll_req.CoordAddrMode); //tr_debug("Poll Confirm: No Data"); if (rf_ptr->protocol_poll == 0) { @@ -333,6 +352,9 @@ void mac_mlme_poll_confirm(protocol_interface_info_entry_t *cur, const mlme_poll } break; } + if (thread_info(cur) && entry) { + thread_neighbor_communication_update(cur, entry->index); + } mac_poll_timer_trig(poll_time, cur); @@ -423,7 +445,6 @@ int8_t mac_data_poll_host_mode_set(struct protocol_interface_info_entry *cur, ne new_poll_time = (poll_time * 1000); if (rf_ptr->host_mode == NET_HOST_RX_ON_IDLE) { tr_debug("Init Poll timer and period"); - mle_class_mode_set(cur->id, MLE_CLASS_SLEEPY_END_DEVICE); } rf_ptr->nwk_app_poll_time = new_poll_time; @@ -449,7 +470,6 @@ int8_t mac_data_poll_host_mode_set(struct protocol_interface_info_entry *cur, ne } } tr_debug("Enable Poll By APP"); - mle_class_mode_set(cur->id, MLE_CLASS_SLEEPY_END_DEVICE); mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, false); mac_poll_timer_trig(1, cur); rf_ptr->nwk_app_poll_time = 300; @@ -525,14 +545,12 @@ void mac_data_poll_init(struct protocol_interface_info_entry *cur) if (cur->mac_parameters->RxOnWhenIdle) { tr_debug("Set Non-Sleepy HOST"); rfd_ptr->host_mode = NET_HOST_RX_ON_IDLE; - mle_class_mode_set(cur->id, MLE_CLASS_END_DEVICE); } else { rfd_ptr->protocol_poll = 1; mac_poll_timer_trig(200, cur); tr_debug("Set Sleepy HOST configure"); rfd_ptr->host_mode = NET_HOST_FAST_POLL_MODE; - mle_class_mode_set(cur->id, MLE_CLASS_SLEEPY_END_DEVICE); rfd_ptr->slow_poll_rate_seconds = 3; rfd_ptr->timeOutInSeconds = 32; rfd_ptr->nwk_app_poll_time = 300; diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/MAC/mac_helper.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/MAC/mac_helper.c index faf954010d1b..97ab748da5bc 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/MAC/mac_helper.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/MAC/mac_helper.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, Arm Limited and affiliates. + * Copyright (c) 2016-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -25,7 +25,6 @@ #include "net_nwk_scan.h" #include "ns_trace.h" #include "common_functions.h" -#include "MLE/mle_tlv.h" #include "mac_api.h" #define TRACE_GROUP "MACh" @@ -685,7 +684,7 @@ int8_t mac_helper_mac64_set(protocol_interface_info_entry_t *interface, const ui * Given a buffer, with address and security flags set, compute the maximum * MAC payload that could be put in that buffer. */ -uint_fast16_t mac_helper_max_payload_size(protocol_interface_info_entry_t *cur, uint_fast8_t frame_overhead) +uint_fast16_t mac_helper_max_payload_size(protocol_interface_info_entry_t *cur, uint_fast16_t frame_overhead) { uint16_t max; @@ -833,7 +832,17 @@ void mac_helper_devicetable_remove(mac_api_t *mac_api, uint8_t attribute_index) mac_api->mlme_req(mac_api,MLME_SET , &set_req); } -void mac_helper_devicetable_set(mle_neigh_table_entry_t *entry_temp, protocol_interface_info_entry_t *cur, uint32_t frame_counter, uint8_t keyID, bool force_set) +void mac_helper_device_description_write(protocol_interface_info_entry_t *cur, mlme_device_descriptor_t *device_desc, uint8_t *mac64, uint16_t mac16, uint32_t frame_counter, bool exempt) +{ + memcpy(device_desc->ExtAddress, mac64, 8); + device_desc->ShortAddress = mac16; + device_desc->PANId = mac_helper_panid_get(cur); + device_desc->Exempt = exempt; + device_desc->FrameCounter = frame_counter; +} + +void mac_helper_devicetable_set(const mlme_device_descriptor_t *device_desc, protocol_interface_info_entry_t *cur, uint8_t attribute_index, uint8_t keyID, bool force_set) + { if (!cur->mac_api) { return; @@ -844,18 +853,10 @@ void mac_helper_devicetable_set(mle_neigh_table_entry_t *entry_temp, protocol_in return; } - mlme_device_descriptor_t device_desc; mlme_set_t set_req; - device_desc.FrameCounter = frame_counter; - device_desc.Exempt = false; - device_desc.ShortAddress = entry_temp->short_adr; - memcpy(device_desc.ExtAddress, entry_temp->mac64, 8); - device_desc.PANId = mac_helper_panid_get(cur); - - set_req.attr = macDeviceTable; - set_req.attr_index = entry_temp->attribute_index; - set_req.value_pointer = (void*)&device_desc; + set_req.attr_index = attribute_index; + set_req.value_pointer = (void*)device_desc; set_req.value_size = sizeof(mlme_device_descriptor_t); tr_debug("Register Device"); cur->mac_api->mlme_req(cur->mac_api,MLME_SET , &set_req); diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/MAC/mac_helper.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/MAC/mac_helper.h index a1fe37cd6812..d95f22e2d28b 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/MAC/mac_helper.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/MAC/mac_helper.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, Arm Limited and affiliates. + * Copyright (c) 2016-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -29,7 +29,6 @@ struct protocol_interface_info_entry; struct ns_sockaddr; struct buffer; struct mac_api_s; -struct mle_neigh_table_entry_t; void mac_create_scan_request(mac_scan_type_t type, struct channel_list_s *chanlist, uint8_t scan_duration, struct mlme_scan_s *request); @@ -100,7 +99,7 @@ bool mac_helper_write_our_addr(struct protocol_interface_info_entry *interface, int8_t mac_helper_mac64_set(struct protocol_interface_info_entry *interface, const uint8_t *mac64); -uint_fast16_t mac_helper_max_payload_size(struct protocol_interface_info_entry *cur, uint_fast8_t frame_overhead); +uint_fast16_t mac_helper_max_payload_size(struct protocol_interface_info_entry *cur, uint_fast16_t frame_overhead); uint_fast8_t mac_helper_frame_overhead(struct protocol_interface_info_entry *cur, const struct buffer *buf); @@ -110,8 +109,9 @@ int8_t mac_helper_link_frame_counter_set(int8_t interface_id, uint32_t seq_ptr); void mac_helper_devicetable_remove(struct mac_api_s *mac_api, uint8_t attribute_index); -void mac_helper_devicetable_set(struct mle_neigh_table_entry_t *entry_temp, struct protocol_interface_info_entry *cur, uint32_t frame_counter, uint8_t keyID, bool force_set); +void mac_helper_device_description_write(struct protocol_interface_info_entry *cur, mlme_device_descriptor_t *device_desc, uint8_t *mac64, uint16_t mac16, uint32_t frame_counter, bool exempt); +void mac_helper_devicetable_set(const mlme_device_descriptor_t *device_dec, struct protocol_interface_info_entry *cur, uint8_t attribute_index, uint8_t keyID, bool force_set); int8_t mac_helper_mac_mlme_max_retry_set(int8_t interface_id, uint8_t mac_retry_set); #endif // MAC_HELPER_H diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/MAC/mac_ie_lib.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/MAC/mac_ie_lib.c new file mode 100644 index 000000000000..037b64527f60 --- /dev/null +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/MAC/mac_ie_lib.c @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2018, Arm Limited and affiliates. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "nsconfig.h" +#include "ns_types.h" +#include "string.h" +#include "common_functions.h" +#include "mac_common_defines.h" +#include "mac_ie_lib.h" + + +#define MAC_IE_HEADER_LENGTH_MASK 0x007f +#define MAC_IE_HEADER_ID_MASK 0x7f80 +#define MAC_IE_PAYLOAD_LENGTH_MASK 0x07ff +#define MAC_IE_PAYLOAD_ID_MASK 0x7800 +#define MAC_IE_TYPE_PAYLOAD_MASK 0x8000 + +#define MAC_NESTED_LONG_IE_PAYLOAD_LENGTH_MASK 0x07ff +#define MAC_NESTED_LONG_IE_PAYLOAD_ID_MASK 0x7800 +#define MAC_NESTED_SHORT_IE_PAYLOAD_LENGTH_MASK 0x00ff +#define MAC_NESTED_SHORT_IE_PAYLOAD_ID_MASK 0x7f00 +#define MAC_NESTED_IE_TYPE_LONG_MASK 0x8000 + +static void mac_ie_header_parse(mac_header_IE_t *header_element, uint8_t *ptr) +{ + uint16_t ie_dummy = common_read_16_bit_inverse(ptr); + header_element->length = (ie_dummy & MAC_IE_HEADER_LENGTH_MASK); + header_element->id = ((ie_dummy & MAC_IE_HEADER_ID_MASK ) >> 7 ); + header_element->content_ptr = ptr + 2; +} + +static void mac_ie_payload_parse(mac_payload_IE_t *payload_element, uint8_t *ptr) +{ + uint16_t ie_dummy = common_read_16_bit_inverse(ptr); + payload_element->length = (ie_dummy & MAC_IE_PAYLOAD_LENGTH_MASK); + payload_element->id = ((ie_dummy & MAC_IE_PAYLOAD_ID_MASK ) >> 11); + payload_element->content_ptr = ptr + 2; +} + +static void mac_ie_nested_id_parse(mac_nested_payload_IE_t *element, uint8_t *ptr) +{ + uint16_t ie_dummy = common_read_16_bit_inverse(ptr); + + if (ie_dummy & MAC_NESTED_IE_TYPE_LONG_MASK) { + element->type_long = true; + element->length = (ie_dummy & MAC_NESTED_LONG_IE_PAYLOAD_LENGTH_MASK); + element->id = ((ie_dummy & MAC_NESTED_LONG_IE_PAYLOAD_ID_MASK ) >> 11); + } else { + element->type_long = false; + element->length = (ie_dummy & MAC_NESTED_SHORT_IE_PAYLOAD_LENGTH_MASK); + element->id = ((ie_dummy & MAC_NESTED_SHORT_IE_PAYLOAD_ID_MASK ) >> 8); + } + + element->content_ptr = ptr + 2; +} + + +uint8_t *mac_ie_header_base_write(uint8_t *ptr, uint8_t type, uint16_t length) +{ + uint16_t ie_dummy = 0; //Header Type + ie_dummy |= (length & MAC_IE_HEADER_LENGTH_MASK); + ie_dummy |= ((type << 7 ) & MAC_IE_HEADER_ID_MASK); + return common_write_16_bit_inverse(ie_dummy, ptr); +} + +uint8_t *mac_ie_payload_base_write(uint8_t *ptr, uint8_t type, uint16_t length) +{ + + uint16_t ie_dummy = MAC_IE_TYPE_PAYLOAD_MASK; //Payload type + ie_dummy |= (length & MAC_IE_PAYLOAD_LENGTH_MASK); + ie_dummy |= ((type << 11 ) & MAC_IE_PAYLOAD_ID_MASK); + return common_write_16_bit_inverse(ie_dummy, ptr); +} + +uint8_t *mac_ie_nested_ie_long_base_write(uint8_t *ptr, uint8_t sub_id, uint16_t length) +{ + uint16_t ie_dummy = MAC_NESTED_IE_TYPE_LONG_MASK; + ie_dummy |= (length & MAC_NESTED_LONG_IE_PAYLOAD_LENGTH_MASK); + ie_dummy |= ((sub_id << 11 ) & MAC_NESTED_LONG_IE_PAYLOAD_ID_MASK); + + return common_write_16_bit_inverse(ie_dummy, ptr); +} + +uint8_t *mac_ie_nested_ie_short_base_write(uint8_t *ptr, uint8_t sub_id, uint16_t length) +{ + uint16_t ie_dummy = 0; + ie_dummy |= (length & MAC_NESTED_SHORT_IE_PAYLOAD_LENGTH_MASK); + ie_dummy |= ((sub_id << 8 ) & MAC_NESTED_SHORT_IE_PAYLOAD_ID_MASK); + + return common_write_16_bit_inverse(ie_dummy, ptr); +} + +uint16_t mac_ie_payload_discover(uint8_t *payload_ptr, uint16_t length, mac_payload_IE_t * payload_ie) +{ + mac_payload_IE_t ie_element; + while (length >= 2) { + mac_ie_payload_parse(&ie_element, payload_ptr); + if (payload_ie->id == ie_element.id) { + payload_ie->content_ptr = ie_element.content_ptr; + payload_ie->length = ie_element.length; + return ie_element.length; + } + + length -= ie_element.length + 2; + + payload_ptr += ie_element.length + 2; + } + return 0; +} + +uint16_t mac_ie_nested_discover(uint8_t *payload_ptr, uint16_t length, mac_nested_payload_IE_t * nested_ie) +{ + mac_nested_payload_IE_t ie_element; + while (length >= 2) { + mac_ie_nested_id_parse(&ie_element, payload_ptr); + + if (length < ie_element.length + 2) { + return 0; + } + + if (nested_ie->id == ie_element.id && nested_ie->type_long == ie_element.type_long) { + nested_ie->content_ptr = ie_element.content_ptr; + nested_ie->length = ie_element.length; + return ie_element.length; + } + + length -= ie_element.length + 2; + + payload_ptr += ie_element.length + 2; + } + return 0; +} + +uint8_t mac_ie_header_discover(uint8_t *header_ptr, uint16_t length, mac_header_IE_t * header_ie) +{ + mac_header_IE_t ie_element; + while (length >= 2) { + mac_ie_header_parse(&ie_element, header_ptr); + if (header_ie->id == ie_element.id) { + header_ie->content_ptr = ie_element.content_ptr; + header_ie->length = ie_element.length; + return ie_element.length; + } + + length -= ie_element.length + 2; + + header_ptr += ie_element.length + 2; + } + return 0; +} + +uint8_t mac_ie_header_sub_id_discover(uint8_t *header_ptr, uint16_t length, mac_header_IE_t * header_ie, uint8_t sub_id) +{ + mac_header_IE_t ie_element; + uint8_t *sub_id_ptr; + while (length > 2) { + mac_ie_header_parse(&ie_element, header_ptr); + sub_id_ptr = ie_element.content_ptr; + if (ie_element.length && header_ie->id == ie_element.id && *sub_id_ptr == sub_id) { + sub_id_ptr++; + ie_element.length--; + header_ie->content_ptr = sub_id_ptr; + header_ie->length = ie_element.length; + return ie_element.length; + } + + length -= ie_element.length + 2; + + header_ptr += ie_element.length + 2; + } + return 0; +} diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/MAC/mac_ie_lib.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/MAC/mac_ie_lib.h new file mode 100644 index 000000000000..dbdf8c2eeabf --- /dev/null +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/MAC/mac_ie_lib.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2018, Arm Limited and affiliates. + * 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 MAC_IE_LIB_H_ +#define MAC_IE_LIB_H_ + +struct mac_payload_IE_s; +struct mac_payload_IE_s; + +/** + * @brief struct mac_nested_payload_IE_t Mac Nested IE Payload information element structure for parsing or write operation + */ +typedef struct mac_nested_payload_IE_s { + uint8_t *content_ptr; /**< Content data */ + uint16_t length; /**< Element length 0- 2047 when type_long true and for short 0- 255*/ + unsigned id:7; /**< Group ID 4-bit for long and 7 bit for short type */ + bool type_long:1; /**< True when Nested IE long format and false for short */ +} mac_nested_payload_IE_t; + +/** IE header element generic header write */ +uint8_t *mac_ie_header_base_write(uint8_t *ptr, uint8_t type, uint16_t length); + +/** IE payload element generic header write */ +uint8_t *mac_ie_payload_base_write(uint8_t *ptr, uint8_t type, uint16_t length); + +/** Nested IE long header write */ +uint8_t *mac_ie_nested_ie_long_base_write(uint8_t *ptr, uint8_t sub_id, uint16_t length); + +/** Nested IE short header write */ +uint8_t *mac_ie_nested_ie_short_base_write(uint8_t *ptr, uint8_t sub_id, uint16_t length); + +/** Payload IE discover for spesific group ID */ +uint16_t mac_ie_payload_discover(uint8_t *payload_ptr, uint16_t length, struct mac_payload_IE_s * payload_ie); + +/** Nested IE element discover inside parsed payload element */ +uint16_t mac_ie_nested_discover(uint8_t *payload_ptr, uint16_t length, mac_nested_payload_IE_t * nested_ie); + +/** Header IE elemnt discover */ +uint8_t mac_ie_header_discover(uint8_t *header_ptr, uint16_t length, struct mac_header_IE_s * header_ie); + +/** Header IE elemnt discover with sub id */ +uint8_t mac_ie_header_sub_id_discover(uint8_t *header_ptr, uint16_t length, mac_header_IE_t * header_ie, uint8_t sub_id); + +#endif /* MAC_IE_LIB_H_ */ diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/MAC/mac_pairwise_key.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/MAC/mac_pairwise_key.c index bb37e137fd66..96bf1f79a027 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/MAC/mac_pairwise_key.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/MAC/mac_pairwise_key.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -29,6 +29,7 @@ #include "6LoWPAN/MAC/mac_pairwise_key.h" #include "MLE/mle.h" #include "NWK_INTERFACE/Include/protocol.h" +#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h" #define TRACE_GROUP "mPKe" @@ -171,12 +172,12 @@ static mac_pairwise_interface_entry_t *mac_pairwise_key_main_class(uint8_t key_l static void mac_pairwise_key_list_free(protocol_interface_info_entry_t *interface, mac_pairwise_interface_entry_t *main_list) { //Delete mle entries & Keys - mle_neigh_table_entry_t *cur_entry; + mac_neighbor_table_entry_t *cur_entry; mac_pairwise_key_info_t *cur = main_list->mac_pairwise_key_table; for (uint8_t i = 0; i< main_list->key_table_size; i++) { - cur_entry = mle_class_get_by_device_attribute_id(interface->id, cur->device_descriptor_attribute); + cur_entry = mac_neighbor_table_attribute_discover(mac_neighbor_info(interface), cur->device_descriptor_attribute); if (cur_entry) { - mle_class_remove_entry(interface->id, cur_entry); + mac_neighbor_table_neighbor_remove(mac_neighbor_info(interface), cur_entry); } mac_helper_security_pairwisekey_set(interface, NULL, NULL, cur->key_decriptor_attribute); } @@ -266,30 +267,31 @@ int mac_pairwise_key_add(int8_t interface_id, uint32_t valid_life_time, const ui } //Allocate mle entry - mle_neigh_table_entry_t *mle_entry = mle_class_get_entry_by_mac64(interface_id, 0, eui64, true, &new_entry_created); - if (!mle_entry) { + mac_neighbor_table_entry_t *mac_entry = mac_neighbor_entry_get_by_mac64(mac_neighbor_info(interface), eui64, true, &new_entry_created); + if (!mac_entry) { return -1; } - mle_entry->thread_commission = true; - mle_entry->short_adr = 0xffff; - mle_entry->ttl = 20; + + mac_neighbor_table_trusted_neighbor(mac_neighbor_info(interface), mac_entry, true); + mac_entry->mac16 = 0xffff; //Allocate key description - mac_pairwise_key_info_t *key_desc = mac_pairwise_key_info_get(main_list, mle_entry->attribute_index); + mac_pairwise_key_info_t *key_desc = mac_pairwise_key_info_get(main_list, mac_entry->index); if (!key_desc) { - mle_class_remove_entry(interface_id, mle_entry); + mac_neighbor_table_neighbor_remove(mac_neighbor_info(interface), mac_entry); return -1; } - //Set device descriptor - mac_helper_devicetable_set(mle_entry, interface, 0, interface->mac_parameters->mac_default_key_index, new_entry_created); + mlme_device_descriptor_t device_desc; + mac_helper_device_description_write(interface, &device_desc, mac_entry->mac64, mac_entry->mac16,0, false); + mac_helper_devicetable_set(&device_desc, interface,mac_entry->index, interface->mac_parameters->mac_default_key_index, new_entry_created); //set key descriptor if (mac_helper_security_pairwisekey_set(interface, key, eui64, key_desc->key_decriptor_attribute) != 0) { main_list->key_table_size--; - mle_class_remove_entry(interface_id, mle_entry); + mac_neighbor_table_neighbor_remove(mac_neighbor_info(interface), mac_entry); return -1; } @@ -309,23 +311,23 @@ int mac_pairwise_key_del(int8_t interface_id, const uint8_t eui64[static 8]) if (!main_list) { return -1; } - //Get from mle - mle_neigh_table_entry_t *mle_entry = mle_class_get_entry_by_mac64(interface_id, 0, eui64, true, NULL); - if (!mle_entry) { + //Get from mac + mac_neighbor_table_entry_t *mac_entry = mac_neighbor_entry_get_by_mac64(mac_neighbor_info(interface), eui64, true, NULL); + if (!mac_entry) { return -1; } //discover by mle entry attribute uint8_t key_attribute; - if (!mac_pairwise_key_info_delete(main_list, mle_entry->attribute_index, &key_attribute)) { + if (!mac_pairwise_key_info_delete(main_list, mac_entry->index, &key_attribute)) { return -1; } //kill Entry & overwrite key mac_helper_security_pairwisekey_set(interface, NULL, NULL, key_attribute); - mle_class_remove_entry(interface_id, mle_entry); + mac_neighbor_table_neighbor_remove(mac_neighbor_info(interface), mac_entry); return 0; } diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/MAC/mac_response_handler.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/MAC/mac_response_handler.c index 9a24f36bfeb5..0c21681c2fc1 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/MAC/mac_response_handler.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/MAC/mac_response_handler.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, Arm Limited and affiliates. + * Copyright (c) 2016-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -31,9 +31,9 @@ #include "mac_mcps.h" #include "6LoWPAN/MAC/mac_data_poll.h" #include "6LoWPAN/MAC/mac_response_handler.h" +#include "6LoWPAN/MAC/mpx_api.h" #include "6LoWPAN/lowpan_adaptation_interface.h" - -static bool mac_data_is_broadcast_addr(const sockaddr_t *addr); +#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h" #define TRACE_GROUP "MRsH" @@ -49,15 +49,16 @@ static void mac_mlme_device_table_confirmation_handle(protocol_interface_info_en if (confirmation->status == MLME_SUCCESS) { //GET ME table by extended mac64 address - mle_neigh_table_entry_t * entry = mle_class_get_by_link_address(info_entry->id, descpription->ExtAddress, ADDR_802_15_4_LONG); + mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(info_entry), descpription->ExtAddress, ADDR_802_15_4_LONG); + if (!entry) { return; } - if (entry->short_adr != descpription->ShortAddress) { + if (entry->mac16 != descpription->ShortAddress) { //Refresh Short ADDRESS mlme_set_t set_request; - descpription->ShortAddress = entry->short_adr; + descpription->ShortAddress = entry->mac16; //CALL MLME-SET set_request.attr = macDeviceTable; @@ -107,62 +108,10 @@ void mcps_data_confirm_handler( const mac_api_t* api, const mcps_data_conf_t *da lowpan_adaptation_interface_tx_confirm(info_entry, data); } -static bool mcps_data_indication_neighbor_validate(int8_t interface_id, const sockaddr_t *addr) -{ - /* If MLE is enabled, we will talk if we have an MLE association */ - mle_neigh_table_entry_t *mle_entry = mle_class_get_by_link_address(interface_id, addr->address + 2, addr->addr_type); - if (mle_entry && (mle_entry->handshakeReady || mle_entry->thread_commission)) { - return true; - } - - /* Otherwise, we don't know them */ - return false; - -} - void mcps_data_indication_handler( const mac_api_t* api, const mcps_data_ind_t *data_ind ) { protocol_interface_info_entry_t *info_entry = protocol_stack_interface_info_get_by_id(api->parent_id); - buffer_t *buf = buffer_get(data_ind->msduLength); - if (!buf || !info_entry) { - return; - } - uint8_t *ptr; - buffer_data_add(buf, data_ind->msdu_ptr, data_ind->msduLength); - //tr_debug("MAC Paylod size %u %s",data_ind->msduLength, trace_array(data_ind->msdu_ptr, 8)); - buf->options.lqi = data_ind->mpduLinkQuality; - buf->options.dbm = data_ind->signal_dbm; - buf->src_sa.addr_type = (addrtype_t)data_ind->SrcAddrMode; - ptr = common_write_16_bit(data_ind->SrcPANId, buf->src_sa.address); - memcpy(ptr, data_ind->SrcAddr, 8); - buf->dst_sa.addr_type = (addrtype_t)data_ind->DstAddrMode; - ptr = common_write_16_bit(data_ind->DstPANId, buf->dst_sa.address); - memcpy(ptr, data_ind->DstAddr, 8); - //Set Link spesific stuff to seperately - buf->link_specific.ieee802_15_4.srcPanId = data_ind->SrcPANId; - buf->link_specific.ieee802_15_4.dstPanId = data_ind->DstPANId; - - if (mac_data_is_broadcast_addr(&buf->dst_sa)) { - buf->options.ll_broadcast_rx = true; - } - buf->interface = info_entry; - if (data_ind->Key.SecurityLevel) { - buf->link_specific.ieee802_15_4.fc_security = true; - - if (info_entry->mac_security_key_usage_update_cb) { - info_entry->mac_security_key_usage_update_cb(info_entry, &data_ind->Key); - } - } else { - buf->link_specific.ieee802_15_4.fc_security = false; - if (mac_helper_default_security_level_get(info_entry) || - !mcps_data_indication_neighbor_validate(info_entry->id, &buf->src_sa)) { - //SET By Pass - buf->options.ll_security_bypass_rx = true; - } - } - - buf->info = (buffer_info_t)(B_TO_IPV6_TXRX | B_FROM_MAC | B_DIR_UP); - protocol_push(buf); + lowpan_adaptation_interface_data_ind(info_entry, data_ind); } void mcps_purge_confirm_handler( const mac_api_t* api, mcps_purge_conf_t *data ) @@ -306,9 +255,3 @@ void mlme_indication_handler( const mac_api_t* api, mlme_primitive id, const voi } } -bool mac_data_is_broadcast_addr(const sockaddr_t *addr) -{ - return (addr->addr_type == ADDR_802_15_4_SHORT) && - (addr->address[2] == 0xFF && addr->address[3] == 0xFF); -} - diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/MAC/mpx_api.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/MAC/mpx_api.h new file mode 100644 index 000000000000..a61e3e00537f --- /dev/null +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/MAC/mpx_api.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2018, Arm Limited and affiliates. + * 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 MPX_API_H_ +#define MPX_API_H_ + +struct mcps_data_req_s; +struct mcps_data_conf_s; +struct mcps_data_ind_s; +struct mcps_purge_s; + +typedef struct mpx_api_s mpx_api_t; + +/** + * @brief mpx_data_request MPX_DATA request with user ID + * @param api API to handle the request + * @param data MCPS-DATA.request specific values + * @param user_id MPX user ID + * + */ +typedef void mpx_data_request(const mpx_api_t *api, const struct mcps_data_req_s *data, uint16_t user_id); + +/** + * @brief mpx_data_queue_clean clean MPX user data + * @param api API to handle the request + * @param purge MCPS-purge request + * @param user_id MPX user ID + * + */ +typedef void mpx_data_purge_request(const mpx_api_t *api, struct mcps_purge_s *purge, uint16_t user_id); + +/** + * @brief mpx_data_confirm MPX-DATA confirm is called as a response to MPX-DATA request + * @param api The API which handled the response + * @param data MCPS-DATA.confirm specific values + * @param user_id MPX user ID + */ +typedef void mpx_data_confirm(const mpx_api_t* api, const struct mcps_data_conf_s *data); + +/** + * @brief mpx_data_indication MPX-DATA confirm is called as a response to MPX-DATA request + * @param api The API which handled the response + * @param data MCPS-DATA.indication specific values + * @param user_id MPX user ID + */ +typedef void mpx_data_indication(const mpx_api_t* api, const struct mcps_data_ind_s *data); + +/** + * @brief mpx_header_size_get Function for request MPX user head room size + * @param api The API which handled the response + * @param user_id MPX user ID + * + * @return >0 Head room size in bytes + * @return 0 When Unknown User Id + */ +typedef uint16_t mpx_header_size_get(const mpx_api_t * api, uint16_t user_id); + +/** + * @brief mpx_data_cb_register MPX-DATA confirm cb register by user + * @param api The API which handled the response + * @param confirm_cb MPX Data Confirm call back + * @param indication_cb MPX Data indication + * @param user_id MPX user ID + * + * @return 0 register OK + * @return -1 Unknown User ID + */ +typedef int8_t mpx_data_cb_register(const mpx_api_t* api, mpx_data_confirm *confirm_cb, mpx_data_indication *indication_cb, uint16_t user_id); + +/** + * \brief Struct mpx_api_s defines functions for MPX user for register call backs and send data. + */ +struct mpx_api_s { + mpx_data_request * mpx_data_request; /**< MPX data request. */ + mpx_data_purge_request *mpx_data_purge; /**< MPX data Purge. */ + mpx_header_size_get * mpx_headroom_size_get; /**< MPX headroom size get in bytes. */ + mpx_data_cb_register * mpx_user_registration; /**< MPX User cb registration must be call before enable to send or RX data*/ +}; + + +#endif /* MPX_API_H_ */ diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ND/nd_router_object.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ND/nd_router_object.c index d52645a8496d..35f923042039 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ND/nd_router_object.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ND/nd_router_object.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017, Arm Limited and affiliates. + * Copyright (c) 2013-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -41,6 +41,8 @@ #include "BorderRouter/border_router.h" #include "Service_Libs/pan_blacklist/pan_blacklist_api.h" #include "6LoWPAN/MAC/mac_data_poll.h" +#include "6LoWPAN/ws/ws_common.h" +#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h" #define TRACE_GROUP "loND" @@ -845,17 +847,18 @@ static void nd_update_registration(protocol_interface_info_entry_t *cur_interfac ipv6_neighbour_set_state(&cur_interface->ipv6_neighbour_cache, neigh, IP_NEIGHBOUR_STALE); /* Register with 2 seconds off the lifetime - don't want the NCE to expire before the route */ ipv6_route_add(neigh->ip_address, 128, cur_interface->id, NULL, ROUTE_ARO, neigh->lifetime - 2, 0); -#ifndef NO_MLE + /* We need to know peer is a host before publishing - this needs MLE. Not yet established * what to do without MLE - might need special external/non-external prioritisation at root. * This "publish for RFD" rule comes from ZigBee IP. */ - mle_neigh_table_entry_t *mle_entry = mle_class_get_by_link_address(cur_interface->id, ipv6_neighbour_eui64(&cur_interface->ipv6_neighbour_cache, neigh), ADDR_802_15_4_LONG); - if (mle_entry && ((mle_entry->mode & MLE_DEV_MASK) == MLE_RFD_DEV)) { + mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur_interface), ipv6_neighbour_eui64(&cur_interface->ipv6_neighbour_cache, neigh), ADDR_802_15_4_LONG); + + if (entry && !entry->ffd_device) { rpl_control_publish_host_address(protocol_6lowpan_rpl_domain, neigh->ip_address, neigh->lifetime); } protocol_6lowpan_neighbor_address_state_synch(cur_interface, aro->eui64, neigh->ip_address + 8); -#endif + } else { /* Um, no - can't transmit response if we remove NCE now! */ //ipv6_neighbour_entry_remove(&cur_interface->ipv6_neighbour_cache, neigh); @@ -863,9 +866,7 @@ static void nd_update_registration(protocol_interface_info_entry_t *cur_interfac neigh->lifetime = 2; ipv6_neighbour_set_state(&cur_interface->ipv6_neighbour_cache, neigh, IP_NEIGHBOUR_STALE); ipv6_route_add(neigh->ip_address, 128, cur_interface->id, NULL, ROUTE_ARO, 4, 0); -#ifndef NO_MLE rpl_control_unpublish_address(protocol_6lowpan_rpl_domain, neigh->ip_address); -#endif } } @@ -967,7 +968,13 @@ bool nd_ns_aro_handler(protocol_interface_info_entry_t *cur_interface, const uin /* Set the LL address, ensure it's marked STALE */ ipv6_neighbour_entry_update_unsolicited(&cur_interface->ipv6_neighbour_cache, neigh, ll_addr.addr_type, ll_addr.address); ipv6_neighbour_set_state(&cur_interface->ipv6_neighbour_cache, neigh, IP_NEIGHBOUR_STALE); - + if (ws_info(cur_interface)) { + aro_out->status = ARO_SUCCESS; + aro_out->present = true; + // Todo: this might not be needed... + nd_update_registration(cur_interface, neigh, aro_out); + return true; + } if (cur_interface->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER || nd_params.multihop_dad == false) { if (cur_interface->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) { whiteboard_entry_t *wb; diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_address_registration_client.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_address_registration_client.h index 4713401f691d..d43f964d9432 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_address_registration_client.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_address_registration_client.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Arm Limited and affiliates. + * Copyright (c) 2017-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -30,10 +30,23 @@ #ifndef THREAD_ADDRESS_REGISTRATION_CLIENT_H_ #define THREAD_ADDRESS_REGISTRATION_CLIENT_H_ + +#ifdef HAVE_THREAD_V2 + +void thread_address_registration_init(void); +void thread_address_registration_deinit(void); + +void thread_address_registration_timer_set(protocol_interface_info_entry_t *interface, uint16_t dua_delay_seconds, uint16_t mlr_refresh_seconds); +void thread_address_registration_timer(protocol_interface_info_entry_t *interface, uint16_t seconds); +#else + #define thread_address_registration_init(void) #define thread_address_registration_deinit(void) -#define thread_address_registration_timer_set(interface, seconds); +#define thread_address_registration_timer_set(interface, dua_delay_seconds, mlr_refresh_seconds); #define thread_address_registration_timer(interface, seconds); +#endif + + #endif /* THREAD_ADDRESS_REGISTRATION_CLIENT_H_ */ diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_bbr_api.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_bbr_api.c index 0e0fc04d1162..6c0b09a2c0f9 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_bbr_api.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_bbr_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Arm Limited and affiliates. + * Copyright (c) 2017-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -943,7 +943,7 @@ void thread_bbr_seconds_timer(int8_t interface_id, uint32_t seconds) #endif // HAVE_THREAD_ROUTER #ifdef HAVE_THREAD_BORDER_ROUTER -static int thread_bbr_na_send(int8_t interface_id, const uint8_t target[static 16]) +int thread_bbr_na_send(int8_t interface_id, const uint8_t target[static 16]) { protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); if (!cur) { @@ -955,18 +955,18 @@ static int thread_bbr_na_send(int8_t interface_id, const uint8_t target[static 1 return 0; } -int thread_bbr_nd_entry_add (int8_t interface_id, const uint8_t *addr_data_ptr, uint32_t lifetime, void *info, const uint8_t *mleid_ptr) { - (void) mleid_ptr; + +int thread_bbr_nd_entry_add (int8_t interface_id, const uint8_t *addr_data_ptr, uint32_t lifetime, void *info) +{ thread_bbr_t *this = thread_bbr_find_by_interface(interface_id); if (!this || this->backbone_interface_id < 0) { - tr_err("bbr not ready"); return -1; } ipv6_route_t *route = ipv6_route_add_with_info(addr_data_ptr, 128, interface_id, NULL, ROUTE_THREAD_PROXIED_HOST, info, 0, lifetime, 0); // We are using route info field to store sequence number if (!route) { // Direct route to host allows ND proxying to work - tr_err("out of resources"); + tr_err("bbr out of resources"); return -2; } // send NA @@ -975,14 +975,44 @@ int thread_bbr_nd_entry_add (int8_t interface_id, const uint8_t *addr_data_ptr, return 0; } -int thread_bbr_nd_entry_find(int8_t interface_id, const uint8_t *addr_data_ptr) { - ipv6_route_t *route = ipv6_route_choose_next_hop(addr_data_ptr, interface_id, NULL); - if (!route || route->prefix_len < 128 || !route->on_link || route->info.source != ROUTE_THREAD_PROXIED_HOST ) { - //Not found +int thread_bbr_dua_entry_add (int8_t interface_id, const uint8_t *addr_data_ptr, uint32_t lifetime, const uint8_t *mleid_ptr) +{ + thread_bbr_t *this = thread_bbr_find_by_interface(interface_id); + if (!this || this->backbone_interface_id < 0) { return -1; } - //TODO get information to route to parameters eq mleid, timeout + thread_pbbr_dua_info_t *map = ns_dyn_mem_alloc(sizeof(thread_pbbr_dua_info_t)); + if (!map) { + goto error; + } + memcpy(map->mleid_ptr, mleid_ptr, 8); + map->last_contact_time = protocol_core_monotonic_time; + + // We are using route info field to store BBR MLEID map + ipv6_route_t *route = ipv6_route_add_with_info(addr_data_ptr, 128, interface_id, NULL, ROUTE_THREAD_PROXIED_DUA_HOST, map, 0, lifetime, 0); + if (!route) { + // Direct route to host allows ND proxying to work + ns_dyn_mem_free(map); + goto error; + } + // Route info autofreed + route->info_autofree = true; + // send NA + thread_bbr_na_send(this->backbone_interface_id, addr_data_ptr); + return 0; +error: + tr_err("out of resources"); + return -2; +} + +struct ipv6_route *thread_bbr_dua_entry_find(int8_t interface_id, const uint8_t *addr_data_ptr) { + ipv6_route_t *route = ipv6_route_choose_next_hop(addr_data_ptr, interface_id, NULL); + if (!route || route->prefix_len < 128 || !route->on_link || route->info.source != ROUTE_THREAD_PROXIED_DUA_HOST ) { + //Not found + return NULL; + } + return route; } int thread_bbr_proxy_state_update(int8_t caller_interface_id , int8_t handler_interface_id, bool status) @@ -1090,6 +1120,17 @@ return 0; #endif // HAVE_THREAD_BORDER_ROUTER } +int thread_bbr_prefix_set(int8_t interface_id, uint8_t *prefix) +{ + (void) interface_id; + (void) prefix; +#ifdef HAVE_THREAD_BORDER_ROUTER + return thread_extension_bbr_prefix_set(interface_id, prefix); +#else + return -1; +#endif // HAVE_THREAD_BORDER_ROUTER +} + int thread_bbr_validation_interface_address_set(int8_t interface_id, const uint8_t *addr_ptr, uint16_t port) { (void) interface_id; diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_bbr_api_internal.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_bbr_api_internal.h index 8930e0190fcd..dd05ca7525bf 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_bbr_api_internal.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_bbr_api_internal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, Arm Limited and affiliates. + * Copyright (c) 2016-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -36,6 +36,8 @@ #include "net_interface.h" #ifdef HAVE_THREAD_ROUTER +struct ipv6_route; + /** * \brief Initialize Thread Commissioner relay for BBR and Routers * @@ -98,23 +100,39 @@ void thread_bbr_network_data_update_notify(protocol_interface_info_entry_t *cur) /** * \brief Add new nd entry to bbr * + * \param interface_id addr_data_ptr lifetime info + */ +int thread_bbr_nd_entry_add(int8_t interface_id, const uint8_t *addr_data_ptr, uint32_t lifetime, void *info); + +/** + * \brief Add new dua entry to bbr + * + * \param interface_id addr_data_ptr lifetime info mleid_ptr + */ +int thread_bbr_dua_entry_add (int8_t interface_id, const uint8_t *addr_data_ptr, uint32_t lifetime, const uint8_t *mleid_ptr); + +/** + * \brief Send na + * * \param interface_id addr_data_ptr lifetime info mleid_ptr */ -int thread_bbr_nd_entry_add(int8_t interface_id, const uint8_t *addr_data_ptr, uint32_t lifetime, void *info, const uint8_t *mleid_ptr); +int thread_bbr_na_send(int8_t interface_id, const uint8_t target[static 16]); /** - * \brief Find if bbr has nd entry + * \brief Find if bbr has dua entry * * \param interface_id addr_data_ptr */ -int thread_bbr_nd_entry_find(int8_t interface_id, const uint8_t *addr_data_ptr); +struct ipv6_route *thread_bbr_dua_entry_find(int8_t interface_id, const uint8_t *addr_data_ptr); #else #define thread_bbr_proxy_state_update(caller_interface_id , handler_interface_id, status) (NULL) #define thread_bbr_routing_enabled(cur) false #define thread_bbr_network_data_update_notify(cur) -#define thread_bbr_nd_entry_add(interface_id, addr_data_ptr, lifetime, info, mleid_ptr) (0) -#define thread_bbr_nd_entry_find(interface_id, addr_data_ptr) (0) +#define thread_bbr_nd_entry_add(interface_id, addr_data_ptr, lifetime, info) (0) +#define thread_bbr_dua_entry_add(interface_id, addr_data_ptr, lifetime, mleid_ptr) (0) +#define thread_bbr_dua_entry_find(interface_id, addr_data_ptr) (NULL) +#define thread_bbr_na_send(interface_id, target) (0) #endif //HAVE_THREAD_BORDER_ROUTER diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_bootstrap.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_bootstrap.c index 3f746d20d1a8..0e26b643edf1 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_bootstrap.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_bootstrap.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -59,6 +59,7 @@ #include "6LoWPAN/Thread/thread_router_bootstrap.h" #include "6LoWPAN/Thread/thread_management_internal.h" #include "6LoWPAN/Thread/thread_management_server.h" +#include "6LoWPAN/Thread/thread_neighbor_class.h" #include "6LoWPAN/Thread/thread_network_data_lib.h" #include "6LoWPAN/Thread/thread_network_synch.h" #include "6LoWPAN/Thread/thread_joiner_application.h" @@ -90,9 +91,14 @@ #include "thread_meshcop_lib.h" #include "multicast_api.h" #include "mlme.h" +#include "Service_Libs/etx/etx.h" #include "Service_Libs/nd_proxy/nd_proxy.h" #include "Service_Libs/blacklist/blacklist.h" +#include "Service_Libs/mle_service/mle_service_api.h" #include "6LoWPAN/MAC/mac_data_poll.h" +#include "6LoWPAN/lowpan_adaptation_interface.h" +#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h" +#include "platform/topo_trace.h" #define TRACE_GROUP "thbs" @@ -111,27 +117,46 @@ static void thread_bootstrap_generate_leader_and_link(protocol_interface_info_en static int thread_bootstrap_attach_start(int8_t interface_id, thread_bootsrap_state_type_e state); static void thread_bootsrap_network_discovery_failure(int8_t interface_id); -static void thread_neighbor_remove(int8_t interface_id, mle_neigh_table_entry_t *cur); +static void thread_neighbor_remove(mac_neighbor_table_entry_t *entry_ptr, void *user_data); static void thread_bootsrap_network_join_start(struct protocol_interface_info_entry *cur_interface, discovery_response_list_t *nwk_info); -static bool thread_interface_is_active(int8_t interface_id) { - protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); - if (!cur || !(cur->lowpan_info & INTERFACE_NWK_ACTIVE)) { - return false; - } +static void thread_neighbor_remove(mac_neighbor_table_entry_t *entry_ptr, void *user_data) +{ + protocol_interface_info_entry_t *cur = user_data; + lowpan_adaptation_remove_free_indirect_table(cur, entry_ptr); - return true; + thread_reset_neighbour_info(cur, entry_ptr); + //Removes ETX neighbor + etx_neighbor_remove(cur->id, entry_ptr->index); + //Remove MLE frame counter info + mle_service_frame_counter_entry_delete(cur->id, entry_ptr->index); } -static void thread_neighbor_remove(int8_t interface_id, mle_neigh_table_entry_t *cur) +static bool thread_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr, void *user_data) { - protocol_interface_info_entry_t *cur_interface = protocol_stack_interface_info_get_by_id(interface_id); - if (!cur_interface) { - return; + + // Sleepy host + protocol_interface_info_entry_t *cur_interface = user_data; + + if (thread_am_router(cur_interface)) { + return false; //Never do Keep alive with any one + } + + if (entry_ptr->link_role != PRIORITY_PARENT_NEIGHBOUR) { + return false; //Do not never challenge than priority parent } - thread_reset_neighbour_info(cur_interface, cur); + + if (cur_interface->lowpan_info & INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE) { + return false; //Sleepy end device should not never challenge + } + + if (entry_ptr->lifetime > MLE_TABLE_CHALLENGE_TIMER) { + return false; + } + + return thread_host_bootstrap_child_update(cur_interface, entry_ptr->mac64); } int8_t thread_mle_class_init(int8_t interface_id) @@ -151,11 +176,29 @@ int8_t thread_mle_class_init(int8_t interface_id) return -1; } - if (mle_class_init(interface_id, buffer.device_decription_table_size - 1, &thread_neighbor_remove, &thread_host_bootstrap_child_update, &thread_interface_is_active) != 0) { + thread_neighbor_class_delete(&cur->thread_info->neighbor_class); + + if (!thread_neighbor_class_create(&cur->thread_info->neighbor_class, buffer.device_decription_table_size - 1)) { return -1; } - mle_class_router_challenge(interface_id, NULL); + if (!mac_neighbor_info(cur) ) { + mac_neighbor_info(cur) = mac_neighbor_table_create(buffer.device_decription_table_size - 1, thread_neighbor_remove + , thread_neighbor_entry_nud_notify, cur); + if (!mac_neighbor_info(cur)) { + return -1; + } + } + + if (mle_service_frame_counter_table_allocate(interface_id, buffer.device_decription_table_size - 1)) { + return -1; + } + + if (!etx_storage_list_allocate(cur->id, buffer.device_decription_table_size - 1)) { + return -1; + } + + lowpan_adaptation_interface_etx_update_enable(cur->id); //Defined well know neighbour for discovery @@ -232,7 +275,7 @@ uint8_t thread_calculate_link_margin(int8_t dbm, uint8_t compLinkMarginFromParen return newLqi; } -bool thread_check_is_this_my_parent(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *entry_temp) +bool thread_check_is_this_my_parent(protocol_interface_info_entry_t *cur, mac_neighbor_table_entry_t *entry_temp) { if (entry_temp && thread_info(cur)->thread_endnode_parent) { if(memcmp(entry_temp->mac64, thread_info(cur)->thread_endnode_parent->mac64, 8) == 0) { @@ -245,45 +288,31 @@ bool thread_check_is_this_my_parent(protocol_interface_info_entry_t *cur, mle_ne bool thread_bootstrap_request_network_data(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData, uint16_t short_address) { bool requestNetworkdata = false; - thread_leader_data_t *leadeInfo = thread_info(cur)->thread_leader_data; + thread_leader_data_t *leaderInfo = thread_info(cur)->thread_leader_data; if (thread_info(cur)->thread_endnode_parent->shortAddress != short_address) { return false; } - if (thread_info(cur)->thread_leader_data->partitionId != leaderData->partitionId) { + if (!thread_partition_match(cur, leaderData)) { tr_debug("Learn new Network Data"); requestNetworkdata = true; - thread_info(cur)->thread_leader_data->dataVersion = leaderData->dataVersion - 1; - thread_info(cur)->thread_leader_data->stableDataVersion = leaderData->stableDataVersion - 1; + thread_partition_info_update(cur, leaderData); } - else if (common_serial_number_greater_8(leaderData->dataVersion, leadeInfo->dataVersion)) { + else if (common_serial_number_greater_8(leaderData->dataVersion, leaderInfo->dataVersion)) { requestNetworkdata = true; - } else if (common_serial_number_greater_8(leaderData->stableDataVersion, leadeInfo->stableDataVersion)) { + } else if (common_serial_number_greater_8(leaderData->stableDataVersion, leaderInfo->stableDataVersion)) { requestNetworkdata = true; } - // Version number is updated when new network data is learned to avoid synchronization problems - thread_info(cur)->thread_leader_data->leaderRouterId = leaderData->leaderRouterId; - thread_info(cur)->thread_leader_data->partitionId = leaderData->partitionId; if (requestNetworkdata) { thread_bootstrap_parent_network_data_request(cur, true); } return true; } -bool thread_instance_id_matches(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData) -{ - if (thread_info(cur)->thread_leader_data) { - if (thread_info(cur)->thread_leader_data->partitionId == leaderData->partitionId) { - return true; - } - } - return false; -} - static int thread_router_check_previous_partition_info(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData, mle_tlv_info_t *routeTlv) { if (!routeTlv || !routeTlv->dataPtr || !routeTlv->tlvLen || !leaderData) { @@ -386,8 +415,7 @@ int thread_leader_data_validation(protocol_interface_info_entry_t *cur, thread_l if (!thread_info(cur)->thread_leader_data) { return -1; } - if ((thread_info(cur)->thread_leader_data->partitionId != leaderData->partitionId) || - (thread_info(cur)->thread_leader_data->weighting != leaderData->weighting)) { + if (!thread_partition_match(cur, leaderData)) { uint8_t routers_in_route_tlv = thread_get_router_count_from_route_tlv(routeTlv); //partition checks return thread_bootstrap_partition_process(cur,routers_in_route_tlv,leaderData, routeTlv); @@ -472,11 +500,9 @@ void thread_end_device_mode_set(protocol_interface_info_entry_t *cur, bool sleep { if (sleepy) { cur->lowpan_info |= INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE; - mle_class_mode_set(cur->id, MLE_CLASS_SLEEPY_END_DEVICE); mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, false); } else { cur->lowpan_info &= ~INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE; - mle_class_mode_set(cur->id, MLE_CLASS_END_DEVICE); mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, true); } } @@ -537,9 +563,6 @@ void thread_set_link_local_address(protocol_interface_info_entry_t *cur) static int thread_configuration_security_activate(protocol_interface_info_entry_t *cur, link_configuration_s *linkConfiguration) { - uint8_t key_material[32]; - uint8_t key_index; - tr_debug("MAC SET Security Mode"); if (!(cur->lowpan_info & INTERFACE_NWK_ACTIVE) || !(cur->configure_flags & INTERFACE_BOOTSTRAP_DEFINED)) { @@ -554,16 +577,11 @@ static int thread_configuration_security_activate(protocol_interface_info_entry_ cur->thread_info->masterSecretMaterial.historyKeyValid = false; cur->thread_info->masterSecretMaterial.valid_Info = true; // Update the guard timer value - thread_calculate_key_guard_timer(cur, linkConfiguration, true); + thread_key_guard_timer_calculate(cur, linkConfiguration, true); //Define KEY's - thread_key_get(linkConfiguration->master_key, key_material, linkConfiguration->key_sequence); - key_index = THREAD_KEY_INDEX(linkConfiguration->key_sequence); - //Set Keys - mac_helper_security_default_key_set(cur, &key_material[16], key_index, MAC_KEY_ID_MODE_IDX); - //Add Security to MLE service - mle_service_security_set_security_key(cur->id, key_material, key_index, true); - //Gen also Next Key - thread_security_next_key_generate(cur, linkConfiguration->master_key, linkConfiguration->key_sequence); + thread_security_prev_key_generate(cur,linkConfiguration->master_key,linkConfiguration->key_sequence); + thread_security_key_generate(cur,linkConfiguration->master_key,linkConfiguration->key_sequence); + thread_security_next_key_generate(cur,linkConfiguration->master_key,linkConfiguration->key_sequence); return 0; } @@ -711,9 +729,9 @@ int thread_configuration_mle_disable(protocol_interface_info_entry_t *cur) return 0; } -int thread_mle_service_register(int8_t interface_id, uint8_t *mac64 ) +static int thread_mle_service_register(protocol_interface_info_entry_t *cur, uint8_t *mac64 ) { - if (mle_service_interface_register(interface_id,thread_mle_parent_discover_receive_cb, mac64,8) != 0) { + if (mle_service_interface_register(cur->id, cur, thread_mle_parent_discover_receive_cb, mac64,8) != 0) { tr_error("Mle Service init Fail"); return -1; } @@ -1052,7 +1070,7 @@ void thread_tasklet(arm_event_s *event) case THREAD_CHILD_UPDATE: tr_debug_extra("Thread SM THREAD_CHILD_UPDATE"); if (thread_info(cur)->thread_endnode_parent) { - thread_host_bootstrap_child_update(cur->id, cur->thread_info->thread_endnode_parent->mac64); + thread_host_bootstrap_child_update(cur, cur->thread_info->thread_endnode_parent->mac64); } break; case THREAD_ANNOUNCE_ACTIVE: { @@ -1166,12 +1184,12 @@ void thread_bootstrap_ready(protocol_interface_info_entry_t *cur) void thread_neighbor_list_clean(struct protocol_interface_info_entry *cur) { - mle_neigh_table_list_t *neig_list = mle_class_active_list_get(cur->id); + mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list; - ns_list_foreach_safe(mle_neigh_table_entry_t, cur_entry, neig_list) { - if (!thread_addr_is_equal_or_child(cur->thread_info->routerShortAddress, cur_entry->short_adr)) { - tr_debug("Free ID %x", cur_entry->short_adr); - mle_class_remove_entry(cur->id, cur_entry); + ns_list_foreach_safe(mac_neighbor_table_entry_t, cur_entry, mac_table_list) { + if (!thread_addr_is_equal_or_child(cur->thread_info->routerShortAddress, cur_entry->mac16)) { + tr_debug("Free ID %x", cur_entry->mac16); + mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), cur_entry); } } } @@ -1454,9 +1472,7 @@ int thread_bootstrap_reset(protocol_interface_info_entry_t *cur) neighbor_cache_flush(&cur->neigh_cache); thread_bootstrap_stop(cur); -#ifndef NO_MLE - mle_class_list_clean(cur->id); -#endif + mac_neighbor_table_neighbor_list_clean(mac_neighbor_info(cur)); cur->bootsrap_state_machine_cnt = 0; mac_helper_free_scan_confirm(&cur->mac_parameters->nwk_scan_params); //tr_debug( "--> idle"); @@ -1600,6 +1616,7 @@ void thread_bootstrap_routing_activate(protocol_interface_info_entry_t *cur) // FEDs and routers (REEDs) perform their own address resolution thread_nd_service_activate(cur->id); } else { + thread_nd_client_service_activate(cur->id); thread_child_set_default_route(cur); } } @@ -2177,7 +2194,7 @@ void thread_bootstrap_start_network_discovery(protocol_interface_info_entry_t *c scan_request.channel_mask = cur->mac_parameters->nwk_scan_params.stack_chan_list.channel_mask[0]; scan_request.filter_tlv_data = NULL; scan_request.filter_tlv_length = 0; - if (thread_discovery_network_scan(cur->id, &scan_request, discover_ready) != 0 ) { + if (thread_discovery_network_scan(cur, &scan_request, discover_ready) != 0 ) { tr_error("Discovery scan start fail"); } } @@ -2198,7 +2215,7 @@ void thread_bootstrap_state_machine(protocol_interface_info_entry_t *cur) //SET Link by Static configuration tr_info("thread network attach start"); - if (thread_mle_service_register(cur->id,thread_joiner_application_random_mac_get(cur->id)) != 0 || + if (thread_mle_service_register(cur,thread_joiner_application_random_mac_get(cur->id)) != 0 || thread_link_configuration_activate(cur, linkConfiguration) != 0) { tr_error("Network Bootsrap Start Fail"); bootsrap_next_state_kick(ER_BOOTSTRAP_SCAN_FAIL, cur); @@ -2257,6 +2274,7 @@ void thread_bootstrap_stop(protocol_interface_info_entry_t *cur) ipv6_route_table_remove_info(cur->id, ROUTE_THREAD, NULL); ipv6_route_table_remove_info(cur->id, ROUTE_THREAD_BORDER_ROUTER, NULL); ipv6_route_table_remove_info(cur->id, ROUTE_THREAD_PROXIED_HOST, NULL); + ipv6_route_table_remove_info(cur->id, ROUTE_THREAD_PROXIED_DUA_HOST, NULL); thread_leader_service_leader_data_free(cur->thread_info); thread_bootstrap_all_nodes_multicast_unregister(cur); thread_data_base_init(cur->thread_info, cur->id); @@ -2672,7 +2690,7 @@ int thread_bootstrap_network_data_activate(protocol_interface_info_entry_t *cur) thread_router_bootstrap_anycast_address_register(cur); // Update joiner router status thread_management_server_joiner_router_init(cur->id); - thread_extension_joiner_router_init(cur->id); + thread_extension_service_init(cur); // Update border router relay thread_bbr_commissioner_proxy_service_update(cur->id); @@ -2870,8 +2888,7 @@ void thread_bootstrap_clear_neighbor_entries(protocol_interface_info_entry_t *cu ipv6_neighbour_entry_remove(&cur->ipv6_neighbour_cache, neighbour); } } - - mle_class_list_clean(cur->id); + mac_neighbor_table_neighbor_list_clean(mac_neighbor_info(cur)); } void thread_bootstrap_dynamic_configuration_save(protocol_interface_info_entry_t *cur) @@ -2883,10 +2900,10 @@ void thread_bootstrap_dynamic_configuration_save(protocol_interface_info_entry_t if (thread_i_am_router(cur)) { /* Store information of our children to the dynamic storage */ - mle_neigh_table_list_t *neig_list = mle_class_active_list_get(cur->id); - ns_list_foreach_safe(mle_neigh_table_entry_t, entry, neig_list) { - if (thread_addr_is_child(mac_helper_mac16_address_get(cur), entry->short_adr)) { - thread_dynamic_storage_child_info_store(cur->id, entry); + mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list; + ns_list_foreach_safe(mac_neighbor_table_entry_t, entry, mac_table_list) { + if (thread_addr_is_child(mac_helper_mac16_address_get(cur), entry->mac16)) { + thread_dynamic_storage_child_info_store(cur, entry); } } } @@ -2910,7 +2927,7 @@ bool thread_bootstrap_link_create_check(protocol_interface_info_entry_t *interfa return false; } - if(mle_class_free_entry_count_get(interface->id) < 1) { + if(mle_class_free_entry_count_get(interface) < 1) { // We dont have room for any new links tr_warn("Link ignore no room for addr:%x", short_address); return false; @@ -2928,7 +2945,7 @@ bool thread_bootstrap_link_create_check(protocol_interface_info_entry_t *interfa return false; } - if (mle_class_active_neigh_counter(interface->id) < THREAD_REED_AND_END_DEVICE_NEIGHBOR_LINKS + 1) { + if (mle_class_active_neigh_counter(interface) < THREAD_REED_AND_END_DEVICE_NEIGHBOR_LINKS + 1) { return true; } diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_bootstrap.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_bootstrap.h index 517321704b0e..212f1ca04491 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_bootstrap.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_bootstrap.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -52,7 +52,7 @@ struct thread_info_s; struct protocol_interface_info_entry; struct thread_leader_data_s; struct link_configuration; -struct mle_neigh_table_entry_t; +struct mac_neighbor_table_entry; struct mle_tlv_info_s; typedef enum { @@ -103,12 +103,11 @@ uint8_t thread_mode_get_by_interface_ptr(struct protocol_interface_info_entry *c void thread_bootstrap_device_synch_finish(protocol_interface_info_entry_t *cur); int8_t thread_mle_class_init(int8_t interface_id); void thread_general_mle_receive_cb(int8_t interface_id, mle_message_t *mle_msg, mle_security_header_t *security_headers); -int thread_bootstrap_reset_child_info(protocol_interface_info_entry_t *cur, struct mle_neigh_table_entry_t *child); void thread_bootstrap_ready(struct protocol_interface_info_entry *cur); int thread_bootstrap_reset(struct protocol_interface_info_entry *cur); void thread_neighbor_list_clean(struct protocol_interface_info_entry *cur); bool thread_bootstrap_request_network_data(struct protocol_interface_info_entry *cur, struct thread_leader_data_s *leaderData, uint16_t short_address); -bool thread_check_is_this_my_parent(struct protocol_interface_info_entry *cur, struct mle_neigh_table_entry_t *entry_temp); +bool thread_check_is_this_my_parent(struct protocol_interface_info_entry *cur, struct mac_neighbor_table_entry *entry_temp); void thread_clean_old_16_bit_address_based_addresses(struct protocol_interface_info_entry *cur); int8_t thread_bootsrap_event_trig(thread_bootsrap_event_type_e event_type, int8_t Id, arm_library_event_priority_e priority); void thread_interface_init(struct protocol_interface_info_entry *cur); @@ -126,7 +125,6 @@ int thread_parent_discover_start(int8_t interface_id, uint8_t *mac64 ); bool thread_device_synch_timeout(int8_t interface_id, uint16_t msgId, bool usedAllRetries); bool thread_link_request_timeout(int8_t interface_id, uint16_t msgId, bool usedAllRetries); -bool thread_instance_id_matches(struct protocol_interface_info_entry *cur, struct thread_leader_data_s *leaderData); int thread_leader_data_validation(struct protocol_interface_info_entry *cur, struct thread_leader_data_s *leaderData, struct mle_tlv_info_s *routeTlv); uint8_t thread_calculate_link_margin(int8_t dbm, uint8_t compLinkMarginFromParent); uint8_t thread_compute_link_margin(int8_t rssi); diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_border_router_api.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_border_router_api.c index acad9e474cf1..8ca402db62ba 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_border_router_api.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_border_router_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -297,19 +297,19 @@ static bool thread_border_router_local_network_data_prefix_match(thread_network_ return true; } -static void thread_border_router_child_network_data_clean(uint8_t interface_id, uint16_t child_id) +static void thread_border_router_child_network_data_clean(protocol_interface_info_entry_t *cur, uint16_t child_id) { uint8_t addr16_buf[2]; common_write_16_bit(child_id, addr16_buf); - if (mle_class_get_by_link_address(interface_id, addr16_buf, ADDR_802_15_4_SHORT)) { + if (mac_neighbor_table_address_discover(mac_neighbor_info(cur), addr16_buf, ADDR_802_15_4_SHORT)) { /* Child is available in mle, do nothing */ return; } // Child is not our child => network data contains data from lost children, remove it tr_debug("Remove nwk data from lost child: %04x", child_id); - thread_management_client_network_data_unregister(interface_id, child_id); + thread_management_client_network_data_unregister(cur->id, child_id); } static void thread_border_router_lost_children_nwk_data_validate(protocol_interface_info_entry_t *cur, uint16_t router_short_addr) @@ -326,7 +326,7 @@ static void thread_border_router_lost_children_nwk_data_validate(protocol_interf ns_list_foreach(thread_network_server_data_entry_t, curRoute, &curLP->routeList) { if (thread_addr_is_child(router_short_addr, curRoute->routerID)) { // Router children found - thread_border_router_child_network_data_clean(cur->id, curRoute->routerID); + thread_border_router_child_network_data_clean(cur, curRoute->routerID); } } @@ -334,7 +334,7 @@ static void thread_border_router_lost_children_nwk_data_validate(protocol_interf ns_list_foreach(thread_network_server_data_entry_t, curBR, &curLP->borderRouterList) { if (thread_addr_is_child(router_short_addr, curBR->routerID)) { // Router children found - thread_border_router_child_network_data_clean(cur->id, curBR->routerID); + thread_border_router_child_network_data_clean(cur, curBR->routerID); } } } @@ -344,7 +344,7 @@ static void thread_border_router_lost_children_nwk_data_validate(protocol_interf ns_list_foreach(thread_network_data_service_server_entry_t, server, &service->server_list) { if (thread_addr_is_child(router_short_addr, server->router_id)) { // Router children found - thread_border_router_child_network_data_clean(cur->id, server->router_id); + thread_border_router_child_network_data_clean(cur, server->router_id); } } } @@ -626,6 +626,7 @@ int thread_border_router_prefix_add(int8_t interface_id, uint8_t *prefix_ptr, ui service.stableData = prefix_info_ptr->stableData; service.P_on_mesh = prefix_info_ptr->P_on_mesh; service.P_nd_dns = prefix_info_ptr->P_nd_dns; + service.P_res1 = prefix_info_ptr->P_res1; return thread_local_server_list_add_on_mesh_server(&cur->thread_info->localServerDataBase, &prefixTlv, &service); #else diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_common.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_common.c index db166f84cecc..0716d79cf7ac 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_common.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, 2017, Arm Limited and affiliates. + * Copyright (c) 2014-2015, 2017-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -64,6 +64,7 @@ #include "6LoWPAN/Thread/thread_address_registration_client.h" #include "6LoWPAN/Thread/thread_resolution_client.h" #include <6LoWPAN/Thread/thread_extension_bootstrap.h> +#include "6LoWPAN/Thread/thread_neighbor_class.h" #include "MLE/mle.h" #include "Service_Libs/mle_service/mle_service_security.h" #include "Service_Libs/blacklist/blacklist.h" @@ -79,6 +80,7 @@ #include "MLE/mle_tlv.h" #include "Service_Libs/nd_proxy/nd_proxy.h" #include "Service_Libs/mle_service/mle_service_api.h" +#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h" #include "6LoWPAN/MAC/mac_helper.h" #include "6LoWPAN/MAC/mac_pairwise_key.h" #include "6LoWPAN/MAC/mac_data_poll.h" @@ -104,7 +106,7 @@ thread_leader_data_t *thread_leader_data_generate(void); thread_parent_info_t *thread_parent_data_allocate(thread_info_t *info); static uint8_t * thread_joining_port_tlv_write(uint16_t port, uint8_t *ptr); static uint8_t * thread_commissioner_port_tlv_write(uint16_t port, uint8_t *ptr); -static void thread_tx_failure_handler(int8_t nwk_id, uint8_t accumulated_failures, mle_neigh_table_entry_t *neighbor); +static void thread_tx_failure_handler(int8_t nwk_id, uint8_t accumulated_failures, uint8_t attribute_index); static void thread_address_notification_cb(struct protocol_interface_info_entry *interface, const struct if_address_entry *addr, if_address_callback_t reason); /* Helper functions*/ @@ -152,33 +154,37 @@ uint8_t *thread_management_key_request_with_sequence(int8_t interface_id, uint8_ if (!linkConfiguration) { return NULL; } + //tr_debug("MLE key request by sequence id %"PRIu8" seq %"PRIu32, keyId, keySequnce); cur = protocol_stack_interface_info_get_by_id(interface_id); - if (cur && cur->thread_info) { - if (cur->thread_info->masterSecretMaterial.valid_Info) { - if (keySequnce == linkConfiguration->key_sequence) { - if (mle_service_security_default_key_id_get(interface_id) == keyId) { - keyPtr = mle_service_security_default_key_get(interface_id); - } - } else if (keySequnce == (linkConfiguration->key_sequence + 1)) { - if (mle_service_security_next_key_id_get(interface_id) == keyId) { - keyPtr = mle_service_security_next_key_get(interface_id); - } - } - - if (!keyPtr) { - tr_debug("Gen temporary key id %"PRIu8" seq %"PRIu32, keyId, keySequnce); - thread_key_get(linkConfiguration->master_key, cur->thread_info->masterSecretMaterial.historyKey, keySequnce); - cur->thread_info->masterSecretMaterial.historyKeyId = keyId; - cur->thread_info->masterSecretMaterial.historyKeyValid = false; - keyPtr = cur->thread_info->masterSecretMaterial.historyKey; - } + if (!cur || !cur->thread_info) { + return NULL; + } + if (!cur->thread_info->masterSecretMaterial.valid_Info) { + return NULL; + } + if (keySequnce == linkConfiguration->key_sequence) { + if (mle_service_security_default_key_id_get(interface_id) == keyId) { + keyPtr = mle_service_security_default_key_get(interface_id); } + } else if (keySequnce == (linkConfiguration->key_sequence + 1)) { + if (mle_service_security_next_key_id_get(interface_id) == keyId) { + keyPtr = mle_service_security_next_key_get(interface_id); + } + } + + if (!keyPtr) { + tr_debug("Gen temporary key id %"PRIu8" seq %"PRIu32, keyId, keySequnce); + thread_key_get(linkConfiguration->master_key, cur->thread_info->masterSecretMaterial.historyKey, keySequnce); + cur->thread_info->masterSecretMaterial.historyKeyId = keyId; + cur->thread_info->masterSecretMaterial.historyKeyValid = false; + keyPtr = cur->thread_info->masterSecretMaterial.historyKey; } return keyPtr; } uint8_t * thread_mle_service_security_notify_cb(int8_t interface_id, mle_security_event_t event, uint8_t keyId) { + (void)keyId; protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id); if (!interface) { return NULL; @@ -197,7 +203,7 @@ uint8_t * thread_mle_service_security_notify_cb(int8_t interface_id, mle_securit break; case MLE_SEC_UNKNOWN_KEY: - return thread_management_key_request(interface_id,keyId); + return NULL; } return NULL; } @@ -360,23 +366,31 @@ bool thread_connectivity_tlv_parse(uint8_t *ptr, uint16_t dataLength, thread_con return false; } -void thread_calculate_key_guard_timer(protocol_interface_info_entry_t *cur, link_configuration_s *linkConfiguration, bool is_init) +void thread_key_guard_timer_calculate(protocol_interface_info_entry_t *cur, link_configuration_s *linkConfiguration, bool is_init) { uint32_t key_rotation = linkConfiguration ? linkConfiguration->key_rotation : 0; - if (is_init && key_rotation < 3600) { + if (is_init && key_rotation < 1) { tr_warn("Attempted to set key rotation time smaller than 1 hour."); - key_rotation = 3600; + key_rotation = 1; } - cur->thread_info->masterSecretMaterial.keyRotation = key_rotation; - cur->thread_info->masterSecretMaterial.keySwitchGuardTimer = is_init ? 0 : (key_rotation * 0.93); + cur->thread_info->masterSecretMaterial.keyRotation = key_rotation * 3600; // setting value is hours converting to seconds + cur->thread_info->masterSecretMaterial.keySwitchGuardTimer = is_init ? 0 : (key_rotation * 3600 * 0.93); +} + +void thread_key_guard_timer_reset(protocol_interface_info_entry_t *cur) +{ + cur->thread_info->masterSecretMaterial.keySwitchGuardTimer = 0; } thread_leader_data_t *thread_leader_data_generate(void) { thread_leader_data_t *leader_data; leader_data = ns_dyn_mem_alloc(sizeof(thread_leader_data_t)); + if (leader_data) { + memset(leader_data,0,sizeof(thread_leader_data_t)); + } return leader_data; } @@ -663,16 +677,27 @@ thread_mcast_child_t *thread_child_mcast_entry_find(thread_mcast_children_list_t return NULL; } +bool thread_stable_context_check(protocol_interface_info_entry_t *cur, buffer_t *buf) +{ + mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur),buf->dst_sa.address + 2 , buf->dst_sa.addr_type); + if (entry && thread_addr_is_child(mac_helper_mac16_address_get(cur), entry->mac16)) { + + /* Check if the child can handle only stable network data (e.g. sleepy device) */ + return !(thread_neighbor_class_request_full_data_setup(&cur->thread_info->neighbor_class, entry->index)); + } + return false; +} + thread_mcast_child_t *thread_child_mcast_entry_get(protocol_interface_info_entry_t *cur, const uint8_t *mcast_addr, const uint8_t *mac64) { - mle_neigh_table_entry_t *mle_entry = mle_class_get_by_link_address(cur->id, mac64, ADDR_802_15_4_LONG); + mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), mac64, ADDR_802_15_4_LONG); - if (!mle_entry) { + if (!entry) { tr_error("No MLE entry."); return NULL; } - if (mle_entry->mode & MLE_RX_ON_IDLE) { + if (entry->rx_on_idle) { /* Not a sleepy child */ tr_debug("Not a sleepy child"); return NULL; @@ -791,8 +816,6 @@ int thread_init(protocol_interface_info_entry_t *cur) return -1; } - mle_class_router_challenge(cur->id, NULL); - if (etx_accum_failures_callback_register(cur->nwk_id, cur->id, 1, thread_tx_failure_handler) != 1) { return -1; } @@ -803,7 +826,6 @@ int thread_init(protocol_interface_info_entry_t *cur) thread_data_base_init(cur->thread_info, cur->id); mac_helper_pib_boolean_set(cur,macThreadForceLongAddressForBeacon , true); mac_helper_mac16_address_set(cur, 0xffff); - mle_class_mode_set(cur->id, MLE_CLASS_END_DEVICE); return 0; } @@ -817,7 +839,7 @@ int thread_attach_ready(protocol_interface_info_entry_t *cur) case THREAD_STATE_CONNECTED: case THREAD_STATE_CONNECTED_ROUTER: return 0; - break; + /* break; */ default: break; } @@ -919,7 +941,7 @@ static void thread_key_switch_timer(protocol_interface_info_entry_t *cur, uint16 tr_debug("thrKeyRotation == 0: sync key material by %"PRIu32, linkConfiguration->key_sequence + 1); thread_management_key_sets_calc(cur, linkConfiguration, linkConfiguration->key_sequence + 1); - thread_calculate_key_guard_timer(cur, linkConfiguration, false); + thread_key_guard_timer_calculate(cur, linkConfiguration, false); } } @@ -1019,14 +1041,15 @@ void thread_timer(protocol_interface_info_entry_t *cur, uint8_t ticks) return; } - if (thread_i_am_router(cur)) { + if (cur->nwk_bootstrap_state != ER_BOOTSRAP_DONE && cur->nwk_bootstrap_state != ER_MLE_ATTACH_READY) { + /* Own attach is ongoing, do not send advertisements */ + return; + } + if (thread_i_am_router(cur)) { if (thread_routing_timer(thread_info, ticks)) { thread_router_bootstrap_mle_advertise(cur); } - - } else { - } } @@ -1121,14 +1144,20 @@ uint8_t thread_beacon_indication(uint8_t *ptr, uint8_t len, protocol_interface_i static uint8_t *thread_linkquality_write(int8_t interface_id, uint8_t *buffer) { + protocol_interface_info_entry_t *interface_ptr = protocol_stack_interface_info_get_by_id(interface_id); + if (!interface_ptr && !interface_ptr->thread_info) { + return buffer; + } + uint8_t lqi1 = 0, lqi2 = 0, lqi3 = 0; thread_link_quality_e thread_link_quality; - mle_neigh_table_list_t *neigh_list = mle_class_active_list_get(interface_id); + mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(interface_ptr)->neighbour_list; - ns_list_foreach(mle_neigh_table_entry_t, cur, neigh_list) { - if (thread_is_router_addr(cur->short_adr)) { + ns_list_foreach(mac_neighbor_table_entry_t, cur, mac_table_list) { + if (thread_is_router_addr(cur->mac16)) { // Only count routers to link quality - thread_link_quality = thread_link_margin_to_quality(cur->link_margin); + uint16_t link_margin = thread_neighbor_entry_linkmargin_get(&interface_ptr->thread_info->neighbor_class, cur->index); + thread_link_quality = thread_link_margin_to_quality(link_margin); switch (thread_link_quality) { case QUALITY_20dB: lqi3++; @@ -1193,14 +1222,14 @@ uint8_t *thread_connectivity_tlv_write(uint8_t *ptr, protocol_interface_info_ent *ptr++ = 10; // determine parent priority - if ((mode & MLE_DEV_MASK) == MLE_RFD_DEV && (3*mle_class_rfd_entry_count_get(cur->id) > 2*THREAD_MAX_MTD_CHILDREN)) { + if ((mode & MLE_DEV_MASK) == MLE_RFD_DEV && (3*mle_class_rfd_entry_count_get(cur) > 2*THREAD_MAX_MTD_CHILDREN)) { *ptr++ = CONNECTIVITY_PP_LOW; - } else if (!(mode & MLE_RX_ON_IDLE) && (3*mle_class_sleepy_entry_count_get(cur->id) > 2*THREAD_MAX_SED_CHILDREN)) { + } else if (!(mode & MLE_RX_ON_IDLE) && (3*mle_class_sleepy_entry_count_get(cur) > 2*THREAD_MAX_SED_CHILDREN)) { *ptr++ = CONNECTIVITY_PP_LOW; } else if (3*thread_router_bootstrap_child_count_get(cur) > 2*thread->maxChildCount) { // 1/3 of the child capacity remaining, PP=low *ptr++ = CONNECTIVITY_PP_LOW; - } else if (mle_class_free_entry_count_get(cur->id) < THREAD_FREE_MLE_ENTRY_THRESHOLD) { + } else if (mle_class_free_entry_count_get(cur) < THREAD_FREE_MLE_ENTRY_THRESHOLD) { // If only few entries available in the MLE table, change priority to low *ptr++ = CONNECTIVITY_PP_LOW; } else { @@ -1829,7 +1858,7 @@ static uint8_t * thread_commissioner_port_tlv_write(uint16_t port, uint8_t *ptr) return common_write_16_bit(port, ptr); } -static void thread_tx_failure_handler(int8_t nwk_id, uint8_t accumulated_failures, mle_neigh_table_entry_t *neighbor) +static void thread_tx_failure_handler(int8_t nwk_id, uint8_t accumulated_failures, uint8_t attribute_index) { protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(nwk_id); @@ -1839,27 +1868,33 @@ static void thread_tx_failure_handler(int8_t nwk_id, uint8_t accumulated_failure return; } + mac_neighbor_table_entry_t *neighbor = mac_neighbor_table_attribute_discover(mac_neighbor_info(cur), attribute_index); + if (!neighbor) { + return; + } + if (accumulated_failures >= THREAD_MAC_TRANSMISSIONS*THREAD_FAILED_CHILD_TRANSMISSIONS) { - mle_class_remove_entry(cur->id, neighbor); + mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), neighbor); } } /* Called when MLE link to neighbour lost, or ETX callback says link is bad */ -void thread_reset_neighbour_info(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *neighbour) +void thread_reset_neighbour_info(protocol_interface_info_entry_t *cur, mac_neighbor_table_entry_t *neighbour) { thread_parent_info_t *thread_endnode_parent = thread_info(cur)->thread_endnode_parent; - if (!thread_i_am_router(cur) && thread_endnode_parent && thread_endnode_parent->shortAddress == neighbour->short_adr) { + if (!thread_i_am_router(cur) && thread_endnode_parent && thread_endnode_parent->shortAddress == neighbour->mac16) { if(cur->nwk_bootstrap_state != ER_CHILD_ID_REQ) { tr_warn("End device lost parent, reset!\n"); thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL); } } - thread_routing_remove_link(cur, neighbour->short_adr); + thread_routing_remove_link(cur, neighbour->mac16); thread_router_bootstrap_reset_child_info(cur, neighbour); protocol_6lowpan_release_long_link_address_from_neighcache(cur, neighbour->mac64); - mac_helper_devicetable_remove(cur->mac_api, neighbour->attribute_index); + mac_helper_devicetable_remove(cur->mac_api, neighbour->index); + thread_neighbor_class_entry_remove(&cur->thread_info->neighbor_class, neighbour->index); } uint8_t thread_get_router_count_from_route_tlv(mle_tlv_info_t *routeTlv) @@ -1894,7 +1929,7 @@ static void thread_address_notification_cb(struct protocol_interface_info_entry } else { if (reason == ADDR_CALLBACK_DAD_COMPLETE) { /* Send address notification (our parent doesn't do that for us) */ - thread_extension_address_registration(interface, addr->address, NULL); + thread_extension_address_registration(interface, addr->address, NULL, false, false); } } } @@ -1902,9 +1937,6 @@ static void thread_address_notification_cb(struct protocol_interface_info_entry void thread_mcast_group_change(struct protocol_interface_info_entry *interface, if_group_entry_t *group, bool addr_added) { - (void) addr_added; - - group->mld_timer = 0; if (thread_attach_ready(interface) != 0) { return; @@ -1918,11 +1950,13 @@ void thread_mcast_group_change(struct protocol_interface_info_entry *interface, interface->thread_info->childUpdateReqTimer = 1; } } else { - thread_extension_mcast_subscrition_change(interface, group, addr_added); + if (addr_added) { + thread_address_registration_timer_set(interface, 0, 1); + } } } -void thread_old_partition_data_purge(protocol_interface_info_entry_t *cur) +void thread_partition_data_purge(protocol_interface_info_entry_t *cur) { /* Partition has been changed. Wipe out data related to old partition */ thread_management_client_pending_coap_request_kill(cur->id); @@ -1935,5 +1969,33 @@ void thread_old_partition_data_purge(protocol_interface_info_entry_t *cur) } +bool thread_partition_match(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData) +{ + if (thread_info(cur)->thread_leader_data) { + if ((thread_info(cur)->thread_leader_data->partitionId == leaderData->partitionId) && + (thread_info(cur)->thread_leader_data->weighting == leaderData->weighting)) { + return true; + } + } + return false; +} + +void thread_partition_info_update(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData) +{ + /* Force network data update later when processing network data TLV */ + thread_info(cur)->thread_leader_data->dataVersion = leaderData->dataVersion - 1; + thread_info(cur)->thread_leader_data->stableDataVersion = leaderData->stableDataVersion - 1; + thread_info(cur)->thread_leader_data->leaderRouterId = leaderData->leaderRouterId; + thread_info(cur)->thread_leader_data->partitionId = leaderData->partitionId; + thread_info(cur)->thread_leader_data->weighting = leaderData->weighting; + /* New network data learned, get rid of old partition data */ + thread_partition_data_purge(cur); +} + +void thread_neighbor_communication_update(protocol_interface_info_entry_t *cur, uint8_t neighbor_attribute_index) +{ + thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, neighbor_attribute_index); +} + #endif diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_common.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_common.h index b06b9454e442..09ffce3900fe 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_common.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -40,6 +40,8 @@ #include "eventOS_event_timer.h" #include "MLE/mle_tlv.h" +struct mac_neighbor_table_entry; + #define MAX_MLE_CHALLENGE_LENGTH 32 /* @@ -55,8 +57,8 @@ #define NETWORK_ID_TIMEOUT 120 //seconds // Values when adverticements are made faster when leader connection is restored -#define NETWORK_ID_SPEEDUP 60 //seconds -#define NETWORK_ID_SPEEDUP_MAX 100 //seconds +#define NETWORK_ID_SPEEDUP 55 //seconds +#define NETWORK_ID_SPEEDUP_MAX 80 //seconds #define DHCPV6_ENTERPRISE_THREAD 0x0000AFAA #define DHCPV6_OPTION_VENDOR_SPESIFIC_INFO_LEN 0x0011 @@ -92,6 +94,22 @@ typedef enum { THREAD_COMMISSIONER_REGISTERED } thread_commissioner_register_status_e; +typedef struct thread_neigh_table_entry_s { + uint8_t mlEid[8]; + uint32_t last_contact_time; /*!< monotonic time - hard to define "contact"; used for Thread Leasequery replies */ + uint16_t link_margin; + bool secured_data_request:1; + bool request_full_data_set:1; +} thread_neigh_table_entry_t ; + +/** + * Neighbor info data base + */ +typedef struct thread_neighbor_class_s { + thread_neigh_table_entry_t *neigh_info_list; /*!< Allocated Neighbour info array*/ + uint8_t list_size; /*!< List size*/ +} thread_neighbor_class_t; + typedef struct thread_mcast_child { uint8_t mac64[8]; ns_list_link_t link; @@ -261,6 +279,7 @@ typedef struct thread_previous_partition_info_s { typedef struct thread_info_s { thread_routing_info_t routing; + thread_neighbor_class_t neighbor_class; thread_master_secret_material_t masterSecretMaterial; thread_network_data_cache_entry_t networkDataStorage; thread_network_local_data_cache_entry_t localServerDataBase; @@ -363,7 +382,7 @@ uint16_t thread_network_data_generate_stable_set(protocol_interface_info_entry_t void thread_set_active_router(protocol_interface_info_entry_t *cur, if_address_entry_t *address_entry, uint8_t *routerId); uint8_t thread_get_router_count_from_route_tlv(mle_tlv_info_t *routeTlv); -void thread_reset_neighbour_info(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *neighbour); +void thread_reset_neighbour_info(protocol_interface_info_entry_t *cur, struct mac_neighbor_table_entry *neighbour); void thread_child_id_request_entry_clean(protocol_interface_info_entry_t *cur); thread_pending_child_id_req_t *thread_child_id_request_entry_get(protocol_interface_info_entry_t *cur, uint8_t *euid64); @@ -413,15 +432,19 @@ uint8_t *thread_pending_operational_dataset_write(protocol_interface_info_entry_ bool thread_pending_operational_dataset_process(protocol_interface_info_entry_t *cur, uint64_t mle_pending_timestamp, uint8_t *ptr, uint16_t len); /*Write optional thread leader data TLV if leader data is known*/ uint8_t thread_pending_timestamp_tlv_size(protocol_interface_info_entry_t *cur); -void thread_calculate_key_guard_timer(protocol_interface_info_entry_t *cur, link_configuration_s *linkConfiguration, bool is_init); +void thread_key_guard_timer_calculate(protocol_interface_info_entry_t *cur, link_configuration_s *linkConfiguration, bool is_init); +void thread_key_guard_timer_reset(protocol_interface_info_entry_t *cur); void thread_set_link_local_address(protocol_interface_info_entry_t *cur); void thread_mcast_group_change(struct protocol_interface_info_entry *interface, struct if_group_entry *group, bool group_added); -void thread_old_partition_data_purge(protocol_interface_info_entry_t *cur); - +void thread_partition_data_purge(protocol_interface_info_entry_t *cur); +bool thread_partition_match(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData); +void thread_partition_info_update(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData); +void thread_neighbor_communication_update(protocol_interface_info_entry_t *cur, uint8_t neighbor_attribute_index); +bool thread_stable_context_check(protocol_interface_info_entry_t *cur, buffer_t *buf); #else // HAVE_THREAD NS_DUMMY_DEFINITIONS_OK - +#define thread_stable_context_check(cur, buf) (false) #define thread_info(cur) ((thread_info_t *) NULL) #define thread_am_router(cur) (false) #define thread_am_host(cur) (false) @@ -438,6 +461,7 @@ NS_DUMMY_DEFINITIONS_OK #define thread_link_reject_send(interface, ll64) 0 #define thread_addr_is_mesh_local_16(addr, cur) false #define thread_mcast_group_change(interface, group, group_added) ((void)0) +#define thread_neighbor_communication_update(cur, neighbor_attribute_index) ((void)0) #endif // HAVE_THREAD #endif /* LOWPAN_THREAD_H_ */ diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_config.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_config.h index ca689a004f23..0db796cd5d91 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_config.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_config.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_constants.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_constants.h index 978606b360b2..4150f4cc2376 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_constants.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_constants.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, Arm Limited and affiliates. + * Copyright (c) 2016-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_dhcpv6_client.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_dhcpv6_client.c index 642857bdd708..a49054e3ed06 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_dhcpv6_client.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_dhcpv6_client.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017, Arm Limited and affiliates. + * Copyright (c) 2013-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_diagnostic.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_diagnostic.c index 673aa22df97c..fdce83ece823 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_diagnostic.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_diagnostic.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, Arm Limited and affiliates. + * Copyright (c) 2016-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -39,6 +39,7 @@ #include "thread_joiner_application.h" #include "thread_leader_service.h" #include "thread_router_bootstrap.h" +#include "6LoWPAN/Thread/thread_neighbor_class.h" #include "MLE/mle.h" #include "6LoWPAN/Thread/thread_router_bootstrap.h" #include "thread_config.h" @@ -47,6 +48,7 @@ #include "thread_diagcop_lib.h" #include "common_functions.h" #include "6LoWPAN/MAC/mac_helper.h" +#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h" #include "mac_api.h" @@ -93,31 +95,31 @@ static uint8_t *thread_diagnostic_child_table_tlv_build(uint8_t *data_ptr, proto uint8_t child_count = 0; uint8_t calculated_timeout; - mle_neigh_table_list_t *mle_table = mle_class_active_list_get(cur->id); - if (!mle_table) { - return data_ptr; - } + mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list; child_count = thread_router_bootstrap_child_count_get(cur); *data_ptr++ = DIAGCOP_TLV_CHILD_TABLE; // Type *data_ptr++ = (3 * child_count); // Length - ns_list_foreach(mle_neigh_table_entry_t, cur_entry, mle_table) { - if (cur_entry->threadNeighbor && thread_router_addr_from_addr(cur_entry->short_adr) == mac_helper_mac16_address_get(cur)){ + ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, mac_table_list) { + if (thread_router_addr_from_addr(cur_entry->mac16) == mac_helper_mac16_address_get(cur)){ /* |0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1|2|3| */ /* |Timeout |Rsv| Child ID | Mode | */ - calculated_timeout = thread_log2_aprx((cur_entry->timeout_rx-1)*MLE_TIMER_TICKS_SECONDS) + 4; - tr_debug("Write child table TLV entry: %d - %d - %d", calculated_timeout, cur_entry->short_adr, cur_entry->mode); + calculated_timeout = thread_log2_aprx(cur_entry->link_lifetime - 1) + 4; + uint8_t mode = 0; + mode |= mle_mode_write_from_mac_entry(cur_entry); + mode |= thread_neighbor_class_mode_write_from_entry(&cur->thread_info->neighbor_class, cur_entry->index); + tr_debug("Write child table TLV entry: %d - %d - %d", calculated_timeout, cur_entry->mac16, mode); *data_ptr = 0x00; //reserved bytes to zero *data_ptr = calculated_timeout << 3; - if(cur_entry->short_adr & 0x0100){ + if(cur_entry->mac16 & 0x0100){ *data_ptr = *data_ptr | 0x01; } data_ptr++; - *data_ptr++ = (uint8_t)(cur_entry->short_adr & 0x00ff); - *data_ptr++ = cur_entry->mode; + *data_ptr++ = (uint8_t)(cur_entry->mac16 & 0x00ff); + *data_ptr++ = mode; } } diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_discovery.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_discovery.c index b9e484f341a4..8597483fa187 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_discovery.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_discovery.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, Arm Limited and affiliates. + * Copyright (c) 2016-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -818,7 +818,7 @@ static void thread_discovery_request_msg_handler(thread_discovery_class_t * disc tr_debug("Thread discovery request message RX"); // Check if we have room for new neighbor - if (mle_class_free_entry_count_get(discovery_class->interface_id) < 1) { + if (mle_class_free_entry_count_get(discovery_class->interface) < 1) { tr_debug("MLE table full, skip request"); return; } @@ -1281,10 +1281,10 @@ static void thread_discovery_normal_receive_cb(int8_t interface_id, mle_message_ /** * Start Thread network discovery */ -int thread_discovery_network_scan(int8_t interface_id, thread_discover_reques_t *scan_request, thread_discovery_ready_cb *ready_cb) +int thread_discovery_network_scan(struct protocol_interface_info_entry *cur_interface, thread_discover_reques_t *scan_request, thread_discovery_ready_cb *ready_cb) { - thread_discovery_class_t * discovery_class = thread_discovery_class_get(interface_id); + thread_discovery_class_t * discovery_class = thread_discovery_class_get(cur_interface->id); if (!discovery_class || !ready_cb || !scan_request) { return -1; } @@ -1304,12 +1304,12 @@ int thread_discovery_network_scan(int8_t interface_id, thread_discover_reques_t return -3; } - if (mle_service_interface_register(interface_id, thread_discovery_normal_receive_cb, discovery_class->discovery_request->temporary_mac64,8) != 0) { + if (mle_service_interface_register(cur_interface->id, cur_interface, thread_discovery_normal_receive_cb, discovery_class->discovery_request->temporary_mac64,8) != 0) { thread_discovery_request_free(discovery_class); return -1; } - if (mle_service_interface_receiver_bypass_handler_update(interface_id, thread_discovery_message_receiver_cb) != 0) { + if (mle_service_interface_receiver_bypass_handler_update(cur_interface->id, thread_discovery_message_receiver_cb) != 0) { thread_discovery_request_free(discovery_class); return -1; } diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_discovery.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_discovery.h index 35487ebec063..dd08496bf6f2 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_discovery.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_discovery.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, Arm Limited and affiliates. + * Copyright (c) 2016-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -122,7 +122,7 @@ int thread_discovery_responser_enable(int8_t interface_id, bool enable_service); /** * Start Thread network discovery */ -int thread_discovery_network_scan(int8_t interface_id, thread_discover_reques_t *scan_request, thread_discovery_ready_cb *ready_cb); +int thread_discovery_network_scan(struct protocol_interface_info_entry *cur_interface, thread_discover_reques_t *scan_request, thread_discovery_ready_cb *ready_cb); /** * Start device orphan scan diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_extension.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_extension.h index 8e7a555e0193..671ea9823c8e 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_extension.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_extension.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, Arm Limited and affiliates. + * Copyright (c) 2016-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -40,27 +40,66 @@ extern "C" { struct discovery_response_list; +#ifdef HAVE_THREAD_V2 + +void thread_extension_allocate(protocol_interface_info_entry_t *cur); +void thread_extension_free(protocol_interface_info_entry_t *cur); +void thread_extension_init(int8_t interface_id, int8_t coap_service_id); +void thread_extension_mtd_service_register(protocol_interface_info_entry_t *cur); +int thread_extension_network_prefix_get(int8_t interface_id, uint8_t *options_ptr, uint8_t *prefix_ptr, uint8_t *prefix_len); +void thread_extension_network_data_process(struct protocol_interface_info_entry *cur); +int thread_extension_primary_bbr_get(struct protocol_interface_info_entry *cur, uint8_t *addr_ptr, uint8_t *seq_ptr, uint32_t *timer1_ptr, uint32_t *timer2_ptr); +void thread_extension_address_registration(struct protocol_interface_info_entry *interface, const uint8_t *addr, const uint8_t *child_mac64, bool refresh_child_entry, bool duplicate_child_detected); +void thread_extension_address_generate(protocol_interface_info_entry_t *cur); +void thread_extension_aloc_generate(struct protocol_interface_info_entry *cur); +bool thread_extension_aloc_map(protocol_interface_info_entry_t *cur, uint16_t *addr16); +void thread_extension_mcast_subscrition_change(protocol_interface_info_entry_t *interface); +void thread_extension_address_registration_trigger(protocol_interface_info_entry_t *interface); +void thread_extension_route_set(protocol_interface_info_entry_t *cur); +void thread_extension_activate(protocol_interface_info_entry_t *cur); +bool thread_extension_enabled(protocol_interface_info_entry_t *cur); +bool thread_extension_context_can_delete(int8_t id, uint8_t servicesPrefix[16], uint8_t context_prefix_length); +bool thread_extension_version_check(uint8_t version); +void thread_extension_discover_response_read(struct discovery_response_list *nwk_info, uint16_t discover_response_tlv, uint8_t *data_ptr, uint16_t data_len); +void thread_extension_discover_response_tlv_write(uint16_t *data, uint8_t version, uint16_t securityPolicy); +int thread_extension_service_init(protocol_interface_info_entry_t *cur); +void thread_extension_addr_ntf_send(struct protocol_interface_info_entry *cur, uint8_t *destination_address, const uint8_t *addr_data_ptr, uint8_t bbr_status); +#ifdef HAVE_THREAD_ROUTER +bool thread_extension_joining_enabled(int8_t interface_id); +uint8_t thread_extension_discover_response_len(protocol_interface_info_entry_t *cur); +uint8_t *thread_extension_discover_response_write(protocol_interface_info_entry_t *cur, uint8_t *ptr); + +#else +#define thread_extension_joining_enabled(interface_id) false +#define thread_extension_discover_response_len(cur) 0 +#define thread_extension_discover_response_write(cur, ptr) (ptr) +#endif //HAVE_THREAD_ROUTER +#else + #define thread_extension_allocate(cur) #define thread_extension_free(cur) #define thread_extension_init(interface_id,coap_service_id) #define thread_extension_network_prefix_get(interface_id,options_ptr,prefix_ptr,prefix_len) (-1) #define thread_extension_network_data_process(cur) #define thread_extension_primary_bbr_get(cur,addr_ptr,seq_ptr,timer1_ptr, timer2_ptr) (-1) -#define thread_extension_address_registration(interface,addr,child_mac64) +#define thread_extension_address_registration(interface,addr,child_mac64,refresh_child_entry,duplicate_child_detected) #define thread_extension_address_generate(cur) #define thread_extension_aloc_generate(cur) #define thread_extension_aloc_map(cur, addr16) false -#define thread_extension_mcast_subscrition_change(interface, group, added) +#define thread_extension_mcast_subscrition_change(interface) #define thread_extension_route_set(cur) #define thread_extension_activate(cur) #define thread_extension_enabled(cur) (false) #define thread_extension_version_check(version) (false) #define thread_extension_discover_response_read(nwk_info, discover_response_tlv, data_ptr, data_len) #define thread_extension_discover_response_tlv_write(data, version, extension_bit) (data) -#define thread_extension_joiner_router_init(interface_id) +#define thread_extension_service_init(cur) 0 #define thread_extension_joining_enabled(interface_id) false #define thread_extension_discover_response_len(cur) 0 #define thread_extension_discover_response_write(cur, ptr) (ptr) +#define thread_extension_addr_ntf_send(cur,destination_address,addr_data_ptr,bbr_status) +#define thread_extension_context_can_delete(id, servicesPrefix, context_prefix_length) false +#endif #ifdef __cplusplus } diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_extension_bbr.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_extension_bbr.h index 5e4ac8f8c157..cad08464b09a 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_extension_bbr.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_extension_bbr.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Arm Limited and affiliates. + * Copyright (c) 2017-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -38,6 +38,14 @@ extern "C" { #endif +/* + * Thread PBBR ML-EID map structure + */ +typedef struct thread_pbbr_dua_info { + uint8_t mleid_ptr[8]; + uint32_t last_contact_time; +} thread_pbbr_dua_info_t; + #if defined(HAVE_THREAD_V2) && defined(HAVE_THREAD_BORDER_ROUTER) int8_t thread_extension_bbr_init(int8_t interface_id, int8_t backbone_interface_id); @@ -47,6 +55,7 @@ void thread_extension_bbr_seconds_timer(int8_t interface_id, uint32_t seconds); int thread_extension_bbr_timeout_set(int8_t interface_id, uint32_t timeout_a, uint32_t timeout_b, uint32_t delay); int thread_extension_bbr_address_set(int8_t interface_id, const uint8_t *addr_ptr, uint16_t port); void thread_extension_bbr_route_update(protocol_interface_info_entry_t *cur); +int thread_extension_bbr_prefix_set(int8_t interface_id, uint8_t *prefix); #else @@ -58,6 +67,7 @@ void thread_extension_bbr_route_update(protocol_interface_info_entry_t *cur); #define thread_extension_bbr_timeout_set(interface_id, timeout_a, timeout_b, delay) #define thread_extension_bbr_address_set(interface_id, addr_ptr, port) (-1) #define thread_extension_bbr_route_update(cur) +#define thread_extension_bbr_prefix_set(interface_id, prefix) 0 #endif #ifdef __cplusplus diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_host_bootstrap.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_host_bootstrap.c index b1cf6441477d..503666161209 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_host_bootstrap.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_host_bootstrap.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -63,6 +63,7 @@ #include "6LoWPAN/Thread/thread_management_client.h" #include "6LoWPAN/Thread/thread_network_data_lib.h" #include "6LoWPAN/Thread/thread_tmfcop_lib.h" +#include "6LoWPAN/Thread/thread_neighbor_class.h" #include "thread_management_if.h" #include "Common_Protocols/ipv6.h" #include "MPL/mpl.h" @@ -73,6 +74,7 @@ #include "6LoWPAN/MAC/mac_helper.h" #include "6LoWPAN/MAC/mac_data_poll.h" #include "Core/include/address.h" +#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h" #define TRACE_GROUP "tebs" @@ -122,7 +124,8 @@ static void thread_merge_prepare(protocol_interface_info_entry_t *cur) thread_clean_old_16_bit_address_based_addresses(cur); mpl_clear_realm_scope_seeds(cur); ipv6_route_table_remove_info(cur->id, ROUTE_THREAD_PROXIED_HOST, NULL); - thread_old_partition_data_purge(cur); + ipv6_route_table_remove_info(cur->id, ROUTE_THREAD_PROXIED_DUA_HOST, NULL); + thread_partition_data_purge(cur); thread_network_data_clean(cur); cur->nwk_mode = ARM_NWK_GP_IP_MODE; } @@ -145,7 +148,7 @@ static bool thread_parent_discover_timeout_cb(int8_t interface_id, uint16_t msgI uint8_t ll64[16]; thread_scanned_parent_t *parent = cur->thread_info->thread_attach_scanned_parent; link_configuration_s *linkConfiguration; - mle_neigh_table_entry_t *entry_temp; + mac_neighbor_table_entry_t *entry_temp; linkConfiguration = thread_joiner_application_get_config(interface_id); if (!linkConfiguration) { @@ -156,22 +159,25 @@ static bool thread_parent_discover_timeout_cb(int8_t interface_id, uint16_t msgI memcpy(ll64, ADDR_LINK_LOCAL_PREFIX , 8); memcpy(&ll64[8], parent->mac64 , 8); ll64[8] ^= 2; - - entry_temp = mle_class_get_entry_by_ll64(interface_id, parent->linkMarginToParent,ll64, true, &new_entry_created); + entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), ll64, true, &new_entry_created); if (entry_temp == NULL) { return false; } - entry_temp->threadNeighbor = true; - entry_temp->short_adr = parent->shortAddress; - entry_temp->priorityFlag = true; - entry_temp->holdTime = 90; - entry_temp->mle_frame_counter = parent->mleFrameCounter; + thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index, parent->linkMarginToParent, new_entry_created); + thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index); + + entry_temp->mac16 = parent->shortAddress; + entry_temp->link_role = PRIORITY_PARENT_NEIGHBOUR; + + mle_service_frame_counter_entry_add(interface_id, entry_temp->index, parent->mleFrameCounter); thread_management_key_sets_calc(cur, linkConfiguration, cur->thread_info->thread_attach_scanned_parent->keySequence); - thread_calculate_key_guard_timer(cur, linkConfiguration, true); + thread_key_guard_timer_calculate(cur, linkConfiguration, true); - mac_helper_devicetable_set(entry_temp, cur, parent->linLayerFrameCounter, mac_helper_default_key_index_get(cur), new_entry_created); - mle_entry_timeout_update(entry_temp, THREAD_DEFAULT_LINK_LIFETIME); + mlme_device_descriptor_t device_desc; + mac_helper_device_description_write(cur, &device_desc, entry_temp->mac64, entry_temp->mac16,parent->linLayerFrameCounter, false); + mac_helper_devicetable_set(&device_desc, cur,entry_temp->index, mac_helper_default_key_index_get(cur), new_entry_created); + mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, THREAD_DEFAULT_LINK_LIFETIME); if (cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_SLEEPY_END_DEVICE) { nwk_thread_host_control(cur, NET_HOST_FAST_POLL_MODE, 50); @@ -284,6 +290,8 @@ void thread_network_attach_start(protocol_interface_info_entry_t *cur) tr_debug("MLE Parent request"); cur->nwk_bootstrap_state = ER_MLE_SCAN; cur->bootsrap_state_machine_cnt = 0; + /* advance trickle timer by 6 (in 100ms ticks) seconds if needed */ + thread_routing_trickle_advance(&cur->thread_info->routing, 6*10); } else { cur->bootsrap_state_machine_cnt = 5; } @@ -297,7 +305,7 @@ static int thread_end_device_synch_response_validate(protocol_interface_info_ent uint16_t address16; uint32_t llFrameCounter; thread_leader_data_t leaderData; - mle_neigh_table_entry_t *entry_temp; + mac_neighbor_table_entry_t *entry_temp; bool new_entry_created; tr_debug("Validate Link Synch Response"); @@ -323,31 +331,36 @@ static int thread_end_device_synch_response_validate(protocol_interface_info_ent if (securityHeader->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) { thread_management_key_synch_req(cur->id, common_read_32_bit(securityHeader->Keysource)); + // if learning key sequence from link sync actual guard timer value is not known + thread_key_guard_timer_reset(cur); } else { tr_debug("Key ID Mode 2 not used; dropped."); return -3; } //Update parent link information - entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, src_address, true, &new_entry_created); + entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), src_address, true, &new_entry_created); if (!entry_temp) { tr_debug("Neighbor allocate fail"); return -2; } + thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index, linkMargin, new_entry_created); + thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index); /* */ - entry_temp->threadNeighbor = true; - entry_temp->short_adr = srcAddress; - entry_temp->handshakeReady = 1; - entry_temp->holdTime = 90; - entry_temp->priorityFlag = true; // Make this our parent - common_write_16_bit(entry_temp->short_adr, shortAddress); + entry_temp->mac16 = srcAddress; + entry_temp->connected_device = 1; + entry_temp->link_role = PRIORITY_PARENT_NEIGHBOUR; // Make this our parent + common_write_16_bit(entry_temp->mac16, shortAddress); mac_helper_coordinator_address_set(cur, ADDR_802_15_4_SHORT, shortAddress); - mle_entry_timeout_update(entry_temp, thread_info(cur)->host_link_timeout); - mac_helper_devicetable_set(entry_temp, cur, llFrameCounter, securityHeader->KeyIndex, new_entry_created); + mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, thread_info(cur)->host_link_timeout); + + mlme_device_descriptor_t device_desc; + mac_helper_device_description_write(cur, &device_desc, entry_temp->mac64, entry_temp->mac16,llFrameCounter, false); + mac_helper_devicetable_set(&device_desc, cur, entry_temp->index, securityHeader->KeyIndex, new_entry_created); thread_info(cur)->thread_attached_state = THREAD_STATE_CONNECTED; thread_bootstrap_update_ml16_address(cur, address16); @@ -377,12 +390,10 @@ static int thread_end_device_synch_response_validate(protocol_interface_info_ent static void thread_child_synch_receive_cb(int8_t interface_id, mle_message_t *mle_msg, mle_security_header_t *security_headers) { + (void) interface_id; tr_debug("Thread MLE message child_synch handler"); //State machine What packet shuold accept in this case - protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); - if (!cur) { - return; - } + protocol_interface_info_entry_t *cur = mle_msg->interface_ptr; /* Check that message is from link-local scope */ if(!addr_is_ipv6_link_local(mle_msg->packet_src_address)) { @@ -466,10 +477,8 @@ static bool thread_host_prefer_parent_response(protocol_interface_info_entry_t * */ void thread_mle_parent_discover_receive_cb(int8_t interface_id, mle_message_t *mle_msg, mle_security_header_t *security_headers) { - protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); - if (!cur) { - return; - } + (void) interface_id; + protocol_interface_info_entry_t *cur = mle_msg->interface_ptr; /* Check that message is from link-local scope */ if(!addr_is_ipv6_link_local(mle_msg->packet_src_address)) { @@ -538,8 +547,7 @@ void thread_mle_parent_discover_receive_cb(int8_t interface_id, mle_message_t *m if (thread_info(cur)->thread_attached_state == THREAD_STATE_REATTACH || thread_info(cur)->thread_attached_state == THREAD_STATE_REATTACH_RETRY) { tr_debug("Reattach"); if (thread_info(cur)->thread_leader_data) { - if ((thread_info(cur)->thread_leader_data->partitionId != leaderData.partitionId) || - (thread_info(cur)->thread_leader_data->weighting != leaderData.weighting)) { + if (!thread_partition_match(cur, &leaderData)) { //accept only same ID at reattach phase return; } @@ -557,8 +565,7 @@ void thread_mle_parent_discover_receive_cb(int8_t interface_id, mle_message_t *m thread_info(cur)->thread_attached_state == THREAD_STATE_CONNECTED || thread_info(cur)->thread_attached_state == THREAD_STATE_CONNECTED_ROUTER) { if (thread_info(cur)->thread_leader_data) { - if ((thread_info(cur)->thread_leader_data->partitionId == leaderData.partitionId) && - (thread_info(cur)->thread_leader_data->weighting == leaderData.weighting)) { + if (thread_partition_match(cur, &leaderData)) { //accept only different ID at anyattach phase tr_debug("Drop old partition"); return; @@ -736,12 +743,9 @@ void thread_mle_parent_discover_receive_cb(int8_t interface_id, mle_message_t *m static void thread_mle_child_request_receive_cb(int8_t interface_id, mle_message_t *mle_msg, mle_security_header_t *security_headers) { thread_leader_data_t leaderData; - mle_neigh_table_entry_t *entry_temp; - protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); + mac_neighbor_table_entry_t *entry_temp; + protocol_interface_info_entry_t *cur = mle_msg->interface_ptr; link_configuration_s *link_configuration; - if (!cur) { - return; - } link_configuration = thread_joiner_application_get_config(cur->id); if (!link_configuration) { return; @@ -790,17 +794,19 @@ static void thread_mle_child_request_receive_cb(int8_t interface_id, mle_message thread_merge_prepare(cur); // Create entry for new parent - entry_temp = mle_class_get_entry_by_ll64(cur->id, thread_compute_link_margin(mle_msg->dbm), mle_msg->packet_src_address, true, &new_entry_created); + entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, true, &new_entry_created); if (entry_temp == NULL) { // todo: what to do here? return; } + thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index, thread_compute_link_margin(mle_msg->dbm), new_entry_created); + thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index); //Parse mandatory TLV's if (!thread_leader_data_parse(mle_msg->data_ptr, mle_msg->data_length, &leaderData)) { return; } - if (!mle_tlv_read_16_bit_tlv(MLE_TYPE_SRC_ADDRESS, mle_msg->data_ptr, mle_msg->data_length, &entry_temp->short_adr)) { + if (!mle_tlv_read_16_bit_tlv(MLE_TYPE_SRC_ADDRESS, mle_msg->data_ptr, mle_msg->data_length, &entry_temp->mac16)) { return; } @@ -836,25 +842,24 @@ static void thread_mle_child_request_receive_cb(int8_t interface_id, mle_message return; } - common_write_16_bit(entry_temp->short_adr, shortAddress); + common_write_16_bit(entry_temp->mac16, shortAddress); //Update possible reed address by real router address - scan_result->shortAddress = entry_temp->short_adr; + scan_result->shortAddress = entry_temp->mac16; - entry_temp->holdTime = 90; - entry_temp->handshakeReady = 1; - entry_temp->priorityFlag = true; - entry_temp->threadNeighbor = true; + entry_temp->connected_device = 1; + entry_temp->link_role = PRIORITY_PARENT_NEIGHBOUR; mac_helper_coordinator_address_set(cur, ADDR_802_15_4_SHORT, shortAddress); - mle_entry_timeout_update(entry_temp, thread_info(cur)->host_link_timeout); + mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, thread_info(cur)->host_link_timeout); if (scan_result->security_key_index != security_headers->KeyIndex) { // KeyIndex has been changed between parent_response and child_id_response, reset link layer frame counter scan_result->linLayerFrameCounter = 0; scan_result->security_key_index = security_headers->KeyIndex; } - - mac_helper_devicetable_set(entry_temp, cur, scan_result->linLayerFrameCounter, security_headers->KeyIndex, new_entry_created); + mlme_device_descriptor_t device_desc; + mac_helper_device_description_write(cur, &device_desc, entry_temp->mac64, entry_temp->mac16,scan_result->linLayerFrameCounter, false); + mac_helper_devicetable_set(&device_desc, cur, entry_temp->index, security_headers->KeyIndex, new_entry_created); thread_info(cur)->thread_attached_state = THREAD_STATE_CONNECTED; @@ -948,23 +953,26 @@ static int8_t thread_end_device_synch_start(protocol_interface_info_entry_t *cur void thread_endevice_synch_start(protocol_interface_info_entry_t *cur) { if (cur->thread_info->thread_endnode_parent) { - mle_neigh_table_entry_t *entry_temp; bool new_entry_created; // Add the parent to the MLE neighbor table - entry_temp = mle_class_get_entry_by_mac64(cur->id, 64, cur->thread_info->thread_endnode_parent->mac64, true, &new_entry_created); + mac_neighbor_table_entry_t *mac_entry = mac_neighbor_entry_get_by_mac64(mac_neighbor_info(cur), cur->thread_info->thread_endnode_parent->mac64, true, &new_entry_created); + if (mac_entry) { + //Add link margin 64 + thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, mac_entry->index,64, new_entry_created); + thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, mac_entry->index); - if (entry_temp) { - entry_temp->short_adr = cur->thread_info->thread_endnode_parent->shortAddress; - entry_temp->handshakeReady = 1; - entry_temp->threadNeighbor = true; + mac_entry->mac16 = cur->thread_info->thread_endnode_parent->shortAddress; + mac_entry->connected_device = 1; // In case we don't get response to sync; use temporary timeout here, // Child ID Response handler will set correct value later - mle_entry_timeout_update(entry_temp, 20); + mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), mac_entry, mac_entry->link_lifetime); // Add the parent to the MAC table (for e.g. secured/fragmented Child Update Response) - mac_helper_devicetable_set(entry_temp, cur, 0, cur->mac_parameters->mac_default_key_index, new_entry_created); + mlme_device_descriptor_t device_desc; + mac_helper_device_description_write(cur, &device_desc, mac_entry->mac64, mac_entry->mac16,0, false); + mac_helper_devicetable_set(&device_desc, cur, mac_entry->index, cur->mac_parameters->mac_default_key_index, new_entry_created); } } @@ -978,10 +986,9 @@ void thread_endevice_synch_start(protocol_interface_info_entry_t *cur) static bool thread_child_id_req_timeout(int8_t interface_id, uint16_t msgId, bool usedAllRetries) { - mle_neigh_table_entry_t *entry_temp; + mac_neighbor_table_entry_t *entry_temp; thread_scanned_parent_t *scanned_parent; protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); - uint8_t ll64[16]; (void)msgId; @@ -1017,15 +1024,17 @@ static bool thread_child_id_req_timeout(int8_t interface_id, uint16_t msgId, boo tr_debug("Back to old partition"); /* If scanned parent is from other partition, delete from MLE table */ - if (scanned_parent->leader_data.partitionId != thread_info(cur)->thread_leader_data->partitionId) { - memcpy(ll64, ADDR_LINK_LOCAL_PREFIX , 8); - memcpy(&ll64[8], scanned_parent->mac64 , 8); - ll64[8] ^= 2; - - entry_temp = mle_class_get_entry_by_ll64(cur->id, scanned_parent->linkMarginToParent, ll64, false, NULL); - if (entry_temp && !thread_check_is_this_my_parent(cur, entry_temp)) { - // remove scanned_parent entry only if it is not my parent - mle_class_remove_entry(cur->id, entry_temp); + if ((scanned_parent->leader_data.partitionId != thread_info(cur)->thread_leader_data->partitionId) || + (scanned_parent->leader_data.weighting != thread_info(cur)->thread_leader_data->weighting)) { + entry_temp = mac_neighbor_table_address_discover(mac_neighbor_info(cur), scanned_parent->mac64, ADDR_802_15_4_LONG); + if (entry_temp) { + bool my_parent = thread_check_is_this_my_parent(cur, entry_temp); + mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry_temp); + if (my_parent) { + tr_debug("No parent resp - any-attach"); + thread_bootstrap_connection_error(interface_id, CON_ERROR_NETWORK_ATTACH_FAIL, NULL); + goto exit; + } } } @@ -1159,22 +1168,22 @@ static bool thread_child_update_timeout_cb(int8_t interface_id, uint16_t msgId, } -int8_t thread_host_bootstrap_child_update(int8_t interface_id, const uint8_t *mac64) +bool thread_host_bootstrap_child_update(protocol_interface_info_entry_t *cur, const uint8_t *mac64) { - protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); mle_message_timeout_params_t timeout; uint8_t mode; uint32_t keySequence; if (!cur->thread_info->thread_endnode_parent) { - return -1; + tr_debug("Not end device parent info for NUD"); + return false; } if (cur->thread_info->thread_endnode_parent->childUpdateProcessActive) { //Set Pending if earlier process is already started cur->thread_info->thread_endnode_parent->childUpdatePending = true; - return -1; + return false; } //Trig event cur->thread_info->thread_endnode_parent->childUpdatePending = false; @@ -1189,7 +1198,7 @@ int8_t thread_host_bootstrap_child_update(int8_t interface_id, const uint8_t *ma uint16_t bufId = mle_service_msg_allocate(cur->id, 150 + 3 + 6 + 10, false, MLE_COMMAND_CHILD_UPDATE_REQUEST); if (bufId == 0) { - return -1; + return false; } thread_management_get_current_keysequence(cur->id, &keySequence); @@ -1228,7 +1237,7 @@ int8_t thread_host_bootstrap_child_update(int8_t interface_id, const uint8_t *ma mle_service_set_msg_timeout_parameters(bufId, &timeout); mle_service_send_message(bufId); - return 0; + return true; } int thread_host_bootstrap_child_update_negative_response(protocol_interface_info_entry_t *cur, uint8_t *dstAddress, mle_tlv_info_t *challenge) { diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_host_bootstrap.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_host_bootstrap.h index e154208540d6..b54115452730 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_host_bootstrap.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_host_bootstrap.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -42,7 +42,7 @@ struct protocol_interface_info_entry; struct mle_security_header; void thread_network_attach_start(struct protocol_interface_info_entry *cur); -int8_t thread_host_bootstrap_child_update(int8_t interface_id, const uint8_t *mac64); +bool thread_host_bootstrap_child_update(struct protocol_interface_info_entry *cur, const uint8_t *mac64); int thread_host_bootstrap_child_update_negative_response(protocol_interface_info_entry_t *cur, uint8_t *dstAddress, mle_tlv_info_t *challenge); void thread_child_set_default_route(struct protocol_interface_info_entry *cur); diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_joiner_application.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_joiner_application.c index 91400d7e4018..5bc1b7849362 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_joiner_application.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_joiner_application.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -778,8 +778,8 @@ static bool thread_joiner_application_validate_settings(thread_joiner_t *this) new_value_generated = 1; tr_info("Generating Random ML-EID"); } - if (this->configuration_ptr->key_rotation < 3600) { - this->configuration_ptr->key_rotation = 3600; + if (this->configuration_ptr->key_rotation < 1) { + this->configuration_ptr->key_rotation = 1; } return new_value_generated; } @@ -967,17 +967,12 @@ static int thread_joiner_application_nvm_link_config_read(thread_joiner_t *this) this->configuration_valid = true; link_configuration_trace(this->configuration_ptr); + protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(this->interface_id); //Add Security to MLE service - uint8_t key_material[32]; - uint8_t key_index; - //Define KEY's + thread_security_prev_key_generate(cur,this->configuration_ptr->master_key,this->configuration_ptr->key_sequence); + thread_security_key_generate(cur,this->configuration_ptr->master_key,this->configuration_ptr->key_sequence); + thread_security_next_key_generate(cur,this->configuration_ptr->master_key,this->configuration_ptr->key_sequence); - thread_key_get(this->configuration_ptr->master_key, key_material, this->configuration_ptr->key_sequence); - key_index = THREAD_KEY_INDEX(this->configuration_ptr->key_sequence); - //Set Keys - protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(this->interface_id); - mac_helper_security_default_key_set(cur, &key_material[16], key_index, MAC_KEY_ID_MODE_IDX); - mle_service_security_set_security_key(this->interface_id, key_material, key_index, true); // update counters mle_service_security_set_frame_counter(this->interface_id, fast_data.mle_frame_counter); mac_helper_link_frame_counter_set(this->interface_id, fast_data.mac_frame_counter); diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_joiner_application.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_joiner_application.h index 21258690ee2e..2720e429ce3c 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_joiner_application.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_joiner_application.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_leader_service.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_leader_service.c index d1e21e7f6d66..d2be5fd3ebfd 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_leader_service.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_leader_service.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, Arm Limited and affiliates. + * Copyright (c) 2016-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -414,7 +414,7 @@ static int thread_leader_service_active_set_cb(int8_t service_id, uint8_t source } } if (3 <= thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_SECURITY_POLICY, &ptr)) { - if (common_read_16_bit(ptr) < 3600) { + if (common_read_16_bit(ptr) < 1) { tr_warn("invalid security policy"); ret = -1; goto send_response; @@ -1090,7 +1090,7 @@ static int thread_leader_service_petition_cb(int8_t service_id, uint8_t source_a ptr = thread_meshcop_tlv_data_write_uint8(ptr, MESHCOP_TLV_STATE, 0xff); } - tr_debug("Petition req recv id %s, RESP session id: %d ret %d", commissioner_id_ptr, session_id, ret); + tr_debug("Petition req recv id %s, RESP session id: %d ret %d", commissioner_id_ptr ? commissioner_id_ptr : "(none)", session_id, ret); send_error_response: coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, response_code, COAP_CT_OCTET_STREAM, payload, ptr - payload); @@ -1346,7 +1346,7 @@ static void thread_leader_service_interface_setup_activate(protocol_interface_in thread_leader_service_private_routemask_init(private); //SET Router ID thread_leader_allocate_router_id_by_allocated_id(private, routerId, cur->mac); - thread_old_partition_data_purge(cur); + thread_partition_data_purge(cur); // remove any existing rloc mapping in nvm thread_nvm_store_mleid_rloc_map_remove(); cur->lowpan_address_mode = NET_6LOWPAN_GP16_ADDRESS; @@ -1526,7 +1526,7 @@ void thread_leader_service_timer(protocol_interface_info_entry_t *cur, uint32_t cur->thread_info->leader_private_data->leader_id_seq_timer = ID_SEQUENCE_PERIOD; thread_leader_service_update_id_set(cur); - thread_network_data_context_re_use_timer_update(&cur->thread_info->networkDataStorage, 10, &cur->lowpan_contexts); + thread_network_data_context_re_use_timer_update(cur->id, &cur->thread_info->networkDataStorage, 10, &cur->lowpan_contexts); // Send update to network data if needed thread_leader_service_network_data_changed(cur, false, false); } @@ -1621,7 +1621,6 @@ void thread_leader_service_thread_partitition_generate(int8_t interface_id, bool //memset(cur->thread_info->lastValidRouteMask, 0, (N_THREAD_ROUTERS+7)/8); //SET SHort Address & PAN-ID cur->lowpan_info &= ~INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE; - mle_class_mode_set(cur->id, MLE_CLASS_ROUTER); mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, true); cur->interface_mode = INTERFACE_UP; cur->nwk_mode = ARM_NWK_GP_IP_MODE; diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_leader_service.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_leader_service.h index 7eabcb302832..a28bb9202f56 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_leader_service.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_leader_service.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, Arm Limited and affiliates. + * Copyright (c) 2016-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_management_client.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_management_client.c index 3d1f7a812f6c..0ccae5a3ac3a 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_management_client.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_management_client.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -146,6 +146,8 @@ void thread_management_client_init(int8_t interface_id) if (this) { this->network_data_set_cb_ptr = NULL; + this->router_id_release_cb_ptr = NULL; + this->neighbor_discovery_cb_ptr = NULL; this->router_id_cb_ptr = NULL; this->interface_id = interface_id; this->coap_asd_msg_id = 0; @@ -333,6 +335,15 @@ static int thread_management_client_neighbor_discovery_data_cb(int8_t service_id return 0; } +int thread_management_client_get_interface_id_by_service_id(int8_t service_id) +{ + thread_management_t *this = thread_management_find_by_service(service_id); + if (!this) { + return -1; + } + return this->interface_id; +} + int thread_management_client_neighbor_discovery_data_request(int8_t interface_id, const uint8_t destination[16], const uint8_t *options, uint8_t options_len, thread_management_client_network_data_set_cb *set_cb) { thread_management_t *this = thread_management_find(interface_id); diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_management_client.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_management_client.h index d08a95d74096..583b6fcec461 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_management_client.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_management_client.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -148,6 +148,15 @@ int thread_management_client_network_data_unregister(int8_t interface_id, uint16 */ int thread_management_client_neighbor_discovery_data_request(int8_t interface_id, const uint8_t destination[16], const uint8_t *options, uint8_t options_len, thread_management_client_network_data_set_cb *set_cb); +/** Get interface_id of based on coap service_id + * + * + * /param service_id coap service id. + * + *return interface_id of thread instance if successful and -1 for failure + */ +int thread_management_client_get_interface_id_by_service_id(int8_t service_id); + /** send active configuration dataset get for parent * * /param interface_id interface id of this thread instance. diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_management_if.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_management_if.c index 58ea54aea3e3..767bb355389c 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_management_if.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_management_if.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -62,6 +62,7 @@ #include "6LoWPAN/Thread/thread_tmfcop_lib.h" #include "6LoWPAN/Thread/thread_constants.h" #include "6LoWPAN/Thread/thread_extension_bootstrap.h" +#include "6LoWPAN/Thread/thread_extension.h" #include "6LoWPAN/Bootstraps/protocol_6lowpan.h" #include "RPL/rpl_control.h" // insanity - bootstraps shouldn't be doing each others' clean-up #include "MLE/mle.h" @@ -77,7 +78,9 @@ #include "Service_Libs/blacklist/blacklist.h" #include "6LoWPAN/MAC/mac_helper.h" #include "6LoWPAN/MAC/mac_pairwise_key.h" +#include "6LoWPAN/MAC/mpx_api.h" #include "6LoWPAN/lowpan_adaptation_interface.h" +#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h" #include "mac_common_defines.h" #include "mlme.h" #include "mac_api.h" @@ -308,95 +311,43 @@ void thread_key_get(uint8_t *key, uint8_t *key_material_buf, uint32_t key_seque } /** - * Increment Thread key sequence counter - * - * \param interface_id Network Interface + * Thread key sequence & key synch * - * return 0, ADD OK - * return <0 Add Not OK */ -uint8_t *thread_management_key_request(int8_t interface_id, uint8_t keyId) +void thread_management_key_synch_req(int8_t interface_id, uint32_t keySequnce) { protocol_interface_info_entry_t *cur; - uint8_t *keyPtr = NULL; link_configuration_s *linkConfiguration; linkConfiguration = thread_joiner_application_get_config(interface_id); if (!linkConfiguration) { - return NULL; + return; } cur = protocol_stack_interface_info_get_by_id(interface_id); - if (cur && cur->thread_info) { - if (cur->thread_info->masterSecretMaterial.valid_Info) { - - if (cur->thread_info->masterSecretMaterial.historyKeyValid && (cur->thread_info->masterSecretMaterial.historyKeyId == keyId)) { - - keyPtr = cur->thread_info->masterSecretMaterial.historyKey; - - } else { - uint32_t thrSequenceCounter; - uint8_t compId = 0xff, keyIdDiff; - thrSequenceCounter = linkConfiguration->key_sequence + 1; - //Calculate Current Next key ID - compId = THREAD_KEY_INDEX(thrSequenceCounter); - - if (keyId > compId) { - keyIdDiff = (keyId - compId); - } else { - keyIdDiff = (128 - (compId - keyId)); - } - - if (keyIdDiff > 64) { - //Calc Temp Key - thrSequenceCounter -= (128 - keyIdDiff); - tr_debug("Gen temporary key id %"PRIu8" seq %"PRIu32, keyId, thrSequenceCounter); - thread_key_get(linkConfiguration->master_key, cur->thread_info->masterSecretMaterial.historyKey, thrSequenceCounter); - cur->thread_info->masterSecretMaterial.historyKeyId = keyId; - cur->thread_info->masterSecretMaterial.historyKeyValid = true; - keyPtr = cur->thread_info->masterSecretMaterial.historyKey; - } else { - tr_debug("Gen new key id %"PRIu8" %"PRIu8" diff", keyId, keyIdDiff); - thrSequenceCounter += keyIdDiff; - //Generate - tr_debug("Missed n key Update...generated missed key %"PRIu8" update by seq %"PRIu32, keyIdDiff, thrSequenceCounter); - thread_management_key_sets_calc(cur, linkConfiguration, thrSequenceCounter); - //Get Default key - keyPtr = mle_service_security_default_key_get(interface_id); - } - thread_nvm_store_seq_counter_write(linkConfiguration->key_sequence); - } - } + if (!cur || !cur->thread_info) { + return; } - return keyPtr; -} - -/** - * Thread key sequence & key synch - * - */ -void thread_management_key_synch_req(int8_t interface_id, uint32_t keySequnce) -{ - protocol_interface_info_entry_t *cur; - link_configuration_s *linkConfiguration; - linkConfiguration = thread_joiner_application_get_config(interface_id); - if (!linkConfiguration) { + if (!cur->thread_info->masterSecretMaterial.valid_Info) { return; } + //tr_debug("Sync key material by %"PRIu32, keySequnce); - cur = protocol_stack_interface_info_get_by_id(interface_id); - if (cur && cur->thread_info) { - if (cur->thread_info->masterSecretMaterial.valid_Info) { - if (keySequnce != linkConfiguration->key_sequence) { - if ((cur->thread_info->masterSecretMaterial.keySwitchGuardTimer == 0 && keySequnce > linkConfiguration->key_sequence)) { - tr_debug("Sync key material by %"PRIu32, keySequnce); - thread_management_key_sets_calc(cur, linkConfiguration, keySequnce); - thread_calculate_key_guard_timer(cur, linkConfiguration, false); - } - } - } + if (keySequnce <= linkConfiguration->key_sequence) { + // Smaller or equal request ignored + //tr_debug("Sync key material no change"); + return; } + if ((cur->thread_info->masterSecretMaterial.keySwitchGuardTimer > 0)) { + // Guard time prevent the change + //tr_debug("Sync key material guard blocked"); + return; + } + // Calculate new keys + tr_debug("Sync key material by %"PRIu32, keySequnce); + thread_management_key_sets_calc(cur, linkConfiguration, keySequnce); + thread_key_guard_timer_calculate(cur, linkConfiguration, false); } -void thread_history_key_material_push(thread_info_t *thread_info, uint8_t *mleKeyPtr, uint8_t keyId) +static void thread_history_key_material_push(thread_info_t *thread_info, uint8_t *mleKeyPtr, uint8_t keyId) { thread_info->masterSecretMaterial.historyKeyValid = true; thread_info->masterSecretMaterial.historyKeyId = keyId; @@ -424,7 +375,7 @@ void thread_security_update_from_mac(protocol_interface_info_entry_t *cur) linkConfiguration->key_sequence++; mac_helper_link_frame_counter_set(cur->id, 0); thread_security_next_key_generate(cur, linkConfiguration->master_key, linkConfiguration->key_sequence); - thread_calculate_key_guard_timer(cur, linkConfiguration, false); + thread_key_guard_timer_calculate(cur, linkConfiguration, false); } void thread_security_key_generate(protocol_interface_info_entry_t *cur, uint8_t *masterKey, uint32_t keySequence) @@ -437,11 +388,33 @@ void thread_security_key_generate(protocol_interface_info_entry_t *cur, uint8_t thread_key_get(masterKey, key_material, thrKeySequenceCounter); /* Update keys as primary keys */ key_index = THREAD_KEY_INDEX(thrKeySequenceCounter); - tr_debug("Set key Id: %u", key_index); + tr_debug("Set current key Id: %u", key_index); mac_helper_security_default_key_set(cur, &key_material[16], key_index, MAC_KEY_ID_MODE_IDX); mle_service_security_set_security_key(cur->id, key_material, key_index, true); } + +void thread_security_prev_key_generate(protocol_interface_info_entry_t *cur, uint8_t *masterKey, uint32_t keySequence) +{ + uint8_t key_material[32]; + uint8_t key_index; + uint32_t thrKeySequenceCounter; + if (keySequence == 0) { + // in initial value there is no prev available + return; + } + thrKeySequenceCounter = keySequence - 1; + /* Produced keys from Thread security material: MAC key | MLE key */ + thread_key_get(masterKey, key_material, thrKeySequenceCounter); + /* Update keys as primary keys */ + key_index = THREAD_KEY_INDEX(thrKeySequenceCounter); + tr_debug("Set previous key Id: %u", key_index); + mac_helper_security_prev_key_set(cur, &key_material[16], key_index, MAC_KEY_ID_MODE_IDX); + mle_service_security_set_security_key(cur->id, key_material, key_index, false); + //copy master secret material to history + thread_history_key_material_push(cur->thread_info, key_material, key_index); +} + void thread_security_next_key_generate(protocol_interface_info_entry_t *cur, uint8_t *masterKey, uint32_t keySequence) { uint8_t key_material[32]; @@ -471,31 +444,17 @@ int thread_management_key_sets_calc(protocol_interface_info_entry_t *cur, link_c ret_val = 0; } else { /* Generate new key set */ - uint8_t key_material[32]; - uint8_t key_index; - thread_nvm_fast_data_t fast_data; - //SET History key, Current Key & Next Key - //Generate History Key //Clean All Keys mac_helper_security_key_clean(cur); - thrKeySequenceCounter--; - /* Update keys as non-primary keys */ - thread_key_get(linkConfiguration->master_key, key_material, thrKeySequenceCounter); - key_index = THREAD_KEY_INDEX(thrKeySequenceCounter); - //copy master secret material to history - memcpy(cur->thread_info->masterSecretMaterial.historyKey, key_material, 32); - cur->thread_info->masterSecretMaterial.historyKeyId = key_index; - cur->thread_info->masterSecretMaterial.historyKeyValid = true; - - mac_helper_security_prev_key_set(cur, &key_material[16], key_index, MAC_KEY_ID_MODE_IDX); - //Set New Active Key - thrKeySequenceCounter++; + + // Update key sequence linkConfiguration->key_sequence = thrKeySequenceCounter; - fast_data.seq_counter = thrKeySequenceCounter; - fast_data.mac_frame_counter = 0; - fast_data.mle_frame_counter = mle_service_security_get_frame_counter(cur->interface_mode); - thread_nvm_store_fast_data_write(&fast_data); + // Zero all frame counters. MLE does it automatically mac_helper_link_frame_counter_set(cur->id, 0); + // Store all frame counters as zero and update the sequence counter + thread_nvm_store_fast_data_write_all(0, 0, thrKeySequenceCounter); + + thread_security_prev_key_generate(cur,linkConfiguration->master_key,linkConfiguration->key_sequence); thread_security_key_generate(cur,linkConfiguration->master_key,linkConfiguration->key_sequence); thread_security_next_key_generate(cur,linkConfiguration->master_key,linkConfiguration->key_sequence); ret_val = 0; @@ -790,12 +749,23 @@ int thread_dhcpv6_server_delete(int8_t interface_id, uint8_t *prefix_ptr) } #ifdef HAVE_THREAD +static mac_neighbor_table_entry_t *neighbor_data_poll_referesh(protocol_interface_info_entry_t *cur, const uint8_t *address, addrtype_t type) +{ + mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), address, type); + if (!entry || !entry->connected_device) { + return NULL; + } + + entry->lifetime = entry->link_lifetime; + return entry; +} void thread_comm_status_indication_cb(int8_t if_id, const mlme_comm_status_t* status) { protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(if_id); if (!cur) { return; } + mac_neighbor_table_entry_t *entry; switch (status->status) { @@ -808,7 +778,10 @@ void thread_comm_status_indication_cb(int8_t if_id, const mlme_comm_status_t* st break; case MLME_DATA_POLL_NOTIFICATION: - mle_refresh_entry_timeout(if_id, status->SrcAddr, (addrtype_t)status->SrcAddrMode, false); + entry = neighbor_data_poll_referesh(cur, status->SrcAddr, (addrtype_t)status->SrcAddrMode); + if (entry) { + thread_neighbor_communication_update(cur, entry->index); + } break; default: break; @@ -908,7 +881,7 @@ int thread_management_node_init( scan_params->scan_duration = 5; cur->thread_info->masterSecretMaterial.valid_Info = false; - thread_calculate_key_guard_timer(cur, static_configuration, true); + thread_key_guard_timer_calculate(cur, static_configuration, true); cur->thread_info->maxChildCount = THREAD_MAX_CHILD_COUNT; cur->thread_info->rfc6775 = false; @@ -1439,10 +1412,21 @@ int thread_management_partition_weighting_set(int8_t interface_id, uint8_t parti return 0; } + bool trig_network_scan = false; + if (cur->thread_info->thread_leader_data) { + if (cur->thread_info->thread_leader_data->weighting < partition_weighting) { + trig_network_scan = true; + } + } + cur->thread_info->partition_weighting = partition_weighting; + if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) { - // bootstrap active and weighting has changed - thread_bootstrap_reset_restart(interface_id); + if (trig_network_scan && thread_extension_enabled(cur)) { + thread_nvm_store_link_info_clear(); + // bootstrap active and weighting has changed + thread_bootstrap_reset_restart(interface_id); + } } return 0; diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_management_internal.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_management_internal.h index 0d3dc94f40ba..3e3dac832fec 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_management_internal.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_management_internal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -77,15 +77,13 @@ int thread_management_increment_key_sequence_counter(int8_t interface_id); int thread_management_key_sets_calc(protocol_interface_info_entry_t *cur, link_configuration_s *linkConfiguration, uint32_t thrKeySequenceCounter); -uint8_t *thread_management_key_request(int8_t interface_id, uint8_t keyId); - void thread_management_key_synch_req(int8_t interface_id, uint32_t keySequnce); uint8_t *thread_management_key_request_with_sequence(int8_t interface_id, uint8_t keyId, uint32_t keySequnce); void thread_security_update_from_mac(struct protocol_interface_info_entry *cur); -void thread_history_key_material_push(struct thread_info_s *thread_info, uint8_t *mleKeyPtr, uint8_t keyId); - +void thread_security_key_generate(struct protocol_interface_info_entry *cur, uint8_t *masterKey, uint32_t keySequence); +void thread_security_prev_key_generate(struct protocol_interface_info_entry *cur, uint8_t *masterKey, uint32_t keySequence); void thread_security_next_key_generate(struct protocol_interface_info_entry *cur, uint8_t *masterKey, uint32_t keySequence); void thread_key_get(uint8_t *key, uint8_t *key_material_buf, uint32_t key_sequence_counter); diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_management_server.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_management_server.c index 329c26c14af5..8a4ae139fd61 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_management_server.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_management_server.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -1159,7 +1159,6 @@ int thread_management_server_init(int8_t interface_id) } #endif thread_extension_init(interface_id, this->coap_service_id); - // All thread devices coap_service_register_uri(this->coap_service_id, THREAD_URI_MANAGEMENT_GET, COAP_SERVICE_ACCESS_GET_ALLOWED, thread_management_server_get_command_cb); diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_mle_message_handler.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_mle_message_handler.c index fee1e2235038..2c108ee6e88d 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_mle_message_handler.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_mle_message_handler.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, Arm Limited and affiliates. + * Copyright (c) 2016-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -38,6 +38,7 @@ #include "6LoWPAN/Thread/thread_config.h" #include "6LoWPAN/Thread/thread_common.h" #include "6LoWPAN/Thread/thread_lowpower_private_api.h" +#include "6LoWPAN/Thread/thread_neighbor_class.h" #include "6LoWPAN/Thread/thread_mle_message_handler.h" #include "6LoWPAN/Thread/thread_bootstrap.h" #include "6LoWPAN/Thread/thread_management_internal.h" @@ -48,13 +49,15 @@ #include "6LoWPAN/Thread/thread_extension.h" #include "6LoWPAN/Thread/thread_router_bootstrap.h" #include "6LoWPAN/Thread/thread_network_synch.h" +#include "6LoWPAN/Thread/thread_neighbor_class.h" +#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h" #include "6LoWPAN/MAC/mac_helper.h" #include "6LoWPAN/MAC/mac_data_poll.h" #include "MLE/mle.h" #include "mac_api.h" #define TRACE_GROUP "thmh" static int8_t thread_link_request_start(protocol_interface_info_entry_t *cur, uint8_t *router_ll64); -static bool thread_router_leader_data_process(protocol_interface_info_entry_t *cur, uint8_t *src_address, thread_leader_data_t *leaderData, mle_tlv_info_t *routeTlv, mle_neigh_table_entry_t *neighbor); +static bool thread_router_leader_data_process(protocol_interface_info_entry_t *cur, uint8_t *src_address, thread_leader_data_t *leaderData, mle_tlv_info_t *routeTlv, mac_neighbor_table_entry_t *neighbor); static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle_message_t *mle_msg, mle_security_header_t *security_headers, uint8_t linkMargin); static void thread_save_leader_data(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData); static void thread_parse_accept(protocol_interface_info_entry_t *cur, mle_message_t *mle_msg, mle_security_header_t *security_headers, uint8_t linkMargin); @@ -72,11 +75,7 @@ void thread_general_mle_receive_cb(int8_t interface_id, mle_message_t *mle_msg, * and MUST be discarded. */ - protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); - - if (!cur) { - return; - } + protocol_interface_info_entry_t *cur = mle_msg->interface_ptr; /* Check that message is from link-local scope */ if(!addr_is_ipv6_link_local(mle_msg->packet_src_address)) { @@ -100,11 +99,11 @@ void thread_general_mle_receive_cb(int8_t interface_id, mle_message_t *mle_msg, } case MLE_COMMAND_REJECT: { - mle_neigh_table_entry_t *entry_temp; + mac_neighbor_table_entry_t *entry_temp; tr_warn("Reject Link"); - entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL); + entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL); if (entry_temp) { - mle_class_remove_entry(cur->id, entry_temp); + mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry_temp); } break; } @@ -159,16 +158,11 @@ static void thread_save_leader_data(protocol_interface_info_entry_t *cur, thread requestNetworkdata = true; } - if (thread_info(cur)->thread_leader_data->partitionId != leaderData->partitionId) { + if (!thread_partition_match(cur, leaderData)) { requestNetworkdata = true; - thread_info(cur)->thread_leader_data->stableDataVersion = leaderData->stableDataVersion - 1; - thread_info(cur)->thread_leader_data->dataVersion = leaderData->dataVersion - 1; + thread_partition_info_update(cur, leaderData); } - thread_info(cur)->thread_leader_data->partitionId = leaderData->partitionId; - thread_info(cur)->thread_leader_data->leaderRouterId = leaderData->leaderRouterId; - thread_info(cur)->thread_leader_data->weighting = leaderData->weighting; - if (requestNetworkdata) { thread_bootstrap_parent_network_data_request(cur, false); } else { @@ -215,12 +209,12 @@ static int8_t thread_link_request_start(protocol_interface_info_entry_t *cur, ui return 0; } -static bool thread_router_leader_data_process(protocol_interface_info_entry_t *cur, uint8_t *src_address, thread_leader_data_t *leaderData, mle_tlv_info_t *routeTlv, mle_neigh_table_entry_t *neighbor) +static bool thread_router_leader_data_process(protocol_interface_info_entry_t *cur, uint8_t *src_address, thread_leader_data_t *leaderData, mle_tlv_info_t *routeTlv, mac_neighbor_table_entry_t *neighbor) { int leaderDataUpdate = thread_leader_data_validation(cur, leaderData, routeTlv); if (leaderDataUpdate == 1) { - if (neighbor && neighbor->handshakeReady == 1) { + if (neighbor && neighbor->connected_device == 1) { // Request network data if we have a 2-way link tr_debug("Request New Network Data from %s", trace_ipv6(src_address)); thread_network_data_request_send(cur, src_address, true); @@ -272,30 +266,32 @@ static bool thread_router_advertiment_tlv_analyze(uint8_t *ptr, uint16_t data_le return true; } -static void thread_update_mle_entry(protocol_interface_info_entry_t *cur, mle_message_t *mle_msg, mle_security_header_t *security_headers, mle_neigh_table_entry_t *entry_temp, uint16_t short_address) +static void thread_update_mle_entry(protocol_interface_info_entry_t *cur, mle_message_t *mle_msg, mle_security_header_t *security_headers, mac_neighbor_table_entry_t *entry_temp, uint16_t short_address) { if (!entry_temp) { return; } + uint8_t linkMargin = thread_compute_link_margin(mle_msg->dbm); mle_neigh_entry_frame_counter_update(entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur, security_headers->KeyIndex); + thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index,linkMargin, false); + thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index); + if (!thread_attach_active_router(cur) && !thread_check_is_this_my_parent(cur, entry_temp)) { - mle_entry_timeout_refresh(entry_temp); - } else { - entry_temp->last_contact_time = protocol_core_monotonic_time; + mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, entry_temp->link_lifetime); } - if (short_address != entry_temp->short_adr) { - if (thread_router_addr_from_addr(entry_temp->short_adr) == cur->thread_info->routerShortAddress) { + if (short_address != entry_temp->mac16) { + if (thread_router_addr_from_addr(entry_temp->mac16) == cur->thread_info->routerShortAddress) { thread_dynamic_storage_child_info_clear(cur->id, entry_temp); - protocol_6lowpan_release_short_link_address_from_neighcache(cur, entry_temp->short_adr); + protocol_6lowpan_release_short_link_address_from_neighcache(cur, entry_temp->mac16); } - entry_temp->short_adr = short_address; + entry_temp->mac16 = short_address; /* throw MLME_GET request, short address is changed automatically in get request callback */ mlme_get_t get_req; get_req.attr = macDeviceTable; - get_req.attr_index = entry_temp->attribute_index; + get_req.attr_index = entry_temp->index; cur->mac_api->mlme_req(cur->mac_api, MLME_GET, &get_req); } @@ -304,11 +300,6 @@ static void thread_update_mle_entry(protocol_interface_info_entry_t *cur, mle_me static bool thread_parse_advertisement_from_parent(protocol_interface_info_entry_t *cur, thread_leader_data_t *leader_data, uint16_t short_address) { - if ((thread_info(cur)->thread_leader_data->partitionId != leader_data->partitionId) || - (thread_info(cur)->thread_leader_data->weighting != leader_data->weighting)) { - //parent changed partition/weight - reset own routing information - thread_old_partition_data_purge(cur); - } //check if network data needs to be requested if (!thread_bootstrap_request_network_data(cur, leader_data, short_address)) { tr_debug("Parent short address changed - re-attach"); @@ -323,7 +314,7 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle { mle_tlv_info_t routeTlv; thread_leader_data_t leaderData; - mle_neigh_table_entry_t *entry_temp; + mac_neighbor_table_entry_t *entry_temp; uint16_t shortAddress; bool adv_from_my_partition; bool my_parent; @@ -342,12 +333,16 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle } // Get MLE entry - entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL); + entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL); + if (entry_temp) { + thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index, linkMargin, false); + thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index); + } // Check if this is from my parent my_parent = thread_check_is_this_my_parent(cur, entry_temp); - adv_from_my_partition = thread_instance_id_matches(cur, &leaderData); + adv_from_my_partition = thread_partition_match(cur, &leaderData); if ((security_headers->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) && adv_from_my_partition) { thread_management_key_synch_req(cur->id, common_read_32_bit(security_headers->Keysource)); @@ -355,13 +350,14 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle if (entry_temp && !adv_from_my_partition && !my_parent ) { // Remove MLE entry that are located in other partition and is not my parent - mle_class_remove_entry(cur->id, entry_temp); + mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry_temp); entry_temp = NULL; } /* Check parent status */ if (!thread_attach_active_router(cur) && my_parent) { if (!thread_parse_advertisement_from_parent(cur, &leaderData, shortAddress)) { + mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry_temp); return; } } @@ -374,7 +370,7 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle /* REED and FED */ if (!thread_attach_active_router(cur)) { /* Check if advertisement is from same partition */ - if (thread_info(cur)->thread_leader_data->weighting == leaderData.weighting && thread_info(cur)->thread_leader_data->partitionId == leaderData.partitionId ) { + if (thread_partition_match(cur, &leaderData)) { if (!entry_temp && thread_bootstrap_link_create_check(cur, shortAddress) && thread_bootstrap_link_create_allowed(cur, shortAddress, mle_msg->packet_src_address)) { // Create link to new neighbor no other processing allowed thread_link_request_start(cur, mle_msg->packet_src_address); @@ -404,9 +400,8 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle } // Process route TLV - if ((entry_temp && routeTlv.dataPtr && routeTlv.tlvLen) && - (thread_info(cur)->thread_leader_data->partitionId == leaderData.partitionId)){ - tr_debug("Update Route TLV %x", entry_temp->short_adr); + if ((entry_temp && routeTlv.dataPtr && routeTlv.tlvLen) && thread_partition_match(cur, &leaderData)){ + tr_debug("Update Route TLV %x", entry_temp->mac16); thread_router_bootstrap_route_tlv_push(cur, routeTlv.dataPtr, routeTlv.tlvLen , linkMargin, entry_temp); } } @@ -417,7 +412,7 @@ static void thread_parse_accept(protocol_interface_info_entry_t *cur, mle_messag uint16_t version, shortAddress; uint16_t messageId; uint8_t linkMarginfronNeigh; - mle_neigh_table_entry_t *entry_temp; + mac_neighbor_table_entry_t *entry_temp; bool createNew, new_entry_created; tr_info("MLE LINK ACCEPT"); @@ -444,12 +439,14 @@ static void thread_parse_accept(protocol_interface_info_entry_t *cur, mle_messag /* Call to determine whether or not we should create a new link */ createNew = thread_bootstrap_link_create_check(cur, shortAddress); - entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, createNew, &new_entry_created); + entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, createNew, &new_entry_created); if (!entry_temp) { thread_link_reject_send(cur, mle_msg->packet_src_address); return; } + thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index, linkMargin, new_entry_created); + thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index); if (security_headers->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) { thread_management_key_synch_req(cur->id, common_read_32_bit(security_headers->Keysource)); @@ -460,32 +457,35 @@ static void thread_parse_accept(protocol_interface_info_entry_t *cur, mle_messag mleFrameCounter = llFrameCounter; } - entry_temp->threadNeighbor = true; - entry_temp->short_adr = shortAddress; - entry_temp->mle_frame_counter = mleFrameCounter; + entry_temp->mac16 = shortAddress; + mle_service_frame_counter_entry_add(cur->id, entry_temp->index, mleFrameCounter); // Set full data as REED needs full data and SED will not make links - entry_temp->mode |= MLE_THREAD_REQ_FULL_DATA_SET; - - mac_helper_devicetable_set(entry_temp, cur, llFrameCounter, security_headers->KeyIndex, new_entry_created); + thread_neighbor_class_request_full_data_setup_set(&cur->thread_info->neighbor_class, entry_temp->index, true); + mlme_device_descriptor_t device_desc; + mac_helper_device_description_write(cur, &device_desc, entry_temp->mac64, entry_temp->mac16,llFrameCounter, false); + mac_helper_devicetable_set(&device_desc, cur, entry_temp->index, security_headers->KeyIndex, new_entry_created); + uint32_t timeout; - if (entry_temp->timeout_rx) { - mle_entry_timeout_refresh(entry_temp); + if (new_entry_created) { + timeout = THREAD_DEFAULT_LINK_LIFETIME; } else { - mle_entry_timeout_update(entry_temp, THREAD_DEFAULT_LINK_LIFETIME); + timeout = entry_temp->link_lifetime; } - if (thread_i_am_router(cur) && thread_is_router_addr(entry_temp->short_adr)) { + mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, timeout); + + if (thread_i_am_router(cur) && thread_is_router_addr(entry_temp->mac16)) { // If we both are routers, mark the link as 2-way - entry_temp->handshakeReady = 1; - tr_debug("Marked link as 2-way, handshakeReady=%d", entry_temp->handshakeReady); + entry_temp->connected_device = 1; + tr_debug("Marked link as 2-way, handshakeReady=%d", entry_temp->connected_device); } else { - tr_debug("Marked link as 1-way, handshakeReady=%d", entry_temp->handshakeReady); + tr_debug("Marked link as 1-way, handshakeReady=%d", entry_temp->connected_device); } blacklist_update(mle_msg->packet_src_address, true); if (mle_tlv_read_8_bit_tlv(MLE_TYPE_RSSI, mle_msg->data_ptr, mle_msg->data_length, &linkMarginfronNeigh)) { - thread_routing_update_link_margin(cur, entry_temp->short_adr, linkMargin, linkMarginfronNeigh); + thread_routing_update_link_margin(cur, entry_temp->mac16, linkMargin, linkMarginfronNeigh); } } static void thread_parse_annoucement(protocol_interface_info_entry_t *cur, mle_message_t *mle_msg) @@ -544,7 +544,7 @@ static void thread_parse_data_response(protocol_interface_info_entry_t *cur, mle mle_tlv_info_t ConfigurationTlv; uint64_t active_timestamp = 0; uint64_t pending_timestamp = 0;// means no pending timestamp - mle_neigh_table_entry_t *entry_temp; + mac_neighbor_table_entry_t *entry_temp; bool accept_new_data = false; bool leaderDataReceived; @@ -560,7 +560,12 @@ static void thread_parse_data_response(protocol_interface_info_entry_t *cur, mle return; } - entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL); + entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL); + + if (entry_temp) { + thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index, linkMargin, false); + thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index); + } if(cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_ROUTER || cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_FULL_END_DEVICE) { @@ -570,7 +575,7 @@ static void thread_parse_data_response(protocol_interface_info_entry_t *cur, mle return; } } else { - if (thread_info(cur)->thread_leader_data->partitionId != leaderData.partitionId) { + if (!thread_partition_match(cur, &leaderData)) { // if receiving data response from different partition it is dropped return; } @@ -583,10 +588,8 @@ static void thread_parse_data_response(protocol_interface_info_entry_t *cur, mle } } - if (thread_info(cur)->thread_leader_data->partitionId != leaderData.partitionId) { - thread_info(cur)->thread_leader_data->leaderRouterId = leaderData.leaderRouterId; - thread_info(cur)->thread_leader_data->partitionId = leaderData.partitionId; - thread_old_partition_data_purge(cur); + if (!thread_partition_match(cur, &leaderData)) { + thread_partition_info_update(cur, &leaderData); accept_new_data = true; } @@ -705,11 +708,11 @@ static void thread_host_child_update_request_process(protocol_interface_info_ent mle_tlv_info_t tlv_req; uint64_t active_timestamp = 0; uint64_t pending_timestamp = 0;// means no pending timestamp - mle_neigh_table_entry_t *entry_temp; + mac_neighbor_table_entry_t *entry_temp; bool data_request_needed = false; tr_debug("Child update request"); - entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL); + entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL); if (!thread_leader_data_parse(mle_msg->data_ptr, mle_msg->data_length, &leaderData) || !entry_temp || @@ -718,14 +721,16 @@ static void thread_host_child_update_request_process(protocol_interface_info_ent tr_warn("invalid message"); return; } + + thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index, linkMargin, false); + thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index); + mle_tlv_read_tlv(MLE_TYPE_CHALLENGE, mle_msg->data_ptr, mle_msg->data_length, &challengeTlv); mle_tlv_read_tlv(MLE_TYPE_TLV_REQUEST, mle_msg->data_ptr, mle_msg->data_length, &tlv_req); // Check if partition changed - if (thread_info(cur)->thread_leader_data->partitionId != leaderData.partitionId) { - thread_info(cur)->thread_leader_data->leaderRouterId = leaderData.leaderRouterId; - thread_info(cur)->thread_leader_data->partitionId = leaderData.partitionId; - thread_old_partition_data_purge(cur); + if (!thread_partition_match(cur, &leaderData)) { + thread_partition_info_update(cur, &leaderData); } //Check Network Data TLV if (mle_tlv_read_tlv(MLE_TYPE_NETWORK_DATA, mle_msg->data_ptr, mle_msg->data_length, &networkDataTlv)) { @@ -767,7 +772,7 @@ static void thread_parse_child_update_response(protocol_interface_info_entry_t * { uint8_t mode; uint32_t timeout; - mle_neigh_table_entry_t *entry_temp; + mac_neighbor_table_entry_t *entry_temp; thread_leader_data_t leaderData = {0}; uint8_t status; bool leader_data_received; @@ -780,11 +785,12 @@ static void thread_parse_child_update_response(protocol_interface_info_entry_t * //mle_service_buffer_find leader_data_received = thread_leader_data_parse(mle_msg->data_ptr, mle_msg->data_length, &leaderData); - entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL); + entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL); if (mle_tlv_read_8_bit_tlv(MLE_TYPE_STATUS, mle_msg->data_ptr, mle_msg->data_length, &status) && status == 1 && thread_check_is_this_my_parent(cur, entry_temp)) { tr_debug("parent has connection error"); + mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry_temp); thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL); return; } @@ -798,6 +804,8 @@ static void thread_parse_child_update_response(protocol_interface_info_entry_t * } if (security_headers->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) { + thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index, linkMargin, false); + thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index); thread_management_key_synch_req(cur->id, common_read_32_bit(security_headers->Keysource)); } else { tr_debug("Key ID Mode 2 not used; dropped."); @@ -811,13 +819,11 @@ static void thread_parse_child_update_response(protocol_interface_info_entry_t * timeout = cur->thread_info->host_link_timeout; if (mle_tlv_read_32_bit_tlv(MLE_TYPE_TIMEOUT, mle_msg->data_ptr, mle_msg->data_length, &timeout)) { - entry_temp->holdTime = 90; tr_debug("Setting child timeout, value=%"PRIu32, timeout); - mle_entry_timeout_update(entry_temp, timeout); } tr_debug("Keep-Alive -->Respond from Parent"); - mle_entry_timeout_refresh(entry_temp); + mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, timeout); //Save possible new Leader Data if (leader_data_received) { diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_nd.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_nd.c index 4c9a5af39184..717e757bffd6 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_nd.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_nd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -50,6 +50,7 @@ #include "ns_trace.h" #include "6LoWPAN/Thread/thread_common.h" #include "6LoWPAN/Thread/thread_routing.h" +#include "6LoWPAN/Thread/thread_neighbor_class.h" #include "6LoWPAN/Thread/thread_nd.h" #include "6LoWPAN/Thread/thread_joiner_application.h" #include "6LoWPAN/Thread/thread_extension.h" @@ -57,6 +58,7 @@ #include "6LoWPAN/Thread/thread_resolution_server.h" #include "6LoWPAN/Thread/thread_bbr_api_internal.h" #include "6LoWPAN/Thread/thread_extension_bbr.h" +#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h" #include "6LoWPAN/MAC/mac_helper.h" #include "Common_Protocols/icmpv6.h" #include "MLE/mle.h" @@ -196,14 +198,14 @@ bool thread_nd_ns_transmit(protocol_interface_info_entry_t *cur, ipv6_neighbour_ } } -static mle_neigh_table_entry_t *thread_nd_child_mleid_get(int8_t interface_id, uint8_t *childAddress, uint8_t *mlmeid_ptr) +static mac_neighbor_table_entry_t *thread_nd_child_mleid_get(protocol_interface_info_entry_t *cur, uint8_t *childAddress, uint8_t *mlmeid_ptr) { - mle_neigh_table_entry_t *entry_temp; - entry_temp = mle_class_get_by_link_address(interface_id, childAddress, ADDR_802_15_4_SHORT); - if (entry_temp) { - if ((entry_temp->mode & MLE_DEV_MASK) == MLE_RFD_DEV) { - memcpy(mlmeid_ptr,entry_temp->mlEid,8); - return entry_temp; + mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), childAddress, ADDR_802_15_4_SHORT); + if (entry && !entry->ffd_device) { + uint8_t *ptr = thread_neighbor_class_get_mleid(&cur->thread_info->neighbor_class, entry->index); + if (ptr) { + memcpy(mlmeid_ptr, ptr, 8); + return entry; } } return NULL; @@ -228,12 +230,13 @@ static int thread_nd_address_query_lookup(int8_t interface_id, const uint8_t tar /* Scan IPv6 neighbour cache for registered entries of children */ ns_list_foreach(ipv6_neighbour_t, n, &cur->ipv6_neighbour_cache.list) { if (n->type == IP_NEIGHBOUR_REGISTERED && addr_ipv6_equal(n->ip_address, target_addr)) { - mle_neigh_table_entry_t *mle_entry; + mac_neighbor_table_entry_t *mle_entry; *addr_out = mac16; - mle_entry = thread_nd_child_mleid_get(interface_id, &n->ll_address[2], mleid_ptr); + mle_entry = thread_nd_child_mleid_get(cur, &n->ll_address[2], mleid_ptr); if (mle_entry) { //Get MLEID from Child - *last_transaction_time = (protocol_core_monotonic_time - mle_entry->last_contact_time) / 10; /* Both variables are count of 100ms ticks. */ + uint32_t last_contact = thread_neighbor_last_communication_time_get(&cur->thread_info->neighbor_class, mle_entry->index); + *last_transaction_time = (protocol_core_monotonic_time - last_contact) / 10; /* Both variables are count of 100ms ticks. */ *proxy = true; return 0; } @@ -291,17 +294,18 @@ static void thread_nd_address_error(int8_t interface_id, const uint8_t ip_addr[1 if_address_entry_t *addr_entry = addr_get_entry(cur, ip_addr); if (addr_entry && memcmp(ml_eid, cur->iid_slaac, 8)) { addr_duplicate_detected(cur, ip_addr); + thread_extension_address_generate(cur); } /* Scan IPv6 neighbour cache for registered entries of children */ ns_list_foreach_safe(ipv6_neighbour_t, n, &cur->ipv6_neighbour_cache.list) { if (n->type == IP_NEIGHBOUR_REGISTERED && addr_ipv6_equal(n->ip_address, ip_addr)) { uint8_t child_mleid[8]; - mle_neigh_table_entry_t *child = thread_nd_child_mleid_get(interface_id, &n->ll_address[2], child_mleid); + mac_neighbor_table_entry_t *child = thread_nd_child_mleid_get(cur, &n->ll_address[2], child_mleid); /* If this address belongs to an RFD child, with a different ML-EID, we must send it a duplicate message, and remove the EID */ if (child && memcmp(child_mleid, ml_eid, 8)) { uint8_t child_ml_addr[16]; - thread_addr_write_mesh_local_16(child_ml_addr, child->short_adr, cur->thread_info); + thread_addr_write_mesh_local_16(child_ml_addr, child->mac16, cur->thread_info); tr_warn("Forwarding address error to child %04x", common_read_16_bit(&n->ll_address[2])); thread_resolution_client_address_error(interface_id, child_ml_addr, ip_addr, ml_eid); ipv6_neighbour_entry_remove(&cur->ipv6_neighbour_cache, n); @@ -367,7 +371,7 @@ buffer_t *thread_nd_snoop(protocol_interface_info_entry_t *cur, buffer_t *buf, c return buffer_free(buf); } - if (!mle_class_get_by_link_address(cur->id, &ll_dst->address[2], ADDR_802_15_4_SHORT)) { + if (!mac_neighbor_table_address_discover(mac_neighbor_info(cur), &ll_dst->address[2], ADDR_802_15_4_SHORT)) { /* We now know this was a packet for a non-existent child */ goto bounce; } @@ -433,7 +437,7 @@ buffer_t *thread_nd_special_forwarding(protocol_interface_info_entry_t *cur, buf return buf; } - mle_neigh_table_entry_t *entry = mle_class_get_by_link_address(cur->id, &ll_src->address[2], ADDR_802_15_4_SHORT); + mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), &ll_src->address[2], ADDR_802_15_4_SHORT); /* Due to note 1 and 1b above, full-function children / neighbor routers * who did resolve to an RLOC16 may have optimised out the mesh header. @@ -446,7 +450,7 @@ buffer_t *thread_nd_special_forwarding(protocol_interface_info_entry_t *cur, buf * is not in our neighbour cache, we need to send the child an error * to clear its cache.) */ - if (!(buf->options.lowpan_mesh_rx || (entry && (entry->mode & MLE_DEV_MASK) == MLE_FFD_DEV))) { + if (!(buf->options.lowpan_mesh_rx || (entry && entry->ffd_device))) { return buf; } @@ -530,10 +534,11 @@ buffer_t *thread_nd_icmp_handler(protocol_interface_info_entry_t *cur, buffer_t return buf; } -int thread_nd_address_registration(protocol_interface_info_entry_t *cur, const uint8_t *ipv6Address, uint16_t mac16, uint16_t panId, const uint8_t *mac64) +int thread_nd_address_registration(protocol_interface_info_entry_t *cur, const uint8_t *ipv6Address, uint16_t mac16, uint16_t panId, const uint8_t *mac64, bool *new_neighbour_created) { ipv6_neighbour_t *neigh; uint8_t ll_address[4]; + bool neighbor_created = false; common_write_16_bit(panId, ll_address + 0); common_write_16_bit(mac16, ll_address + 2); neigh = ipv6_neighbour_lookup_or_create(&cur->ipv6_neighbour_cache, ipv6Address); @@ -542,21 +547,24 @@ int thread_nd_address_registration(protocol_interface_info_entry_t *cur, const u } uint8_t *nce_eui64 = ipv6_neighbour_eui64(&cur->ipv6_neighbour_cache, neigh); - /*if (neigh->state != IP_NEIGHBOUR_NEW) - { - // Worry about this later - // Compare mac64 to nce_eui64 to spot duplicates - } - else*/ + if (neigh->state != IP_NEIGHBOUR_NEW && memcmp(nce_eui64, mac64, 8) != 0) { - /* New entry */ - memcpy(nce_eui64, mac64, 8); + return -2; } + + /* New entry */ + if (neigh->state == IP_NEIGHBOUR_NEW) { + neighbor_created = true; + } + memcpy(nce_eui64, mac64, 8); /* Set the LL address, ensure it's marked STALE */ ipv6_neighbour_entry_update_unsolicited(&cur->ipv6_neighbour_cache, neigh, ADDR_802_15_4_SHORT, ll_address); neigh->type = IP_NEIGHBOUR_REGISTERED; neigh->lifetime = 0xffffffff; //Set Infinite ipv6_neighbour_set_state(&cur->ipv6_neighbour_cache, neigh, IP_NEIGHBOUR_STALE); + if (new_neighbour_created) { + *new_neighbour_created = neighbor_created; + } return 0; } diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_nd.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_nd.h index 69d35740f3cc..60277db436c5 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_nd.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_nd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -55,7 +55,7 @@ int thread_nd_map_anycast_address(protocol_interface_info_entry_t *cur, uint16_t void thread_nd_address_remove(protocol_interface_info_entry_t *cur_interface, addrtype_t ll_type, const uint8_t *ll_address); void thread_nd_flush_neighbour_cache_for_short_addr(struct protocol_interface_info_entry *cur, uint16_t flushee, bool children); -int thread_nd_address_registration(struct protocol_interface_info_entry *cur, const uint8_t *ipv6Address, uint16_t mac16, uint16_t panId, const uint8_t *mac64); +int thread_nd_address_registration(struct protocol_interface_info_entry *cur, const uint8_t *ipv6Address, uint16_t mac16, uint16_t panId, const uint8_t *mac64, bool *new_neighbour_created); #else //HAVE_THREAD_NEIGHBOR_DISCOVERY diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_neighbor_class.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_neighbor_class.c new file mode 100644 index 000000000000..5d626c4d84dd --- /dev/null +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_neighbor_class.c @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2018, Arm Limited and affiliates. + * SPDX-License-Identifier: BSD-3-Clause + * + * 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 the copyright holder 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 "nsconfig.h" +#include +#include "ns_types.h" +#include "ns_trace.h" +#include "nsdynmemLIB.h" +#include "common_functions.h" +#include "NWK_INTERFACE/Include/protocol.h" +#include "6LoWPAN/Thread/thread_common.h" +#include "6LoWPAN/Thread/thread_routing.h" +#include "6LoWPAN/Thread/thread_neighbor_class.h" + + +static thread_neigh_table_entry_t * thread_neighbor_class_table_entry_get(thread_neighbor_class_t *class_ptr, uint8_t attribute_index) +{ + if (!class_ptr->neigh_info_list || attribute_index >= class_ptr->list_size) { + return NULL; + } + + thread_neigh_table_entry_t *entry = class_ptr->neigh_info_list + attribute_index; + return entry; +} + +bool thread_neighbor_class_create(thread_neighbor_class_t *class_ptr, uint8_t neigh_table_size) +{ + class_ptr->neigh_info_list = ns_dyn_mem_alloc(sizeof(thread_neigh_table_entry_t) * neigh_table_size); + if (!class_ptr->neigh_info_list) { + return false; + } + + class_ptr->list_size = neigh_table_size; + thread_neigh_table_entry_t * list_ptr = class_ptr->neigh_info_list; + for (uint8_t i = 0; i< neigh_table_size; i++) { + memset(list_ptr, 0, sizeof(thread_neigh_table_entry_t)); + list_ptr++; + } + return true; +} + +void thread_neighbor_class_delete(thread_neighbor_class_t *class_ptr) +{ + ns_dyn_mem_free(class_ptr->neigh_info_list); + class_ptr->neigh_info_list = NULL; + class_ptr->list_size = 0; +} + +void thread_neighbor_class_add_mleid(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index, const uint8_t *mleid) +{ + thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index); + if (!entry) { + return; + } + memcpy(entry->mlEid, mleid, 8); +} + +uint8_t * thread_neighbor_class_get_mleid(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index) +{ + thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index); + if (!entry) { + return NULL; + } + return entry->mlEid; +} + +void thread_neighbor_last_communication_time_update(thread_neighbor_class_t *class_ptr, uint8_t attribute_index) +{ + thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index); + if (!entry) { + return; + } + entry->last_contact_time = protocol_core_monotonic_time; +} + +void thread_neighbor_class_update_link(thread_neighbor_class_t *class_ptr, uint8_t attribute_index, uint8_t linkmargin, bool new_link) +{ + thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index); + if (!entry) { + return; + } + + if (new_link) { + entry->link_margin = entry->link_margin + linkmargin - (entry->link_margin >> THREAD_LINK_MARGIN_SCALING); + } else { + entry->link_margin = linkmargin << THREAD_LINK_MARGIN_SCALING; + } +} + +uint16_t thread_neighbor_entry_linkmargin_get(thread_neighbor_class_t *class_ptr, uint8_t attribute_index) +{ + thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index); + if (!entry) { + return 0; + } + return entry->link_margin; +} + +uint32_t thread_neighbor_last_communication_time_get(thread_neighbor_class_t *class_ptr, uint8_t attribute_index) +{ + thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index); + if (!entry) { + return 0; + } + return entry->last_contact_time; +} + +bool thread_neighbor_class_mleid_compare(thread_neighbor_class_t *class_ptr, uint8_t attribute_index, const uint8_t *mleid) +{ + thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index); + if (!entry || memcmp(entry->mlEid, mleid, 8)) { + return false; + } + return true; +} + +bool thread_neighbor_class_request_full_data_setup(thread_neighbor_class_t *class_ptr, uint8_t attribute_index) +{ + thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index); + if (!entry) { + return false; + } + return entry->request_full_data_set; + +} + +bool thread_neighbor_class_secured_data_request(thread_neighbor_class_t *class_ptr, uint8_t attribute_index) +{ + thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index); + if (!entry) { + return false; + } + return entry->secured_data_request; +} + +void thread_neighbor_class_request_full_data_setup_set(thread_neighbor_class_t *class_ptr, uint8_t attribute_index, bool value) +{ + thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index); + if (entry) { + entry->request_full_data_set = value; + } +} + +void thread_neighbor_class_secured_data_request_set(thread_neighbor_class_t *class_ptr, uint8_t attribute_index, bool value) +{ + thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index); + if (entry) { + entry->secured_data_request = value; + } +} + +void thread_neighbor_class_mode_parse_to_entry(thread_neighbor_class_t *class_ptr, uint8_t attribute_index, uint8_t mode) +{ + thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index); + if (entry) { + entry->request_full_data_set = mode & MLE_THREAD_REQ_FULL_DATA_SET; + entry->secured_data_request = mode & MLE_THREAD_SECURED_DATA_REQUEST; + } +} + +uint8_t thread_neighbor_class_mode_write_from_entry(thread_neighbor_class_t *class_ptr, uint8_t attribute_index) +{ + uint8_t mode = 0; + thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index); + if (entry) { + if (entry->request_full_data_set) { + mode |= MLE_THREAD_REQ_FULL_DATA_SET; + } + + if (entry->secured_data_request) { + mode |= MLE_THREAD_SECURED_DATA_REQUEST; + } + } + return mode; +} + + +void thread_neighbor_class_entry_remove(thread_neighbor_class_t *class_ptr, uint8_t attribute_index) +{ + thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index); + if (entry) { + memset(entry, 0, sizeof(thread_neigh_table_entry_t)); + } +} diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_neighbor_class.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_neighbor_class.h new file mode 100644 index 000000000000..ccf5f766e419 --- /dev/null +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_neighbor_class.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2018, Arm Limited and affiliates. + * SPDX-License-Identifier: BSD-3-Clause + * + * 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 the copyright holder 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 THREAD_NEIGHBOR_CLASS_H_ +#define THREAD_NEIGHBOR_CLASS_H_ + +struct thread_neighbor_class_s; + +/** Thead Spesific ModeFlags */ +#define MLE_THREAD_SECURED_DATA_REQUEST 0x04 +#define MLE_THREAD_REQ_FULL_DATA_SET 0x01 + +bool thread_neighbor_class_create(struct thread_neighbor_class_s *class_ptr, uint8_t neigh_table_size); + +void thread_neighbor_class_delete(struct thread_neighbor_class_s *class_ptr); + +void thread_neighbor_class_add_link(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index, uint8_t linkmargin); + +void thread_neighbor_class_add_mleid(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index, const uint8_t *mleid); + +uint8_t * thread_neighbor_class_get_mleid(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index); + +void thread_neighbor_class_update_link(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index, uint8_t linkmargin, bool new_link); + +void thread_neighbor_last_communication_time_update(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index); + +uint16_t thread_neighbor_entry_linkmargin_get(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index); + +uint32_t thread_neighbor_last_communication_time_get(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index); + +bool thread_neighbor_class_mleid_compare(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index, const uint8_t *mleid); + +bool thread_neighbor_class_request_full_data_setup(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index); + +bool thread_neighbor_class_secured_data_request(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index); + +void thread_neighbor_class_mode_parse_to_entry(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index, uint8_t mode); + +uint8_t thread_neighbor_class_mode_write_from_entry(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index); + +void thread_neighbor_class_request_full_data_setup_set(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index, bool value); + +void thread_neighbor_class_secured_data_request_set(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index, bool value); + +void thread_neighbor_class_entry_remove(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index); + +#endif /* THREAD_NEIGHBOR_CLASS_H_ */ diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_network_data_lib.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_network_data_lib.h index ecc85cfcd12d..5c3790111158 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_network_data_lib.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_network_data_lib.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -60,6 +60,7 @@ #define THREAD_P_DEF_ROUTE_BIT_MOVE 9 /* R-bit */ #define THREAD_P_ON_MESH_BIT_MOVE 8 /* O-bit */ #define THREAD_P_ND_DNS_BIT_MOVE 7 /* N-bit */ +#define THREAD_P_ND_RES_BIT_MOVE 6 /* First reserved bit */ /* Bit shift for HasRouteTLV preference bit */ #define THREAD_HAS_ROUTE_PRF_BIT_MOVE 6 /* Prf-bits */ diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_network_data_storage.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_network_data_storage.c index 2ba5226c2d9a..0947cf4564bc 100755 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_network_data_storage.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_network_data_storage.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -328,9 +328,8 @@ thread_network_local_data_entry_t *thread_local_service_list_allocate(thread_pre newEntry->servicesPrefixLen = prefixTlv->PrefixLen; newEntry->domainId = prefixTlv->domainId; newEntry->dhcpv6ServerActive = false; - newEntry->dhcpv6ServerDataStable = false; + newEntry->brDataStable = false; newEntry->slaacServerActive = false; - newEntry->slaacServerDataStable = false; newEntry->slaacPreferred = false; newEntry->routeActive = false; newEntry->routeDataStable = false; @@ -339,6 +338,8 @@ thread_network_local_data_entry_t *thread_local_service_list_allocate(thread_pre newEntry->defaultRoute = false; newEntry->onMesh = false; newEntry->ndDns = false; + newEntry->brActive = false; + newEntry->res1 = false; } return newEntry; } @@ -373,6 +374,7 @@ thread_network_server_data_entry_t *thread_server_entry_allocate(thread_border_r newEntry->Prf = service->Prf; newEntry->P_on_mesh = service->P_on_mesh; newEntry->P_nd_dns = service->P_nd_dns; + newEntry->P_res1 = service->P_res1; newEntry->canDelete = false; } @@ -868,7 +870,7 @@ static int thread_service_data_delete_mark_by_router_id(thread_network_data_serv return retVal; } -static int thread_server_context_clean(thread_network_data_cache_entry_t *cachePtr, thread_data_context_list_t *listPtr, thread_network_data_prefix_cache_entry_t *prefixEntry, lowpan_context_list_t *context_list) +static int thread_server_context_clean(int8_t id, thread_network_data_cache_entry_t *cachePtr, thread_data_context_list_t *listPtr, thread_network_data_prefix_cache_entry_t *prefixEntry, lowpan_context_list_t *context_list) { int retVal = -1; (void) prefixEntry; @@ -879,7 +881,9 @@ static int thread_server_context_clean(thread_network_data_cache_entry_t *cacheP cachePtr->stableUpdatePushed = true; } // Set context lifetime to 0 to delete - lowpan_context_update(context_list, cur->cid, 0, NULL, 0, true); + if (thread_extension_context_can_delete(id, prefixEntry->servicesPrefix, cur->contextPrefixLength)) { + lowpan_context_update(context_list, cur->cid, 0, NULL, 0, true); + } ns_list_remove(listPtr, cur); ns_dyn_mem_free(cur); retVal = 0; @@ -1019,7 +1023,7 @@ bool thread_network_data_router_id_free(thread_network_data_cache_entry_t *cache } thread_server_data_clean_by_router_id(cachePtr, &cur->routeList, cur, true, curInterface); if (!is_leader) { - thread_server_context_clean(cachePtr, &cur->contextList, cur, &curInterface->lowpan_contexts); + thread_server_context_clean(curInterface->id, cachePtr, &cur->contextList, cur, &curInterface->lowpan_contexts); } if (ns_list_is_empty(&cur->borderRouterList)) { @@ -1071,7 +1075,7 @@ bool thread_network_data_router_id_free(thread_network_data_cache_entry_t *cache return address_removed; } -void thread_network_data_context_re_use_timer_update(thread_network_data_cache_entry_t *cachePtr, uint32_t ticks, lowpan_context_list_t *context_list) +void thread_network_data_context_re_use_timer_update(int8_t id, thread_network_data_cache_entry_t *cachePtr, uint32_t ticks, lowpan_context_list_t *context_list) { ns_list_foreach_safe(thread_network_data_prefix_cache_entry_t, cur, &cachePtr->localPrefixList) { ns_list_foreach_safe(thread_network_data_context_entry_t, curContext, &cur->contextList) { @@ -1086,7 +1090,9 @@ void thread_network_data_context_re_use_timer_update(thread_network_data_cache_e cachePtr->temporaryUpdatePushed = true; } // Set context lifetime to 0 to delete - lowpan_context_update(context_list, curContext->cid, 0, NULL, 0, true); + if (thread_extension_context_can_delete(id, cur->servicesPrefix,curContext->contextPrefixLength)) { + lowpan_context_update(context_list, curContext->cid, 0, NULL, 0, true); + } ns_dyn_mem_free(curContext); } } @@ -1708,21 +1714,21 @@ int thread_local_server_list_add_on_mesh_server(thread_network_local_data_cache_ if (networkDataList) { thread_network_local_data_entry_t *prefix_entry = thread_local_prefix_entry_get(&networkDataList->prefix_list, prefixTlv); if (prefix_entry) { + prefix_entry->brDataStable = service->stableData; prefix_entry->preference = service->Prf; prefix_entry->configure = service->P_configure; prefix_entry->defaultRoute = service->P_default_route; prefix_entry->onMesh = service->P_on_mesh; prefix_entry->ndDns = service->P_nd_dns; - - if (service->P_dhcp) { - prefix_entry->dhcpv6ServerActive = true; - prefix_entry->dhcpv6ServerDataStable = service->stableData; - } - - if (service->P_slaac) { - prefix_entry->slaacServerActive = true; - prefix_entry->slaacServerDataStable = service->stableData; - prefix_entry->slaacPreferred = service->P_preferred; + prefix_entry->res1 = service->P_res1; + prefix_entry->dhcpv6ServerActive = service->P_dhcp; + prefix_entry->slaacServerActive = service->P_slaac; + prefix_entry->slaacPreferred = service->P_preferred; + + if (service->P_dhcp || + service->P_slaac || + service->P_res1) { + prefix_entry->brActive = true; } if (prefixTlv->PrefixLen == 0) { @@ -1891,9 +1897,7 @@ int thread_local_server_del_route(thread_network_local_data_cache_entry_t *netwo } prefix_entry->routeActive = false; - if (prefix_entry->dhcpv6ServerActive) { - return 0; - } else if (prefix_entry->slaacServerActive) { + if (prefix_entry->brActive) { return 0; } @@ -2023,17 +2027,13 @@ uint8_t thread_server_prefix_length(thread_network_local_data_entry_t *cur) if (cur->routeActive) { - if (!((cur->slaacServerActive || cur->dhcpv6ServerActive) && cur->defaultRoute)) { + if (!(cur->brActive && cur->defaultRoute)) { // HasRoute is added if BorderRouter TLV does not have default route bit tempLength += 5; } } - if (cur->dhcpv6ServerActive) { - tempLength += 6; - } - - if (cur->slaacServerActive) { + if (cur->brActive) { tempLength += 6; } @@ -2091,14 +2091,9 @@ uint16_t thread_nd_own_service_list_data_size(thread_network_local_data_cache_en static bool thread_check_local_data_prefix_stable_boolean(thread_network_local_data_entry_t *dataList) { - if (dataList->dhcpv6ServerActive && dataList->dhcpv6ServerDataStable) { + if (dataList->brActive && dataList->brDataStable) { return true; } - - if (dataList->slaacServerActive && dataList->slaacServerDataStable) { - return true; - } - return false; } @@ -2269,7 +2264,7 @@ uint8_t * thread_nd_own_service_list_data_write(thread_network_local_data_cache_ if (servicesLen) { ptr = thread_nd_hosted_prefix_header_write(ptr,servicesLen, cur); if (cur->routeActive) { - if (!((cur->slaacServerActive || cur->dhcpv6ServerActive) && cur->defaultRoute)) { + if (!(cur->brActive && cur->defaultRoute)) { // HasRoute is added if BorderRouter TLV does not have default route bit uint8_t preference = 0; tlvType = THREAD_NWK_DATA_TYPE_ROUTE; @@ -2283,10 +2278,10 @@ uint8_t * thread_nd_own_service_list_data_write(thread_network_local_data_cache_ } } - if (cur->slaacServerActive || cur->dhcpv6ServerActive) { + if (cur->brActive) { uint16_t flags = 0; tlvType = THREAD_NWK_DATA_TYPE_BORDER_ROUTER; - if (cur->slaacServerDataStable || cur->dhcpv6ServerDataStable) { + if (cur->brDataStable) { tlvType |= THREAD_NWK_STABLE_DATA; } if (cur->slaacServerActive) { @@ -2313,6 +2308,9 @@ uint8_t * thread_nd_own_service_list_data_write(thread_network_local_data_cache_ if (cur->ndDns) { flags |= 1 << THREAD_P_ND_DNS_BIT_MOVE; } + if (cur->res1) { + flags |= 1 << THREAD_P_ND_RES_BIT_MOVE; + } ptr = thread_service_border_router_tlv_write(ptr, tlvType, routerID, flags); } // slaac or dhcp } diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_network_data_storage.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_network_data_storage.h index 33671a74cf36..10dbd298f167 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_network_data_storage.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_network_data_storage.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -72,6 +72,7 @@ typedef struct thread_network_data_temporary_route_or_dhcpv6_server_entry_s { bool stableData: 1; bool P_on_mesh: 1; bool P_nd_dns: 1; + bool P_res1: 1; bool canDelete: 1; ns_list_link_t link; /*!< List link entry */ } thread_network_server_data_entry_t; @@ -87,6 +88,7 @@ typedef struct thread_border_router_tlv_entry_t { bool stableData: 1; /* P_stable */ bool P_on_mesh: 1; /* P_on_mesh */ bool P_nd_dns: 1; /* P_nd_dns */ + bool P_res1: 1; /* P_res1 */ } thread_border_router_tlv_entry_t; typedef struct thread_prefix_tlv { @@ -136,16 +138,17 @@ typedef struct thread_network_local_data_entry_s { uint8_t servicesPrefixLen; /*!< Prefix length in bits This Can Be 1-128 */ bool routeActive: 1; bool routeDataStable: 1; + bool brActive: 1; bool dhcpv6ServerActive: 1; - bool dhcpv6ServerDataStable: 1; + bool brDataStable: 1; bool slaacServerActive: 1; - bool slaacServerDataStable: 1; bool slaacPreferred: 1; unsigned preference: 2; bool configure: 1; bool defaultRoute: 1; bool onMesh: 1; bool ndDns: 1; + bool res1:1; ns_list_link_t link; /*!< List link entry */ } thread_network_local_data_entry_t; @@ -207,7 +210,7 @@ bool thread_network_data_router_id_free(thread_network_data_cache_entry_t *cache void thread_network_local_data_free_and_clean(thread_network_local_data_cache_entry_t *cachePtr, int8_t interface_id); -void thread_network_data_context_re_use_timer_update(thread_network_data_cache_entry_t *cachePtr, uint32_t ticks, lowpan_context_list_t *context_list); +void thread_network_data_context_re_use_timer_update(int8_t id, thread_network_data_cache_entry_t *cachePtr, uint32_t ticks, lowpan_context_list_t *context_list); /** * Add new route information to route List diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_network_synch.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_network_synch.c index 8528d0c8b87b..22d6e212bc14 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_network_synch.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_network_synch.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -56,12 +56,14 @@ #include "6LoWPAN/Thread/thread_joiner_application.h" #include "6LoWPAN/Thread/thread_management_client.h" #include "6LoWPAN/Thread/thread_network_synch.h" +#include "6LoWPAN/Thread/thread_neighbor_class.h" #include "thread_management_if.h" #include "thread_config.h" #include "Common_Protocols/ipv6.h" #include "Common_Protocols/icmpv6.h" #include "Common_Protocols/icmpv6_radv.h" #include "MLE/mle.h" +#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h" #include "6LoWPAN/MAC/mac_helper.h" #define TRACE_GROUP "tsyn" @@ -90,7 +92,7 @@ typedef struct thread_network_dynamic_data_entry { } thread_network_dynamic_data_entry_t; static thread_sync_child_info_t *thread_dynamic_storage_free_child_find(int8_t interface_id); -static thread_sync_child_info_t *thread_dynamic_storage_child_info_find(int8_t interface_id, mle_neigh_table_entry_t *child); +static thread_sync_child_info_t *thread_dynamic_storage_child_info_find(int8_t interface_id, mac_neighbor_table_entry_t *child); static NS_LIST_DEFINE(thread_network_dynamic_data_info, thread_network_dynamic_data_entry_t, link); thread_network_dynamic_data_entry_t *thread_network_synch_create(int8_t interfaceId) @@ -155,54 +157,53 @@ int thread_network_synch_data_free(int8_t interface_id) * Dynamic network data storage. */ -void thread_dynamic_storage_child_info_store(int8_t interface_id, mle_neigh_table_entry_t *child) +void thread_dynamic_storage_child_info_store(protocol_interface_info_entry_t *cur_interface, mac_neighbor_table_entry_t *child) { - thread_network_dynamic_data_entry_t *storeEntry = thread_network_synch_find(interface_id); + thread_network_dynamic_data_entry_t *storeEntry = thread_network_synch_find(cur_interface->id); if (!storeEntry) { - storeEntry = thread_network_synch_create(interface_id); + storeEntry = thread_network_synch_create(cur_interface->id); } if (!storeEntry) { return; } - thread_sync_child_info_t *child_info = thread_dynamic_storage_child_info_find(interface_id, child); - if (child_info) { - child_info->mode = child->mode; - child_info->short_addr = child->short_adr; - child_info->mle_frame_counter = child->mle_frame_counter; - child_info->mac_frame_counter = 0; - memcpy(child_info->long_addr, child->mac64, 8); - return; - } + uint32_t mle_frame_counter = mle_service_neighbor_frame_counter_get(cur_interface->id, child->index); - child_info = thread_dynamic_storage_free_child_find(interface_id); + thread_sync_child_info_t *child_info = thread_dynamic_storage_child_info_find(cur_interface->id, child); + if (!child_info) { + child_info = thread_dynamic_storage_free_child_find(cur_interface->id); + } if (child_info) { - child_info->mode = child->mode; - child_info->short_addr = child->short_adr; - child_info->mle_frame_counter = child->mle_frame_counter; + uint8_t mode = mle_mode_write_from_mac_entry(child); + mode |= thread_neighbor_class_mode_write_from_entry(&cur_interface->thread_info->neighbor_class, child->index); + + child_info->mode = mode; + child_info->short_addr = child->mac16; + child_info->mle_frame_counter = mle_frame_counter; child_info->mac_frame_counter = 0; memcpy(child_info->long_addr, child->mac64, 8); + return; } return; } -void thread_dynamic_storage_child_info_clear(int8_t interface_id, mle_neigh_table_entry_t *child) +void thread_dynamic_storage_child_info_clear(int8_t interface_id, struct mac_neighbor_table_entry *child) { thread_sync_child_info_t *child_info = thread_dynamic_storage_child_info_find(interface_id, child); if (child_info){ // Clear child information memset (child_info,0,sizeof(thread_sync_child_info_t)); - tr_debug("Dynamic storage: cleared child; mac16=%04x", child->short_adr); + tr_debug("Dynamic storage: cleared child; mac16=%04x", child->mac16); return; } return; } -static thread_sync_child_info_t *thread_dynamic_storage_child_info_find(int8_t interface_id, mle_neigh_table_entry_t *child) +static thread_sync_child_info_t *thread_dynamic_storage_child_info_find(int8_t interface_id, mac_neighbor_table_entry_t *child) { thread_network_dynamic_data_entry_t *storeEntry = thread_network_synch_find(interface_id); @@ -236,6 +237,10 @@ static thread_sync_child_info_t *thread_dynamic_storage_free_child_find(int8_t i void thread_dynamic_storage_build_mle_table(int8_t interface_id) { tr_debug("Dynamic storage: building MLE table."); + protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); + if (!cur || !cur->mac_parameters) { + return; + } thread_network_dynamic_data_entry_t *storeEntry = thread_network_synch_find(interface_id); bool new_entry_created; @@ -248,9 +253,9 @@ void thread_dynamic_storage_build_mle_table(int8_t interface_id) return; } - mle_neigh_table_list_t *neig_list = mle_class_active_list_get(interface_id); + mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list; - if (!neig_list) { + if (!mac_table_list) { return; } @@ -262,19 +267,21 @@ void thread_dynamic_storage_build_mle_table(int8_t interface_id) } uint8_t *mac64 = storeEntry->networ_dynamic_data_parameters.children[i].long_addr; tr_debug("Child: %04x, %s", storeEntry->networ_dynamic_data_parameters.children[i].short_addr, trace_array(mac64, 8)); - mle_neigh_table_entry_t *entry = mle_class_get_entry_by_mac64(interface_id, 64, mac64, true, &new_entry_created); - if (entry) { - entry->short_adr = storeEntry->networ_dynamic_data_parameters.children[i].short_addr; - entry->mle_frame_counter = storeEntry->networ_dynamic_data_parameters.children[i].mle_frame_counter; - entry->mode = storeEntry->networ_dynamic_data_parameters.children[i].mode; - entry->threadNeighbor = true; - - protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); - - if (cur && cur->mac_parameters) { - // Set MAC layer frame counter for the child - mac_helper_devicetable_set(entry, cur, storeEntry->networ_dynamic_data_parameters.children[i].mac_frame_counter, cur->mac_parameters->mac_default_key_index, new_entry_created); - } + + mac_neighbor_table_entry_t *mac_entry = mac_neighbor_entry_get_by_mac64(mac_neighbor_info(cur), mac64, true, &new_entry_created); + if (mac_entry) { + + mac_entry->mac16 = storeEntry->networ_dynamic_data_parameters.children[i].short_addr; + mle_service_frame_counter_entry_add(interface_id, mac_entry->index, storeEntry->networ_dynamic_data_parameters.children[i].mle_frame_counter); + mle_mode_parse_to_mac_entry(mac_entry, storeEntry->networ_dynamic_data_parameters.children[i].mode); + + // Set MAC layer frame counter for the child + mlme_device_descriptor_t device_desc; + thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, mac_entry->index,64, new_entry_created); + thread_neighbor_class_mode_parse_to_entry(&cur->thread_info->neighbor_class, mac_entry->index,storeEntry->networ_dynamic_data_parameters.children[i].mode); + thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, mac_entry->index); + mac_helper_device_description_write(cur, &device_desc, mac_entry->mac64, mac_entry->mac16,storeEntry->networ_dynamic_data_parameters.children[i].mac_frame_counter, false); + mac_helper_devicetable_set(&device_desc, cur, mac_entry->index, cur->mac_parameters->mac_default_key_index, new_entry_created); } } } diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_network_synch.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_network_synch.h index eae9f1807cdb..eb85ae0a03fc 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_network_synch.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_network_synch.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -35,6 +35,9 @@ #ifndef THREAD_NETWORK_SYNCH_H_ #define THREAD_NETWORK_SYNCH_H_ +struct protocol_interface_info_entry; +struct mac_neighbor_table_entry; + //Call This when clean synched networkdata int thread_network_synch_data_free(int8_t interface_id); //Call This when want synch last network setup @@ -46,8 +49,8 @@ bool thread_dynamic_storage_pending_configuration_exists(int8_t interface_id); void thread_dynamic_storage_pending_configuration_read(int8_t interface_id, void *data, uint16_t size); void thread_dynamic_storage_pending_configuration_store(int8_t interface_id, void *data, uint16_t size); -void thread_dynamic_storage_child_info_store(int8_t interface_id, mle_neigh_table_entry_t *child); -void thread_dynamic_storage_child_info_clear(int8_t interface_id, mle_neigh_table_entry_t *child); +void thread_dynamic_storage_child_info_store(struct protocol_interface_info_entry *cur_interface, struct mac_neighbor_table_entry *child); +void thread_dynamic_storage_child_info_clear(int8_t interface_id, struct mac_neighbor_table_entry *child); void thread_dynamic_storage_build_mle_table(int8_t interface_id); void thread_dynamic_storage_frame_counter_store(int8_t interface_id, uint32_t mle_frame_counter, uint32_t mac_frame_counter); uint32_t thread_dynamic_storage_mle_frame_counter_get(int8_t interfaceId); diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_nvm_store.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_nvm_store.c index e0c7c9224c94..0aa4657f687e 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_nvm_store.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_nvm_store.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Arm Limited and affiliates. + * Copyright (c) 2017-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -84,7 +84,7 @@ static int thread_nvm_store_fast_data_save(thread_nvm_fast_data_t* fast_data_to_ static int thread_nvm_store_all_counters_store(uint32_t mac_frame_counter, uint32_t mle_frame_counter, uint32_t seq_counter); static void thread_nvm_store_link_info_delayed_write(uint32_t seconds); -#define MAX_ROOT_PATH_LEN 150 +#define MAX_ROOT_PATH_LEN 200 #define FAST_DATA_STRING_LEN (strlen(FAST_DATA_FILE)+strlen(thread_nvm_store_get_root_path())+1) #define ACTIVE_CONF_STRING_LEN (strlen(THREAD_NVM_ACTIVE_CONF_FILE)+strlen(thread_nvm_store_get_root_path())+1) @@ -330,6 +330,15 @@ int thread_nvm_store_fast_data_check_and_write(uint32_t mac_frame_counter, uint3 return ret; } +int thread_nvm_store_fast_data_write_all(uint32_t mac_frame_counter, uint32_t mle_frame_counter, uint32_t network_seq_counter) +{ + int ret; + ret = thread_nvm_store_all_counters_store(mac_frame_counter, mle_frame_counter, network_seq_counter); + cached_fast_data.mac_frame_counter = mac_frame_counter; + cached_fast_data.mle_frame_counter = mle_frame_counter; + cached_fast_data.seq_counter=network_seq_counter; + return ret; +} int thread_nvm_store_frame_counters_check_and_write(uint32_t mac_frame_counter, uint32_t mle_frame_counter) { diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_nvm_store.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_nvm_store.h index cd160590add4..081c7cf6edc5 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_nvm_store.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_nvm_store.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Arm Limited and affiliates. + * Copyright (c) 2017-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -84,6 +84,9 @@ int thread_nvm_store_fast_data_write(thread_nvm_fast_data_t* fast_data); int thread_nvm_store_frame_counters_check_and_write(uint32_t mac_frame_counter, uint32_t mle_frame_counter); /* stores the frame counter and seq counter to nvm only if any threshold is passed*/ int thread_nvm_store_fast_data_check_and_write(uint32_t mac_frame_counter, uint32_t mle_frame_counter, uint32_t network_seq_counter); +/*Store all fast data values unconditionally*/ +int thread_nvm_store_fast_data_write_all(uint32_t mac_frame_counter, uint32_t mle_frame_counter, uint32_t network_seq_counter); + /* stores the value to nvm only if it has changed */ int thread_nvm_store_seq_counter_write(uint32_t network_seq_counter); diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_resolution_server.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_resolution_server.c index 292b7ca84366..362f96aa7cdf 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_resolution_server.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_resolution_server.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_resolution_server.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_resolution_server.h index a3795a1867c9..77fa6110454d 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_resolution_server.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_resolution_server.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_router_bootstrap.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_router_bootstrap.c index ced6b84281ca..0c00650f7fda 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_router_bootstrap.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_router_bootstrap.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -66,6 +66,7 @@ #include "6LoWPAN/Thread/thread_lowpower_private_api.h" #include "6LoWPAN/Thread/thread_tmfcop_lib.h" #include "6LoWPAN/Thread/thread_nvm_store.h" +#include "6LoWPAN/Thread/thread_neighbor_class.h" #include "thread_management_if.h" #include "Common_Protocols/ipv6.h" #include "Common_Protocols/icmpv6.h" @@ -83,12 +84,12 @@ #include "6LoWPAN/MAC/mac_data_poll.h" #include "thread_border_router_api.h" #include "Core/include/address.h" +#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h" #ifdef HAVE_THREAD_ROUTER #define TRACE_GROUP "trbs" -static bool thread_rfd_device(uint8_t mode); static uint8_t *thread_tlv_add(protocol_interface_info_entry_t *cur, uint8_t *ptr, uint8_t tlv_type, uint8_t mode); static void mle_multicast_push_to_sleep_child(protocol_interface_info_entry_t *cur, buffer_t *buf); @@ -103,18 +104,10 @@ static int thread_router_accept_request_build(protocol_interface_info_entry_t *c static int thread_child_update_response(protocol_interface_info_entry_t *cur, uint8_t *dst_address, uint8_t mode, uint16_t short_address, uint32_t timeout, mle_tlv_info_t *addressRegisterTlv,mle_tlv_info_t *tlvReq, mle_tlv_info_t *challengeTlv, uint64_t active_timestamp, uint64_t pending_timestamp); static int mle_build_and_send_data_response_msg(protocol_interface_info_entry_t *cur, uint8_t *dst_address, uint8_t *data_ptr, uint16_t data_len, mle_tlv_info_t *request_tlv, uint8_t mode); static int thread_attach_parent_response_build(protocol_interface_info_entry_t *cur, uint8_t *dstAddress, uint8_t *challenge, uint16_t chalLen, uint8_t linkMargin, uint8_t scanMask, uint8_t mode); -static int mle_attach_child_id_response_build(protocol_interface_info_entry_t *cur, uint8_t *dstAddress,thread_pending_child_id_req_t *child_req,mle_neigh_table_entry_t *neigh_info); +static int mle_attach_child_id_response_build(protocol_interface_info_entry_t *cur, uint8_t *dstAddress,thread_pending_child_id_req_t *child_req, struct mac_neighbor_table_entry *neigh_info); static int8_t thread_router_bootstrap_synch_request_send(protocol_interface_info_entry_t *cur); -static bool thread_child_id_request(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *entry_temp); - -static bool thread_rfd_device(uint8_t mode) -{ - if ((mode & MLE_DEV_MASK) != MLE_RFD_DEV) { - return false; - } - return true; -} +static bool thread_child_id_request(protocol_interface_info_entry_t *cur, struct mac_neighbor_table_entry *entry_temp); static bool thread_router_parent_address_check(protocol_interface_info_entry_t *cur, uint8_t *source_addr) { @@ -209,7 +202,7 @@ int thread_router_bootstrap_mle_advertise(protocol_interface_info_entry_t *cur) } -static void clone_multicast_to_unicast(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *mle_entry, buffer_t *buf) +static void clone_multicast_to_unicast(protocol_interface_info_entry_t *cur, mac_neighbor_table_entry_t *entry, buffer_t *buf) { link_configuration_s *linkConfiguration = thread_joiner_application_get_config(cur->id); if (!linkConfiguration) { @@ -224,7 +217,7 @@ static void clone_multicast_to_unicast(protocol_interface_info_entry_t *cur, mle new_buf->info = (buffer_info_t) (B_DIR_DOWN | B_TO_IPV6_TXRX | B_FROM_IPV6_FWD); uint8_t next_hop[16]; memcpy(next_hop, ADDR_LINK_LOCAL_PREFIX, 8); - memcpy(&next_hop[8], mle_entry->mac64, 8); + memcpy(&next_hop[8], entry->mac64, 8); next_hop[8] ^= 2; ipv6_buffer_route_to(new_buf, next_hop, cur); @@ -234,15 +227,11 @@ static void clone_multicast_to_unicast(protocol_interface_info_entry_t *cur, mle static void mle_multicast_push_to_sleep_child(protocol_interface_info_entry_t *cur, buffer_t *buf) { - mle_neigh_table_list_t *mle_neigh_list = mle_class_active_list_get(cur->id); - if (!mle_neigh_list) { - return; - } - ns_list_foreach(mle_neigh_table_entry_t, cur_entry, mle_neigh_list) { - if (cur_entry->threadNeighbor) { - if (!(cur_entry->mode & MLE_RX_ON_IDLE)) { - clone_multicast_to_unicast(cur, cur_entry, buf); - } + mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list; + + ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, mac_table_list) { + if (!cur_entry->rx_on_idle) { + clone_multicast_to_unicast(cur, cur_entry, buf); } } } @@ -260,9 +249,9 @@ static void thread_registered_mcast_forward_to_child(protocol_interface_info_ent tr_debug("Forwarding to registered multicast address: %s", trace_ipv6(addr->address)); ns_list_foreach(thread_mcast_child_t, child, &addr->children) { - mle_neigh_table_entry_t *mle_entry = mle_class_get_by_link_address(cur->id, child->mac64, ADDR_802_15_4_LONG); - if (mle_entry && mle_entry->threadNeighbor && !(mle_entry->mode & MLE_RX_ON_IDLE)) { - clone_multicast_to_unicast(cur, mle_entry, buffer); + mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), child->mac64, ADDR_802_15_4_LONG); + if (entry && !entry->rx_on_idle) { + clone_multicast_to_unicast(cur, entry, buffer); } } } @@ -304,13 +293,10 @@ static void thread_router_synch_receive_cb(int8_t interface_id, mle_message_t *m uint16_t version, shortAddress, address16; uint32_t llFrameCounter; mle_tlv_info_t routing; - mle_neigh_table_entry_t *entry_temp; + mac_neighbor_table_entry_t *entry_temp; tr_debug("Thread MLE message router sync"); //State machine What packet shuold accept in this case - protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); - if (!cur) { - return; - } + protocol_interface_info_entry_t *cur = mle_msg->interface_ptr; /* Check that message is from link-local scope */ if(!addr_is_ipv6_link_local(mle_msg->packet_src_address)) { @@ -353,42 +339,56 @@ static void thread_router_synch_receive_cb(int8_t interface_id, mle_message_t *m return; } //Allocate neighbor entry - - entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, true, &new_neigbour); + entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, true, &new_neigbour); if (!entry_temp) { return; } + if (security_headers->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) { + thread_management_key_synch_req(cur->id, common_read_32_bit(security_headers->Keysource)); + thread_key_guard_timer_reset(cur); + } else { + tr_error("Key ID Mode 2 not used; dropped."); + return; + } + + thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index, linkMargin, new_neigbour); + thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index); + //Free Response mle_service_msg_free(messageId); - entry_temp->threadNeighbor = true; - entry_temp->short_adr = shortAddress; + entry_temp->mac16 = shortAddress; + //when allocating neighbour entry, use MLE Frame counter if present to validate further advertisements from the neighbour - entry_temp->mle_frame_counter = mleFrameCounter; - if (entry_temp->timeout_rx) { - mle_entry_timeout_refresh(entry_temp); + mle_service_frame_counter_entry_add(cur->id, entry_temp->index, mleFrameCounter); + uint32_t timeout_tlv; + + mle_tlv_info_t mle_tlv_info; + + if (mle_tlv_option_discover(mle_msg->data_ptr, mle_msg->data_length, MLE_TYPE_TIMEOUT, &mle_tlv_info) > 0) { + timeout_tlv = common_read_32_bit(mle_tlv_info.dataPtr); } else { - mle_tlv_info_t mle_tlv_info; - uint32_t timeout_tlv; - if (mle_tlv_option_discover(mle_msg->data_ptr, mle_msg->data_length, MLE_TYPE_TIMEOUT, &mle_tlv_info) > 0) { - timeout_tlv = common_read_32_bit(mle_tlv_info.dataPtr); - mle_entry_timeout_update(entry_temp, timeout_tlv); + if (new_neigbour) { + timeout_tlv = THREAD_DEFAULT_LINK_LIFETIME; } else { - mle_entry_timeout_update(entry_temp, THREAD_DEFAULT_LINK_LIFETIME); + timeout_tlv = entry_temp->link_lifetime; } } + mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, timeout_tlv); + if (thread_is_router_addr(shortAddress)) { - entry_temp->handshakeReady = 1; + entry_temp->connected_device = 1; } - - entry_temp->mode |= MLE_THREAD_REQ_FULL_DATA_SET; + thread_neighbor_class_request_full_data_setup_set(&cur->thread_info->neighbor_class, entry_temp->index, true); if (mle_tlv_read_8_bit_tlv(MLE_TYPE_RSSI, mle_msg->data_ptr, mle_msg->data_length, &linkMarginfronNeigh)) { - thread_routing_update_link_margin(cur, entry_temp->short_adr, linkMargin, linkMarginfronNeigh); + thread_routing_update_link_margin(cur, entry_temp->mac16, linkMargin, linkMarginfronNeigh); } - mac_helper_devicetable_set(entry_temp, cur, llFrameCounter, security_headers->KeyIndex, new_neigbour); + mlme_device_descriptor_t device_desc; + mac_helper_device_description_write(cur, &device_desc, entry_temp->mac64, entry_temp->mac16,llFrameCounter, false); + mac_helper_devicetable_set(&device_desc, cur, entry_temp->index, security_headers->KeyIndex, new_neigbour); //Copy Leader Data *cur->thread_info->thread_leader_data = leaderData; @@ -949,17 +949,17 @@ static int thread_attach_parent_response_build(protocol_interface_info_entry_t * return 0; } -int thread_router_bootstrap_reset_child_info(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *child) +int thread_router_bootstrap_reset_child_info(protocol_interface_info_entry_t *cur, struct mac_neighbor_table_entry *child) { /* Cleanup occurs for /any/ link we lose to something that looks like a child address, * not just links that are /now/ our children. * Due to REED/partition transitions the address may not look like a current child address; * we could be holding a child entry for future repromotion to router with same ID. */ - if (thread_is_router_addr(child->short_adr) || child->short_adr >= 0xfffe) { + if (thread_is_router_addr(child->mac16) || child->mac16 >= 0xfffe) { return -1; } - tr_debug("Child free %x", child->short_adr); + tr_debug("Child free %x", child->mac16); thread_dynamic_storage_child_info_clear(cur->id, child); /* As we are losing a link to a child address, we can assume that if we have an IP neighbour cache @@ -967,12 +967,12 @@ int thread_router_bootstrap_reset_child_info(protocol_interface_info_entry_t *cu * finding a new parent, and hence a new 16-bit address. (Losing a link to a router address would not * invalidate our IP->16-bit mapping.) */ - protocol_6lowpan_release_short_link_address_from_neighcache(cur, child->short_adr); + protocol_6lowpan_release_short_link_address_from_neighcache(cur, child->mac16); // If Child's RLOC16 appears in the Network Data send the RLOC16 to the Leader - if (thread_network_data_services_registered(&cur->thread_info->networkDataStorage, child->short_adr)) { + if (thread_network_data_services_registered(&cur->thread_info->networkDataStorage, child->mac16)) { tr_debug("Remove references to Child's RLOC16 from the Network Data"); - thread_management_client_network_data_unregister(cur->id, child->short_adr); + thread_management_client_network_data_unregister(cur->id, child->mac16); } // Clear all (sleepy) child registrations to multicast groups @@ -991,13 +991,11 @@ void thread_router_bootstrap_child_information_clear(protocol_interface_info_ent } // Remove mle neighbour entries for children in previous partition - mle_neigh_table_list_t *entry_list = mle_class_active_list_get(cur->id); - if (!entry_list) { - return; - } - ns_list_foreach_safe(mle_neigh_table_entry_t, table_entry, entry_list) { - if (table_entry->short_adr < 0xfffe && !thread_is_router_addr(table_entry->short_adr)) { - mle_class_remove_entry(cur->id, table_entry); + mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list; + + ns_list_foreach_safe(mac_neighbor_table_entry_t, table_entry, mac_table_list) { + if (table_entry->mac16 < 0xfffe && !thread_is_router_addr(table_entry->mac16)) { + mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), table_entry); } } } @@ -1006,17 +1004,14 @@ static void thread_router_bootstrap_invalid_child_information_clear(protocol_int tr_debug("Thread Short address changed old: %x new: %x", cur->thread_info->routerShortAddress, router_rloc); - mle_neigh_table_list_t *entry_list = mle_class_active_list_get(cur->id); - if (!entry_list) { - return; - } + mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list; // scrub neighbours with child addresses that are not ours - ns_list_foreach_safe(mle_neigh_table_entry_t, table_entry, entry_list) { - if (table_entry->short_adr < 0xfffe && - !thread_is_router_addr(table_entry->short_adr) && - thread_router_addr_from_addr(table_entry->short_adr) != router_rloc) { - mle_class_remove_entry(cur->id, table_entry); + ns_list_foreach_safe(mac_neighbor_table_entry_t, table_entry, mac_table_list) { + if (table_entry->mac16 < 0xfffe && + !thread_is_router_addr(table_entry->mac16) && + thread_router_addr_from_addr(table_entry->mac16) != router_rloc) { + mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), table_entry); } } } @@ -1105,7 +1100,7 @@ void thread_router_bootstrap_router_id_request(protocol_interface_info_entry_t * } } -static int mle_attach_child_id_response_build(protocol_interface_info_entry_t *cur, uint8_t *dstAddress,thread_pending_child_id_req_t *child_req,mle_neigh_table_entry_t *neigh_info) +static int mle_attach_child_id_response_build(protocol_interface_info_entry_t *cur, uint8_t *dstAddress,thread_pending_child_id_req_t *child_req, struct mac_neighbor_table_entry *neigh_info) { uint16_t len = 12 + 4; //Leader data and short address uint8_t *ptr; @@ -1117,7 +1112,7 @@ static int mle_attach_child_id_response_build(protocol_interface_info_entry_t *c return -1; } - if (neigh_info->mode & MLE_THREAD_REQ_FULL_DATA_SET) { + if (thread_neighbor_class_request_full_data_setup(&cur->thread_info->neighbor_class, neigh_info->index)) { fullList = true; } @@ -1163,7 +1158,7 @@ static int mle_attach_child_id_response_build(protocol_interface_info_entry_t *c ptr = mle_general_write_source_address(ptr, cur); if (child_req->shortAddressReq) { - ptr = mle_tlv_write_short_address(ptr, neigh_info->short_adr); + ptr = mle_tlv_write_short_address(ptr, neigh_info->mac16); } if (child_req->routeReq) { @@ -1214,12 +1209,10 @@ uint16_t thread_router_bootstrap_child_count_get(protocol_interface_info_entry_t if (router_address >= 0xfffe) { return 0; } - mle_neigh_table_list_t *mle_table = mle_class_active_list_get(cur->id); - if (!mle_table) { - return -1; - } - ns_list_foreach(mle_neigh_table_entry_t, cur_entry, mle_table) { - if (thread_router_addr_from_addr(cur_entry->short_adr) == router_address) { + mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list; + + ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, mac_table_list) { + if (thread_router_addr_from_addr(cur_entry->mac16) == router_address) { child_count++; } } @@ -1228,22 +1221,19 @@ uint16_t thread_router_bootstrap_child_count_get(protocol_interface_info_entry_t static uint16_t thread_router_bootstrap_child_address_generate(protocol_interface_info_entry_t *cur) { - mle_neigh_table_list_t *mle_table = mle_class_active_list_get(cur->id); - if (!mle_table) { - return -1; - } + mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list; if (thread_router_bootstrap_child_count_get(cur) >= cur->thread_info->maxChildCount) { tr_info("Maximum count %d reached", cur->thread_info->maxChildCount); - return 0xffff; + return 0xfffe; } bool address_allocated = false; for (uint16_t i = 0; i < cur->thread_info->maxChildCount; i++) { address_allocated = false; cur->thread_info->lastAllocatedChildAddress = (cur->thread_info->lastAllocatedChildAddress % THREAD_MAX_CHILD_ID_COUNT) + 1; - ns_list_foreach(mle_neigh_table_entry_t, cur_entry, mle_table) { - if ( (cur_entry->short_adr & THREAD_CHILD_MASK) == cur->thread_info->lastAllocatedChildAddress) { + ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, mac_table_list) { + if ( (cur_entry->mac16 & THREAD_CHILD_MASK) == cur->thread_info->lastAllocatedChildAddress) { address_allocated = true; break; } @@ -1254,29 +1244,29 @@ static uint16_t thread_router_bootstrap_child_address_generate(protocol_interfac } if (address_allocated){ // all possible addresses already allocated - return 0xffff; + return 0xfffe; } return ((mac_helper_mac16_address_get(cur) & THREAD_ROUTER_MASK) | cur->thread_info->lastAllocatedChildAddress); } -static bool thread_child_id_request(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *entry_temp) +static bool thread_child_id_request(protocol_interface_info_entry_t *cur, struct mac_neighbor_table_entry *entry_temp) { //Remove All Short address links from router - if (entry_temp->short_adr != 0xffff) { - protocol_6lowpan_release_short_link_address_from_neighcache(cur, entry_temp->short_adr); + if (entry_temp->mac16 < 0xfffe) { + protocol_6lowpan_release_short_link_address_from_neighcache(cur, entry_temp->mac16); } //allocate child address if current is router, 0xffff or not our child - if (!thread_addr_is_child(mac_helper_mac16_address_get(cur), entry_temp->short_adr)) { - entry_temp->short_adr = thread_router_bootstrap_child_address_generate(cur); + if (!thread_addr_is_child(mac_helper_mac16_address_get(cur), entry_temp->mac16)) { + entry_temp->mac16 = thread_router_bootstrap_child_address_generate(cur); } - if (entry_temp->short_adr == 0xffff) { + if (entry_temp->mac16 >= 0xfffe) { return false; } // Store this child info to the NVM - thread_dynamic_storage_child_info_store(cur->id, entry_temp); + thread_dynamic_storage_child_info_store(cur, entry_temp); //} return true; } @@ -1311,7 +1301,7 @@ void thread_router_bootstrap_child_id_handler(protocol_interface_info_entry_t *c memcpy(&ll64[8], req->euid64 , 8); ll64[8] ^= 2; //Allocate entry - mle_neigh_table_entry_t *entry_temp = mle_class_get_entry_by_ll64(cur->id, req->linkMargin, ll64, true, &new_neigbour); + mac_neighbor_table_entry_t *entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), ll64, true, &new_neigbour); if (!entry_temp) { //Send link reject @@ -1319,44 +1309,48 @@ void thread_router_bootstrap_child_id_handler(protocol_interface_info_entry_t *c goto free_request; } + thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index, req->linkMargin, new_neigbour); + thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index); + // If mac frame couter is less than previous we need to leave the old one //Update or set neigh info - entry_temp->holdTime = 90; - - mle_entry_timeout_update(entry_temp, req->timeout); - entry_temp->mode = req->mode; - entry_temp->threadNeighbor = true; - entry_temp->handshakeReady = 1; - entry_temp->mle_frame_counter = req->mleFrameCounter; + mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, req->timeout); + mle_mode_parse_to_mac_entry(entry_temp, req->mode); + thread_neighbor_class_mode_parse_to_entry(&cur->thread_info->neighbor_class, entry_temp->index, req->mode); + entry_temp->connected_device = 1; + mle_service_frame_counter_entry_add(cur->id, entry_temp->index, req->mleFrameCounter); if (req->shortAddressReq) { if (!thread_child_id_request(cur, entry_temp)) { - mle_class_remove_entry(cur->id, entry_temp); + mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry_temp); thread_link_reject_send(cur, ll64); goto free_request; } } if (new_neigbour) { - mac_helper_devicetable_set(entry_temp, cur, req->frameCounter, req->keyId, new_neigbour); + mlme_device_descriptor_t device_desc; + mac_helper_device_description_write(cur, &device_desc, entry_temp->mac64, entry_temp->mac16,req->frameCounter, false); + mac_helper_devicetable_set(&device_desc, cur, entry_temp->index, req->keyId, new_neigbour); } else { // in get response handler this will update the short address from MLE table mlme_get_t get_req; get_req.attr = macDeviceTable; - get_req.attr_index = entry_temp->attribute_index; + get_req.attr_index = entry_temp->index; cur->mac_api->mlme_req(cur->mac_api, MLME_GET, &get_req); } //Register MLEID if RRFD device - if ((entry_temp->mode & MLE_DEV_MASK) == MLE_RFD_DEV) { + if (!entry_temp->ffd_device) { uint8_t tempIPv6Address[16]; memcpy(tempIPv6Address, thread_info(cur)->threadPrivatePrefixInfo.ulaPrefix, 8); memcpy(&tempIPv6Address[8], req->eiid, 8); - memcpy(&entry_temp->mlEid, req->eiid, 8); + + thread_neighbor_class_add_mleid(&cur->thread_info->neighbor_class, entry_temp->index, req->eiid); tr_debug("Register %s", trace_ipv6(tempIPv6Address)); //Register GP --> 16 - thread_nd_address_registration(cur, tempIPv6Address, entry_temp->short_adr, cur->mac_parameters->pan_id, entry_temp->mac64); + thread_nd_address_registration(cur, tempIPv6Address, entry_temp->mac16, cur->mac_parameters->pan_id, entry_temp->mac64, NULL); } mle_attach_child_id_response_build(cur,ll64,req, entry_temp); @@ -1371,6 +1365,7 @@ static void thread_address_registration_tlv_parse(uint8_t *ptr, uint16_t data_le lowpan_context_t *ctx; uint8_t tempIPv6Address[16]; uint8_t ctxId; + bool new_neighbour_created; while (data_length) { //Read @@ -1383,8 +1378,8 @@ static void thread_address_registration_tlv_parse(uint8_t *ptr, uint16_t data_le memcpy(&tempIPv6Address[8], ptr, 8); tr_debug("Register %s", trace_ipv6(tempIPv6Address)); //Register GP --> 16 - thread_nd_address_registration(cur, tempIPv6Address, mac16, cur->mac_parameters->pan_id, mac64); - thread_extension_address_registration(cur, tempIPv6Address, mac64); + int retVal = thread_nd_address_registration(cur, tempIPv6Address, mac16, cur->mac_parameters->pan_id, mac64, &new_neighbour_created); + thread_extension_address_registration(cur, tempIPv6Address, mac64, new_neighbour_created, retVal == -2); } else { tr_debug("No Context %u", ctxId); } @@ -1403,8 +1398,8 @@ static void thread_address_registration_tlv_parse(uint8_t *ptr, uint16_t data_le } } else { //Register GP --> 16 - thread_nd_address_registration(cur, ptr, mac16, cur->mac_parameters->pan_id, mac64); - thread_extension_address_registration(cur, ptr, mac64); + int retVal = thread_nd_address_registration(cur, ptr, mac16, cur->mac_parameters->pan_id, mac64, &new_neighbour_created); + thread_extension_address_registration(cur, ptr, mac64, new_neighbour_created, retVal == -2); } ptr += 16; @@ -1415,14 +1410,12 @@ static void thread_address_registration_tlv_parse(uint8_t *ptr, uint16_t data_le void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *mle_msg, mle_security_header_t *security_headers) { + (void) interface_id; thread_leader_data_t leaderData; - mle_neigh_table_entry_t *entry_temp; + mac_neighbor_table_entry_t *entry_temp; bool rssiTLV; bool leaderDataReceived; - protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); - if (!cur) { - return; - } + protocol_interface_info_entry_t *cur = mle_msg->interface_ptr; //TLV REQUSTED if (mle_tlv_type_requested(MLE_TYPE_RSSI, mle_msg->data_ptr, mle_msg->data_length)) { @@ -1471,9 +1464,13 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t * } // parent request received - entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL); + entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL); if (entry_temp) { - entry_temp->mode = (MLE_FFD_DEV | MLE_RX_ON_IDLE | MLE_THREAD_REQ_FULL_DATA_SET); + //Set MAC modes + mle_mode_parse_to_mac_entry(entry_temp, (MLE_FFD_DEV | MLE_RX_ON_IDLE)); + thread_neighbor_class_mode_parse_to_entry(&cur->thread_info->neighbor_class, entry_temp->index, MLE_THREAD_REQ_FULL_DATA_SET); + thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index, linkMargin, false); + thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index); } if(!entry_temp) { if (!mle_tlv_read_8_bit_tlv(MLE_TYPE_MODE, mle_msg->data_ptr, mle_msg->data_length, &mode)) { @@ -1487,17 +1484,17 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t * return; } - if (mle_class_free_entry_count_get(cur->id) < 1) { + if (mle_class_free_entry_count_get(cur) < 1) { tr_info("Drop MLE message: no space left in the MLE table"); return; } - if ((mode & MLE_DEV_MASK) == MLE_RFD_DEV && mle_class_rfd_entry_count_get(cur->id) >= THREAD_MAX_MTD_CHILDREN) { + if ((mode & MLE_DEV_MASK) == MLE_RFD_DEV && mle_class_rfd_entry_count_get(cur) >= THREAD_MAX_MTD_CHILDREN) { tr_info("Drop MLE message: maximum MTD child count reached."); return; } - if (!(mode & MLE_RX_ON_IDLE) && mle_class_sleepy_entry_count_get(cur->id) >= THREAD_MAX_SED_CHILDREN) { + if (!(mode & MLE_RX_ON_IDLE) && mle_class_sleepy_entry_count_get(cur) >= THREAD_MAX_SED_CHILDREN) { tr_info("Drop MLE message: maximum SED child count reached."); return; } @@ -1571,10 +1568,14 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t * return; } - // If we are in REED mode and receive child IR request from our parent, call connection error. + // If we are in REED mode and receive child ID request from our parent, call connection error. if (thread_am_reed(cur)) { if (thread_router_parent_address_check(cur, mle_msg->packet_src_address)) { tr_debug("Child ID req from own parent -> connection error"); + entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL); + if (entry_temp) { + mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry_temp); + } thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL); return; } @@ -1714,7 +1715,7 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t * if (mle_tlv_read_16_bit_tlv(MLE_TYPE_SRC_ADDRESS, mle_msg->data_ptr, mle_msg->data_length, &shortAddress)) { //Correct TLV's lets response if (!thread_is_router_addr(shortAddress)) { - if (leaderDataReceived && thread_info(cur)->thread_leader_data->partitionId == leaderData.partitionId) { + if (leaderDataReceived && thread_partition_match(cur, &leaderData)) { //REED or end device send response thread_router_accept_to_endevice(cur, mle_msg, challengeTlv.dataPtr, challengeTlv.tlvLen); } else { @@ -1726,7 +1727,7 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t * return; } - entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL); + entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL); if (!mle_tlv_read_16_bit_tlv(MLE_TYPE_SRC_ADDRESS, mle_msg->data_ptr, mle_msg->data_length, &shortAddress)) { @@ -1738,9 +1739,11 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t * * */ - if (entry_temp && entry_temp->handshakeReady) { - mle_entry_timeout_refresh(entry_temp); - thread_router_synch_accept_request_build(cur, mle_msg, entry_temp->short_adr, challengeTlv.dataPtr, challengeTlv.tlvLen, requestTlv.dataPtr, requestTlv.tlvLen); + if (entry_temp && entry_temp->connected_device) { + mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, entry_temp->link_lifetime); + thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index,linkMargin, false); + thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index); + thread_router_synch_accept_request_build(cur, mle_msg, entry_temp->mac16, challengeTlv.dataPtr, challengeTlv.tlvLen, requestTlv.dataPtr, requestTlv.tlvLen); } } bool update_mac_mib = false; @@ -1759,7 +1762,7 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t * } //validate partition id - if (thread_info(cur)->thread_leader_data->partitionId != leaderData.partitionId) { + if (!thread_partition_match(cur, &leaderData)) { tr_debug("Drop link request from wrong partition"); return; } @@ -1767,26 +1770,28 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t * if (entry_temp) { /*remove from child list when becoming router*/ // Was this previously our child? If yes, update. - if ((entry_temp->short_adr & THREAD_CHILD_MASK) && thread_router_addr_from_addr(entry_temp->short_adr) == cur->thread_info->routerShortAddress) { + if ((entry_temp->mac16 & THREAD_CHILD_MASK) && thread_router_addr_from_addr(entry_temp->mac16) == cur->thread_info->routerShortAddress) { thread_dynamic_storage_child_info_clear(cur->id, entry_temp); - protocol_6lowpan_release_short_link_address_from_neighcache(cur, entry_temp->short_adr); + protocol_6lowpan_release_short_link_address_from_neighcache(cur, entry_temp->mac16); } update_mac_mib = true; - entry_temp->short_adr = shortAddress; // short address refreshed + entry_temp->mac16 = shortAddress; // short address refreshed - if (entry_temp->handshakeReady) { + if (entry_temp->connected_device) { if (mle_tlv_read_tlv(MLE_TYPE_ADDRESS_REGISTRATION, mle_msg->data_ptr, mle_msg->data_length, &addressRegisteredTlv)) { - if (thread_rfd_device(entry_temp->mode)) { - thread_address_registration_tlv_parse(addressRegisteredTlv.dataPtr, addressRegisteredTlv.tlvLen, cur, entry_temp->short_adr, entry_temp->mac64); + if (!entry_temp->ffd_device) { + thread_address_registration_tlv_parse(addressRegisteredTlv.dataPtr, addressRegisteredTlv.tlvLen, cur, entry_temp->mac16, entry_temp->mac64); } } - mle_entry_timeout_refresh(entry_temp); + mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, entry_temp->link_lifetime); + thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index,linkMargin, false); + thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index); if (!mle_neigh_entry_frame_counter_update(entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur, security_headers->KeyIndex) && update_mac_mib) { //GET mlme_get_t get_req; get_req.attr = macDeviceTable; - get_req.attr_index = entry_temp->attribute_index; + get_req.attr_index = entry_temp->index; cur->mac_api->mlme_req(cur->mac_api, MLME_GET, &get_req); } response_type = MLE_COMMAND_ACCEPT; @@ -1853,32 +1858,41 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t * createNew = thread_bootstrap_link_create_check(cur, shortAddress); //Send Response - entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, createNew, &new_entry); + + entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, createNew, &new_entry); if (entry_temp) { + thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index,linkMargin, new_entry); + thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index); if (security_headers->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) { thread_management_key_synch_req(cur->id, common_read_32_bit(security_headers->Keysource)); } - entry_temp->threadNeighbor = true; - entry_temp->short_adr = shortAddress; - mac_helper_devicetable_set(entry_temp, cur, llFrameCounter, security_headers->KeyIndex, new_entry); - if (entry_temp->timeout_rx) { - mle_entry_timeout_refresh(entry_temp); + entry_temp->mac16 = shortAddress; + mlme_device_descriptor_t device_desc; + mac_helper_device_description_write(cur, &device_desc, entry_temp->mac64, entry_temp->mac16,llFrameCounter, false); + mac_helper_devicetable_set(&device_desc, cur, entry_temp->index, security_headers->KeyIndex, new_entry); + + uint32_t link_lifetime; + if (new_entry) { + link_lifetime = THREAD_DEFAULT_LINK_LIFETIME; + } else { - mle_entry_timeout_update(entry_temp, THREAD_DEFAULT_LINK_LIFETIME); + link_lifetime = entry_temp->link_lifetime; } + mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, link_lifetime); + if (thread_is_router_addr(shortAddress)) { - entry_temp->handshakeReady = 1; + entry_temp->connected_device = 1; } - entry_temp->mode |= MLE_THREAD_REQ_FULL_DATA_SET; + thread_neighbor_class_request_full_data_setup_set(&cur->thread_info->neighbor_class, entry_temp->index, true); - thread_routing_update_link_margin(cur, entry_temp->short_adr, linkMargin, linkMarginfronNeigh); + thread_routing_update_link_margin(cur, entry_temp->mac16, linkMargin, linkMarginfronNeigh); //Read Source address and Challenge mac_data_poll_protocol_poll_mode_decrement(cur); - thread_router_accept_request_build(cur, mle_msg, entry_temp->short_adr, challengeTlv.dataPtr, challengeTlv.tlvLen, MLE_COMMAND_ACCEPT, rssiTLV, linkMargin); + thread_router_accept_request_build(cur, mle_msg, entry_temp->mac16, challengeTlv.dataPtr, challengeTlv.tlvLen, MLE_COMMAND_ACCEPT, rssiTLV, linkMargin); blacklist_update(mle_msg->packet_src_address, true); } else { @@ -1899,11 +1913,12 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t * mle_tlv_info_t addressRegisterTlv = {0}; mle_tlv_info_t challengeTlv = {0}; mle_tlv_info_t tlv_req = {0}; - entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL); + entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL); if (mle_tlv_read_8_bit_tlv(MLE_TYPE_STATUS, mle_msg->data_ptr, mle_msg->data_length, &status)) { if (1 == status && thread_check_is_this_my_parent(cur, entry_temp)) { - tr_debug("parent has removed REED"); + tr_debug("Parent has removed REED"); + mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry_temp); thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL); } return; @@ -1923,9 +1938,10 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t * } //Keep alive updated - entry_temp->ttl = entry_temp->timeout_rx; - entry_temp->last_contact_time = protocol_core_monotonic_time; - entry_temp->mode = mode; + thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index,linkMargin, false); + thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index); + mle_mode_parse_to_mac_entry(entry_temp, mode); + thread_neighbor_class_mode_parse_to_entry(&cur->thread_info->neighbor_class, entry_temp->index, mode); addressRegisterTlv.tlvType = MLE_TYPE_UNASSIGNED; mle_tlv_read_tlv(MLE_TYPE_ADDRESS_REGISTRATION, mle_msg->data_ptr, mle_msg->data_length, &addressRegisterTlv); @@ -1935,25 +1951,26 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t * mle_tlv_read_tlv(MLE_TYPE_TLV_REQUEST, mle_msg->data_ptr, mle_msg->data_length, &tlv_req); if (addressRegisterTlv.tlvType == MLE_TYPE_ADDRESS_REGISTRATION && - thread_rfd_device(entry_temp->mode)) { - + !entry_temp->ffd_device) { tr_debug("Register child address"); - thread_address_registration_tlv_parse(addressRegisterTlv.dataPtr, addressRegisterTlv.tlvLen, cur, entry_temp->short_adr, entry_temp->mac64); + thread_address_registration_tlv_parse(addressRegisterTlv.dataPtr, addressRegisterTlv.tlvLen, cur, entry_temp->mac16, entry_temp->mac64); } if (mle_tlv_read_32_bit_tlv(MLE_TYPE_TIMEOUT, mle_msg->data_ptr, mle_msg->data_length, &timeout)) { tr_debug("Setting child timeout, value=%"PRIu32, timeout); - entry_temp->holdTime = 90; - mle_entry_timeout_update(entry_temp, timeout); + mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, timeout); + } else { + mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, entry_temp->link_lifetime); } + if (!leaderDataReceived) { tr_debug("Child synch req"); } tr_debug("Keep-Alive -->Respond Child"); //Response - thread_child_update_response(cur, mle_msg->packet_src_address, mode, entry_temp->short_adr, timeout, &addressRegisterTlv, &tlv_req, &challengeTlv, active_timestamp, pending_timestamp); + thread_child_update_response(cur, mle_msg->packet_src_address, mode, entry_temp->mac16, timeout, &addressRegisterTlv, &tlv_req, &challengeTlv, active_timestamp, pending_timestamp); } break; @@ -1969,11 +1986,16 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t * case MLE_COMMAND_DATA_REQUEST: { mle_tlv_info_t requestTlv; tr_info("Recv Router Data Request"); - entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL); + + entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL); if (!entry_temp || !mle_tlv_read_tlv(MLE_TYPE_TLV_REQUEST, mle_msg->data_ptr, mle_msg->data_length, &requestTlv)) { return; } - mle_build_and_send_data_response_msg(cur, mle_msg->packet_src_address, mle_msg->data_ptr, mle_msg->data_length, &requestTlv, entry_temp->mode); + thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index,linkMargin, false); + thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index); + uint8_t mode = mle_mode_write_from_mac_entry(entry_temp); + mode |= thread_neighbor_class_mode_write_from_entry(&cur->thread_info->neighbor_class, entry_temp->index); + mle_build_and_send_data_response_msg(cur, mle_msg->packet_src_address, mle_msg->data_ptr, mle_msg->data_length, &requestTlv, mode); } break; default: @@ -2184,7 +2206,10 @@ void thread_router_bootstrap_child_id_reject(protocol_interface_info_entry_t *cu while (req) { tr_debug("Remove entry from list"); //Remove entry from list - mle_class_remove_neighbour(cur->id, req->euid64, ADDR_802_15_4_LONG); + mac_neighbor_table_entry_t *neighbor = mac_neighbor_table_address_discover(mac_neighbor_info(cur), req->euid64, ADDR_802_15_4_LONG); + if (neighbor) { + mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), neighbor); + } ns_dyn_mem_free(req); req = thread_child_id_request_entry_get_from_the_list(cur); @@ -2206,7 +2231,6 @@ void thread_router_bootstrap_active_router_attach(protocol_interface_info_entry_ cur->lowpan_info |= INTERFACE_NWK_ROUTER_DEVICE; thread_routing_activate(&cur->thread_info->routing); thread_router_synch_new_router(cur, ADDR_LINK_LOCAL_ALL_ROUTERS); - mle_class_mode_set(cur->id, MLE_CLASS_ROUTER); thread_bootstrap_ready(cur); thread_bootstrap_network_prefixes_process(cur); thread_nd_service_activate(cur->id); @@ -2226,7 +2250,7 @@ static int thread_validate_own_routeid_from_new_mask(const uint8_t *master_route return ret_val; } -int thread_router_bootstrap_route_tlv_push(protocol_interface_info_entry_t *cur, uint8_t *route_tlv, uint8_t route_len, uint8_t linkMargin, mle_neigh_table_entry_t *entry) +int thread_router_bootstrap_route_tlv_push(protocol_interface_info_entry_t *cur, uint8_t *route_tlv, uint8_t route_len, uint8_t linkMargin, struct mac_neighbor_table_entry *entry) { (void) route_len; @@ -2239,9 +2263,9 @@ int thread_router_bootstrap_route_tlv_push(protocol_interface_info_entry_t *cur, route_data = route_tlv; uint16_t mac16 = mac_helper_mac16_address_get(cur); - if (!thread_is_router_addr(entry->short_adr)) { + if (!thread_is_router_addr(entry->mac16)) { // Received route tlv from non router ignore - tr_info("drop route Processing from end device %x", entry->short_adr); + tr_info("drop route Processing from end device %x", entry->mac16); return 0; } @@ -2251,21 +2275,20 @@ int thread_router_bootstrap_route_tlv_push(protocol_interface_info_entry_t *cur, thread_routing_leader_connection_validate(cur->thread_info,routing->networkFragmentationTimer); routing->networkFragmentationTimer = 0; if (thread_validate_own_routeid_from_new_mask(router_id_mask, thread_router_id_from_addr(mac16)) != 0) { - tr_debug("RouterID not valid any More"); thread_bootstrap_connection_error(cur->id, CON_ERROR_NETWORK_KICK, NULL); return 0; } } } else if (!thread_info(cur)->thread_endnode_parent || - thread_info(cur)->thread_endnode_parent->shortAddress != entry->short_adr ) { + thread_info(cur)->thread_endnode_parent->shortAddress != entry->mac16 ) { return 0; } /* XXX Is short_src_adr ever reset? Is it undefined if info not in msg? */ /* Don't add routing link if MLE link is NOT bi-directional (i.e. we can only hear) */ - if (entry->handshakeReady) { - thread_routing_add_link(cur, entry->short_adr, linkMargin, route_id_seq, router_id_mask, route_data, false); + if (entry->connected_device) { + thread_routing_add_link(cur, entry->mac16, linkMargin, route_id_seq, router_id_mask, route_data, false); } return 0; @@ -2342,6 +2365,13 @@ static void thread_reed_advertisements_cb(void* arg) protocol_interface_info_entry_t *cur = arg; cur->thread_info->routerSelectParameters.reedAdvertisementTimeout = NULL; + + if (cur->nwk_bootstrap_state != ER_BOOTSRAP_DONE && cur->nwk_bootstrap_state != ER_MLE_ATTACH_READY) { + /* Own attach is ongoing, try to send advertisement after few seconds */ + cur->thread_info->routerSelectParameters.reedAdvertisementTimeout = eventOS_timeout_ms(thread_reed_advertisements_cb, 2 * 1000, cur); + return; + } + if (cur->thread_info->thread_attached_state == THREAD_STATE_CONNECTED && cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_ROUTER){ thread_reed_advertise(cur); @@ -2461,23 +2491,22 @@ void thread_router_bootstrap_timer(protocol_interface_info_entry_t *cur, uint32_ return; } -void thread_router_bootstrap_advertiment_analyze(protocol_interface_info_entry_t *cur, uint8_t *src_address, mle_neigh_table_entry_t *entry_temp, uint16_t shortAddress) +void thread_router_bootstrap_advertiment_analyze(protocol_interface_info_entry_t *cur, uint8_t *src_address, struct mac_neighbor_table_entry *entry_temp, uint16_t shortAddress) { if (entry_temp) { - entry_temp->threadNeighbor = true; - if (entry_temp->timeout_rx == 0 || thread_is_router_addr(shortAddress)) { - entry_temp->timeout_rx = THREAD_DEFAULT_LINK_LIFETIME / MLE_TIMER_TICKS_SECONDS; - entry_temp->timeout_rx++; + if (thread_is_router_addr(shortAddress)) { + entry_temp->link_lifetime = THREAD_DEFAULT_LINK_LIFETIME; + entry_temp->link_lifetime++; } if (thread_is_router_addr(shortAddress)) { //Update MAC Security PIB table by get & set Operation mlme_get_t get_req; get_req.attr = macDeviceTable; - get_req.attr_index = entry_temp->attribute_index; + get_req.attr_index = entry_temp->index; cur->mac_api->mlme_req(cur->mac_api, MLME_GET, &get_req); - entry_temp->ttl = entry_temp->timeout_rx; + entry_temp->lifetime = entry_temp->link_lifetime; } } else { // @@ -2661,19 +2690,18 @@ static int thread_router_bootstrap_network_data_propagation(protocol_interface_i static void thread_router_bootstrap_network_data_push_to_sleep_child(protocol_interface_info_entry_t *cur, bool stableDataUpdate) { uint8_t childLinkLocalAddress[16]; - mle_neigh_table_list_t *mle_table = mle_class_active_list_get(cur->id); + mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list; + memcpy(childLinkLocalAddress, ADDR_LINK_LOCAL_PREFIX, 8); - ns_list_foreach(mle_neigh_table_entry_t, cur_entry, mle_table) { - if (cur_entry->threadNeighbor) { - if (!(cur_entry->mode & MLE_RX_ON_IDLE)) { - memcpy(&childLinkLocalAddress[8], cur_entry->mac64, 8); - childLinkLocalAddress[8] ^= 2; - if (cur_entry->mode & MLE_THREAD_REQ_FULL_DATA_SET) { - thread_router_bootstrap_network_data_propagation(cur, childLinkLocalAddress, true); - } else { - if (stableDataUpdate) { - thread_router_bootstrap_network_data_propagation(cur, childLinkLocalAddress, false); - } + ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, mac_table_list) { + if (!cur_entry->rx_on_idle) { + memcpy(&childLinkLocalAddress[8], cur_entry->mac64, 8); + childLinkLocalAddress[8] ^= 2; + if (thread_neighbor_class_request_full_data_setup(&cur->thread_info->neighbor_class, cur_entry->index)) { + thread_router_bootstrap_network_data_propagation(cur, childLinkLocalAddress, true); + } else { + if (stableDataUpdate) { + thread_router_bootstrap_network_data_propagation(cur, childLinkLocalAddress, false); } } } diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_router_bootstrap.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_router_bootstrap.h index faf2f7db0d6b..0143ce1e30cc 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_router_bootstrap.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_router_bootstrap.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -43,13 +43,14 @@ struct protocol_interface_info_entry; struct thread_info_s; struct mle_security_header; struct buffer; +struct mac_neighbor_table_entry; void thread_router_bootstrap_reed_advertisements_start(protocol_interface_info_entry_t *cur); void thread_router_bootstrap_reed_merge_advertisement(protocol_interface_info_entry_t *cur); int thread_router_bootstrap_mle_advertise(struct protocol_interface_info_entry *cur); void thread_router_bootstrap_child_information_clear(protocol_interface_info_entry_t *cur); -int thread_router_bootstrap_reset_child_info(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *child); +int thread_router_bootstrap_reset_child_info(protocol_interface_info_entry_t *cur, struct mac_neighbor_table_entry *child); uint16_t thread_router_bootstrap_child_count_get(protocol_interface_info_entry_t *cur); void thread_router_bootstrap_child_id_handler(struct protocol_interface_info_entry *cur); void thread_router_bootstrap_child_id_reject(struct protocol_interface_info_entry *cur); @@ -61,11 +62,11 @@ int thread_router_bootstrap_link_synch_start(struct protocol_interface_info_entr bool thread_router_bootstrap_router_downgrade(struct protocol_interface_info_entry *cur); bool thread_router_bootstrap_reed_upgrade(struct protocol_interface_info_entry *cur); void thread_router_bootstrap_active_router_attach(struct protocol_interface_info_entry *cur); -int thread_router_bootstrap_route_tlv_push(protocol_interface_info_entry_t *cur, uint8_t *route_tlv, uint8_t route_len, uint8_t linkMargin, mle_neigh_table_entry_t *entry); +int thread_router_bootstrap_route_tlv_push(protocol_interface_info_entry_t *cur, uint8_t *route_tlv, uint8_t route_len, uint8_t linkMargin, struct mac_neighbor_table_entry *entry); void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *mle_msg, struct mle_security_header *security_headers); void thread_router_bootstrap_timer(protocol_interface_info_entry_t *cur, uint32_t ticks); -uint32_t thread_router_bootstrap_random_upgrade_jitter(); -void thread_router_bootstrap_advertiment_analyze(protocol_interface_info_entry_t *cur, uint8_t *src_address, mle_neigh_table_entry_t *entry_temp, uint16_t shortAddress); +uint32_t thread_router_bootstrap_random_upgrade_jitter(void); +void thread_router_bootstrap_advertiment_analyze(protocol_interface_info_entry_t *cur, uint8_t *src_address, struct mac_neighbor_table_entry *entry_temp, uint16_t shortAddress); void thread_router_bootstrap_multicast_forwarder_enable(protocol_interface_info_entry_t *cur, buffer_t *buf); void thread_router_bootstrap_anycast_address_register(protocol_interface_info_entry_t *cur); diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_routing.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_routing.c index 8fdf01da7b66..43042de94e35 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_routing.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_routing.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -52,6 +52,7 @@ #include "6LoWPAN/Thread/thread_routing.h" #include "6LoWPAN/Thread/thread_leader_service.h" #include "6LoWPAN/MAC/mac_helper.h" +#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h" #define TRACE_GROUP "trou" @@ -183,7 +184,7 @@ static inline thread_link_quality_e thread_quality_combine(thread_link_quality_e /* Return the quality (worse of incoming and outgoing quality) for a neighbour router */ static inline thread_link_quality_e thread_neighbour_router_quality(const thread_router_link_t *neighbour) { - return thread_quality_combine(neighbour->incoming_quality, neighbour->outgoing_quality); + return thread_quality_combine((thread_link_quality_e) neighbour->incoming_quality, (thread_link_quality_e) neighbour->outgoing_quality); } @@ -265,8 +266,8 @@ static int_fast8_t thread_route_fn( uint16_t dest_router_addr = thread_router_addr_from_addr(dest); if (dest_router_addr == mac16) { /* We're this device's parent - transmit direct to it */ - mle_neigh_table_entry_t *entry = mle_class_get_by_link_address(cur->id, dest_addr, ADDR_802_15_4_SHORT); - if (!entry || (entry->mode & MLE_DEV_MASK) == MLE_RFD_DEV) { + mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), dest_addr, ADDR_802_15_4_SHORT); + if (!entry || !entry->ffd_device) { /* To cover some of draft-kelsey-thread-network-data-00, we send the * packet up to our own IP layer in the case where it's addressed to * an unrecognised child. The special IP forwarding rules can then @@ -690,8 +691,8 @@ int_fast8_t thread_routing_add_link(protocol_interface_info_entry_t *cur, if (our_quality_to_other_neighbour < QUALITY_10dB) { continue; } - thread_link_quality_e neighbours_incoming_quality_to_other_neighbour = (byte & ROUTE_DATA_IN_MASK) >> ROUTE_DATA_IN_SHIFT; - thread_link_quality_e neighbours_outgoing_quality_to_other_neighbour = (byte & ROUTE_DATA_OUT_MASK) >> ROUTE_DATA_OUT_SHIFT; + thread_link_quality_e neighbours_incoming_quality_to_other_neighbour = (thread_link_quality_e) ((byte & ROUTE_DATA_IN_MASK) >> ROUTE_DATA_IN_SHIFT); + thread_link_quality_e neighbours_outgoing_quality_to_other_neighbour = (thread_link_quality_e) ((byte & ROUTE_DATA_OUT_MASK) >> ROUTE_DATA_OUT_SHIFT); thread_link_quality_e neighbours_quality_to_other_neighbour = thread_quality_combine(neighbours_incoming_quality_to_other_neighbour, neighbours_outgoing_quality_to_other_neighbour); if (neighbours_quality_to_other_neighbour < our_quality_to_other_neighbour) { @@ -975,6 +976,21 @@ static void thread_trickle_accelerate(trickle_t *t, const trickle_params_t *para } } +void thread_routing_trickle_advance(thread_routing_info_t *routing, uint16_t ticks) +{ + trickle_t *t =&routing->mle_advert_timer; + + if (!trickle_running(t, &thread_mle_advert_trickle_params)) { + return; + } + + if ((t->t > t->now) && (t->t - t->now < ticks)) { + /* advance trickle elapsing time by number of ticks */ + t->t = t->t + ticks - (t->t - t->now); + tr_debug("trickle advanced to %d, now %d ", t->t, t->now); + } +} + // This functions speeds up next advertisement depending on the disconnect period to leader void thread_routing_leader_connection_validate(thread_info_t *thread, uint16_t disconnect_period) { diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_routing.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_routing.h index 9896e982c085..e895bb03e5e6 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_routing.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_routing.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -187,6 +187,7 @@ void thread_routing_free(thread_routing_info_t *routing); void thread_routing_activate(thread_routing_info_t *routing); void thread_routing_deactivate(thread_routing_info_t *routing); bool thread_routing_timer(struct thread_info_s *thread, uint8_t ticks); +void thread_routing_trickle_advance(thread_routing_info_t *routing, uint16_t ticks); void thread_routing_leader_connection_validate(struct thread_info_s *thread, uint16_t disconnect_period); void thread_routing_set_mesh_callbacks(protocol_interface_info_entry_t *cur); @@ -233,6 +234,7 @@ int_fast8_t thread_routing_get_route_data(protocol_interface_info_entry_t *cur, #define thread_routing_activate(routing) #define thread_routing_deactivate(routing) #define thread_routing_timer(thread, ticks) false +#define thread_routing_trickle_advance(routing, ticks) #define thread_routing_leader_connection_validate(thread, disconnect_period) #define thread_routing_set_mesh_callbacks(cur) #define thread_routing_cost_get_by_router_id(routing, routerId) (0) diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_test_api.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_test_api.c index c6504beee849..d2da48561e48 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_test_api.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/Thread/thread_test_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * * Redistribution and use in source and binary forms, with or without @@ -49,11 +49,13 @@ #include "6LoWPAN/Thread/thread_discovery.h" #include "6LoWPAN/Thread/thread_nvm_store.h" #include "6LoWPAN/Thread/thread_extension_bootstrap.h" +#include "6LoWPAN/Thread/thread_neighbor_class.h" #include "MLE/mle.h" #include "thread_meshcop_lib.h" #include "thread_diagcop_lib.h" #include "coap_service_api.h" #include "Service_Libs/mle_service/mle_service_api.h" +#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h" #include "6LoWPAN/MAC/mac_helper.h" #define TRACE_GROUP "tapi" @@ -452,7 +454,7 @@ int thread_test_key_rotation_update(int8_t interface_id, uint32_t thrKeyRotation if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) { if (cur->configure_flags & INTERFACE_BOOTSTRAP_DEFINED) { linkConfiguration->key_rotation = thrKeyRotation; - thread_calculate_key_guard_timer(cur, linkConfiguration, false); + thread_key_guard_timer_calculate(cur, linkConfiguration, false); ret_val = 0; } } @@ -593,7 +595,7 @@ int thread_test_security_material_set(int8_t interface_id, bool enableSecurity, mle_service_security_set_security_key(cur->id, key_material, key_index, true); //Gen also Next Key thread_security_next_key_generate(cur, linkConfiguration->master_key, thrKeySequenceCounter); - thread_calculate_key_guard_timer(cur, linkConfiguration, false); + thread_key_guard_timer_calculate(cur, linkConfiguration, false); } } else { ret_val = 0; @@ -625,7 +627,8 @@ int thread_test_version_set(int8_t interface_id, uint8_t version) thread_version = version; cur = protocol_stack_interface_info_get_by_id(interface_id); if (!cur) { - return -1; + /*We already stored the new Thread version above, so even if cur is NULL the version is updated.*/ + return 0; } cur->thread_info->version = version; return 0; @@ -1114,22 +1117,22 @@ int8_t thread_test_child_info_get(int8_t interface_id, uint8_t index, uint16_t * protocol_interface_info_entry_t *cur; uint8_t n= 0; cur = protocol_stack_interface_info_get_by_id(interface_id); - if (!cur || !cur->thread_info || cur->thread_info->thread_device_mode != THREAD_DEVICE_MODE_ROUTER) { + if (!cur || !cur->mac_parameters || !cur->thread_info || cur->thread_info->thread_device_mode != THREAD_DEVICE_MODE_ROUTER) { return -1; } uint16_t mac16 = mac_helper_mac16_address_get(cur); - mle_neigh_table_list_t *mle_table = mle_class_active_list_get(interface_id); - if (!mle_table) { + mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list; + if (!mac_table_list) { return -1; } - ns_list_foreach(mle_neigh_table_entry_t, cur_entry, mle_table) { - if (cur_entry->threadNeighbor && thread_router_addr_from_addr(cur_entry->short_adr) == thread_router_addr_from_addr(mac16)) { + ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, mac_table_list) { + if (thread_router_addr_from_addr(cur_entry->mac16) == thread_router_addr_from_addr(mac16)) { if (n == index) { - *short_addr = cur_entry->short_adr; + *short_addr = cur_entry->mac16; memcpy(mac64,cur_entry->mac64, 8); - *sleepy = (cur_entry->mode & MLE_RX_ON_IDLE) != MLE_RX_ON_IDLE; - *margin = cur_entry->link_margin; + *sleepy = cur_entry->rx_on_idle != true; + *margin = thread_neighbor_entry_linkmargin_get(&cur->thread_info->neighbor_class, cur_entry->index); return 0; } n++; @@ -1156,17 +1159,17 @@ int8_t thread_test_neighbour_info_get(int8_t interface_id, uint8_t index, uint16 return -1; } uint16_t mac16 = mac_helper_mac16_address_get(cur); - mle_neigh_table_list_t *mle_table = mle_class_active_list_get(interface_id); - if (!mle_table) { + mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list; + if (!mac_table_list) { return -1; } - ns_list_foreach(mle_neigh_table_entry_t, cur_entry, mle_table) { - if (cur_entry->threadNeighbor && thread_router_addr_from_addr(cur_entry->short_adr) != thread_router_addr_from_addr(mac16)) { + ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, mac_table_list) { + if (thread_router_addr_from_addr(cur_entry->mac16) != thread_router_addr_from_addr(mac16)) { if (n == index) { - *short_addr = cur_entry->short_adr; + *short_addr = cur_entry->mac16; memcpy(mac64,cur_entry->mac64, 8); - *margin = cur_entry->link_margin; + *margin = thread_neighbor_entry_linkmargin_get(&cur->thread_info->neighbor_class, cur_entry->index); return 0; } n++; diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/adaptation_interface.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/adaptation_interface.c index 230a21893c06..226ed6f9642d 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/adaptation_interface.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/adaptation_interface.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, Arm Limited and affiliates. + * Copyright (c) 2016-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -35,6 +35,7 @@ #include "NWK_INTERFACE/Include/protocol_timer.h" #include "Service_Libs/etx/etx.h" #include "6LoWPAN/MAC/mac_helper.h" +#include "6LoWPAN/MAC/mpx_api.h" #include "6LoWPAN/Mesh/mesh.h" #include "6LoWPAN/IPHC_Decode/iphc_decompress.h" #include "lowpan_adaptation_interface.h" @@ -42,9 +43,15 @@ #ifdef HAVE_RPL #include "RPL/rpl_data.h" #endif +#include "6LoWPAN/ws/ws_common.h" +#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h" +#include "6LoWPAN/Thread/thread_common.h" +#include "6LoWPAN/ws/ws_common.h" #define TRACE_GROUP "6lAd" +typedef void (adaptation_etx_update_cb)(protocol_interface_info_entry_t *cur, buffer_t *buf, const mcps_data_conf_t *confirm); + // #define EXTRA_DEBUG_EXTRA #ifdef EXTRA_DEBUG_EXTRA #define tr_debug_extra(...) tr_debug(__VA_ARGS__) @@ -88,6 +95,9 @@ typedef struct { uint16_t max_indirect_big_packets_total; uint16_t max_indirect_small_packets_per_child; bool fragmenter_active; /*!< Fragmenter state */ + adaptation_etx_update_cb *etx_update_cb; + mpx_api_t *mpx_api; + uint16_t mpx_user_id; ns_list_link_t link; /*!< List link entry */ } fragmenter_interface_t; @@ -101,8 +111,8 @@ static void lowpan_adaptation_tx_queue_write(fragmenter_interface_t *interface_p static buffer_t * lowpan_adaptation_tx_queue_read(fragmenter_interface_t *interface_ptr, protocol_interface_info_entry_t *cur); /* Data direction and message length validation */ -static bool lowpan_adaptation_indirect_data_request(mle_neigh_table_entry_t *mle_entry); -static bool lowpan_adaptation_request_longer_than_mtu(protocol_interface_info_entry_t *cur, buffer_t *buf); +static bool lowpan_adaptation_indirect_data_request(mac_neighbor_table_entry_t *mle_entry); +static bool lowpan_adaptation_request_longer_than_mtu(protocol_interface_info_entry_t *cur, buffer_t *buf, fragmenter_interface_t *interface_ptr); /* Common data tx request process functions */ static void lowpan_active_buffer_state_reset(fragmenter_tx_entry_t *tx_buffer); @@ -110,7 +120,7 @@ static uint8_t lowpan_data_request_unique_handle_get(fragmenter_interface_t *int static fragmenter_tx_entry_t *lowpan_indirect_entry_allocate(uint16_t fragment_buffer_size); static fragmenter_tx_entry_t * lowpan_adaptation_tx_process_init(fragmenter_interface_t *interface_ptr, bool indirect, bool fragmented, bool is_unicast); static void lowpan_adaptation_data_request_primitiv_set(const buffer_t *buf, mcps_data_req_t *dataReq, protocol_interface_info_entry_t *cur); -static void lowpan_data_request_to_mac(protocol_interface_info_entry_t *cur, buffer_t *buf, fragmenter_tx_entry_t *tx_ptr); +static void lowpan_data_request_to_mac(protocol_interface_info_entry_t *cur, buffer_t *buf, fragmenter_tx_entry_t *tx_ptr, fragmenter_interface_t *interface_ptr); /* Tx confirmation local functions */ static bool lowpan_active_tx_handle_verify(uint8_t handle, buffer_t *buf); @@ -120,12 +130,49 @@ static uint8_t map_mlme_status_to_socket_event(uint8_t mlme_status); static bool lowpan_adaptation_tx_process_ready(fragmenter_tx_entry_t *tx_ptr); /* Fragmentation local functions */ -static int8_t lowpan_message_fragmentation_init(buffer_t *buf, fragmenter_tx_entry_t *frag_entry, protocol_interface_info_entry_t *cur); +static int8_t lowpan_message_fragmentation_init(buffer_t *buf, fragmenter_tx_entry_t *frag_entry, protocol_interface_info_entry_t *cur, fragmenter_interface_t *interface_ptr); static bool lowpan_message_fragmentation_message_write(const fragmenter_tx_entry_t *frag_entry, mcps_data_req_t *dataReq); static void lowpan_adaptation_indirect_queue_free_message(struct protocol_interface_info_entry *cur, fragmenter_interface_t *interface_ptr, fragmenter_tx_entry_t *tx_ptr); static fragmenter_tx_entry_t* lowpan_adaptation_indirect_mac_data_request_active(fragmenter_interface_t *interface_ptr, fragmenter_tx_entry_t *tx_ptr); +static void lowpan_adaptation_etx_update_cb(protocol_interface_info_entry_t *cur, buffer_t *buf, const mcps_data_conf_t *confirm) +{ + switch (confirm->status) { + case MLME_TX_NO_ACK: + case MLME_NO_DATA: + case MLME_SUCCESS: + if (buf->link_specific.ieee802_15_4.requestAck) { + if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) { + bool success = false; + if (confirm->status == MLME_SUCCESS) { + success = true; + } + // Gets table entry + mac_neighbor_table_entry_t *neigh_table_ptr = mac_neighbor_table_address_discover(mac_neighbor_info(cur), buf->dst_sa.address + PAN_ID_LEN, buf->dst_sa.addr_type); + if (neigh_table_ptr) { + etx_transm_attempts_update(cur->id, 1 + confirm->tx_retries , success, neigh_table_ptr->index); + // Updates ETX statistics + etx_storage_t * etx_entry = etx_storage_entry_get(cur->id, neigh_table_ptr->index); + if (etx_entry) { + if (neigh_table_ptr->link_role == PRIORITY_PARENT_NEIGHBOUR) { + protocol_stats_update(STATS_ETX_1ST_PARENT, etx_entry->etx >> 4); + } else if (neigh_table_ptr->link_role == SECONDARY_PARENT_NEIGHBOUR) { + protocol_stats_update(STATS_ETX_2ND_PARENT, etx_entry->etx >> 4); + } + } + } + } + } + break; + default: + + break; + + } +} + + //Discover static fragmenter_interface_t *lowpan_adaptation_interface_discover(int8_t interfaceId) { @@ -139,6 +186,18 @@ static fragmenter_interface_t *lowpan_adaptation_interface_discover(int8_t inter return NULL; } +static struct protocol_interface_info_entry *lowpan_adaptation_network_interface_discover(const mpx_api_t* api) +{ + + ns_list_foreach(fragmenter_interface_t, interface_ptr, &fragmenter_interface_list) { + if (api == interface_ptr->mpx_api) { + return protocol_stack_interface_info_get_by_id(interface_ptr->interface_id); + } + } + + return NULL; +} + static void lowpan_adaptation_tx_queue_write(fragmenter_interface_t *interface_ptr , buffer_t *buf) { @@ -164,7 +223,7 @@ static buffer_t * lowpan_adaptation_tx_queue_read(fragmenter_interface_t *interf * Data confirm has freed the corresponding "active buffer" and this function will look for new buffer to be set as active buffer. */ ns_list_foreach_safe(buffer_t, buf, &interface_ptr->directTxQueue) { - bool fragmented_needed = lowpan_adaptation_request_longer_than_mtu(cur, buf); + bool fragmented_needed = lowpan_adaptation_request_longer_than_mtu(cur, buf, interface_ptr); //Check that we not trig second active fragmentation process if (fragmented_needed && interface_ptr->fragmenter_active) { tr_debug("Do not trig Second active fragmentation"); @@ -179,9 +238,13 @@ static buffer_t * lowpan_adaptation_tx_queue_read(fragmenter_interface_t *interf //fragmentation needed -static bool lowpan_adaptation_request_longer_than_mtu(protocol_interface_info_entry_t *cur, buffer_t *buf) +static bool lowpan_adaptation_request_longer_than_mtu(protocol_interface_info_entry_t *cur, buffer_t *buf, fragmenter_interface_t *interface_ptr) { - uint_fast8_t overhead = mac_helper_frame_overhead(cur, buf); + uint_fast16_t overhead = mac_helper_frame_overhead(cur, buf); + + if (interface_ptr->mpx_api) { + overhead += interface_ptr->mpx_api->mpx_headroom_size_get(interface_ptr->mpx_api, interface_ptr->mpx_user_id); + } if (buffer_data_length(buf) > (int16_t)mac_helper_max_payload_size(cur, overhead)) { @@ -191,9 +254,9 @@ static bool lowpan_adaptation_request_longer_than_mtu(protocol_interface_info_en } } -static bool lowpan_adaptation_indirect_data_request(mle_neigh_table_entry_t *mle_entry) +static bool lowpan_adaptation_indirect_data_request(mac_neighbor_table_entry_t *entry_ptr) { - if (mle_entry && !(mle_entry->mode & MLE_RX_ON_IDLE)) { + if (entry_ptr && !(entry_ptr->rx_on_idle)) { return true; } return false; @@ -302,6 +365,14 @@ int8_t lowpan_adaptation_interface_init(int8_t interface_id, uint16_t mac_mtu_si return 0; } +void lowpan_adaptation_interface_etx_update_enable(int8_t interface_id) +{ + fragmenter_interface_t *interface_ptr = lowpan_adaptation_interface_discover(interface_id); + if (interface_ptr) { + interface_ptr->etx_update_cb = lowpan_adaptation_etx_update_cb; + } +} + int8_t lowpan_adaptation_interface_free(int8_t interface_id) { //Discover @@ -350,6 +421,44 @@ int8_t lowpan_adaptation_interface_reset(int8_t interface_id) return 0; } +static void lowpan_adaptation_mpx_data_confirm(const mpx_api_t* api, const struct mcps_data_conf_s *data) +{ + protocol_interface_info_entry_t * interface = lowpan_adaptation_network_interface_discover(api); + + lowpan_adaptation_interface_tx_confirm(interface, data); +} + +static void lowpan_adaptation_mpx_data_indication(const mpx_api_t* api, const struct mcps_data_ind_s *data) +{ + protocol_interface_info_entry_t * interface = lowpan_adaptation_network_interface_discover(api); + lowpan_adaptation_interface_data_ind(interface, data); +} + + + + +int8_t lowpan_adaptation_interface_mpx_register(int8_t interface_id, struct mpx_api_s *mpx_api, uint16_t mpx_user_id) +{ + //Discover + fragmenter_interface_t *interface_ptr = lowpan_adaptation_interface_discover(interface_id); + if (!interface_ptr) { + return -1; + } + if (!mpx_api && interface_ptr->mpx_api) { + //Disable Data Callbacks from MPX Class + interface_ptr->mpx_api->mpx_user_registration(interface_ptr->mpx_api, NULL, NULL, interface_ptr->mpx_user_id); + } + + interface_ptr->mpx_api = mpx_api; + interface_ptr->mpx_user_id = mpx_user_id; + + if (interface_ptr->mpx_api) { + //Register MPX callbacks: confirmation and indication + interface_ptr->mpx_api->mpx_user_registration(interface_ptr->mpx_api, lowpan_adaptation_mpx_data_confirm, lowpan_adaptation_mpx_data_indication, interface_ptr->mpx_user_id); + } + return 0; +} + static fragmenter_tx_entry_t *lowpan_indirect_entry_allocate(uint16_t fragment_buffer_size) { @@ -377,7 +486,7 @@ static fragmenter_tx_entry_t *lowpan_indirect_entry_allocate(uint16_t fragment_b return indirec_entry; } -static int8_t lowpan_message_fragmentation_init(buffer_t *buf, fragmenter_tx_entry_t *frag_entry, protocol_interface_info_entry_t *cur) +static int8_t lowpan_message_fragmentation_init(buffer_t *buf, fragmenter_tx_entry_t *frag_entry, protocol_interface_info_entry_t *cur, fragmenter_interface_t *interface_ptr) { uint8_t *ptr; uint16_t uncompressed_size; @@ -405,7 +514,11 @@ static int8_t lowpan_message_fragmentation_init(buffer_t *buf, fragmenter_tx_ent frag_entry->orig_size = frag_entry->size; frag_entry->size += (uncompressed_size - frag_entry->pattern); - uint_fast8_t overhead = mac_helper_frame_overhead(cur, buf); + uint_fast16_t overhead = mac_helper_frame_overhead(cur, buf); + if (interface_ptr->mpx_api) { + overhead += interface_ptr->mpx_api->mpx_headroom_size_get(interface_ptr->mpx_api, interface_ptr->mpx_user_id); + } + frag_entry->frag_max = mac_helper_max_payload_size(cur, overhead); @@ -498,24 +611,25 @@ static fragmenter_tx_entry_t * lowpan_adaptation_tx_process_init(fragmenter_inte buffer_t * lowpan_adaptation_data_process_tx_preprocess(protocol_interface_info_entry_t *cur, buffer_t *buf) { + mac_neighbor_table_entry_t *neigh_entry_ptr = NULL; + //Validate is link known and set indirect, datareq and security key id mode if (buf->dst_sa.addr_type == ADDR_NONE) { goto tx_error_handler; } - mle_neigh_table_entry_t *mle_entry = NULL; /* If MLE is enabled, we will talk if we have an MLE association */ if (buf->dst_sa.addr_type == ADDR_802_15_4_LONG ) { - mle_entry = mle_class_get_by_link_address(cur->id, buf->dst_sa.address + 2, buf->dst_sa.addr_type); + neigh_entry_ptr = mac_neighbor_table_address_discover(mac_neighbor_info(cur), buf->dst_sa.address + 2, buf->dst_sa.addr_type); } else if(buf->dst_sa.addr_type == ADDR_802_15_4_SHORT && (common_read_16_bit(buf->dst_sa.address + 2)) != 0xffff) { - mle_entry = mle_class_get_by_link_address(cur->id, buf->dst_sa.address + 2, buf->dst_sa.addr_type); + neigh_entry_ptr = mac_neighbor_table_address_discover(mac_neighbor_info(cur), buf->dst_sa.address + 2, buf->dst_sa.addr_type); } //Validate neighbour - if (!buf->options.ll_security_bypass_tx && mle_entry) { + if (!buf->options.ll_security_bypass_tx && neigh_entry_ptr) { - if (mle_entry->handshakeReady || mle_entry->thread_commission) { + if (neigh_entry_ptr->connected_device || neigh_entry_ptr->trusted_device) { } else { //tr_warn("Drop TX to unassociated %s", trace_sockaddr(&buf->dst_sa, true)); @@ -534,14 +648,14 @@ buffer_t * lowpan_adaptation_data_process_tx_preprocess(protocol_interface_info_ buf->link_specific.ieee802_15_4.requestAck = false; } else { buf->link_specific.ieee802_15_4.requestAck = true; - buf->link_specific.ieee802_15_4.indirectTxProcess = lowpan_adaptation_indirect_data_request(mle_entry); + buf->link_specific.ieee802_15_4.indirectTxProcess = lowpan_adaptation_indirect_data_request(neigh_entry_ptr); } if (buf->link_specific.ieee802_15_4.key_id_mode != B_SECURITY_KEY_ID_2) { if (!buf->link_specific.ieee802_15_4.requestAck ) { buf->link_specific.ieee802_15_4.key_id_mode = B_SECURITY_KEY_ID_MODE_DEFAULT; - } else if (mle_entry && !mle_entry->thread_commission) { + } else if (ws_info(cur) || (neigh_entry_ptr && !neigh_entry_ptr->trusted_device)) { buf->link_specific.ieee802_15_4.key_id_mode = B_SECURITY_KEY_ID_MODE_DEFAULT; } else { buf->link_specific.ieee802_15_4.key_id_mode = B_SECURITY_KEY_ID_IMPLICIT; @@ -551,6 +665,11 @@ buffer_t * lowpan_adaptation_data_process_tx_preprocess(protocol_interface_info_ return buf; tx_error_handler: + if (neigh_entry_ptr && neigh_entry_ptr->nud_active) { + mac_neighbor_info(cur)->active_nud_process--; + neigh_entry_ptr->nud_active = false; + + } socket_tx_buffer_event_and_free(buf, SOCKET_TX_FAIL); return NULL; @@ -616,7 +735,7 @@ static bool lowpan_adaptation_indirect_cache_sanity_check(protocol_interface_inf // entry is in cache and is not sent to mac => trigger this tr_debug_extra("sanity check, push seq %d to addr %s", fragmenter_tx_entry->buf->seq, trace_ipv6(fragmenter_tx_entry->buf->dst_sa.address)); fragmenter_tx_entry->indirect_data_cached = false; - lowpan_data_request_to_mac(cur, fragmenter_tx_entry->buf, fragmenter_tx_entry); + lowpan_data_request_to_mac(cur, fragmenter_tx_entry->buf, fragmenter_tx_entry, interface_ptr); return true; } } @@ -638,7 +757,7 @@ static bool lowpan_adaptation_indirect_cache_trigger(protocol_interface_info_ent if (addr_ipv6_equal(tx_ptr->buf->dst_sa.address, fragmenter_tx_entry->buf->dst_sa.address)) { tr_debug_extra("pushing seq %d to addr %s", fragmenter_tx_entry->buf->seq, trace_ipv6(fragmenter_tx_entry->buf->dst_sa.address)); fragmenter_tx_entry->indirect_data_cached = false; - lowpan_data_request_to_mac(cur, fragmenter_tx_entry->buf, fragmenter_tx_entry); + lowpan_data_request_to_mac(cur, fragmenter_tx_entry->buf, fragmenter_tx_entry, interface_ptr); return true; } } @@ -674,7 +793,7 @@ static fragmenter_tx_entry_t* lowpan_adaptation_indirect_first_cached_request_ge return NULL; } -static void lowpan_adaptation_make_room_for_small_packet(protocol_interface_info_entry_t *cur, fragmenter_interface_t *interface_ptr, mle_neigh_table_entry_t *neighbour_to_count) +static void lowpan_adaptation_make_room_for_small_packet(protocol_interface_info_entry_t *cur, fragmenter_interface_t *interface_ptr, mac_neighbor_table_entry_t *neighbour_to_count) { if (interface_ptr->max_indirect_small_packets_per_child == 0) { return; @@ -683,7 +802,7 @@ static void lowpan_adaptation_make_room_for_small_packet(protocol_interface_info uint_fast16_t count = 0; ns_list_foreach_reverse_safe(fragmenter_tx_entry_t, tx_entry, &interface_ptr->indirect_tx_queue) { - mle_neigh_table_entry_t *tx_neighbour = mle_class_get_by_link_address(cur->id, tx_entry->buf->dst_sa.address + 2, tx_entry->buf->dst_sa.addr_type); + mac_neighbor_table_entry_t *tx_neighbour = mac_neighbor_table_address_discover(mac_neighbor_info(cur), tx_entry->buf->dst_sa.address + 2, tx_entry->buf->dst_sa.addr_type); if (tx_neighbour == neighbour_to_count && buffer_data_length(tx_entry->buf) <= interface_ptr->indirect_big_packet_threshold) { if (++count >= interface_ptr->max_indirect_small_packets_per_child) { lowpan_adaptation_indirect_queue_free_message(cur, interface_ptr, tx_entry); @@ -710,7 +829,7 @@ static void lowpan_adaptation_make_room_for_big_packet(struct protocol_interface } } -static void lowpan_data_request_to_mac(protocol_interface_info_entry_t *cur, buffer_t *buf, fragmenter_tx_entry_t *tx_ptr) +static void lowpan_data_request_to_mac(protocol_interface_info_entry_t *cur, buffer_t *buf, fragmenter_tx_entry_t *tx_ptr, fragmenter_interface_t *interface_ptr) { mcps_data_req_t dataReq; @@ -737,7 +856,11 @@ static void lowpan_data_request_to_mac(protocol_interface_info_entry_t *cur, buf } } - cur->mac_api->mcps_data_req(cur->mac_api, &dataReq); + if (interface_ptr->mpx_api) { + interface_ptr->mpx_api->mpx_data_request(interface_ptr->mpx_api, &dataReq, interface_ptr->mpx_user_id); + } else { + cur->mac_api->mcps_data_req(cur->mac_api, &dataReq); + } } int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buffer_t *buf) @@ -756,7 +879,7 @@ int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buff } //Check packet size - bool fragmented_needed = lowpan_adaptation_request_longer_than_mtu(cur, buf); + bool fragmented_needed = lowpan_adaptation_request_longer_than_mtu(cur, buf, interface_ptr); bool is_unicast = buf->link_specific.ieee802_15_4.requestAck; bool indirect = buf->link_specific.ieee802_15_4.indirectTxProcess; if (!indirect) { @@ -783,7 +906,7 @@ int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buff if (fragmented_needed) { //Fragmentation init - if (lowpan_message_fragmentation_init(buf, tx_ptr, cur) ) { + if (lowpan_message_fragmentation_init(buf, tx_ptr, cur, interface_ptr) ) { tr_error("Fragment init fail"); if (indirect) { ns_dyn_mem_free(tx_ptr->fragmenter_buf); @@ -801,9 +924,9 @@ int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buff if (indirect) { //Add to indirectQUue fragmenter_tx_entry_t *tx_ptr_cached; - mle_neigh_table_entry_t *mle_entry = mle_class_get_by_link_address(cur->id, buf->dst_sa.address + 2, buf->dst_sa.addr_type); - if (mle_entry) { - buf->link_specific.ieee802_15_4.indirectTTL = (uint32_t) mle_entry->timeout_rx * MLE_TIMER_TICKS_MS; + mac_neighbor_table_entry_t *neigh_entry_ptr = mac_neighbor_table_address_discover(mac_neighbor_info(cur), buf->dst_sa.address + PAN_ID_LEN, buf->dst_sa.addr_type); + if (neigh_entry_ptr) { + buf->link_specific.ieee802_15_4.indirectTTL = (uint32_t) neigh_entry_ptr->link_lifetime * 1000; } else { buf->link_specific.ieee802_15_4.indirectTTL = cur->mac_parameters->mac_in_direct_entry_timeout; } @@ -812,7 +935,7 @@ int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buff // Make room for new message if needed */ if (buffer_data_length(buf) <= interface_ptr->indirect_big_packet_threshold) { - lowpan_adaptation_make_room_for_small_packet(cur, interface_ptr, mle_entry); + lowpan_adaptation_make_room_for_small_packet(cur, interface_ptr, neigh_entry_ptr); } else { lowpan_adaptation_make_room_for_big_packet(cur, interface_ptr); } @@ -841,7 +964,7 @@ int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buff } } - lowpan_data_request_to_mac(cur, buf, tx_ptr); + lowpan_data_request_to_mac(cur, buf, tx_ptr, interface_ptr); return 0; @@ -952,28 +1075,15 @@ int8_t lowpan_adaptation_interface_tx_confirm(protocol_interface_info_entry_t *c { buf->link_specific.ieee802_15_4.indirectTTL -= 7000; //Push Back to MAC - lowpan_data_request_to_mac(cur, buf, tx_ptr); + lowpan_data_request_to_mac(cur, buf, tx_ptr, interface_ptr); return 0; } } - switch (confirm->status) { - case MLME_TX_NO_ACK: - case MLME_NO_DATA: - case MLME_SUCCESS: - if (buf->link_specific.ieee802_15_4.requestAck) { - bool success = false; - if (confirm->status == MLME_SUCCESS) { - success = true; - } - etx_transm_attempts_update(cur->id, 1 + confirm->tx_retries , success, buf->dst_sa.addr_type, buf->dst_sa.address); - } - break; - default: - - break; - + if (interface_ptr->etx_update_cb) { + interface_ptr->etx_update_cb(cur, buf, confirm); } + //Switch original channel back if (buf->link_specific.ieee802_15_4.rf_channel_switch) { mac_helper_mac_channel_set(cur, buf->link_specific.ieee802_15_4.selected_channel); @@ -983,7 +1093,7 @@ int8_t lowpan_adaptation_interface_tx_confirm(protocol_interface_info_entry_t *c switch (confirm->status) { case MLME_BUSY_CHAN: - lowpan_data_request_to_mac(cur, buf, tx_ptr); + lowpan_data_request_to_mac(cur, buf, tx_ptr, interface_ptr); break; case MLME_SUCCESS: @@ -1005,7 +1115,7 @@ int8_t lowpan_adaptation_interface_tx_confirm(protocol_interface_info_entry_t *c return 0; } } else { - lowpan_data_request_to_mac(cur, buf, tx_ptr); + lowpan_data_request_to_mac(cur, buf, tx_ptr, interface_ptr); } break; @@ -1049,6 +1159,73 @@ int8_t lowpan_adaptation_interface_tx_confirm(protocol_interface_info_entry_t *c } +static bool mac_data_is_broadcast_addr(const sockaddr_t *addr) +{ + return (addr->addr_type == ADDR_802_15_4_SHORT) && + (addr->address[2] == 0xFF && addr->address[3] == 0xFF); +} + +static bool mcps_data_indication_neighbor_validate(protocol_interface_info_entry_t *cur, const sockaddr_t *addr) +{ + if (thread_info(cur) || ws_info(cur) || (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE)) { + mac_neighbor_table_entry_t * neighbor = mac_neighbor_table_address_discover(mac_neighbor_info(cur), addr->address + 2, addr->addr_type); + if (neighbor && (neighbor->connected_device || neighbor->trusted_device)) { + return true; + } + + /* Otherwise, we don't know them */ + return false; + } else { + //6lowpan without MLE don't can't do validation + return true; + } + +} + +void lowpan_adaptation_interface_data_ind(protocol_interface_info_entry_t *cur, const mcps_data_ind_t *data_ind) +{ + buffer_t *buf = buffer_get(data_ind->msduLength); + if (!buf || !cur) { + return; + } + uint8_t *ptr; + buffer_data_add(buf, data_ind->msdu_ptr, data_ind->msduLength); + //tr_debug("MAC Paylod size %u %s",data_ind->msduLength, trace_array(data_ind->msdu_ptr, 8)); + buf->options.lqi = data_ind->mpduLinkQuality; + buf->options.dbm = data_ind->signal_dbm; + buf->src_sa.addr_type = (addrtype_t)data_ind->SrcAddrMode; + ptr = common_write_16_bit(data_ind->SrcPANId, buf->src_sa.address); + memcpy(ptr, data_ind->SrcAddr, 8); + buf->dst_sa.addr_type = (addrtype_t)data_ind->DstAddrMode; + ptr = common_write_16_bit(data_ind->DstPANId, buf->dst_sa.address); + memcpy(ptr, data_ind->DstAddr, 8); + //Set Link spesific stuff to seperately + buf->link_specific.ieee802_15_4.srcPanId = data_ind->SrcPANId; + buf->link_specific.ieee802_15_4.dstPanId = data_ind->DstPANId; + + if (mac_data_is_broadcast_addr(&buf->dst_sa)) { + buf->options.ll_broadcast_rx = true; + } + buf->interface = cur; + if (data_ind->Key.SecurityLevel) { + buf->link_specific.ieee802_15_4.fc_security = true; + + if (cur->mac_security_key_usage_update_cb) { + cur->mac_security_key_usage_update_cb(cur, &data_ind->Key); + } + } else { + buf->link_specific.ieee802_15_4.fc_security = false; + if (mac_helper_default_security_level_get(cur) || + !mcps_data_indication_neighbor_validate(cur, &buf->src_sa)) { + //SET By Pass + buf->options.ll_security_bypass_rx = true; + } + } + + buf->info = (buffer_info_t)(B_TO_IPV6_TXRX | B_FROM_MAC | B_DIR_UP); + protocol_push(buf); +} + static uint8_t map_mlme_status_to_socket_event(uint8_t mlme_status) { uint8_t socket_event; @@ -1104,22 +1281,38 @@ static bool lowpan_tx_buffer_address_compare(sockaddr_t *dst_sa, uint8_t *addres return true; } -static void lowpan_adaptation_purge_from_mac(struct protocol_interface_info_entry *cur, uint8_t msduhandle) +static void lowpan_adaptation_purge_from_mac(struct protocol_interface_info_entry *cur, fragmenter_interface_t *interface_ptr, uint8_t msduhandle) { mcps_purge_t purge_req; purge_req.msduHandle = msduhandle; - cur->mac_api->mcps_purge_req(cur->mac_api, &purge_req); + if (interface_ptr->mpx_api) { + interface_ptr->mpx_api->mpx_data_purge(interface_ptr->mpx_api, &purge_req, interface_ptr->mpx_user_id); + } else { + if (cur->mac_api->mcps_purge_req) { + cur->mac_api->mcps_purge_req(cur->mac_api, &purge_req); + } + } } static void lowpan_adaptation_indirect_queue_free_message(struct protocol_interface_info_entry *cur, fragmenter_interface_t *interface_ptr, fragmenter_tx_entry_t *tx_ptr) { tr_debug("Purge from indirect handle %u", tx_ptr->buf->seq); - if (cur->mac_api->mcps_purge_req) { - lowpan_adaptation_purge_from_mac(cur, tx_ptr->buf->seq); - } + lowpan_adaptation_purge_from_mac(cur, interface_ptr, tx_ptr->buf->seq); lowpan_adaptation_data_process_clean(interface_ptr, tx_ptr, SOCKET_TX_FAIL); } +void lowpan_adaptation_remove_free_indirect_table(protocol_interface_info_entry_t *cur_interface, mac_neighbor_table_entry_t *entry_ptr) +{ + //Free firts by defined short address + if (entry_ptr->mac16 < 0xfffe) { + uint8_t temp_address[2]; + common_write_16_bit(entry_ptr->mac16, temp_address); + lowpan_adaptation_indirect_free_messages_from_queues_by_address(cur_interface, temp_address, ADDR_802_15_4_SHORT); + } + lowpan_adaptation_indirect_free_messages_from_queues_by_address(cur_interface, entry_ptr->mac64, ADDR_802_15_4_LONG); +} + + int8_t lowpan_adaptation_indirect_free_messages_from_queues_by_address(struct protocol_interface_info_entry *cur, uint8_t *address_ptr, addrtype_t adr_type) { fragmenter_interface_t *interface_ptr = lowpan_adaptation_interface_discover(cur->id); diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/lowpan_adaptation_interface.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/lowpan_adaptation_interface.h index 896c4f614825..6f823b1fa078 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/lowpan_adaptation_interface.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/lowpan_adaptation_interface.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, Arm Limited and affiliates. + * Copyright (c) 2016-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,13 +21,21 @@ struct protocol_interface_info_entry; struct mcps_data_conf_s; +struct mcps_data_ind_s; struct buffer; +struct mpx_api_s; +struct mac_neighbor_table_entry; + int8_t lowpan_adaptation_interface_init(int8_t interface_id, uint16_t mac_mtu_size); +void lowpan_adaptation_interface_etx_update_enable(int8_t interface_id); + int8_t lowpan_adaptation_interface_free(int8_t interface_id); int8_t lowpan_adaptation_interface_reset(int8_t interface_id); +int8_t lowpan_adaptation_interface_mpx_register(int8_t interface_id, struct mpx_api_s *mpx_api, uint16_t mpx_user_id); + /** * \brief call this before normatl TX. This function prepare buffer link spesific metadata and verify packet destination */ @@ -37,10 +45,14 @@ int8_t lowpan_adaptation_interface_tx(struct protocol_interface_info_entry *cur, int8_t lowpan_adaptation_interface_tx_confirm(struct protocol_interface_info_entry *cur, const struct mcps_data_conf_s *confirm); +void lowpan_adaptation_interface_data_ind(struct protocol_interface_info_entry *cur, const struct mcps_data_ind_s *data_ind); + struct buffer *lowpan_adaptation_reassembly(struct protocol_interface_info_entry *cur, struct buffer *buf); bool lowpan_adaptation_tx_active(int8_t interface_id); +void lowpan_adaptation_remove_free_indirect_table(struct protocol_interface_info_entry *cur_interface, struct mac_neighbor_table_entry *entry_ptr); + int8_t lowpan_adaptation_indirect_free_messages_from_queues_by_address(struct protocol_interface_info_entry *cur, uint8_t *address_ptr, addrtype_t adr_type); int8_t lowpan_adaptation_indirect_queue_params_set(struct protocol_interface_info_entry *cur, uint16_t indirect_big_packet_threshold, uint16_t max_indirect_big_packets_total, uint16_t max_indirect_small_packets_per_child); diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_bootstrap.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_bootstrap.h new file mode 100644 index 000000000000..4cd3316e5a83 --- /dev/null +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_bootstrap.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2016-2018, Arm Limited and affiliates. + * 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 WS_BOOTSTRAP_H_ +#define WS_BOOTSTRAP_H_ + + +typedef enum { + WS_INIT_EVENT = 0, /**< tasklet initializion event*/ + WS_DISCOVERY_START, /**< discovery start*/ + WS_CONFIGURATION_START, /**< configuration learn start*/ + WS_AUTHENTICATION_START, /**< authentication start*/ + WS_OPERATION_START, /**< active operation start*/ + WS_ROUTING_READY, /**< RPL routing connected to BR*/ + WS_ADDRESS_ADDED /**< Address added to IF*/ +} ws_bootsrap_event_type_e; + +#ifdef HAVE_WS + +int ws_bootstrap_init(int8_t interface_id, net_6lowpan_mode_e bootstrap_mode); + +void ws_bootstrap_state_machine(protocol_interface_info_entry_t *cur); + +/*State machine transactions*/ +void ws_bootstrap_event_discovery_start(protocol_interface_info_entry_t *cur); + +void ws_bootstrap_event_configuration_start(protocol_interface_info_entry_t *cur); + +void ws_bootstrap_event_authentication_start(protocol_interface_info_entry_t *cur); + +void ws_bootstrap_event_operation_start(protocol_interface_info_entry_t *cur); + +void ws_bootstrap_event_routing_ready(protocol_interface_info_entry_t *cur); + +void ws_bootstrap_configuration_trickle_reset(protocol_interface_info_entry_t *cur); + +void ws_bootstrap_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds); + +void ws_bootstrap_trigle_timer(protocol_interface_info_entry_t *cur, uint16_t ticks); + +#else + +#define ws_bootstrap_init(interface_id, bootstrap_mode) (-1) +#define ws_bootstrap_state_machine(cur) + +#endif //HAVE_WS + +#endif /* WS_BOOTSTRAP_H_ */ diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_common.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_common.h new file mode 100644 index 000000000000..dc02f6938a85 --- /dev/null +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_common.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2016-2018, Arm Limited and affiliates. + * 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 WS_COMMON_H_ +#define WS_COMMON_H_ + + +#include "ns_types.h" +#include "fhss_api.h" +#include "fhss_config.h" +#include "net_fhss.h" +#include "6LoWPAN/ws/ws_common_defines.h" +#include "6LoWPAN/ws/ws_neighbor_class.h" + +struct ws_pan_information_s; +struct ws_neighbor_class_s; + +typedef struct parent_info_s { + uint16_t pan_id; /**< PAN ID */ + uint8_t addr[8]; /**< address */ + uint8_t link_quality; /**< LQI value measured during reception of the MPDU */ + int8_t signal_dbm; /**< This extension for normal IEEE 802.15.4 Data indication */ + ws_pan_information_t pan_information; + ws_utt_ie_t ws_utt; + ws_us_ie_t ws_us; + uint32_t timestamp; /**< Timestamp when packet was received */ +}parent_info_t; + +typedef struct ws_info_s { + char network_name[33]; // Network name max 32 octets + terminating 0. + uint16_t network_pan_id; + + trickle_t trickle_pan_config_solicit; + trickle_t trickle_pan_config; + trickle_t trickle_pan_advertisement_solicit; + trickle_t trickle_pan_advertisement; + uint8_t rpl_state; // state from rpl_event_t + uint8_t pas_requests; // Amount of PAN solicits sent + parent_info_t parent_info; + uint32_t pan_version_timer; /**< border router version udate timeout */ + uint32_t pan_version_timeout_timer; /**< routers will fallback to previous state after this */ + uint8_t gtkhash[32]; + bool configuration_learned:1; + + struct ws_pan_information_s pan_information; + ws_hopping_schedule_t hopping_schdule; + struct ws_neighbor_class_s neighbor_storage; + struct fhss_timer *fhss_timer_ptr; // Platform adaptation for FHSS timers. + struct fhss_api *fhss_api; +} ws_info_t; + +#ifdef HAVE_WS + +int8_t ws_common_regulatory_domain_config(protocol_interface_info_entry_t *cur); + +int8_t ws_common_allocate_and_init(protocol_interface_info_entry_t *cur); + +void ws_common_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds); + +void ws_common_fast_timer(protocol_interface_info_entry_t *cur, uint16_t ticks); + +void ws_common_neighbor_update(protocol_interface_info_entry_t *cur, const uint8_t *ll_address); + +#define ws_info(cur) ((cur)->ws_info) +#else +#define ws_info(cur) ((ws_info_t *) NULL) +#define ws_common_seconds_timer(cur, seconds) +#define ws_common_neighbor_update(cur, ll_address) ((void) 0) +#define ws_common_fast_timer(cur, ticks) ((void) 0) + + +#endif //HAVE_WS +#endif //WS_COMMON_H_ diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_common_defines.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_common_defines.h new file mode 100644 index 000000000000..4b4c067f70fc --- /dev/null +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_common_defines.h @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2016-2018, Arm Limited and affiliates. + * 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 WS_COMMON_DEFINES_H_ +#define WS_COMMON_DEFINES_H_ + +#define WH_IE_ELEMENT_HEADER_LENGTH 3 + +/* Header IE Sub elements */ +#define WH_IE_UTT_TYPE 1 /**< Unicast Timing and Frame type information */ +#define WH_IE_BT_TYPE 2 /**< Broadcast timing information */ +#define WH_IE_FC_TYPE 3 /**< Flow Control for Extended Direct Frame Exchange */ +#define WH_IE_RSL_TYPE 4 /**< Received Signal Level information */ +#define WH_IE_MHDS_TYPE 5 /**< MHDS information for mesh routing */ +#define WH_IE_VH_TYPE 6 /**< Vendor header information */ + +#define WS_WP_NESTED_IE 4 /**< WS nested Payload IE element'selement could include mltiple sub payload IE */ + +#define WS_WP_SUB_IE_ELEMENT_HEADER_LENGTH 2 + +/* Payload IE sub elements in side WS_WP_NESTED_IE */ +#define WP_PAYLOAD_IE_US_TYPE 1 /**< Unicast Schedule information */ +#define WP_PAYLOAD_IE_BS_TYPE 2 /**< Broadcast Schedule information */ +#define WP_PAYLOAD_IE_VP_TYPE 3 /**< Vendor Payload information */ +#define WP_PAYLOAD_IE_PAN_TYPE 4 /**< PAN Information */ +#define WP_PAYLOAD_IE_NETNAME_TYPE 5 /**< Network Name information */ +#define WP_PAYLOAD_IE_PAN_VER_TYPE 6 /**< Pan configuration version */ +#define WP_PAYLOAD_IE_GTKHASH_TYPE 7 /**< GTK Hash information */ + +/* WS frame types to WH_IE_UTT_TYPE */ +#define WS_FT_PAN_ADVERT 0 /**< PAN Advert */ +#define WS_FT_PAN_ADVERT_SOL 1 /**< PAN Advert Solicit */ +#define WS_FT_PAN_CONF 2 /**< PAN Config */ +#define WS_FT_PAN_CONF_SOL 3 /**< PAN Config Solicit */ +#define WS_FT_DATA 4 /**< data type inside MPX */ +#define WS_FT_ACK 5 /**< Enhanced ACK */ +#define WS_FT_EAPOL 6 /**< EAPOL message inside MPX */ + + +/** + * @brief ws_pan_information_t PAN information + */ +typedef struct ws_pan_information_s { + uint16_t pan_size; /**< Number devices connected to Border Router. */ + uint16_t routing_cost; /**< ETX to border Router. */ + uint16_t pan_version; /**< Pan configuration version will be updatd by Border router at PAN. */ + bool use_parent_bs:1; /**< 1 for force to follow parent broadcast schedule. 0 node may define own schedule. */ + bool rpl_routing_method:1; /**< 1 when RPL routing is selected and 0 when L2 routing. */ + unsigned version:3; /**< Pan version support. */ +} ws_pan_information_t; + +/** + * @brief ws_hopping_schedule_t Chanel hopping schedule information + */ +typedef struct ws_hopping_schedule_s { + uint8_t fhss_uc_dwell_interval; + uint8_t fhss_bc_dwell_interval; + uint8_t regulatory_domain; /**< PHY regulatory domain default to "KR" 0x09 */ + uint8_t operating_class; /**< PHY operating class default to 1 */ + uint8_t operating_mode; /**< PHY operating mode default to "1b" symbol rate 50, modulation index 1 */ + uint8_t channel_plan; /**< 0: use regulatory domain values 1: application defined plan */ + uint8_t channel_function; /**< 0: Fixed channel, 1:TR51CF, 2: Direct Hash, 3: Vendor defined */ + uint8_t channel_spacing; /**< derived from regulatory domain. 0:200k, 1:400k, 2:600k, 3:100k */ + uint8_t number_of_channels; /**< derived from regulatory domain */ + uint8_t clock_drift; + uint8_t timing_accurancy; + uint16_t fixed_channel; + uint16_t fhss_bsi; + uint32_t fhss_broadcast_interval; + uint32_t channel_mask[8]; + uint_fast24_t ch0_freq; // Default should be derived from regulatory domain +} ws_hopping_schedule_t; + +/** + * @brief ws_utt_ie_t WS UTT-IE + */ +typedef struct ws_utt_ie { + uint8_t message_type; + uint_fast24_t ufsi; +} ws_utt_ie_t; + +/** + * @brief ws_bt_ie_t WS BT-IE read + */ +typedef struct ws_bt_ie { + uint16_t broadcast_slot_number; + uint_fast24_t broadcast_interval_offset; +} ws_bt_ie_t; + + +/** + * @brief ws_channel_plan_zero_t WS channel plan 0 define domain and class + */ +typedef struct ws_channel_plan_zero { + uint8_t regulator_domain; + uint8_t operation_class; +} ws_channel_plan_zero_t; + +/** + * @brief ws_channel_plan_one_t WS channel plan 1 define ch0, spasing and channel count + */ +typedef struct ws_channel_plan_one { + uint_fast24_t ch0; + unsigned channel_spacing:4; + uint16_t number_of_channel; +} ws_channel_plan_one_t; + +/** + * @brief ws_channel_function_zero_t WS function 0 fixed channel + */ +typedef struct ws_channel_function_zero { + uint16_t fixed_channel; +} ws_channel_function_zero_t; + +/** + * @brief ws_channel_function_three_t WS function 3 vendor spesific channel hop + */ +typedef struct ws_channel_function_three { + uint8_t channel_hop_count; + uint8_t *channel_list; +} ws_channel_function_three_t; + +/** + * @brief ws_us_ie_t WS US-IE read + */ +typedef struct ws_us_ie { + uint8_t dwell_interval; + uint8_t clock_drift; + uint8_t timing_accurancy; + unsigned channel_plan:3; + unsigned channel_function:3; + unsigned excluded_channel_ctrl:2; + union { + ws_channel_plan_zero_t zero; + ws_channel_plan_one_t one; + } plan; + union { + ws_channel_function_zero_t zero; + ws_channel_function_three_t three; + } function; +} ws_us_ie_t; + +/** + * @brief ws_bs_ie_t WS BS-IE read + */ +typedef struct ws_bs_ie { + uint32_t broadcast_interval; + uint16_t broadcast_schedule_identifier; + uint8_t dwell_interval; + uint8_t clock_drift; + uint8_t timing_accurancy; + unsigned channel_plan:3; + unsigned channel_function:3; + unsigned excluded_channel_ctrl:2; + union { + ws_channel_plan_zero_t zero; + ws_channel_plan_one_t one; + } plan; + union { + ws_channel_function_zero_t zero; + ws_channel_function_three_t three; + } function; +} ws_bs_ie_t; + + +#define MPX_KEY_MANAGEMENT_ENC_USER_ID 0x0001 /**< MPX Key management user ID */ +#define MPX_LOWPAN_ENC_USER_ID 0xA0ED /**< MPX Lowpan User Id */ + +#define WS_FAN_VERSION_1_0 1 + +#define WS_NEIGHBOR_LINK_TIMEOUT 240 +#define WS_NEIGHBOR_NUD_TIMEOUT WS_NEIGHBOR_LINK_TIMEOUT / 2 + +/* + * Threshold (referenced to DEVICE_MIN_SENS) above which a neighbor node may be considered for inclusion into candidate parent set + */ +#define CAND_PARENT_THRESHOLD 10 +/* + * Hysteresis factor to be applied to CAND_PARENT_THRESHOLD when admitting or dropping nodes from the candidate parent set. + */ +#define CAND_PARENT_HYSTERISIS 3 + +/* + * value when send the first RPL DIS in 100ms ticks. Value is randomized between timeout/2 - timeout + */ +#define WS_RPL_DIS_INITIAL_TIMEOUT 600 +/* + * value when send subsequent RPL DIS in 100 ms tics. Value is randomized between timeout/2 - timeout + */ +#define WS_RPL_DIS_TIMEOUT 1800 + +#endif /* WS_COMMON_DEFINES_H_ */ diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_neighbor_class.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_neighbor_class.h new file mode 100644 index 000000000000..c05964f00b02 --- /dev/null +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_neighbor_class.h @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2016-2018, Arm Limited and affiliates. + * 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 WS_NEIGHBOR_CLASS_H_ +#define WS_NEIGHBOR_CLASS_H_ + +#include "fhss_ws_extension.h" +#include "6LoWPAN/ws/ws_common_defines.h" + +typedef struct ws_neighbor_class_entry { + fhss_ws_neighbor_timing_info_t fhss_data; + uint16_t rsl_in; /*!< RSL EWMA heard from neighbour*/ + uint16_t rsl_out; /*!< RSL EWMA heard by neighbour*/ + bool candidate_parent:1; +} ws_neighbor_class_entry_t; + +/** + * Neighbor hopping info data base + */ +typedef struct ws_neighbor_class_s { + ws_neighbor_class_entry_t *neigh_info_list; /*!< Allocated hopping info array*/ + uint8_t list_size; /*!< List size*/ +} ws_neighbor_class_t; + +/** + * ws_neighbor_class_alloc a function for allocate giving list size + * + * \param class_data pointer to structure which will be initialized by this function + * \param list_size define list size + * + * \return true Allocate Ok + * \return false Allocate Fail + * + */ +bool ws_neighbor_class_alloc(ws_neighbor_class_t *class_data, uint8_t list_size); + +/** + * ws_neighbor_class_dealloc a function for free allocated neighbor hopping info + * + * \param class_data pointer to structure which will be initialized by this function + * + */ +void ws_neighbor_class_dealloc(ws_neighbor_class_t *class_data); + +/** + * ws_neighbor_class_entry_t a function for search hopping info for giving neighbor attribut + * + * \param class_data pointer to structure which will be initialized by this function + * \param attribute_index define pointer to storage info + * + * \return NULL when Attribute is not correct + * \return Pointer to neighbor hopping info + * + */ +ws_neighbor_class_entry_t * ws_neighbor_class_entry_get(ws_neighbor_class_t *class_data, uint8_t attribute_index); + +/** + * ws_neighbor_class_entry_t a function for search hopping info for giving neighbor attribute index + * + * \param class_data pointer to structure which will be initialized by this function + * \param entry which attribute index is counted. + * + * \return Attribute index of entry + * + */ +uint8_t ws_neighbor_class_entry_index_get(ws_neighbor_class_t *class_data, ws_neighbor_class_entry_t *entry); + +/** + * ws_neighbor_class_entry_remove a function for clean information should be call when neighbor is removed + * + * \param class_data pointer to structure which will be initialized by this function + * \param attribute_index define pointer to storage info + * + */ +void ws_neighbor_class_entry_remove(ws_neighbor_class_t *class_data, uint8_t attribute_index); + +/** + * ws_neighbor_class_neighbor_unicast_time_info_update a function for update neighbor unicast time information + * + * \param ws_neighbor pointer to neighbor + * \param ws_utt Unicast time IE data + * \param timestamp timestamp for received data + * + */ +void ws_neighbor_class_neighbor_unicast_time_info_update(ws_neighbor_class_entry_t *ws_neighbor, ws_utt_ie_t *ws_utt, uint32_t timestamp); + +/** + * ws_neighbor_class_neighbor_unicast_schedule_set a function for update neighbor unicast shedule information + * + * \param ws_neighbor pointer to neighbor + * \param ws_us Unicast schedule IE data + * + */ +void ws_neighbor_class_neighbor_unicast_schedule_set(ws_neighbor_class_entry_t *ws_neighbor, ws_us_ie_t *ws_us); + + +/** + * ws_neighbor_class_neighbor_broadcast_time_info_update a function for update neighbor broadcast time information + * + * \param ws_neighbor pointer to neighbor + * \param ws_bt_ie Broadcast time IE data + * \param timestamp timestamp for received data + * + */ +void ws_neighbor_class_neighbor_broadcast_time_info_update(ws_neighbor_class_entry_t *ws_neighbor, ws_bt_ie_t *ws_bt_ie, uint32_t timestamp); + +/** + * ws_neighbor_class_neighbor_broadcast_schedule_set a function for update neighbor broadcast shedule information + * + * \param ws_neighbor pointer to neighbor + * \param ws_bs_ie Broadcast schedule IE data + * + */ +void ws_neighbor_class_neighbor_broadcast_schedule_set(ws_neighbor_class_entry_t *ws_neighbor, ws_bs_ie_t *ws_bs_ie); + +/** + * ws_neighbor_class_rssi_from_dbm_calculate + * + * Calculates rssi value from dbm heard taking into account min sensitivity of radio + * dynamically adjusts min sensitivity if value is not properly set + * + * \param dbm_heard; dbm heard from the neighbour + * + */ +uint8_t ws_neighbor_class_rssi_from_dbm_calculate(int8_t dbm_heard); + +/** Helper macros to read RSL values from neighbour class. + * + */ +#define ws_neighbor_class_rsl_in_get(ws_neighbour) (ws_neighbour->rsl_in >> WS_RSL_SCALING) +#define ws_neighbor_class_rsl_out_get(ws_neighbour) (ws_neighbour->rsl_in >> WS_RSL_SCALING) + +/** + * ws_neighbor_class_neighbor_broadcast_schedule_set a function for update neighbor broadcast shedule information + * + * \param ws_neighbor pointer to neighbor + * \param dbm_heard; dbm heard from the neighbour + * + */ +void ws_neighbor_class_rsl_in_calculate(ws_neighbor_class_entry_t *ws_neighbor, int8_t dbm_heard); +/** + * ws_neighbor_class_neighbor_broadcast_schedule_set a function for update neighbor broadcast shedule information + * + * \param ws_neighbor pointer to neighbor + * \param rsl_reported; rsl value reported by neighbour in packet from RSL-IE + * + */ +void ws_neighbor_class_rsl_out_calculate(ws_neighbor_class_entry_t *ws_neighbor, uint8_t rsl_reported); + +#endif /* WS_NEIGHBOR_CLASS_H_ */ diff --git a/features/nanostack/sal-stack-nanostack/source/BorderRouter/border_router.c b/features/nanostack/sal-stack-nanostack/source/BorderRouter/border_router.c index e090e6ef5712..08d7b13a056d 100644 --- a/features/nanostack/sal-stack-nanostack/source/BorderRouter/border_router.c +++ b/features/nanostack/sal-stack-nanostack/source/BorderRouter/border_router.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017, Arm Limited and affiliates. + * Copyright (c) 2012-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -506,9 +506,8 @@ void border_router_start(protocol_interface_info_entry_t *cur, bool warm_link_re if (warm_link_restart) { return; } - + mac_neighbor_table_neighbor_list_clean(mac_neighbor_info(cur)); #ifndef NO_MLE - mle_class_list_clean(cur->id); blacklist_clear(); #endif @@ -708,8 +707,8 @@ static int8_t arm_border_router_interface_down(protocol_interface_info_entry_t * cur->nwk_wpan_nvm_api->nvm_params_update_cb(cur->nwk_wpan_nvm_api, true); } cur->if_lowpan_security_params->mle_security_frame_counter = mle_service_security_get_frame_counter(cur->id); + mac_neighbor_table_neighbor_list_clean(mac_neighbor_info(cur)); #ifndef NO_MLE - mle_class_list_clean(cur->id); blacklist_clear(); #endif if (nd_nwk) { diff --git a/features/nanostack/sal-stack-nanostack/source/Common_Protocols/icmpv6.c b/features/nanostack/sal-stack-nanostack/source/Common_Protocols/icmpv6.c index 6c4240b65de8..647cb200cb32 100644 --- a/features/nanostack/sal-stack-nanostack/source/Common_Protocols/icmpv6.c +++ b/features/nanostack/sal-stack-nanostack/source/Common_Protocols/icmpv6.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017, Arm Limited and affiliates. + * Copyright (c) 2013-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,8 +20,8 @@ #include "ns_trace.h" #include "randLIB.h" #include "NWK_INTERFACE/Include/protocol.h" -#ifdef HAVE_RPL #include "RPL/rpl_control.h" +#ifdef HAVE_RPL #include "RPL/rpl_data.h" #endif #include "RPL/rpl_protocol.h" @@ -44,6 +44,8 @@ #include "common_functions.h" #include "6LoWPAN/ND/nd_router_object.h" #include "6LoWPAN/Bootstraps/protocol_6lowpan.h" +#include "6LoWPAN/ws/ws_common_defines.h" +#include "6LoWPAN/ws/ws_common.h" #define TRACE_GROUP "icmp" @@ -420,6 +422,7 @@ static buffer_t *icmpv6_ns_handler(buffer_t *buf) { protocol_interface_info_entry_t *cur; uint8_t target[16]; + uint8_t dummy_sllao[16]; bool proxy = false; const uint8_t *sllao; const uint8_t *aro; @@ -439,7 +442,9 @@ static buffer_t *icmpv6_ns_handler(buffer_t *buf) sllao = icmpv6_find_option_in_buffer(buf, 20, ICMPV6_OPT_SRC_LL_ADDR, 0); /* If no SLLAO, ignore ARO (RFC 6775 6.5) */ - if (sllao && cur->ipv6_neighbour_cache.recv_addr_reg) { + /* This rule can be bypassed by setting flag "use_eui64_as_slla_in_aro" to true */ + if (cur->ipv6_neighbour_cache.recv_addr_reg && + (cur->ipv6_neighbour_cache.use_eui64_as_slla_in_aro || sllao)) { aro = icmpv6_find_option_in_buffer(buf, 20, ICMPV6_OPT_ADDR_REGISTRATION, 0); } else { aro = NULL; @@ -450,6 +455,15 @@ static buffer_t *icmpv6_ns_handler(buffer_t *buf) goto drop; } + /* If there was no SLLAO on ARO, use mac address to create dummy one... */ + if (aro && !sllao && cur->ipv6_neighbour_cache.use_eui64_as_slla_in_aro) { + dummy_sllao[0] = ICMPV6_OPT_SRC_LL_ADDR; // Type + dummy_sllao[1] = 2; // Length = 2x8 bytes + memcpy(dummy_sllao + 2, aro + 8, 8); // EUI-64 + memset(dummy_sllao + 10, 0, 6); // Padding + + sllao = dummy_sllao; + } // Skip the 4 reserved bytes dptr += 4; @@ -529,7 +543,7 @@ static buffer_t *icmpv6_ns_handler(buffer_t *buf) } -int icmpv6_slaac_prefix_update(struct protocol_interface_info_entry *cur, uint8_t *prefix_ptr, uint8_t prefix_len, uint32_t valid_lifetime, uint32_t preferred_lifetime) +int icmpv6_slaac_prefix_update(struct protocol_interface_info_entry *cur, const uint8_t *prefix_ptr, uint8_t prefix_len, uint32_t valid_lifetime, uint32_t preferred_lifetime) { int ret_val = -1; @@ -564,7 +578,7 @@ void icmpv6_slaac_prefix_register_trig(struct protocol_interface_info_entry *cur } #endif // HAVE_IPV6_ND -if_address_entry_t *icmpv6_slaac_address_add(protocol_interface_info_entry_t *cur, uint8_t *prefix_ptr, uint8_t prefix_len, uint32_t valid_lifetime, uint32_t preferred_lifetime, bool skip_dad, slaac_src_e slaac_src) +if_address_entry_t *icmpv6_slaac_address_add(protocol_interface_info_entry_t *cur, const uint8_t *prefix_ptr, uint8_t prefix_len, uint32_t valid_lifetime, uint32_t preferred_lifetime, bool skip_dad, slaac_src_e slaac_src) { if_address_entry_t *address_entry; uint8_t ipv6_address[16]; @@ -774,7 +788,7 @@ static buffer_t *icmpv6_ra_handler(buffer_t *buf) ptr += 4; uint32_t preferred_lifetime = common_read_32_bit(ptr); ptr += 8; //Update 32-bit time and reserved 32-bit - uint8_t *prefix_ptr = ptr; + const uint8_t *prefix_ptr = ptr; //Check is L Flag active if (prefix_flags & PIO_L) { @@ -990,6 +1004,10 @@ static buffer_t *icmpv6_na_handler(buffer_t *buf) } ipv6_neighbour_update_from_na(&cur->ipv6_neighbour_cache, neighbour_entry, flags, buf->dst_sa.addr_type, buf->dst_sa.address); + if (ws_info(cur) && neighbour_entry->state == IP_NEIGHBOUR_REACHABLE) { + tr_debug("NA neigh update"); + ws_common_neighbor_update(cur, target); + } drop: return buffer_free(buf); @@ -1323,7 +1341,7 @@ buffer_t *icmpv6_build_ns(protocol_interface_info_entry_t *cur, const uint8_t ta } else { /* RFC 4861 7.2.2. says we should use the source of traffic prompting the NS, if possible */ /* This is also used to specify the address for ARO messages */ - if (prompting_src_addr && addr_is_assigned_to_interface(cur, prompting_src_addr)) { + if (aro || (prompting_src_addr && addr_is_assigned_to_interface(cur, prompting_src_addr))) { memcpy(buf->src_sa.address, prompting_src_addr, 16); } else { /* Otherwise, according to RFC 4861, we could use any address. @@ -1347,7 +1365,15 @@ buffer_t *icmpv6_build_ns(protocol_interface_info_entry_t *cur, const uint8_t ta } } /* SLLAO is required if we're sending an ARO */ - ptr = icmpv6_write_icmp_lla(cur, ptr, ICMPV6_OPT_SRC_LL_ADDR, aro, buf->src_sa.address); + /* This rule can be bypassed with flag use_eui64_as_slla_in_aro */ + if (!cur->ipv6_neighbour_cache.use_eui64_as_slla_in_aro) { + ptr = icmpv6_write_icmp_lla(cur, ptr, ICMPV6_OPT_SRC_LL_ADDR, aro, buf->src_sa.address); + } + /* If ARO Success sending is omitted, MAC ACK is used instead */ + /* Setting callback for receiving ACK from adaptation layer */ + if (aro && cur->ipv6_neighbour_cache.omit_aro_success) { + buf->ack_receive_cb = rpl_control_address_register_done; + } } buf->src_sa.addr_type = ADDR_IPV6; @@ -1481,6 +1507,12 @@ buffer_t *icmpv6_build_na(protocol_interface_info_entry_t *cur, bool solicited, tr_debug("Build NA"); + /* Check if ARO status == success, then sending can be omitted with flag */ + if (aro && cur->ipv6_neighbour_cache.omit_aro_success && aro->status == ARO_SUCCESS) { + tr_debug("Omit success reply"); + return NULL; + } + buffer_t *buf = buffer_get(8 + 16 + 16 + 16); /* fixed, target addr, target ll addr, aro */ if (!buf) { return NULL; diff --git a/features/nanostack/sal-stack-nanostack/source/Common_Protocols/icmpv6.h b/features/nanostack/sal-stack-nanostack/source/Common_Protocols/icmpv6.h index 7dfd83231a0e..c209e2af427c 100644 --- a/features/nanostack/sal-stack-nanostack/source/Common_Protocols/icmpv6.h +++ b/features/nanostack/sal-stack-nanostack/source/Common_Protocols/icmpv6.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017, Arm Limited and affiliates. + * Copyright (c) 2013-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -140,8 +140,8 @@ extern void icmpv6_recv_ra_routes(struct protocol_interface_info_entry *cur, boo extern void icmpv6_recv_ra_prefixes(struct protocol_interface_info_entry *cur, bool enable); extern void icmpv6_slaac_prefix_register_trig(struct protocol_interface_info_entry *cur, uint8_t *prefix_ptr, uint8_t prefix_len); -extern int icmpv6_slaac_prefix_update(struct protocol_interface_info_entry *cur, uint8_t *prefix_ptr, uint8_t prefix_len, uint32_t valid_lifetime, uint32_t preferred_lifetime); -extern struct if_address_entry *icmpv6_slaac_address_add(struct protocol_interface_info_entry *cur, uint8_t *prefix_ptr, uint8_t prefix_len, uint32_t valid_lifetime, uint32_t preferred_lifetime, bool skip_dad, slaac_src_e slaac_src); +extern int icmpv6_slaac_prefix_update(struct protocol_interface_info_entry *cur, const uint8_t *prefix_ptr, uint8_t prefix_len, uint32_t valid_lifetime, uint32_t preferred_lifetime); +extern struct if_address_entry *icmpv6_slaac_address_add(struct protocol_interface_info_entry *cur, const uint8_t *prefix_ptr, uint8_t prefix_len, uint32_t valid_lifetime, uint32_t preferred_lifetime, bool skip_dad, slaac_src_e slaac_src); /* diff --git a/features/nanostack/sal-stack-nanostack/source/Common_Protocols/ipv6.c b/features/nanostack/sal-stack-nanostack/source/Common_Protocols/ipv6.c index bf19d1a5682f..af3ca814f49d 100644 --- a/features/nanostack/sal-stack-nanostack/source/Common_Protocols/ipv6.c +++ b/features/nanostack/sal-stack-nanostack/source/Common_Protocols/ipv6.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017, Arm Limited and affiliates. + * Copyright (c) 2013-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/features/nanostack/sal-stack-nanostack/source/Common_Protocols/ipv6_fragmentation.c b/features/nanostack/sal-stack-nanostack/source/Common_Protocols/ipv6_fragmentation.c index 13169a0c191b..0c770e26ebb8 100644 --- a/features/nanostack/sal-stack-nanostack/source/Common_Protocols/ipv6_fragmentation.c +++ b/features/nanostack/sal-stack-nanostack/source/Common_Protocols/ipv6_fragmentation.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/features/nanostack/sal-stack-nanostack/source/Common_Protocols/tcp.c b/features/nanostack/sal-stack-nanostack/source/Common_Protocols/tcp.c index 5fb61554edef..526196eb8b2a 100644 --- a/features/nanostack/sal-stack-nanostack/source/Common_Protocols/tcp.c +++ b/features/nanostack/sal-stack-nanostack/source/Common_Protocols/tcp.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017, Arm Limited and affiliates. + * Copyright (c) 2013-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/features/nanostack/sal-stack-nanostack/source/Core/address.c b/features/nanostack/sal-stack-nanostack/source/Core/address.c index 31b4434e75fb..5bf5bd4ed0fe 100644 --- a/features/nanostack/sal-stack-nanostack/source/Core/address.c +++ b/features/nanostack/sal-stack-nanostack/source/Core/address.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2010-2017, Arm Limited and affiliates. + * Copyright (c) 2008, 2010-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/features/nanostack/sal-stack-nanostack/source/Core/buffer_dyn.c b/features/nanostack/sal-stack-nanostack/source/Core/buffer_dyn.c index 14668536890b..b83d7164e0cc 100644 --- a/features/nanostack/sal-stack-nanostack/source/Core/buffer_dyn.c +++ b/features/nanostack/sal-stack-nanostack/source/Core/buffer_dyn.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2017, Arm Limited and affiliates. + * Copyright (c) 2011-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -110,7 +110,7 @@ buffer_t *buffer_get_specific(uint16_t headroom, uint16_t size, uint16_t minspac #endif buf->size = total_size; } else { - tr_error("buffer_get failed: alloc(%zd)", sizeof(buffer_t) + total_size); + tr_error("buffer_get failed: alloc(%d)", (int) sizeof(buffer_t) + total_size); } protocol_stats_update(STATS_BUFFER_ALLOC, 1); diff --git a/features/nanostack/sal-stack-nanostack/source/Core/include/address.h b/features/nanostack/sal-stack-nanostack/source/Core/include/address.h index 9f3c6b24d8aa..09f7e6a8cf26 100644 --- a/features/nanostack/sal-stack-nanostack/source/Core/include/address.h +++ b/features/nanostack/sal-stack-nanostack/source/Core/include/address.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2010-2017, Arm Limited and affiliates. + * Copyright (c) 2008, 2010-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -96,6 +96,8 @@ typedef struct if_address_entry { bool temporary:1; // RFC 4941 temporary address bool tentative:1; // Tentative address (Duplicate Address Detection running) bool group_added:1; // Solicited-Node group added + uint8_t addr_reg_pend; // Bitmask for pending address registrations. Based on RPL path control bits + uint8_t addr_reg_done; // Bitmask for address registration done. Based on RPL path control bits if_address_source_t source; // if_address_callback_fn *cb; // Address protocol callback function void *data; // Address protocol data diff --git a/features/nanostack/sal-stack-nanostack/source/Core/include/ns_buffer.h b/features/nanostack/sal-stack-nanostack/source/Core/include/ns_buffer.h index 60e5f22bff46..b89ab3f7775a 100644 --- a/features/nanostack/sal-stack-nanostack/source/Core/include/ns_buffer.h +++ b/features/nanostack/sal-stack-nanostack/source/Core/include/ns_buffer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2017, Arm Limited and affiliates. + * Copyright (c) 2008-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -228,6 +228,7 @@ typedef struct buffer { uint8_t trickle_data_field[4]; buffer_options_t options; /*!< Additional signal info etc */ buffer_routing_info_t *route; /* A pointer last to try to get neat alignment for data */ + void (*ack_receive_cb)(struct buffer *buffer_ptr, uint8_t status); /*!< ACK receive callback. If set, will be called when TX is done */ uint8_t buf[]; /*!< Trailing buffer data */ } buffer_t; diff --git a/features/nanostack/sal-stack-nanostack/source/Core/ns_socket.c b/features/nanostack/sal-stack-nanostack/source/Core/ns_socket.c index 01f7fe2360ec..ad9135ca90e6 100644 --- a/features/nanostack/sal-stack-nanostack/source/Core/ns_socket.c +++ b/features/nanostack/sal-stack-nanostack/source/Core/ns_socket.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2015, 2017, Arm Limited and affiliates. + * Copyright (c) 2008-2015, 2017-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -1396,6 +1396,10 @@ buffer_t *socket_tx_buffer_event(buffer_t *buf, uint8_t status) * and we mapped straight to MAC address). */ + if (buf->ack_receive_cb) { + buf->ack_receive_cb(buf, status); + } + /* Suppress events once socket orphaned */ if (!buf->socket || (buf->socket->flags & (SOCKET_FLAG_PENDING|SOCKET_FLAG_CLOSED))) { return buf; diff --git a/features/nanostack/sal-stack-nanostack/source/DHCPv6_Server/DHCPv6_Server_service.c b/features/nanostack/sal-stack-nanostack/source/DHCPv6_Server/DHCPv6_Server_service.c index e33f3e361e8a..26b7b3a7963d 100644 --- a/features/nanostack/sal-stack-nanostack/source/DHCPv6_Server/DHCPv6_Server_service.c +++ b/features/nanostack/sal-stack-nanostack/source/DHCPv6_Server/DHCPv6_Server_service.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -106,7 +106,7 @@ int DHCPv6_server_respond_client(dhcpv6_gua_server_entry_s *serverBase, dhcpv6_r // coverity[returned_null] for ignoring protocol_stack_interface_info_get_by_id NULL return DHCPV6_server_service_remove_GUA_from_neighcache(protocol_stack_interface_info_get_by_id(serverBase->interfaceId), nonTemporalAddress.requestedAddress); } - if (thread_bbr_nd_entry_add(serverBase->interfaceId,dhcp_allocated_address->nonTemporalAddress, nonTemporalAddress.validLifeTime, serverBase->guaPrefix, NULL) == -1) { + if (thread_bbr_nd_entry_add(serverBase->interfaceId,dhcp_allocated_address->nonTemporalAddress, nonTemporalAddress.validLifeTime, serverBase->guaPrefix) == -1) { // No nanostack BBR present we will put entry for application implemented BBR ipv6_route_t *route = ipv6_route_add_with_info(dhcp_allocated_address->nonTemporalAddress, 128, serverBase->interfaceId, NULL, ROUTE_THREAD_PROXIED_HOST,serverBase->guaPrefix,0, nonTemporalAddress.validLifeTime, 0); if (!route) { @@ -114,7 +114,6 @@ int DHCPv6_server_respond_client(dhcpv6_gua_server_entry_s *serverBase, dhcpv6_r libdhcpv6_address_rm_from_allocated_list(serverBase,dhcp_allocated_address->nonTemporalAddress); } - } } diff --git a/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_defines.h b/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_defines.h index cd7a6fa20df3..9315d36e95c6 100644 --- a/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_defines.h +++ b/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_defines.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -139,6 +139,9 @@ typedef struct protocol_interface_rf_mac_setup { bool macUpState; bool shortAdressValid: 1; //Define Dynamic src address to mac16 when it is true bool beaconSrcAddressModeLong: 1; //This force beacon src to mac64 otherwise shortAdressValid will define type + bool mac_extension_enabled:1; + bool mac_ack_tx_active:1; + bool mac_frame_pending:1; uint16_t mac_short_address; uint16_t pan_id; uint8_t mac64[8]; @@ -154,6 +157,8 @@ typedef struct protocol_interface_rf_mac_setup { bool macProminousMode:1; bool macGTSPermit:1; bool mac_security_enabled:1; + /* Let trough packet which is secured properly (MIC authenticated group key) and src address is 64-bit*/ + bool mac_security_bypass_unknow_device:1; /* Load balancing need this feature */ bool macAcceptAnyBeacon:1; @@ -169,6 +174,7 @@ typedef struct protocol_interface_rf_mac_setup { bool macRfRadioTxActive:1; bool macBroadcastDisabled:1; bool scan_active:1; + bool rf_csma_extension_supported:1; /* CSMA Params */ unsigned macMinBE:4; unsigned macMaxBE:4; @@ -201,6 +207,7 @@ typedef struct protocol_interface_rf_mac_setup { uint8_t mac_cca_retry; uint8_t mac_ack_wait_duration; uint8_t mac_mlme_retry_max; + uint8_t aUnitBackoffPeriod; /* Indirect queue parameters */ struct mac_pre_build_frame *indirect_pd_data_request_queue; arm_event_t mac_mcps_timer_event; @@ -217,6 +224,8 @@ typedef struct protocol_interface_rf_mac_setup { int8_t cca_timer_id; int8_t bc_timer_id; uint32_t mlme_tick_count; + uint32_t symbol_rate; + uint32_t symbol_time_us; uint8_t max_ED; uint16_t mlme_ED_counter; mac_tx_status_t mac_tx_status; @@ -250,22 +259,26 @@ typedef struct protocol_interface_rf_mac_setup { } protocol_interface_rf_mac_setup_s; -#define MAC_FCF_FRAME_TYPE_MASK 0x0007 -#define MAC_FCF_FRAME_TYPE_SHIFT 0 -#define MAC_FCF_SECURITY_BIT_MASK 0x0008 -#define MAC_FCF_SECURITY_BIT_SHIFT 3 -#define MAC_FCF_PENDING_BIT_MASK 0x0010 -#define MAC_FCF_PENDING_BIT_SHIFT 4 -#define MAC_FCF_ACK_REQ_BIT_MASK 0x0020 -#define MAC_FCF_ACK_REQ_BIT_SHIFT 5 -#define MAC_FCF_INTRA_PANID_MASK 0x0040 -#define MAC_FCF_INTRA_PANID_SHIFT 6 -#define MAC_FCF_DST_ADDR_MASK 0x0c00 -#define MAC_FCF_DST_ADDR_SHIFT 10 -#define MAC_FCF_VERSION_MASK 0x3000 -#define MAC_FCF_VERSION_SHIFT 12 -#define MAC_FCF_SRC_ADDR_MASK 0xc000 -#define MAC_FCF_SRC_ADDR_SHIFT 14 +#define MAC_FCF_FRAME_TYPE_MASK 0x0007 +#define MAC_FCF_FRAME_TYPE_SHIFT 0 +#define MAC_FCF_SECURITY_BIT_MASK 0x0008 +#define MAC_FCF_SECURITY_BIT_SHIFT 3 +#define MAC_FCF_PENDING_BIT_MASK 0x0010 +#define MAC_FCF_PENDING_BIT_SHIFT 4 +#define MAC_FCF_ACK_REQ_BIT_MASK 0x0020 +#define MAC_FCF_ACK_REQ_BIT_SHIFT 5 +#define MAC_FCF_INTRA_PANID_MASK 0x0040 +#define MAC_FCF_INTRA_PANID_SHIFT 6 +#define MAC_FCF_SEQ_NUM_SUPPRESS_MASK 0x0100 +#define MAC_FCF_SEQ_NUM_SUPPRESS_SHIFT 8 +#define MAC_FCF_IE_PRESENTS_MASK 0x0200 +#define MAC_FCF_IE_PRESENTS_SHIFT 9 +#define MAC_FCF_DST_ADDR_MASK 0x0c00 +#define MAC_FCF_DST_ADDR_SHIFT 10 +#define MAC_FCF_VERSION_MASK 0x3000 +#define MAC_FCF_VERSION_SHIFT 12 +#define MAC_FCF_SRC_ADDR_MASK 0xc000 +#define MAC_FCF_SRC_ADDR_SHIFT 14 /* MAC supported frame types */ #define FC_BEACON_FRAME 0x00 diff --git a/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_fhss_callbacks.c b/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_fhss_callbacks.c index 24e8d7eadd4d..d326aaa078a4 100644 --- a/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_fhss_callbacks.c +++ b/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_fhss_callbacks.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, Arm Limited and affiliates. + * Copyright (c) 2016-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -57,7 +57,12 @@ uint32_t mac_read_phy_datarate(const fhss_api_t *fhss_api) if (!mac_setup) { return 0; } - return dev_get_phy_datarate(mac_setup->dev_driver->phy_driver, mac_setup->mac_channel_list.channel_page); + uint32_t datarate = dev_get_phy_datarate(mac_setup->dev_driver->phy_driver, mac_setup->mac_channel_list.channel_page); + // If datarate is not set, use default 250kbit/s. + if (!datarate) { + datarate = 250000; + } + return datarate; } int mac_set_channel(const fhss_api_t *fhss_api, uint8_t channel_number) @@ -66,9 +71,8 @@ int mac_set_channel(const fhss_api_t *fhss_api, uint8_t channel_number) if (!mac_setup) { return -1; } - // If TX is active, send internal CCA fail event. MAC state machine would crash without TX done event. - if (mac_setup->macRfRadioTxActive == true) { - mac_setup->dev_driver->phy_driver->phy_tx_done_cb(mac_setup->dev_driver->id, 1, PHY_LINK_TX_FAIL, 0, 0); + if (mac_setup->mac_ack_tx_active || (mac_setup->active_pd_data_request && mac_setup->active_pd_data_request->asynch_request)) { + return -1; } return mac_mlme_rf_channel_change(mac_setup, channel_number); } diff --git a/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_filter.c b/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_filter.c index 6bcaee9d59f9..5701a9499734 100644 --- a/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_filter.c +++ b/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_filter.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -26,6 +26,7 @@ #include "mac_filter.h" #include "mac_common_defines.h" +#include "mac_mcps.h" #include "MAC/IEEE802_15_4/mac_mcps_sap.h" #include "MAC/IEEE802_15_4/mac_header_helper_functions.h" diff --git a/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_header_helper_functions.c b/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_header_helper_functions.c index e5ed44e63e52..2867513170f0 100644 --- a/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_header_helper_functions.c +++ b/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_header_helper_functions.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, Arm Limited and affiliates. + * Copyright (c) 2016-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,16 +14,139 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "nsconfig.h" #include "ns_types.h" #include "string.h" +#include "ns_trace.h" #include "mlme.h" #include "mac_api.h" +#include "fhss_api.h" #include "common_functions.h" #include "mac_common_defines.h" #include "MAC/IEEE802_15_4/mac_defines.h" #include "MAC/IEEE802_15_4/mac_mcps_sap.h" #include "MAC/IEEE802_15_4/mac_header_helper_functions.h" +static uint8_t *mcps_mac_security_aux_header_start_pointer_get(const mac_pre_parsed_frame_t *buffer); +static uint8_t * mac_header_information_elements_write(const mac_pre_build_frame_t *buffer, uint8_t *ptr); + + +static uint8_t mac_fcf_lenght(const mac_fcf_sequence_t *header) +{ + uint8_t length; + if (header->frameVersion == MAC_FRAME_VERSION_2015) { + if (header->sequenceNumberSuppress) { + length = 2; //Skip FCF + } else { + length = 3; //Skip FCF + DSN + } + } else { + length= 3; //Skip FCF + DSN + } + return length; +} + +bool mac_dst_panid_present(const mac_fcf_sequence_t *header) +{ + bool presents = false; + if (header->DstAddrMode && header->SrcAddrMode) { + if (header->frameVersion == MAC_FRAME_VERSION_2015) { + if (header->DstAddrMode == MAC_ADDR_MODE_64_BIT && header->SrcAddrMode == MAC_ADDR_MODE_64_BIT && header->intraPan) { + + } else { + presents = true; + } + } else { + presents = true; + } + + } else if (header->DstAddrMode && !header->SrcAddrMode) { + if (header->frameVersion == MAC_FRAME_VERSION_2015) { + if (!header->intraPan) { + presents = true; + } + } else { + presents = true; + } + + } else if (!header->DstAddrMode && !header->SrcAddrMode) { + if (header->frameVersion == MAC_FRAME_VERSION_2015) { + if (header->intraPan) { + presents = true; + } + } + } + + return presents; +} + +bool mac_src_panid_present(const mac_fcf_sequence_t *header) +{ + bool presents = false; + if (header->DstAddrMode && header->SrcAddrMode) { + if (header->frameVersion == MAC_FRAME_VERSION_2015) { + if (header->DstAddrMode == MAC_ADDR_MODE_64_BIT && header->SrcAddrMode == MAC_ADDR_MODE_64_BIT) { + + } else if (!header->intraPan) { + presents = true; + } + } else if (!header->intraPan) { + presents = true; + } + + } else if (header->SrcAddrMode) { + if (header->frameVersion == MAC_FRAME_VERSION_2015) { + if (!header->intraPan) { + presents = true; + } + } else { + presents = true; + } + } + return presents; +} + +uint8_t mac_address_length(uint8_t address_mode) +{ + uint8_t length = 0; + switch (address_mode) { + case MAC_ADDR_MODE_NONE: + break; + case MAC_ADDR_MODE_16_BIT: + length = 2; + break; + case MAC_ADDR_MODE_64_BIT: + length = 8; + break; + } + return length; +} + +static uint8_t mac_dst_address_length_with_panid(const mac_fcf_sequence_t *header) +{ + uint8_t length = 0; + + if (header->DstPanPresents) { + length += 2; + } + + length += mac_address_length(header->DstAddrMode); + + return length; +} + +static uint8_t mac_src_address_length_with_panid(const mac_fcf_sequence_t *header) +{ + uint8_t length = 0; + + if (header->SrcPanPresents) { + length += 2; + } + + length += mac_address_length(header->SrcAddrMode); + + return length; +} uint8_t mac_security_mic_length_get(uint8_t security_level) @@ -75,48 +198,16 @@ uint8_t mac_header_security_aux_header_length(uint8_t security_level, uint8_t ke uint8_t mac_header_address_length(const mac_fcf_sequence_t *fcf) { uint8_t address_length = 0; - if( !fcf ){ - return address_length; - } - - if(fcf->DstAddrMode && fcf->SrcAddrMode) { - if (fcf->DstAddrMode == MAC_ADDR_MODE_16_BIT) { - address_length = 4; - } else { - address_length = 10; - } - if (fcf->SrcAddrMode == MAC_ADDR_MODE_16_BIT) { - address_length += 2; - } else { - address_length += 8; - } + address_length += mac_dst_address_length_with_panid(fcf); + address_length += mac_src_address_length_with_panid(fcf); - if (!fcf->intraPan) { - address_length += 2; - } - } else if (fcf->DstAddrMode) { - if (fcf->DstAddrMode == MAC_ADDR_MODE_16_BIT) { - address_length = 4; - } else { - address_length = 10; - } - } else if (fcf->SrcAddrMode){ - if (fcf->SrcAddrMode == MAC_ADDR_MODE_16_BIT) { - address_length = 4; - } else { - address_length = 10; - } - } return address_length; } void mac_header_security_parameter_set(mac_aux_security_header_t *header, const mlme_security_t *frame_setup) { - if( !header || !frame_setup ){ - return; - } header->securityLevel = frame_setup->SecurityLevel; if (header->securityLevel) { @@ -145,14 +236,10 @@ void mac_header_security_parameter_set(mac_aux_security_header_t *header, const } } -void mac_header_parse_fcf_dsn(mac_fcf_sequence_t *header, const uint8_t *ptr) +const uint8_t * mac_header_parse_fcf_dsn(mac_fcf_sequence_t *header, const uint8_t *ptr) { - if( !header || !ptr ){ - return; - } uint16_t fcf = common_read_16_bit_inverse(ptr); ptr += 2; - header->DSN = *ptr; //Read Frame Type header->frametype = ((fcf & MAC_FCF_FRAME_TYPE_MASK) >> MAC_FCF_FRAME_TYPE_SHIFT); @@ -160,9 +247,27 @@ void mac_header_parse_fcf_dsn(mac_fcf_sequence_t *header, const uint8_t *ptr) header->framePending = ((fcf & MAC_FCF_PENDING_BIT_MASK) >> MAC_FCF_PENDING_BIT_SHIFT); header->ackRequested = ((fcf & MAC_FCF_ACK_REQ_BIT_MASK) >> MAC_FCF_ACK_REQ_BIT_SHIFT); header->intraPan = ((fcf & MAC_FCF_INTRA_PANID_MASK ) >> MAC_FCF_INTRA_PANID_SHIFT); + header->DstAddrMode = ((fcf & MAC_FCF_DST_ADDR_MASK ) >> MAC_FCF_DST_ADDR_SHIFT); header->frameVersion = ((fcf & MAC_FCF_VERSION_MASK) >> MAC_FCF_VERSION_SHIFT); header->SrcAddrMode = ((fcf & MAC_FCF_SRC_ADDR_MASK ) >> MAC_FCF_SRC_ADDR_SHIFT); + + if (header->frameVersion == MAC_FRAME_VERSION_2015 ) { + header->sequenceNumberSuppress = ((fcf & MAC_FCF_SEQ_NUM_SUPPRESS_MASK ) >> MAC_FCF_SEQ_NUM_SUPPRESS_SHIFT); + header->informationElementsPresets = ((fcf & MAC_FCF_IE_PRESENTS_MASK ) >> MAC_FCF_IE_PRESENTS_SHIFT); + } else { + //SET False to ALL 2015 Extension's by default + header->sequenceNumberSuppress = false; + header->informationElementsPresets = false; + } + + if (header->frameVersion < MAC_FRAME_VERSION_2015 || (header->frameVersion == MAC_FRAME_VERSION_2015 && !header->sequenceNumberSuppress)) { + header->DSN = *ptr++; + } else { + header->DSN = 0; + } + return ptr; + } static uint8_t * mac_header_write_fcf_dsn(const mac_fcf_sequence_t *header, uint8_t *ptr) @@ -174,29 +279,36 @@ static uint8_t * mac_header_write_fcf_dsn(const mac_fcf_sequence_t *header, uint fcf |= (header->framePending << MAC_FCF_PENDING_BIT_SHIFT); fcf |= (header->ackRequested << MAC_FCF_ACK_REQ_BIT_SHIFT); fcf |= (header->intraPan << MAC_FCF_INTRA_PANID_SHIFT); + fcf |= (header->sequenceNumberSuppress << MAC_FCF_SEQ_NUM_SUPPRESS_SHIFT); + fcf |= (header->informationElementsPresets << MAC_FCF_IE_PRESENTS_SHIFT); fcf |= (header->DstAddrMode << MAC_FCF_DST_ADDR_SHIFT); fcf |= (header->frameVersion << MAC_FCF_VERSION_SHIFT); fcf |= (header->SrcAddrMode << MAC_FCF_SRC_ADDR_SHIFT); ptr = common_write_16_bit_inverse(fcf,ptr); - *ptr++ = header->DSN; + if (header->frameVersion < MAC_FRAME_VERSION_2015 || (header->frameVersion == MAC_FRAME_VERSION_2015 && !header->sequenceNumberSuppress)) { + *ptr++ = header->DSN; + } return ptr; } -void mac_header_security_components_read(mac_pre_parsed_frame_t *buffer, mlme_security_t *security_params) +uint16_t mac_header_off_set_to_aux_header(const mac_fcf_sequence_t *fcf) { - if( !buffer || !security_params ){ - return; - } - uint8_t *ptr = mcps_mac_security_aux_header_start_pointer_get(buffer); - memset(security_params, 0, sizeof(mlme_security_t)); - uint8_t key_source_len = 0; - if (!buffer->fcf_dsn.securityEnabled) { - return; - } + //Skip first FCF & address field + uint16_t offset = mac_fcf_lenght(fcf);//Skip FCF + DSN + offset += mac_dst_address_length_with_panid(fcf); + offset += mac_address_length(fcf->SrcAddrMode); + if (fcf->SrcPanPresents) { + offset += 2; //Skip PanId + } + return offset; +} +void mac_header_security_aux_header_parse(const uint8_t *ptr, mlme_security_t *security_params) +{ + uint8_t key_source_len = 0; security_params->KeyIdMode = (*ptr >> 3); security_params->SecurityLevel = *ptr++; - ptr += 4; + ptr += 4; //Skip Frame counter switch (security_params->KeyIdMode) { case MAC_KEY_ID_MODE_IMPLICIT: break; @@ -214,84 +326,65 @@ void mac_header_security_components_read(mac_pre_parsed_frame_t *buffer, mlme_se } } -uint16_t mac_header_get_src_panid(const mac_fcf_sequence_t *header, const uint8_t *ptr) +void mac_header_security_components_read(mac_pre_parsed_frame_t *buffer, mlme_security_t *security_params) { - if( !header || !ptr ){ - return 0; + memset(security_params, 0, sizeof(mlme_security_t)); + if (!buffer->fcf_dsn.securityEnabled) { + return; } - ptr += 3; //Skip FCF + DSN - if (!header->intraPan) { - switch (header->DstAddrMode) { - case MAC_ADDR_MODE_NONE: - break; - case MAC_ADDR_MODE_16_BIT: - ptr += 4; - break; - case MAC_ADDR_MODE_64_BIT: - ptr += 10; - break; + mac_header_security_aux_header_parse(mcps_mac_security_aux_header_start_pointer_get(buffer), security_params); + +} + +uint16_t mac_header_get_src_panid(const mac_fcf_sequence_t *header, const uint8_t *ptr) +{ + + if (!header->SrcPanPresents) { + if (!header->DstPanPresents) { + return 0xffff; } + return mac_header_get_dst_panid(header, ptr); } - uint16_t panid = 0; - panid += *ptr++; - panid += (uint16_t)(*ptr++) << 8; - return panid; + ptr += mac_fcf_lenght(header);//Skip FCF + DSN + + ptr += mac_dst_address_length_with_panid(header); //Skip Dst panID & Address + + return common_read_16_bit_inverse(ptr); } uint16_t mac_header_get_dst_panid(const mac_fcf_sequence_t *header, const uint8_t *ptr) { - if( !header || !ptr ){ - return 0; - } - if (header->DstAddrMode == MAC_ADDR_MODE_NONE) { + if (!header->DstPanPresents) { return 0xffff; } - ptr += 3; - uint16_t panid = 0; - panid += *ptr++; - panid += (uint16_t)(*ptr++) << 8; - return panid; + ptr += mac_fcf_lenght(header);//Skip FCF + DSN + + return common_read_16_bit_inverse(ptr); } void mac_header_get_src_address(const mac_fcf_sequence_t *header, const uint8_t *ptr, uint8_t *address_ptr) { - if( !header || !ptr || !address_ptr ){ - return; - } - ptr += 3; //Skip FCF + DSN - switch (header->DstAddrMode) { - case MAC_ADDR_MODE_NONE: - ptr += 2; - break; - case MAC_ADDR_MODE_16_BIT: - ptr += 4; - if (!header->intraPan) { - ptr += 2; - } - break; - case MAC_ADDR_MODE_64_BIT: - ptr += 10; - if (!header->intraPan) { - ptr += 2; - } - break; - } - if (header->SrcAddrMode == MAC_ADDR_MODE_NONE) { return; } + + ptr += mac_fcf_lenght(header);//Skip FCF + DSN + + ptr += mac_dst_address_length_with_panid(header); + uint8_t address_len, address_index, i; - if (header->SrcAddrMode == MAC_ADDR_MODE_16_BIT) { - address_len = 2; - address_index = 1; - } else { - address_len = 8; - address_index = 7; + + address_len = mac_address_length(header->SrcAddrMode); + + if (header->SrcPanPresents) { + ptr += 2; //Skip PanId } + address_index = address_len - 1; + for (i = 0; i < address_len; i++) { address_ptr[address_index - i] = *ptr++; @@ -300,67 +393,59 @@ void mac_header_get_src_address(const mac_fcf_sequence_t *header, const uint8_t void mac_header_get_dst_address(const mac_fcf_sequence_t *header, const uint8_t *ptr, uint8_t *address_ptr) { - if( !header || !ptr || !address_ptr ){ - return; - } if (header->DstAddrMode == MAC_ADDR_MODE_NONE) { return; } uint8_t address_len, address_index, i; - if (header->DstAddrMode == MAC_ADDR_MODE_16_BIT) { - address_len = 2; - address_index = 1; - } else { - address_len = 8; - address_index = 7; + ptr += mac_fcf_lenght(header);//Skip FCF + DSN + + address_len = mac_address_length(header->DstAddrMode); + + if (header->DstPanPresents) { + ptr += 2; //Skip PanId } - ptr += 5; //Skip fcf, dsn & PANID + address_index = address_len - 1; for (i = 0; i < address_len; i++) { address_ptr[address_index - i] = *ptr++; } } -uint16_t mcps_payload_length_from_received_frame(const mac_pre_parsed_frame_t *buffer) +static uint16_t mac_payload_length_calc_with_ie(uint16_t payload_length, uint16_t payload_ie_length) { - if( !buffer ){ - return 0; + uint16_t length = payload_length; + if (payload_ie_length) { + if (length) { + length += 2; + } + length += payload_ie_length; } - return buffer->mac_payload_length; + return length; } uint8_t mcps_mac_header_length_from_received_frame(const mac_pre_parsed_frame_t *buffer) { - if( !buffer ){ - return 0; - } - return (buffer->mac_header_length + buffer->security_aux_header_length); + return (buffer->mac_header_length + buffer->security_aux_header_length + buffer->header_ie_length); } uint8_t *mcps_mac_payload_pointer_get(const mac_pre_parsed_frame_t *buffer) { - if( !buffer ){ - return NULL; - } uint8_t *ptr = (uint8_t *) mac_header_message_start_pointer(buffer); - ptr += (buffer->mac_header_length + buffer->security_aux_header_length); + ptr += mcps_mac_header_length_from_received_frame(buffer); return ptr; } uint8_t *mcps_security_mic_pointer_get(const mac_pre_parsed_frame_t *buffer) { - if (!buffer) { - return NULL; - } - uint8_t *ptr = mcps_mac_payload_pointer_get(buffer); - return (ptr + buffer->mac_payload_length); + uint8_t *ptr = mcps_mac_payload_pointer_get(buffer) + buffer->mac_payload_length; + return ptr; } -uint8_t *mcps_mac_security_aux_header_start_pointer_get(const mac_pre_parsed_frame_t *buffer) +static uint8_t *mcps_mac_security_aux_header_start_pointer_get(const mac_pre_parsed_frame_t *buffer) { - if (!buffer || !buffer->fcf_dsn.securityEnabled) { + if (!buffer->fcf_dsn.securityEnabled) { return NULL; } return (uint8_t *) (mac_header_message_start_pointer(buffer) + buffer->mac_header_length); @@ -368,16 +453,13 @@ uint8_t *mcps_mac_security_aux_header_start_pointer_get(const mac_pre_parsed_fra uint8_t mcps_mac_command_frame_id_get(const mac_pre_parsed_frame_t *buffer) { - if ( !buffer ) { - return 0; - } const uint8_t *ptr = mcps_mac_payload_pointer_get(buffer); return *ptr; } uint32_t mcps_mac_security_frame_counter_read(const mac_pre_parsed_frame_t *buffer) { - if (!buffer || !buffer->fcf_dsn.securityEnabled) { + if (!buffer->fcf_dsn.securityEnabled) { return 0xffffffff; } @@ -386,7 +468,6 @@ uint32_t mcps_mac_security_frame_counter_read(const mac_pre_parsed_frame_t *buff } - static uint8_t *mcps_mac_frame_address_write(uint8_t *ptr, uint8_t addressType, const uint8_t *addressPtr) { if (addressType == MAC_ADDR_MODE_16_BIT) { @@ -401,22 +482,267 @@ static uint8_t *mcps_mac_frame_address_write(uint8_t *ptr, uint8_t addressType, return ptr; } -uint8_t * mcps_generic_header_write(uint8_t *ptr, const mac_pre_build_frame_t *buffer) +static uint8_t *mac_security_interface_aux_security_header_write(uint8_t *ptr, const mac_aux_security_header_t *auxHeader) +{ + uint8_t auxBaseHeader; + auxBaseHeader = auxHeader->securityLevel; + auxBaseHeader |= (auxHeader->KeyIdMode << 3); + *ptr++ = auxBaseHeader; + ptr = common_write_32_bit_inverse(auxHeader->frameCounter, ptr); + + switch (auxHeader->KeyIdMode) { + case MAC_KEY_ID_MODE_SRC8_IDX: + memcpy(ptr, auxHeader->Keysource, 8); + ptr += 8; + *ptr++ = auxHeader->KeyIndex; + break; + case MAC_KEY_ID_MODE_SRC4_IDX: + memcpy(ptr, auxHeader->Keysource, 4); + ptr += 4; + *ptr++ = auxHeader->KeyIndex; + break; + case MAC_KEY_ID_MODE_IDX: + *ptr++ = auxHeader->KeyIndex; + break; + default: + break; + } + return ptr; +} + +uint8_t * mac_generic_packet_write(struct protocol_interface_rf_mac_setup *rf_ptr, uint8_t *ptr, const mac_pre_build_frame_t *buffer) { ptr = mac_header_write_fcf_dsn(&buffer->fcf_dsn, ptr); - if (buffer->fcf_dsn.DstAddrMode) { + if (buffer->fcf_dsn.DstPanPresents) { ptr = common_write_16_bit_inverse(buffer->DstPANId, ptr); + } + + if (buffer->fcf_dsn.DstAddrMode) { //Write DST ptr = mcps_mac_frame_address_write(ptr, buffer->fcf_dsn.DstAddrMode, buffer->DstAddr); } - if (buffer->fcf_dsn.SrcAddrMode ){ - if (!(buffer->fcf_dsn.intraPan)) { - ptr = common_write_16_bit_inverse(buffer->SrcPANId, ptr); - } + if (buffer->fcf_dsn.SrcPanPresents) { + ptr = common_write_16_bit_inverse(buffer->SrcPANId, ptr); + } + + if (buffer->fcf_dsn.SrcAddrMode ) { ptr = mcps_mac_frame_address_write(ptr, buffer->fcf_dsn.SrcAddrMode, buffer->SrcAddr); } + + if (buffer->fcf_dsn.securityEnabled) { + ptr = mac_security_interface_aux_security_header_write(ptr, &buffer->aux_header); + } + uint8_t *ie_start = ptr; + //Copy Payload and set IE Elemets + ptr = mac_header_information_elements_write(buffer, ptr); + if (buffer->mac_payload_length) { + memcpy(ptr, buffer->mac_payload, buffer->mac_payload_length ); + ptr += buffer->mac_payload_length; + } + if (rf_ptr->fhss_api) { + rf_ptr->fhss_api->write_synch_info(rf_ptr->fhss_api, ie_start, buffer->headerIeLength, FHSS_DATA_FRAME, buffer->tx_time); + } + return ptr; +} + +static uint8_t *mac_write_ie_vector_list(ns_ie_iovec_t *list, uint16_t length, uint8_t *ptr) +{ + const ns_ie_iovec_t *msg_iov = list; + for (uint_fast16_t i = 0; i < length; i++, msg_iov++) { + memcpy(ptr, msg_iov->ieBase, msg_iov->iovLen); + ptr += msg_iov->iovLen; + } + return ptr; +} + +static bool mac_parse_header_ie(mac_header_IE_t *header_element, uint8_t *ptr) +{ + uint16_t ie_dummy = common_read_16_bit_inverse(ptr); + if (ie_dummy & 0x8000) { + return false; + } + header_element->length = (ie_dummy & 0x007f); + header_element->id = ((ie_dummy & 0x7f80 ) >> 7 ); + header_element->content_ptr = ptr + 2; + return true; +} + +static bool mac_parse_payload_ie(mac_payload_IE_t *payload_element, uint8_t *ptr) +{ + uint16_t ie_dummy = common_read_16_bit_inverse(ptr); + if (!(ie_dummy & 0x8000)) { + return false; + } + payload_element->length = (ie_dummy & 0x07ff); + payload_element->id = ((ie_dummy & 0x7800 ) >> 11); + payload_element->content_ptr = ptr + 2; + return true; +} + + +bool mac_header_information_elements_parse(mac_pre_parsed_frame_t *buffer) +{ + uint8_t *ptr = (mac_header_message_start_pointer(buffer) + buffer->mac_header_length + buffer->security_aux_header_length); + + buffer->headerIePtr = NULL; + buffer->headerIeLength = 0; + buffer->payloadsIePtr = NULL; + buffer->payloadsIeLength = 0; + buffer->header_ie_length = 0; + if (!buffer->fcf_dsn.informationElementsPresets) { + buffer->macPayloadPtr = ptr; + return true; + } + + if (buffer->mac_payload_length < 2) { + return false; + } + + mac_header_IE_t header_ie; + buffer->headerIePtr = ptr; + + while (buffer->mac_payload_length >= 2) { + + if (!mac_parse_header_ie(&header_ie, ptr)) { + return false; + } + + buffer->mac_payload_length -= 2; + if (header_ie.length > buffer->mac_payload_length) { + return false; + } + + buffer->mac_payload_length -= header_ie.length; + + buffer->header_ie_length += header_ie.length +2; + ptr += (2 + header_ie.length); + + if (header_ie.id == MAC_HEADER_TERMINATION1_IE_ID) { + break; + } else if (header_ie.id == MAC_HEADER_TERMINATION2_IE_ID) { + buffer->macPayloadPtr = ptr; + return true; + } + buffer->headerIeLength += header_ie.length +2; + } + + return true; +} + + +bool mac_payload_information_elements_parse(mac_pre_parsed_frame_t *buffer) +{ + uint8_t *ptr = (mac_header_message_start_pointer(buffer) + buffer->mac_header_length + buffer->security_aux_header_length + buffer->header_ie_length); + if (!buffer->fcf_dsn.informationElementsPresets) { + return true; + } + + if (buffer->mac_payload_length < 2) { + return false; + } + + //Parse Payload IE + buffer->payloadsIePtr = ptr; + mac_payload_IE_t payload_ie; + while (buffer->mac_payload_length >= 2) { + + if (!mac_parse_payload_ie(&payload_ie, ptr)) { + return false; + } + buffer->mac_payload_length -= 2; + if (payload_ie.length > buffer->mac_payload_length) { + return false; + } + buffer->mac_payload_length -= payload_ie.length; + + if (payload_ie.id == MAC_PAYLOAD_TERMINATION_IE_GROUP_ID) { + break; + } + buffer->payloadsIeLength += payload_ie.length + 2; + buffer->macPayloadPtr += payload_ie.length + 2; + ptr += (2 + payload_ie.length); + + } + buffer->macPayloadPtr = ptr; + return true; +} + + +static uint8_t *mac_header_ie_terimate(uint8_t *ptr, uint8_t type) +{ + uint16_t ie_dummy = 0; + ie_dummy |= (type << 7 ); + return common_write_16_bit_inverse(ie_dummy, ptr); + + +} + +static uint8_t *mac_payload_ie_terimate(uint8_t *ptr) +{ + uint16_t ie_dummy = 0; + ie_dummy |= (MAC_PAYLOAD_TERMINATION_IE_GROUP_ID << 11 ); + ie_dummy |= (1 << 15); + return common_write_16_bit_inverse(ie_dummy, ptr); +} + + +void mac_header_information_elements_preparation(mac_pre_build_frame_t *buffer) +{ + if (buffer->message_builded) { + return; + } + + if (buffer->headerIeLength || buffer->payloadsIeLength) { + buffer->fcf_dsn.frameVersion = MAC_FRAME_VERSION_2015; + buffer->fcf_dsn.informationElementsPresets = true; + buffer->message_builded = true; + //Write Header elements + if (buffer->headerIeLength) { + buffer->mac_header_length_with_security += buffer->headerIeLength; + if (!buffer->payloadsIeLength && !buffer->mac_payload_length) { + //No termination needed + return; + } + //Terminate + buffer->mac_header_length_with_security += 2; + } else { + buffer->mac_header_length_with_security += 2; + } + } +} + +uint16_t mac_buffer_total_payload_length(mac_pre_build_frame_t *buffer) +{ + return mac_payload_length_calc_with_ie(buffer->mac_payload_length, buffer->payloadsIeLength); +} + + +static uint8_t * mac_header_information_elements_write(const mac_pre_build_frame_t *buffer, uint8_t *ptr) +{ + if (buffer->fcf_dsn.frameVersion == MAC_FRAME_VERSION_2015 && buffer->fcf_dsn.informationElementsPresets) { + //Write Header elements + if (buffer->headerIeLength) { + ptr = mac_write_ie_vector_list(buffer->ie_elements.headerIeVectorList, buffer->ie_elements.headerIovLength, ptr); + + if (!buffer->payloadsIeLength && !buffer->mac_payload_length) { + //No termination needed + return ptr; + } else if (!buffer->payloadsIeLength && buffer->mac_payload_length) { + return mac_header_ie_terimate(ptr, MAC_HEADER_TERMINATION2_IE_ID); + } + } + //Add Header Termination + ptr = mac_header_ie_terimate(ptr, MAC_HEADER_TERMINATION1_IE_ID); + + if (buffer->payloadsIeLength) { + ptr = mac_write_ie_vector_list(buffer->ie_elements.payloadIeVectorList, buffer->ie_elements.payloadIovLength, ptr); + if (buffer->mac_payload_length) { + ptr = mac_payload_ie_terimate(ptr); + } + } + } return ptr; } diff --git a/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_header_helper_functions.h b/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_header_helper_functions.h index 5b71c648491d..4231f3982099 100644 --- a/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_header_helper_functions.h +++ b/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_header_helper_functions.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, Arm Limited and affiliates. + * Copyright (c) 2016-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,9 +24,13 @@ struct mlme_security_s; struct mac_pre_parsed_frame_s; struct mac_pre_build_frame; struct mac_aux_security_header_s; +struct ns_ie_iovec; +struct protocol_interface_rf_mac_setup; uint8_t mac_security_mic_length_get(uint8_t security_level); uint8_t mac_header_security_aux_header_length(uint8_t security_level, uint8_t keyIdmode); +bool mac_dst_panid_present(const struct mac_fcf_sequence_s *header); +bool mac_src_panid_present(const struct mac_fcf_sequence_s *header); uint8_t mac_header_address_length(const struct mac_fcf_sequence_s *fcf); void mac_header_security_parameter_set(struct mac_aux_security_header_s *header, const struct mlme_security_s *frame_setup); @@ -34,10 +38,24 @@ void mac_header_security_parameter_set(struct mac_aux_security_header_s *header, /** * MAC layer FCF and data sequence parse from data */ -void mac_header_parse_fcf_dsn(struct mac_fcf_sequence_s *header, const uint8_t *ptr); +const uint8_t * mac_header_parse_fcf_dsn(struct mac_fcf_sequence_s *header, const uint8_t *ptr); + +uint16_t mac_header_off_set_to_aux_header(const struct mac_fcf_sequence_s *fcf); + +void mac_header_security_aux_header_parse(const uint8_t *ptr, struct mlme_security_s *security_params); void mac_header_security_components_read(struct mac_pre_parsed_frame_s *buffer, struct mlme_security_s *security_params); +bool mac_header_information_elements_parse(struct mac_pre_parsed_frame_s *buffer); + +bool mac_payload_information_elements_parse(struct mac_pre_parsed_frame_s *buffer); + +uint16_t mac_header_information_elements_length(struct mac_pre_build_frame *buffer); + +void mac_header_information_elements_preparation(struct mac_pre_build_frame *buffer); + +uint16_t mac_buffer_total_payload_length(struct mac_pre_build_frame *buffer); + /** * Next function should only call when address mode is not MAC_ADDR_MODE_NONE and parsed proper header! */ @@ -45,16 +63,14 @@ uint16_t mac_header_get_src_panid(const struct mac_fcf_sequence_s *header, const uint16_t mac_header_get_dst_panid(const struct mac_fcf_sequence_s *header, const uint8_t *ptr); void mac_header_get_src_address(const struct mac_fcf_sequence_s *header, const uint8_t *ptr, uint8_t *address_ptr); void mac_header_get_dst_address(const struct mac_fcf_sequence_s *header, const uint8_t *ptr, uint8_t *address_ptr); - -uint16_t mcps_payload_length_from_received_frame(const struct mac_pre_parsed_frame_s *buffer); +uint8_t mac_address_length(uint8_t address_mode); uint8_t mcps_mac_header_length_from_received_frame(const struct mac_pre_parsed_frame_s *buffer); uint32_t mcps_mac_security_frame_counter_read(const struct mac_pre_parsed_frame_s *buffer); uint8_t mcps_mac_command_frame_id_get(const struct mac_pre_parsed_frame_s *buffer); uint8_t *mcps_mac_payload_pointer_get(const struct mac_pre_parsed_frame_s *buffer); uint8_t *mcps_security_mic_pointer_get(const struct mac_pre_parsed_frame_s *buffer); -uint8_t *mcps_mac_security_aux_header_start_pointer_get(const struct mac_pre_parsed_frame_s *buffer); - -uint8_t * mcps_generic_header_write(uint8_t *ptr, const struct mac_pre_build_frame *buffer); +/* Write Mac Header and payload */ +uint8_t * mac_generic_packet_write(struct protocol_interface_rf_mac_setup *rf_ptr, uint8_t *ptr, const struct mac_pre_build_frame *buffer); /** get pointer to Mac header start point*/ diff --git a/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_indirect_data.c b/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_indirect_data.c index 153c68ee0935..3820c16e8d26 100644 --- a/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_indirect_data.c +++ b/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_indirect_data.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -55,6 +55,7 @@ void mac_indirect_data_ttl_handle(protocol_interface_rf_mac_setup_s *cur, uint16 if( dev_driver && dev_driver->extension ){ dev_driver->extension(PHY_EXTENSION_CTRL_PENDING_BIT, &value); } + cur->mac_frame_pending = false; return; } mac_pre_build_frame_t *buf, *buf_prev = 0, *buf_temp = 0; @@ -93,7 +94,13 @@ void mac_indirect_data_ttl_handle(protocol_interface_rf_mac_setup_s *cur, uint16 confirm.status = MLME_TRANSACTION_EXPIRED; mcps_sap_prebuild_frame_buffer_free(buf_temp); - if( api->data_conf_cb ) { + + if (cur->mac_extension_enabled) { + mcps_data_conf_payload_t data_conf; + memset(&data_conf, 0, sizeof(mcps_data_conf_payload_t)); + //Check Payload Here + api->data_conf_ext_cb(api, &confirm, &data_conf); + } else { api->data_conf_cb(api, &confirm); } } @@ -216,6 +223,7 @@ void mac_indirect_queue_write(protocol_interface_rf_mac_setup_s *rf_mac_setup, m //Trig timer and set pending flag to radio eventOS_callback_timer_stop(rf_mac_setup->mac_mcps_timer); eventOS_callback_timer_start(rf_mac_setup->mac_mcps_timer, MAC_INDIRECT_TICK_IN_MS * 20); + rf_mac_setup->mac_frame_pending = true; if (rf_mac_setup->dev_driver->phy_driver->extension) { uint8_t value = 1; diff --git a/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_mcps_sap.c b/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_mcps_sap.c index eafdeb6b2533..cfe56837606c 100644 --- a/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_mcps_sap.c +++ b/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_mcps_sap.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -51,6 +51,9 @@ #define TRACE_GROUP "mMCp" +// Used to set TX time (us) with FHSS. Must be <= 65ms. +#define MAC_TX_PROCESSING_DELAY_INITIAL 2000 + typedef struct { uint8_t address[8]; unsigned addr_type:2; @@ -62,13 +65,72 @@ typedef struct { void mcps_sap_pd_req_queue_write(protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_pre_build_frame_t *buffer); static mac_pre_build_frame_t * mcps_sap_pd_req_queue_read(protocol_interface_rf_mac_setup_s *rf_mac_setup, bool is_bc_queue, bool flush); static int8_t mcps_pd_data_request(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer); -static void mcps_data_confirm_handle(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer); +static void mcps_data_confirm_handle(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer, mac_pre_parsed_frame_t *ack_buf); static void mac_set_active_event(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t event_type); static void mac_clear_active_event(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t event_type); static bool mac_read_active_event(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t event_type); +static int8_t mcps_pd_data_cca_trig(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer); static int8_t mac_tasklet_event_handler = -1; +/** + * Get PHY time stamp. + * + * \param rf_mac_setup pointer to MAC + * \return Timestamp from PHY + * + */ +static uint32_t mac_mcps_sap_get_phy_timestamp(protocol_interface_rf_mac_setup_s *rf_mac_setup) +{ + uint32_t timestamp; + rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_GET_TIMESTAMP, (uint8_t *)×tamp); + return timestamp; +} + +static void mac_data_request_init(protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_pre_build_frame_t *buffer) +{ + rf_mac_setup->active_pd_data_request = buffer; + if (buffer->asynch_request) { + buffer->asynch_channel = rf_mac_setup->mac_channel; //Store Original channel + uint16_t channel = mlme_scan_analyze_next_channel(&buffer->asynch_channel_list); + if (channel <= 0xff) { + uint8_t switch_channel = channel; + if (rf_mac_setup->mac_channel != switch_channel) { + mac_mlme_mac_radio_disabled(rf_mac_setup); + rf_mac_setup->mac_channel = channel; + mac_mlme_mac_radio_enable(rf_mac_setup); + } + } + } +} + +static bool mac_data_request_confirmation_finnish(protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_pre_build_frame_t *buffer) +{ + if (!buffer->asynch_request) { + return true; + } + + uint16_t channel = mlme_scan_analyze_next_channel(&buffer->asynch_channel_list); + uint8_t switch_channel; + bool return_value; + + if (channel > 0x00ff) { + return_value = true; + switch_channel = buffer->asynch_channel; + } else { + switch_channel = channel; + return_value = false; + } + //Set original Channel back if channel is switched + if (rf_mac_setup->mac_channel != switch_channel) { + mac_mlme_mac_radio_disabled(rf_mac_setup); + rf_mac_setup->mac_channel = switch_channel; + mac_mlme_mac_radio_enable(rf_mac_setup); + } + return return_value; + +} + static void mac_data_poll_radio_disable_check(protocol_interface_rf_mac_setup_s *rf_mac_setup) { @@ -81,20 +143,79 @@ static void mac_data_poll_radio_disable_check(protocol_interface_rf_mac_setup_s } } -static void mcps_data_confirm_cb(protocol_interface_rf_mac_setup_s *rf_mac_setup, mcps_data_conf_t *confirm) +static void mcps_data_confirm_cb(protocol_interface_rf_mac_setup_s *rf_mac_setup, mcps_data_conf_t *confirm, mac_pre_parsed_frame_t *ack_buf) { mac_data_poll_radio_disable_check(rf_mac_setup); if( get_sw_mac_api(rf_mac_setup) ) { - get_sw_mac_api(rf_mac_setup)->data_conf_cb(get_sw_mac_api(rf_mac_setup), confirm); + if (rf_mac_setup->mac_extension_enabled) { + mcps_data_conf_payload_t data_conf; + memset(&data_conf, 0, sizeof(mcps_data_conf_payload_t)); + if (ack_buf) { + data_conf.payloadIeList = ack_buf->payloadsIePtr; + data_conf.payloadIeListLength = ack_buf->payloadsIeLength; + data_conf.headerIeList = ack_buf->headerIePtr; + data_conf.headerIeListLength = ack_buf->headerIeLength; + data_conf.payloadLength = ack_buf->mac_payload_length; + data_conf.payloadPtr = ack_buf->macPayloadPtr; + } + //Check Payload Here + get_sw_mac_api(rf_mac_setup)->data_conf_ext_cb(get_sw_mac_api(rf_mac_setup), confirm, &data_conf); + } else { + get_sw_mac_api(rf_mac_setup)->data_conf_cb(get_sw_mac_api(rf_mac_setup), confirm); + } } } -void mcps_sap_data_req_handler(protocol_interface_rf_mac_setup_s *rf_mac_setup , const mcps_data_req_t *data_req ) { +void mcps_sap_data_req_handler(protocol_interface_rf_mac_setup_s *rf_mac_setup , const mcps_data_req_t *data_req) +{ + mcps_data_req_ie_list_t ie_list; + memset(&ie_list, 0 , sizeof(mcps_data_req_ie_list_t)); + mcps_sap_data_req_handler_ext(rf_mac_setup, data_req, &ie_list, NULL); +} + +static bool mac_ie_vector_length_validate(ns_ie_iovec_t *ie_vector, uint16_t iov_length, uint16_t *length_out) +{ + if (length_out) { + *length_out = 0; + } + + if (!iov_length) { + return true; + } + + if (iov_length != 0 && !ie_vector) { + return false; + } + + uint16_t msg_length = 0; + ns_ie_iovec_t *msg_iov = ie_vector; + for (uint_fast16_t i = 0; i < iov_length; i++) { + if (msg_iov->iovLen != 0 && !msg_iov->ieBase) { + return false; + } + msg_length += msg_iov->iovLen; + if (msg_length < msg_iov->iovLen) { + return false; + } + msg_iov++; + } + + if (length_out) { + *length_out = msg_length; + } + + return true; + +} + + +void mcps_sap_data_req_handler_ext(protocol_interface_rf_mac_setup_s *rf_mac_setup , const mcps_data_req_t *data_req , const mcps_data_req_ie_list_t *ie_list, const channel_list_s *asynch_channel_list) { uint8_t status = MLME_SUCCESS; mac_pre_build_frame_t *buffer = NULL; + if (!rf_mac_setup->mac_security_enabled) { if (data_req->Key.SecurityLevel) { status = MLME_UNSUPPORTED_SECURITY; @@ -102,12 +223,34 @@ void mcps_sap_data_req_handler(protocol_interface_rf_mac_setup_s *rf_mac_setup , } } - if (data_req->msduLength > rf_mac_setup->dev_driver->phy_driver->phy_MTU - MAC_DATA_PACKET_MIN_HEADER_LENGTH) { + uint16_t ie_header_length = 0; + uint16_t ie_payload_length = 0; + + if (!mac_ie_vector_length_validate(ie_list->headerIeVectorList, ie_list->headerIovLength, &ie_header_length)) { + status = MLME_INVALID_PARAMETER; + goto verify_status; + } + + if (!mac_ie_vector_length_validate(ie_list->payloadIeVectorList, ie_list->payloadIovLength, &ie_payload_length)) { + status = MLME_INVALID_PARAMETER; + goto verify_status; + } + + if ((ie_header_length || ie_payload_length || asynch_channel_list) && !rf_mac_setup->mac_extension_enabled ) { + //Report error when feature is not enaled yet + status = MLME_INVALID_PARAMETER; + goto verify_status; + } else if (asynch_channel_list && data_req->TxAckReq) { + //Report Asynch Message is not allowed to call with ACK requested. + status = MLME_INVALID_PARAMETER; + goto verify_status; + } + + if ((data_req->msduLength + ie_header_length + ie_payload_length) > rf_mac_setup->dev_driver->phy_driver->phy_MTU - MAC_DATA_PACKET_MIN_HEADER_LENGTH) { tr_debug("packet %u, %u",data_req->msduLength, rf_mac_setup->dev_driver->phy_driver->phy_MTU); status = MLME_FRAME_TOO_LONG; goto verify_status; } - //protocol_interface_rf_mac_setup_s *rf_mac_setup = (protocol_interface_rf_mac_setup_s*)api; buffer = mcps_sap_prebuild_frame_buffer_get(0); //tr_debug("Data Req"); if (!buffer) { @@ -121,6 +264,13 @@ void mcps_sap_data_req_handler(protocol_interface_rf_mac_setup_s *rf_mac_setup , tr_debug("Drop MAC tx packet when mac disabled"); goto verify_status; } + + if (asynch_channel_list ) { + //Copy Asynch data list + buffer->asynch_channel_list = *asynch_channel_list; + buffer->asynch_request = true; + } + buffer->upper_layer_request = true; buffer->fcf_dsn.frametype = FC_DATA_FRAME; buffer->fcf_dsn.ackRequested = data_req->TxAckReq; @@ -143,8 +293,8 @@ void mcps_sap_data_req_handler(protocol_interface_rf_mac_setup_s *rf_mac_setup , buffer->fcf_dsn.SrcAddrMode = data_req->SrcAddrMode; buffer->fcf_dsn.framePending = data_req->PendingBit; - if (buffer->fcf_dsn.SrcAddrMode == MAC_ADDR_MODE_NONE) { - if (buffer->fcf_dsn.DstAddrMode == MAC_ADDR_MODE_NONE) { + if (buffer->fcf_dsn.SrcAddrMode == MAC_ADDR_MODE_NONE && !rf_mac_setup->mac_extension_enabled) { + if (buffer->fcf_dsn.DstAddrMode == MAC_ADDR_MODE_NONE ) { status = MLME_INVALID_ADDRESS; goto verify_status; } @@ -158,10 +308,48 @@ void mcps_sap_data_req_handler(protocol_interface_rf_mac_setup_s *rf_mac_setup , mac_frame_src_address_set_from_interface(buffer->fcf_dsn.SrcAddrMode, rf_mac_setup, buffer->SrcAddr); - if (buffer->DstPANId == buffer->SrcPANId) { - buffer->fcf_dsn.intraPan = true; + buffer->ie_elements.headerIeVectorList = ie_list->headerIeVectorList; + buffer->ie_elements.headerIovLength = ie_list->headerIovLength; + buffer->ie_elements.payloadIeVectorList = ie_list->payloadIeVectorList; + buffer->ie_elements.payloadIovLength = ie_list->payloadIovLength; + buffer->headerIeLength = ie_header_length; + buffer->payloadsIeLength = ie_payload_length; + + + if (rf_mac_setup->mac_extension_enabled) { + //Handle mac extension's + buffer->fcf_dsn.frameVersion = MAC_FRAME_VERSION_2015; + if (ie_header_length || ie_payload_length) { + buffer->fcf_dsn.informationElementsPresets = true; + } + + buffer->fcf_dsn.sequenceNumberSuppress = data_req->SeqNumSuppressed; + if (buffer->fcf_dsn.sequenceNumberSuppress) { + buffer->mac_header_length_with_security--; + } + /* PAN-ID compression bit enable when necessary */ + if (buffer->fcf_dsn.SrcAddrMode == MAC_ADDR_MODE_NONE && buffer->fcf_dsn.DstAddrMode == MAC_ADDR_MODE_NONE) { + buffer->fcf_dsn.intraPan = !data_req->PanIdSuppressed; + } else if (buffer->fcf_dsn.DstAddrMode == MAC_ADDR_MODE_NONE) { + buffer->fcf_dsn.intraPan = data_req->PanIdSuppressed; + } else if (buffer->fcf_dsn.SrcAddrMode == MAC_ADDR_MODE_NONE || (buffer->fcf_dsn.SrcAddrMode == MAC_ADDR_MODE_64_BIT && buffer->fcf_dsn.DstAddrMode == MAC_ADDR_MODE_64_BIT)) { + buffer->fcf_dsn.intraPan = data_req->PanIdSuppressed; + } else /* two addresses, at least one address short */ { + // ignore or fault panidsuppressed + if (buffer->DstPANId == buffer->SrcPANId ) { + buffer->fcf_dsn.intraPan = true; + } + } + } else { + /* PAN-ID compression bit enable when necessary */ + if ((buffer->fcf_dsn.DstAddrMode && buffer->fcf_dsn.SrcAddrMode) && (buffer->DstPANId == buffer->SrcPANId)) { + buffer->fcf_dsn.intraPan = true; + } } + //Check PanID presents at header + buffer->fcf_dsn.DstPanPresents = mac_dst_panid_present(&buffer->fcf_dsn); + buffer->fcf_dsn.SrcPanPresents = mac_src_panid_present(&buffer->fcf_dsn); //Calculate address length buffer->mac_header_length_with_security += mac_header_address_length(&buffer->fcf_dsn); buffer->mac_payload = data_req->msdu; @@ -181,7 +369,7 @@ void mcps_sap_data_req_handler(protocol_interface_rf_mac_setup_s *rf_mac_setup , confirm.status = status; tr_debug("DATA REQ Fail %u", status); mcps_sap_prebuild_frame_buffer_free(buffer); - mcps_data_confirm_cb(rf_mac_setup, &confirm); + mcps_data_confirm_cb(rf_mac_setup, &confirm, NULL); } } @@ -200,8 +388,10 @@ static int8_t mac_virtual_data_req_handler(protocol_interface_rf_mac_setup_s *rf } mac_header_parse_fcf_dsn(&buffer->fcf_dsn, data_ptr); + buffer->fcf_dsn.DstPanPresents = mac_dst_panid_present(&buffer->fcf_dsn); + buffer->fcf_dsn.SrcPanPresents = mac_src_panid_present(&buffer->fcf_dsn); // Use MAC sequence as handle - buffer->msduHandle = data_ptr[2]; + buffer->msduHandle = buffer->fcf_dsn.DSN; memcpy(buffer->mac_payload,data_ptr, data_length); buffer->mac_payload_length = data_length; @@ -227,8 +417,8 @@ static int8_t mac_virtual_mlme_nap_req_handler(protocol_interface_rf_mac_setup_s } mlme_scan_t mlme_scan_req; - mlme_scan_req.ScanType = *ptr++; - mlme_scan_req.ScanChannels.channel_page = *ptr++; + mlme_scan_req.ScanType = (mac_scan_type_t) *ptr++; + mlme_scan_req.ScanChannels.channel_page = (channel_page_e) *ptr++; memcpy(mlme_scan_req.ScanChannels.channel_mask, ptr, 32); ptr += 32; mlme_scan_req.ScanDuration = *ptr++; @@ -239,14 +429,13 @@ static int8_t mac_virtual_mlme_nap_req_handler(protocol_interface_rf_mac_setup_s memcpy(mlme_scan_req.Key.Keysource, ptr, 8); mac_mlme_scan_request(&mlme_scan_req, rf_mac_setup); return 0; - break; } case MLME_SET:{ if (mlme_req->ptr_length < 3) { return -1; } mlme_set_t mlme_set_req; - mlme_set_req.attr = *ptr++; + mlme_set_req.attr = (mlme_attr_t) *ptr++; mlme_set_req.attr_index = *ptr++; mlme_set_req.value_pointer = ptr; mlme_set_req.value_size = mlme_req->ptr_length - 2; @@ -338,6 +527,7 @@ static uint8_t mac_data_interface_decrypt_packet(mac_pre_parsed_frame_t *b, mlme mlme_key_device_descriptor_t *key_device_description = NULL; uint8_t device_descriptor_handle; uint8_t openPayloadLength = 0; + bool security_by_pass = false; protocol_interface_rf_mac_setup_s *rf_mac_setup = (protocol_interface_rf_mac_setup_s*)b->mac_class_ptr; // mlme_security_level_descriptor_t security_level_compare; @@ -401,7 +591,12 @@ static uint8_t mac_data_interface_decrypt_packet(mac_pre_parsed_frame_t *b, mlme } else { if (!b->neigh_info) { - return MLME_UNSUPPORTED_SECURITY; + if (rf_mac_setup->mac_security_bypass_unknow_device && (b->fcf_dsn.SrcAddrMode == MAC_ADDR_MODE_64_BIT + && security_params->SecurityLevel > AES_SECURITY_LEVEL_ENC)) { + security_by_pass = true; + } else { + return MLME_UNSUPPORTED_SECURITY; + } } device_descriptor_handle = mac_mib_device_descption_attribute_get_by_descriptor(rf_mac_setup, b->neigh_info); @@ -415,52 +610,57 @@ static uint8_t mac_data_interface_decrypt_packet(mac_pre_parsed_frame_t *b, mlme return MLME_UNAVAILABLE_KEY; } - if (neighbour_validation.frameCounter < b->neigh_info->FrameCounter ) { + if (b->neigh_info && neighbour_validation.frameCounter < b->neigh_info->FrameCounter ) { tr_debug("MLME_COUNTER_ERROR"); return MLME_COUNTER_ERROR; } } key = key_description->Key; - memcpy(neighbour_validation.nonce_ptr, b->neigh_info->ExtAddress, 8); + if (security_by_pass) { + memcpy(neighbour_validation.nonce_ptr, neighbour_validation.address, 8); + } else { + memcpy(neighbour_validation.nonce_ptr, b->neigh_info->ExtAddress, 8); + } - ccm_globals_t *ccm_ptr = ccm_sec_init(security_params->SecurityLevel, key, AES_CCM_DECRYPT, 2); + ccm_globals_t ccm_ptr; - if (!ccm_ptr) { + if (!ccm_sec_init(&ccm_ptr, security_params->SecurityLevel, key, AES_CCM_DECRYPT, 2)) { return MLME_UNSUPPORTED_SECURITY; } - mac_security_interface_aux_ccm_nonce_set(ccm_ptr->exp_nonce, neighbour_validation.nonce_ptr, neighbour_validation.frameCounter, security_params->SecurityLevel); + mac_security_interface_aux_ccm_nonce_set(ccm_ptr.exp_nonce, neighbour_validation.nonce_ptr, neighbour_validation.frameCounter, security_params->SecurityLevel); - if (ccm_ptr->mic_len) { + if (ccm_ptr.mic_len) { // this is asuming that there is no headroom for buffers. - ccm_ptr->adata_len = mcps_mac_header_length_from_received_frame(b) + openPayloadLength; + ccm_ptr.adata_len = mcps_mac_header_length_from_received_frame(b) + openPayloadLength; //SET MIC PTR - ccm_ptr->mic = mcps_security_mic_pointer_get(b); - ccm_ptr->adata_ptr = mac_header_message_start_pointer(b); + ccm_ptr.mic = mcps_security_mic_pointer_get(b); + ccm_ptr.adata_ptr = mac_header_message_start_pointer(b); } - ccm_ptr->data_ptr = (mcps_mac_payload_pointer_get(b) + openPayloadLength); - ccm_ptr->data_len = mcps_payload_length_from_received_frame(b) - openPayloadLength; - if (ccm_process_run(ccm_ptr) != 0) { - tr_warning("MIC Fail adata %s", trace_array(ccm_ptr->adata_ptr, ccm_ptr->adata_len)); - tr_warning("Nonce %s", trace_array(ccm_ptr->exp_nonce, 13)); + ccm_ptr.data_ptr = (mcps_mac_payload_pointer_get(b) + openPayloadLength); + ccm_ptr.data_len = b->mac_payload_length - openPayloadLength; + if (ccm_process_run(&ccm_ptr) != 0) { + tr_warning("MIC Fail adata %s", trace_array(ccm_ptr.adata_ptr, ccm_ptr.adata_len)); + tr_warning("Nonce %s", trace_array(ccm_ptr.exp_nonce, 13)); if (openPayloadLength) { - tr_warning("%s", tr_array(ccm_ptr->data_ptr, ccm_ptr->data_len)); + tr_warning("%s", tr_array(ccm_ptr.data_ptr, ccm_ptr.data_len)); } return MLME_SECURITY_FAIL; } //Update key device and key description tables - - b->neigh_info->FrameCounter = neighbour_validation.frameCounter + 1; - if (!key_device_description) { - // Black list old used keys by this device - mac_sec_mib_device_description_blacklist(rf_mac_setup, device_descriptor_handle); - key_device_description = mac_sec_mib_key_device_description_list_update(key_description); - if (key_device_description) { - tr_debug("Set new device user %u for key", device_descriptor_handle); - key_device_description->DeviceDescriptorHandle = device_descriptor_handle; + if (!security_by_pass) { + b->neigh_info->FrameCounter = neighbour_validation.frameCounter + 1; + if (!key_device_description) { + // Black list old used keys by this device + mac_sec_mib_device_description_blacklist(rf_mac_setup, device_descriptor_handle); + key_device_description = mac_sec_mib_key_device_description_list_update(key_description); + if (key_device_description) { + tr_debug("Set new device user %u for key", device_descriptor_handle); + key_device_description->DeviceDescriptorHandle = device_descriptor_handle; + } } } @@ -531,22 +731,27 @@ static int8_t mac_data_sap_rx_handler(mac_pre_parsed_frame_t *buf, protocol_inte data_ind->mpduLinkQuality = buf->LQI; data_ind->signal_dbm = buf->dbm; + data_ind->timestamp = buf->timestamp; /* Parse security part */ mac_header_security_components_read(buf, &data_ind->Key); - data_ind->msduLength = buf->mac_payload_length; - data_ind->msdu_ptr = mcps_mac_payload_pointer_get(buf); - - buf->neigh_info = mac_sec_mib_device_description_get(rf_mac_setup, data_ind->SrcAddr, data_ind->SrcAddrMode); if (buf->fcf_dsn.securityEnabled) { status = mac_data_interface_decrypt_packet(buf, &data_ind->Key); if (status != MLME_SUCCESS) { + tr_debug("Decrypt fail, %d", status); mcps_comm_status_indication_generate(status, buf, mac); goto DROP_PACKET; } } + if (!mac_payload_information_elements_parse(buf)) { + tr_debug("Drop by Paylod IE"); + goto DROP_PACKET; + } + data_ind->msduLength = buf->mac_payload_length; + data_ind->msdu_ptr = buf->macPayloadPtr; + /* Validate Polling device */ if (!rf_mac_setup->macCapRxOnIdle) { if (mac_data_interface_host_accept_data(data_ind, rf_mac_setup) != 0) { @@ -556,7 +761,22 @@ static int8_t mac_data_sap_rx_handler(mac_pre_parsed_frame_t *buf, protocol_inte } if (mac) { - mac->data_ind_cb(mac, data_ind); + + if (buf->fcf_dsn.frameVersion == MAC_FRAME_VERSION_2015) { + if (!rf_mac_setup->mac_extension_enabled) { + tr_debug("No Ext reg"); + goto DROP_PACKET; + } + mcps_data_ie_list_t ie_list; + ie_list.payloadIeList = buf->payloadsIePtr; + ie_list.payloadIeListLength = buf->payloadsIeLength; + ie_list.headerIeList = buf->headerIePtr; + ie_list.headerIeListLength = buf->headerIeLength; + mac->data_ind_ext_cb(mac, data_ind, &ie_list); + + } else { + mac->data_ind_cb(mac, data_ind); + } retval = 0; } @@ -586,6 +806,10 @@ static void mac_lib_res_no_data_to_req(mac_pre_parsed_frame_t *buffer, protocol_ buf->fcf_dsn.intraPan = true; buf->fcf_dsn.ackRequested = true; buf->mac_header_length_with_security = 3; + //Check PanID presents at header + buf->fcf_dsn.DstPanPresents = mac_dst_panid_present(&buf->fcf_dsn); + buf->fcf_dsn.SrcPanPresents = mac_src_panid_present(&buf->fcf_dsn); + if (buffer->fcf_dsn.securityEnabled) { buf->fcf_dsn.frameVersion = MAC_FRAME_VERSION_2006; buf->aux_header.securityLevel = rf_mac_setup->mac_auto_request.SecurityLevel; @@ -649,7 +873,6 @@ static int8_t mac_command_sap_rx_handler(mac_pre_parsed_frame_t *buf, protocol_i case MAC_DATA_REQ: //Here 2 check if (mac_indirect_data_req_handle(buf, rf_mac_setup) == 0) { - tr_debug("Trig Dummy packet"); mac_lib_res_no_data_to_req(buf, rf_mac_setup); } retval = 0; @@ -695,11 +918,16 @@ static void mac_data_interface_parse_beacon(mac_pre_parsed_frame_t *buf, protoco return; } + if (!mac_payload_information_elements_parse(buf)) { + tr_debug("Drop by Paylod IE"); + return; + } + /*Add received bytes in statistics*/ tr_debug("mac_parse_beacon"); - ptr = mcps_mac_payload_pointer_get(buf); - len = mcps_payload_length_from_received_frame(buf); + ptr = buf->macPayloadPtr; + len = buf->mac_payload_length; SuperframeSpec[0] = *ptr++; SuperframeSpec[1] = *ptr++; gts_spec.description_count = (*ptr & 7); @@ -836,10 +1064,10 @@ void mac_mcps_trig_buffer_from_queue(protocol_interface_rf_mac_setup_s *rf_mac_s buffer = mcps_sap_pd_req_queue_read(rf_mac_setup, is_bc_queue, false); if (buffer) { - rf_mac_setup->active_pd_data_request = buffer; + mac_data_request_init(rf_mac_setup, buffer); if (mcps_pd_data_request(rf_mac_setup, buffer) != 0) { rf_mac_setup->active_pd_data_request = NULL; - mcps_data_confirm_handle(rf_mac_setup, buffer); + mcps_data_confirm_handle(rf_mac_setup, buffer, NULL); } else { return; } @@ -849,19 +1077,89 @@ void mac_mcps_trig_buffer_from_queue(protocol_interface_rf_mac_setup_s *rf_mac_s } } + +static int8_t mac_ack_sap_rx_handler(mac_pre_parsed_frame_t *buf, protocol_interface_rf_mac_setup_s *rf_mac_setup) +{ + //allocate Data ind primitiv and parse packet to that + mlme_security_t key; + uint8_t SrcAddr[8]; /**< Source address */ + memset(SrcAddr, 0, 8); + memset(&key, 0, sizeof(mlme_security_t)); + mac_header_get_src_address(&buf->fcf_dsn, mac_header_message_start_pointer(buf), SrcAddr); + /* Parse security part */ + mac_header_security_components_read(buf, &key); + + buf->neigh_info = mac_sec_mib_device_description_get(rf_mac_setup, SrcAddr, buf->fcf_dsn.SrcAddrMode); + if (buf->fcf_dsn.securityEnabled) { + uint8_t status = mac_data_interface_decrypt_packet(buf, &key); + if (status != MLME_SUCCESS) { + tr_debug("ACK Decrypt fail"); + return -1; + } + } + + if (buf->mac_payload_length && !mac_payload_information_elements_parse(buf)) { + tr_debug("Drop ACK by Paylod IE"); + return -1; + } + + return 0; +} + static void mac_pd_data_confirm_handle(protocol_interface_rf_mac_setup_s *rf_mac_setup) { + if (rf_mac_setup->active_pd_data_request) { + mac_pre_build_frame_t *buffer = rf_mac_setup->active_pd_data_request; + if (mac_data_request_confirmation_finnish(rf_mac_setup, buffer) ) { + rf_mac_setup->active_pd_data_request = NULL; + if (buffer->asynch_request && rf_mac_setup->fhss_api) { + // Must return to scheduled channel after asynch process by calling TX done + rf_mac_setup->fhss_api->data_tx_done(rf_mac_setup->fhss_api, false, true, buffer->msduHandle); + } + mcps_data_confirm_handle(rf_mac_setup, buffer, NULL); + } else { + if (mcps_pd_data_request(rf_mac_setup, buffer) != 0) { + rf_mac_setup->active_pd_data_request = NULL; + mcps_data_confirm_handle(rf_mac_setup, buffer, NULL); + } else { + return; + } + } + } + + mac_mcps_trig_buffer_from_queue(rf_mac_setup); +} + + +static void mac_pd_data_ack_handler(mac_pre_parsed_frame_t *buf) { + + protocol_interface_rf_mac_setup_s *rf_mac_setup = buf->mac_class_ptr; + if (!rf_mac_setup->active_pd_data_request) { - tr_debug("No pending TX process anymore"); + mcps_sap_pre_parsed_frame_buffer_free(buf); } else { mac_pre_build_frame_t *buffer = rf_mac_setup->active_pd_data_request; + + if (mac_ack_sap_rx_handler(buf, rf_mac_setup)) { + //Do not forward ACK payload but Accept ACK + mcps_sap_pre_parsed_frame_buffer_free(buf); + buf = NULL; + } + rf_mac_setup->active_pd_data_request = NULL; - mcps_data_confirm_handle(rf_mac_setup, buffer); + if (buffer->asynch_request && rf_mac_setup->fhss_api) { + // Must return to scheduled channel after asynch process by calling TX done + rf_mac_setup->fhss_api->data_tx_done(rf_mac_setup->fhss_api, false, true, buffer->msduHandle); + } + mcps_data_confirm_handle(rf_mac_setup, buffer, buf); + mcps_sap_pre_parsed_frame_buffer_free(buf); + } mac_mcps_trig_buffer_from_queue(rf_mac_setup); } + static void mac_mcps_sap_data_tasklet(arm_event_s *event) { uint8_t event_type = event->event_type; @@ -879,6 +1177,10 @@ static void mac_mcps_sap_data_tasklet(arm_event_s *event) mac_pd_data_confirm_handle((protocol_interface_rf_mac_setup_s*)event->data_ptr); break; + case MCPS_SAP_DATA_ACK_CNF_EVENT: + mac_pd_data_ack_handler((mac_pre_parsed_frame_t*)event->data_ptr); + break; + case MAC_MLME_EVENT_HANDLER: mac_mlme_event_cb(event->data_ptr); break; @@ -944,7 +1246,7 @@ void mcps_sap_prebuild_frame_buffer_free(mac_pre_build_frame_t *buffer) } -static ccm_globals_t * mac_frame_security_parameters_init(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer) +static bool mac_frame_security_parameters_init(ccm_globals_t *ccm_ptr, protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer) { /* Encrypt the packet payload if AES encyption bit is set */ mlme_security_t key_source; @@ -956,7 +1258,7 @@ static ccm_globals_t * mac_frame_security_parameters_init(protocol_interface_rf_ if (!key_description ) { buffer->status = MLME_UNAVAILABLE_KEY; - return NULL; + return false; } mlme_device_descriptor_t *device_description; @@ -967,7 +1269,7 @@ static ccm_globals_t * mac_frame_security_parameters_init(protocol_interface_rf_ if (!device_description) { buffer->status = MLME_UNAVAILABLE_KEY; - return NULL; + return false; } nonce_ext_64_ptr = device_description->ExtAddress; } else { @@ -976,8 +1278,13 @@ static ccm_globals_t * mac_frame_security_parameters_init(protocol_interface_rf_ device_description = mac_sec_mib_device_description_get(rf_ptr, buffer->DstAddr, buffer->fcf_dsn.DstAddrMode); if (!device_description) { - buffer->status = MLME_UNAVAILABLE_KEY; - return NULL; + if (rf_ptr->mac_security_bypass_unknow_device && (buffer->fcf_dsn.SrcAddrMode == MAC_ADDR_MODE_64_BIT + && buffer->aux_header.securityLevel > AES_SECURITY_LEVEL_ENC)) { + + } else { + buffer->status = MLME_UNAVAILABLE_KEY; + return false; + } } } nonce_ext_64_ptr = rf_ptr->mac64; @@ -985,26 +1292,20 @@ static ccm_globals_t * mac_frame_security_parameters_init(protocol_interface_rf_ uint8_t *key_ptr = key_description->Key; - //Remember to update security counter here! - buffer->aux_header.frameCounter = rf_ptr->security_frame_counter; - //Check If frame counter overflow is coming if (buffer->aux_header.frameCounter == 0xffffffff) { buffer->status = MLME_COUNTER_ERROR; - return NULL; + return false; } - ccm_globals_t *ccm_ptr = ccm_sec_init(buffer->aux_header.securityLevel, key_ptr, AES_CCM_ENCRYPT, 2); - if (!ccm_ptr) { + if (!ccm_sec_init(ccm_ptr, buffer->aux_header.securityLevel, key_ptr, AES_CCM_ENCRYPT, 2)) { buffer->status = MLME_SECURITY_FAIL; - return NULL; + return false; } mac_security_interface_aux_ccm_nonce_set(ccm_ptr->exp_nonce, nonce_ext_64_ptr, buffer->aux_header.frameCounter, buffer->aux_header.securityLevel); - //Increment security counter - rf_ptr->security_frame_counter++; - return ccm_ptr; + return true; } @@ -1113,7 +1414,7 @@ static void mac_data_interface_internal_tx_confirm_handle(protocol_interface_rf_ } -static void mcps_data_confirm_handle(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer) { +static void mcps_data_confirm_handle(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer, mac_pre_parsed_frame_t *ack_buf) { sw_mac_stats_update(rf_ptr, STAT_MAC_TX_CCA_ATT, rf_ptr->mac_tx_status.cca_cnt); sw_mac_stats_update(rf_ptr, STAT_MAC_TX_RETRY, rf_ptr->mac_tx_status.retry); @@ -1123,7 +1424,6 @@ static void mcps_data_confirm_handle(protocol_interface_rf_mac_setup_s *rf_ptr, if ((rf_ptr->mac_tx_result == MAC_TX_FAIL) || (rf_ptr->mac_tx_result == MAC_CCA_FAIL)) { if (rf_ptr->fhss_api->data_tx_fail(rf_ptr->fhss_api, buffer->msduHandle, mac_convert_frame_type_to_fhss(buffer->fcf_dsn.frametype)) == true) { mcps_sap_pd_req_queue_write(rf_ptr, buffer); - tr_debug("Channel retry, TX result: %u, handle: %u", rf_ptr->mac_tx_result, buffer->msduHandle); return; } } @@ -1133,12 +1433,16 @@ static void mcps_data_confirm_handle(protocol_interface_rf_mac_setup_s *rf_ptr, mac_common_data_confirmation_handle(rf_ptr, buffer); confirm.msduHandle = buffer->msduHandle; confirm.status = buffer->status; - confirm.timestamp = 0; + if (ack_buf) { + confirm.timestamp = ack_buf->timestamp; + } else { + confirm.timestamp = 0; + } if (buffer->upper_layer_request) { //Check tunnel mcps_sap_prebuild_frame_buffer_free(buffer); - mcps_data_confirm_cb(rf_ptr, &confirm); + mcps_data_confirm_cb(rf_ptr, &confirm, ack_buf); } else { mac_data_interface_internal_tx_confirm_handle(rf_ptr, buffer); } @@ -1163,127 +1467,395 @@ static void mac_security_authentication_data_params_set(ccm_globals_t *ccm_ptr, } } -static uint8_t *mac_security_interface_aux_security_header_write(uint8_t *ptr, const mac_aux_security_header_t *auxHeader) +static uint32_t mcps_calculate_tx_time(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint32_t time_to_tx) { - uint8_t auxBaseHeader; - auxBaseHeader = auxHeader->securityLevel; - auxBaseHeader |= (auxHeader->KeyIdMode << 3); - *ptr++ = auxBaseHeader; - ptr = common_write_32_bit_inverse(auxHeader->frameCounter, ptr); - - switch (auxHeader->KeyIdMode) { - case MAC_KEY_ID_MODE_SRC8_IDX: - memcpy(ptr, auxHeader->Keysource, 8); - ptr += 8; - *ptr++ = auxHeader->KeyIndex; - break; - case MAC_KEY_ID_MODE_SRC4_IDX: - memcpy(ptr, auxHeader->Keysource, 4); - ptr += 4; - *ptr++ = auxHeader->KeyIndex; - break; - case MAC_KEY_ID_MODE_IDX: - *ptr++ = auxHeader->KeyIndex; - break; - default: - break; + // Max. time to TX is 65ms + if (time_to_tx > 65000) { + time_to_tx = 65000; + } + return mac_mcps_sap_get_phy_timestamp(rf_mac_setup) + time_to_tx; +} + +static void mcps_generic_sequence_number_allocate(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer) +{ + if (buffer->fcf_dsn.frameVersion < MAC_FRAME_VERSION_2015 || (buffer->fcf_dsn.frameVersion == MAC_FRAME_VERSION_2015 && !buffer->fcf_dsn.sequenceNumberSuppress)) { + /* Allocate SQN */ + switch (buffer->fcf_dsn.frametype) { + case MAC_FRAME_CMD: + case MAC_FRAME_DATA: + buffer->fcf_dsn.DSN = mac_mlme_set_new_sqn(rf_ptr); + break; + case MAC_FRAME_BEACON: + buffer->fcf_dsn.DSN = mac_mlme_set_new_beacon_sqn(rf_ptr); + break; + default: + break; + } } - return ptr; } -static int8_t mcps_generic_packet_build(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer) { +static uint32_t mcps_generic_backoff_calc(protocol_interface_rf_mac_setup_s *rf_ptr) +{ + uint32_t random_period = mac_csma_backoff_get(rf_ptr); + if (rf_ptr->rf_csma_extension_supported) { + return mcps_calculate_tx_time(rf_ptr, random_period); + } + return random_period; +} + +static int8_t mcps_generic_packet_build(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer) +{ phy_device_driver_s *dev_driver = rf_ptr->dev_driver->phy_driver; dev_driver_tx_buffer_s *tx_buf = &rf_ptr->dev_driver_tx_buffer; - uint8_t open_payload = 0; - uint8_t *ptr; - ccm_globals_t *ccm_ptr = NULL; + + ccm_globals_t ccm_ptr; if (buffer->mac_header_length_with_security == 0) { rf_ptr->mac_tx_status.length = buffer->mac_payload_length; - ptr = tx_buf->buf; + uint8_t *ptr = tx_buf->buf; if (dev_driver->phy_header_length) { ptr += dev_driver->phy_header_length; } tx_buf->len = buffer->mac_payload_length; memcpy(ptr, buffer->mac_payload, buffer->mac_payload_length ); + buffer->tx_time = mcps_generic_backoff_calc(rf_ptr); return 0; } - if (buffer->fcf_dsn.frametype != FC_DATA_FRAME) { - open_payload = 1; - } + //This will prepare MHR length with Header IE + mac_header_information_elements_preparation(buffer); - if (buffer->fcf_dsn.frametype == MAC_FRAME_BEACON) { - buffer->fcf_dsn.DSN = mac_mlme_set_new_beacon_sqn(rf_ptr); - } else { - buffer->fcf_dsn.DSN = mac_mlme_set_new_sqn(rf_ptr); - } + mcps_generic_sequence_number_allocate(rf_ptr, buffer); if (buffer->fcf_dsn.securityEnabled) { - ccm_ptr = mac_frame_security_parameters_init(rf_ptr, buffer); - if ( !ccm_ptr) { + //Remember to update security counter here! + buffer->aux_header.frameCounter = mac_mlme_framecounter_get(rf_ptr); + if (!mac_frame_security_parameters_init(&ccm_ptr, rf_ptr, buffer)) { return -2; } + //Increment security counter + mac_mlme_framecounter_increment(rf_ptr); + } - if (buffer->mac_payload_length > MAC_IEEE_802_15_4_MAX_MAC_SAFE_PAYLOAD_SIZE && + //Calculate Payload length here with IE extension + uint16_t frame_length = mac_buffer_total_payload_length(buffer); + //Storage Mac Payload length here + uint16_t mac_payload_length = frame_length; + + if (mac_payload_length > MAC_IEEE_802_15_4_MAX_MAC_SAFE_PAYLOAD_SIZE && dev_driver->phy_MTU == MAC_IEEE_802_15_4_MAX_PHY_PACKET_SIZE) { /* IEEE 802.15.4-2003 only allowed unsecured payloads up to 102 bytes * (always leaving room for maximum MAC overhead). * IEEE 802.15.4-2006 allows bigger if MAC header is small enough, but * we have to set the version field. */ - buffer->fcf_dsn.frameVersion = MAC_FRAME_VERSION_2006; + if (buffer->fcf_dsn.frameVersion < MAC_FRAME_VERSION_2006) { + buffer->fcf_dsn.frameVersion = MAC_FRAME_VERSION_2006; + } } - //Frame length - uint16_t frame_length = buffer->mac_header_length_with_security + buffer->mac_payload_length + buffer->security_mic_len; + + if (rf_ptr->mac_ack_tx_active) { + if (buffer->fcf_dsn.securityEnabled) { + ccm_free(&ccm_ptr); + } + return 0; + } + + //Add MHR length to total length + frame_length += buffer->mac_header_length_with_security + buffer->security_mic_len; if ((frame_length) > dev_driver->phy_MTU - 2) { - tr_debug("Too Long %u, %u pa %u header %u mic",frame_length, buffer->mac_payload_length, buffer->mac_header_length_with_security, buffer->security_mic_len); + tr_debug("Too Long %u, %u pa %u header %u mic %u",frame_length, mac_payload_length, buffer->mac_header_length_with_security, buffer->security_mic_len, dev_driver->phy_MTU); buffer->status = MLME_FRAME_TOO_LONG; + //decrement security counter + mac_mlme_framecounter_decrement(rf_ptr); return -1; } rf_ptr->mac_tx_status.length = frame_length; - ptr = tx_buf->buf; + uint8_t *ptr = tx_buf->buf; if (dev_driver->phy_header_length) { ptr += dev_driver->phy_header_length; } + tx_buf->len = frame_length; + uint8_t *mhr_start = ptr; + buffer->tx_time = mcps_generic_backoff_calc(rf_ptr); + + ptr = mac_generic_packet_write(rf_ptr, ptr, buffer); - ptr = mcps_generic_header_write(ptr, buffer); if (buffer->fcf_dsn.securityEnabled) { - ptr = mac_security_interface_aux_security_header_write(ptr, &buffer->aux_header); - ccm_ptr->data_len = (buffer->mac_payload_length - open_payload); - ccm_ptr->data_ptr = ptr + open_payload; - mac_security_data_params_set(ccm_ptr, (ptr + open_payload), (buffer->mac_payload_length - open_payload)); - mac_security_authentication_data_params_set(ccm_ptr, (ptr - buffer->mac_header_length_with_security), (buffer->mac_header_length_with_security +open_payload)); - //Copy Payload - memcpy(ptr, buffer->mac_payload, buffer->mac_payload_length); - ccm_process_run(ccm_ptr); + uint8_t open_payload = 0; + if (buffer->fcf_dsn.frametype == MAC_FRAME_CMD) { + open_payload = 1; + } + mac_security_data_params_set(&ccm_ptr, (mhr_start + (buffer->mac_header_length_with_security + open_payload)), (mac_payload_length - open_payload)); + mac_security_authentication_data_params_set(&ccm_ptr, mhr_start, (buffer->mac_header_length_with_security +open_payload)); + ccm_process_run(&ccm_ptr); + } + + return 0; +} + + +int8_t mcps_generic_ack_build(protocol_interface_rf_mac_setup_s *rf_ptr, const mac_fcf_sequence_t *fcf, const uint8_t *data_ptr, const mcps_ack_data_payload_t *ack_payload, uint32_t rx_time) +{ + phy_device_driver_s *dev_driver = rf_ptr->dev_driver->phy_driver; + dev_driver_tx_buffer_s *tx_buf = &rf_ptr->dev_driver_tx_buffer; + + ccm_globals_t ccm_ptr; + + mac_pre_build_frame_t pd_act_buf; + mac_pre_build_frame_t *buffer = &pd_act_buf; + memset(buffer, 0, sizeof(mac_pre_build_frame_t)); + buffer->fcf_dsn.frametype = FC_ACK_FRAME; + buffer->fcf_dsn.frameVersion = fcf->frameVersion; + buffer->fcf_dsn.framePending = rf_ptr->mac_frame_pending; + buffer->fcf_dsn.DSN = fcf->DSN; + buffer->fcf_dsn.sequenceNumberSuppress = fcf->sequenceNumberSuppress; + buffer->fcf_dsn.DstPanPresents = fcf->DstPanPresents; + buffer->fcf_dsn.SrcAddrMode = fcf->DstAddrMode; + buffer->fcf_dsn.SrcPanPresents = fcf->SrcPanPresents; + buffer->fcf_dsn.DstAddrMode = fcf->SrcAddrMode; + if (buffer->fcf_dsn.sequenceNumberSuppress) { + buffer->mac_header_length_with_security = 2; } else { - //Copy Payload + buffer->mac_header_length_with_security = 3; + } + + buffer->mac_header_length_with_security += mac_header_address_length(&buffer->fcf_dsn); + + buffer->DstPANId = mac_header_get_src_panid(fcf, data_ptr); + buffer->SrcPANId = mac_header_get_dst_panid(fcf, data_ptr); + + mac_header_get_src_address(fcf, data_ptr, buffer->DstAddr); + mac_header_get_dst_address(fcf, data_ptr, buffer->SrcAddr); + + //Security + buffer->fcf_dsn.securityEnabled = fcf->securityEnabled; + if (buffer->fcf_dsn.securityEnabled ) { + //Read Security AUX headers + const uint8_t *ptr = data_ptr; + ptr += mac_header_off_set_to_aux_header(fcf); + //Start parsing AUX header + mlme_security_t aux_parse; + mac_header_security_aux_header_parse(ptr, &aux_parse); + buffer->aux_header.KeyIdMode = aux_parse.KeyIdMode; + buffer->aux_header.KeyIndex = aux_parse.KeyIndex; + buffer->aux_header.securityLevel = aux_parse.SecurityLevel; + memcpy(buffer->aux_header.Keysource, aux_parse.Keysource, 8); + + buffer->security_mic_len = mac_security_mic_length_get(buffer->aux_header.securityLevel); + buffer->fcf_dsn.frameVersion = MAC_FRAME_VERSION_2006; + buffer->mac_header_length_with_security += mac_header_security_aux_header_length(buffer->aux_header.securityLevel, buffer->aux_header.KeyIdMode); + + } + + + //TODO Request Application data to ACK + uint16_t ie_header_length = 0; + uint16_t ie_payload_length = 0; + + if (!mac_ie_vector_length_validate(ack_payload->ie_elements.headerIeVectorList, ack_payload->ie_elements.headerIovLength, &ie_header_length)) { + return -1; + } + + if (!mac_ie_vector_length_validate(ack_payload->ie_elements.payloadIeVectorList, ack_payload->ie_elements.payloadIovLength, &ie_payload_length)) { + return -1; + } + + buffer->ie_elements.headerIeVectorList = ack_payload->ie_elements.headerIeVectorList; + buffer->ie_elements.headerIovLength = ack_payload->ie_elements.headerIovLength; + buffer->ie_elements.payloadIeVectorList = ack_payload->ie_elements.payloadIeVectorList; + buffer->ie_elements.payloadIovLength = ack_payload->ie_elements.payloadIovLength; + buffer->headerIeLength = ie_header_length; + buffer->payloadsIeLength = ie_payload_length; + buffer->mac_payload = ack_payload->payloadPtr; + buffer->mac_payload_length = ack_payload->payloadLength; + + //This will prepare MHR length with Header IE + mac_header_information_elements_preparation(buffer); + + if (buffer->fcf_dsn.securityEnabled) { + //Remember to update security counter here! + buffer->aux_header.frameCounter = mac_mlme_framecounter_get(rf_ptr); + if ( !mac_frame_security_parameters_init(&ccm_ptr, rf_ptr, buffer)) { + return -2; + } + //Increment security counter + mac_mlme_framecounter_increment(rf_ptr); + } + + //Calculate Payload length here with IE extension + uint16_t frame_length = mac_buffer_total_payload_length(buffer); + //Storage Mac Payload length here + uint16_t mac_payload_length = frame_length; + + //Add MHR length to total length + frame_length += buffer->mac_header_length_with_security + buffer->security_mic_len; + if ((frame_length) > dev_driver->phy_MTU - 2) { + buffer->status = MLME_FRAME_TOO_LONG; + + if (buffer->fcf_dsn.securityEnabled) { + //decrement security counter + mac_mlme_framecounter_decrement(rf_ptr); + ccm_free(&ccm_ptr); + } + return -1; + } + + rf_ptr->mac_tx_status.length = frame_length; + uint8_t *ptr = tx_buf->buf; + if (dev_driver->phy_header_length) { + ptr += dev_driver->phy_header_length; + } + + tx_buf->len = frame_length; + uint8_t *mhr_start = ptr; + buffer->tx_time = rx_time + 196; //Send 196 us later + + ptr = mac_generic_packet_write(rf_ptr, ptr, buffer); + + + if (buffer->fcf_dsn.securityEnabled) { + mac_security_data_params_set(&ccm_ptr, (mhr_start + (buffer->mac_header_length_with_security )), (mac_payload_length )); + mac_security_authentication_data_params_set(&ccm_ptr, mhr_start, (buffer->mac_header_length_with_security)); + ccm_process_run(&ccm_ptr); + } + //Disable TX Time + phy_csma_params_t csma_params; + csma_params.backoff_time = 0; + csma_params.cca_enabled = false; + rf_ptr->dev_driver->phy_driver->extension(PHY_EXTENSION_SET_CSMA_PARAMETERS, (uint8_t*) &csma_params); + if (rf_ptr->active_pd_data_request) { + mac_pd_sap_set_phy_tx_time(rf_ptr, 0, false); + } + + return mcps_pd_data_cca_trig(rf_ptr, buffer); +} + + +static int8_t mcps_generic_packet_rebuild(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer) +{ + phy_device_driver_s *dev_driver = rf_ptr->dev_driver->phy_driver; + dev_driver_tx_buffer_s *tx_buf = &rf_ptr->dev_driver_tx_buffer; + ccm_globals_t ccm_ptr; + + if (!buffer) { + return -1; + } + + if (buffer->mac_header_length_with_security == 0) { + rf_ptr->mac_tx_status.length = buffer->mac_payload_length; + uint8_t *ptr = tx_buf->buf; + if (dev_driver->phy_header_length) { + ptr += dev_driver->phy_header_length; + } + tx_buf->len = buffer->mac_payload_length; + memcpy(ptr, buffer->mac_payload, buffer->mac_payload_length ); + buffer->tx_time = mcps_generic_backoff_calc(rf_ptr); + return 0; + } + + if (buffer->fcf_dsn.securityEnabled) { + if ( !mac_frame_security_parameters_init(&ccm_ptr, rf_ptr, buffer)) { + return -2; + } + } + + //Calculate Payload length here with IE extension + uint16_t frame_length = mac_buffer_total_payload_length(buffer); + //Storage Mac Payload length here + uint16_t mac_payload_length = frame_length; + + //Add MHR length to total length + frame_length += buffer->mac_header_length_with_security + buffer->security_mic_len; + + rf_ptr->mac_tx_status.length = frame_length; + uint8_t *ptr = tx_buf->buf; + if (dev_driver->phy_header_length) { + ptr += dev_driver->phy_header_length; + } + + tx_buf->len = frame_length; + uint8_t *mhr_start = ptr; + + buffer->tx_time = mcps_generic_backoff_calc(rf_ptr); + + ptr = mac_generic_packet_write(rf_ptr, ptr, buffer); + + if (buffer->fcf_dsn.securityEnabled) { + uint8_t open_payload = 0; + if (buffer->fcf_dsn.frametype == MAC_FRAME_CMD) { + open_payload = 1; + } + mac_security_data_params_set(&ccm_ptr, (mhr_start + (buffer->mac_header_length_with_security + open_payload)), (mac_payload_length - open_payload)); + mac_security_authentication_data_params_set(&ccm_ptr, mhr_start, (buffer->mac_header_length_with_security +open_payload)); + ccm_process_run(&ccm_ptr); } + + return 0; +} + +static int8_t mcps_pd_data_cca_trig(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer) +{ + mac_mlme_mac_radio_enable(rf_ptr); + rf_ptr->macTxProcessActive = true; + if (rf_ptr->rf_csma_extension_supported) { + //Write TX time + bool cca_enabled; + if (buffer->fcf_dsn.frametype == MAC_FRAME_ACK) { + cca_enabled = false; + } else { + cca_enabled = true; + } + mac_pd_sap_set_phy_tx_time(rf_ptr, buffer->tx_time, cca_enabled); + if (mac_plme_cca_req(rf_ptr) != 0) { + rf_ptr->macTxProcessActive = false; + return -1; + } + } else { + timer_mac_start(rf_ptr, MAC_TIMER_CCA, (uint16_t)(buffer->tx_time / 50)); + } + return 0; } static int8_t mcps_pd_data_request(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer) { rf_ptr->macTxRequestAck = false; + + memset(&(rf_ptr->mac_tx_status), 0, sizeof(mac_tx_status_t)); + rf_ptr->mac_cca_retry = 0; + rf_ptr->mac_tx_retry = 0; + mac_csma_param_init(rf_ptr); if (mcps_generic_packet_build(rf_ptr, buffer) != 0) { return -1; } rf_ptr->macTxRequestAck = buffer->fcf_dsn.ackRequested; + if (!rf_ptr->mac_ack_tx_active) { + return mcps_pd_data_cca_trig(rf_ptr, buffer); + } else { + return 0; + } - mac_mlme_mac_radio_enable(rf_ptr); - /* Trig MAC TX */ - return mac_pd_sap_req(rf_ptr); } +int8_t mcps_pd_data_rebuild(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer) +{ + if (mcps_generic_packet_rebuild(rf_ptr, buffer) != 0) { + return -1; + } + + return mcps_pd_data_cca_trig(rf_ptr, buffer); +} + + bool mac_is_ack_request_set(mac_pre_build_frame_t *buffer) { return buffer->fcf_dsn.ackRequested; @@ -1310,15 +1882,16 @@ void mcps_sap_pd_req_queue_write(protocol_interface_rf_mac_setup_s *rf_mac_setup if ((rf_mac_setup->macBroadcastDisabled == true) && !mac_is_ack_request_set(buffer)) { goto push_to_queue; } - if (rf_mac_setup->fhss_api) { + if (rf_mac_setup->fhss_api && (buffer->asynch_request == false)) { + uint16_t frame_length = buffer->mac_payload_length + buffer->headerIeLength + buffer->payloadsIeLength; if (rf_mac_setup->fhss_api->check_tx_conditions(rf_mac_setup->fhss_api, !mac_is_ack_request_set(buffer), - buffer->msduHandle, mac_convert_frame_type_to_fhss(buffer->fcf_dsn.frametype), buffer->mac_payload_length, - rf_mac_setup->dev_driver->phy_driver->phy_header_length, rf_mac_setup->dev_driver->phy_driver->phy_tail_length) == false) { + buffer->msduHandle, mac_convert_frame_type_to_fhss(buffer->fcf_dsn.frametype), frame_length, + rf_mac_setup->dev_driver->phy_driver->phy_header_length, rf_mac_setup->dev_driver->phy_driver->phy_tail_length) == false) { goto push_to_queue; } } //Start TX process immediately - rf_mac_setup->active_pd_data_request = buffer; + mac_data_request_init(rf_mac_setup, buffer); if (mcps_pd_data_request(rf_mac_setup, buffer) != 0) { rf_mac_setup->active_pd_data_request = NULL; mcps_data_conf_t confirm; @@ -1328,7 +1901,7 @@ void mcps_sap_pd_req_queue_write(protocol_interface_rf_mac_setup_s *rf_mac_setup bool requested_from_up = buffer->upper_layer_request; mcps_sap_prebuild_frame_buffer_free(buffer); if (requested_from_up) { - mcps_data_confirm_cb(rf_mac_setup, &confirm); + mcps_data_confirm_cb(rf_mac_setup, &confirm, NULL); } //Call } @@ -1342,7 +1915,7 @@ void mcps_sap_pd_req_queue_write(protocol_interface_rf_mac_setup_s *rf_mac_setup bool use_bc_queue = false; // When FHSS is enabled, broadcast buffers are pushed to own queue - if (rf_mac_setup->fhss_api) { + if (rf_mac_setup->fhss_api && (buffer->asynch_request == false)) { if (rf_mac_setup->fhss_api->use_broadcast_queue(rf_mac_setup->fhss_api, !mac_is_ack_request_set(buffer), mac_convert_frame_type_to_fhss(buffer->fcf_dsn.frametype)) == true) { cur = rf_mac_setup->pd_data_request_bc_queue_to_go; @@ -1524,9 +2097,25 @@ void mcps_sap_pd_confirm(void *mac_ptr) .priority = ARM_LIB_HIGH_PRIORITY_EVENT, }; - if (eventOS_event_send(&event) != 0) { - tr_error("mcps_sap_pd_confirm(): event send failed"); + eventOS_event_send(&event); + +} + +void mcps_sap_pd_ack(void *ack_ptr) +{ + if (mac_tasklet_event_handler < 0 || !ack_ptr) { + return; } + arm_event_s event = { + .receiver = mac_tasklet_event_handler, + .sender = 0, + .event_id = 0, + .data_ptr = ack_ptr, + .event_type = MCPS_SAP_DATA_ACK_CNF_EVENT, + .priority = ARM_LIB_HIGH_PRIORITY_EVENT, + }; + + eventOS_event_send(&event); } void mcps_sap_trig_tx(void *mac_ptr) @@ -1546,9 +2135,7 @@ void mcps_sap_trig_tx(void *mac_ptr) .priority = ARM_LIB_MED_PRIORITY_EVENT, }; - if (eventOS_event_send(&event) != 0) { - tr_error("mcps_sap_trig_tx(): event send failed"); - } else { + if (eventOS_event_send(&event) == 0) { mac_set_active_event(mac_ptr, MAC_SAP_TRIG_TX); } } @@ -1571,9 +2158,7 @@ void mac_generic_event_trig(uint8_t event_type, void *mac_ptr, bool low_latency) .priority = priority, }; - if (eventOS_event_send(&event) != 0) { - tr_error("mac_generic_event_trig(): event send failed"); - } + eventOS_event_send(&event); } void mac_mcps_buffer_queue_free(protocol_interface_rf_mac_setup_s *rf_mac_setup) { diff --git a/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_mcps_sap.h b/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_mcps_sap.h index 2da856fdf485..59d14cdbf761 100644 --- a/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_mcps_sap.h +++ b/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_mcps_sap.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, Arm Limited and affiliates. + * Copyright (c) 2016-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -32,6 +32,9 @@ struct protocol_interface_rf_mac_setup; struct mcps_data_req_s; struct arm_phy_sap_msg_s; struct mcps_purge_s; +struct mcps_data_ie_list; +struct mcps_data_req_ie_list; +struct channel_list_s; /** Address types */ typedef enum { @@ -51,6 +54,7 @@ typedef enum { #define MAC_MCPS_INDIRECT_TIMER_CB 4 #define MAC_MLME_SCAN_CONFIRM_HANDLER 5 #define MAC_SAP_TRIG_TX 6 +#define MCPS_SAP_DATA_ACK_CNF_EVENT 7 /** @@ -71,6 +75,10 @@ typedef struct mac_fcf_sequence_s{ bool framePending :1; bool ackRequested:1; bool intraPan:1; + bool sequenceNumberSuppress:1; + bool informationElementsPresets:1; + bool DstPanPresents:1; + bool SrcPanPresents:1; unsigned DstAddrMode:2; /*0x00 = no address 0x01 = reserved 0x02 = 16-bit short address 0x03 = 64-bit extended address */ unsigned frameVersion:2; unsigned SrcAddrMode:2; /*0x00 = no address 0x01 = reserved 0x02 = 16-bit short address 0x03 = 64-bit extended address */ @@ -79,16 +87,23 @@ typedef struct mac_fcf_sequence_s{ typedef struct mac_pre_parsed_frame_s{ void *mac_class_ptr; + uint8_t *payloadsIePtr; + uint8_t *headerIePtr; + uint8_t *macPayloadPtr; mlme_device_descriptor_t *neigh_info; uint8_t LQI; int8_t dbm; mac_fcf_sequence_t fcf_dsn; uint16_t frameLength; //Encoded or open payload length - uint8_t mac_header_length; + uint16_t payloadsIeLength; + uint16_t headerIeLength; + uint16_t mac_header_length; + uint16_t header_ie_length; uint8_t security_aux_header_length; uint16_t mac_payload_length; uint32_t timestamp; bool ack_pendinfg_status; + uint8_t buf[]; /*!< Trailing buffer data */ } mac_pre_parsed_frame_t; @@ -100,14 +115,22 @@ typedef struct mac_pre_build_frame{ uint8_t SrcAddr[8]; mac_aux_security_header_t aux_header; uint8_t mac_command_id; //For MLME + uint16_t payloadsIeLength; + uint16_t headerIeLength; uint16_t mac_payload_length; + uint16_t mac_header_length_with_security; uint8_t msduHandle; uint16_t buffer_ttl; + struct mcps_data_req_ie_list ie_elements; + struct channel_list_s asynch_channel_list; uint8_t *mac_payload; uint8_t status; + uint8_t asynch_channel; + uint32_t tx_time; bool upper_layer_request; bool mac_allocated_payload_ptr:1; - unsigned mac_header_length_with_security : 6; //Total max is 37 + bool asynch_request:1; + bool message_builded:1; unsigned security_mic_len:5; //Max possible lengths 0, 4, 8, 16 bytes unsigned priority:2; struct mac_pre_build_frame *next; //Pointer for queue purpose @@ -159,10 +182,14 @@ int8_t mcps_sap_pd_ind(mac_pre_parsed_frame_t *buffer); */ void mcps_sap_pd_confirm(void *mac_ptr); +void mcps_sap_pd_ack(void *ack_ptr); + int8_t mac_virtual_sap_data_cb(void *identifier, struct arm_phy_sap_msg_s *message); void mcps_sap_data_req_handler(struct protocol_interface_rf_mac_setup *rf_mac_setup , const struct mcps_data_req_s *data_req ); +void mcps_sap_data_req_handler_ext(struct protocol_interface_rf_mac_setup *rf_mac_setup , const struct mcps_data_req_s *data_req , const struct mcps_data_req_ie_list *ie_list, const channel_list_s *asynch_channel_list); + void mac_mcps_trig_buffer_from_queue(struct protocol_interface_rf_mac_setup *rf_mac_setup); void mac_mcps_buffer_queue_free(struct protocol_interface_rf_mac_setup *rf_mac_setup); @@ -175,4 +202,8 @@ void mcps_sap_trig_tx(void *mac_ptr); void mcps_sap_purge_reg_handler(struct protocol_interface_rf_mac_setup *rf_mac_setup, const struct mcps_purge_s *purge_req); +int8_t mcps_pd_data_rebuild(struct protocol_interface_rf_mac_setup *rf_ptr, mac_pre_build_frame_t *buffer); + +int8_t mcps_generic_ack_build(struct protocol_interface_rf_mac_setup *rf_ptr, const mac_fcf_sequence_t *fcf, const uint8_t *data_ptr, const mcps_ack_data_payload_t *ack_payload, uint32_t rx_time); + #endif /* MAC_IEEE802_15_4_MAC_MCPS_SAP_H_ */ diff --git a/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_mlme.c b/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_mlme.c index 56431691547a..bdf1c0496905 100644 --- a/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_mlme.c +++ b/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_mlme.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017, Arm Limited and affiliates. + * Copyright (c) 2013-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -85,14 +85,14 @@ static void mac_mlme_energy_scan_start(protocol_interface_rf_mac_setup_s *rf_mac rf_mac_setup->macRfRadioTxActive = false; } -static uint16_t mlme_scan_analyze_next_channel(protocol_interface_rf_mac_setup_s *rf_mac_setup) +uint16_t mlme_scan_analyze_next_channel(channel_list_s *mac_channel_list) { uint8_t i, j = 0, k = 1; uint32_t mask = 1; - uint32_t *channel_mask = rf_mac_setup->mac_channel_list.channel_mask; + uint32_t *channel_mask = mac_channel_list->channel_mask; - if (rf_mac_setup->mac_channel_list.channel_page == CHANNEL_PAGE_9 || - rf_mac_setup->mac_channel_list.channel_page == CHANNEL_PAGE_10) { + if (mac_channel_list->channel_page == CHANNEL_PAGE_9 || + mac_channel_list->channel_page == CHANNEL_PAGE_10) { k=8; } for(j=0; jmac_payload = &buf->mac_command_id; buf->mac_payload_length = 1; buf->priority = MAC_PD_DATA_MEDIUM_PRIORITY; + buf->fcf_dsn.DstPanPresents = true; + buf->fcf_dsn.SrcPanPresents = false; tr_debug("BEA REQ tx"); mcps_sap_pd_req_queue_write(rf_ptr, buf); @@ -278,7 +280,7 @@ static void mac_mlme_scan_start(protocol_interface_rf_mac_setup_s *rf_mac_setup) { uint8_t channel; - channel = (uint8_t) mlme_scan_analyze_next_channel(rf_mac_setup); + channel = (uint8_t) mlme_scan_analyze_next_channel(&rf_mac_setup->mac_channel_list); mac_mlme_scan_init(channel, rf_mac_setup); } @@ -508,6 +510,9 @@ static int8_t mac_mlme_boolean_set(protocol_interface_rf_mac_setup_s *rf_mac_set rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_ACCEPT_ANY_BEACON, (uint8_t*)&value); } break; + case macAcceptByPassUnknowDevice: + rf_mac_setup->mac_security_bypass_unknow_device = value; + break; default: return -1; @@ -607,7 +612,9 @@ static int8_t mac_mlme_32bit_set(protocol_interface_rf_mac_setup_s *rf_mac_setup (void) value; switch (attribute) { case macFrameCounter: + platform_enter_critical(); rf_mac_setup->security_frame_counter = value; + platform_exit_critical(); break; default: @@ -718,6 +725,30 @@ int8_t mac_mlme_set_req(protocol_interface_rf_mac_setup_s *rf_mac_setup,const ml } } +uint32_t mac_mlme_framecounter_get(struct protocol_interface_rf_mac_setup *rf_mac_setup) +{ + uint32_t value; + platform_enter_critical(); + value = rf_mac_setup->security_frame_counter; + platform_exit_critical(); + return value; +} + +void mac_mlme_framecounter_increment(struct protocol_interface_rf_mac_setup *rf_mac_setup) +{ + platform_enter_critical(); + rf_mac_setup->security_frame_counter++; + platform_exit_critical(); +} + +void mac_mlme_framecounter_decrement(struct protocol_interface_rf_mac_setup *rf_mac_setup) +{ + platform_enter_critical(); + rf_mac_setup->security_frame_counter--; + platform_exit_critical(); +} + + int8_t mac_mlme_get_req(struct protocol_interface_rf_mac_setup *rf_mac_setup, mlme_get_conf_t *get_req) { if (!get_req || !rf_mac_setup ) { @@ -740,7 +771,9 @@ int8_t mac_mlme_get_req(struct protocol_interface_rf_mac_setup *rf_mac_setup, ml break; case macFrameCounter: + platform_enter_critical(); get_req->value_pointer = &rf_mac_setup->security_frame_counter; + platform_exit_critical(); get_req->value_size = 4; break; @@ -762,7 +795,7 @@ static void mlme_scan_operation(protocol_interface_rf_mac_setup_s *rf_mac_setup) resp->ResultListSize++; } - channel = mlme_scan_analyze_next_channel(rf_mac_setup); + channel = mlme_scan_analyze_next_channel(&rf_mac_setup->mac_channel_list); if (channel > 0xff || rf_mac_setup->mac_mlme_scan_resp->ResultListSize == MLME_MAC_RES_SIZE_MAX) { resp->status = MLME_SUCCESS; tr_debug("Scan Complete..Halt MAC"); @@ -993,6 +1026,7 @@ protocol_interface_rf_mac_setup_s * mac_mlme_data_base_allocate(uint8_t *mac64, entry->bc_timer_id = -1; entry->mac_interface_id = -1; entry->dev_driver = dev_driver; + entry->aUnitBackoffPeriod = 20; //This can be different in some Platform 20 comes from 12-symbol turnaround and 8 symbol CCA read if (mac_sec_mib_init(entry, storage_sizes) != 0) { mac_mlme_data_base_deallocate(entry); @@ -1058,6 +1092,15 @@ protocol_interface_rf_mac_setup_s * mac_mlme_data_base_allocate(uint8_t *mac64, entry->mac_mcps_timer_event.receiver = entry->mac_tasklet_id; entry->mac_mcps_timer_event.sender = 0; entry->mac_mcps_timer_event.event_id = 0; + bool rf_support = false; + dev_driver->phy_driver->extension(PHY_EXTENSION_DYNAMIC_RF_SUPPORTED, (uint8_t*)&rf_support); + entry->rf_csma_extension_supported = rf_support; + if (entry->rf_csma_extension_supported) { + entry->dev_driver->phy_driver->extension(PHY_EXTENSION_GET_SYMBOLS_PER_SECOND, (uint8_t*) &entry->symbol_rate); + entry->symbol_time_us = 1000000 / entry->symbol_rate; + tr_debug("SW-MAC driver support rf extension %"PRIu32" symbol/seconds %"PRIu32" us symbol time length", entry->symbol_rate, entry->symbol_time_us); + } + //How many 10us ticks backoff period is for waiting 20symbols which is typically 10 bytes time entry->backoff_period_in_10us = mac_backoff_ticks_calc(dev_driver->phy_driver); return entry; @@ -1255,7 +1298,7 @@ int8_t mac_mlme_virtual_confirmation_handle(int8_t driver_id, const uint8_t *dat if (!mac_setup) { return -1; } - mlme_primitive primitive = *data_ptr; + mlme_primitive primitive = (mlme_primitive) *data_ptr; if (primitive == MLME_SCAN) { mlme_scan_conf_t *resp = ns_dyn_mem_temporary_alloc(sizeof(mlme_scan_conf_t)); if (!resp) { @@ -1560,6 +1603,9 @@ void mac_mlme_poll_req(protocol_interface_rf_mac_setup_s *cur, const mlme_poll_t buf->fcf_dsn.SrcAddrMode = MAC_ADDR_MODE_16_BIT; } mac_frame_src_address_set_from_interface(buf->fcf_dsn.SrcAddrMode, cur, buf->SrcAddr); + //Check PanID presents at header + buf->fcf_dsn.DstPanPresents = mac_dst_panid_present(&buf->fcf_dsn); + buf->fcf_dsn.SrcPanPresents = mac_src_panid_present(&buf->fcf_dsn); buf->mac_header_length_with_security += mac_header_address_length(&buf->fcf_dsn); buf->priority = MAC_PD_DATA_MEDIUM_PRIORITY; mcps_sap_pd_req_queue_write(cur, buf); @@ -1626,6 +1672,9 @@ int8_t mac_mlme_beacon_tx(protocol_interface_rf_mac_setup_s *rf_ptr) } buf->SrcPANId = mac_mlme_get_panid(rf_ptr); mac_frame_src_address_set_from_interface(buf->fcf_dsn.SrcAddrMode, rf_ptr, buf->SrcAddr); + buf->fcf_dsn.DstPanPresents = false; + buf->fcf_dsn.SrcPanPresents = true; + uint8_t *ptr = buf->mac_payload; *ptr++ = 0xff;//Superframe disabled diff --git a/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_mlme.h b/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_mlme.h index 70d13c4480a7..41f296015963 100644 --- a/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_mlme.h +++ b/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_mlme.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -39,6 +39,7 @@ struct mlme_scan_s; struct mlme_start_s; struct mlme_get_conf_s; struct mlme_set_s; +struct channel_list_s; void mac_mlme_scan_confirmation_handle(struct protocol_interface_rf_mac_setup *rf_ptr); @@ -64,6 +65,11 @@ int8_t mac_mlme_get_req(struct protocol_interface_rf_mac_setup *rf_mac_setup, st void mac_extended_mac_set(struct protocol_interface_rf_mac_setup *rf_mac_setup, const uint8_t *mac64); +uint32_t mac_mlme_framecounter_get(struct protocol_interface_rf_mac_setup *rf_mac_setup); + +void mac_mlme_framecounter_increment(struct protocol_interface_rf_mac_setup *rf_mac_setup); +void mac_mlme_framecounter_decrement(struct protocol_interface_rf_mac_setup *rf_mac_setup); + /** * MLME Poll Request * @@ -119,4 +125,6 @@ int8_t mac_mlme_beacon_tx(struct protocol_interface_rf_mac_setup *rf_ptr); uint8_t mac_mlme_beacon_req_tx(struct protocol_interface_rf_mac_setup *rf_ptr); int8_t mac_mlme_virtual_confirmation_handle(int8_t driver_id, const uint8_t *data_ptr, uint16_t length); +uint16_t mlme_scan_analyze_next_channel(struct channel_list_s *mac_channel_list); + #endif /* MAC_MLME_H_ */ diff --git a/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_pd_sap.c b/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_pd_sap.c index 289fb15337fb..9a736779c1bd 100644 --- a/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_pd_sap.c +++ b/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_pd_sap.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,7 +18,6 @@ #include "ns_types.h" #include "eventOS_event.h" #include "string.h" -#include "ns_trace.h" #include "nsdynmemLIB.h" #include "randLIB.h" #include "ccmLIB.h" @@ -36,16 +35,13 @@ #include "MAC/IEEE802_15_4/mac_mcps_sap.h" #include "MAC/rf_driver_storage.h" - -#define TRACE_GROUP "mPDs" - /* Define TX Timeot Period */ // Hardcoded to 1200ms. Should be changed dynamic: (FHSS) channel retries needs longer timeout #define NWKTX_TIMEOUT_PERIOD (1200*20) static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *rf_ptr, phy_link_tx_status_e status, uint8_t cca_retry, uint8_t tx_retry); -static void mac_csma_param_init(protocol_interface_rf_mac_setup_s *rf_mac_setup) +void mac_csma_param_init(protocol_interface_rf_mac_setup_s *rf_mac_setup) { rf_mac_setup->macCurrentBE = rf_mac_setup->macMinBE; } @@ -79,6 +75,25 @@ static void mac_csma_backoff_start(protocol_interface_rf_mac_setup_s *rf_mac_set timer_mac_start(rf_mac_setup, MAC_TIMER_CCA, backoff_slots); } + +uint32_t mac_csma_backoff_get(protocol_interface_rf_mac_setup_s *rf_mac_setup) +{ + uint8_t backoff = mac_csma_random_backoff_get(rf_mac_setup); + uint32_t backoff_in_us; + //Multiple aUnitBackoffPeriod symbol time + if (rf_mac_setup->rf_csma_extension_supported) { + backoff_in_us = backoff * rf_mac_setup->aUnitBackoffPeriod * rf_mac_setup->symbol_time_us; + } else { + backoff_in_us = backoff * rf_mac_setup->backoff_period_in_10us * 10; + } + + if (backoff_in_us == 0) { + backoff_in_us = 1; + } + return backoff_in_us; +} + + /* * \file mac_pd_sap.c * \brief Add short description about this file!!! @@ -117,23 +132,23 @@ static void mac_data_interface_tx_to_cb(protocol_interface_rf_mac_setup_s *rf_pt mac_tx_done_state_set(rf_ptr, MAC_TX_TIMEOUT); } -static int8_t mac_plme_cca_req(protocol_interface_rf_mac_setup_s *rf_ptr) { - dev_driver_tx_buffer_s *tx_buf = &rf_ptr->dev_driver_tx_buffer; - phy_device_driver_s *dev_driver = rf_ptr->dev_driver->phy_driver; +int8_t mac_plme_cca_req(protocol_interface_rf_mac_setup_s *rf_mac_setup) { + dev_driver_tx_buffer_s *tx_buf = &rf_mac_setup->dev_driver_tx_buffer; + phy_device_driver_s *dev_driver = rf_mac_setup->dev_driver->phy_driver; if (dev_driver->arm_net_virtual_tx_cb) { if (dev_driver->tx(tx_buf->buf, tx_buf->len, 1, PHY_LAYER_PAYLOAD) == 0) { - rf_ptr->macRfRadioTxActive = true; - timer_mac_start(rf_ptr, MAC_TX_TIMEOUT, NWKTX_TIMEOUT_PERIOD); /*Start Timeout timer for virtual packet loss*/ + rf_mac_setup->macRfRadioTxActive = true; + timer_mac_start(rf_mac_setup, MAC_TX_TIMEOUT, NWKTX_TIMEOUT_PERIOD); /*Start Timeout timer for virtual packet loss*/ } else { - mac_data_interface_tx_to_cb(rf_ptr); + mac_data_interface_tx_to_cb(rf_mac_setup); } return 0; } if (dev_driver->tx(tx_buf->buf, tx_buf->len, 1, PHY_LAYER_PAYLOAD) == 0) { - rf_ptr->macRfRadioTxActive = true; + rf_mac_setup->macRfRadioTxActive = true; return 0; } return -1; @@ -160,12 +175,47 @@ int8_t mac_pd_sap_req(protocol_interface_rf_mac_setup_s *rf_mac_setup) return 0; } + +/** + * Set PHY TX time. + * + * \param rf_mac_setup pointer to MAC. + * \param tx_time TX timestamp to be set. + * + */ +void mac_pd_sap_set_phy_tx_time(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint32_t tx_time, bool cca_enabled) +{ + // With TX time set to zero, PHY sends immediately + if (!tx_time) { + tx_time++; + } + phy_csma_params_t csma_params; + csma_params.backoff_time = tx_time; + csma_params.cca_enabled = cca_enabled; + rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_SET_CSMA_PARAMETERS, (uint8_t*) &csma_params); +} + +/** + * Get PHY RX time. + * + * \param rf_mac_setup pointer to MAC + * \return Timestamp of last PHY reception + * + */ +static uint32_t mac_pd_sap_get_phy_rx_time(protocol_interface_rf_mac_setup_s *rf_mac_setup) +{ + uint8_t rx_time_buffer[4]; + rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_READ_RX_TIME, rx_time_buffer); + return common_read_32_bit(rx_time_buffer); +} + /** * Run Mac data interface state Machine for mac timer. * */ void mac_pd_sap_state_machine(protocol_interface_rf_mac_setup_s *rf_mac_setup) { + if (rf_mac_setup->macUpState && rf_mac_setup->macTxProcessActive) { if (rf_mac_setup->mac_tx_result == MAC_TIMER_CCA) { @@ -175,16 +225,25 @@ void mac_pd_sap_state_machine(protocol_interface_rf_mac_setup_s *rf_mac_setup) if (!active_buf) { return; } + bool cca_enabled; + if (active_buf->fcf_dsn.frametype == MAC_FRAME_ACK) { + cca_enabled = false; + } else { + cca_enabled = true; + } + + mac_pd_sap_set_phy_tx_time(rf_mac_setup, active_buf->tx_time, cca_enabled); if (active_buf->fcf_dsn.frametype == FC_BEACON_FRAME) { // FHSS synchronization info is written in the end of transmitted (Beacon) buffer dev_driver_tx_buffer_s *tx_buf = &rf_mac_setup->dev_driver_tx_buffer; synch_info = tx_buf->buf + rf_mac_setup->dev_driver->phy_driver->phy_header_length + tx_buf->len - FHSS_SYNCH_INFO_LENGTH; + rf_mac_setup->fhss_api->write_synch_info(rf_mac_setup->fhss_api, synch_info, 0, FHSS_SYNCH_FRAME, 0); } // Change to destination channel and write synchronization info to Beacon frames here int tx_handle_retval = rf_mac_setup->fhss_api->tx_handle(rf_mac_setup->fhss_api, !mac_is_ack_request_set(active_buf), active_buf->DstAddr, mac_convert_frame_type_to_fhss(active_buf->fcf_dsn.frametype), - synch_info, active_buf->mac_payload_length, rf_mac_setup->dev_driver->phy_driver->phy_header_length, - rf_mac_setup->dev_driver->phy_driver->phy_tail_length); + active_buf->mac_payload_length, rf_mac_setup->dev_driver->phy_driver->phy_header_length, + rf_mac_setup->dev_driver->phy_driver->phy_tail_length, active_buf->tx_time); // When FHSS TX handle returns -1, transmission of the packet is currently not allowed -> restart CCA timer if (tx_handle_retval == -1) { timer_mac_start(rf_mac_setup, MAC_TIMER_CCA, randLIB_get_random_in_range(20, 400) + 1); @@ -210,28 +269,30 @@ void mac_pd_sap_state_machine(protocol_interface_rf_mac_setup_s *rf_mac_setup) static void mac_sap_cca_fail_cb(protocol_interface_rf_mac_setup_s *rf_ptr) { rf_ptr->macRfRadioTxActive = false; - if (rf_ptr->mac_cca_retry > rf_ptr->macMaxCSMABackoffs) { + if (rf_ptr->mac_cca_retry > rf_ptr->macMaxCSMABackoffs || (rf_ptr->active_pd_data_request && rf_ptr->active_pd_data_request->asynch_request)) { //Send MAC_CCA_FAIL mac_tx_done_state_set(rf_ptr, MAC_CCA_FAIL); } else { timer_mac_stop(rf_ptr); mac_csma_BE_update(rf_ptr); - mac_csma_backoff_start(rf_ptr); + if (mcps_pd_data_rebuild(rf_ptr, rf_ptr->active_pd_data_request) ) { + mac_tx_done_state_set(rf_ptr, MAC_CCA_FAIL); + } } } -static uint16_t mac_get_retry_period(protocol_interface_rf_mac_setup_s *rf_ptr) -{ - if (rf_ptr->fhss_api) { - return rf_ptr->fhss_api->get_retry_period(rf_ptr->fhss_api, rf_ptr->active_pd_data_request->DstAddr, rf_ptr->dev_driver->phy_driver->phy_MTU); - } - uint8_t backoff_length = mac_csma_random_backoff_get(rf_ptr); - uint16_t backoff_slots = mac_csma_backoff_period_convert_to50us(backoff_length, rf_ptr->backoff_period_in_10us); - if (backoff_slots == 0) { - backoff_slots = 1; - } - return backoff_slots; -} +//static uint16_t mac_get_retry_period(protocol_interface_rf_mac_setup_s *rf_ptr) +//{ +// if (rf_ptr->fhss_api && rf_ptr->fhss_api->get_retry_period) { +// return rf_ptr->fhss_api->get_retry_period(rf_ptr->fhss_api, rf_ptr->active_pd_data_request->DstAddr, rf_ptr->dev_driver->phy_driver->phy_MTU); +// } +// uint8_t backoff_length = mac_csma_random_backoff_get(rf_ptr); +// uint16_t backoff_slots = mac_csma_backoff_period_convert_to50us(backoff_length, rf_ptr->backoff_period_in_10us); +// if (backoff_slots == 0) { +// backoff_slots = 1; +// } +// return backoff_slots; +//} static void mac_sap_no_ack_cb(protocol_interface_rf_mac_setup_s *rf_ptr) { rf_ptr->macRfRadioTxActive = false; @@ -241,7 +302,10 @@ static void mac_sap_no_ack_cb(protocol_interface_rf_mac_setup_s *rf_ptr) { mac_csma_param_init(rf_ptr); rf_ptr->mac_tx_status.retry++; /*Send retry using random interval*/ - timer_mac_start(rf_ptr, MAC_TIMER_CCA, mac_get_retry_period(rf_ptr)); + if (mcps_pd_data_rebuild(rf_ptr, rf_ptr->active_pd_data_request) ) { + mac_tx_done_state_set(rf_ptr, MAC_CCA_FAIL); + } + } else { //Send TX Fail event // rf_mac_setup->ip_tx_active->bad_channel = rf_mac_setup->mac_channel; @@ -249,6 +313,14 @@ static void mac_sap_no_ack_cb(protocol_interface_rf_mac_setup_s *rf_ptr) { } } +static bool mac_data_counter_too_small(uint32_t current_counter, uint32_t packet_counter) +{ + if((current_counter - packet_counter) >= 2) { + return true; + } + return false; +} + static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *rf_ptr, phy_link_tx_status_e status, uint8_t cca_retry, uint8_t tx_retry) { @@ -256,21 +328,80 @@ static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *r if (!rf_ptr->macRfRadioTxActive) { return -1; } + + if (status == PHY_LINK_CCA_PREPARE) { + if (rf_ptr->fhss_api) { + if (rf_ptr->mac_ack_tx_active) { + return 0; + } + mac_pre_build_frame_t *active_buf = rf_ptr->active_pd_data_request; + if (!active_buf) { + return -1; + } + + if (active_buf->fcf_dsn.frametype == FC_BEACON_FRAME) { + // FHSS synchronization info is written in the end of transmitted (Beacon) buffer + dev_driver_tx_buffer_s *tx_buf = &rf_ptr->dev_driver_tx_buffer; + uint8_t *synch_info = tx_buf->buf + rf_ptr->dev_driver->phy_driver->phy_header_length + tx_buf->len - FHSS_SYNCH_INFO_LENGTH; + rf_ptr->fhss_api->write_synch_info(rf_ptr->fhss_api, synch_info, 0, FHSS_SYNCH_FRAME, 0); + } + if (active_buf->asynch_request == false) { + // Change to destination channel and write synchronization info to Beacon frames here + int tx_handle_retval = rf_ptr->fhss_api->tx_handle(rf_ptr->fhss_api, !mac_is_ack_request_set(active_buf), + active_buf->DstAddr, mac_convert_frame_type_to_fhss(active_buf->fcf_dsn.frametype), + active_buf->mac_payload_length, rf_ptr->dev_driver->phy_driver->phy_header_length, + rf_ptr->dev_driver->phy_driver->phy_tail_length, active_buf->tx_time); + // When FHSS TX handle returns -1, transmission of the packet is currently not allowed -> restart CCA timer + if (tx_handle_retval == -1) { + mac_sap_cca_fail_cb(rf_ptr); + return -2; + } + // When FHSS TX handle returns -3, we are trying to transmit broadcast packet on unicast channel -> push back + // to queue by using CCA fail event + if (tx_handle_retval == -3) { + mac_tx_done_state_set(rf_ptr, MAC_CCA_FAIL); + return -3; + } + } + } + return 0; + } + + // bool waiting_ack = false; - // Do not update CCA count when Ack is received, it was already updated with PHY_LINK_TX_SUCCESS event - if ((status != PHY_LINK_TX_DONE) && (status != PHY_LINK_TX_DONE_PENDING)) { - /* For PHY_LINK_TX_SUCCESS and PHY_LINK_CCA_FAIL cca_retry must always be > 0. - * PHY_LINK_TX_FAIL either happened during transmission or when waiting Ack -> we must use the CCA count given by PHY. - */ - if ((cca_retry == 0) && (status != PHY_LINK_TX_FAIL)) { - cca_retry = 1; + + + if (rf_ptr->mac_ack_tx_active) { + rf_ptr->mac_ack_tx_active = false; + if (rf_ptr->active_pd_data_request) { + + if (rf_ptr->active_pd_data_request->fcf_dsn.securityEnabled) { + uint32_t current_counter = mac_mlme_framecounter_get(rf_ptr); + if (mac_data_counter_too_small(current_counter, rf_ptr->active_pd_data_request->aux_header.frameCounter)) { + rf_ptr->active_pd_data_request->aux_header.frameCounter = current_counter; + mac_mlme_framecounter_increment(rf_ptr); + } + } + //GEN TX failure + mac_sap_cca_fail_cb(rf_ptr); + } + return 0; + } else { + // Do not update CCA count when Ack is received, it was already updated with PHY_LINK_TX_SUCCESS event + if ((status != PHY_LINK_TX_DONE) && (status != PHY_LINK_TX_DONE_PENDING)) { + /* For PHY_LINK_TX_SUCCESS and PHY_LINK_CCA_FAIL cca_retry must always be > 0. + * PHY_LINK_TX_FAIL either happened during transmission or when waiting Ack -> we must use the CCA count given by PHY. + */ + if ((cca_retry == 0) && (status != PHY_LINK_TX_FAIL)) { + cca_retry = 1; + } + rf_ptr->mac_tx_status.cca_cnt += cca_retry; + rf_ptr->mac_cca_retry += cca_retry; } - rf_ptr->mac_tx_status.cca_cnt += cca_retry; - rf_ptr->mac_cca_retry += cca_retry; + rf_ptr->mac_tx_status.retry += tx_retry; + rf_ptr->mac_tx_retry += tx_retry; + timer_mac_stop(rf_ptr); } - rf_ptr->mac_tx_status.retry += tx_retry; - rf_ptr->mac_tx_retry += tx_retry; - timer_mac_stop(rf_ptr); switch (status) { case PHY_LINK_TX_SUCCESS: @@ -298,7 +429,9 @@ static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *r case PHY_LINK_TX_DONE_PENDING: mac_tx_done_state_set(rf_ptr, MAC_TX_DONE_PENDING); + break; + default: break; } if (rf_ptr->fhss_api) { @@ -306,14 +439,99 @@ static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *r if (rf_ptr->mac_tx_result == MAC_TX_DONE) { tx_is_done = true; } - rf_ptr->fhss_api->data_tx_done(rf_ptr->fhss_api, waiting_ack, tx_is_done, rf_ptr->active_pd_data_request->msduHandle); + if (rf_ptr->active_pd_data_request->asynch_request == false) { + rf_ptr->fhss_api->data_tx_done(rf_ptr->fhss_api, waiting_ack, tx_is_done, rf_ptr->active_pd_data_request->msduHandle); + } + } + return 0; +} + + +static int8_t mac_data_interface_tx_done_by_ack_cb(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_parsed_frame_t *buf) +{ + + if (!rf_ptr->macRfRadioTxActive) { + return -1; + } + + timer_mac_stop(rf_ptr); + if (buf->fcf_dsn.framePending) { + rf_ptr->mac_tx_result = MAC_TX_DONE_PENDING; + } else { + rf_ptr->mac_tx_result = MAC_TX_DONE; + } + rf_ptr->macRfRadioTxActive = false; + rf_ptr->macTxProcessActive = false; + mcps_sap_pd_ack(buf); + + if (rf_ptr->fhss_api) { + if (rf_ptr->active_pd_data_request->asynch_request == false) { + rf_ptr->fhss_api->data_tx_done(rf_ptr->fhss_api, false, true, rf_ptr->active_pd_data_request->msduHandle); + } } return 0; } +static bool mac_pd_sap_ack_validation(protocol_interface_rf_mac_setup_s *rf_ptr, mac_fcf_sequence_t *fcf_dsn, const uint8_t *data_ptr) +{ + if (!rf_ptr->active_pd_data_request || !rf_ptr->active_pd_data_request->fcf_dsn.ackRequested) { + return false; //No active Data request anymore or no ACK request for current TX + } + + if (fcf_dsn->frameVersion != rf_ptr->active_pd_data_request->fcf_dsn.frameVersion) { + return false; + } + + if (fcf_dsn->frameVersion == MAC_FRAME_VERSION_2015) { + + //Validate ACK SRC address mode and address to Active TX dst address + if (rf_ptr->active_pd_data_request->fcf_dsn.DstAddrMode != fcf_dsn->SrcAddrMode) { + return false; + } + + if (fcf_dsn->SrcAddrMode) { + uint8_t srcAddress[8]; + uint8_t address_length = mac_address_length(fcf_dsn->SrcAddrMode); + mac_header_get_src_address(fcf_dsn, data_ptr, srcAddress); + if (memcmp(srcAddress, rf_ptr->active_pd_data_request->DstAddr, address_length)) { + return false; + } + } + + //Validate ACK DST address mode and address to Active TX src address + if (rf_ptr->active_pd_data_request->fcf_dsn.SrcAddrMode != fcf_dsn->DstAddrMode) { + return false; + } + + if (fcf_dsn->DstAddrMode) { + uint8_t dstAddress[8]; + uint8_t address_length = mac_address_length(fcf_dsn->DstAddrMode); + mac_header_get_dst_address(fcf_dsn, data_ptr, dstAddress); + if (memcmp(dstAddress, rf_ptr->active_pd_data_request->SrcAddr, address_length)) { + return false; + } + } + + if (rf_ptr->active_pd_data_request->fcf_dsn.sequenceNumberSuppress != fcf_dsn->sequenceNumberSuppress) { + return false; //sequence number validation not correct + } + + if (!fcf_dsn->sequenceNumberSuppress && (rf_ptr->active_pd_data_request->fcf_dsn.DSN != fcf_dsn->DSN)) { + return false; + } + return true; + } + + if (rf_ptr->active_pd_data_request->fcf_dsn.DSN != fcf_dsn->DSN) { + return false; + } + return true; +} + int8_t mac_pd_sap_data_cb(void *identifier, arm_phy_sap_msg_t *message) { protocol_interface_rf_mac_setup_s *rf_ptr = (protocol_interface_rf_mac_setup_s*)identifier; + mac_pre_parsed_frame_t *buffer = NULL; if (!rf_ptr || !message ) { return -1; @@ -325,7 +543,6 @@ int8_t mac_pd_sap_data_cb(void *identifier, arm_phy_sap_msg_t *message) if (message->id == MAC15_4_PD_SAP_DATA_IND) { const uint8_t *ptr; - arm_pd_sap_generic_ind_t *pd_data_ind = &(message->message.generic_data_ind); if (pd_data_ind->data_len < 3 ) { @@ -333,21 +550,86 @@ int8_t mac_pd_sap_data_cb(void *identifier, arm_phy_sap_msg_t *message) } ptr = pd_data_ind->data_ptr; - mac_pre_parsed_frame_t *buffer = mcps_sap_pre_parsed_frame_buffer_get(pd_data_ind->data_ptr, pd_data_ind->data_len); + uint32_t time_stamp = 0; + if (rf_ptr->rf_csma_extension_supported) { + time_stamp = mac_pd_sap_get_phy_rx_time(rf_ptr); + } + mac_fcf_sequence_t fcf_read; + ptr = mac_header_parse_fcf_dsn(&fcf_read, ptr); + //Check PanID presents at header + fcf_read.DstPanPresents = mac_dst_panid_present(&fcf_read); + fcf_read.SrcPanPresents = mac_src_panid_present(&fcf_read); + int16_t length = pd_data_ind->data_len; + if (!rf_ptr->macProminousMode) { + + //Unsupported Frame + if (fcf_read.frametype > FC_CMD_FRAME || (fcf_read.frametype == FC_ACK_FRAME && fcf_read.frameVersion != MAC_FRAME_VERSION_2015)) { + goto ERROR_HANDLER; + } + + switch (fcf_read.frametype) { + case FC_DATA_FRAME: + if (fcf_read.SrcAddrMode == MAC_ADDR_MODE_NONE) { + return -1; + } else if (fcf_read.DstAddrMode == MAC_ADDR_MODE_NONE && fcf_read.frameVersion != MAC_FRAME_VERSION_2015) { + return -1; + } + break; + case FC_BEACON_FRAME: + if (fcf_read.SrcAddrMode == MAC_ADDR_MODE_NONE || fcf_read.DstAddrMode != MAC_ADDR_MODE_NONE) { + return -1; + } + break; + case FC_ACK_FRAME: + //Validate here that we are waiting ack + if (fcf_read.ackRequested) { + return -1; + } + + //Validate ACK + if (!mac_pd_sap_ack_validation(rf_ptr, &fcf_read, pd_data_ind->data_ptr)) { + return -1; + } + break; + + default: + break; + } + + //Generate ACK when Extension is enabled and ACK is requested + if (rf_ptr->mac_extension_enabled && fcf_read.ackRequested && fcf_read.frameVersion == MAC_FRAME_VERSION_2015) { + //SEND ACK here + if (rf_ptr->mac_ack_tx_active) { + return -1; + } + + mcps_ack_data_payload_t ack_payload; + mac_api_t *mac_api = get_sw_mac_api(rf_ptr); + mac_api->enhanced_ack_data_req_cb(mac_api, &ack_payload, pd_data_ind->dbm, pd_data_ind->link_quality); + //Calculate Delta time + + if (mcps_generic_ack_build(rf_ptr, &fcf_read, pd_data_ind->data_ptr, &ack_payload, time_stamp) !=0) { + return -1; + } + + rf_ptr->mac_ack_tx_active = true; + } + } + + buffer = mcps_sap_pre_parsed_frame_buffer_get(pd_data_ind->data_ptr, pd_data_ind->data_len); if (!buffer) { - tr_error("pd_ind buffer get fail %u", pd_data_ind->data_len); sw_mac_stats_update(rf_ptr, STAT_MAC_RX_DROP, 0); return -3; } - if (rf_ptr->fhss_api) { - buffer->timestamp = rf_ptr->fhss_api->read_timestamp(rf_ptr->fhss_api); - } + + //Copy Pre Parsed values + buffer->fcf_dsn = fcf_read; + buffer->timestamp = time_stamp; + buffer->ack_pendinfg_status = mac_data_interface_read_last_ack_pending_status(rf_ptr); - mac_header_parse_fcf_dsn(&buffer->fcf_dsn, ptr); - int16_t length = pd_data_ind->data_len; - ptr += 3; + // Upward direction functions assume no headroom and are trusting that removed bytes are still valid. // see mac.c:655 @@ -355,41 +637,16 @@ int8_t mac_pd_sap_data_cb(void *identifier, arm_phy_sap_msg_t *message) buffer->dbm = pd_data_ind->dbm; buffer->LQI = pd_data_ind->link_quality; buffer->mac_class_ptr = rf_ptr; - buffer->mac_header_length = 3; + //Dnamic calculation for FCF + SEQ parse + buffer->mac_header_length = ptr - pd_data_ind->data_ptr; if (!rf_ptr->macProminousMode) { - if (buffer->fcf_dsn.frametype > FC_CMD_FRAME || buffer->fcf_dsn.frametype == FC_ACK_FRAME) { + if (buffer->fcf_dsn.frametype > FC_CMD_FRAME) { goto ERROR_HANDLER; } - //Verify Length after address field - switch (buffer->fcf_dsn.DstAddrMode) { - case MAC_ADDR_MODE_64_BIT: - buffer->mac_header_length += 10; - break; - case MAC_ADDR_MODE_16_BIT: - buffer->mac_header_length += 4; - break; - case MAC_ADDR_MODE_NONE: - break; - } - switch (buffer->fcf_dsn.SrcAddrMode) { - case MAC_ADDR_MODE_64_BIT: - buffer->mac_header_length += 8; - if (!buffer->fcf_dsn.intraPan) { - buffer->mac_header_length += 2; - } - break; - case MAC_ADDR_MODE_16_BIT: - buffer->mac_header_length += 2; - if (!buffer->fcf_dsn.intraPan) { - buffer->mac_header_length += 2; - } - break; - case MAC_ADDR_MODE_NONE: - break; - } + buffer->mac_header_length += mac_header_address_length(&buffer->fcf_dsn); length -= buffer->mac_header_length; @@ -406,6 +663,7 @@ int8_t mac_pd_sap_data_cb(void *identifier, arm_phy_sap_msg_t *message) uint8_t auxBaseHeader = *security_ptr; key_id_mode = (auxBaseHeader >> 3) & 3; security_level = auxBaseHeader & 7; + switch (key_id_mode) { case MAC_KEY_ID_MODE_IMPLICIT: if (security_level) { @@ -426,24 +684,7 @@ int8_t mac_pd_sap_data_cb(void *identifier, arm_phy_sap_msg_t *message) } length -= buffer->security_aux_header_length; - - switch (security_level) { - case 1: - case 5: - mic_len = 4; - break; - case 2: - case 6: - mic_len = 8; - break; - case 3: - case 7: - mic_len = 16; - break; - default: - mic_len = 0; - break; - } + mic_len = mac_security_mic_length_get(security_level); length -= mic_len; @@ -455,28 +696,29 @@ int8_t mac_pd_sap_data_cb(void *identifier, arm_phy_sap_msg_t *message) buffer->mac_payload_length -= (buffer->security_aux_header_length + mic_len); } - switch (buffer->fcf_dsn.frametype) { - case FC_DATA_FRAME: - if (buffer->fcf_dsn.SrcAddrMode == MAC_ADDR_MODE_NONE || buffer->fcf_dsn.DstAddrMode == MAC_ADDR_MODE_NONE) { - goto ERROR_HANDLER; - } - break; - case FC_BEACON_FRAME: - if (buffer->fcf_dsn.SrcAddrMode == MAC_ADDR_MODE_NONE || buffer->fcf_dsn.DstAddrMode != MAC_ADDR_MODE_NONE) { - goto ERROR_HANDLER; - } - break; - default: - if (length == 0) { - goto ERROR_HANDLER; - } - break; - } } + //Do not accept commend frame with length 0 + if (fcf_read.frametype == FC_CMD_FRAME && length == 0) { + return -1; + } + + //Parse IE Elements + if (!mac_header_information_elements_parse(buffer)) { + goto ERROR_HANDLER; + } - if (mcps_sap_pd_ind(buffer) == 0) { + if (!rf_ptr->macProminousMode && buffer->fcf_dsn.frametype == FC_ACK_FRAME) { + if (mac_data_interface_tx_done_by_ack_cb(rf_ptr, buffer)) { + mcps_sap_pre_parsed_frame_buffer_free(buffer); + } return 0; + + } else { + + if (mcps_sap_pd_ind(buffer) == 0) { + return 0; + } } ERROR_HANDLER: mcps_sap_pre_parsed_frame_buffer_free(buffer); diff --git a/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_pd_sap.h b/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_pd_sap.h index b476ea1af86d..f975f0395229 100644 --- a/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_pd_sap.h +++ b/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_pd_sap.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -37,9 +37,17 @@ struct arm_phy_sap_msg_s; */ int8_t mac_pd_sap_req(struct protocol_interface_rf_mac_setup *rf_mac_setup); +int8_t mac_plme_cca_req(struct protocol_interface_rf_mac_setup *rf_mac_setup); + +void mac_pd_sap_set_phy_tx_time(struct protocol_interface_rf_mac_setup *rf_mac_setup, uint32_t tx_time, bool cca_enabled); + void mac_pd_sap_rf_low_level_function_set(void *mac_ptr, void *driver); int8_t mac_pd_sap_data_cb(void *identifier, struct arm_phy_sap_msg_s *message); + +void mac_csma_param_init(struct protocol_interface_rf_mac_setup *rf_mac_setup); + +uint32_t mac_csma_backoff_get(struct protocol_interface_rf_mac_setup *rf_mac_setup); /** * Run Mac data interface state Machine. * diff --git a/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_security_mib.c b/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_security_mib.c index 02a5918c29b3..3b6470772286 100644 --- a/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_security_mib.c +++ b/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/mac_security_mib.c @@ -395,7 +395,7 @@ mlme_key_descriptor_t * mac_sec_key_description_get(protocol_interface_rf_mac_se key_description++; } - tr_debug("LookuPdata search fail %s", trace_array(lookup_data, 9)); + //tr_debug("LookuPdata search fail %s", trace_array(lookup_data, 9)); return NULL; } diff --git a/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/sw_mac.c b/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/sw_mac.c index a0be817f9571..45fbfc2ca06c 100644 --- a/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/sw_mac.c +++ b/features/nanostack/sal-stack-nanostack/source/MAC/IEEE802_15_4/sw_mac.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, Arm Limited and affiliates. + * Copyright (c) 2016-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -49,9 +49,11 @@ static mac_internal_t mac_store; //Hack only at this point, later put into linke static int8_t ns_sw_mac_initialize(mac_api_t *api, mcps_data_confirm *mcps_data_conf_cb, mcps_data_indication *mcps_data_ind_cb, mcps_purge_confirm *purge_conf_cb, mlme_confirm *mlme_conf_callback, mlme_indication *mlme_ind_callback, int8_t parent_id); +static int8_t ns_sw_mac_api_enable_mcps_ext(mac_api_t *api, mcps_data_indication_ext *data_ind_cb, mcps_data_confirm_ext *data_cnf_cb, mcps_ack_data_req_ext *ack_data_req_cb); static void mlme_req(const mac_api_t* api, mlme_primitive id, const void *data); static void mcps_req(const mac_api_t* api, const mcps_data_req_t *data); +static void mcps_req_ext(const mac_api_t* api, const mcps_data_req_t *data, const mcps_data_req_ie_list_t *ie_ext, const channel_list_s *asynch_channel_list); static void purge_req(const mac_api_t* api, const mcps_purge_t *data); static int8_t macext_mac64_address_set( const mac_api_t* api, const uint8_t *mac64); static int8_t macext_mac64_address_get( const mac_api_t* api, mac_extended_address_type type, uint8_t *mac64_buf); @@ -105,8 +107,10 @@ mac_api_t *ns_sw_mac_create(int8_t rf_driver_id, mac_description_storage_size_t arm_net_virtual_confirmation_rx_cb_set(driver->phy_driver, &mac_mlme_virtual_confirmation_handle); this->mac_initialize = &ns_sw_mac_initialize; + this->mac_mcps_extension_enable = &ns_sw_mac_api_enable_mcps_ext; this->mlme_req = &mlme_req; this->mcps_data_req = &mcps_req; + this->mcps_data_req_ext = &mcps_req_ext; this->mcps_purge_req = &purge_req; this->mac64_get = &macext_mac64_address_get; this->mac64_set = &macext_mac64_address_set; @@ -161,6 +165,11 @@ int ns_sw_mac_fhss_register(mac_api_t *mac_api, fhss_api_t *fhss_api) if (!mac_setup) { return -2; } + + if (!mac_setup->rf_csma_extension_supported) { + return -2; + } + // Assign FHSS API mac_setup->fhss_api = fhss_api; // Pass MAC functions to FHSS @@ -178,6 +187,18 @@ int ns_sw_mac_fhss_register(mac_api_t *mac_api, fhss_api_t *fhss_api) return 0; } +struct fhss_api *ns_sw_mac_get_fhss_api(struct mac_api_s *mac_api) +{ + if (!mac_api) { + return NULL; + } + protocol_interface_rf_mac_setup_s *mac_setup = get_sw_mac_ptr_by_mac_api(mac_api); + if (!mac_setup) { + return NULL; + } + return mac_setup->fhss_api; +} + int ns_sw_mac_statistics_start(struct mac_api_s *mac_api, struct mac_statistics_s *mac_statistics) { if (!mac_api || !mac_statistics) { @@ -213,6 +234,30 @@ static int8_t ns_sw_mac_initialize(mac_api_t *api, mcps_data_confirm *mcps_data_ return 0; } +static int8_t ns_sw_mac_api_enable_mcps_ext(mac_api_t *api, mcps_data_indication_ext *data_ind_cb, mcps_data_confirm_ext *data_cnf_cb, mcps_ack_data_req_ext *ack_data_req_cb) +{ + //TODO: Find from linked list instead + if(api != mac_store.mac_api ){ + return -1; + } + + mac_api_t *cur = mac_store.mac_api; + + if (!mac_store.setup->rf_csma_extension_supported) { + return -1; + } + + cur->data_conf_ext_cb = data_cnf_cb; + cur->data_ind_ext_cb = data_ind_cb; + cur->enhanced_ack_data_req_cb = ack_data_req_cb; + if (data_cnf_cb && data_ind_cb && ack_data_req_cb) { + mac_store.setup->mac_extension_enabled = true; + } else { + mac_store.setup->mac_extension_enabled = false; + } + return 0; +} + mac_api_t *get_sw_mac_api(protocol_interface_rf_mac_setup_s *setup) { if (!mac_store.mac_api || mac_store.mac_api->parent_id == -1 || mac_store.setup != setup) { @@ -448,10 +493,22 @@ void mcps_req(const mac_api_t* api, const mcps_data_req_t *data) { //TODO: Populate linked list when present if (mac_store.mac_api == api) { - mcps_sap_data_req_handler(mac_store.setup , data ); + /* Call direct new API but without IE extensions */ + mcps_data_req_ie_list_t ie_list; + memset(&ie_list, 0 , sizeof(mcps_data_req_ie_list_t)); + mcps_sap_data_req_handler_ext(mac_store.setup , data , &ie_list, NULL); + } +} + +void mcps_req_ext(const mac_api_t* api, const mcps_data_req_t *data, const mcps_data_req_ie_list_t *ie_ext, const channel_list_s *asynch_channel_list) +{ +//TODO: Populate linked list when present + if (mac_store.mac_api == api) { + mcps_sap_data_req_handler_ext(mac_store.setup , data , ie_ext, asynch_channel_list); } } + static void purge_req(const mac_api_t* api, const mcps_purge_t *data) { if (mac_store.mac_api == api) { diff --git a/features/nanostack/sal-stack-nanostack/source/MAC/virtual_rf/virtual_rf_client.c b/features/nanostack/sal-stack-nanostack/source/MAC/virtual_rf/virtual_rf_client.c index b81b2564dc37..651e21e05d57 100644 --- a/features/nanostack/sal-stack-nanostack/source/MAC/virtual_rf/virtual_rf_client.c +++ b/features/nanostack/sal-stack-nanostack/source/MAC/virtual_rf/virtual_rf_client.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, Arm Limited and affiliates. + * Copyright (c) 2016-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -138,7 +138,7 @@ static int8_t phy_rf_virtual_rx(const uint8_t *data_ptr, uint16_t data_len,int8_ return -1; } phy_msg.id = MACTUN_MLME_NAP_EXTENSION; - phy_msg.message.mlme_request.primitive = *data_ptr++; + phy_msg.message.mlme_request.primitive = (mlme_primitive) *data_ptr++; phy_msg.message.mlme_request.mlme_ptr = data_ptr; phy_msg.message.mlme_request.ptr_length = (data_len - 2); diff --git a/features/nanostack/sal-stack-nanostack/source/MLE/mle.c b/features/nanostack/sal-stack-nanostack/source/MLE/mle.c index 39177b1537d0..5168fce5c2e5 100644 --- a/features/nanostack/sal-stack-nanostack/source/MLE/mle.c +++ b/features/nanostack/sal-stack-nanostack/source/MLE/mle.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017, Arm Limited and affiliates. + * Copyright (c) 2013-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,7 +18,7 @@ #include "nsconfig.h" #include "MLE/mle.h" -#ifndef NO_MLE + #include "ns_types.h" #include "eventOS_event.h" #include "eventOS_event_timer.h" @@ -46,320 +46,25 @@ #include "6LoWPAN/MAC/mac_data_poll.h" #include "6LoWPAN/lowpan_adaptation_interface.h" -#define MLE_UNICAST_CHALLENGE_TIMEOUT 20 - #define TRACE_GROUP "mle" -typedef enum { - ARM_MLE_INIT = 0, - ARM_MLE_TTL_TIMER -} arm_mle_event_id_e; - -//MLE class structure -typedef struct mle_table_class { - int8_t interfaceId; - mle_class_user_mode mode; - mle_neigh_table_list_t mle_table; //Active Entry - mle_neigh_table_list_t free_enty_list; - mle_neigh_table_entry_t *allocated_buffer; - uint8_t buffer_size; - mle_entry_user_entry_remove_notify *remove_cb; - mle_entry_link_keep_alive *keep_alive_cb; - mle_entry_link_keep_alive *challenge_cb; - mle_entry_interface_activate *interface_is_active; - ns_list_link_t link; /*!< List link entry */ -} mle_table_class_t; - -static NS_LIST_DEFINE(mle_table_calss_list, mle_table_class_t, link); - -static int8_t mle_tasklet_id = -1; - -static arm_event_storage_t *mle_class_timer_storage = NULL; - -static mle_neigh_table_entry_t *mle_class_neighbor_get(mle_neigh_table_list_t *mle_table, const uint8_t *address, addrtype_t type); -static mle_neigh_table_entry_t *mle_class_get_free_entry(mle_neigh_table_list_t *mle_table); -static bool mle_class_neighbor_validate(mle_neigh_table_list_t *mle_table, const mle_neigh_table_entry_t *entry); -static void mle_event_handler(arm_event_s *event); - - -static bool mle_table_timer_start(void) -{ - if (!mle_class_timer_storage) { - - arm_event_s event = { - .receiver = mle_tasklet_id, - .sender = 0, - .event_id = 0, - .data_ptr = NULL, - .event_type = ARM_MLE_TTL_TIMER, - .priority = ARM_LIB_LOW_PRIORITY_EVENT, - }; - - mle_class_timer_storage = eventOS_event_timer_request_every(&event, eventOS_event_timer_ms_to_ticks(MLE_TIMER_TICKS_MS)); - if (!mle_class_timer_storage) { - tr_error("Mle timer start fail"); - return false; - } - } - - return true; -} - -static void mle_table_timer_stop(void) -{ - if (mle_class_timer_storage && ns_list_is_empty(&mle_table_calss_list)) { - eventOS_cancel(mle_class_timer_storage); - mle_class_timer_storage = NULL; - } -} -static void mle_table_remove_free_indirect_table(int8_t interface_id, mle_neigh_table_entry_t *entry_ptr) +int16_t mle_class_free_entry_count_get(struct protocol_interface_info_entry *cur) { - protocol_interface_info_entry_t *cur_interface = protocol_stack_interface_info_get_by_id(interface_id); - if (!cur_interface) { - return; - } - //Free firts by defined short address - if (entry_ptr->short_adr < 0xfffe) { - uint8_t temp_address[2]; - common_write_16_bit(entry_ptr->short_adr, temp_address); - lowpan_adaptation_indirect_free_messages_from_queues_by_address(cur_interface, temp_address, ADDR_802_15_4_SHORT); - } - lowpan_adaptation_indirect_free_messages_from_queues_by_address(cur_interface, entry_ptr->mac64, ADDR_802_15_4_LONG); -} + mac_neighbor_table_list_t *mac_table_free_list = &mac_neighbor_info(cur)->free_list; + return ns_list_count(mac_table_free_list); -static void mle_table_class_list_free(mle_table_class_t *mle_table_class) { - - ns_list_foreach_safe(mle_neigh_table_entry_t, cur, &mle_table_class->mle_table) { - ns_list_remove(&mle_table_class->mle_table, cur); - //Clean Indirect queue - mle_table_remove_free_indirect_table(mle_table_class->interfaceId, cur); - //Call Remove callback - mle_table_class->remove_cb(mle_table_class->interfaceId, cur); - //Removes ETX neighbor - etx_neighbor_remove(mle_table_class->interfaceId, cur); - ns_list_add_to_start(&mle_table_class->free_enty_list, cur); - } - topo_trace(TOPOLOGY_MLE, NULL, TOPO_CLEAR); } -static void mle_table_class_free(mle_table_class_t *main_list) +int16_t mle_class_sleepy_entry_count_get(struct protocol_interface_info_entry *cur) { - ns_list_remove(&mle_table_calss_list, main_list); - mle_table_class_list_free(main_list); - //Free list buffer - ns_dyn_mem_free(main_list->allocated_buffer); - ns_dyn_mem_free(main_list); - mle_table_timer_stop(); -} - - - -static int8_t mle_table_class_table_buffer_allocate(mle_table_class_t *mle_class, uint8_t list_size) -{ - mle_neigh_table_entry_t *list_buffer = ns_dyn_mem_alloc(sizeof(mle_neigh_table_entry_t) * list_size); - if (!list_buffer) { - return -1; - } - - mle_class->allocated_buffer = list_buffer; //Save storaged - ns_list_init(&mle_class->free_enty_list); - ns_list_init(&mle_class->mle_table); - for (uint8_t i = 0; i< list_size; i++) { - memset(list_buffer, 0, sizeof(mle_neigh_table_entry_t)); - - list_buffer->attribute_index = i; - //Add to list - ns_list_add_to_end(&mle_class->free_enty_list,list_buffer); - list_buffer++; - } - return 0; -} - - -static mle_table_class_t * mle_table_class_allocate(int8_t interfaceId, uint8_t list_size) -{ - mle_table_class_t *newClass = ns_dyn_mem_alloc(sizeof(mle_table_class_t)); - - if (newClass) { - memset(newClass, 0, sizeof(mle_table_class_t)); - if (mle_table_class_table_buffer_allocate(newClass,list_size) != 0) { - ns_dyn_mem_free(newClass); - return NULL; - } - newClass->interfaceId = interfaceId; - newClass->buffer_size = list_size; - } - return newClass; -} - -static mle_table_class_t * mle_table_class_discover(int8_t interface_id) { - ns_list_foreach(mle_table_class_t, cur_mle_class, &mle_table_calss_list) { - if (cur_mle_class->interfaceId == interface_id) { - return cur_mle_class; - } - } - return NULL; -} - -static int8_t mle_class_event_handler_init(void) { - if (mle_tasklet_id == -1) { - //GENERATE TASKLET - mle_tasklet_id = eventOS_event_handler_create(&mle_event_handler, ARM_MLE_INIT); - - } - - return mle_tasklet_id; -} - -int8_t mle_class_init(int8_t interface_id, uint8_t table_size, mle_entry_user_entry_remove_notify *remove_cb, mle_entry_link_keep_alive *keep_alive_cb, mle_entry_interface_activate *interface_is_active) -{ - //Discover from the list - mle_table_class_t *mle_class_ptr = mle_table_class_discover(interface_id); - //Clean list and set function pointer call backs - if (mle_class_ptr) { - mle_class_ptr->remove_cb = remove_cb; - mle_class_ptr->keep_alive_cb = keep_alive_cb; - mle_class_ptr->challenge_cb = NULL; - mle_class_ptr->interface_is_active = interface_is_active; - if (mle_class_ptr->buffer_size != table_size) { //Clean tabs only when table size is different - mle_table_class_list_free(mle_class_ptr); - ns_dyn_mem_free(mle_class_ptr->allocated_buffer); - mle_class_ptr->allocated_buffer = NULL; - //Reallocate - if (mle_table_class_table_buffer_allocate(mle_class_ptr,table_size) != 0) { - ns_list_remove(&mle_table_calss_list, mle_class_ptr); - ns_dyn_mem_free(mle_class_ptr); - return -2; - } - mle_class_ptr->buffer_size = table_size; - } - return 0; - } - - if (mle_class_event_handler_init() < 0) { - return -2; - } - - if (!mle_table_timer_start()) { - return -2; - } - - mle_class_ptr = mle_table_class_allocate(interface_id, table_size); - //Allocate new - if (!mle_class_ptr) { - return -2; - } - - tr_debug("MLE service init size %d", table_size); - mle_class_ptr->remove_cb = remove_cb; - mle_class_ptr->keep_alive_cb = keep_alive_cb; - mle_class_ptr->challenge_cb = NULL; - mle_class_ptr->interface_is_active = interface_is_active; - ns_list_add_to_end(&mle_table_calss_list, mle_class_ptr); - return 0; - -} - -int8_t mle_class_router_challenge(int8_t interface_id,mle_entry_link_keep_alive *challenge_cb) -{ - mle_table_class_t *mle_class_ptr = mle_table_class_discover(interface_id); - //Clean list and set function pointer call backs - if (!mle_class_ptr) { - return -1; - } - mle_class_ptr->challenge_cb = challenge_cb; - return 0; -} - -bool mle_class_exists_for_interface(int8_t interface_id) { - - if (mle_table_class_discover(interface_id)) { - return true; - } - - return false; -} - -int8_t mle_class_deallocate(int8_t interface_id) -{ - //Discover from the list - mle_table_class_t *mle_class_ptr = mle_table_class_discover(interface_id); - //Clean list and set function pointer call backs - if (!mle_class_ptr) { - return -1; - } - - mle_table_class_free(mle_class_ptr); - return 0; - -} - -int8_t mle_class_list_clean(int8_t interface_id) -{ - //Discover from the list - mle_table_class_t *mle_class_ptr = mle_table_class_discover(interface_id); - //Clean list and set function pointer call backs - if (!mle_class_ptr) { - return -1; - } - - mle_table_class_list_free(mle_class_ptr); - return 0; - -} - -int8_t mle_class_mode_set(int8_t interface_id,mle_class_user_mode mode) -{ - mle_table_class_t *mle_class_ptr = mle_table_class_discover(interface_id); - //Clean list and set function pointer call backs - if (!mle_class_ptr) { - return -1; - } - mle_class_ptr->mode = mode; - - return 0; -} - -int8_t mle_class_set_new_key_pending(int8_t interface_id) -{ - mle_table_class_t *mle_class_ptr = mle_table_class_discover(interface_id); - - if (!mle_class_ptr) { - return -1; - } - - ns_list_foreach_safe(mle_neigh_table_entry_t, cur, &mle_class_ptr->mle_table) { - cur->new_key_pending = true; - } - - return 0; -} - -int16_t mle_class_free_entry_count_get(int8_t interface_id) -{ - mle_table_class_t *mle_class_ptr = mle_table_class_discover(interface_id); - //Clean list and set function pointer call backs - if (!mle_class_ptr) { - return 0; - } - return ns_list_count(&(mle_class_ptr->free_enty_list)); - -} - -int16_t mle_class_sleepy_entry_count_get(int8_t interface_id) -{ - mle_table_class_t *mle_class_ptr = mle_table_class_discover(interface_id); - - if (!mle_class_ptr) { - return 0; - } + mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list; uint16_t count = 0; - ns_list_foreach(mle_neigh_table_entry_t, entry, &mle_class_ptr->mle_table) { - if (!(entry->mode & MLE_RX_ON_IDLE)) { + ns_list_foreach(mac_neighbor_table_entry_t, entry, mac_table_list) { + if (!entry->rx_on_idle) { count++; } } @@ -367,18 +72,14 @@ int16_t mle_class_sleepy_entry_count_get(int8_t interface_id) return count; } -int16_t mle_class_rfd_entry_count_get(int8_t interface_id) +int16_t mle_class_rfd_entry_count_get(struct protocol_interface_info_entry *cur) { - mle_table_class_t *mle_class_ptr = mle_table_class_discover(interface_id); - - if (!mle_class_ptr) { - return 0; - } + mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list; uint16_t count = 0; - ns_list_foreach(mle_neigh_table_entry_t, entry, &mle_class_ptr->mle_table) { - if ((entry->mode & MLE_DEV_MASK) == MLE_RFD_DEV) { + ns_list_foreach(mac_neighbor_table_entry_t, entry, mac_table_list) { + if (!entry->ffd_device ) { count++; } } @@ -386,360 +87,24 @@ int16_t mle_class_rfd_entry_count_get(int8_t interface_id) return count; } -mle_neigh_table_entry_t *mle_class_get_entry_by_ll64(int8_t interface_id, uint8_t linkMargin, const uint8_t *ipv6Address, bool allocateNew, bool *new_entry_allocated) +uint16_t mle_class_active_neigh_counter(protocol_interface_info_entry_t *cur) { - // Check it really is LL64 (not LL16) - - if (memcmp(ipv6Address, ADDR_LINK_LOCAL_PREFIX , 8) != 0) { - return NULL; //Mot Link Local Address - } + mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list; - if (memcmp((ipv6Address + 8), ADDR_SHORT_ADR_SUFFIC , 6) == 0) { - return NULL; - } - // map - uint8_t temporary_mac64[8]; - memcpy(temporary_mac64, (ipv6Address + 8), 8); - temporary_mac64[0] ^= 2; - - return mle_class_get_entry_by_mac64(interface_id, linkMargin, temporary_mac64, allocateNew, new_entry_allocated); + return ns_list_count(mac_table_list); } -mle_neigh_table_entry_t *mle_class_discover_entry_by_ll64(int8_t interface_id, const uint8_t *ipv6Address) -{ - - // Check it really is LL64 (not LL16) - - if (memcmp(ipv6Address, ADDR_LINK_LOCAL_PREFIX , 8) != 0) { - return NULL; //Mot Link Local Address - } - - if (memcmp((ipv6Address + 8), ADDR_SHORT_ADR_SUFFIC , 6) == 0) { - return NULL; - } - // map - uint8_t temporary_mac64[8]; - memcpy(temporary_mac64, (ipv6Address + 8), 8); - temporary_mac64[0] ^= 2; - - return mle_class_get_by_link_address(interface_id, temporary_mac64, ADDR_802_15_4_LONG); -} - - -mle_neigh_table_entry_t *mle_class_get_entry_by_mac64(int8_t interface_id, uint8_t linkMargin, const uint8_t *mac64, bool allocateNew, bool *new_entry_allocated) -{ - mle_table_class_t *mle_class_ptr = mle_table_class_discover(interface_id); - //Clean list and set function pointer call backs - if (!mle_class_ptr) { - return NULL; - } - - if (new_entry_allocated) { - *new_entry_allocated = false; - } - - mle_neigh_table_entry_t *ret_val = mle_class_neighbor_get(&mle_class_ptr->mle_table, mac64, ADDR_802_15_4_LONG); - - - /* Look for existing entry */ - if (ret_val) { - ret_val->link_margin = ret_val->link_margin + linkMargin - (ret_val->link_margin >> THREAD_LINK_MARGIN_SCALING); - return ret_val; - } - - if (allocateNew) { - ret_val = mle_class_get_free_entry(&mle_class_ptr->free_enty_list); - - if (ret_val) { - //Add to active list - ns_list_add_to_start(&mle_class_ptr->mle_table, ret_val); - topo_trace(TOPOLOGY_MLE, mac64, TOPO_ADD); - ret_val->link_margin = linkMargin << THREAD_LINK_MARGIN_SCALING; - memcpy(ret_val->mac64, mac64, 8); - if (new_entry_allocated) { - *new_entry_allocated = true; - } - } - } - return ret_val; -} - -static mle_neigh_table_entry_t *mle_class_neighbor_get_by_attribute_index(mle_neigh_table_list_t *mle_table, uint8_t attribute_index) -{ - - ns_list_foreach(mle_neigh_table_entry_t, cur, mle_table) { - if (cur->attribute_index == attribute_index) { - return cur; - } - } - return NULL; -} - -static bool mle_class_neighbor_validate(mle_neigh_table_list_t *mle_table, const mle_neigh_table_entry_t *entry) -{ - - ns_list_foreach(mle_neigh_table_entry_t, cur, mle_table) { - if (cur == entry) { - return true; - } - } - return false; -} - -static mle_neigh_table_entry_t *mle_class_neighbor_get(mle_neigh_table_list_t *mle_table, const uint8_t *address, addrtype_t type) -{ - uint16_t short_id; - if (type == ADDR_802_15_4_SHORT) { - short_id = common_read_16_bit(address); - } - ns_list_foreach(mle_neigh_table_entry_t, cur, mle_table) { - - if (type == ADDR_802_15_4_SHORT) { - if (cur->short_adr == short_id) { - return cur; - } - } else { - if (memcmp(cur->mac64, address, 8) == 0) { - return cur; - } - } - - } - return NULL; -} - -static mle_neigh_table_entry_t *mle_class_get_free_entry(mle_neigh_table_list_t *mle_table) -{ - mle_neigh_table_entry_t *mle_entry = ns_list_get_first(mle_table); - if (mle_entry) { - //Remove from the list - ns_list_remove(mle_table, mle_entry); - uint8_t attribute_id = mle_entry->attribute_index; - memset(mle_entry, 0, sizeof(mle_neigh_table_entry_t)); - mle_entry->attribute_index = attribute_id; - mle_entry->short_adr = 0xffff; - mle_entry->mode = MLE_FFD_DEV | MLE_RX_ON_IDLE; - mle_entry->holdTime = 7; - mle_entry->last_contact_time = protocol_core_monotonic_time; - mle_entry->mle_frame_counter = 0; - mle_entry->last_key_sequence = 0; - mle_entry->new_key_pending = false; - mle_entry->medium_ttl_challenge = false; - } - - return mle_entry; -} - - - -mle_neigh_table_entry_t *mle_class_get_by_link_address(int8_t interface_id, const uint8_t *address, addrtype_t type) -{ - switch (type) { - case ADDR_802_15_4_SHORT: - case ADDR_802_15_4_LONG: - - break; - default: - return NULL; - } - - mle_table_class_t *mle_class_ptr = mle_table_class_discover(interface_id); - //Clean list and set function pointer call backs - if (!mle_class_ptr) { - return NULL; - } - - return mle_class_neighbor_get(&mle_class_ptr->mle_table, address, type); - -} - -mle_neigh_table_entry_t *mle_class_get_by_device_attribute_id(int8_t interface_id, uint8_t attribute_index) -{ - mle_table_class_t *mle_class_ptr = mle_table_class_discover(interface_id); - //Clean list and set function pointer call backs - if (!mle_class_ptr) { - return NULL; - } - - return mle_class_neighbor_get_by_attribute_index(&mle_class_ptr->mle_table, attribute_index); - -} - -int8_t mle_class_remove_entry(int8_t interface_id, mle_neigh_table_entry_t *entry) -{ - mle_table_class_t *mle_class_ptr = mle_table_class_discover(interface_id); - //Clean list and set function pointer call backs - if (!mle_class_ptr) { - return -1; - } - - //Validate Pointer - if (!mle_class_neighbor_validate(&mle_class_ptr->mle_table, entry)) { - return -2; - } - //Remove from list - ns_list_remove(&mle_class_ptr->mle_table, entry); - //Free Indirect Queue - mle_table_remove_free_indirect_table(mle_class_ptr->interfaceId, entry); - //Call Remove callback - mle_class_ptr->remove_cb(mle_class_ptr->interfaceId, entry); - topo_trace(TOPOLOGY_MLE, entry->ext64, TOPO_REMOVE); - - //Removes ETX neighbor - etx_neighbor_remove(interface_id, entry); - //Add to free list - ns_list_add_to_start(&mle_class_ptr->free_enty_list, entry); - return 0; -} +#ifndef NO_MLE -int8_t mle_class_remove_neighbour(int8_t interface_id, const uint8_t *address, addrtype_t type) +int8_t mle_class_set_new_key_pending(struct protocol_interface_info_entry *cur) { - mle_table_class_t *mle_class_ptr = mle_table_class_discover(interface_id); - //Clean list and set function pointer call backs - if (!mle_class_ptr) { - return -1; - } + mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list; - mle_neigh_table_entry_t * entry = mle_class_get_by_link_address(interface_id, address, type); - if (!entry) { - return -2; + ns_list_foreach_safe(mac_neighbor_table_entry_t, cur_entry, mac_table_list) { + mle_service_frame_counter_entry_new_key_pending_set(cur->id, cur_entry->index); } - //Remove from list - ns_list_remove(&mle_class_ptr->mle_table, entry); - //Free Indirect Queue - mle_table_remove_free_indirect_table(mle_class_ptr->interfaceId, entry); - //Call Remove callback - mle_class_ptr->remove_cb(mle_class_ptr->interfaceId, entry); - - topo_trace(TOPOLOGY_MLE, entry->ext64, TOPO_REMOVE); - - //Removes ETX neighbor - etx_neighbor_remove(interface_id, entry); - //Add to free list - ns_list_add_to_start(&mle_class_ptr->free_enty_list, entry); return 0; - -} - - - -static void mle_class_table_ttl(uint16_t ticks, mle_table_class_t *mle_class_ptr) -{ - uint16_t new_ttl; - bool challengeCheck; - bool remove_entry; - - //validate that interface is still active - if (!mle_class_ptr->interface_is_active(mle_class_ptr->interfaceId)) { - return; - } - - ns_list_foreach_safe(mle_neigh_table_entry_t, cur, &mle_class_ptr->mle_table) { - new_ttl = 0; - remove_entry = false; - switch (mle_class_ptr->mode) { - case MLE_CLASS_END_DEVICE: - if (cur->priorityFlag) { - challengeCheck = true; - } else { - challengeCheck = false; - } - break; - case MLE_CLASS_ROUTER: //Router and sleepy end device never do challenge - default: - challengeCheck = false; - break; - } - - if (challengeCheck) { - if (cur->ttl > MLE_TABLE_CHALLENGE_TIMER || cur->ttl < MLE_TABLE_CHALLENGE_TIMER) { - new_ttl = ticks + MLE_TABLE_CHALLENGE_TIMER; - } - - if (cur->ttl <= new_ttl) { - if (cur->ttl != 1) { - if (mle_class_ptr->keep_alive_cb(mle_class_ptr->interfaceId, cur->mac64) != 0) { - cur->ttl--; - if (cur->ttl == 1) { - remove_entry = true; - } - } else { - cur->ttl = 1; //Lock retries here - } - } - } else { - cur->ttl -= ticks; - } - } else { - if (ticks >= cur->ttl) { - - remove_entry = true; - } else { - cur->ttl -= ticks; - } - } - - if (remove_entry) { - //Silence delete - //Remove from list - ns_list_remove(&mle_class_ptr->mle_table, cur); - //Free Indirect Queue - mle_table_remove_free_indirect_table(mle_class_ptr->interfaceId, cur); - mle_class_ptr->remove_cb(mle_class_ptr->interfaceId, cur); - topo_trace(TOPOLOGY_MLE, cur->ext64, TOPO_REMOVE); - //Removes ETX neighbor - etx_neighbor_remove(mle_class_ptr->interfaceId, cur); - //Add to free list - ns_list_add_to_start(&mle_class_ptr->free_enty_list, cur); - - } - } // for each entry - - //Router to Router Challenge timeout for big network and FHSS systems which could loose broadcast messages. - if (mle_class_ptr->challenge_cb && mle_class_ptr->mode == MLE_CLASS_ROUTER) { - //Calculate timeout trigger - uint8_t challenge_count = 0; - ns_list_foreach_safe(mle_neigh_table_entry_t, cur, &mle_class_ptr->mle_table) { - if (((cur->mode & MLE_DEV_MASK) == MLE_FFD_DEV) && !cur->medium_ttl_challenge) { - //Challenge Neighbour - if (cur->ttl < (cur->timeout_rx / 2)) { - if (mle_class_ptr->challenge_cb(mle_class_ptr->interfaceId, cur->mac64) != 0) { - tr_error("Router2Router challenge start fail"); - return; - } - cur->medium_ttl_challenge = true; - if (++challenge_count == 2) { - //trig only 2 active / 4 second period. - return; - } - } - } - } - } -} - - -mle_neigh_table_list_t *mle_class_active_list_get(int8_t interface_id) -{ - mle_table_class_t *mle_class_ptr = mle_table_class_discover(interface_id); - //Clean list and set function pointer call backs - if (!mle_class_ptr) { - return NULL; - } - return &mle_class_ptr->mle_table; -} - -uint16_t mle_class_active_neigh_counter(int8_t interface_id) -{ - mle_table_class_t *mle_class_ptr = mle_table_class_discover(interface_id); - //Clean list and set function pointer call backs - if (!mle_class_ptr) { - return 0xffff; - } - - - return ns_list_count(&mle_class_ptr->mle_table); } uint8_t *mle_general_write_source_address(uint8_t *ptr, protocol_interface_info_entry_t *cur) @@ -760,26 +125,7 @@ uint8_t *mle_general_write_link_layer_framecounter(uint8_t *ptr, protocol_interf return mle_tlv_write_link_layer_framecount(ptr, temp_counter); } -static void mle_event_handler(arm_event_s *event) -{ - switch (event->event_type) { - case ARM_MLE_INIT: - tr_debug("MLE Tasklet Generated"); - break; - - case ARM_MLE_TTL_TIMER: - //Do list in future for each of mle user - //Set here mle class ttl update - ns_list_foreach_safe(mle_table_class_t, mle_clas_entry, &mle_table_calss_list) { - mle_class_table_ttl(1, mle_clas_entry); - } - - - break; - } -} - -bool mle_neigh_entry_frame_counter_update(mle_neigh_table_entry_t *entry_temp, uint8_t *tlv_ptr, uint16_t tlv_length, protocol_interface_info_entry_t *cur, uint8_t key_id) +bool mle_neigh_entry_frame_counter_update(struct mac_neighbor_table_entry *entry_temp, uint8_t *tlv_ptr, uint16_t tlv_length, protocol_interface_info_entry_t *cur, uint8_t key_id) { mle_tlv_info_t mle_tlv_info; uint32_t frame_counter; @@ -792,58 +138,31 @@ bool mle_neigh_entry_frame_counter_update(mle_neigh_table_entry_t *entry_temp, u } else { frame_counter = common_read_32_bit(mle_tlv_info.dataPtr); } - - mac_helper_devicetable_set(entry_temp, cur, frame_counter, key_id, false); + mlme_device_descriptor_t device_desc; + mac_helper_device_description_write(cur, &device_desc, entry_temp->mac64, entry_temp->mac16,frame_counter, false); + mac_helper_devicetable_set(&device_desc, cur, entry_temp->index, key_id, false); return true; } -void mle_entry_timeout_update(mle_neigh_table_entry_t *entry_temp, uint32_t timeout_tlv) -{ - if (timeout_tlv > 86400) { - timeout_tlv = 86400; - } else if (timeout_tlv == 0) { - timeout_tlv = 500; - } - timeout_tlv /= MLE_TIMER_TICKS_SECONDS; - timeout_tlv++; - entry_temp->timeout_rx = timeout_tlv; - mle_entry_timeout_refresh(entry_temp); -} -void mle_entry_timeout_refresh(mle_neigh_table_entry_t *entry_temp) +void mle_mode_parse_to_mac_entry(mac_neighbor_table_entry_t *mac_entry, uint8_t mode) { - entry_temp->ttl = entry_temp->timeout_rx; - entry_temp->last_contact_time = protocol_core_monotonic_time; - entry_temp->medium_ttl_challenge = false; + mac_entry->rx_on_idle = mode & MLE_RX_ON_IDLE; + mac_entry->ffd_device = mode & MLE_FFD_DEV; } -static void mle_refresh_entry(mle_neigh_table_entry_t *neig_info, bool dataPollConfirmation) +uint8_t mle_mode_write_from_mac_entry(mac_neighbor_table_entry_t *mac_entry) { - if (!neig_info) { - return; - } - if (!neig_info->handshakeReady) { - tr_debug("refresh:Link Handshake not ready yet"); - return; + uint8_t mode = 0; + if (mac_entry->rx_on_idle) { + mode |= MLE_RX_ON_IDLE; } - neig_info->last_contact_time = protocol_core_monotonic_time; - neig_info->medium_ttl_challenge = false; - - if (dataPollConfirmation) { - if (neig_info->ttl > MLE_TABLE_CHALLENGE_TIMER) { - neig_info->ttl = neig_info->timeout_rx; - } - } else { - neig_info->ttl = neig_info->timeout_rx; + if (mac_entry->ffd_device) { + mode |= MLE_FFD_DEV; } + return mode; } -mle_neigh_table_entry_t *mle_refresh_entry_timeout(int8_t interfaceId, const uint8_t *addressPtr, addrtype_t addressType, bool dataPollConfirmation) -{ - mle_neigh_table_entry_t * neigh_info = mle_class_get_by_link_address(interfaceId, addressPtr, addressType); - mle_refresh_entry(neigh_info, dataPollConfirmation); - return neigh_info; -} #endif /* NO_MLE */ diff --git a/features/nanostack/sal-stack-nanostack/source/MLE/mle.h b/features/nanostack/sal-stack-nanostack/source/MLE/mle.h index 3d16cdec4050..6cd67cd5f1d7 100644 --- a/features/nanostack/sal-stack-nanostack/source/MLE/mle.h +++ b/features/nanostack/sal-stack-nanostack/source/MLE/mle.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017, Arm Limited and affiliates. + * Copyright (c) 2013-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -23,14 +23,7 @@ #include "ns_list.h" struct buffer; - -#ifndef MAX_MLE_INFO_CNT -#ifdef CORTEXM3_STM32W108CC -#define MAX_MLE_INFO_CNT 40 -#else -#define MAX_MLE_INFO_CNT 256 -#endif -#endif +struct mac_neighbor_table_entry; #define MLE_MAX_ROUTERS 64 /* Route option layout: 1 Sequence byte, ID mask (bit per router), Data (byte per valid ID) */ @@ -131,118 +124,25 @@ typedef enum mle_tlv_type_t_ { #define MLE_FFD_DEV 2 #define MLE_RFD_DEV 0 #define MLE_RX_ON_IDLE 8 -/** Thead Spesific ModeFlags */ -#define MLE_THREAD_SECURED_DATA_REQUEST 0x04 -#define MLE_THREAD_REQ_FULL_DATA_SET 0x01 - -#define MLE_TIMER_TICKS_SECONDS 4 -#define MLE_TIMER_TICKS_MS (MLE_TIMER_TICKS_SECONDS*1000) -#define MLE_TABLE_CHALLENGE_TIMER 3 +#define MLE_TABLE_CHALLENGE_TIMER 12 #define MLE_NEIGHBOR_PRIORITY_LINK (1 << 5) #define MLE_NEIGHBOR_OUTGOING_LINK (1 << 6) #define MLE_NEIGHBOR_INCOMING_LINK (1 << 7) -typedef struct mle_neigh_table_entry_t { - uint8_t attribute_index; - uint16_t ttl; /*!< destination TTL * 4 seconds */ - uint32_t last_contact_time; /*!< monotonic time - hard to define "contact"; used for Thread Leasequery replies */ - uint32_t mle_frame_counter; - uint16_t timeout_rx; - uint16_t holdTime; - uint16_t link_margin; - uint8_t mac64[8]; /*!< MAC64 */ - uint8_t mlEid[8]; - uint16_t short_adr; - uint8_t mode; - uint16_t etx; /*!< 12 bits fraction */ - uint16_t stored_diff_etx; /*!< 12 bits fraction */ - uint8_t remote_incoming_idr; /*!< 5 bits fraction */ - uint32_t last_key_sequence; - unsigned accumulated_failures: 5; - unsigned new_key_pending:1; - unsigned link_q_adv_sent: 1; - unsigned tmp_etx: 1; - unsigned priority_child_flag: 1; /* Is using our node as preferred parent */ - unsigned second_priority_flag: 1; /* Is secondary parent */ - unsigned thread_commission: 1; - unsigned threadNeighbor: 1; - unsigned priorityFlag: 1; - unsigned handshakeReady: 1; - unsigned medium_ttl_challenge: 1; - unsigned linkIdr: 4; - ns_list_link_t link; -} mle_neigh_table_entry_t ; - -typedef NS_LIST_HEAD(mle_neigh_table_entry_t, link) mle_neigh_table_list_t; - - -/* MLE TLV types */ -typedef enum mle_class_user_mode { - MLE_CLASS_ROUTER = 0, - MLE_CLASS_END_DEVICE, - MLE_CLASS_SLEEPY_END_DEVICE, -} mle_class_user_mode; - -//MLE table class function pointer types -/** - * Remove entry notify - */ -typedef void mle_entry_user_entry_remove_notify(int8_t interface_id, mle_neigh_table_entry_t *entry_ptr); - -typedef int8_t mle_entry_link_keep_alive(int8_t interface_id, const uint8_t *mac64); - -typedef bool mle_entry_interface_activate(int8_t interface_id); - -int8_t mle_class_init(int8_t interface_id, uint8_t table_size, mle_entry_user_entry_remove_notify *remove_cb, mle_entry_link_keep_alive *keep_alive_cb, mle_entry_interface_activate *interface_is_active); - -int8_t mle_class_router_challenge(int8_t interface_id,mle_entry_link_keep_alive *challenge_cb); - -bool mle_class_exists_for_interface(int8_t interface_id); - -int8_t mle_class_deallocate(int8_t interface_id); - -int8_t mle_class_list_clean(int8_t interface_id); - -int8_t mle_class_mode_set(int8_t interface_id,mle_class_user_mode mode); - -int8_t mle_class_set_new_key_pending(int8_t interface_id); - -int16_t mle_class_free_entry_count_get(int8_t interface_id); - -mle_neigh_table_entry_t *mle_class_get_entry_by_ll64(int8_t interface_id, uint8_t linkMargin, const uint8_t *ipv6Address, bool allocateNew, bool *new_entry_allocated); - -mle_neigh_table_entry_t *mle_class_discover_entry_by_ll64(int8_t interface_id, const uint8_t *ipv6Address); - -mle_neigh_table_entry_t *mle_class_get_entry_by_mac64(int8_t interface_id, uint8_t linkMargin, const uint8_t *mac64, bool allocateNew, bool *new_entry_allocated); - -mle_neigh_table_entry_t *mle_class_get_by_link_address(int8_t interface_id, const uint8_t *address, addrtype_t type); - -mle_neigh_table_entry_t *mle_class_get_by_device_attribute_id(int8_t interface_id, uint8_t attribute_index); - -int8_t mle_class_remove_entry(int8_t interface_id, mle_neigh_table_entry_t *entry); - -int8_t mle_class_remove_neighbour(int8_t interface_id, const uint8_t *address, addrtype_t type); - -mle_neigh_table_list_t *mle_class_active_list_get(int8_t interface_id); - -int16_t mle_class_sleepy_entry_count_get(int8_t interface_id); -int16_t mle_class_rfd_entry_count_get(int8_t interface_id); - -uint16_t mle_class_active_neigh_counter(int8_t interface_id); - -/** - * Function to refresh Neigh Entry when get some trusted response or spesified place - */ -mle_neigh_table_entry_t *mle_refresh_entry_timeout(int8_t interfaceId, const uint8_t *addressPtr, addrtype_t addressType, bool dataPollConfirmation); - -bool mle_neigh_entry_frame_counter_update(mle_neigh_table_entry_t *entry_temp, uint8_t *tlv_ptr, uint16_t tlv_length, struct protocol_interface_info_entry *cur, uint8_t key_id); +int8_t mle_class_set_new_key_pending(struct protocol_interface_info_entry *cur); +int16_t mle_class_free_entry_count_get(struct protocol_interface_info_entry *cur); +int16_t mle_class_sleepy_entry_count_get(struct protocol_interface_info_entry *cur); +int16_t mle_class_rfd_entry_count_get(struct protocol_interface_info_entry *cur); +uint16_t mle_class_active_neigh_counter(struct protocol_interface_info_entry *cur); +bool mle_neigh_entry_frame_counter_update(struct mac_neighbor_table_entry *entry_temp, uint8_t *tlv_ptr, uint16_t tlv_length, struct protocol_interface_info_entry *cur, uint8_t key_id); uint8_t *mle_general_write_source_address(uint8_t *ptr, struct protocol_interface_info_entry *cur); uint8_t *mle_general_write_link_layer_framecounter(uint8_t *ptr, struct protocol_interface_info_entry *cur); -void mle_entry_timeout_update(mle_neigh_table_entry_t *entry_temp, uint32_t timeout_tlv); -void mle_entry_timeout_refresh(mle_neigh_table_entry_t *entry_temp); + +void mle_mode_parse_to_mac_entry(struct mac_neighbor_table_entry *mac_entry, uint8_t mode); +uint8_t mle_mode_write_from_mac_entry(struct mac_neighbor_table_entry *mac_entry); #endif /* MLE_H_ */ diff --git a/features/nanostack/sal-stack-nanostack/source/MPL/mpl.c b/features/nanostack/sal-stack-nanostack/source/MPL/mpl.c index 9ad06d49d3be..13ad35e10e6d 100644 --- a/features/nanostack/sal-stack-nanostack/source/MPL/mpl.c +++ b/features/nanostack/sal-stack-nanostack/source/MPL/mpl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/features/nanostack/sal-stack-nanostack/source/NWK_INTERFACE/Include/protocol.h b/features/nanostack/sal-stack-nanostack/source/NWK_INTERFACE/Include/protocol.h index 1e7290c1184d..de582791d74a 100644 --- a/features/nanostack/sal-stack-nanostack/source/NWK_INTERFACE/Include/protocol.h +++ b/features/nanostack/sal-stack-nanostack/source/NWK_INTERFACE/Include/protocol.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -45,6 +45,7 @@ #include "Service_Libs/Neighbor_cache/neighbor_table_definition.h" #include "Service_Libs/Trickle/trickle.h" #include "Service_Libs/pan_blacklist/pan_blacklist_api.h" +#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h" #include "net_polling_api.h" #include "ipv6_stack/ipv6_routing_table.h" @@ -246,6 +247,7 @@ typedef struct arm_15_4_mac_parameters_t { beacon_compare_rx_cb *beacon_compare_rx_cb_ptr; beacon_join_priority_tx_cb *beacon_join_priority_tx_cb_ptr; uint8_t (*beacon_ind)(uint8_t *ptr, uint8_t len, protocol_interface_info_entry_t *cur); + mac_neighbor_table_t *mac_neighbor_table; }arm_15_4_mac_parameters_t; typedef void mac_poll_fail_cb(int8_t nwk_interface_id); @@ -316,6 +318,7 @@ typedef struct { } ipv6_interface_info_t; struct thread_info_s; +struct ws_info_s; struct mesh_callbacks_s; struct auth_info; struct rpl_domain; @@ -339,7 +342,6 @@ typedef void beacon_indication_cb(int8_t if_id, const mlme_beacon_ind_t* conf); typedef void comm_status_indication_cb(int8_t if_id, const mlme_comm_status_t* status); - struct protocol_interface_info_entry { beacon_indication_cb *beacon_cb; scan_confirm_cb *scan_cb; @@ -444,6 +446,9 @@ struct protocol_interface_info_entry { pan_coordinator_blaclist_cache_s pan_cordinator_black_list; #ifdef HAVE_THREAD struct thread_info_s *thread_info; +#endif +#ifdef HAVE_WS + struct ws_info_s *ws_info; #endif struct rpl_domain *rpl_domain; struct mesh_callbacks_s *mesh_callbacks; @@ -470,6 +475,7 @@ struct protocol_interface_info_entry { uint8_t (*if_llao_parse)(struct protocol_interface_info_entry *cur, const uint8_t *opt_in, sockaddr_t *ll_addr_out); uint8_t (*if_llao_write)(struct protocol_interface_info_entry *cur, uint8_t *opt_out, uint8_t opt_type, bool must, const uint8_t *ip_addr); void (*mac_security_key_usage_update_cb)(struct protocol_interface_info_entry *cur, const struct mlme_security_s *security_params); + uint16_t (*etx_read_override)(struct protocol_interface_info_entry *cur, addrtype_t addr_type, const uint8_t *addr_ptr); }; typedef NS_LIST_HEAD(protocol_interface_info_entry_t, link) protocol_interface_list_t; diff --git a/features/nanostack/sal-stack-nanostack/source/NWK_INTERFACE/Include/protocol_abstract.h b/features/nanostack/sal-stack-nanostack/source/NWK_INTERFACE/Include/protocol_abstract.h index 3c9100caa712..78aa552c3867 100644 --- a/features/nanostack/sal-stack-nanostack/source/NWK_INTERFACE/Include/protocol_abstract.h +++ b/features/nanostack/sal-stack-nanostack/source/NWK_INTERFACE/Include/protocol_abstract.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,6 +21,7 @@ #include "ns_types.h" struct rpl_domain; +struct fhss_api; /*! * \enum nwk_interface_id @@ -43,5 +44,6 @@ extern int protocol_core_buffers_in_event_queue; protocol_interface_info_entry_t *protocol_stack_interface_info_get_by_id(int8_t nwk_id); protocol_interface_info_entry_t *protocol_stack_interface_info_get_by_bootstrap_id(int8_t id); protocol_interface_info_entry_t *protocol_stack_interface_info_get_by_rpl_domain(const struct rpl_domain *domain, int8_t last_id); +protocol_interface_info_entry_t *protocol_stack_interface_info_get_by_fhss_api(const struct fhss_api *fhss_api); #endif /* NWK_INTERFACE_INCLUDE_PROTOCOL_ABSTRACT_H_ */ diff --git a/features/nanostack/sal-stack-nanostack/source/NWK_INTERFACE/protocol_core.c b/features/nanostack/sal-stack-nanostack/source/NWK_INTERFACE/protocol_core.c index 2950b79964e3..5cb03ce1a382 100644 --- a/features/nanostack/sal-stack-nanostack/source/NWK_INTERFACE/protocol_core.c +++ b/features/nanostack/sal-stack-nanostack/source/NWK_INTERFACE/protocol_core.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -64,6 +64,8 @@ #include "6LoWPAN/Thread/thread_bootstrap.h" #include "6LoWPAN/Thread/thread_routing.h" #include "6LoWPAN/Thread/thread_management_internal.h" +#include "6LoWPAN/ws/ws_bootstrap.h" +#include "6LoWPAN/ws/ws_common.h" #include "ipv6_stack/protocol_ipv6.h" #include "Service_Libs/whiteboard/whiteboard.h" @@ -242,10 +244,16 @@ void core_timer_event_handle(uint16_t ticksUpdate) if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) { if (thread_info(cur)) { thread_seconds_timer(cur, seconds); + } else if (ws_info(cur)) { + ws_common_seconds_timer(cur, seconds); } else if (cur->lowpan_info & INTERFACE_NWK_ROUTER_DEVICE) { beacon_join_priority_update(cur->id); } + if (cur->mac_parameters) { + mac_neighbor_table_neighbor_timeout_update(mac_neighbor_info(cur), seconds); + } + if (cur->nwk_wpan_nvm_api) { cur->nwk_wpan_nvm_api->nvm_params_update_cb(cur->nwk_wpan_nvm_api, false); } @@ -304,6 +312,8 @@ void core_timer_event_handle(uint16_t ticksUpdate) nd_object_timer(cur,ticksUpdate); if (thread_info(cur)) { thread_timer(cur, ticksUpdate); + } else if (ws_info(cur)) { + ws_common_fast_timer(cur, ticksUpdate); } lowpan_context_timer(&cur->lowpan_contexts, ticksUpdate); } @@ -383,6 +393,11 @@ void protocol_core_interface_info_reset(protocol_interface_info_entry_t *entry) ns_list_foreach_safe(if_address_entry_t, addr, &entry->ip_addresses) { addr_delete_entry(entry, addr); } +#ifdef MULTICAST_FORWARDING + ns_list_foreach_safe(if_group_fwd_entry_t, group, &entry->ip_groups_fwd) { + addr_multicast_fwd_remove(entry, group->group); + } +#endif #ifdef HAVE_RPL /* This is done after address deletion, so RPL can act on them */ rpl_control_remove_domain_from_interface(entry); @@ -759,6 +774,20 @@ protocol_interface_info_entry_t *protocol_stack_interface_info_get_by_rpl_domain return NULL; } +protocol_interface_info_entry_t *protocol_stack_interface_info_get_by_fhss_api(const struct fhss_api *fhss_api) +{ +#ifdef HAVE_WS + ns_list_foreach(protocol_interface_info_entry_t, cur, &protocol_interface_info_list) { + if (cur->ws_info->fhss_api == fhss_api) { + return cur; + } + } +#else + (void)fhss_api; +#endif //HAVE_WS + return NULL; +} + protocol_interface_info_entry_t *protocol_stack_interface_sleep_possibility(void) { ns_list_foreach(protocol_interface_info_entry_t, cur, &protocol_interface_info_list) { @@ -1059,6 +1088,8 @@ void net_bootsrap_cb_run(uint8_t event) //eventOS_scheduler_set_active_tasklet(protocol_read_tasklet_id()); if (thread_info(cur)) { thread_bootstrap_state_machine(cur); + } else if (ws_info(cur)) { + ws_bootstrap_state_machine(cur); } else { protocol_6lowpan_bootstrap(cur); } diff --git a/features/nanostack/sal-stack-nanostack/source/RPL/rpl_control.c b/features/nanostack/sal-stack-nanostack/source/RPL/rpl_control.c index 703f81c261f7..e95865bfad75 100644 --- a/features/nanostack/sal-stack-nanostack/source/RPL/rpl_control.c +++ b/features/nanostack/sal-stack-nanostack/source/RPL/rpl_control.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -45,7 +45,7 @@ #include "NWK_INTERFACE/Include/protocol_stats.h" #include "Common_Protocols/ipv6_constants.h" #include "Common_Protocols/icmpv6.h" - +#include "ipv6_stack/protocol_ipv6.h" #include "Service_Libs/etx/etx.h" /* slight ick */ #include "net_rpl.h" @@ -182,6 +182,51 @@ void rpl_control_unpublish_address(rpl_domain_t *domain, const uint8_t addr[16]) } } +static if_address_entry_t *rpl_instance_reg_addr_get(protocol_interface_info_entry_t *interface) +{ + ns_list_foreach(if_address_entry_t, address, &interface->ip_addresses) { + if (!address->addr_reg_done && !addr_is_ipv6_link_local(address->address)) { + return address; + } + } + + return NULL; +} + +/* Send address registration to either specified address, or to non-registered address */ +void rpl_control_register_address(protocol_interface_info_entry_t *interface, if_address_entry_t *addr) +{ + if_address_entry_t *reg_addr = addr; + + if (!reg_addr) { + reg_addr = rpl_instance_reg_addr_get(interface); + + if (!reg_addr) { + return; + } + } + ns_list_foreach(struct rpl_instance, instance, &interface->rpl_domain->instances) { + rpl_instance_send_address_registration(interface, instance, reg_addr); + } +} + +void rpl_control_address_register_done(struct buffer *buf, uint8_t status) +{ + ns_list_foreach(if_address_entry_t, addr, &buf->interface->ip_addresses) { + + /* Optimize, ll addresses are not registered anyway.. */ + if (addr_is_ipv6_link_local(addr->address) || !addr->addr_reg_pend) { + continue; + } + + ns_list_foreach(struct rpl_instance, instance, &buf->interface->rpl_domain->instances) { + if (rpl_instance_address_registration_done(buf->interface, instance, addr, status)) { + return; + } + } + } +} + /* Address changes need to trigger DAO target re-evaluation */ static void rpl_control_addr_notifier(struct protocol_interface_info_entry *interface, const if_address_entry_t *addr, if_address_callback_t reason) { @@ -209,11 +254,10 @@ static void rpl_control_addr_notifier(struct protocol_interface_info_entry *inte } } -static void rpl_control_etx_change_callback(int8_t nwk_id, uint16_t previous_etx, uint16_t current_etx, const uint8_t *mac64_addr_ptr, uint16_t mac16_addr) +static void rpl_control_etx_change_callback(int8_t nwk_id, uint16_t previous_etx, uint16_t current_etx, uint8_t attribute_index) { (void)previous_etx; (void)current_etx; - (void)mac16_addr; protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(nwk_id); if (!cur || !cur->rpl_domain) { @@ -221,7 +265,7 @@ static void rpl_control_etx_change_callback(int8_t nwk_id, uint16_t previous_et } rpl_domain_t *domain = cur->rpl_domain; uint16_t delay = rpl_policy_etx_change_parent_selection_delay(domain); - tr_debug("Triggering parent selection due to ETX change on %s", trace_array(mac64_addr_ptr, 8)); + tr_debug("Triggering parent selection due to ETX change on neigh index %u, etx %u", attribute_index, current_etx); ns_list_foreach(rpl_instance_t, instance, &domain->instances) { rpl_instance_trigger_parent_selection(instance, delay); @@ -411,7 +455,7 @@ void rpl_control_delete_dodag_root(rpl_domain_t *domain, rpl_dodag_t *dodag) { (void)domain; - rpl_delete_dodag(dodag); + rpl_delete_dodag_root(dodag); } void rpl_control_update_dodag_route(rpl_dodag_t *dodag, const uint8_t *prefix, uint8_t prefix_len, uint8_t flags, uint32_t lifetime, bool age) @@ -628,15 +672,26 @@ static void rpl_control_process_prefix_options(protocol_interface_info_entry_t * } uint8_t prefix_len = ptr[2]; uint8_t flags = ptr[3]; - uint32_t preferred = common_read_32_bit(ptr + 4); - uint32_t valid = common_read_32_bit(ptr + 8); + uint32_t valid = common_read_32_bit(ptr + 4); + uint32_t preferred = common_read_32_bit(ptr + 8); const uint8_t *prefix = ptr + 16; if (!pref_parent || neighbour == pref_parent) { - /* XXX We don't yet locally handle A and L flags. Presumably should - * only locally process for DODAG's we're a member of? Should we - * process now, or later? + //Check is L Flag active + if (flags & PIO_L) { + //define ONLink Route Information + //tr_debug("Register On Link Prefix to routing table"); + ipv6_route_add(prefix, prefix_len, cur->id, NULL, ROUTE_RADV, valid, 0); + } + /* Check if A-Flag. + * A RPL node may use this option for the purpose of Stateless Address Autoconfiguration (SLAAC) + * from a prefix advertised by a parent. */ + if (pref_parent && (flags & PIO_A)) { + if (icmpv6_slaac_prefix_update(cur, prefix, prefix_len, valid, preferred) != 0) { + ipv6_interface_slaac_handler(cur, prefix, prefix_len, valid, preferred); + } + } /* Store prefixes for possible forwarding */ /* XXX if leaf - don't bother? Or do we want to remember them for @@ -1602,6 +1657,12 @@ const uint8_t *rpl_control_preferred_parent_addr(const rpl_instance_t *instance, } } +uint16_t rpl_control_current_rank(const struct rpl_instance *instance) +{ + return rpl_instance_current_rank(instance); +} + + static void rpl_domain_print(const rpl_domain_t *domain, route_print_fn_t *print_fn) { print_fn("RPL Domain %p", (void *) domain); diff --git a/features/nanostack/sal-stack-nanostack/source/RPL/rpl_control.h b/features/nanostack/sal-stack-nanostack/source/RPL/rpl_control.h index 6b6ff40f82dd..72f778855141 100644 --- a/features/nanostack/sal-stack-nanostack/source/RPL/rpl_control.h +++ b/features/nanostack/sal-stack-nanostack/source/RPL/rpl_control.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -143,6 +143,8 @@ void rpl_control_set_callback(rpl_domain_t *domain, rpl_domain_callback_t callba /* Target publishing */ void rpl_control_publish_host_address(rpl_domain_t *domain, const uint8_t addr[16], uint32_t lifetime); void rpl_control_unpublish_address(rpl_domain_t *domain, const uint8_t addr[16]); +void rpl_control_register_address(struct protocol_interface_info_entry *interface, if_address_entry_t *addr); +void rpl_control_address_register_done(struct buffer *buf, uint8_t status); /* Configure and return the routing lookup predicate for a specified RPL instance ID */ ipv6_route_predicate_fn_t *rpl_control_get_route_predicate(rpl_domain_t *domain, uint8_t instance_id, const uint8_t src[16], const uint8_t dst[16]); @@ -156,12 +158,16 @@ bool rpl_control_get_instance_dao_target_count(rpl_domain_t *domain, uint8_t ins bool rpl_control_read_dodag_info(const struct rpl_instance *instance, struct rpl_dodag_info_t *dodag_info); const rpl_dodag_conf_t *rpl_control_get_dodag_config(const struct rpl_instance *instance); const uint8_t *rpl_control_preferred_parent_addr(const struct rpl_instance *instance, bool global); +uint16_t rpl_control_current_rank(const struct rpl_instance *instance); + #else /* HAVE_RPL */ #define rpl_control_fast_timer(ticks) ((void) 0) #define rpl_control_slow_timer(seconds) ((void) 0) #define rpl_control_remove_domain_from_interface(cur) ((void) 0) +#define rpl_control_register_address(interface, addr) ((void) 0) +#define rpl_control_address_register_done NULL #endif /* HAVE_RPL */ diff --git a/features/nanostack/sal-stack-nanostack/source/RPL/rpl_data.c b/features/nanostack/sal-stack-nanostack/source/RPL/rpl_data.c index 4c3a84a57e13..d599133e7ed8 100644 --- a/features/nanostack/sal-stack-nanostack/source/RPL/rpl_data.c +++ b/features/nanostack/sal-stack-nanostack/source/RPL/rpl_data.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/features/nanostack/sal-stack-nanostack/source/RPL/rpl_downward.c b/features/nanostack/sal-stack-nanostack/source/RPL/rpl_downward.c index d9c98dc63d8c..8e040e5c67ed 100644 --- a/features/nanostack/sal-stack-nanostack/source/RPL/rpl_downward.c +++ b/features/nanostack/sal-stack-nanostack/source/RPL/rpl_downward.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -88,6 +88,7 @@ #include "randLIB.h" #include "ip6string.h" +#include "Common_Protocols/icmpv6.h" #include "NWK_INTERFACE/Include/protocol.h" #include "ipv6_stack/ipv6_routing_table.h" @@ -580,6 +581,61 @@ static void rpl_downward_reset_assigning(rpl_instance_t *instance, uint8_t pcs_m } +void rpl_instance_send_address_registration(protocol_interface_info_entry_t *interface, rpl_instance_t *instance, if_address_entry_t *addr) +{ + aro_t aro; + buffer_t *buf; + + aro.status = ARO_SUCCESS; + aro.present = true; + aro.lifetime = addr->preferred_lifetime; + memcpy(aro.eui64, interface->mac, 8); + + // go through neighbour list, and send to all assigned parents. + ns_list_foreach(rpl_neighbour_t, neighbour, &instance->candidate_neighbours) { + if (neighbour->dao_path_control) { + tr_debug("Send ARO %s to %s", trace_ipv6(addr->address), trace_ipv6(neighbour->ll_address)); + buf = icmpv6_build_ns(interface, neighbour->ll_address, addr->address, true, false, &aro); + addr->addr_reg_pend |= neighbour->dao_path_control; + protocol_push(buf); + } else { + tr_debug("Skip ARO to %s - no pc", trace_ipv6(neighbour->ll_address)); + } + } +} + +bool rpl_instance_address_registration_done(protocol_interface_info_entry_t *interface, rpl_instance_t *instance, if_address_entry_t *addr, uint8_t status) +{ + ns_list_foreach(rpl_neighbour_t, neighbour, &instance->candidate_neighbours) { + // Check path control mask + if (!(addr->addr_reg_pend & neighbour->dao_path_control)) { + continue; + } + + tr_debug("Address %s register to %s", trace_ipv6(addr->address), trace_ipv6(neighbour->ll_address)); + + /* Clear pending flag */ + addr->addr_reg_pend &= ~neighbour->dao_path_control; + + if (status == SOCKET_TX_DONE) { + addr->addr_reg_done |= neighbour->dao_path_control; + /* State_timer is 1/10 s. Set renewal to 75-85% of lifetime */ + addr->state_timer = (addr->preferred_lifetime * randLIB_get_random_in_range(75, 85) / 10); + } else { + tr_error("Address registration failed"); + } + + /* If that was last one to reply, send next one. */ + if (!addr->addr_reg_pend) { + rpl_control_register_address(interface, NULL); + } + + return true; + } + + return false; +} + /* We are optimised for sending updates to existing targets to current parents; * we track the state of what information DAO parents have, and manage the * updates together with message coalescing and ack tracking. diff --git a/features/nanostack/sal-stack-nanostack/source/RPL/rpl_downward.h b/features/nanostack/sal-stack-nanostack/source/RPL/rpl_downward.h index 8dcfa893b6f6..15d40bae7ade 100644 --- a/features/nanostack/sal-stack-nanostack/source/RPL/rpl_downward.h +++ b/features/nanostack/sal-stack-nanostack/source/RPL/rpl_downward.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -41,6 +41,9 @@ void rpl_instance_dao_request(struct rpl_instance *instance, struct rpl_neighbou void rpl_instance_dao_trigger(struct rpl_instance *instance, uint16_t delay); void rpl_instance_dao_acked(struct rpl_instance *instance, const uint8_t src[16], int8_t interface_id, uint8_t dao_sequence, uint8_t status); +void rpl_instance_send_address_registration(protocol_interface_info_entry_t *interface, rpl_instance_t *instance, if_address_entry_t *addr); +bool rpl_instance_address_registration_done(protocol_interface_info_entry_t *interface, rpl_instance_t *instance, if_address_entry_t *addr, uint8_t status); + #ifdef HAVE_RPL_DAO_HANDLING bool rpl_instance_dao_received(struct rpl_instance *instance, const uint8_t src[16], int8_t interface_id, bool multicast, const uint8_t *opts, uint16_t opts_len, uint8_t *status_out); #endif diff --git a/features/nanostack/sal-stack-nanostack/source/RPL/rpl_upward.c b/features/nanostack/sal-stack-nanostack/source/RPL/rpl_upward.c index d364c01ab31a..126e195312ef 100644 --- a/features/nanostack/sal-stack-nanostack/source/RPL/rpl_upward.c +++ b/features/nanostack/sal-stack-nanostack/source/RPL/rpl_upward.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -542,6 +542,14 @@ void rpl_delete_dodag_version(rpl_dodag_version_t *version) rpl_dodag_t *dodag = version->dodag; rpl_instance_t *instance = dodag->instance; + if (instance->current_dodag_version == version) { + // Don't call rpl_instance_set_dodag_version(NULL) - that would pre-empt parent reselection, + // triggering poison immediately. + // Give parent selection a chance to select another version (but will it have any info on-hand?) + instance->current_dodag_version = NULL; + rpl_instance_trigger_parent_selection(instance, 5); + } + ns_list_foreach_safe(rpl_neighbour_t, neighbour, &instance->candidate_neighbours) { if (neighbour->dodag_version == version) { rpl_delete_neighbour(instance, neighbour); @@ -649,6 +657,21 @@ void rpl_delete_dodag(rpl_dodag_t *dodag) rpl_free(dodag, sizeof(*dodag)); } +void rpl_delete_dodag_root(rpl_dodag_t *dodag) +{ + // This should trigger immediate poison + rpl_instance_set_dodag_version(dodag->instance, NULL, RPL_RANK_INFINITE); + // Deleting DODAG is not ideal - we will just pick up adverts from our + // former children, and recreate, possibly violating the MaxRankIncrease. + // Should retain DODAG version info and just unset root flag, which will + // limit what happens when we hear adverts. + // Problem is rpl_control_create_dodag_root which can't handle the + // case where DODAG already exists. This would always be a problem if + // we'd heard adverts in between delete and create, but would be an instant + // problem without this delete. Need to fix. + rpl_delete_dodag(dodag); +} + /* Convert RPL configuration to generic trickle parameters. Returns true if * the value in the generic object has changed. */ @@ -1008,31 +1031,15 @@ rpl_instance_t *rpl_create_instance(rpl_domain_t *domain, uint8_t instance_id) if (!instance) { return NULL; } + memset(instance, 0, sizeof(rpl_instance_t)); ns_list_init(&instance->dodags); ns_list_init(&instance->candidate_neighbours); ns_list_init(&instance->dao_targets); instance->dtsn = rpl_seq_init(); - instance->srh_error_count = 0; - instance->poison_count = 0; - instance->repair_dis_timer = 0; - instance->repair_dis_count = 0; instance->last_dao_trigger_time = protocol_core_monotonic_time; - instance->root_paths_valid = false; - instance->root_topo_sort_valid = false; instance->dao_sequence = rpl_seq_init(); - instance->dao_sequence_in_transit = 0; - instance->dao_in_transit = false; - instance->dao_retry_timer = 0; - instance->dao_attempt = 0; - instance->delay_dao_timer = 0; - instance->parent_selection_timer = 0; - instance->neighbours_changed = false; - instance->local_repair = false; instance->id = instance_id; instance->domain = domain; - instance->current_dodag_version = NULL; - instance->dio_not_consistent = false; - instance->of = NULL; ns_list_add_to_start(&domain->instances, instance); return instance; @@ -1345,7 +1352,6 @@ void rpl_instance_run_parent_selection(rpl_instance_t *instance) protocol_stats_update(STATS_RPL_PARENT_CHANGE, 1); } -#ifndef NO_MLE // Sets new preferred parent if (preferred_parent) { ipv6_map_ip_to_ll_and_call_ll_addr_handler(NULL, preferred_parent->interface_id, NULL, preferred_parent->ll_address, @@ -1359,7 +1365,6 @@ void rpl_instance_run_parent_selection(rpl_instance_t *instance) protocol_6lowpan_neighbor_priority_clear_all(preferred_parent->interface_id, PRIORITY_2ND); } } -#endif rpl_instance_set_local_repair(instance, preferred_parent == NULL); diff --git a/features/nanostack/sal-stack-nanostack/source/RPL/rpl_upward.h b/features/nanostack/sal-stack-nanostack/source/RPL/rpl_upward.h index b269f6e55dc4..1718d753739b 100644 --- a/features/nanostack/sal-stack-nanostack/source/RPL/rpl_upward.h +++ b/features/nanostack/sal-stack-nanostack/source/RPL/rpl_upward.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -88,6 +88,7 @@ void rpl_instance_slow_timer(rpl_instance_t *instance, uint16_t seconds); rpl_dodag_t *rpl_lookup_dodag(const rpl_instance_t *instance, const uint8_t *dodagid); rpl_dodag_t *rpl_create_dodag(rpl_instance_t *instance, const uint8_t *dodagid, uint8_t g_mop_prf); void rpl_delete_dodag(rpl_dodag_t *dodag); +void rpl_delete_dodag_root(rpl_dodag_t *dodag); uint8_t rpl_dodag_mop(const rpl_dodag_t *dodag); void rpl_dodag_set_root(rpl_dodag_t *dodag, bool root); #ifdef HAVE_RPL_ROOT diff --git a/features/nanostack/sal-stack-nanostack/source/Security/PANA/eap_protocol.c b/features/nanostack/sal-stack-nanostack/source/Security/PANA/eap_protocol.c index d28dfba0c21e..7a2e8c61993c 100644 --- a/features/nanostack/sal-stack-nanostack/source/Security/PANA/eap_protocol.c +++ b/features/nanostack/sal-stack-nanostack/source/Security/PANA/eap_protocol.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Arm Limited and affiliates. + * Copyright (c) 2017-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/features/nanostack/sal-stack-nanostack/source/Security/PANA/pana.c b/features/nanostack/sal-stack-nanostack/source/Security/PANA/pana.c index 23a9cc5d87b7..b760f10f0601 100644 --- a/features/nanostack/sal-stack-nanostack/source/Security/PANA/pana.c +++ b/features/nanostack/sal-stack-nanostack/source/Security/PANA/pana.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017, Arm Limited and affiliates. + * Copyright (c) 2013-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -750,24 +750,23 @@ int8_t pana_ccm_data_crypt(uint8_t *ptr, uint16_t len, uint8_t operation_type, u { uint8_t *explict_ptr; uint8_t *key_ptr = 0; - ccm_globals_t *ccm_ptr = 0; + ccm_globals_t ccm_ptr; key_ptr = suite->pana_session.pana_PAA_enc_key; //Here Comes AES Decrypt - ccm_ptr = ccm_sec_init(AES_SECURITY_LEVEL_ENC, key_ptr, operation_type , 3); - if (!ccm_ptr) { + if (!ccm_sec_init(&ccm_ptr, AES_SECURITY_LEVEL_ENC, key_ptr, operation_type , 3)) { return -1; } - explict_ptr = ccm_ptr->exp_nonce; + explict_ptr = ccm_ptr.exp_nonce; //Set IV explict_ptr = common_write_32_bit(suite->pana_session.pana_key_id, explict_ptr); //SET EXP 4 octest Session ID, 4 Octet Pana SQN number explict_ptr = common_write_32_bit(suite->pana_session.session_id, explict_ptr); explict_ptr = common_write_32_bit(message_seq, explict_ptr); - ccm_ptr->data_len = len; - ccm_ptr->data_ptr = ptr; - return ccm_process_run(ccm_ptr); + ccm_ptr.data_len = len; + ccm_ptr.data_ptr = ptr; + return ccm_process_run(&ccm_ptr); } buffer_t *pana_relay_parse(buffer_t *buf) diff --git a/features/nanostack/sal-stack-nanostack/source/Security/TLS/tls_ccm_crypt.c b/features/nanostack/sal-stack-nanostack/source/Security/TLS/tls_ccm_crypt.c index 6627a49d1991..45693639afbd 100644 --- a/features/nanostack/sal-stack-nanostack/source/Security/TLS/tls_ccm_crypt.c +++ b/features/nanostack/sal-stack-nanostack/source/Security/TLS/tls_ccm_crypt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Arm Limited and affiliates. + * Copyright (c) 2017-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -30,9 +30,8 @@ #define TRACE_GROUP "cryp" #define TLS_1_2_VER 0x0303 -static ccm_globals_t * tls_ccm_init(const uint8_t *key_expansion, const uint8_t *nonce, bool server, uint8_t crypt_process) +static bool tls_ccm_init(ccm_globals_t *ccm_ptr, const uint8_t *key_expansion, const uint8_t *nonce, bool server, uint8_t crypt_process) { - ccm_globals_t *ccm_ptr; const uint8_t *key, *iv_ptr; if (server) { key = key_expansion + SERVER_WRITE_KEY; @@ -41,12 +40,14 @@ static ccm_globals_t * tls_ccm_init(const uint8_t *key_expansion, const uint8_t key = key_expansion + CLIENT_WRITE_KEY; iv_ptr = key_expansion + CLIENT_IV; } - ccm_ptr = ccm_sec_init(AES_SECURITY_LEVEL_ENC_MIC64, key, crypt_process , 3); - if (ccm_ptr) { - memcpy(ccm_ptr->exp_nonce, iv_ptr, 4); - memcpy(&ccm_ptr->exp_nonce[4], nonce, 8); + + if (!ccm_sec_init(ccm_ptr, AES_SECURITY_LEVEL_ENC_MIC64, key, crypt_process , 3) ) { + return false; } - return ccm_ptr; + + memcpy(ccm_ptr->exp_nonce, iv_ptr, 4); + memcpy(&ccm_ptr->exp_nonce[4], nonce, 8); + return true; } @@ -64,16 +65,16 @@ static void tls_set_adata(ccm_globals_t *ccm_ptr, uint8_t *a_data, const uint8_t int8_t tls_ccm_data_encrypt(uint8_t *data_ptr, uint16_t data_length, const uint8_t *key_expansion, const uint8_t *nonce, uint8_t type, bool server) { - ccm_globals_t * ccm_ptr = tls_ccm_init(key_expansion, nonce, server, AES_CCM_ENCRYPT); - if (!ccm_ptr) { + ccm_globals_t ccm_ptr; + if (!tls_ccm_init(&ccm_ptr, key_expansion, nonce, server, AES_CCM_ENCRYPT)) { return -1; } uint8_t adata[13]; - ccm_ptr->data_len = data_length; - ccm_ptr->data_ptr = data_ptr; - ccm_ptr->mic = (ccm_ptr->data_ptr + ccm_ptr->data_len); - tls_set_adata(ccm_ptr,adata, nonce, type); - return ccm_process_run(ccm_ptr); + ccm_ptr.data_len = data_length; + ccm_ptr.data_ptr = data_ptr; + ccm_ptr.mic = (ccm_ptr.data_ptr + ccm_ptr.data_len); + tls_set_adata(&ccm_ptr,adata, nonce, type); + return ccm_process_run(&ccm_ptr); } int8_t tls_ccm_data_decrypt(uint8_t *data_ptr, uint16_t data_length, const uint8_t *key_expansion, uint8_t type, bool server) @@ -82,18 +83,19 @@ int8_t tls_ccm_data_decrypt(uint8_t *data_ptr, uint16_t data_length, const uint8 if (data_length <= 16) { return -1; } - ccm_globals_t *ccm_ptr = tls_ccm_init(key_expansion, data_ptr, server, AES_CCM_DECRYPT); - if (!ccm_ptr) { + ccm_globals_t ccm_ptr; + + if (!tls_ccm_init(&ccm_ptr, key_expansion, data_ptr, server, AES_CCM_DECRYPT)) { return -1; } uint8_t adata[13]; - ccm_ptr->data_len = data_length - 16; + ccm_ptr.data_len = data_length - 16; - tls_set_adata(ccm_ptr, adata, data_ptr, type); - ccm_ptr->data_ptr = data_ptr + 8; - ccm_ptr->mic = (ccm_ptr->data_ptr + ccm_ptr->data_len); + tls_set_adata(&ccm_ptr, adata, data_ptr, type); + ccm_ptr.data_ptr = data_ptr + 8; + ccm_ptr.mic = (ccm_ptr.data_ptr + ccm_ptr.data_len); - return ccm_process_run(ccm_ptr); + return ccm_process_run(&ccm_ptr); } #endif diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/CCM_lib/ccm_security.c b/features/nanostack/sal-stack-nanostack/source/Service_Libs/CCM_lib/ccm_security.c index 9561075745dd..14deaa522684 100644 --- a/features/nanostack/sal-stack-nanostack/source/Service_Libs/CCM_lib/ccm_security.c +++ b/features/nanostack/sal-stack-nanostack/source/Service_Libs/CCM_lib/ccm_security.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, 2017, Arm Limited and affiliates. + * Copyright (c) 2014-2015, 2017-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -43,25 +43,12 @@ #include "ccmLIB.h" #include "platform/arm_hal_aes.h" -#ifndef CCM_USE_MUTEX -#define arm_ccm_mutex_lock() -#define arm_ccm_mutex_unlock() -#endif - -static ccm_globals_t ccm_globals; - -/* CCM Library Parameters */ -static uint8_t CCM_L_PARAM = 2; -static uint8_t ccm_sec_level; -static uint8_t CCM_ENCODE_MODE; -static const uint8_t *ccm_key_ptr; - -static void ccm_generate_A0(uint8_t *ptr); -static void ccm_auth_generate_B0(uint8_t *ptr, uint16_t len); -static void ccm_auth_calc_Xi(uint8_t X[static 16], uint8_t Blen, const uint8_t B[static Blen]); +static void ccm_generate_A0(uint8_t *ptr, ccm_globals_t *ccm_pramters); +static void ccm_auth_generate_B0(uint8_t *ptr, ccm_globals_t *ccm_params); +static void ccm_auth_calc_Xi(void *aes_context, uint8_t X[static 16], uint8_t Blen, const uint8_t B[static Blen]); static uint8_t ccm_mic_len_calc(uint8_t sec_level); -static void ccm_encode(uint16_t len , uint8_t *ptr); -static int8_t ccm_calc_auth_MIC(const uint8_t *data_ptr, uint16_t data_len, const uint8_t *adata_ptr, uint16_t adata_len); +static void ccm_encode(ccm_globals_t *ccm_params); +static int8_t ccm_calc_auth_MIC(ccm_globals_t *ccm_params); /** * \brief A function to init CCM library. @@ -73,24 +60,24 @@ static int8_t ccm_calc_auth_MIC(const uint8_t *data_ptr, uint16_t data_len, cons * \return Pointer to Global CCM paramameter buffer. * \return 0 When parameter fail or CCM is Busy. */ -ccm_globals_t *ccm_sec_init(uint8_t sec_level, const uint8_t *ccm_key, uint8_t mode, uint8_t ccm_l) +bool ccm_sec_init(ccm_globals_t *ccm_context, uint8_t sec_level, const uint8_t *ccm_key, uint8_t mode, uint8_t ccm_l) { - ccm_globals_t *ret_val = 0; + memset(ccm_context, 0, sizeof(ccm_globals_t)); + if ((ccm_l == 2 || ccm_l == 3) && (sec_level < 8)) { - arm_ccm_mutex_lock(); - memset(&ccm_globals, 0, sizeof(ccm_globals_t)); - CCM_ENCODE_MODE = mode; - ccm_sec_level = sec_level; - CCM_L_PARAM = ccm_l; - ccm_key_ptr = ccm_key; - arm_aes_start(ccm_key); - ccm_globals.mic_len = ccm_mic_len_calc(ccm_sec_level); - ccm_globals.mic = 0; - ret_val = &ccm_globals; - } else { - ccm_key_ptr = 0; + void *aes_context = arm_aes_start(ccm_key); + if (!aes_context) { + return false; + } + ccm_context->aes_context = aes_context; + ccm_context->ccm_encode_mode = mode; + ccm_context->ccm_sec_level = sec_level; + ccm_context->ccm_l_param = ccm_l; + ccm_context->key_ptr = ccm_key; + ccm_context->mic_len = ccm_mic_len_calc(sec_level); + return true; } - return ret_val; + return false; } /** @@ -128,23 +115,23 @@ int8_t ccm_process_run(ccm_globals_t *ccm_params) goto END; } - if (CCM_ENCODE_MODE == AES_CCM_ENCRYPT) { + if (ccm_params->ccm_encode_mode == AES_CCM_ENCRYPT) { if (ccm_params->mic_len) { //Calc - if (ccm_calc_auth_MIC(ccm_params->data_ptr, ccm_params->data_len, ccm_params->adata_ptr, ccm_params->adata_len)) { + if (ccm_calc_auth_MIC(ccm_params)) { goto END; } } if (ccm_params->data_len) { - ccm_encode(ccm_params->data_len, ccm_params->data_ptr); + ccm_encode(ccm_params); } ret_val = 0; } else { if (ccm_params->data_len) { - ccm_encode(ccm_params->data_len, ccm_params->data_ptr); + ccm_encode(ccm_params); } if (ccm_params->mic_len) { - if (ccm_calc_auth_MIC(ccm_params->data_ptr, ccm_params->data_len, ccm_params->adata_ptr, ccm_params->adata_len) == 0) { + if (ccm_calc_auth_MIC(ccm_params) == 0) { ret_val = 0; } } else { @@ -153,26 +140,32 @@ int8_t ccm_process_run(ccm_globals_t *ccm_params) } END: - ccm_key_ptr = 0; - arm_aes_finish(); - arm_ccm_mutex_unlock(); + ccm_free(ccm_params); return ret_val; } +void ccm_free(ccm_globals_t *ccm_params) +{ + if (ccm_params && ccm_params->aes_context) { + arm_aes_finish(ccm_params->aes_context); + } +} + /* Counter-mode encryption/decryption * Ci := E(Key, Ai) ^ Mi */ -static void ccm_encode(uint16_t len , uint8_t *ptr) +static void ccm_encode(ccm_globals_t *ccm_params) { - if (!ccm_key_ptr || ccm_sec_level < AES_SECURITY_LEVEL_ENC) { + if (!ccm_params->key_ptr || ccm_params->ccm_sec_level < AES_SECURITY_LEVEL_ENC) { return; } - + uint16_t len = ccm_params->data_len; + uint8_t *ptr = ccm_params->data_ptr; uint8_t Ai[16], Si[16]; //first, generate A0 - ccm_generate_A0(Ai); + ccm_generate_A0(Ai, ccm_params); while (len) { //increment counter in Ai - 16-bit increment enough; len is 16-bit @@ -181,7 +174,7 @@ static void ccm_encode(uint16_t len , uint8_t *ptr) } // Si := E(Key, Ai) - arm_aes_encrypt(Ai, Si); + arm_aes_encrypt(ccm_params->aes_context, Ai, Si); // output := Si ^ input for (int_fast8_t i = 0; i < 16 && len; i++, len--) { @@ -191,15 +184,19 @@ static void ccm_encode(uint16_t len , uint8_t *ptr) } -static int8_t ccm_calc_auth_MIC(const uint8_t *data_ptr, uint16_t data_len, const uint8_t *adata_ptr, uint16_t adata_len) +static int8_t ccm_calc_auth_MIC(ccm_globals_t *ccm_params) { + const uint8_t *data_ptr = ccm_params->data_ptr; + uint16_t data_len = ccm_params->data_len; + const uint8_t *adata_ptr = ccm_params->adata_ptr; + uint16_t adata_len = ccm_params->adata_len; uint8_t Xi[16]; // As a convenience, treat "data" as "adata", reflecting that "Private // Payload" is part of "a data" not "m data" for unencrypted modes. // The distinction matters because there's an "align to block" between // "a" and "m", which we don't do when it's all in "a". - if (ccm_sec_level < AES_SECURITY_LEVEL_ENC && data_len != 0) { + if (ccm_params->ccm_sec_level < AES_SECURITY_LEVEL_ENC && data_len != 0) { // This trick only works if data follows adata if (data_ptr == adata_ptr + adata_len) { adata_len += data_len; @@ -209,11 +206,11 @@ static int8_t ccm_calc_auth_MIC(const uint8_t *data_ptr, uint16_t data_len, cons } } - ccm_auth_generate_B0(Xi, data_len); //Set B0 + ccm_auth_generate_B0(Xi, ccm_params); //Set B0 // Calculate X1: E(key, B0) // [Could use ccm_auth_calc_Xi - it's formally X1 := E(key, B0 ^ X0), where X0 = 0] - arm_aes_encrypt(Xi, Xi); + arm_aes_encrypt(ccm_params->aes_context, Xi, Xi); //First authentication block has 2-byte length field concatenated if (adata_len) { @@ -224,7 +221,7 @@ static int8_t ccm_calc_auth_MIC(const uint8_t *data_ptr, uint16_t data_len, cons B1[1] = adata_len; memcpy(&B1[2], adata_ptr, t_len); - ccm_auth_calc_Xi(Xi, 2 + t_len, B1); + ccm_auth_calc_Xi(ccm_params->aes_context, Xi, 2 + t_len, B1); adata_ptr += t_len; adata_len -= t_len; } @@ -232,7 +229,7 @@ static int8_t ccm_calc_auth_MIC(const uint8_t *data_ptr, uint16_t data_len, cons while (adata_len) { uint_fast8_t t_len = adata_len > 16 ? 16 : adata_len; - ccm_auth_calc_Xi(Xi, t_len, adata_ptr); + ccm_auth_calc_Xi(ccm_params->aes_context, Xi, t_len, adata_ptr); adata_ptr += t_len; adata_len -= t_len; } @@ -240,7 +237,7 @@ static int8_t ccm_calc_auth_MIC(const uint8_t *data_ptr, uint16_t data_len, cons while (data_len) { uint_fast8_t t_len = data_len > 16 ? 16 : data_len; - ccm_auth_calc_Xi(Xi, t_len, data_ptr); + ccm_auth_calc_Xi(ccm_params->aes_context, Xi, t_len, data_ptr); data_ptr += t_len; data_len -= t_len; } @@ -249,17 +246,17 @@ static int8_t ccm_calc_auth_MIC(const uint8_t *data_ptr, uint16_t data_len, cons // Encryption block S0 is E(Key, A0) uint8_t S0[16]; - ccm_generate_A0(S0); - arm_aes_encrypt(S0, S0); + ccm_generate_A0(S0, ccm_params); + arm_aes_encrypt(ccm_params->aes_context, S0, S0); // Encrypted authentication tag U is S0^T (leftmost M octets) - if (CCM_ENCODE_MODE == AES_CCM_ENCRYPT) { - for (uint_fast8_t i = 0; i < ccm_globals.mic_len; i++) { - ccm_globals.mic[i] = Xi[i] ^ S0[i]; + if (ccm_params->ccm_encode_mode == AES_CCM_ENCRYPT) { + for (uint_fast8_t i = 0; i < ccm_params->mic_len; i++) { + ccm_params->mic[i] = Xi[i] ^ S0[i]; } } else { - for (uint_fast8_t i = 0; i < ccm_globals.mic_len; i++) - if (ccm_globals.mic[i] != (Xi[i] ^ S0[i])) { + for (uint_fast8_t i = 0; i < ccm_params->mic_len; i++) + if (ccm_params->mic[i] != (Xi[i] ^ S0[i])) { return -1; } } @@ -273,27 +270,27 @@ static int8_t ccm_calc_auth_MIC(const uint8_t *data_ptr, uint16_t data_len, cons * * \return none. */ -static void ccm_generate_A0(uint8_t *ptr) +static void ccm_generate_A0(uint8_t *ptr, ccm_globals_t *ccm_pramters) { uint8_t n_len, flags; - flags = CCM_L_PARAM - 1; - n_len = 15 - CCM_L_PARAM; + flags = ccm_pramters->ccm_l_param - 1; + n_len = 15 - ccm_pramters->ccm_l_param; //FLAGS = L' = L - 1; *ptr++ = flags; - memcpy(ptr, ccm_globals.exp_nonce, n_len); + memcpy(ptr, ccm_pramters->exp_nonce, n_len); ptr += n_len; - memset(ptr, 0, CCM_L_PARAM); + memset(ptr, 0, ccm_pramters->ccm_l_param); } /* Calculate X[i+1]: X[i+1] := E(Key, X[i] ^ B[i]) */ /* Blen is <= 16; this handles zero-padding B when it is < 16 */ -static void ccm_auth_calc_Xi(uint8_t X[static 16], uint8_t Blen, const uint8_t B[static Blen]) +static void ccm_auth_calc_Xi(void *aes_context, uint8_t X[static 16], uint8_t Blen, const uint8_t B[static Blen]) { for (uint_fast8_t i = 0; i < Blen; i++) { X[i] ^= B[i]; } - arm_aes_encrypt(X, X); + arm_aes_encrypt(aes_context, X, X); } /* flags = reserved(1) || Adata(1) || M (3) || L (3) @@ -301,27 +298,27 @@ static void ccm_auth_calc_Xi(uint8_t X[static 16], uint8_t Blen, const uint8_t B * L = CCM_L_PARAM - 1 */ /* B0 := flags(1)|| Nonce(15-L) || length of message(L) */ -static void ccm_auth_generate_B0(uint8_t *ptr, uint16_t len) +static void ccm_auth_generate_B0(uint8_t *ptr, ccm_globals_t *ccm_params) { uint8_t flags = 0; uint8_t n_len; - n_len = 15 - CCM_L_PARAM; + n_len = 15 - ccm_params->ccm_l_param; - if (ccm_globals.mic_len) { - flags = ccm_globals.mic_len - 2; + if (ccm_params->mic_len) { + flags = ccm_params->mic_len - 2; flags <<= 2; } flags |= 0x40; - flags |= (CCM_L_PARAM - 1); + flags |= (ccm_params->ccm_l_param - 1); *ptr++ = flags; - memcpy(ptr, ccm_globals.exp_nonce, n_len); + memcpy(ptr, ccm_params->exp_nonce, n_len); ptr += n_len; - if (CCM_L_PARAM == 3) { + if (ccm_params->ccm_l_param == 3) { *ptr++ = 0; } - *ptr++ = len >> 8; - *ptr = len; + *ptr++ = ccm_params->data_len >> 8; + *ptr = ccm_params->data_len; } diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/CCM_lib/mbedOS/aes_mbedtls_adapter.c b/features/nanostack/sal-stack-nanostack/source/Service_Libs/CCM_lib/mbedOS/aes_mbedtls_adapter.c index 294e7e2233f7..801946fb919f 100644 --- a/features/nanostack/sal-stack-nanostack/source/Service_Libs/CCM_lib/mbedOS/aes_mbedtls_adapter.c +++ b/features/nanostack/sal-stack-nanostack/source/Service_Libs/CCM_lib/mbedOS/aes_mbedtls_adapter.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -25,7 +25,9 @@ * * 2) Platform with hardware AES assist, mbed TLS not in use: * Do not use this source file - implement arm_hal_aes.h yourself using - * your AES hardware. + * your AES hardware. Note that you must be able to provide + * ARM_AES_MBEDTLS_CONTEXT_MIN contexts. This may or may not be 1, depending + * on Nanostack config. * * 3) Platform without hardware assist, already using (or wanting to use) mbed TLS: * Use this source file, and define NS_USE_EXTERNAL_MBED_TLS so that @@ -38,18 +40,11 @@ * MBEDTLS_AES_C enabled. Attach your hardware-accelerated AES to mbed TLS * by defining MBEDTLS_AES_ALT; it will then be used both by users * of arm_hal_aes.h, and other users of mbed TLS. - * - * 5) Platform with non-context-capable hardware assist, already using mbed TLS: - * If it's not possible, or too complex, to handle multiple contexts for the - * AES decode, then you will not be able to accelerate all mbed TLS users. - * Instead you can reserve the AES hardware for providing arm_hal_aes.h, so - * this becomes the same as case 2. Don't use this source file - implement - * arm_hal_aes.h yourself using your AES hardware. The external mbed TLS - * will use its software implementation. */ /* Get the API we are implementing from libService */ #include "platform/arm_hal_aes.h" +#include "platform/arm_hal_interrupt.h" /* Either pull in the external mbed TLS header for its AES functions, or * pull in our own local cut-down copy of the mbed TLS code. @@ -60,20 +55,48 @@ #include "aes_mbedtls.c" #endif /* NS_USE_EXTERNAL_MBED_TLS */ -static mbedtls_aes_context context; +struct arm_aes_context { + mbedtls_aes_context ctx; + bool reserved; +}; + +static arm_aes_context_t context_list[ARM_AES_MBEDTLS_CONTEXT_MIN]; + +static arm_aes_context_t * mbed_tls_context_get(void) +{ + platform_enter_critical(); + for (int i = 0; i < ARM_AES_MBEDTLS_CONTEXT_MIN; i++) { + if (!context_list[i].reserved) { + //Reserve context + context_list[i].reserved = true; + platform_exit_critical(); + return &context_list[i]; + } + } + + platform_exit_critical(); + return NULL; +} -void arm_aes_start(const uint8_t key[static 16]) +arm_aes_context_t *arm_aes_start(const uint8_t key[static 16]) { - mbedtls_aes_init(&context); - mbedtls_aes_setkey_enc(&context, key, 128); + arm_aes_context_t *context = mbed_tls_context_get(); + if (context) { + mbedtls_aes_init(&context->ctx); + mbedtls_aes_setkey_enc(&context->ctx, key, 128); + } + return context; } -void arm_aes_encrypt(const uint8_t src[static 16], uint8_t dst[static 16]) +void arm_aes_encrypt(arm_aes_context_t *aes_context, const uint8_t src[static 16], uint8_t dst[static 16]) { - mbedtls_aes_crypt_ecb(&context, MBEDTLS_AES_ENCRYPT, src, dst); + mbedtls_aes_crypt_ecb(&aes_context->ctx, MBEDTLS_AES_ENCRYPT, src, dst); } -void arm_aes_finish(void) +void arm_aes_finish(arm_aes_context_t *aes_context) { - mbedtls_aes_free(&context); + mbedtls_aes_free(&aes_context->ctx); + platform_enter_critical(); + aes_context->reserved = false; + platform_exit_critical(); } diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/etx/etx.c b/features/nanostack/sal-stack-nanostack/source/Service_Libs/etx/etx.c index 4047a8688cbe..981ab71ad8e1 100644 --- a/features/nanostack/sal-stack-nanostack/source/Service_Libs/etx/etx.c +++ b/features/nanostack/sal-stack-nanostack/source/Service_Libs/etx/etx.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -28,6 +28,7 @@ #include "NWK_INTERFACE/Include/protocol.h" #include "NWK_INTERFACE/Include/protocol_stats.h" #include "Service_Libs/etx/etx.h" +#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h" #include "Service_Libs/utils/isqrt.h" //TODO: Refactor this away! @@ -37,14 +38,16 @@ static uint16_t etx_current_calc(uint16_t etx, uint8_t accumulated_failures); static uint16_t etx_dbm_lqi_calc(uint8_t lqi, int8_t dbm); -static void etx_value_change_callback_needed_check(uint16_t etx, uint16_t *stored_diff_etx, uint8_t accumulated_failures, const uint8_t *mac64_addr_ptr, uint16_t mac16_addr); -static void etx_accum_failures_callback_needed_check(struct mle_neigh_table_entry_t *neigh_table_ptr); +static void etx_value_change_callback_needed_check(uint16_t etx, uint16_t *stored_diff_etx, uint8_t accumulated_failures, uint8_t attribute_index); +static void etx_accum_failures_callback_needed_check(etx_storage_t * entry, uint8_t attribute_index); typedef struct { uint16_t hysteresis; // 12 bit fraction uint8_t accum_threshold; etx_value_change_handler_t *callback_ptr; etx_accum_failures_handler_t *accum_cb_ptr; + etx_storage_t *etx_storage_list; + uint8_t ext_storage_list_size; int8_t interface_id; } ext_info_t; @@ -53,6 +56,8 @@ static ext_info_t etx_info = { .accum_threshold = 0, .callback_ptr = NULL, .accum_cb_ptr = NULL, + .etx_storage_list = NULL, + .ext_storage_list_size = 0, .interface_id = -1 }; @@ -67,71 +72,57 @@ static ext_info_t etx_info = { * \param addr_type address type, ADDR_802_15_4_SHORT or ADDR_802_15_4_LONG * \param addr_ptr PAN ID with 802.15.4 address */ -void etx_transm_attempts_update(int8_t interface_id, uint8_t attempts, bool success, addrtype_t addr_type, const uint8_t *addr_ptr) +void etx_transm_attempts_update(int8_t interface_id, uint8_t attempts, bool success, uint8_t attribute_index) { - mle_neigh_table_entry_t *neigh_table_ptr = NULL; uint32_t etx; uint8_t accumulated_failures; - - if (!addr_ptr) { - return; - } - // Gets table entry - neigh_table_ptr = mle_class_get_by_link_address(interface_id, addr_ptr + PAN_ID_LEN, addr_type); - - if (neigh_table_ptr == NULL) { + etx_storage_t * entry = etx_storage_entry_get(interface_id, attribute_index); + if (!entry) { return; } - accumulated_failures = neigh_table_ptr->accumulated_failures; + accumulated_failures = entry->accumulated_failures; if (!success) { /* Stores failed attempts to estimate ETX and to calculate new ETX after successful sending */ if (accumulated_failures + attempts < 32) { - neigh_table_ptr->accumulated_failures += attempts; + entry->accumulated_failures += attempts; } else { success = true; } } if (success) { - neigh_table_ptr->accumulated_failures = 0; + entry->accumulated_failures = 0; } else { - etx_accum_failures_callback_needed_check(neigh_table_ptr); + etx_accum_failures_callback_needed_check(entry, attribute_index); } - if (neigh_table_ptr->etx) { + if (entry->etx) { // If hysteresis is set stores ETX value for comparison - if (etx_info.hysteresis && !neigh_table_ptr->stored_diff_etx) { - neigh_table_ptr->stored_diff_etx = neigh_table_ptr->etx; + if (etx_info.hysteresis && !entry->stored_diff_etx) { + entry->stored_diff_etx = entry->etx; } if (success) { // ETX = 7/8 * current ETX + 1/8 * ((attempts + failed attempts) << 12) - etx = neigh_table_ptr->etx - (neigh_table_ptr->etx >> ETX_MOVING_AVERAGE_FRACTION); + etx = entry->etx - (entry->etx >> ETX_MOVING_AVERAGE_FRACTION); etx += (attempts + accumulated_failures) << (12 - ETX_MOVING_AVERAGE_FRACTION); if (etx > 0xffff) { - neigh_table_ptr->etx = 0xffff; + entry->etx = 0xffff; } else { - neigh_table_ptr->etx = etx; + entry->etx = etx; } } // If real ETX value has been received do not update based on LQI or dBm - neigh_table_ptr->tmp_etx = false; + entry->tmp_etx = false; // Checks if ETX value change callback is needed - etx_value_change_callback_needed_check(neigh_table_ptr->etx, &(neigh_table_ptr->stored_diff_etx), neigh_table_ptr->accumulated_failures, &(neigh_table_ptr->mac64[0]), neigh_table_ptr->short_adr); - - // Updates ETX statistics - if (neigh_table_ptr->priorityFlag) { - protocol_stats_update(STATS_ETX_1ST_PARENT, neigh_table_ptr->etx >> 4); - } else if (neigh_table_ptr->second_priority_flag) { - protocol_stats_update(STATS_ETX_2ND_PARENT, neigh_table_ptr->etx >> 4); - } + etx_value_change_callback_needed_check(entry->etx, &(entry->stored_diff_etx), entry->accumulated_failures, attribute_index); } } @@ -144,34 +135,34 @@ void etx_transm_attempts_update(int8_t interface_id, uint8_t attempts, bool succ * \param remote_incoming_idr Remote incoming IDR * \param mac64_addr_ptr long MAC address */ -void etx_remote_incoming_idr_update(int8_t interface_id, uint8_t remote_incoming_idr, mle_neigh_table_entry_t *neigh_table_ptr) +void etx_remote_incoming_idr_update(int8_t interface_id, uint8_t remote_incoming_idr, uint8_t attribute_index) { - (void) interface_id; + etx_storage_t * entry = etx_storage_entry_get(interface_id, attribute_index); - if (neigh_table_ptr) { + if (entry) { // If ETX has been set - if (neigh_table_ptr->etx) { + if (entry->etx) { // If hysteresis is set stores ETX value to enable comparison - if (etx_info.hysteresis && !neigh_table_ptr->stored_diff_etx) { - neigh_table_ptr->stored_diff_etx = neigh_table_ptr->etx; + if (etx_info.hysteresis && !entry->stored_diff_etx) { + entry->stored_diff_etx = entry->etx; } // remote EXT = remote incoming IDR^2 (12 bit fraction) uint32_t remote_ext = ((uint32_t)remote_incoming_idr * remote_incoming_idr) << 2; // ETX = 7/8 * current ETX + 1/8 * remote ETX */ - uint32_t etx = neigh_table_ptr->etx - (neigh_table_ptr->etx >> ETX_MOVING_AVERAGE_FRACTION); + uint32_t etx = entry->etx - (entry->etx >> ETX_MOVING_AVERAGE_FRACTION); etx += remote_ext >> ETX_MOVING_AVERAGE_FRACTION; if (etx > 0xffff) { - neigh_table_ptr->etx = 0xffff; + entry->etx = 0xffff; } else { - neigh_table_ptr->etx = etx; + entry->etx = etx; } // Checks if ETX value change callback is needed - etx_value_change_callback_needed_check(neigh_table_ptr->etx, &(neigh_table_ptr->stored_diff_etx), neigh_table_ptr->accumulated_failures, &(neigh_table_ptr->mac64[0]), neigh_table_ptr->short_adr); + etx_value_change_callback_needed_check(entry->etx, &(entry->stored_diff_etx), entry->accumulated_failures, attribute_index); } - neigh_table_ptr->remote_incoming_idr = remote_incoming_idr; + entry->remote_incoming_idr = remote_incoming_idr; } } @@ -191,26 +182,43 @@ void etx_remote_incoming_idr_update(int8_t interface_id, uint8_t remote_incoming */ uint16_t etx_read(int8_t interface_id, addrtype_t addr_type, const uint8_t *addr_ptr) { - mle_neigh_table_entry_t *neigh_table_ptr; - uint16_t etx = 0; + protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id); - if (!addr_ptr) { + if (!addr_ptr || !interface) { return 0; } - if (!mle_class_exists_for_interface(interface_id)) { + if (interface->etx_read_override) { + // Interface has modified ETX calculation + return interface->etx_read_override(interface, addr_type, addr_ptr); + } + + uint8_t attribute_index; + if (interface->nwk_id == IF_IPV6) { return 1; } - neigh_table_ptr = mle_class_get_by_link_address(interface_id, addr_ptr + PAN_ID_LEN, addr_type); + //Must Support old MLE table and new still same time + mac_neighbor_table_entry_t *mac_neighbor = mac_neighbor_table_address_discover(mac_neighbor_info(interface), addr_ptr + PAN_ID_LEN, addr_type); + if (!mac_neighbor) { + return 0xffff; + } + attribute_index = mac_neighbor->index; + - if (neigh_table_ptr) { - etx = etx_current_calc(neigh_table_ptr->etx, neigh_table_ptr->accumulated_failures); - etx >>= 4; - } else { - etx = 0xffff; + //tr_debug("Etx Read from atribute %u", attribute_index); + + etx_storage_t * entry = etx_storage_entry_get(interface_id, attribute_index); + + if (!entry) { + return 0xffff; } + uint16_t etx = etx_current_calc(entry->etx, entry->accumulated_failures); + etx >>= 4; + + //tr_debug("Etx value %u", etx); + return etx; } @@ -224,12 +232,12 @@ uint16_t etx_read(int8_t interface_id, addrtype_t addr_type, const uint8_t *addr * \return 0x0100 to 0xFFFF incoming IDR value (8 bit fraction) * \return 0x0000 address unknown */ -uint16_t etx_local_incoming_idr_read(int8_t interface_id, mle_neigh_table_entry_t *neigh_table_ptr) +uint16_t etx_local_incoming_idr_read(int8_t interface_id, uint8_t attribute_index) { uint32_t local_incoming_idr = 0; - (void) interface_id; - if (neigh_table_ptr) { - uint16_t local_etx = etx_current_calc(neigh_table_ptr->etx, neigh_table_ptr->accumulated_failures); + etx_storage_t * entry = etx_storage_entry_get(interface_id, attribute_index); + if (entry) { + uint16_t local_etx = etx_current_calc(entry->etx, entry->accumulated_failures); local_incoming_idr = isqrt32((uint32_t)local_etx << 16); // divide by sqrt(2^12) @@ -239,6 +247,25 @@ uint16_t etx_local_incoming_idr_read(int8_t interface_id, mle_neigh_table_entry_ return local_incoming_idr; } +/** + * \brief A function to read local incoming IDR value + * + * Returns local incoming IDR value for an address + * + * \param mac64_addr_ptr long MAC address + * + * \return 0x0100 to 0xFFFF incoming IDR value (8 bit fraction) + * \return 0x0000 address unknown + */ +uint16_t etx_local_etx_read(int8_t interface_id, uint8_t attribute_index) +{ + etx_storage_t * entry = etx_storage_entry_get(interface_id, attribute_index); + if (!entry) { + return 0; + } + return etx_current_calc(entry->etx, entry->accumulated_failures) >> 4; +} + /** * \brief A function to calculate current ETX * @@ -280,37 +307,38 @@ static uint16_t etx_current_calc(uint16_t etx, uint8_t accumulated_failures) * * \return 0x0100 to 0xFFFF local incoming IDR value (8 bit fraction) */ -uint16_t etx_lqi_dbm_update(int8_t interface_id, uint8_t lqi, int8_t dbm, mle_neigh_table_entry_t *neigh_table_ptr) +uint16_t etx_lqi_dbm_update(int8_t interface_id, uint8_t lqi, int8_t dbm, uint8_t attribute_index) { uint32_t local_incoming_idr = 0; uint32_t etx = 0; - (void) interface_id; - if (neigh_table_ptr) { + etx_storage_t *entry = etx_storage_entry_get(interface_id, attribute_index); + + if (entry) { // If local ETX is not set calculate it based on LQI and dBm - if (!neigh_table_ptr->etx) { + if (!entry->etx) { etx = etx_dbm_lqi_calc(lqi, dbm); - neigh_table_ptr->etx = etx; - neigh_table_ptr->tmp_etx = true; + entry->etx = etx; + entry->tmp_etx = true; } // If local ETX has been calculated without remote incoming IDR and // remote incoming IDR is available update it by remote incoming IDR value - if (neigh_table_ptr->remote_incoming_idr && neigh_table_ptr->tmp_etx) { - neigh_table_ptr->tmp_etx = false; + if (entry->remote_incoming_idr && entry->tmp_etx) { + entry->tmp_etx = false; - local_incoming_idr = isqrt32((uint32_t)neigh_table_ptr->etx << 16); + local_incoming_idr = isqrt32((uint32_t)entry->etx << 16); // divide by sqrt(2^12) and scale to 12 bit fraction local_incoming_idr = local_incoming_idr >> 2; - etx = local_incoming_idr * (((uint16_t)neigh_table_ptr->remote_incoming_idr) << 7); - neigh_table_ptr->etx = etx >> 12; + etx = local_incoming_idr * (((uint16_t)entry->remote_incoming_idr) << 7); + entry->etx = etx >> 12; local_incoming_idr >>= 4; } // If local ETX has been calculated indicates new neighbor if (etx) { - etx_neighbor_add(interface_id, neigh_table_ptr); + etx_neighbor_add(interface_id, attribute_index); } } @@ -402,6 +430,50 @@ uint8_t etx_value_change_callback_register(nwk_interface_id nwk_id, int8_t inter } } +bool etx_storage_list_allocate(int8_t interface_id, uint8_t etx_storage_size) +{ + if (!etx_storage_size) { + ns_dyn_mem_free(etx_info.etx_storage_list); + etx_info.etx_storage_list = NULL; + etx_info.ext_storage_list_size = 0; + return true; + } + + if (etx_info.ext_storage_list_size == etx_storage_size) { + return true; + } + + ns_dyn_mem_free(etx_info.etx_storage_list); + etx_info.ext_storage_list_size = 0; + etx_info.etx_storage_list = ns_dyn_mem_alloc(sizeof(etx_storage_t) * etx_storage_size); + if (!etx_info.etx_storage_list) { + return false; + } + + etx_info.ext_storage_list_size = etx_storage_size; + etx_info.interface_id = interface_id; + etx_storage_t * list_ptr = etx_info.etx_storage_list; + for (uint8_t i = 0; i< etx_storage_size; i++) { + memset(list_ptr, 0, sizeof(etx_storage_t)); + + list_ptr++; + } + return true; + +} + +etx_storage_t *etx_storage_entry_get(int8_t interface_id, uint8_t attribute_index) +{ + if (etx_info.interface_id != interface_id || !etx_info.etx_storage_list || attribute_index >= etx_info.ext_storage_list_size) { + tr_debug("Unknow ID or un initilized ETX %u", attribute_index); + return NULL; + } + + etx_storage_t *entry = etx_info.etx_storage_list + attribute_index; + return entry; +} + + /** * \brief A function to register accumulated failures callback * @@ -444,11 +516,10 @@ uint8_t etx_accum_failures_callback_register(nwk_interface_id nwk_id, int8_t int * * \return ETX value (12 bit fraction) */ -static void etx_value_change_callback_needed_check(uint16_t etx, uint16_t *stored_diff_etx, uint8_t accumulated_failures, const uint8_t *mac64_addr_ptr, uint16_t mac16_addr) +static void etx_value_change_callback_needed_check(uint16_t etx, uint16_t *stored_diff_etx, uint8_t accumulated_failures, uint8_t attribute_index) { uint16_t current_etx; bool callback = false; - if (!etx_info.hysteresis) { return; } @@ -469,7 +540,7 @@ static void etx_value_change_callback_needed_check(uint16_t etx, uint16_t *store // Calls callback function if (callback) { - etx_info.callback_ptr(etx_info.interface_id, (*stored_diff_etx) >> 4, current_etx >> 4, mac64_addr_ptr, mac16_addr); + etx_info.callback_ptr(etx_info.interface_id, (*stored_diff_etx) >> 4, current_etx >> 4, attribute_index); *stored_diff_etx = current_etx; } } @@ -482,17 +553,17 @@ static void etx_value_change_callback_needed_check(uint16_t etx, uint16_t *store * * \param neigh_table_ptr the neighbor node in question */ -static void etx_accum_failures_callback_needed_check(struct mle_neigh_table_entry_t *neigh_table_ptr) +static void etx_accum_failures_callback_needed_check(etx_storage_t * entry, uint8_t attribute_index) { if (!etx_info.accum_threshold) { return; } - if (neigh_table_ptr->accumulated_failures < etx_info.accum_threshold) { + if (entry->accumulated_failures < etx_info.accum_threshold) { return; } - etx_info.accum_cb_ptr(etx_info.interface_id, neigh_table_ptr->accumulated_failures, neigh_table_ptr); + etx_info.accum_cb_ptr(etx_info.interface_id, entry->accumulated_failures, attribute_index); } /** @@ -504,19 +575,22 @@ static void etx_accum_failures_callback_needed_check(struct mle_neigh_table_entr * \param mac64_addr_ptr long MAC address * */ -void etx_neighbor_remove(int8_t interface_id, mle_neigh_table_entry_t *neigh_table_ptr) { +void etx_neighbor_remove(int8_t interface_id, uint8_t attribute_index) { + tr_debug("Remove attribute %u", attribute_index); uint16_t stored_diff_etx; - (void) interface_id; - if (neigh_table_ptr && etx_info.callback_ptr) { - if (neigh_table_ptr->etx) { - stored_diff_etx = neigh_table_ptr->stored_diff_etx >> 4; + etx_storage_t *entry = etx_storage_entry_get(interface_id, attribute_index); + if (entry && etx_info.callback_ptr) { + + if (entry->etx) { + stored_diff_etx = entry->stored_diff_etx >> 4; if (!stored_diff_etx) { stored_diff_etx = 0xffff; } - etx_info.callback_ptr(etx_info.interface_id, stored_diff_etx, 0xffff, neigh_table_ptr->mac64, - neigh_table_ptr->short_adr); + etx_info.callback_ptr(etx_info.interface_id, stored_diff_etx, 0xffff, attribute_index); } + //Clear all data base back to zero for new user + memset(entry, 0, sizeof(etx_storage_t)); } } @@ -529,20 +603,21 @@ void etx_neighbor_remove(int8_t interface_id, mle_neigh_table_entry_t *neigh_tab * \param mac64_addr_ptr long MAC address * */ -void etx_neighbor_add(int8_t interface_id, mle_neigh_table_entry_t *neigh_table_ptr) { +void etx_neighbor_add(int8_t interface_id, uint8_t attribute_index) { + tr_debug("Add attribute %u", attribute_index); uint16_t stored_diff_etx; - (void) interface_id; - if (neigh_table_ptr && etx_info.callback_ptr) { + etx_storage_t *entry = etx_storage_entry_get(interface_id, attribute_index); + if (entry && etx_info.callback_ptr) { // Gets table entry - if (neigh_table_ptr->etx) { - stored_diff_etx = neigh_table_ptr->stored_diff_etx; + if (entry->etx) { + stored_diff_etx = entry->stored_diff_etx; if (!stored_diff_etx) { - stored_diff_etx = neigh_table_ptr->etx; + stored_diff_etx = entry->etx; } - etx_info.callback_ptr(etx_info.interface_id, stored_diff_etx >> 4, neigh_table_ptr->etx >> 4, - neigh_table_ptr->mac64, neigh_table_ptr->short_adr); + etx_info.callback_ptr(etx_info.interface_id, stored_diff_etx >> 4, entry->etx >> 4, + attribute_index); } } } diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/etx/etx.h b/features/nanostack/sal-stack-nanostack/source/Service_Libs/etx/etx.h index f234b848681b..12b1ee6117cf 100644 --- a/features/nanostack/sal-stack-nanostack/source/Service_Libs/etx/etx.h +++ b/features/nanostack/sal-stack-nanostack/source/Service_Libs/etx/etx.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -26,12 +26,20 @@ #include "NWK_INTERFACE/Include/protocol_abstract.h" -struct mle_neigh_table_entry_t; /* Fraction that is used when calculating moving average e.g. ETX = 7/8 * current ETX + 1/8 * new ETX sample Range for value can be from 1 to 11 */ #define ETX_MOVING_AVERAGE_FRACTION 3 // n >> 3, 1/8 +typedef struct etx_storage_s { + uint16_t etx; /*!< 12 bits fraction */ + uint16_t stored_diff_etx; /*!< 12 bits fraction */ + uint8_t remote_incoming_idr; /*!< 5 bits fraction */ + unsigned accumulated_failures: 5; + unsigned tmp_etx: 1; + unsigned linkIdr: 4; +} etx_storage_t; + /** * \brief A function to update ETX value based on transmission attempts * @@ -41,10 +49,9 @@ struct mle_neigh_table_entry_t; * \param interface_id Interface identifier * \param attempts number of attempts to send message * \param success was message sending successful - * \param addr_type address type, ADDR_802_15_4_SHORT or ADDR_802_15_4_LONG - * \param addr_ptr PAN ID with 802.15.4 address + * \param attribute_index Neighbour attribute index */ -void etx_transm_attempts_update(int8_t interface_id, uint8_t attempts, bool success, addrtype_t addr_type, const uint8_t *addr_ptr); +void etx_transm_attempts_update(int8_t interface_id, uint8_t attempts, bool success, uint8_t attribute_index); /** * \brief A function to update ETX value based on remote incoming IDR @@ -54,9 +61,9 @@ void etx_transm_attempts_update(int8_t interface_id, uint8_t attempts, bool succ * * \param interface_id Interface identifier * \param remote_incoming_idr Remote incoming IDR - * \param mac64_addr_ptr long MAC address + * \param attribute_index Neighbour attribute index */ -void etx_remote_incoming_idr_update(int8_t interface_id, uint8_t remote_incoming_idr, struct mle_neigh_table_entry_t *neigh_table_ptr); +void etx_remote_incoming_idr_update(int8_t interface_id, uint8_t remote_incoming_idr, uint8_t attribute_index); /** * \brief A function to read ETX value @@ -77,14 +84,26 @@ uint16_t etx_read(int8_t interface_id, addrtype_t addr_type, const uint8_t *addr /** * \brief A function to read local incoming IDR value * - * Returns local incoming IDR value for an address + * Returns local incoming IDR value for an neighbour * - * \param mac64_addr_ptr long MAC address + * \param attribute_index Neighbour attribute index * * \return 0x0100 to 0xFFFF incoming IDR value (8 bit fraction) * \return 0x0000 address unknown */ -uint16_t etx_local_incoming_idr_read(int8_t interface_id, struct mle_neigh_table_entry_t *neigh_table_ptr); +uint16_t etx_local_incoming_idr_read(int8_t interface_id, uint8_t attribute_index); + +/** + * \brief A function to read local ETXvalue + * + * Returns local ETX value for an address + * + * \param mac64_addr_ptr long MAC address + * + * \return 0x0100 to 0xFFFF ETX value (8 bit fraction) + * \return 0x0000 address unknown + */ +uint16_t etx_local_etx_read(int8_t interface_id, uint8_t attribute_index); /** * \brief A function to update ETX value based on LQI and dBm @@ -93,11 +112,11 @@ uint16_t etx_local_incoming_idr_read(int8_t interface_id, struct mle_neigh_table * * \param lqi link quality indicator * \param dbm measured dBm - * \param mac64_addr_ptr long MAC address + * \param attribute_index Neighbour attribute index * * \return 0x0100 to 0xFFFF local incoming IDR value (8 bit fraction) */ -uint16_t etx_lqi_dbm_update(int8_t interface_id, uint8_t lqi, int8_t dbm, struct mle_neigh_table_entry_t *neigh_table_ptr); +uint16_t etx_lqi_dbm_update(int8_t interface_id, uint8_t lqi, int8_t dbm, uint8_t attribute_index); /** * \brief A function callback that indicates ETX value change @@ -108,11 +127,10 @@ uint16_t etx_lqi_dbm_update(int8_t interface_id, uint8_t lqi, int8_t dbm, struct * \param nwk_interface_id network interface id * \param previous_etx ETX value to what the current ETX was compared (8 bit fraction) * \param current_etx current ETX value (8 bit fraction) - * \param mac64_addr_ptr long MAC address - * \param mac16_addr short MAC address or 0xffff address is not set + * \param attribute_index Neighbour attribute index * */ -typedef void (etx_value_change_handler_t)(int8_t nwk_id, uint16_t previous_etx, uint16_t current_etx, const uint8_t *mac64_addr_ptr, uint16_t mac16_addr); +typedef void (etx_value_change_handler_t)(int8_t nwk_id, uint16_t previous_etx, uint16_t current_etx, uint8_t attribute_index); /** * \brief A function callback that indicates the number of accumulated TX failures @@ -121,10 +139,10 @@ typedef void (etx_value_change_handler_t)(int8_t nwk_id, uint16_t previous_etx, * * \param interface_id interface ID * \param accumulated_failures number of accumulated failures - * \param neigh_table_ptr the neighbor node in question + * \param attribute_index Neighbour attribute index * */ -typedef void (etx_accum_failures_handler_t)(int8_t interface_id, uint8_t accumulated_failures, struct mle_neigh_table_entry_t *neigh_table_ptr); +typedef void (etx_accum_failures_handler_t)(int8_t interface_id, uint8_t accumulated_failures, uint8_t attribute_index); /** * \brief A function to register ETX value change callback @@ -141,6 +159,29 @@ typedef void (etx_accum_failures_handler_t)(int8_t interface_id, uint8_t accumul */ uint8_t etx_value_change_callback_register(nwk_interface_id nwk_id,int8_t interface_id, uint16_t hysteresis, etx_value_change_handler_t *callback_ptr); +/** + * \brief A function to allocte ETX storage list + * + * \param interface_id interface id + * \param etx_storage_size Size of storage. 0 will free allocate data + * + * \return false Allocate fail + * \return true Allocate OK + */ +bool etx_storage_list_allocate(int8_t interface_id, uint8_t etx_storage_size); + +/** + * \brief A function to read ETX storage for defined neighbour + * + * \param interface_id interface id + * \param attribute_index Neighbour attribute index + * + * \return Pointer to ETX storage + * \return NULL When unknow interface or attribute + */ +etx_storage_t *etx_storage_entry_get(int8_t interface_id, uint8_t attribute_index); + + /** * \brief A function to register accumulated failures callback * @@ -164,10 +205,10 @@ uint8_t etx_accum_failures_callback_register(nwk_interface_id nwk_id, int8_t int * Notifies ETX module that neighbor has been removed. Calls ETX value change callback * if that is set. * - * \param mac64_addr_ptr long MAC address + * \param attribute_index Neighbour attribute index * */ -void etx_neighbor_remove(int8_t interface_id, struct mle_neigh_table_entry_t *neigh_table_ptr); +void etx_neighbor_remove(int8_t interface_id, uint8_t attribute_index); /** * \brief A function to add ETX neighbor @@ -175,9 +216,9 @@ void etx_neighbor_remove(int8_t interface_id, struct mle_neigh_table_entry_t *ne * Notifies ETX module that neighbor has been added. Calls ETX value change callback * if that is set. * - * \param mac64_addr_ptr long MAC address + * \param attribute_index Neighbour attribute index * */ -void etx_neighbor_add(int8_t interface_id, struct mle_neigh_table_entry_t *neigh_table_ptr); +void etx_neighbor_add(int8_t interface_id, uint8_t attribute_index); #endif /* ETX_H_ */ diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/channel_functions.h b/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/channel_functions.h new file mode 100644 index 000000000000..990a7ac90e60 --- /dev/null +++ b/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/channel_functions.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2018, Arm Limited and affiliates. + * 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 CHANNEL_FUNC_H_ +#define CHANNEL_FUNC_H_ + +/** + * @brief Compute the unicast schedule channel index using tr51 channel function. + * @param slot_number Current slot number. + * @param mac MAC address of the node for which the index is calculated. + * @param number_of_channels Number of channels. + * @param excluded_channels Excluded channels. + * @return Channel index. + */ +int32_t tr51_get_uc_channel_index(uint16_t slot_number, uint8_t *mac, int16_t number_of_channels, uint32_t *excluded_channels); + +/** + * @brief Compute the broadcast schedule channel index using tr51 channel function. + * @param slot_number Current slot number. + * @param bsi Broadcast schedule identifier of the node for which the index is calculated. + * @param number_of_channels Number of channels. + * @param excluded_channels Excluded channels. + * @return Channel index. + */ +int32_t tr51_get_bc_channel_index(uint16_t slot_number, uint16_t bsi, int16_t number_of_channels, uint32_t *excluded_channels); + +/** + * @brief Compute the unicast schedule channel index using direct hash channel function. + * @param slot_number Current slot number. + * @param mac MAC address of the node for which the index is calculated. + * @param number_of_channels Number of channels. + * @return Channel index. + */ +int32_t dh1cf_get_uc_channel_index(uint16_t slot_number, uint8_t *mac, int16_t number_of_channels); + +/** + * @brief Compute the broadcast schedule channel index using direct hash channel function. + * @param slot_number Current slot number. + * @param bsi Broadcast schedule identifier of the node for which the index is calculated. + * @param number_of_channels Number of channels. + * @return Channel index. + */ +int32_t dh1cf_get_bc_channel_index(uint16_t slot_number, uint16_t bsi, int16_t number_of_channels); + +#endif /*CHANNEL_FUNC_H_*/ diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/channel_list.c b/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/channel_list.c index baabf9e73465..7d22696bd951 100644 --- a/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/channel_list.c +++ b/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/channel_list.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -30,11 +30,6 @@ const int CHANNEL_LIST_SIZE_IN_BITS = 8*32; static bool channel_list_bit_test32(uint32_t word, int_fast8_t bit_number); static bool channel_list_bit_test(const uint32_t* list, int bit_number); -#if 0 -static void channel_list_bit_set32(uint32_t* word, int_fast8_t bit_number); -static void channel_list_bit_set(uint32_t* list, int bit_number); -#endif - // test bit by number static bool channel_list_bit_test32(uint32_t word, int_fast8_t bit_number) { @@ -55,78 +50,7 @@ static bool channel_list_bit_test(const uint32_t* list, int bit_number) return channel_list_bit_test32(list[word_index], bit_index); } -#if 0 -// set bit by number -static void channel_list_bit_set32(uint32_t* word, int_fast8_t bit_number) -{ - *word |= ((uint32_t) 1 << bit_number); -} - -static void channel_list_bit_set(uint32_t* list, int bit_number) -{ - const int_fast8_t word_index = bit_number / 32; - const int_fast8_t bit_index = bit_number % 32; - - channel_list_bit_set32(&(list[word_index]), bit_index); -} - - -void channel_list_print(uint8_t dlevel, const char *grp, const uint32_t* list) -{ - - int temp_channel = 0; - -#define CHANNELS_PER_LINE 32 - - uint8_t channels[CHANNELS_PER_LINE]; - - for (int line_index = 0; line_index < (CHANNEL_LIST_SIZE_IN_BITS/CHANNELS_PER_LINE); line_index++) { - - int channels_found = 0; - - for (int row_index = 0; row_index < CHANNELS_PER_LINE; row_index++) { - - if (channel_list_bit_test(list, temp_channel)) { - - channels[channels_found] = temp_channel; - channels_found++; - } - - temp_channel++; - } - - tr_info("arr[%d]: %s", line_index, trace_array(channels, channels_found)); - } -} - -// this just avoids mistakes/copypaste on client side -void channel_list_clear_mask(uint32_t* list) -{ - const int mask_size = (sizeof(list)); - - memset(list, 0, mask_size); -} - -static int channel_list_search_in_range(const uint32_t* list, int start_index, int end_index) -{ - int found_index = -1; - for (int index = start_index; index <= end_index; index++) { - - if (channel_list_bit_test(list, index)) { - found_index = index; - break; - } - } - return found_index; -} - -// utility for getting the first channel -int channel_list_get_first(const uint32_t* list) -{ - return channel_list_get_next(list, 0xff); -} -#endif static uint8_t channel_list_search(const uint32_t* list, int index) { uint8_t channel = 0; @@ -163,58 +87,7 @@ uint8_t channel_list_get_channel(const uint32_t* list, int current_index) return found_index; } -#if 0 -int channel_list_get_next(const uint32_t* list, int current_index) -{ - int found_index; - - current_index++; - - if (current_index >= CHANNEL_LIST_SIZE_IN_BITS) { - - current_index = 0; - } - - // One could use a optimization here to avoid looping through masks 1..7 - // if page is not 9 or 10. But is it really worth it? - found_index = channel_list_search_in_range(list, current_index, CHANNEL_LIST_SIZE_IN_BITS-1); - - if ((found_index < 0) && (current_index > 0)) { - - found_index = channel_list_search_in_range(list, 0, current_index-1); - } - - return found_index; -} - -int channel_list_get_next_broadcast(const uint32_t* list, int broadcast_channel_count, int current_index) -{ - - // XXX: all these could/should be pre-calculated on configuration time. - const int first_broadcast = channel_list_get_first(list); - const int total_channel_count = channel_list_count_channels(list); - int channels_to_loop = total_channel_count / broadcast_channel_count; // crash if broadcast is configured to zero - - int next_broadcast = -1; - - // If there are more than one broadcast channels and we're not yet at the last channel, - // iteratively search for next broadcast channel. - if ((channels_to_loop > 1) && (current_index < (CHANNEL_LIST_SIZE_IN_BITS - 1))) { - while (channels_to_loop > 0) { - - current_index = channel_list_get_next(list, current_index); - channels_to_loop--; - } - next_broadcast = current_index; - } - else { - next_broadcast = first_broadcast; - } - - return next_broadcast; -} -#endif // count the amount of channels enabled in a list int channel_list_count_channels(const uint32_t* list) { @@ -230,30 +103,3 @@ int channel_list_count_channels(const uint32_t* list) return channel_count; } -#if 0 -int channel_list_enable_channel(uint32_t* list, int channel_number) -{ - int ret_val = -1; - - if ((channel_number >= 0) && (channel_number < CHANNEL_LIST_SIZE_IN_BITS)) { - - channel_list_bit_set(list, channel_number); - - ret_val = 0; - } - - return ret_val; -} - -bool channel_list_is_channel_enabled(const uint32_t* list, int channel_number) { - - int ret_val = false; - - if ((channel_number >= 0) && (channel_number < CHANNEL_LIST_SIZE_IN_BITS)) { - - ret_val = channel_list_bit_test(list, channel_number); - } - - return ret_val; -} -#endif diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/channel_list.h b/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/channel_list.h index 86ec6bf03d5d..5e3a2139e0d3 100644 --- a/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/channel_list.h +++ b/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/channel_list.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -22,11 +22,6 @@ extern "C" { #endif -/** - * Dump the channel list object data to ns_trace using given trace level and group. - */ -void channel_list_print(uint8_t dlevel, const char* grp, const uint32_t* list); - /** * Get channel number using channel index. * @@ -37,34 +32,6 @@ void channel_list_print(uint8_t dlevel, const char* grp, const uint32_t* list); */ uint8_t channel_list_get_channel(const uint32_t* list, int current_index); -/** - * Clear the channel mask bitmap, does not change channel page. - * - * @param list list which mask is to be cleared - */ -void channel_list_clear_mask(uint32_t* list); - -/** - * Get next enabled channel number from given list. Channels are now taken sequentially, - * starting from the index given. - * - * @param list to scan - * @param the currently used channel index, ie. the place where search for next channel - * is started - * @return channel number of next channel - */ -int channel_list_get_next(const uint32_t* list, int current_index); - -int channel_list_get_next_broadcast(const uint32_t* list, int broadcast_channel_count, int current_index); - -/** - * Get the first channel enabled in a list. - * - * @param list to scan - * @return index of the first channel enabled - */ -int channel_list_get_first(const uint32_t* list); - /** * Count the amount of channels enabled in a list. * @@ -73,31 +40,6 @@ int channel_list_get_first(const uint32_t* list); */ int channel_list_count_channels(const uint32_t* list); -/** - * Enable channel by given channel number. This is likely to be used - * from the test/application configuration side. - * - * Note: the channel number validity is not (yet?) verified, so one - * can enable invalid channels which should not be according to channel page. - * - * @param list to modify - * @param channel number - * @return 0 on success, negative on failure (out of bounds channel) - */ -int channel_list_enable_channel(uint32_t* list, int channel_number); - -/** - * Check, if given channel is enabled. This is likely to be used - * from the test/application configuration side. - * - * Note: the channel number validity is not (yet?) verified, so one - * can enable invalid channels which should not be according to channel page. - * - * @param list to test - * @param channel number - * @return true, if channel is enabled on mask, false if not - */ -bool channel_list_is_channel_enabled(const uint32_t* list, int channel_number); #ifdef __cplusplus } diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss.c b/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss.c index 9294007c6f06..5e898153a46c 100644 --- a/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss.c +++ b/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,133 +19,76 @@ #include "fhss_api.h" #include "fhss_config.h" #include "fhss.h" +#include "fhss_common.h" #include "fhss_channel.h" #include "channel_list.h" #include "nsdynmemLIB.h" -#include "fhss_beacon.h" #include "fhss_statistics.h" #include "ns_trace.h" #include "eventOS_event.h" #include "eventOS_callback_timer.h" +#include "platform/arm_hal_interrupt.h" #include "randLIB.h" +#include "common_functions.h" #include #define TRACE_GROUP "fhss" -// Uncomment this to get timestamped output on superframe events. -// Note: the result may be massive, as there will be dozens or hundreds of lines of trace per second. -// #define FHSS_MASSIVE_TRACE - -// TODO: create linked list -// FHSS object pointer -fhss_structure_t *fhss_struct = 0; +static int fhss_reset(fhss_structure_t *fhss_structure); +static bool fhss_is_bc_sending_superframe(fhss_structure_t *fhss_structure); static bool fhss_check_remaining_tx_time(fhss_structure_t *fhss_structure, uint16_t tx_length, uint8_t phy_header_length, uint8_t phy_tail_length); -static void fhss_event_timer_cb(int8_t timer_id, uint16_t slots); -static fhss_structure_t *fhss_get_object_with_timer_id(const int8_t timer_id); -static int fhss_generate_scramble_table(fhss_structure_t *fhss_structure); static bool fhss_is_there_common_divisor(uint16_t i, uint8_t j); -static void fhss_update_channel(fhss_structure_t *fhss_structure); -static int fhss_reset_synch_monitor(fhss_synch_monitor_s *synch_monitor, bool reset_compensation); -static int fhss_reset(fhss_structure_t *fhss_structure); -static void fhss_failed_list_free(fhss_structure_t *fhss_structure); - - -int8_t fhss_enable(fhss_api_t *fhss_api, const fhss_configuration_t *fhss_configuration, const fhss_timer_t *fhss_timer, fhss_statistics_t *fhss_statistics) +static void fhss_beacon_received(fhss_structure_t *fhss_structure, const uint8_t *synch_info, const uint32_t elapsed_time); +static void fhss_superframe_handler(const fhss_api_t *fhss_api, uint16_t delay); +static int8_t fhss_beacon_create_tasklet(fhss_structure_t *fhss_structure); +static void fhss_beacon_tasklet_func(arm_event_s* event); +static int fhss_beacon_periodic_start(fhss_structure_t *fhss_structure, uint32_t time_to_first_beacon); +static void fhss_beacon_periodic_stop(fhss_structure_t *fhss_structure); + +fhss_structure_t *fhss_enable(fhss_api_t *fhss_api, const fhss_configuration_t *fhss_configuration, const fhss_timer_t *fhss_timer, fhss_statistics_t *fhss_statistics) { - if (!fhss_api || !fhss_configuration || !fhss_timer || fhss_struct) { + if (!fhss_api || !fhss_configuration || !fhss_timer) { tr_err("Invalid FHSS enable configuration"); - return -1; + return NULL; } int channel_count = channel_list_count_channels(fhss_configuration->channel_mask); if (channel_count <= 0) { // There must be at least one configured channel in channel list - return -2; + return NULL; } - fhss_struct = ns_dyn_mem_alloc(sizeof(fhss_structure_t)); + fhss_structure_t *fhss_struct = fhss_allocate_instance(fhss_api, fhss_timer); if (!fhss_struct) { - return -3; + return NULL; + } + fhss_struct->bs = ns_dyn_mem_alloc(sizeof(fhss_bs_t)); + if (!fhss_struct->bs) { + fhss_free_instance(fhss_api); + return NULL; } - fhss_struct->fhss_api = fhss_api; - fhss_struct->fhss_configuration = *fhss_configuration; - fhss_struct->platform_functions = *fhss_timer; - fhss_struct->fhss_stats_ptr = fhss_statistics; + memset(fhss_struct->bs, 0, sizeof(fhss_bs_t)); + + fhss_struct->bs->fhss_configuration = *fhss_configuration; + fhss_struct->bs->fhss_stats_ptr = fhss_statistics; fhss_struct->number_of_channels = channel_count; // set a invalid id to tasklet_id, so we know that one is not started yet fhss_struct->beacon_tasklet_id = -1; - if (!fhss_struct->platform_functions.fhss_resolution_divider) { - fhss_struct->platform_functions.fhss_resolution_divider = 1; - } // Default synch interval is 240 seconds - if (!fhss_struct->fhss_configuration.fhss_max_synch_interval) { - fhss_struct->fhss_configuration.fhss_max_synch_interval = 240; + if (!fhss_struct->bs->fhss_configuration.fhss_max_synch_interval) { + fhss_struct->bs->fhss_configuration.fhss_max_synch_interval = 240; } ns_list_init(&fhss_struct->fhss_failed_tx_list); fhss_struct->own_hop = 0xff; fhss_reset(fhss_struct); - fhss_reset_synch_monitor(&fhss_struct->synch_monitor, true); - fhss_struct->active_fhss_events = 0; - fhss_struct->fhss_beacon_info_store = NULL; - fhss_struct->fhss_event_timer = eventOS_callback_timer_register(fhss_event_timer_cb); - - fhss_generate_scramble_table(fhss_struct); if (fhss_beacon_create_tasklet(fhss_struct) < 0) { - // XXX: should we free the fhss_structure here? - return -5; - } - - return 0; -} - -int8_t fhss_set_datarate(fhss_structure_t *fhss_structure, uint32_t datarate) -{ - if (!fhss_structure) { - return -1; - } - // If datarate is not set, use default 250kbit/s. Datarate is used as divider later. - if (!datarate) { - datarate = 250000; - } - fhss_structure->datarate = datarate; - return 0; -} - -int8_t fhss_set_synch_configuration(fhss_structure_t *fhss_structure, const fhss_synch_configuration_t *fhss_synch_configuration) -{ - if (!fhss_structure) { - return -1; - } - if (!fhss_synch_configuration) { - return -2; - } - // None of the configurations can be set zero - if( fhss_synch_configuration->fhss_number_of_bc_channels == 0 || fhss_synch_configuration->fhss_number_of_tx_slots == 0 - || fhss_synch_configuration->fhss_number_of_superframes == 0 || fhss_synch_configuration->fhss_superframe_length == 0) { - return -3; - } - // Number of channels must be divisible with the number of broadcast channels. - // Number of superframes must be divisible with the number of TX slots - if (((fhss_structure->number_of_channels % fhss_synch_configuration->fhss_number_of_bc_channels) != 0) || - ((fhss_synch_configuration->fhss_number_of_superframes % fhss_synch_configuration->fhss_number_of_tx_slots) != 0) || - (fhss_synch_configuration->fhss_number_of_superframes <= fhss_synch_configuration->fhss_number_of_tx_slots)) { - return -4; - } - fhss_structure->synch_configuration = *fhss_synch_configuration; - fhss_structure->own_hop = 0; - return 0; -} - -fhss_structure_t *fhss_get_object_with_api(const fhss_api_t *fhss_api) -{ - if (!fhss_api || !fhss_struct) { + ns_dyn_mem_free(fhss_struct->bs); + fhss_free_instance(fhss_api); return NULL; } - if (fhss_struct->fhss_api == fhss_api) { - return fhss_struct; - } - return NULL; + + return fhss_struct; } bool fhss_is_synch_root(fhss_structure_t *fhss_structure) @@ -156,45 +99,16 @@ bool fhss_is_synch_root(fhss_structure_t *fhss_structure) return true; } -void fhss_set_active_event(fhss_structure_t *fhss_structure, uint8_t event_type) -{ - fhss_structure->active_fhss_events |= (1 << event_type); -} - -void fhss_clear_active_event(fhss_structure_t *fhss_structure, uint8_t event_type) -{ - fhss_structure->active_fhss_events &= ~(1 << event_type); -} - -bool fhss_read_active_event(fhss_structure_t *fhss_structure, uint8_t event_type) -{ - if (fhss_structure->active_fhss_events & (1 << event_type)) { - return true; - } - return false; -} - -static fhss_structure_t *fhss_get_object_with_timer_id(const int8_t timer_id) -{ - if (timer_id <0 || !fhss_struct) { - return NULL; - } - if (fhss_struct->fhss_event_timer == timer_id) { - return fhss_struct; - } - return NULL; -} - static bool fhss_is_bc_sending_superframe(fhss_structure_t *fhss_structure) { - if (fhss_structure->current_superframe >= fhss_structure->broadcast_start_superframe) { + if (fhss_structure->bs->current_superframe >= fhss_structure->bs->broadcast_start_superframe) { return true; } return false; } -bool fhss_check_bad_channel(fhss_structure_t *fhss_structure, uint8_t handle) +static bool fhss_check_bad_channel(fhss_structure_t *fhss_structure, uint8_t handle) { if (!fhss_structure) { return false; @@ -209,7 +123,7 @@ bool fhss_check_bad_channel(fhss_structure_t *fhss_structure, uint8_t handle) return true; } -bool fhss_check_channel_type(fhss_structure_t *fhss_structure, bool is_bc, int frame_type) +static bool fhss_check_channel_type(fhss_structure_t *fhss_structure, bool is_bc, int frame_type) { if (!fhss_structure) { return false; @@ -228,7 +142,7 @@ bool fhss_check_channel_type(fhss_structure_t *fhss_structure, bool is_bc, int f } } else if (fhss_is_current_channel_broadcast(fhss_structure) == true) { // Drop: If waiting synchronization Beacon and packet has unicast destination - if (fhss_structure->beacons_received_timer) { + if (fhss_structure->bs->beacons_received_timer) { return false; } } @@ -238,26 +152,26 @@ bool fhss_check_channel_type(fhss_structure_t *fhss_structure, bool is_bc, int f } if (frame_type == FHSS_SYNCH_REQUEST_FRAME) { // Drop: If we have unicast channels in our configuration and current channel is broadcast channel - if ((fhss_structure->number_of_channels > fhss_structure->synch_configuration.fhss_number_of_bc_channels) && (fhss_is_current_channel_broadcast(fhss_structure) == true)) { + if ((fhss_structure->number_of_channels > fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels) && (fhss_is_current_channel_broadcast(fhss_structure) == true)) { return false; } - uint8_t current_superframe = fhss_structure->current_superframe; - uint8_t synch_attempt = fhss_structure->beacons_received_timer; - if (fhss_structure->synch_configuration.fhss_number_of_tx_slots > 1) { + uint8_t current_superframe = fhss_structure->bs->current_superframe; + uint8_t synch_attempt = fhss_structure->bs->beacons_received_timer; + if (fhss_structure->bs->synch_configuration.fhss_number_of_tx_slots > 1) { // Send synch request either before or after the middle of the channel depending on attempt number. - uint8_t middle_of_superframes = fhss_structure->synch_configuration.fhss_number_of_superframes / 2; + uint8_t middle_of_superframes = fhss_structure->bs->synch_configuration.fhss_number_of_superframes / 2; if (synch_attempt & 1) { - if (fhss_structure->current_superframe < middle_of_superframes) { + if (fhss_structure->bs->current_superframe < middle_of_superframes) { return false; } } else { - if (fhss_structure->current_superframe >= middle_of_superframes) { + if (fhss_structure->bs->current_superframe >= middle_of_superframes) { return false; } } - } else if ((current_superframe == 0) || (current_superframe == (fhss_structure->synch_configuration.fhss_number_of_superframes - 1))){ + } else if ((current_superframe == 0) || (current_superframe == (fhss_structure->bs->synch_configuration.fhss_number_of_superframes - 1))){ return false; } } @@ -265,7 +179,7 @@ bool fhss_check_channel_type(fhss_structure_t *fhss_structure, bool is_bc, int f } -bool fhss_check_tx_allowed(fhss_structure_t *fhss_structure, bool is_bc, uint16_t frame_length, int frame_type, uint8_t phy_header_length, uint8_t phy_tail_length) +static bool fhss_check_tx_allowed(fhss_structure_t *fhss_structure, bool is_bc, uint16_t frame_length, int frame_type, uint8_t phy_header_length, uint8_t phy_tail_length) { if (!fhss_structure) { return false; @@ -283,7 +197,7 @@ bool fhss_check_tx_allowed(fhss_structure_t *fhss_structure, bool is_bc, uint16_ return true; } // Deny: If FHSS is not on TX slot - if (fhss_structure->tx_allowed == false) { + if (fhss_structure->bs->tx_allowed == false) { return false; } // Deny: If not enough time before TX slot end @@ -293,205 +207,23 @@ bool fhss_check_tx_allowed(fhss_structure_t *fhss_structure, bool is_bc, uint16_ return true; } -static int fhss_reset_synch_monitor(fhss_synch_monitor_s *synch_monitor, bool reset_compensation) +static int fhss_reset_synch_monitor(fhss_synch_monitor_s *synch_monitor) { if (synch_monitor) { synch_monitor->avg_synch_fix = 0; // Initialize to -1 instead of 0 to drop the first beacon after network scan (from synch monitoring) synch_monitor->avg_synch_fix_counter = -1; - if (reset_compensation == true) { - synch_monitor->drift_compensation = 0; - } synch_monitor->channel_counter = 0; return 0; } return -1; } -static int fhss_reset(fhss_structure_t *fhss_structure) -{ - if (fhss_structure) { - fhss_structure->platform_functions.fhss_timer_stop(fhss_structure->fhss_api); - fhss_struct->synch_panid = 0xffff; - fhss_beacon_periodic_stop(fhss_structure); - fhss_struct->current_superframe = 0; - fhss_struct->current_channel_index = 0; - fhss_struct->channel_list_counter = 0; - if (fhss_is_synch_root(fhss_structure) == false) { - fhss_struct->own_hop = 0xff; - } - fhss_struct->tx_allowed = false; - fhss_struct->synch_interval = (uint32_t) (fhss_struct->fhss_configuration.fhss_max_synch_interval/BEACON_INTERVAL_INIT_DIVIDER) * 1000; - fhss_struct->rx_channel = 0; - fhss_struct->beacons_received_timer = 0; - memset(fhss_struct->synch_parent, 0xff, 8); - fhss_struct->send_synch_info_on_next_broadcast_channel = false; - memset(&fhss_struct->synch_configuration, 0, sizeof(fhss_synch_configuration_t)); - fhss_struct->synch_infos_sent_counter = 0; - fhss_struct->broadcast_start_superframe = 0; - fhss_failed_list_free(fhss_structure); - fhss_struct->fhss_state = FHSS_UNSYNCHRONIZED; - return 0; - } - return -1; -} - -int fhss_down(fhss_structure_t *fhss_structure) -{ - if (fhss_structure) { - fhss_reset(fhss_structure); - fhss_reset_synch_monitor(&fhss_struct->synch_monitor, false); - fhss_stats_update(fhss_structure, STATS_FHSS_DRIFT_COMP, fhss_structure->synch_monitor.drift_compensation); - fhss_stats_update(fhss_structure, STATS_FHSS_AVG_SYNCH_FIX, fhss_structure->synch_monitor.avg_synch_fix); - fhss_stats_update(fhss_structure, STATS_FHSS_SYNCH_INTERVAL, fhss_structure->synch_interval / 1000); - return 0; - } - return -1; -} - - -int8_t fhss_disable(fhss_structure_t *fhss_structure) -{ - if (!fhss_structure) { - return -1; - } - ns_dyn_mem_free(fhss_structure); - fhss_structure = 0; - fhss_struct = 0; - return 0; -} - -void fhss_start_timer(fhss_structure_t *fhss_structure, uint32_t time, void (*callback)(const fhss_api_t *fhss_api, uint16_t)) -{ - if (callback){ - // Don't allow starting with zero slots - if (time < fhss_structure->platform_functions.fhss_resolution_divider) { - time = fhss_structure->platform_functions.fhss_resolution_divider; - } - fhss_structure->platform_functions.fhss_timer_start(time / fhss_structure->platform_functions.fhss_resolution_divider, callback, fhss_structure->fhss_api); - } -} - -uint32_t fhss_get_remaining_time_to_next_superframe(const fhss_structure_t *fhss_structure) -{ - const uint32_t slots = fhss_structure->platform_functions.fhss_get_remaining_slots(fhss_structure->fhss_api); - const uint32_t time = slots * fhss_structure->platform_functions.fhss_resolution_divider; - return time; -} - -void fhss_superframe_handler(const fhss_api_t *fhss_api, uint16_t delay) -{ - int compensation = 0; - fhss_structure_t *fhss_structure = fhss_get_object_with_api(fhss_api); - if (!fhss_structure) { - return; - } -/* Drift compensation doesn't work with Linux platform */ -#ifndef __linux__ - // Drift compensation on first superframe - if (fhss_structure->current_superframe == 0) { - /* Idea is to compensate number of drift_compensation (microseconds) on each channel. - * However, fhss_resolution_divider defines the minimum timer resolution. - * E.g. if fhss_resolution_divider = 64, compensate (drift_compensation * 64) on each 64th channel. - */ - if (++fhss_structure->synch_monitor.channel_counter == fhss_structure->platform_functions.fhss_resolution_divider) { - compensation = fhss_structure->synch_monitor.drift_compensation; - fhss_structure->synch_monitor.channel_counter = 0; - } - } -#endif //__linux__ - // Restart timer asap to minimize the effect of dynamic execution time of - // the rest of function. - fhss_start_timer(fhss_structure, (fhss_structure->synch_configuration.fhss_superframe_length) - (delay * fhss_structure->platform_functions.fhss_resolution_divider) + (compensation * fhss_structure->platform_functions.fhss_resolution_divider), fhss_superframe_handler); - - // check, if the current frame was the last one - if (fhss_structure->current_superframe >= (fhss_structure->synch_configuration.fhss_number_of_superframes - 1)) { - - // last superframe has passed, change channel - fhss_structure->current_superframe = 0; - fhss_structure->current_channel_index++; - if (fhss_structure->current_channel_index >= fhss_structure->number_of_channels) { - fhss_structure->synch_infos_sent_counter = 0; - fhss_structure->current_channel_index = 0; - fhss_structure->channel_list_counter++; - // Repeated cycle is started from beginning, reset counter. Don't let the channel_list_counter overflow. - if (fhss_structure->channel_list_counter >= ((uint16_t) fhss_structure->number_of_channels * MAX_SCRAMBLE_TABLE_INDEXES)) { - fhss_structure->channel_list_counter = 0; - } - // Hop 0 don't have parent - if (fhss_is_synch_root(fhss_structure) == false) { - fhss_trig_event(fhss_structure, FHSS_COMPARE_SYNCH_PARENT); - } - fhss_trig_event(fhss_structure, FHSS_UPDATE_SYNCH_INFO_STORAGE); - } - fhss_update_channel(fhss_structure); - } else { - // bump up the superframe counter - fhss_structure->current_superframe++; - -#ifdef FHSS_MASSIVE_TRACE - tr_debug("%"PRIu32": handler, super: %"PRIu8, - fhss_structure->fhss_api->read_timestamp(fhss_structure->fhss_api), fhss_structure->current_superframe); -#endif - } - if ((fhss_structure->send_synch_info_on_next_broadcast_channel == true) && (fhss_is_current_channel_broadcast(fhss_structure) == true)) { - /* Randomize sending superframe of synchronization frame: - * on first superframe probability is 1/number of superframes - * on second superframe probability is 1/(number of superframes-1) - * on third superframe probability is 1/(number of superframes-2) - * on last superframe probability is 1/1 - */ - if (randLIB_get_random_in_range(1, fhss_structure->synch_configuration.fhss_number_of_superframes - fhss_structure->current_superframe) == 1) { - fhss_structure->send_synch_info_on_next_broadcast_channel = false; - fhss_structure->synch_infos_sent_counter++; - fhss_structure->callbacks.send_fhss_frame(fhss_structure->fhss_api, FHSS_SYNCH_FRAME); - } - } - fhss_update_txrx_slots(fhss_structure); - uint16_t queue_size = fhss_structure->callbacks.read_tx_queue_size(fhss_structure->fhss_api, false) + fhss_structure->callbacks.read_tx_queue_size(fhss_structure->fhss_api, true); - if ((fhss_structure->tx_allowed == true || fhss_is_current_channel_broadcast(fhss_structure) == true) && queue_size) { - /* Start timer with random timeout to trigger TX queue poll event. - * Max random is half of the superframe length. Event timer resolution is 50us. - * Divide Max random with TX queue size to transmit faster when TX queue is growing - */ - uint16_t max_random = ((fhss_structure->synch_configuration.fhss_superframe_length / 2) / 50) / queue_size; - eventOS_callback_timer_start(fhss_structure->fhss_event_timer, randLIB_get_random_in_range(1, max_random)); - } - if (fhss_structure->fhss_timeout) { - fhss_structure->fhss_timer += fhss_structure->synch_configuration.fhss_superframe_length; - if (fhss_structure->fhss_timer >= fhss_structure->fhss_timeout) { - fhss_trig_event(fhss_structure, FHSS_TIMER_EVENT); - fhss_structure->fhss_timeout = 0; - fhss_structure->fhss_timer = 0; - } - } -} - -int fhss_timeout_start(fhss_structure_t *fhss_structure, uint32_t time) -{ - if (!fhss_structure) { - return -1; - } - fhss_structure->fhss_timeout = time; - fhss_structure->fhss_timer = 0; - return 0; -} - -int fhss_timeout_stop(fhss_structure_t *fhss_structure) -{ - if (!fhss_structure) { - return -1; - } - fhss_structure->fhss_timeout = 0; - fhss_structure->fhss_timer = 0; - return 0; -} - -int fhss_update_txrx_slots(fhss_structure_t *fhss_structure) +static int fhss_update_txrx_slots(fhss_structure_t *fhss_structure) { - uint8_t cur_superframe = fhss_structure->current_superframe; - uint8_t number_of_tx_slots = fhss_structure->synch_configuration.fhss_number_of_tx_slots; - uint8_t number_of_superframes = fhss_structure->synch_configuration.fhss_number_of_superframes; + uint8_t cur_superframe = fhss_structure->bs->current_superframe; + uint8_t number_of_tx_slots = fhss_structure->bs->synch_configuration.fhss_number_of_tx_slots; + uint8_t number_of_superframes = fhss_structure->bs->synch_configuration.fhss_number_of_superframes; uint8_t tx_slot_length = ((number_of_superframes / 2) / number_of_tx_slots); uint8_t tx_slot_up_limit = tx_slot_length; bool tx_allowed = false; @@ -521,7 +253,7 @@ int fhss_update_txrx_slots(fhss_structure_t *fhss_structure) tx_slot_up_limit += (tx_slot_length * 2); } } - fhss_structure->tx_allowed = tx_allowed; + fhss_structure->bs->tx_allowed = tx_allowed; return 0; } @@ -536,22 +268,22 @@ static int fhss_update_drift_compensation(fhss_structure_t *fhss_structure) if (!fhss_structure) { return 0; } - bc_density = (fhss_structure->number_of_channels / fhss_structure->synch_configuration.fhss_number_of_bc_channels); - channel_dwell_time = ((uint32_t)fhss_structure->synch_configuration.fhss_superframe_length * fhss_structure->synch_configuration.fhss_number_of_superframes) / 1000; + bc_density = (fhss_structure->number_of_channels / fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels); + channel_dwell_time = ((uint32_t)fhss_structure->bs->synch_configuration.fhss_superframe_length * fhss_structure->bs->synch_configuration.fhss_number_of_superframes) / 1000; // Calculate last synchronisation period - if (fhss_structure->synch_interval != ((uint32_t)fhss_structure->fhss_configuration.fhss_max_synch_interval * 1000)) { + if (fhss_structure->bs->synch_interval != ((uint32_t)fhss_structure->bs->fhss_configuration.fhss_max_synch_interval * 1000)) { // Last period was half of the current started period and max random period is shorter - synch_period = (fhss_structure->synch_interval / 2) + (bc_density * channel_dwell_time) * (fhss_structure->synch_configuration.fhss_number_of_bc_channels / 2); + synch_period = (fhss_structure->bs->synch_interval / 2) + (bc_density * channel_dwell_time) * (fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels / 2); } else { - synch_period = fhss_structure->synch_interval + (bc_density * channel_dwell_time) * fhss_structure->synch_configuration.fhss_number_of_bc_channels; + synch_period = fhss_structure->bs->synch_interval + (bc_density * channel_dwell_time) * fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels; } // E.g. 240000ms / (50000us * 8) = 600 channels per fhss_beacon_send_interval - channels_per_synch_period = (synch_period * 1000) / ((uint32_t)fhss_structure->synch_configuration.fhss_superframe_length * fhss_structure->synch_configuration.fhss_number_of_superframes); + channels_per_synch_period = (synch_period * 1000) / ((uint32_t)fhss_structure->bs->synch_configuration.fhss_superframe_length * fhss_structure->bs->synch_configuration.fhss_number_of_superframes); // Calculate compensation value: how much to compensate on each channel. E.g. 6000us / 600channels = 10us/channel - fhss_structure->synch_monitor.drift_compensation += (fhss_structure->synch_monitor.avg_synch_fix / channels_per_synch_period); - fhss_stats_update(fhss_structure, STATS_FHSS_DRIFT_COMP, fhss_structure->synch_monitor.drift_compensation); - if ((fhss_structure->synch_monitor.avg_synch_fix > FHSS_SYNCH_DRIFT_TOO_HIGH_LIMIT) || (fhss_structure->synch_monitor.avg_synch_fix < -FHSS_SYNCH_DRIFT_TOO_HIGH_LIMIT)) { + fhss_structure->bs->synch_monitor.drift_compensation += (fhss_structure->bs->synch_monitor.avg_synch_fix / channels_per_synch_period); + fhss_stats_update(fhss_structure, STATS_FHSS_DRIFT_COMP, fhss_structure->bs->synch_monitor.drift_compensation); + if ((fhss_structure->bs->synch_monitor.avg_synch_fix > FHSS_SYNCH_DRIFT_TOO_HIGH_LIMIT) || (fhss_structure->bs->synch_monitor.avg_synch_fix < -FHSS_SYNCH_DRIFT_TOO_HIGH_LIMIT)) { // Indicates that more frequent synchronization is needed retval = -1; } @@ -560,7 +292,7 @@ static int fhss_update_drift_compensation(fhss_structure_t *fhss_structure) static int fhss_update_synch_monitor(fhss_structure_t *fhss_structure, const fhss_synchronization_beacon_payload_s *payload, uint8_t superframe_own, int32_t remaining_time_own, const int32_t time_to_next_superframe) { - fhss_synch_configuration_t *configuration = &fhss_structure->synch_configuration; + fhss_synch_configuration_t *configuration = &fhss_structure->bs->synch_configuration; int super_frame_changed = payload->current_superframe - superframe_own; int retval = 0; if (((super_frame_changed < 0) && ((super_frame_changed * -1) < (payload->number_of_superframes_per_channel / 2))) || (super_frame_changed > payload->number_of_superframes_per_channel / 2)) { @@ -591,22 +323,22 @@ static int fhss_update_synch_monitor(fhss_structure_t *fhss_structure, const fhs int32_t prev_synch_fix = (time_to_next_superframe - remaining_time_own); // After network scan counter was initialized to -1 to drop this fix from monitoring - if (fhss_structure->synch_monitor.avg_synch_fix_counter >= 0) { - fhss_structure->synch_monitor.avg_synch_fix += prev_synch_fix; + if (fhss_structure->bs->synch_monitor.avg_synch_fix_counter >= 0) { + fhss_structure->bs->synch_monitor.avg_synch_fix += prev_synch_fix; } - fhss_structure->synch_monitor.avg_synch_fix_counter++; - if (fhss_structure->synch_monitor.avg_synch_fix_counter == SYNCH_MONITOR_AVG_SAMPLES) { - fhss_structure->synch_monitor.avg_synch_fix /= SYNCH_MONITOR_AVG_SAMPLES; - fhss_stats_update(fhss_structure, STATS_FHSS_AVG_SYNCH_FIX, fhss_structure->synch_monitor.avg_synch_fix); + fhss_structure->bs->synch_monitor.avg_synch_fix_counter++; + if (fhss_structure->bs->synch_monitor.avg_synch_fix_counter == SYNCH_MONITOR_AVG_SAMPLES) { + fhss_structure->bs->synch_monitor.avg_synch_fix /= SYNCH_MONITOR_AVG_SAMPLES; + fhss_stats_update(fhss_structure, STATS_FHSS_AVG_SYNCH_FIX, fhss_structure->bs->synch_monitor.avg_synch_fix); retval = fhss_update_drift_compensation(fhss_structure); - fhss_structure->synch_monitor.avg_synch_fix_counter = 0; - fhss_structure->synch_monitor.avg_synch_fix = 0; + fhss_structure->bs->synch_monitor.avg_synch_fix_counter = 0; + fhss_structure->bs->synch_monitor.avg_synch_fix = 0; } } return retval; } -int fhss_sync_with_beacon(fhss_structure_t *fhss_structure, +static int fhss_sync_with_beacon(fhss_structure_t *fhss_structure, const fhss_synchronization_beacon_payload_s *payload) { int ret_val = -1; @@ -615,19 +347,19 @@ int fhss_sync_with_beacon(fhss_structure_t *fhss_structure, if (fhss_structure) { // Do not allow synchronising devices above 253 hops. - if (payload->hop_count > 253) { + if (payload->hop_count > (FHSS_MAX_ALLOWED_HOPS-1)) { return 0; } // To make synchronization monitoring more effective, drop extra Beacons. - if (fhss_structure->fhss_state == FHSS_SYNCHRONIZED && (fhss_is_current_channel_broadcast(fhss_structure) == false || (fhss_structure->beacon_received_on_this_bc_channel == true))) { + if (fhss_structure->fhss_state == FHSS_SYNCHRONIZED && (fhss_is_current_channel_broadcast(fhss_structure) == false || (fhss_structure->bs->beacon_received_on_this_bc_channel == true))) { return 0; } - fhss_synch_configuration_t *configuration = &fhss_structure->synch_configuration; - fhss_structure->beacon_received_on_this_bc_channel = true; + fhss_synch_configuration_t *configuration = &fhss_structure->bs->synch_configuration; + fhss_structure->bs->beacon_received_on_this_bc_channel = true; - superframe_own = fhss_structure->current_superframe; - fhss_structure->current_superframe = payload->current_superframe; + superframe_own = fhss_structure->bs->current_superframe; + fhss_structure->bs->current_superframe = payload->current_superframe; // Clone the static config values from parent which has the authority. configuration->fhss_number_of_bc_channels = payload->number_of_broadcast_channels; configuration->fhss_number_of_tx_slots = payload->number_of_tx_slots; @@ -641,36 +373,36 @@ int fhss_sync_with_beacon(fhss_structure_t *fhss_structure, fhss_structure->own_hop = payload->hop_count + 1; } fhss_stats_update(fhss_structure, STATS_FHSS_HOP_COUNT, fhss_structure->own_hop); - fhss_structure->channel_list_counter = payload->channel_list_counter; - fhss_structure->current_channel_index = payload->channel_index; + fhss_structure->bs->channel_list_counter = payload->channel_list_counter; + fhss_structure->bs->current_channel_index = payload->channel_index; uint8_t mac_address[8]; fhss_structure->callbacks.read_mac_address(fhss_structure->fhss_api, mac_address); - fhss_structure->uc_channel_index = fhss_calculate_uc_index(fhss_structure->current_channel_index, fhss_structure->number_of_channels, + fhss_structure->bs->uc_channel_index = fhss_calculate_uc_index(fhss_structure->bs->current_channel_index, fhss_structure->number_of_channels, payload->number_of_broadcast_channels) + fhss_get_offset(fhss_structure, mac_address); // If current channel is not broadcast, fhss_update_channel will increase UC channel index, otherwise do it here if (fhss_is_current_channel_broadcast(fhss_structure) == true || (fhss_structure->fhss_state == FHSS_SYNCHRONIZED)) { - fhss_structure->uc_channel_index += 1; + fhss_structure->bs->uc_channel_index += 1; } - if (fhss_structure->uc_channel_index >= (fhss_structure->number_of_channels - payload->number_of_broadcast_channels)) { - fhss_structure->uc_channel_index -= (fhss_structure->number_of_channels - payload->number_of_broadcast_channels); + if (fhss_structure->bs->uc_channel_index >= (fhss_structure->number_of_channels - payload->number_of_broadcast_channels)) { + fhss_structure->bs->uc_channel_index -= (fhss_structure->number_of_channels - payload->number_of_broadcast_channels); } - fhss_structure->platform_functions.fhss_timer_stop(fhss_structure->fhss_api); + fhss_structure->platform_functions.fhss_timer_stop(fhss_superframe_handler, fhss_structure->fhss_api); // start timer to elapse at approximately same time as the parent will. const int32_t time_to_next_superframe = payload->remaining_slots; remaining_time_own = fhss_get_remaining_time_to_next_superframe(fhss_structure); fhss_start_timer(fhss_structure, time_to_next_superframe, fhss_superframe_handler); // Reset beacon received timer when FHSS synchronization is updated - fhss_structure->beacons_received_timer = 0; - uint16_t bc_density = (fhss_structure->number_of_channels / fhss_structure->synch_configuration.fhss_number_of_bc_channels); - uint8_t fhss_number_of_bc_channels = fhss_structure->synch_configuration.fhss_number_of_bc_channels; - uint16_t channel_dwell_time = ((uint32_t)fhss_structure->synch_configuration.fhss_superframe_length * fhss_structure->synch_configuration.fhss_number_of_superframes) / 1000; + fhss_structure->bs->beacons_received_timer = 0; + uint16_t bc_density = (fhss_structure->number_of_channels / fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels); + uint8_t fhss_number_of_bc_channels = fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels; + uint16_t channel_dwell_time = ((uint32_t)fhss_structure->bs->synch_configuration.fhss_superframe_length * fhss_structure->bs->synch_configuration.fhss_number_of_superframes) / 1000; if (fhss_structure->fhss_state == FHSS_UNSYNCHRONIZED) { fhss_structure->fhss_state = FHSS_SYNCHRONIZED; - fhss_update_channel(fhss_structure); + fhss_change_to_next_channel(fhss_structure); } if (fhss_is_synch_root(fhss_structure) == false) { // Initially synch drift might be massive. Request first few Beacons more frequently until compensation starts fixing the error. @@ -678,31 +410,25 @@ int fhss_sync_with_beacon(fhss_structure_t *fhss_structure, if (fhss_structure->fhss_state == FHSS_SYNCHRONIZED) { if (fhss_update_synch_monitor(fhss_structure, payload, superframe_own, remaining_time_own, time_to_next_superframe)) { - fhss_structure->synch_interval = (uint32_t) (fhss_structure->fhss_configuration.fhss_max_synch_interval/BEACON_INTERVAL_INIT_DIVIDER) * 1000; + fhss_structure->bs->synch_interval = (uint32_t) (fhss_structure->bs->fhss_configuration.fhss_max_synch_interval/BEACON_INTERVAL_INIT_DIVIDER) * 1000; } } - if (fhss_structure->synch_interval != ((uint32_t)fhss_structure->fhss_configuration.fhss_max_synch_interval * 1000)) { - fhss_structure->synch_interval *= 2; - if (fhss_structure->synch_interval > ((uint32_t)fhss_structure->fhss_configuration.fhss_max_synch_interval * 1000)) { - fhss_structure->synch_interval = ((uint32_t)fhss_structure->fhss_configuration.fhss_max_synch_interval * 1000); + if (fhss_structure->bs->synch_interval != ((uint32_t)fhss_structure->bs->fhss_configuration.fhss_max_synch_interval * 1000)) { + fhss_structure->bs->synch_interval *= 2; + if (fhss_structure->bs->synch_interval > ((uint32_t)fhss_structure->bs->fhss_configuration.fhss_max_synch_interval * 1000)) { + fhss_structure->bs->synch_interval = ((uint32_t)fhss_structure->bs->fhss_configuration.fhss_max_synch_interval * 1000); } beacon_interval_random = (bc_density * channel_dwell_time) * randLIB_get_random_in_range(0, fhss_number_of_bc_channels/2); } else { beacon_interval_random = (bc_density * channel_dwell_time) * randLIB_get_random_in_range(0, fhss_number_of_bc_channels); } - fhss_stats_update(fhss_structure, STATS_FHSS_SYNCH_INTERVAL, fhss_structure->synch_interval / 1000); - fhss_beacon_periodic_start(fhss_structure, fhss_structure->synch_interval + beacon_interval_random); - -#ifdef FHSS_MASSIVE_TRACE - tr_debug("start timer, time now: %"PRIu32", sfr: %"PRIu8", ch-ind: %"PRIu8", time after: %"PRIu32, - fhss_structure->fhss_api->read_timestamp(fhss_structure->fhss_api), fhss_structure->current_superframe, - payload->channel_index, time_to_next_superframe); -#endif + fhss_stats_update(fhss_structure, STATS_FHSS_SYNCH_INTERVAL, fhss_structure->bs->synch_interval / 1000); + fhss_beacon_periodic_start(fhss_structure, fhss_structure->bs->synch_interval + beacon_interval_random); } // Our hop has changed, needs to inform possible children by sending Beacon if ((own_hop_tmp != 0) && (own_hop_tmp != fhss_structure->own_hop)) { - fhss_structure->send_synch_info_on_next_broadcast_channel = true; + fhss_structure->bs->send_synch_info_on_next_broadcast_channel = true; } ret_val = 0; } @@ -725,12 +451,12 @@ static uint32_t fhss_get_remaining_tx_time(fhss_structure_t *fhss_structure) uint32_t remaining_tx_time = 0; if (fhss_structure) { - uint8_t cur_superframe = fhss_structure->current_superframe; - uint8_t number_of_tx_slots = fhss_structure->synch_configuration.fhss_number_of_tx_slots; - uint8_t number_of_superframes = fhss_structure->synch_configuration.fhss_number_of_superframes; + uint8_t cur_superframe = fhss_structure->bs->current_superframe; + uint8_t number_of_tx_slots = fhss_structure->bs->synch_configuration.fhss_number_of_tx_slots; + uint8_t number_of_superframes = fhss_structure->bs->synch_configuration.fhss_number_of_superframes; uint8_t tx_slot_length = ((number_of_superframes / 2) / number_of_tx_slots); uint8_t tx_slot_up_limit = tx_slot_length; - uint16_t superframe_length = fhss_structure->synch_configuration.fhss_superframe_length; + uint16_t superframe_length = fhss_structure->bs->synch_configuration.fhss_superframe_length; if ((fhss_structure->own_hop % 2)) { tx_slot_up_limit += tx_slot_length; @@ -748,11 +474,6 @@ static uint32_t fhss_get_remaining_tx_time(fhss_structure_t *fhss_structure) return remaining_tx_time; } -uint32_t fhss_get_tx_time(fhss_structure_t *fhss_structure, uint16_t bytes_to_send, uint8_t phy_header_length, uint8_t phy_tail_length) -{ - return ((1000000 / (fhss_structure->datarate / 8)) * (bytes_to_send + phy_header_length + phy_tail_length)); -} - // CCA adds extra 2ms with FHSS #define CCA_FHSS_PERIOD 2000 // Ack frame length @@ -774,8 +495,8 @@ static bool fhss_check_remaining_tx_time(fhss_structure_t *fhss_structure, uint1 if (fhss_structure->fhss_state == FHSS_UNSYNCHRONIZED) { retval = true; } else { - tx_processing_delay = fhss_structure->fhss_configuration.fhss_tuning_parameters.tx_processing_delay; - ack_processing_delay = fhss_structure->fhss_configuration.fhss_tuning_parameters.ack_processing_delay; + tx_processing_delay = fhss_structure->bs->fhss_configuration.fhss_tuning_parameters.tx_processing_delay; + ack_processing_delay = fhss_structure->bs->fhss_configuration.fhss_tuning_parameters.ack_processing_delay; // Calculate needed TX time (us): CCA static period + TX processing delays + transmission time + Ack processing delays + Ack transmission time needed_tx_time = CCA_FHSS_PERIOD + tx_processing_delay + fhss_get_tx_time(fhss_structure, tx_length, phy_header_length, phy_tail_length) + ack_processing_delay + fhss_get_tx_time(fhss_structure, ACK_LENGTH, phy_header_length, phy_tail_length); @@ -787,81 +508,6 @@ static bool fhss_check_remaining_tx_time(fhss_structure_t *fhss_structure, uint1 return retval; } -int fhss_update_synch_parent_address(fhss_structure_t *fhss_structure) -{ - uint8_t parent_address[8]; - - if (!fhss_get_parent_address(fhss_structure, parent_address)) { - memcpy(fhss_structure->synch_parent, parent_address, 8); - return 0; - } - return -1; -} - -void fhss_trig_event(fhss_structure_t *fhss_structure, uint8_t event_type) -{ - if (fhss_read_active_event(fhss_structure, event_type) == true) { - return; - } - arm_event_s event; - event.receiver = fhss_structure->beacon_tasklet_id; - event.sender = 0; - event.event_type = event_type; - event.event_id = 0; - event.data_ptr = fhss_structure; - event.priority = ARM_LIB_HIGH_PRIORITY_EVENT; - event.event_data = 0; - if (eventOS_event_send(&event) != 0) { - tr_error("Event trigger failed: eventOS_event_send() failed"); - } else { - fhss_set_active_event(fhss_structure, event_type); - } -} - -int fhss_get_parent_address(fhss_structure_t *fhss_structure, uint8_t *p_addr) -{ - int ret_val = -1; - if (!fhss_structure || !p_addr) { - return -1; - } - - ret_val = fhss_structure->callbacks.read_coord_mac_address(fhss_structure->fhss_api, p_addr); - - if (ret_val) { - // Use default synchronization parent when RPL parent not found - memcpy(p_addr, fhss_structure->synch_parent, 8); - ret_val = 0; - } - return ret_val; -} - -int fhss_compare_with_synch_parent_address(fhss_structure_t *fhss_structure, const uint8_t *source_addr) -{ - int ret_val = -1; - if (!fhss_structure || !source_addr) { - return ret_val; - } - uint8_t parent_address[8]; - - if (fhss_is_synch_root(fhss_structure) == false) { - if (!fhss_get_parent_address(fhss_structure, parent_address)) { - ret_val = memcmp(source_addr, parent_address, 8); - } - } - return ret_val; -} - -static void fhss_update_channel(fhss_structure_t *fhss_structure) -{ - // If channel is broadcast channel (true), send event - if (fhss_change_to_next_channel(fhss_structure) == true) { - // Only if device is border router - if (fhss_structure->own_hop == 0) { - fhss_trig_event(fhss_structure, FHSS_BROADCAST_CHANNEL); - } - } -} - static bool fhss_is_there_common_divisor(uint16_t i, uint8_t j) { if (i < j) { @@ -884,7 +530,7 @@ static int fhss_generate_scramble_table(fhss_structure_t *fhss_structure) { // Common divisors are skipped if (fhss_is_there_common_divisor(fhss_structure->number_of_channels, j) == false) { - fhss_structure->fhss_scramble_table[i] = j; + fhss_structure->bs->fhss_scramble_table[i] = j; i++; } j++; @@ -892,19 +538,10 @@ static int fhss_generate_scramble_table(fhss_structure_t *fhss_structure) return 0; } -static void fhss_event_timer_cb(int8_t timer_id, uint16_t slots) -{ - (void) slots; - fhss_structure_t *fhss_structure = fhss_get_object_with_timer_id(timer_id); - if (fhss_structure) { - fhss_structure->callbacks.tx_poll(fhss_structure->fhss_api); - } -} - -fhss_beacon_info_t *fhss_get_beacon_info(fhss_structure_t *fhss_structure, uint16_t pan_id) +static fhss_beacon_info_t *fhss_get_beacon_info(fhss_structure_t *fhss_structure, uint16_t pan_id) { fhss_beacon_info_t *beacon_info; - beacon_info = fhss_structure->fhss_beacon_info_store; + beacon_info = fhss_structure->bs->fhss_beacon_info_store; while (beacon_info) { if (beacon_info->pan_id == pan_id) { break; @@ -918,11 +555,11 @@ static void fhss_store_beacon_info(fhss_structure_t *fhss_structure, fhss_beacon { fhss_beacon_info_t *beacon_info_cur; beacon_info->next = NULL; - if (!fhss_structure->fhss_beacon_info_store) { - fhss_structure->fhss_beacon_info_store = beacon_info; + if (!fhss_structure->bs->fhss_beacon_info_store) { + fhss_structure->bs->fhss_beacon_info_store = beacon_info; return; } - beacon_info_cur = fhss_structure->fhss_beacon_info_store; + beacon_info_cur = fhss_structure->bs->fhss_beacon_info_store; while (beacon_info_cur->next != NULL) { beacon_info_cur = beacon_info_cur->next; } @@ -949,19 +586,19 @@ static fhss_beacon_info_t *fhss_create_beacon_info(fhss_structure_t *fhss_struct static int fhss_remove_beacon_info(fhss_structure_t *fhss_structure, uint16_t pan_id) { - if (!fhss_structure || !fhss_structure->fhss_beacon_info_store) { + if (!fhss_structure || !fhss_structure->bs->fhss_beacon_info_store) { return -1; } - if (fhss_structure->fhss_beacon_info_store->pan_id == pan_id) { - fhss_beacon_info_t *next = fhss_structure->fhss_beacon_info_store->next; - ns_dyn_mem_free(fhss_structure->fhss_beacon_info_store); - fhss_structure->fhss_beacon_info_store = next; + if (fhss_structure->bs->fhss_beacon_info_store->pan_id == pan_id) { + fhss_beacon_info_t *next = fhss_structure->bs->fhss_beacon_info_store->next; + ns_dyn_mem_free(fhss_structure->bs->fhss_beacon_info_store); + fhss_structure->bs->fhss_beacon_info_store = next; return 0; } - fhss_beacon_info_t *removed_beacon_info = fhss_structure->fhss_beacon_info_store->next; - fhss_beacon_info_t *prev_beacon_info = fhss_structure->fhss_beacon_info_store; + fhss_beacon_info_t *removed_beacon_info = fhss_structure->bs->fhss_beacon_info_store->next; + fhss_beacon_info_t *prev_beacon_info = fhss_structure->bs->fhss_beacon_info_store; while (removed_beacon_info) { if (removed_beacon_info->pan_id == pan_id) { @@ -976,22 +613,50 @@ static int fhss_remove_beacon_info(fhss_structure_t *fhss_structure, uint16_t pa return -1; } -int fhss_flush_beacon_info_storage(fhss_structure_t *fhss_structure) +static int fhss_flush_beacon_info_storage(fhss_structure_t *fhss_structure) { if (!fhss_structure) { return -1; } - fhss_beacon_info_t *beacon_info = fhss_structure->fhss_beacon_info_store; + fhss_beacon_info_t *beacon_info = fhss_structure->bs->fhss_beacon_info_store; while (beacon_info) { fhss_beacon_info_t *next = beacon_info->next; ns_dyn_mem_free(beacon_info); beacon_info = next; } - fhss_structure->fhss_beacon_info_store = NULL; + fhss_structure->bs->fhss_beacon_info_store = NULL; return 0; } -int fhss_add_beacon_info(fhss_structure_t *fhss_structure, uint16_t pan_id, uint8_t *source_address, uint32_t timestamp, uint8_t *synch_info) +static int fhss_reset(fhss_structure_t *fhss_structure) +{ + if (!fhss_structure) { + return -1; + } + fhss_structure->platform_functions.fhss_timer_stop(fhss_superframe_handler, fhss_structure->fhss_api); + fhss_structure->bs->synch_panid = 0xffff; + fhss_beacon_periodic_stop(fhss_structure); + fhss_structure->bs->current_superframe = 0; + fhss_structure->bs->current_channel_index = 0; + fhss_structure->bs->channel_list_counter = 0; + if (fhss_is_synch_root(fhss_structure) == false) { + fhss_structure->own_hop = 0xff; + } + fhss_structure->bs->tx_allowed = false; + fhss_structure->bs->synch_interval = (uint32_t) (fhss_structure->bs->fhss_configuration.fhss_max_synch_interval/BEACON_INTERVAL_INIT_DIVIDER) * 1000; + fhss_structure->rx_channel = 0; + fhss_structure->bs->beacons_received_timer = 0; + memset(fhss_structure->synch_parent, 0xff, 8); + fhss_structure->bs->send_synch_info_on_next_broadcast_channel = false; + memset(&fhss_structure->bs->synch_configuration, 0, sizeof(fhss_synch_configuration_t)); + fhss_structure->bs->synch_infos_sent_counter = 0; + fhss_structure->bs->broadcast_start_superframe = 0; + fhss_failed_list_free(fhss_structure); + fhss_structure->fhss_state = FHSS_UNSYNCHRONIZED; + return 0; +} + +static int fhss_add_beacon_info(fhss_structure_t *fhss_structure, uint16_t pan_id, uint8_t *source_address, uint32_t timestamp, uint8_t *synch_info) { if (!fhss_structure || !source_address || !synch_info) { return -1; @@ -1008,10 +673,10 @@ int fhss_add_beacon_info(fhss_structure_t *fhss_structure, uint16_t pan_id, uint return 0; } -void fhss_update_beacon_info_lifetimes(fhss_structure_t *fhss_structure, uint32_t timestamp) +static void fhss_update_beacon_info_lifetimes(fhss_structure_t *fhss_structure, uint32_t timestamp) { fhss_beacon_info_t *beacon_info; - beacon_info = fhss_structure->fhss_beacon_info_store; + beacon_info = fhss_structure->bs->fhss_beacon_info_store; while (beacon_info) { uint32_t time_since_added = timestamp - beacon_info->timestamp; // timestamp is microseconds, lifetime is seconds @@ -1024,43 +689,733 @@ void fhss_update_beacon_info_lifetimes(fhss_structure_t *fhss_structure, uint32_ } } -fhss_failed_tx_t *fhss_failed_handle_find(fhss_structure_t *fhss_structure, uint8_t handle) +static void fhss_synch_state_set_callback(const fhss_api_t *api, fhss_states fhss_state, uint16_t pan_id) { - ns_list_foreach(fhss_failed_tx_t, cur, &fhss_structure->fhss_failed_tx_list) { - if (cur->handle == handle) { - return cur; + fhss_structure_t *fhss_structure = fhss_get_object_with_api(api); + if (!fhss_structure) { + return; + } + // State is already set + if (fhss_structure->fhss_state == fhss_state) { + tr_debug("Synch same state %u", fhss_state); + return; + } + + if (fhss_state == FHSS_UNSYNCHRONIZED) { + tr_debug("FHSS down"); + fhss_reset(fhss_structure); + fhss_reset_synch_monitor(&fhss_structure->bs->synch_monitor); + fhss_stats_update(fhss_structure, STATS_FHSS_DRIFT_COMP, fhss_structure->bs->synch_monitor.drift_compensation); + fhss_stats_update(fhss_structure, STATS_FHSS_AVG_SYNCH_FIX, fhss_structure->bs->synch_monitor.avg_synch_fix); + fhss_stats_update(fhss_structure, STATS_FHSS_SYNCH_INTERVAL, fhss_structure->bs->synch_interval / 1000); + } else { + // Do not synchronize to current pan + if (fhss_structure->bs->synch_panid == pan_id) { + tr_debug("Synch same panid %u", pan_id); + return; + } + fhss_generate_scramble_table(fhss_structure); + + uint8_t mac_address[8]; + fhss_structure->callbacks.read_mac_address(fhss_structure->fhss_api, mac_address); + fhss_structure->bs->uc_channel_index = fhss_get_offset(fhss_structure, mac_address); + // Get Beacon info from storage + fhss_beacon_info_t *beacon_info = fhss_get_beacon_info(fhss_structure, pan_id); + if (beacon_info) { + memcpy(fhss_structure->synch_parent, beacon_info->source_address, 8); + platform_enter_critical(); + // Calculate time since the Beacon was received + uint32_t elapsed_time = fhss_structure->fhss_api->read_timestamp(fhss_structure->fhss_api) - beacon_info->timestamp; + // Synchronize to given PAN + fhss_beacon_received(fhss_structure, beacon_info->synch_info, elapsed_time); + platform_exit_critical(); + // Delete stored Beacon infos + fhss_flush_beacon_info_storage(fhss_structure); + fhss_structure->bs->synch_panid = pan_id; + } else if (fhss_is_synch_root(fhss_structure) == true) { + // Synch root will start new network + fhss_start_timer(fhss_structure, fhss_structure->bs->synch_configuration.fhss_superframe_length, fhss_superframe_handler); + } else { + tr_error("Synch info not found"); + return; } } - return NULL; + fhss_structure->fhss_state = fhss_state; + return; } -int fhss_failed_handle_add(fhss_structure_t *fhss_structure, uint8_t handle) +static void fhss_beacon_decode_raw(fhss_synchronization_beacon_payload_s* dest, const uint8_t* buffer) { - fhss_failed_tx_t *failed_tx = ns_dyn_mem_alloc(sizeof(fhss_failed_tx_t)); - if (!failed_tx) { - return -2; - } - failed_tx->bad_channel = fhss_structure->rx_channel; - failed_tx->retries_done = 0; - failed_tx->handle = handle; - ns_list_add_to_end(&fhss_structure->fhss_failed_tx_list, failed_tx); - return 0; + dest->data_start_delimeter = *buffer++; + dest->channel_index = *buffer++; + dest->sender_unicast_channel = *buffer++; + dest->current_superframe = common_read_16_bit(buffer); + buffer += BEACON_FIELD_SIZE(current_superframe); + dest->remaining_slots = common_read_16_bit(buffer); + buffer += BEACON_FIELD_SIZE(remaining_slots); + dest->channel_list_counter = common_read_16_bit(buffer); + buffer += BEACON_FIELD_SIZE(channel_list_counter); + dest->hop_count = *buffer++; + dest->number_of_broadcast_channels = *buffer++; + dest->number_of_tx_slots = *buffer++; + dest->time_since_last_beacon = common_read_32_bit(buffer); + buffer += BEACON_FIELD_SIZE(time_since_last_beacon); + dest->processing_delay += common_read_16_bit(buffer); + buffer += BEACON_FIELD_SIZE(processing_delay); + dest->superframe_length = common_read_16_bit(buffer); + buffer += BEACON_FIELD_SIZE(superframe_length); + dest->number_of_superframes_per_channel = *buffer; } -int fhss_failed_handle_remove(fhss_structure_t *fhss_structure, uint8_t handle) +static uint32_t fhss_get_time_to_next_channel_change(uint16_t remaining_slots_to_next_superframe, uint8_t number_of_superframes, uint8_t current_superframe, uint16_t superframe_length) { - fhss_failed_tx_t *failed_tx = fhss_failed_handle_find(fhss_structure, handle); - if (!failed_tx) { - return -1; - } - ns_list_remove(&fhss_structure->fhss_failed_tx_list, failed_tx); - ns_dyn_mem_free(failed_tx); // Free entry - return 0; + return remaining_slots_to_next_superframe + ((uint32_t)((number_of_superframes - 1) - current_superframe) * superframe_length); } -static void fhss_failed_list_free(fhss_structure_t *fhss_structure) +// Decode the given raw byte buffer into a struct into dest struct and calculate +// the new values for elapsed_time, channel_index, current_superframe and remaining_slots +// from current state and given data. +static void fhss_beacon_decode(fhss_synchronization_beacon_payload_s* dest, const uint8_t* buffer, uint32_t elapsed_time, uint16_t number_of_channels) { - for (uint16_t i = 0; i<256; i++) { - fhss_failed_handle_remove(fhss_structure, i); + fhss_beacon_decode_raw(dest, buffer); + + elapsed_time += dest->processing_delay; + + /* To calculate channel index after beacon scan, following calculation is performed + * + * rem. slots to channel change(X) Channel length (V) + * |---------------------| |-----------------------------------------------| + * | RX'd channel index (Y) | ... | Y+n | + * ...| sf1 | sf2 | sf3 | sf4 | ... | sf1 | sf2 | sf3 | sf4 |... + * ^ ^ + * |beacon received |beacon scan done + * |-------------------------------------| + * measured time after beacon RX'd(Z) + * V = superframe length * number of superframes + * X = remaining slots to superframe change + length of the remaining full superframes to channel change + * + * Y+n = Y + ((Z - X) / V) + 1 + * + * Or if (Z < X) + * Y+n = Y + */ + + uint32_t remaining_slots_to_next_channel = fhss_get_time_to_next_channel_change(dest->remaining_slots, dest->number_of_superframes_per_channel, dest->current_superframe, dest->superframe_length); + uint16_t temp_channel_index = dest->channel_index; + if (elapsed_time >= remaining_slots_to_next_channel) { + uint32_t channel_length = (uint32_t) dest->number_of_superframes_per_channel * dest->superframe_length; + temp_channel_index = dest->channel_index + ((elapsed_time - remaining_slots_to_next_channel) / channel_length) + 1; + } + while (temp_channel_index >= number_of_channels) { + temp_channel_index -= number_of_channels; + dest->channel_list_counter++; + } + dest->channel_index = temp_channel_index; + while (dest->channel_list_counter >= (number_of_channels * MAX_SCRAMBLE_TABLE_INDEXES)) { + dest->channel_list_counter -= (number_of_channels * MAX_SCRAMBLE_TABLE_INDEXES); + } + + /* To calculate superframe after beacon scan, following calculation is performed + * + * rem. slots(X) sf. length(V) + * |---------------| |-----------------| + *...| RX'd superframe (Y)| ... | Y+n | Y+n+1 |.... + * ^ ^ + * |beacon received |beacon scan done + * |-------------------------------------| + * measured time after beacon RX'd(Z) + * + * Y+n = Y + ((Z - X) / V) + 1 + * + * Or if (Z < X) + * Y+n = Y + */ + + if (elapsed_time >= dest->remaining_slots) { + dest->current_superframe = dest->current_superframe + ((elapsed_time - dest->remaining_slots) / dest->superframe_length) + 1; + } + while (dest->current_superframe >= dest->number_of_superframes_per_channel) { + dest->current_superframe -= dest->number_of_superframes_per_channel; + } + + /* To get the remaining slots after beacon scan, following calculation is performed + * + * rem. slots(Y) sf. length(V) new rem. slots(X) + * |----------| |---------------| |-------------| + *...| superframe 1 | superframe 2 | superframe 3 | superframe 4 |... + * ^ ^ + * |beacon received |beacon scan done + * |--------------------------------------------| + * measured time after beacon RX'd(Z) + * + * X = V - ((Z - Y) % V) + * + * Or if (Z < Y) + * X = Y - Z + */ + + if (elapsed_time < dest->remaining_slots) { + dest->remaining_slots = dest->remaining_slots - elapsed_time; + } else { + dest->remaining_slots = dest->superframe_length - ((elapsed_time - dest->remaining_slots) % dest->superframe_length); + } +} + +static int fhss_synch_info_validate(fhss_synchronization_beacon_payload_s *payload) +{ + if (!payload) { + return -1; + } + if (payload->data_start_delimeter != 0) { + return -1; + } + if (payload->current_superframe >= payload->number_of_superframes_per_channel) { + return -1; + } + if (payload->remaining_slots >= payload->superframe_length) { + return -1; + } + if (payload->hop_count > FHSS_MAX_ALLOWED_HOPS-1) { + return -1; + } + if (payload->number_of_broadcast_channels == 0) { + return -1; + } + if (payload->number_of_tx_slots == 0) { + return -1; + } + if (payload->number_of_superframes_per_channel == 0) { + return -1; + } + return 0; +} + +static void fhss_beacon_received(fhss_structure_t *fhss_structure, const uint8_t *synch_info, const uint32_t elapsed_time) +{ + + if (fhss_structure) { + + if (synch_info) { + fhss_synchronization_beacon_payload_s temp_payload; + temp_payload.processing_delay = fhss_structure->bs->fhss_configuration.fhss_tuning_parameters.rx_processing_delay; + fhss_beacon_decode(&temp_payload, synch_info, elapsed_time, fhss_structure->number_of_channels); + if (!fhss_synch_info_validate(&temp_payload)) { + fhss_sync_with_beacon(fhss_structure, &temp_payload); + } else { + tr_err("Invalid synch info received"); + } + } + } +} + +static uint32_t fhss_get_sf_timeout_callback(fhss_structure_t *fhss_structure) +{ + uint32_t compensation = 0; + /* Drift compensation doesn't work with Linux platform */ +#ifndef __linux__ + // Drift compensation on first superframe + if (fhss_structure->bs->current_superframe == 0) { + /* Idea is to compensate number of drift_compensation (microseconds) on each channel. + * However, fhss_resolution_divider defines the minimum timer resolution. + * E.g. if fhss_resolution_divider = 64, compensate (drift_compensation * 64) on each 64th channel. + */ + if (++fhss_structure->bs->synch_monitor.channel_counter == fhss_structure->platform_functions.fhss_resolution_divider) { + compensation = fhss_structure->bs->synch_monitor.drift_compensation; + fhss_structure->bs->synch_monitor.channel_counter = 0; + } + } +#else + (void) fhss_structure; +#endif //__linux__ + return (fhss_structure->bs->synch_configuration.fhss_superframe_length) + (compensation * fhss_structure->platform_functions.fhss_resolution_divider); +} + +static void fhss_superframe_callback(fhss_structure_t *fhss_structure) +{ + if ((fhss_structure->bs->send_synch_info_on_next_broadcast_channel == true) && (fhss_is_current_channel_broadcast(fhss_structure) == true)) { + /* Randomize sending superframe of synchronization frame: + * on first superframe probability is 1/number of superframes + * on second superframe probability is 1/(number of superframes-1) + * on third superframe probability is 1/(number of superframes-2) + * on last superframe probability is 1/1 + */ + if (randLIB_get_random_in_range(1, fhss_structure->bs->synch_configuration.fhss_number_of_superframes - fhss_structure->bs->current_superframe) == 1) { + fhss_structure->bs->send_synch_info_on_next_broadcast_channel = false; + fhss_structure->bs->synch_infos_sent_counter++; + fhss_structure->callbacks.send_fhss_frame(fhss_structure->fhss_api, FHSS_SYNCH_FRAME); + } + } + fhss_update_txrx_slots(fhss_structure); + uint16_t queue_size = fhss_structure->callbacks.read_tx_queue_size(fhss_structure->fhss_api, false) + fhss_structure->callbacks.read_tx_queue_size(fhss_structure->fhss_api, true); + if ((fhss_structure->bs->tx_allowed == true || fhss_is_current_channel_broadcast(fhss_structure) == true) && queue_size) { + /* Start timer with random timeout to trigger TX queue poll event. + * Max random is half of the superframe length. Event timer resolution is 50us. + * Divide Max random with TX queue size to transmit faster when TX queue is growing + */ + uint16_t max_random = ((fhss_structure->bs->synch_configuration.fhss_superframe_length / 2) / 50) / queue_size; + eventOS_callback_timer_start(fhss_structure->fhss_event_timer, randLIB_get_random_in_range(1, max_random)); + } +} + +static int fhss_tx_handle_callback(const fhss_api_t *api, bool is_broadcast_addr, uint8_t *destination_address, int frame_type, uint16_t frame_length, uint8_t phy_header_length, uint8_t phy_tail_length, uint32_t tx_time) +{ + (void) tx_time; + fhss_structure_t *fhss_structure = fhss_get_object_with_api(api); + if (!fhss_structure) { + return -2; + } + // TODO: needs some more logic to push buffer back to queue + if (frame_type == FHSS_DATA_FRAME) { + if (is_broadcast_addr == true) { + if (fhss_is_current_channel_broadcast(fhss_structure) == false) { + tr_info("Broadcast on UC channel -> Back to queue"); + return -3; + } + } + } + if (fhss_check_tx_allowed(fhss_structure, is_broadcast_addr, frame_length, frame_type, phy_header_length, phy_tail_length) == false) { + return -1; + } + // If sending Beacon request on parents Unicast channel + if (frame_type == FHSS_SYNCH_REQUEST_FRAME && fhss_structure->fhss_state == FHSS_SYNCHRONIZED) { + fhss_change_to_parent_channel(fhss_structure); + } else if (frame_type == FHSS_DATA_FRAME) { + fhss_change_to_tx_channel(fhss_structure, destination_address); + } + return 0; +} + +static bool fhss_check_tx_conditions_callback(const fhss_api_t *api, bool is_broadcast_addr, uint8_t handle, int frame_type, uint16_t frame_length, uint8_t phy_header_length, uint8_t phy_tail_length) +{ + fhss_structure_t *fhss_structure = fhss_get_object_with_api(api); + if (!fhss_structure) { + return true; + } + // This condition will check that message is not sent on bad channel + if (fhss_check_bad_channel(fhss_structure, handle) == false) { + return false; + } + + // This condition will check that broadcast messages are sent only broadcast channels + if (fhss_check_channel_type(fhss_structure, is_broadcast_addr, frame_type) == false) { + return false; + } + + // This condition will check that FHSS is on TX slot and there is enough time to transmit before channel or slot change + if (fhss_check_tx_allowed(fhss_structure, is_broadcast_addr, frame_length, frame_type, phy_header_length, phy_tail_length) == false) { + return false; + } + + return true; +} + +static void fhss_update_channel_callback(fhss_structure_t *fhss_structure) +{ + if (fhss_structure->bs->current_channel_index == 0) { + fhss_structure->bs->synch_infos_sent_counter = 0; + if (++fhss_structure->bs->channel_list_counter >= ((uint16_t) fhss_structure->number_of_channels * MAX_SCRAMBLE_TABLE_INDEXES)) { + fhss_structure->bs->channel_list_counter = 0; + } + if (fhss_is_synch_root(fhss_structure) == false) { + fhss_trig_event(fhss_structure, FHSS_COMPARE_SYNCH_PARENT); + } + fhss_trig_event(fhss_structure, FHSS_UPDATE_SYNCH_INFO_STORAGE); + } + // If channel is broadcast channel (true), send event + if (fhss_change_to_next_channel(fhss_structure) == true) { + // Only if device is border router + if (fhss_structure->own_hop == 0) { + fhss_trig_event(fhss_structure, FHSS_BROADCAST_CHANNEL); + } + } +} + +static uint8_t* fhss_beacon_encode_raw(uint8_t* buffer, const fhss_synchronization_beacon_payload_s* source) +{ + *buffer++ = FHSS_DATA_START_DELIMETER; + *buffer++ = source->channel_index; + *buffer++ = source->sender_unicast_channel; + buffer = common_write_16_bit(source->current_superframe, buffer); + buffer = common_write_16_bit(source->remaining_slots, buffer); + buffer = common_write_16_bit(source->channel_list_counter, buffer); + *buffer++ = source->hop_count; + *buffer++ = source->number_of_broadcast_channels; + *buffer++ = source->number_of_tx_slots; + buffer = common_write_32_bit(source->time_since_last_beacon, buffer); + buffer = common_write_16_bit(source->processing_delay, buffer); + buffer = common_write_16_bit(source->superframe_length, buffer); + *buffer++ = source->number_of_superframes_per_channel; + + return buffer; +} + +static void fhss_beacon_build(fhss_structure_t *fhss_structure, uint8_t* dest) +{ + fhss_synchronization_beacon_payload_s temp_payload; + platform_enter_critical(); + const fhss_synch_configuration_t *config = &fhss_structure->bs->synch_configuration; + temp_payload.channel_index = fhss_structure->bs->current_channel_index; + temp_payload.sender_unicast_channel = 0; + temp_payload.current_superframe = fhss_structure->bs->current_superframe; + // This assumes that the time is always in the range of 0..2**16, which + // should be the case as the superframe length field is also in that range. + temp_payload.remaining_slots = (uint16_t) fhss_get_remaining_time_to_next_superframe(fhss_structure); + temp_payload.channel_list_counter = fhss_structure->bs->channel_list_counter; + temp_payload.hop_count = fhss_structure->own_hop; + temp_payload.number_of_broadcast_channels = config->fhss_number_of_bc_channels; + temp_payload.number_of_tx_slots = config->fhss_number_of_tx_slots; + temp_payload.time_since_last_beacon = 0; // XXX not available yet + uint32_t tx_time = fhss_get_tx_time(fhss_structure, 71, 0, 0); + temp_payload.processing_delay = fhss_structure->bs->fhss_configuration.fhss_tuning_parameters.tx_processing_delay + tx_time; + temp_payload.superframe_length = config->fhss_superframe_length; + temp_payload.number_of_superframes_per_channel = config->fhss_number_of_superframes; + platform_exit_critical(); + fhss_beacon_encode_raw(dest, &temp_payload); +} + +static int16_t fhss_write_synch_info_callback(const fhss_api_t *api, uint8_t *ptr, uint8_t length, int frame_type, uint32_t tx_time) +{ + (void) length; + (void) tx_time; + fhss_structure_t *fhss_structure = fhss_get_object_with_api(api); + if (!fhss_structure || !ptr || (frame_type != FHSS_SYNCH_FRAME)) { + return -1; + } + fhss_beacon_build(fhss_structure, ptr); + return FHSS_SYNCH_INFO_LENGTH; +} + +static void fhss_data_tx_done_callback(const fhss_api_t *api, bool waiting_ack, bool tx_completed, uint8_t handle) +{ + fhss_structure_t *fhss_structure = fhss_get_object_with_api(api); + if (!fhss_structure) { + return; + } + if (waiting_ack == false) { + fhss_change_to_rx_channel(fhss_structure); + } + // Buffer was successfully transmitted. Remove stored failure handle if exists. + if (tx_completed == true) { + fhss_failed_tx_t *fhss_failed_tx = fhss_failed_handle_find(fhss_structure, handle); + if (fhss_failed_tx) { + fhss_failed_handle_remove(fhss_structure, handle); + } + } +} + +static bool fhss_data_tx_fail_callback(const fhss_api_t *api, uint8_t handle, int frame_type) +{ + fhss_structure_t *fhss_structure = fhss_get_object_with_api(api); + if (!fhss_structure) { + return false; + } + // Only use channel retries when device is synchronized + if (fhss_structure->fhss_state == FHSS_UNSYNCHRONIZED) { + return false; + } + // Channel retries are disabled -> return + if (fhss_structure->bs->fhss_configuration.fhss_number_of_channel_retries == 0) { + return false; + } + // Use channel retries only for data frames + if (FHSS_DATA_FRAME != frame_type) { + return false; + } + + fhss_failed_tx_t *fhss_failed_tx = fhss_failed_handle_find(fhss_structure, handle); + if (fhss_failed_tx) { + fhss_failed_tx->retries_done++; + if (fhss_failed_tx->retries_done >= fhss_structure->bs->fhss_configuration.fhss_number_of_channel_retries) { + // No more retries. Return false to stop retransmitting. + fhss_failed_handle_remove(fhss_structure, handle); + return false; + } + } else { + // Create new failure handle and return true to retransmit + fhss_failed_handle_add(fhss_structure, handle, fhss_structure->rx_channel); + } + return true; +} + +static void fhss_receive_frame_callback(const fhss_api_t *api, uint16_t pan_id, uint8_t *source_address, uint32_t timestamp, uint8_t *synch_info, int frame_type) +{ + fhss_structure_t *fhss_structure = fhss_get_object_with_api(api); + if (!fhss_structure) { + return; + } + if (FHSS_SYNCH_FRAME == frame_type) { + if ((fhss_structure->fhss_state == FHSS_UNSYNCHRONIZED) || fhss_structure->bs->synch_panid != pan_id) { + fhss_add_beacon_info(fhss_structure, pan_id, source_address, timestamp, synch_info); + } else { + if (!fhss_compare_with_synch_parent_address(fhss_structure, source_address)) { + // Synch parent address needs to be updated in case parent has changed + fhss_update_synch_parent_address(fhss_structure); + platform_enter_critical(); + // Calculate time since the Beacon was received + uint32_t elapsed_time = api->read_timestamp(api) - timestamp; + // Synchronize to given PAN + fhss_beacon_received(fhss_structure, synch_info, elapsed_time); + platform_exit_critical(); + } + } + } else if (FHSS_SYNCH_REQUEST_FRAME == frame_type) { + // If current channel is broadcast, we don't need to send another synch info on next broadcast channel. + // Only send number of MAX_SYNCH_INFOS_PER_CHANNEL_LIST synch infos per one channel list cycle + if ((fhss_structure->fhss_state == FHSS_SYNCHRONIZED) && (fhss_is_current_channel_broadcast(fhss_structure) == false) + && (fhss_structure->bs->synch_infos_sent_counter < MAX_SYNCH_INFOS_PER_CHANNEL_LIST)) { + fhss_structure->bs->send_synch_info_on_next_broadcast_channel = true; + } + } +} + +static uint16_t fhss_get_retry_period_callback(const fhss_api_t *api, uint8_t *destination_address, uint16_t phy_mtu) +{ + uint16_t retry_period = 0; + uint16_t random_number = randLIB_get_16bit(); + uint16_t rnd_mask; + + /* Generate retry back-off period. FHSS is using the known synchronization parent info to delay retransmissions upstream. + * + */ + if (phy_mtu < 128) { + // Max. random when PHY MTU below 128 is 6.4ms + rnd_mask = 0x7f; + } else if (phy_mtu < 256) { + // Max. random when PHY MTU below 256 is 12.8ms + rnd_mask = 0xff; + } else { + // Max. random when PHY MTU above 255 is 25.6ms + rnd_mask = 0x1ff; + } + + fhss_structure_t *fhss_structure = fhss_get_object_with_api(api); + if (fhss_structure) { + uint32_t datarate = fhss_structure->callbacks.read_datarate(fhss_structure->fhss_api); + uint16_t max_tx_length; + + if (datarate && phy_mtu) { + if (fhss_compare_with_synch_parent_address(fhss_structure, destination_address) == 0) { + // E.g. (1000000 / (250000bit/s / 8 bits)) * 255 bytes = 8160us + max_tx_length = ((1000000 / (datarate / 8)) * phy_mtu); + /* Retrying upstream: delay the transmission until assumed hidden node has retried downstream: + * Static period: max random + max tx length + * 50 comes from MAC timer resolution (50us) + */ + retry_period = (rnd_mask + (max_tx_length / 50)); + } + } + } + + // Add 1 to not to ever return zero value. + retry_period += ((random_number & rnd_mask) + 1); + return retry_period; +} + +static bool fhss_is_broadcast_channel_callback(const fhss_api_t *api) +{ + fhss_structure_t *fhss_structure = fhss_get_object_with_api(api); + if (!fhss_structure) { + return true; + } + // FHSS is unsynchronized, broadcasts allowed + if (fhss_structure->fhss_state == FHSS_UNSYNCHRONIZED) { + return true; + } + return fhss_is_current_channel_broadcast(fhss_structure); +} + +static bool fhss_use_broadcast_queue_cb(const fhss_api_t *api, bool is_broadcast_addr, int frame_type) +{ + fhss_structure_t *fhss_structure = fhss_get_object_with_api(api); + if (!fhss_structure) { + return false; + } + // Synch requests are always stored in unicast queue + if (frame_type == FHSS_SYNCH_REQUEST_FRAME) { + return false; + } + // Broadcast packets are stored in broadcast queue + return is_broadcast_addr; +} + +static void fhss_superframe_handler(const fhss_api_t *fhss_api, uint16_t delay) +{ + uint32_t timeout = 0; + fhss_structure_t *fhss_structure = fhss_get_object_with_api(fhss_api); + if (!fhss_structure) { + return; + } + + timeout = fhss_get_sf_timeout_callback(fhss_structure); + + fhss_start_timer(fhss_structure, timeout - (delay * fhss_structure->platform_functions.fhss_resolution_divider), fhss_superframe_handler); + + if (fhss_structure->bs->current_superframe++ >= (fhss_structure->bs->synch_configuration.fhss_number_of_superframes - 1)) { + fhss_structure->bs->current_superframe = 0; + if (++fhss_structure->bs->current_channel_index >= fhss_structure->number_of_channels) { + fhss_structure->bs->current_channel_index = 0; + } + fhss_update_channel_callback(fhss_structure); + } + fhss_superframe_callback(fhss_structure); + + if (fhss_structure->fhss_timeout) { + fhss_structure->fhss_timer += fhss_structure->bs->synch_configuration.fhss_superframe_length; + if (fhss_structure->fhss_timer >= fhss_structure->fhss_timeout) { + fhss_trig_event(fhss_structure, FHSS_TIMER_EVENT); + fhss_structure->fhss_timeout = 0; + fhss_structure->fhss_timer = 0; + } + } +} + +uint32_t fhss_get_remaining_time_to_next_superframe(const fhss_structure_t *fhss_structure) +{ + const uint32_t slots = fhss_structure->platform_functions.fhss_get_remaining_slots(fhss_superframe_handler, fhss_structure->fhss_api); + return (slots * fhss_structure->platform_functions.fhss_resolution_divider); +} + +int8_t fhss_set_synch_configuration(fhss_structure_t *fhss_structure, const fhss_synch_configuration_t *fhss_synch_configuration) +{ + if (!fhss_structure) { + return -1; + } + if (!fhss_synch_configuration) { + return -2; + } + // None of the configurations can be set zero + if( fhss_synch_configuration->fhss_number_of_bc_channels == 0 || fhss_synch_configuration->fhss_number_of_tx_slots == 0 + || fhss_synch_configuration->fhss_number_of_superframes == 0 || fhss_synch_configuration->fhss_superframe_length == 0) { + return -3; + } + // Number of channels must be divisible with the number of broadcast channels. + // Number of superframes must be divisible with the number of TX slots + if (((fhss_structure->number_of_channels % fhss_synch_configuration->fhss_number_of_bc_channels) != 0) || + ((fhss_synch_configuration->fhss_number_of_superframes % fhss_synch_configuration->fhss_number_of_tx_slots) != 0) || + (fhss_synch_configuration->fhss_number_of_superframes <= fhss_synch_configuration->fhss_number_of_tx_slots)) { + return -4; + } + fhss_structure->bs->synch_configuration = *fhss_synch_configuration; + fhss_structure->own_hop = 0; + return 0; +} + +uint8_t fhss_calculate_uc_index(uint8_t channel_index, uint16_t number_of_channels, uint8_t number_of_broadcast_channels) +{ + // When channel index is 0, return last unicast index + if (channel_index == 0) { + return (number_of_channels - number_of_broadcast_channels - 1); + } + uint16_t bc_channel_density = (number_of_channels/number_of_broadcast_channels); + return channel_index - (channel_index/bc_channel_density) - 1; +} + +int fhss_set_callbacks(fhss_structure_t *fhss_structure) +{ + // Set external API + fhss_structure->fhss_api->is_broadcast_channel = &fhss_is_broadcast_channel_callback; + fhss_structure->fhss_api->use_broadcast_queue = &fhss_use_broadcast_queue_cb; + fhss_structure->fhss_api->tx_handle = &fhss_tx_handle_callback; + fhss_structure->fhss_api->check_tx_conditions = &fhss_check_tx_conditions_callback; + fhss_structure->fhss_api->receive_frame = &fhss_receive_frame_callback; + fhss_structure->fhss_api->data_tx_done = &fhss_data_tx_done_callback; + fhss_structure->fhss_api->data_tx_fail = &fhss_data_tx_fail_callback; + fhss_structure->fhss_api->synch_state_set = &fhss_synch_state_set_callback; + fhss_structure->fhss_api->read_timestamp = &fhss_read_timestamp_cb; + fhss_structure->fhss_api->get_retry_period = &fhss_get_retry_period_callback; + fhss_structure->fhss_api->write_synch_info = &fhss_write_synch_info_callback; + fhss_structure->fhss_api->init_callbacks = &fhss_init_callbacks_cb; + + return 0; +} + +static int8_t fhss_beacon_create_tasklet(fhss_structure_t *fhss_structure) +{ + if (fhss_structure->beacon_tasklet_id < 0) { + fhss_structure->beacon_tasklet_id = eventOS_event_handler_create(fhss_beacon_tasklet_func, FHSS_TASKLET_INIT_EVENT); + } + return fhss_structure->beacon_tasklet_id; +} + +static int fhss_beacon_periodic_start(fhss_structure_t *fhss_structure, uint32_t time_to_first_beacon) +{ + int ret_val = -1; + + if (fhss_structure) { + fhss_beacon_periodic_stop(fhss_structure); + ret_val = fhss_timeout_start(fhss_structure, time_to_first_beacon * 1000); + } + return ret_val; +} + +static void fhss_beacon_periodic_stop(fhss_structure_t *fhss_structure) +{ + if (fhss_structure) { + fhss_timeout_stop(fhss_structure); + } +} + +static void fhss_beacon_tasklet_func(arm_event_s* event) +{ + fhss_structure_t *fhss_structure = (fhss_structure_t *)event->data_ptr; + if (!fhss_structure) { + return; + } + uint8_t parent_address[8]; + fhss_clear_active_event(fhss_structure, event->event_type); + // skip the init event as there will be a timer event after + if (event->event_type == FHSS_TIMER_EVENT) { + // Stop network when lost number of FHSS_SYNCHRONIZATION_LOST synchronization beacons from parent in a row. + if (fhss_structure->bs->beacons_received_timer >= FHSS_SYNCHRONIZATION_LOST) { + fhss_structure->callbacks.synch_lost_notification(fhss_structure->fhss_api); + fhss_stats_update(fhss_structure, STATS_FHSS_SYNCH_LOST, 1); + tr_err("FHSS synchronization lost"); + } else { + uint16_t bc_density = (fhss_structure->number_of_channels / fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels); + uint16_t channel_dwell_time = ((uint32_t)fhss_structure->bs->synch_configuration.fhss_superframe_length * fhss_structure->bs->synch_configuration.fhss_number_of_superframes) / 1000; + + fhss_beacon_periodic_start(fhss_structure, (bc_density * channel_dwell_time) * 2); + // Send synchronization request + fhss_structure->callbacks.send_fhss_frame(fhss_structure->fhss_api, FHSS_SYNCH_REQUEST_FRAME); + fhss_structure->bs->beacons_received_timer++; +#ifdef FEA_TRACE_SUPPORT + if (!fhss_get_parent_address(fhss_structure, parent_address)) { + tr_debug("Update synch, attempt: %u, %s", fhss_structure->bs->beacons_received_timer, trace_array(parent_address, 8)); + } else { + tr_err("No synch parent found"); + } +#endif /*FEA_TRACE_SUPPORT*/ + } + } + // Compare if synchronization parent has changed and request beacon if needed + else if(event->event_type == FHSS_COMPARE_SYNCH_PARENT) + { + if (fhss_compare_with_synch_parent_address(fhss_structure, fhss_structure->synch_parent)) { + fhss_structure->bs->synch_monitor.avg_synch_fix = 0; + if(fhss_structure->bs->synch_monitor.avg_synch_fix_counter > 0) { + fhss_structure->bs->synch_monitor.avg_synch_fix_counter = 0; + } + // Send synchronization request + fhss_structure->callbacks.send_fhss_frame(fhss_structure->fhss_api, FHSS_SYNCH_REQUEST_FRAME); +#ifdef FEA_TRACE_SUPPORT + if (!fhss_get_parent_address(fhss_structure, parent_address)) { + tr_debug("Synch parent changed, New: %s, Old: %s\n", trace_array(parent_address, 8), trace_array(fhss_structure->synch_parent, 8)); + } else { + tr_err("Synch parent changed : No parent found"); + } +#endif /*FEA_TRACE_SUPPORT*/ + } + } + else if(event->event_type == FHSS_BROADCAST_CHANNEL) + { + uint16_t superframe_length = fhss_structure->bs->synch_configuration.fhss_superframe_length; + uint8_t number_of_superframes = fhss_structure->bs->synch_configuration.fhss_number_of_superframes; + // Given broadcast time is channel length minus 1 superframe + fhss_structure->callbacks.broadcast_notify(fhss_structure->fhss_api, (uint32_t)superframe_length * (number_of_superframes - 1)); + } + // Update Beacon info lifetimes + else if(event->event_type == FHSS_UPDATE_SYNCH_INFO_STORAGE) + { + fhss_update_beacon_info_lifetimes(fhss_structure, fhss_read_timestamp_cb(fhss_structure->fhss_api)); } } diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss.h b/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss.h index ed38820cb706..e78073f963c3 100644 --- a/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss.h +++ b/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,164 +16,110 @@ */ #ifndef FHSS_H_ #define FHSS_H_ -#include "ns_list.h" #define MAX_SCRAMBLE_TABLE_INDEXES 20 - // Lifetime is given as seconds #define BEACON_INFO_LIFETIME 600 // Limits the number of synchronization info messages sent on broadcast channels #define MAX_SYNCH_INFOS_PER_CHANNEL_LIST 2 // FHSS randomly selects the starting superframe for broadcast channel. This defines how many superframes are used for randomization. #define NUMBER_OF_BC_START_SUPERFRAMES 3 - -#define FHSS_TASKLET_INIT_EVENT 0 -#define FHSS_TIMER_EVENT 1 -#define FHSS_COMPARE_SYNCH_PARENT 2 -#define FHSS_BROADCAST_CHANNEL 3 -#define FHSS_UPDATE_SYNCH_INFO_STORAGE 4 - -struct fhss_callback; - -typedef struct fhss_beacon_info +#define FHSS_MAX_ALLOWED_HOPS 254 +#define MAX_FHSS_TIMER_DIVIDER 100 +#define SYNCH_MONITOR_AVG_SAMPLES 5 +#define FHSS_DATA_START_DELIMETER 0x00 +#define FHSS_SYNCHRONIZATION_LOST 10 +#define BEACON_INTERVAL_INIT_DIVIDER 100 +#define FHSS_SYNCH_DRIFT_TOO_HIGH_LIMIT 20000 +#define CLOSE_TO_SUPERFRAME_LENGTH 2000 +#define BEACON_FIELD_SIZE(field) (sizeof((fhss_synchronization_beacon_payload_s*)0)->field) + +typedef struct fhss_structure fhss_structure_t; +typedef struct fhss_beacon_info fhss_beacon_info_t; +typedef struct fhss_synch_monitor fhss_synch_monitor_s; +typedef struct fhss_failed_tx fhss_failed_tx_t; +typedef struct fhss_bs fhss_bs_t; +typedef struct fhss_synchronization_beacon_payload fhss_synchronization_beacon_payload_s; + +struct fhss_synchronization_beacon_payload +{ + /** Start delimeter */ + uint8_t data_start_delimeter; + /** Channel index */ + uint8_t channel_index; + /** Sender unicast channel index */ + uint8_t sender_unicast_channel; + /** Current superframe */ + uint16_t current_superframe; + /** Remaining time (us) to next superframe */ + uint16_t remaining_slots; + /** Channel list counter */ + uint16_t channel_list_counter; + /** Hop count */ + uint8_t hop_count; + /** Number of broadcast channels */ + uint8_t number_of_broadcast_channels; + /** Number of TX slots per channel */ + uint8_t number_of_tx_slots; + /** Time since last beacon (us) */ + uint32_t time_since_last_beacon; + /** Processing delay (us) */ + uint16_t processing_delay; + /** Superframe length */ + uint16_t superframe_length; + /** Number of superframes per channel */ + uint8_t number_of_superframes_per_channel; +}; + +struct fhss_beacon_info { uint16_t pan_id; uint8_t source_address[8]; uint32_t timestamp; uint8_t synch_info[FHSS_SYNCH_INFO_LENGTH]; struct fhss_beacon_info *next; -}fhss_beacon_info_t; +}; -typedef struct fhss_failed_tx -{ - uint8_t handle; - uint8_t bad_channel; - uint8_t retries_done; - ns_list_link_t link; -}fhss_failed_tx_t; - -typedef NS_LIST_HEAD(fhss_failed_tx_t, link) fhss_failed_tx_list_t; - -typedef struct +struct fhss_synch_monitor { int32_t avg_synch_fix; int avg_synch_fix_counter; int drift_compensation; int channel_counter; -} fhss_synch_monitor_s; +}; -typedef struct +struct fhss_bs { - fhss_api_t *fhss_api; - uint32_t datarate; - fhss_states fhss_state; - fhss_timer_t platform_functions; - fhss_configuration_t fhss_configuration; - fhss_synch_configuration_t synch_configuration; - - uint8_t fhss_resolution_divider; - /** Unicast channel index, [0..(number_of_channels-number_of_beacon_channels-1)] */ uint8_t uc_channel_index; - /** Current superframe number, [0..(fhss_number_of_superframes-1)] */ uint8_t current_superframe; - /** Current channel index, [0..(number_of channels-1)] */ uint8_t current_channel_index; - /** Current broadcast index, [0..(number_of_bc_channels-1)] */ - uint8_t broadcast_index; - /** Number of channels (unicast and broadcast) */ - uint16_t number_of_channels; - /** Channel list counter is increased every time channel list is gone through*/ - uint16_t channel_list_counter; - /** This is used to store current RX channel*/ - uint8_t rx_channel; - /** Own hop count*/ - uint8_t own_hop; - /** Holds the information: transmission is allowed or not on this superframe*/ - bool tx_allowed; - /** The tasklet_id of periodic beacon sender, -1 if none is started. */ - int8_t beacon_tasklet_id; - /** When synchronization is lost, this counter is used to detect the situation and stop network*/ uint8_t beacons_received_timer; - /** Holds the current synchronization parent MAC address*/ - uint8_t synch_parent[8]; - // Synch info needs to be sent on next broadcast channel - bool send_synch_info_on_next_broadcast_channel; - // Used for randomizing broadcast sending. Device is not allowed to start broadcasting before the given superframe. uint8_t broadcast_start_superframe; - /*Indexes in this table will be used to extend the repeated channel sequence*/ - uint8_t fhss_scramble_table[MAX_SCRAMBLE_TABLE_INDEXES]; - /** Used to monitor and fix synchronization drift*/ - fhss_synch_monitor_s synch_monitor; - /** Used to drop multiple synch info messages on same broadcast channel*/ - bool beacon_received_on_this_bc_channel; - /** Timer used for events other than synchronization.*/ - int8_t fhss_event_timer; - /* Counts the number of sent synch Beacons (Beacon on broadcast channel). Used to limit Beacon traffic when several nodes are scanning network*/ uint8_t synch_infos_sent_counter; - uint32_t synch_interval; - /* This timer/timeout is used to trigger periodically Beacon requests. Resolution is superframe length. Note that FHSS must be synchronized to use this*/ - uint32_t fhss_timeout; - uint32_t fhss_timer; + bool tx_allowed:1; + bool send_synch_info_on_next_broadcast_channel:1; + bool beacon_received_on_this_bc_channel:1; + uint16_t channel_list_counter; uint16_t synch_panid; - /* Bit mask for FHSS events pushed to event queue. Prevents pushing same event to queue multiple times*/ - uint8_t active_fhss_events; - - struct fhss_callback callbacks; - fhss_beacon_info_t *fhss_beacon_info_store; - fhss_failed_tx_list_t fhss_failed_tx_list; - fhss_statistics_t *fhss_stats_ptr; -} fhss_structure_t; + uint32_t synch_interval; + struct fhss_statistics *fhss_stats_ptr; + struct fhss_beacon_info *fhss_beacon_info_store; + struct fhss_configuration fhss_configuration; + struct fhss_synch_configuration synch_configuration; + struct fhss_synch_monitor synch_monitor; + uint8_t fhss_scramble_table[MAX_SCRAMBLE_TABLE_INDEXES]; +}; -int8_t fhss_enable(fhss_api_t *fhss_api, const fhss_configuration_t *fhss_configuration, const fhss_timer_t *fhss_timer, fhss_statistics_t *fhss_statistics); -int8_t fhss_disable(fhss_structure_t *fhss_structure); -int8_t fhss_set_datarate(fhss_structure_t *fhss_structure, uint32_t datarate); +fhss_structure_t *fhss_enable(fhss_api_t *fhss_api, const fhss_configuration_t *fhss_configuration, const fhss_timer_t *fhss_timer, fhss_statistics_t *fhss_statistics); bool fhss_is_synch_root(fhss_structure_t *fhss_structure); -int8_t fhss_set_synch_configuration(fhss_structure_t *fhss_structure, const fhss_synch_configuration_t *fhss_synch_configuration); -bool fhss_check_bad_channel(fhss_structure_t *fhss_structure, uint8_t handle); -bool fhss_check_channel_type(fhss_structure_t *fhss_structure, bool is_bc, int frame_type); -bool fhss_check_tx_allowed(fhss_structure_t *fhss_structure, bool is_bc, uint16_t frame_length, int frame_type, uint8_t phy_header_length, uint8_t phy_tail_length); -fhss_structure_t *fhss_get_object_with_api(const fhss_api_t *fhss_api); -fhss_beacon_info_t *fhss_get_beacon_info(fhss_structure_t *fhss_structure, uint16_t pan_id); -int fhss_flush_beacon_info_storage(fhss_structure_t *fhss_structure); -int fhss_add_beacon_info(fhss_structure_t *fhss_structure, uint16_t pan_id, uint8_t *source_address, uint32_t timestamp, uint8_t *synch_info); -void fhss_update_beacon_info_lifetimes(fhss_structure_t *fhss_structure, uint32_t timestamp); -void fhss_trig_event(fhss_structure_t *fhss_structure, uint8_t event_type); -int fhss_timeout_start(fhss_structure_t *fhss_structure, uint32_t time); -int fhss_timeout_stop(fhss_structure_t *fhss_structure); -int fhss_compare_with_synch_parent_address(fhss_structure_t *fhss_structure, const uint8_t *source_addr); -uint32_t fhss_get_tx_time(fhss_structure_t *fhss_structure, uint16_t bytes_to_send, uint8_t phy_header_length, uint8_t phy_tail_length); -int fhss_get_parent_address(fhss_structure_t *fhss_structure, uint8_t *p_addr); -int fhss_down(fhss_structure_t *fhss_structure); -int fhss_update_synch_parent_address(fhss_structure_t *fhss_structure); -void fhss_superframe_handler(const fhss_api_t *fhss_api, uint16_t delay); -fhss_failed_tx_t *fhss_failed_handle_find(fhss_structure_t *fhss_structure, uint8_t handle); -int fhss_failed_handle_add(fhss_structure_t *fhss_structure, uint8_t handle); -int fhss_failed_handle_remove(fhss_structure_t *fhss_structure, uint8_t handle); -void fhss_set_active_event(fhss_structure_t *fhss_structure, uint8_t event_type); -void fhss_clear_active_event(fhss_structure_t *fhss_structure, uint8_t event_type); -bool fhss_read_active_event(fhss_structure_t *fhss_structure, uint8_t event_type); -#define MAX_FHSS_TIMER_DIVIDER 100 -#define SYNCH_MONITOR_AVG_SAMPLES 5 - -// TX/RX slot management interface -/** - * Update slots - * - * Every superframe handler interrupt calls this function to update the TX/RX slot status. - * - * @param fhss_structure Pointer to FHSS structure - * @return 0 for success, -1 for fail - */ -int fhss_update_txrx_slots(fhss_structure_t *fhss_structure); - -void fhss_start_timer(fhss_structure_t *fhss_structure, uint32_t time, void (*callback)(const fhss_api_t *fhss_api, uint16_t)); - - /** * Calculate time in microseconds to start of next superframe. * - * @param fhss_struct FHSS state + * @param fhss_struct FHSS structure * @return microseconds left to start of next superframe */ uint32_t fhss_get_remaining_time_to_next_superframe(const fhss_structure_t *fhss_struct); +int8_t fhss_set_synch_configuration(fhss_structure_t *fhss_structure, const fhss_synch_configuration_t *fhss_synch_configuration); +int fhss_set_callbacks(fhss_structure_t *fhss_structure); +uint8_t fhss_calculate_uc_index(uint8_t channel_index, uint16_t number_of_channels, uint8_t number_of_broadcast_channels); #endif /* FHSS_H_ */ diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_beacon.c b/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_beacon.c deleted file mode 100644 index fccec57b266d..000000000000 --- a/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_beacon.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright (c) 2015-2017, Arm Limited and affiliates. - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#include "nsconfig.h" -#include "fhss_api.h" -#include "fhss_config.h" -#include "fhss.h" -#include "fhss_beacon.h" - -#include "common_functions.h" -#include // memcpy -#include "ns_trace.h" - -#define TRACE_GROUP "fhss" - -// This function should be called just prior actually sending a beacon packet -// to get precise information. Especially the time variables are essential. -int fhss_beacon_update_payload(fhss_structure_t *fhss_structure, - fhss_synchronization_beacon_payload_s *payload) -{ - - int ret_val = 0; - if (!fhss_structure || !payload) { - return -1; - } - - const fhss_synch_configuration_t *config = &fhss_structure->synch_configuration; - - payload->channel_index = fhss_structure->current_channel_index; - - payload->sender_unicast_channel = 0; - - payload->current_superframe = fhss_structure->current_superframe; - - // This assumes that the time is always in the range of 0..2**16, which - // should be the case as the superframe length field is also in that range. - payload->remaining_slots = (uint16_t) fhss_get_remaining_time_to_next_superframe(fhss_structure); - payload->channel_list_counter = fhss_structure->channel_list_counter; - - payload->hop_count = fhss_structure->own_hop; - payload->number_of_broadcast_channels = config->fhss_number_of_bc_channels; - payload->number_of_tx_slots = config->fhss_number_of_tx_slots; - payload->time_since_last_beacon = 0; // XXX not available yet - // TODO: Get Beacon length from MAC - uint32_t tx_time = fhss_get_tx_time(fhss_structure, 71, 0, 0); - payload->processing_delay = fhss_structure->fhss_configuration.fhss_tuning_parameters.tx_processing_delay + tx_time; - - payload->superframe_length = config->fhss_superframe_length; - - payload->number_of_superframes_per_channel = config->fhss_number_of_superframes; - - return ret_val; -} - -uint8_t* fhss_beacon_encode_raw(uint8_t* buffer, const fhss_synchronization_beacon_payload_s* source) -{ - *buffer++ = FHSS_DATA_START_DELIMETER; - *buffer++ = source->channel_index; - *buffer++ = source->sender_unicast_channel; - buffer = common_write_16_bit(source->current_superframe, buffer); - buffer = common_write_16_bit(source->remaining_slots, buffer); - buffer = common_write_16_bit(source->channel_list_counter, buffer); - *buffer++ = source->hop_count; - *buffer++ = source->number_of_broadcast_channels; - *buffer++ = source->number_of_tx_slots; - buffer = common_write_32_bit(source->time_since_last_beacon, buffer); - buffer = common_write_16_bit(source->processing_delay, buffer); - buffer = common_write_16_bit(source->superframe_length, buffer); - *buffer++ = source->number_of_superframes_per_channel; - - return buffer; -} - -uint8_t fhss_calculate_uc_index(uint8_t channel_index, uint16_t number_of_channels, uint8_t number_of_broadcast_channels) -{ - // When channel index is 0, return last unicast index - if (channel_index == 0) { - return (number_of_channels - number_of_broadcast_channels - 1); - } - uint16_t bc_channel_density = (number_of_channels/number_of_broadcast_channels); - return channel_index - (channel_index/bc_channel_density) - 1; -} - - -uint32_t fhss_get_time_to_next_channel_change(uint16_t remaining_slots_to_next_superframe, uint8_t number_of_superframes, - uint8_t current_superframe, uint16_t superframe_length) -{ - return remaining_slots_to_next_superframe + ((uint32_t)((number_of_superframes - 1) - current_superframe) * superframe_length); -} - -void fhss_beacon_decode_raw(fhss_synchronization_beacon_payload_s* dest, const uint8_t* buffer) -{ - dest->data_start_delimeter = *buffer++; - - dest->channel_index = *buffer++; - dest->sender_unicast_channel = *buffer++; - - dest->current_superframe = common_read_16_bit(buffer); - buffer += BEACON_FIELD_SIZE(current_superframe); - - dest->remaining_slots = common_read_16_bit(buffer); - buffer += BEACON_FIELD_SIZE(remaining_slots); - - dest->channel_list_counter = common_read_16_bit(buffer); - buffer += BEACON_FIELD_SIZE(channel_list_counter); - - dest->hop_count = *buffer++; - dest->number_of_broadcast_channels = *buffer++; - dest->number_of_tx_slots = *buffer++; - - dest->time_since_last_beacon = common_read_32_bit(buffer); - buffer += BEACON_FIELD_SIZE(time_since_last_beacon); - - dest->processing_delay += common_read_16_bit(buffer); - - buffer += BEACON_FIELD_SIZE(processing_delay); - - dest->superframe_length = common_read_16_bit(buffer); - buffer += BEACON_FIELD_SIZE(superframe_length); - - dest->number_of_superframes_per_channel = *buffer; -} - -// Decode the given raw byte buffer into a struct into dest struct and calculate -// the new values for elapsed_time, channel_index, current_superframe and remaining_slots -// from current state and given data. -void fhss_beacon_decode(fhss_synchronization_beacon_payload_s* dest, const uint8_t* buffer, uint32_t elapsed_time, uint16_t number_of_channels) -{ - fhss_beacon_decode_raw(dest, buffer); - - elapsed_time += dest->processing_delay; - - /* To calculate channel index after beacon scan, following calculation is performed - * - * rem. slots to channel change(X) Channel length (V) - * |---------------------| |-----------------------------------------------| - * | RX'd channel index (Y) | ... | Y+n | - * ...| sf1 | sf2 | sf3 | sf4 | ... | sf1 | sf2 | sf3 | sf4 |... - * ^ ^ - * |beacon received |beacon scan done - * |-------------------------------------| - * measured time after beacon RX'd(Z) - * V = superframe length * number of superframes - * X = remaining slots to superframe change + length of the remaining full superframes to channel change - * - * Y+n = Y + ((Z - X) / V) + 1 - * - * Or if (Z < X) - * Y+n = Y - */ - - uint32_t remaining_slots_to_next_channel = fhss_get_time_to_next_channel_change(dest->remaining_slots, dest->number_of_superframes_per_channel, dest->current_superframe, dest->superframe_length); - uint16_t temp_channel_index = dest->channel_index; - if (elapsed_time >= remaining_slots_to_next_channel) { - uint32_t channel_length = (uint32_t) dest->number_of_superframes_per_channel * dest->superframe_length; - temp_channel_index = dest->channel_index + ((elapsed_time - remaining_slots_to_next_channel) / channel_length) + 1; - } - while (temp_channel_index >= number_of_channels) { - temp_channel_index -= number_of_channels; - dest->channel_list_counter++; - } - dest->channel_index = temp_channel_index; - while (dest->channel_list_counter >= (number_of_channels * MAX_SCRAMBLE_TABLE_INDEXES)) { - dest->channel_list_counter -= (number_of_channels * MAX_SCRAMBLE_TABLE_INDEXES); - } - - /* To calculate superframe after beacon scan, following calculation is performed - * - * rem. slots(X) sf. length(V) - * |---------------| |-----------------| - *...| RX'd superframe (Y)| ... | Y+n | Y+n+1 |.... - * ^ ^ - * |beacon received |beacon scan done - * |-------------------------------------| - * measured time after beacon RX'd(Z) - * - * Y+n = Y + ((Z - X) / V) + 1 - * - * Or if (Z < X) - * Y+n = Y - */ - - if (elapsed_time >= dest->remaining_slots) { - dest->current_superframe = dest->current_superframe + ((elapsed_time - dest->remaining_slots) / dest->superframe_length) + 1; - } - while (dest->current_superframe >= dest->number_of_superframes_per_channel) { - dest->current_superframe -= dest->number_of_superframes_per_channel; - } - - /* To get the remaining slots after beacon scan, following calculation is performed - * - * rem. slots(Y) sf. length(V) new rem. slots(X) - * |----------| |---------------| |-------------| - *...| superframe 1 | superframe 2 | superframe 3 | superframe 4 |... - * ^ ^ - * |beacon received |beacon scan done - * |--------------------------------------------| - * measured time after beacon RX'd(Z) - * - * X = V - ((Z - Y) % V) - * - * Or if (Z < Y) - * X = Y - Z - */ - - if (elapsed_time < dest->remaining_slots) { - dest->remaining_slots = dest->remaining_slots - elapsed_time; - } else { - dest->remaining_slots = dest->superframe_length - ((elapsed_time - dest->remaining_slots) % dest->superframe_length); - } - -} diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_beacon.h b/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_beacon.h deleted file mode 100644 index 7684b1c168ad..000000000000 --- a/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_beacon.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (c) 2015-2017, Arm Limited and affiliates. - * 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 __FHSS_BEACON_H__ -#define __FHSS_BEACON_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#define FHSS_DATA_START_DELIMETER 0x00 - -#define FHSS_SYNCH_BEACON_LIMIT 2 -#define FHSS_STOP_SENDING_BEACONS 8 -#define FHSS_SYNCHRONIZATION_LOST 10 - -// Based on datarate and Beacon frame packet length 71 bytes -#define BEACON_TX_TIME (1000000 / (dev_get_phy_datarate(cur) / 8) * 71) - -#define BEACON_INTERVAL_INIT_DIVIDER 100 -#define FHSS_SYNCH_DRIFT_TOO_HIGH_LIMIT 20000 -#define CLOSE_TO_SUPERFRAME_LENGTH 2000 - -/** beacon synchronization info */ -typedef struct { - /** Start delimeter */ - uint8_t data_start_delimeter; - - /** Channel index */ - uint8_t channel_index; - - /** Sender unicast channel index */ - uint8_t sender_unicast_channel; - - /** Current superframe */ - uint16_t current_superframe; - - /** Remaining time (us) to next superframe */ - uint16_t remaining_slots; - - /** Channel list counter */ - uint16_t channel_list_counter; - - /** Hop count */ - uint8_t hop_count; - - /** Number of broadcast channels */ - uint8_t number_of_broadcast_channels; - - /** Number of TX slots per channel */ - uint8_t number_of_tx_slots; - - /** Time since last beacon (us) */ - uint32_t time_since_last_beacon; - - /** Processing delay (us) */ - uint16_t processing_delay; - - /** Superframe length */ - uint16_t superframe_length; - - /** Number of superframes per channel */ - uint8_t number_of_superframes_per_channel; - -} fhss_synchronization_beacon_payload_s; - - -#define BEACON_FIELD_SIZE(field) (sizeof((fhss_synchronization_beacon_payload_s*)0)->field) - -// Calculate the size of data encoded from fhss_synchronization_beacon_payload_s, -// please add new items from that struct to this macro to keep code working. -#define FHSS_SYNC_BEACON_PAYLOAD_SYNC_SIZE \ - (BEACON_FIELD_SIZE(data_start_delimeter) + \ - BEACON_FIELD_SIZE(channel_index) + \ - BEACON_FIELD_SIZE(sender_unicast_channel) + \ - BEACON_FIELD_SIZE(current_superframe) + \ - BEACON_FIELD_SIZE(remaining_slots) + \ - BEACON_FIELD_SIZE(channel_list_counter) + \ - BEACON_FIELD_SIZE(hop_count) + \ - BEACON_FIELD_SIZE(number_of_broadcast_channels) + \ - BEACON_FIELD_SIZE(number_of_tx_slots) + \ - BEACON_FIELD_SIZE(time_since_last_beacon) + \ - BEACON_FIELD_SIZE(processing_delay) + \ - BEACON_FIELD_SIZE(superframe_length) + \ - BEACON_FIELD_SIZE(number_of_superframes_per_channel)) - -// 1 byte for protocol id, -// 1 byte for accept join -// 16 bytes for network id, TODO: find proper define to replace this magic value -#define FHSS_SYNC_BEACON_PAYLOAD_PREFIX_SIZE (1 + 1 + 16) - -// this counts the common prefix and the fhss specific sync payload -#define FHSS_SYNC_BEACON_PAYLOAD_COMPLETE_SIZE \ - (FHSS_SYNC_BEACON_PAYLOAD_PREFIX_SIZE + FHSS_SYNC_BEACON_PAYLOAD_SYNC_SIZE) - - -int fhss_beacon_periodic_start(fhss_structure_t *fhss_structure, uint32_t time_to_first_beacon); -void fhss_beacon_periodic_stop(fhss_structure_t *fhss_structure); - -void fhss_beacon_build(fhss_structure_t *fhss_structure, uint8_t *dest); - -/** - * Encode the given beacon syncronization structure into given buffer. - * - * Note: this information will not include protocol-id, accept_join or network-id - * - * @param buffer target buffer, must be at least FHSS_SYNC_BEACON_PAYLOAD_SIZE in size - * @param source source synchronization data to be encoded - * @return pointer to one byte after the encoded data - */ -uint8_t* fhss_beacon_encode_raw(uint8_t *buffer, const fhss_synchronization_beacon_payload_s *source); - -/** - * Decode the given beacon syncronization structure from given buffer and process the data. - * - * @param protocol_id protocol id from beacon payload - * @param accept_join accept join from beacon payload - * @param network_id network id from beacon payload, 16 bytes in size - * @param dest decoded data - * @param buffer source buffer, must be at least FHSS_SYNC_BEACON_PAYLOAD_SIZE in size - * @param elapsed_time time since previous beacon - * @param number_of_channels number of channels - */ -void fhss_beacon_decode(fhss_synchronization_beacon_payload_s *dest, const uint8_t *buffer, uint32_t elapsed_time, uint16_t number_of_channels); - -/** - * Decode the beacon data as-is to the given struct. - * - * @param dest decoded data - * @param buffer source buffer, must be at least FHSS_SYNC_BEACON_PAYLOAD_SIZE in size - */ -void fhss_beacon_decode_raw(fhss_synchronization_beacon_payload_s* dest, const uint8_t* buffer); - -int fhss_beacon_update_payload(fhss_structure_t *fhss_structure, - fhss_synchronization_beacon_payload_s *payload); - -void fhss_beacon_received(fhss_structure_t *fhss_structure, const uint8_t *synch_info, const uint32_t elapsed_time); - -/** - * This function is called whenever a node receives a beacon in the "proper state". - * The implmentation of it stores the data received and eventually synchronizes - * itself. - * - * Note: this is in completely illogical header file, but we have a - * circular dependency with net_fhss.h and protocol.h. - * - * @param cur the network interface which received beacon - * @param payload decoded beacon payload information - * - * @return 0 on success - */ -int fhss_sync_with_beacon(fhss_structure_t *fhss_structure, - const fhss_synchronization_beacon_payload_s *payload); - -uint8_t fhss_calculate_uc_index(uint8_t channel_index, uint16_t number_of_channels, uint8_t number_of_broadcast_channels); -int8_t fhss_beacon_create_tasklet(fhss_structure_t *fhss_structure); - -#ifdef __cplusplus -} -#endif - -#endif // !__FHSS_BEACON_H__ diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_beacon_tasklet.c b/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_beacon_tasklet.c deleted file mode 100644 index 7c54b6d2b0f7..000000000000 --- a/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_beacon_tasklet.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2015-2017, Arm Limited and affiliates. - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#include "nsconfig.h" -#include "common_functions.h" -#include "eventOS_event.h" -#include "eventOS_event_timer.h" -#include "ns_trace.h" -#include "fhss_api.h" -#include "fhss_config.h" -#include "fhss.h" -#include "fhss_beacon.h" -#include "fhss_statistics.h" -#include "fhss_mac_interface.h" -#include "platform/arm_hal_interrupt.h" - -#include // memset - -#define TRACE_GROUP "fhss" - -static void fhss_beacon_tasklet_func(arm_event_s* event); - -int8_t fhss_beacon_create_tasklet(fhss_structure_t *fhss_structure) -{ - if (fhss_structure->beacon_tasklet_id < 0) { - fhss_structure->beacon_tasklet_id = eventOS_event_handler_create(fhss_beacon_tasklet_func, FHSS_TASKLET_INIT_EVENT); - } - return fhss_structure->beacon_tasklet_id; -} - -int fhss_beacon_periodic_start(fhss_structure_t *fhss_structure, - uint32_t time_to_first_beacon) -{ - int ret_val = -1; - - if (fhss_structure) { - fhss_beacon_periodic_stop(fhss_structure); - ret_val = fhss_timeout_start(fhss_structure, time_to_first_beacon * 1000); - } - return ret_val; -} - -void fhss_beacon_periodic_stop(fhss_structure_t *fhss_structure) -{ - if (fhss_structure) { - fhss_timeout_stop(fhss_structure); - } -} - -static void fhss_beacon_tasklet_func(arm_event_s* event) -{ - fhss_structure_t *fhss_structure = (fhss_structure_t *)event->data_ptr; - if (!fhss_structure) { - return; - } -#ifdef FEA_TRACE_SUPPORT - uint8_t parent_address[8]; -#endif - fhss_clear_active_event(fhss_structure, event->event_type); - // skip the init event as there will be a timer event after - if (event->event_type == FHSS_TIMER_EVENT) { - // Stop network when lost number of FHSS_SYNCHRONIZATION_LOST synchronization beacons from parent in a row. - if (fhss_structure->beacons_received_timer >= FHSS_SYNCHRONIZATION_LOST) { - fhss_structure->callbacks.synch_lost_notification(fhss_structure->fhss_api); - fhss_stats_update(fhss_structure, STATS_FHSS_SYNCH_LOST, 1); - tr_err("FHSS synchronization lost"); - } else { - uint16_t bc_density = (fhss_structure->number_of_channels / fhss_structure->synch_configuration.fhss_number_of_bc_channels); - uint16_t channel_dwell_time = ((uint32_t)fhss_structure->synch_configuration.fhss_superframe_length * fhss_structure->synch_configuration.fhss_number_of_superframes) / 1000; - - fhss_beacon_periodic_start(fhss_structure, (bc_density * channel_dwell_time) * 2); - // Send synchronization request - fhss_structure->callbacks.send_fhss_frame(fhss_structure->fhss_api, FHSS_SYNCH_REQUEST_FRAME); - fhss_structure->beacons_received_timer++; -#ifdef FEA_TRACE_SUPPORT - if (!fhss_get_parent_address(fhss_structure, parent_address)) { - tr_debug("Update synch, attempt: %u, %s", fhss_structure->beacons_received_timer, trace_array(parent_address, 8)); - } else { - tr_err("No synch parent found"); - } -#endif /*FEA_TRACE_SUPPORT*/ - } - } - // Compare if synchronization parent has changed and request beacon if needed - else if(event->event_type == FHSS_COMPARE_SYNCH_PARENT) - { - if (fhss_compare_with_synch_parent_address(fhss_structure, fhss_structure->synch_parent)) { - fhss_structure->synch_monitor.avg_synch_fix = 0; - if(fhss_structure->synch_monitor.avg_synch_fix_counter > 0) { - fhss_structure->synch_monitor.avg_synch_fix_counter = 0; - } - // Send synchronization request - fhss_structure->callbacks.send_fhss_frame(fhss_structure->fhss_api, FHSS_SYNCH_REQUEST_FRAME); -#ifdef FEA_TRACE_SUPPORT - if (!fhss_get_parent_address(fhss_structure, parent_address)) { - tr_debug("Synch parent changed, New: %s, Old: %s\n", trace_array(parent_address, 8), trace_array(fhss_structure->synch_parent, 8)); - } else { - tr_err("Synch parent changed : No parent found"); - } -#endif /*FEA_TRACE_SUPPORT*/ - } - } - else if(event->event_type == FHSS_BROADCAST_CHANNEL) - { - uint16_t superframe_length = fhss_structure->synch_configuration.fhss_superframe_length; - uint8_t number_of_superframes = fhss_structure->synch_configuration.fhss_number_of_superframes; - // Given broadcast time is channel length minus 1 superframe - fhss_structure->callbacks.broadcast_notify(fhss_structure->fhss_api, (uint32_t)superframe_length * (number_of_superframes - 1)); - } - // Update Beacon info lifetimes - else if(event->event_type == FHSS_UPDATE_SYNCH_INFO_STORAGE) - { - fhss_update_beacon_info_lifetimes(fhss_structure, fhss_read_timestamp_cb(fhss_structure->fhss_api)); - } -} - -void fhss_beacon_build(fhss_structure_t *fhss_structure, uint8_t* dest) -{ - fhss_synchronization_beacon_payload_s temp_payload; - platform_enter_critical(); - fhss_beacon_update_payload(fhss_structure, &temp_payload); - platform_exit_critical(); - fhss_beacon_encode_raw(dest, &temp_payload); -} - -// this assumes that the buffer's data pointer is seeked to the beacon payload -void fhss_beacon_received(fhss_structure_t *fhss_structure, const uint8_t *synch_info, const uint32_t elapsed_time) { - - if (fhss_structure) { - - if (synch_info) { - fhss_synchronization_beacon_payload_s temp_payload; - temp_payload.processing_delay = fhss_structure->fhss_configuration.fhss_tuning_parameters.rx_processing_delay; - fhss_beacon_decode(&temp_payload, synch_info, elapsed_time, fhss_structure->number_of_channels); - - // use the received information - fhss_sync_with_beacon(fhss_structure, &temp_payload); - } - } -} - - diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_channel.c b/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_channel.c index 8f28991f2ae2..7bbf622304ff 100644 --- a/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_channel.c +++ b/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_channel.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, Arm Limited and affiliates. + * Copyright (c) 2016-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,8 +19,8 @@ #include "fhss_api.h" #include "fhss_config.h" #include "fhss.h" +#include "fhss_common.h" #include "fhss_channel.h" -#include "fhss_beacon.h" #include "channel_list.h" #include "randLIB.h" #include "ns_trace.h" @@ -28,7 +28,7 @@ #define TRACE_GROUP "fhss" // Enable this flag to use channel traces -//#define FHSS_CHANNEL_DEBUG +// #define FHSS_CHANNEL_DEBUG static uint8_t fhss_get_bc_index(const fhss_structure_t *fhss_structure); @@ -90,10 +90,10 @@ uint8_t fhss_add_channel_list_counter(uint8_t index, uint16_t number_of_channels static void fhss_generate_broadcast_start_superframe(fhss_structure_t *fhss_structure) { // If the number of superframes is low, allow broadcast on any superframe - if (fhss_structure->synch_configuration.fhss_number_of_superframes < 8) { - fhss_structure->broadcast_start_superframe = 0; + if (fhss_structure->bs->synch_configuration.fhss_number_of_superframes < 8) { + fhss_structure->bs->broadcast_start_superframe = 0; } else { - fhss_structure->broadcast_start_superframe = randLIB_get_random_in_range(0, NUMBER_OF_BC_START_SUPERFRAMES - 1); + fhss_structure->bs->broadcast_start_superframe = randLIB_get_random_in_range(0, NUMBER_OF_BC_START_SUPERFRAMES - 1); } } @@ -112,8 +112,8 @@ bool fhss_change_to_next_channel(fhss_structure_t *fhss_structure) bool broadcast_channel = false; uint16_t number_of_channels = fhss_structure->number_of_channels; - uint8_t number_of_broadcast_channels = fhss_structure->synch_configuration.fhss_number_of_bc_channels; - uint8_t unicast_channel_index = fhss_structure->uc_channel_index; + uint8_t number_of_broadcast_channels = fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels; + uint8_t unicast_channel_index = fhss_structure->bs->uc_channel_index; uint8_t channel_index_tmp; /* Get the channel number using channel index. Latter (number_of_broadcast_channels) indexes in channel table are broadcast channels and @@ -123,26 +123,20 @@ bool fhss_change_to_next_channel(fhss_structure_t *fhss_structure) */ /* Get broadcast channel */ if (fhss_is_current_channel_broadcast(fhss_structure) == true) { - channel_index_tmp = fhss_calc_channel_shuffle((number_of_channels - number_of_broadcast_channels) + fhss_get_bc_index(fhss_structure), fhss_structure->number_of_channels, fhss_structure->synch_configuration.fhss_number_of_bc_channels); + channel_index_tmp = fhss_calc_channel_shuffle((number_of_channels - number_of_broadcast_channels) + fhss_get_bc_index(fhss_structure), fhss_structure->number_of_channels, fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels); fhss_generate_broadcast_start_superframe(fhss_structure); broadcast_channel = true; } else { /* Get unicast channel */ - channel_index_tmp = fhss_calc_channel_shuffle(unicast_channel_index, fhss_structure->number_of_channels, fhss_structure->synch_configuration.fhss_number_of_bc_channels); - fhss_structure->uc_channel_index++; - if (fhss_structure->uc_channel_index >= number_of_channels - number_of_broadcast_channels) { - fhss_structure->uc_channel_index = 0; + channel_index_tmp = fhss_calc_channel_shuffle(unicast_channel_index, fhss_structure->number_of_channels, fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels); + if (++fhss_structure->bs->uc_channel_index >= number_of_channels - number_of_broadcast_channels) { + fhss_structure->bs->uc_channel_index = 0; } } // Reset Beacon received flag when channel has changed - fhss_structure->beacon_received_on_this_bc_channel = false; - channel_index_tmp = fhss_add_channel_list_counter(channel_index_tmp, fhss_structure->number_of_channels, fhss_structure->channel_list_counter, fhss_structure->fhss_scramble_table); - next_channel = channel_list_get_channel(fhss_structure->fhss_configuration.channel_mask, channel_index_tmp); + fhss_structure->bs->beacon_received_on_this_bc_channel = false; + channel_index_tmp = fhss_add_channel_list_counter(channel_index_tmp, fhss_structure->number_of_channels, fhss_structure->bs->channel_list_counter, fhss_structure->bs->fhss_scramble_table); + next_channel = channel_list_get_channel(fhss_structure->bs->fhss_configuration.channel_mask, channel_index_tmp); -#ifdef FHSS_MASSIVE_TRACE - tr_debug("%"PRIu32": update, frame: %"PRIu8", channel: %d", - fhss_structure->platform_functions.fhss_get_timestamp(fhss_structure->fhss_api), fhss_structure->current_superframe, - next_channel); -#endif fhss_structure->rx_channel = next_channel; #ifdef FHSS_CHANNEL_DEBUG if (fhss_is_current_channel_broadcast(fhss_structure) == true) { @@ -158,8 +152,8 @@ bool fhss_change_to_next_channel(fhss_structure_t *fhss_structure) static uint8_t fhss_get_bc_index(const fhss_structure_t *fhss_structure) { uint16_t number_of_channels = fhss_structure->number_of_channels; - uint8_t number_of_bc_channels = fhss_structure->synch_configuration.fhss_number_of_bc_channels; - uint8_t cur_channel_index = fhss_structure->current_channel_index; + uint8_t number_of_bc_channels = fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels; + uint8_t cur_channel_index = fhss_structure->bs->current_channel_index; return cur_channel_index / (number_of_channels/number_of_bc_channels); } @@ -169,7 +163,7 @@ uint8_t fhss_get_offset(fhss_structure_t *fhss_structure, const uint8_t *ptr) uint8_t i; uint8_t index = *ptr++; - if (fhss_structure->number_of_channels == fhss_structure->synch_configuration.fhss_number_of_bc_channels) { + if (fhss_structure->number_of_channels == fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels) { // If all channels are defined as broadcast channels then return 0 to avoid division by 0. // This could happen e.g. in OTA case when fast download is needed. return 0; @@ -181,7 +175,7 @@ uint8_t fhss_get_offset(fhss_structure_t *fhss_structure, const uint8_t *ptr) index ^= *ptr++; } // Offset must be < number of unicast channels - index %= (fhss_structure->number_of_channels - fhss_structure->synch_configuration.fhss_number_of_bc_channels); + index %= (fhss_structure->number_of_channels - fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels); return index; } @@ -194,13 +188,13 @@ bool fhss_is_current_channel_broadcast(fhss_structure_t *fhss_structure) } // Should always have broadcast channels with FHSS - if (!fhss_structure->synch_configuration.fhss_number_of_bc_channels) { + if (!fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels) { return true; } - uint8_t channel_index = fhss_structure->current_channel_index; + uint8_t channel_index = fhss_structure->bs->current_channel_index; uint16_t number_of_channels = fhss_structure->number_of_channels; - uint8_t number_of_broadcast_channels = fhss_structure->synch_configuration.fhss_number_of_bc_channels; + uint8_t number_of_broadcast_channels = fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels; if (!(channel_index % (number_of_channels / number_of_broadcast_channels))) { return true; @@ -216,15 +210,15 @@ static uint8_t fhss_get_destination_channel(fhss_structure_t *fhss_structure, ui if (fhss_structure) { if (fhss_is_current_channel_broadcast(fhss_structure) == false) { destination_offset = fhss_get_offset(fhss_structure, destination_address); - uc_index = fhss_calculate_uc_index(fhss_structure->current_channel_index, fhss_structure->number_of_channels, - fhss_structure->synch_configuration.fhss_number_of_bc_channels) + destination_offset; - if (uc_index >= (fhss_structure->number_of_channels - fhss_structure->synch_configuration.fhss_number_of_bc_channels)) { - uc_index -= (fhss_structure->number_of_channels - fhss_structure->synch_configuration.fhss_number_of_bc_channels); + uc_index = fhss_calculate_uc_index(fhss_structure->bs->current_channel_index, fhss_structure->number_of_channels, + fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels) + destination_offset; + if (uc_index >= (fhss_structure->number_of_channels - fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels)) { + uc_index -= (fhss_structure->number_of_channels - fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels); } - uc_index = fhss_calc_channel_shuffle(uc_index, fhss_structure->number_of_channels, fhss_structure->synch_configuration.fhss_number_of_bc_channels); - uc_index = fhss_add_channel_list_counter(uc_index, fhss_structure->number_of_channels, fhss_structure->channel_list_counter, fhss_structure->fhss_scramble_table); - return channel_list_get_channel(fhss_structure->fhss_configuration.channel_mask, uc_index); + uc_index = fhss_calc_channel_shuffle(uc_index, fhss_structure->number_of_channels, fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels); + uc_index = fhss_add_channel_list_counter(uc_index, fhss_structure->number_of_channels, fhss_structure->bs->channel_list_counter, fhss_structure->bs->fhss_scramble_table); + return channel_list_get_channel(fhss_structure->bs->fhss_configuration.channel_mask, uc_index); } return fhss_structure->rx_channel; } @@ -251,7 +245,7 @@ int fhss_change_to_parent_channel(fhss_structure_t *fhss_structure) uint8_t destination_channel; uint8_t destination_offset; if (fhss_structure) { - if (fhss_structure->number_of_channels != fhss_structure->synch_configuration.fhss_number_of_bc_channels) { + if (fhss_structure->number_of_channels != fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels) { uint8_t parent_address[8]; if (fhss_get_parent_address(fhss_structure, parent_address)) { return -1; @@ -259,14 +253,14 @@ int fhss_change_to_parent_channel(fhss_structure_t *fhss_structure) destination_offset = fhss_get_offset(fhss_structure, parent_address); - uc_index = fhss_calculate_uc_index(fhss_structure->current_channel_index, fhss_structure->number_of_channels, - fhss_structure->synch_configuration.fhss_number_of_bc_channels) + destination_offset; - if (uc_index >= (fhss_structure->number_of_channels - fhss_structure->synch_configuration.fhss_number_of_bc_channels)) { - uc_index -= (fhss_structure->number_of_channels - fhss_structure->synch_configuration.fhss_number_of_bc_channels); + uc_index = fhss_calculate_uc_index(fhss_structure->bs->current_channel_index, fhss_structure->number_of_channels, + fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels) + destination_offset; + if (uc_index >= (fhss_structure->number_of_channels - fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels)) { + uc_index -= (fhss_structure->number_of_channels - fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels); } - uc_index = fhss_calc_channel_shuffle(uc_index, fhss_structure->number_of_channels, fhss_structure->synch_configuration.fhss_number_of_bc_channels); - uc_index = fhss_add_channel_list_counter(uc_index, fhss_structure->number_of_channels, fhss_structure->channel_list_counter, fhss_structure->fhss_scramble_table); - destination_channel = channel_list_get_channel(fhss_structure->fhss_configuration.channel_mask, uc_index); + uc_index = fhss_calc_channel_shuffle(uc_index, fhss_structure->number_of_channels, fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels); + uc_index = fhss_add_channel_list_counter(uc_index, fhss_structure->number_of_channels, fhss_structure->bs->channel_list_counter, fhss_structure->bs->fhss_scramble_table); + destination_channel = channel_list_get_channel(fhss_structure->bs->fhss_configuration.channel_mask, uc_index); fhss_structure->callbacks.change_channel(fhss_structure->fhss_api, destination_channel); #ifdef FHSS_CHANNEL_DEBUG tr_info("Parent channel: %u", destination_channel); diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_common.c b/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_common.c new file mode 100644 index 000000000000..592a0b557da6 --- /dev/null +++ b/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_common.c @@ -0,0 +1,293 @@ +/* + * Copyright (c) 2015-2018, Arm Limited and affiliates. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "nsconfig.h" +#include "ns_types.h" +#include "ns_trace.h" +#include "fhss_api.h" +#include "fhss_config.h" +#include "fhss.h" +#include "fhss_common.h" +#include "fhss_ws.h" +#include "fhss_statistics.h" +#include "fhss_channel.h" +#include "channel_list.h" +#include "nsdynmemLIB.h" +#include "eventOS_event.h" +#include "eventOS_callback_timer.h" +#include + +#define TRACE_GROUP "fhssc" + +static fhss_structure_t *fhss_struct = NULL; + +static void fhss_event_timer_cb(int8_t timer_id, uint16_t slots); +static fhss_structure_t *fhss_get_object_with_timer_id(const int8_t timer_id); +static void fhss_set_active_event(fhss_structure_t *fhss_structure, uint8_t event_type); +static bool fhss_read_active_event(fhss_structure_t *fhss_structure, uint8_t event_type); + + +fhss_structure_t *fhss_allocate_instance(fhss_api_t *fhss_api, const fhss_timer_t *fhss_timer) +{ + if (fhss_struct || !fhss_api || !fhss_timer) { + return NULL; + } + fhss_struct = ns_dyn_mem_alloc(sizeof(fhss_structure_t)); + if (!fhss_struct) { + return NULL; + } + memset(fhss_struct, 0, sizeof(fhss_structure_t)); + fhss_struct->fhss_api = fhss_api; + fhss_struct->platform_functions = *fhss_timer; + fhss_struct->fhss_event_timer = eventOS_callback_timer_register(fhss_event_timer_cb); + if (!fhss_struct->platform_functions.fhss_resolution_divider) { + fhss_struct->platform_functions.fhss_resolution_divider = 1; + } + return fhss_struct; +} + +int8_t fhss_free_instance(fhss_api_t *fhss_api) +{ + if (!fhss_struct || fhss_struct->fhss_api != fhss_api) { + return -1; + } + ns_dyn_mem_free(fhss_struct); + fhss_struct = NULL; + return 0; +} + +static void fhss_event_timer_cb(int8_t timer_id, uint16_t slots) +{ + (void) slots; + fhss_structure_t *fhss_structure = fhss_get_object_with_timer_id(timer_id); + if (fhss_structure) { + fhss_structure->callbacks.tx_poll(fhss_structure->fhss_api); + } +} + +static fhss_structure_t *fhss_get_object_with_timer_id(const int8_t timer_id) +{ + if (timer_id < 0 || !fhss_struct) { + return NULL; + } + if (fhss_struct->fhss_event_timer == timer_id) { + return fhss_struct; + } + return NULL; +} + +fhss_structure_t *fhss_get_object_with_api(const fhss_api_t *fhss_api) +{ + if (!fhss_api || !fhss_struct) { + return NULL; + } + if (fhss_struct->fhss_api == fhss_api) { + return fhss_struct; + } + return NULL; +} + +static void fhss_set_active_event(fhss_structure_t *fhss_structure, uint8_t event_type) +{ + fhss_structure->active_fhss_events |= (1 << event_type); +} + +void fhss_clear_active_event(fhss_structure_t *fhss_structure, uint8_t event_type) +{ + fhss_structure->active_fhss_events &= ~(1 << event_type); +} + +static bool fhss_read_active_event(fhss_structure_t *fhss_structure, uint8_t event_type) +{ + if (fhss_structure->active_fhss_events & (1 << event_type)) { + return true; + } + return false; +} + +int8_t fhss_disable(fhss_structure_t *fhss_structure) +{ + if (!fhss_structure) { + return -1; + } + fhss_structure->fhss_api->synch_state_set(fhss_structure->fhss_api, FHSS_UNSYNCHRONIZED, 0); + ns_dyn_mem_free(fhss_structure->bs); + ns_dyn_mem_free(fhss_structure->ws); + ns_dyn_mem_free(fhss_structure); + fhss_struct = 0; + return 0; +} + +void fhss_start_timer(fhss_structure_t *fhss_structure, uint32_t time, void (*callback)(const fhss_api_t *fhss_api, uint16_t)) +{ + if (callback){ + // Don't allow starting with zero slots + if (time < fhss_structure->platform_functions.fhss_resolution_divider) { + time = fhss_structure->platform_functions.fhss_resolution_divider; + } + fhss_structure->platform_functions.fhss_timer_start(time / fhss_structure->platform_functions.fhss_resolution_divider, callback, fhss_structure->fhss_api); + } +} + +int fhss_timeout_start(fhss_structure_t *fhss_structure, uint32_t time) +{ + if (!fhss_structure) { + return -1; + } + fhss_structure->fhss_timeout = time; + fhss_structure->fhss_timer = 0; + return 0; +} + +int fhss_timeout_stop(fhss_structure_t *fhss_structure) +{ + if (!fhss_structure) { + return -1; + } + fhss_structure->fhss_timeout = 0; + fhss_structure->fhss_timer = 0; + return 0; +} + +int fhss_update_synch_parent_address(fhss_structure_t *fhss_structure) +{ + uint8_t parent_address[8]; + + if (!fhss_get_parent_address(fhss_structure, parent_address)) { + memcpy(fhss_structure->synch_parent, parent_address, 8); + return 0; + } + return -1; +} + +void fhss_trig_event(fhss_structure_t *fhss_structure, uint8_t event_type) +{ + if (!fhss_structure || fhss_read_active_event(fhss_structure, event_type) == true) { + return; + } + arm_event_s event; + event.receiver = fhss_structure->beacon_tasklet_id; + event.sender = 0; + event.event_type = event_type; + event.event_id = 0; + event.data_ptr = fhss_structure; + event.priority = ARM_LIB_HIGH_PRIORITY_EVENT; + event.event_data = 0; + if (eventOS_event_send(&event) != 0) { + tr_error("Event trigger failed: eventOS_event_send() failed"); + } else { + fhss_set_active_event(fhss_structure, event_type); + } +} + +int fhss_get_parent_address(fhss_structure_t *fhss_structure, uint8_t *p_addr) +{ + int ret_val = -1; + if (!fhss_structure || !p_addr) { + return -1; + } + + ret_val = fhss_structure->callbacks.read_coord_mac_address(fhss_structure->fhss_api, p_addr); + + if (ret_val) { + // Use default synchronization parent when RPL parent not found + memcpy(p_addr, fhss_structure->synch_parent, 8); + ret_val = 0; + } + return ret_val; +} + +int fhss_compare_with_synch_parent_address(fhss_structure_t *fhss_structure, const uint8_t *source_addr) +{ + int ret_val = -1; + if (!fhss_structure || !source_addr) { + return ret_val; + } + uint8_t parent_address[8]; + + if (fhss_is_synch_root(fhss_structure) == false) { + if (!fhss_get_parent_address(fhss_structure, parent_address)) { + ret_val = memcmp(source_addr, parent_address, 8); + } + } + return ret_val; +} + +uint32_t fhss_read_timestamp_cb(const fhss_api_t *api) +{ + fhss_structure_t *fhss_structure = fhss_get_object_with_api(api); + if (!fhss_structure) { + return 0; + } + return (fhss_structure->platform_functions.fhss_get_timestamp(api) * fhss_structure->platform_functions.fhss_resolution_divider); +} + +int fhss_init_callbacks_cb(const fhss_api_t *api, fhss_callback_t *callbacks) +{ + fhss_structure_t *fhss_structure = fhss_get_object_with_api(api); + if (!fhss_structure || !callbacks) { + return -1; + } + fhss_structure->callbacks = *callbacks; + return 0; +} + + +fhss_failed_tx_t *fhss_failed_handle_find(fhss_structure_t *fhss_structure, uint8_t handle) +{ + ns_list_foreach(fhss_failed_tx_t, cur, &fhss_structure->fhss_failed_tx_list) { + if (cur->handle == handle) { + return cur; + } + } + return NULL; +} + +int fhss_failed_handle_add(fhss_structure_t *fhss_structure, uint8_t handle, uint8_t bad_channel) +{ + fhss_failed_tx_t *failed_tx = ns_dyn_mem_alloc(sizeof(fhss_failed_tx_t)); + if (!failed_tx) { + return -1; + } + failed_tx->bad_channel = bad_channel; + failed_tx->retries_done = 0; + failed_tx->handle = handle; + ns_list_add_to_end(&fhss_structure->fhss_failed_tx_list, failed_tx); + return 0; +} + +int fhss_failed_handle_remove(fhss_structure_t *fhss_structure, uint8_t handle) +{ + fhss_failed_tx_t *failed_tx = fhss_failed_handle_find(fhss_structure, handle); + if (!failed_tx) { + return -1; + } + ns_list_remove(&fhss_structure->fhss_failed_tx_list, failed_tx); + ns_dyn_mem_free(failed_tx); // Free entry + return 0; +} + +void fhss_failed_list_free(fhss_structure_t *fhss_structure) +{ + for (uint16_t i = 0; i<256; i++) { + fhss_failed_handle_remove(fhss_structure, i); + } +} + +uint32_t fhss_get_tx_time(fhss_structure_t *fhss_structure, uint16_t bytes_to_send, uint8_t phy_header_length, uint8_t phy_tail_length) +{ + return ((1000000 / (fhss_structure->callbacks.read_datarate(fhss_structure->fhss_api) / 8)) * (bytes_to_send + phy_header_length + phy_tail_length)); +} diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_common.h b/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_common.h new file mode 100644 index 000000000000..144e089019a2 --- /dev/null +++ b/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_common.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2015-2018, Arm Limited and affiliates. + * 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 FHSS_COMMON_H_ +#define FHSS_COMMON_H_ +#include "ns_list.h" + +#define FHSS_TASKLET_INIT_EVENT 0 +#define FHSS_TIMER_EVENT 1 +#define FHSS_COMPARE_SYNCH_PARENT 2 +#define FHSS_BROADCAST_CHANNEL 3 +#define FHSS_UPDATE_SYNCH_INFO_STORAGE 4 + +struct fhss_failed_tx +{ + uint8_t handle; + uint8_t bad_channel; + uint8_t retries_done; + ns_list_link_t link; +}; +typedef NS_LIST_HEAD(fhss_failed_tx_t, link) fhss_failed_tx_list_t; + +struct fhss_structure +{ + uint8_t own_hop; + uint8_t fhss_resolution_divider; + uint8_t rx_channel; + int8_t beacon_tasklet_id; + int8_t fhss_event_timer; + uint8_t active_fhss_events; + uint16_t number_of_channels; + fhss_states fhss_state; + uint32_t fhss_timeout; + uint32_t fhss_timer; + struct fhss_api *fhss_api; + struct fhss_bs *bs; + struct fhss_ws *ws; + struct fhss_timer platform_functions; + struct fhss_callback callbacks; + fhss_failed_tx_list_t fhss_failed_tx_list; + uint8_t synch_parent[8]; +}; + +fhss_structure_t *fhss_allocate_instance(fhss_api_t *fhss_api, const fhss_timer_t *fhss_timer); +int8_t fhss_free_instance(fhss_api_t *fhss_api); +int8_t fhss_set_datarate(fhss_structure_t *fhss_structure, uint32_t datarate); +fhss_structure_t *fhss_get_object_with_api(const fhss_api_t *fhss_api); +void fhss_clear_active_event(fhss_structure_t *fhss_structure, uint8_t event_type); +int8_t fhss_disable(fhss_structure_t *fhss_structure); +void fhss_start_timer(fhss_structure_t *fhss_structure, uint32_t time, void (*callback)(const fhss_api_t *fhss_api, uint16_t)); +int fhss_timeout_start(fhss_structure_t *fhss_structure, uint32_t time); +int fhss_timeout_stop(fhss_structure_t *fhss_structure); +int fhss_update_synch_parent_address(fhss_structure_t *fhss_structure); +void fhss_trig_event(fhss_structure_t *fhss_structure, uint8_t event_type); +int fhss_get_parent_address(fhss_structure_t *fhss_structure, uint8_t *p_addr); +int fhss_compare_with_synch_parent_address(fhss_structure_t *fhss_structure, const uint8_t *source_addr); +uint32_t fhss_read_timestamp_cb(const fhss_api_t *api); +int fhss_init_callbacks_cb(const fhss_api_t *api, fhss_callback_t *callbacks); +int fhss_failed_handle_remove(fhss_structure_t *fhss_structure, uint8_t handle); +int fhss_failed_handle_add(fhss_structure_t *fhss_structure, uint8_t handle, uint8_t bad_channel); +fhss_failed_tx_t *fhss_failed_handle_find(fhss_structure_t *fhss_structure, uint8_t handle); +void fhss_failed_list_free(fhss_structure_t *fhss_structure); +uint32_t fhss_get_tx_time(fhss_structure_t *fhss_structure, uint16_t bytes_to_send, uint8_t phy_header_length, uint8_t phy_tail_length); +#endif /*FHSS_COMMON_H_*/ diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_configuration_interface.c b/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_configuration_interface.c index 0f6ada010008..0c7567e5169c 100644 --- a/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_configuration_interface.c +++ b/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_configuration_interface.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, Arm Limited and affiliates. + * Copyright (c) 2016-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -22,12 +22,12 @@ #include "net_fhss.h" #include "nsdynmemLIB.h" #include "Service_Libs/fhss/fhss.h" -#include "Service_Libs/fhss/fhss_mac_interface.h" +#include "Service_Libs/fhss/fhss_common.h" +#include "Service_Libs/fhss/fhss_ws.h" #include "ns_trace.h" #define TRACE_GROUP "fhss" - fhss_api_t *ns_fhss_create(const fhss_configuration_t *fhss_configuration, const fhss_timer_t *fhss_timer, fhss_statistics_t *fhss_statistics) { fhss_api_t *this = ns_dyn_mem_alloc(sizeof(fhss_api_t)); @@ -35,26 +35,51 @@ fhss_api_t *ns_fhss_create(const fhss_configuration_t *fhss_configuration, const return NULL; } // Create FHSS object - int8_t retval = fhss_enable(this, fhss_configuration, fhss_timer, fhss_statistics); - if (retval) { - tr_err("Failed to enable FHSS, return code: %i", retval); + fhss_structure_t *fhss_struct = fhss_enable(this, fhss_configuration, fhss_timer, fhss_statistics); + if (!fhss_struct) { + tr_err("Failed to enable FHSS"); + ns_dyn_mem_free(this); + return NULL; + } + fhss_set_callbacks(fhss_struct); + return this; +} + +fhss_api_t *ns_fhss_ws_create(const fhss_ws_configuration_t *fhss_configuration, const fhss_timer_t *fhss_timer) +{ + fhss_api_t *this = ns_dyn_mem_alloc(sizeof(fhss_api_t)); + if (!this) { + return NULL; + } + // Create FHSS object + fhss_structure_t *fhss_struct = fhss_ws_enable(this, fhss_configuration, fhss_timer); + if (!fhss_struct) { + tr_err("Failed to enable FHSS"); ns_dyn_mem_free(this); return NULL; } - this->is_broadcast_channel = &fhss_is_broadcast_channel_cb; - this->use_broadcast_queue = &fhss_use_broadcast_queue_cb; - this->tx_handle = &fhss_tx_handle_cb; - this->check_tx_conditions = &fhss_check_tx_conditions_cb; - this->receive_frame = &fhss_receive_frame_cb; - this->data_tx_done = &fhss_data_tx_done_cb; - this->data_tx_fail = &fhss_data_tx_fail_cb; - this->synch_state_set = &fhss_synch_state_set_cb; - this->read_timestamp = &fhss_read_timestamp_cb; - this->get_retry_period = &fhss_get_retry_period_cb; - this->init_callbacks = &fhss_init_callbacks_cb; + fhss_ws_set_callbacks(fhss_struct); return this; } +int ns_fhss_ws_set_parent(const fhss_api_t *fhss_api, const uint8_t eui64[8], const broadcast_timing_info_t *bc_timing_info) +{ + fhss_structure_t *fhss_structure = fhss_get_object_with_api(fhss_api); + if (!fhss_structure || !eui64 || !bc_timing_info) { + return -1; + } + return fhss_ws_set_parent(fhss_structure, eui64, bc_timing_info); +} + +int ns_fhss_ws_remove_parent(const fhss_api_t *fhss_api, const uint8_t eui64[8]) +{ + fhss_structure_t *fhss_structure = fhss_get_object_with_api(fhss_api); + if (!fhss_structure || !eui64) { + return -1; + } + return fhss_ws_remove_parent(fhss_structure, eui64); +} + int ns_fhss_delete(fhss_api_t *fhss_api) { fhss_structure_t *fhss_structure = fhss_get_object_with_api(fhss_api); @@ -65,7 +90,6 @@ int ns_fhss_delete(fhss_api_t *fhss_api) return -1; } ns_dyn_mem_free(fhss_api); - fhss_api = NULL; return 0; } @@ -77,3 +101,40 @@ int ns_fhss_configuration_set(fhss_api_t *fhss_api, const fhss_synch_configurati } return fhss_set_synch_configuration(fhss_structure, fhss_synch_configuration); } + +int ns_fhss_set_neighbor_info_fp(const fhss_api_t *fhss_api, fhss_get_neighbor_info *get_neighbor_info) +{ + fhss_structure_t *fhss_structure = fhss_get_object_with_api(fhss_api); + if (!fhss_structure || !fhss_structure->ws) { + return -1; + } + fhss_structure->ws->get_neighbor_info = get_neighbor_info; + return 0; +} + +const fhss_ws_configuration_t *ns_fhss_ws_configuration_get(const fhss_api_t *fhss_api) +{ + fhss_structure_t *fhss_structure = fhss_get_object_with_api(fhss_api); + if (!fhss_structure || !fhss_structure->ws) { + return NULL; + } + return &fhss_structure->ws->fhss_configuration; +} + +int ns_fhss_ws_configuration_set(const fhss_api_t *fhss_api, const fhss_ws_configuration_t *fhss_configuration) +{ + fhss_structure_t *fhss_structure = fhss_get_object_with_api(fhss_api); + if (!fhss_structure || !fhss_structure->ws) { + return -1; + } + return fhss_ws_configuration_set(fhss_structure, fhss_configuration); +} + +int ns_fhss_ws_set_hop_count(const fhss_api_t *fhss_api, const uint8_t hop_count) +{ + fhss_structure_t *fhss_structure = fhss_get_object_with_api(fhss_api); + if (!fhss_structure || !fhss_structure->ws) { + return -1; + } + return fhss_ws_set_hop_count(fhss_structure, hop_count); +} diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_mac_interface.c b/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_mac_interface.c deleted file mode 100644 index ae839f3eda39..000000000000 --- a/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_mac_interface.c +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Copyright (c) 2016-2017, Arm Limited and affiliates. - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "nsconfig.h" -#include -#include "ns_types.h" -#include "fhss_api.h" -#include "fhss_config.h" -#include "Service_Libs/fhss/fhss.h" -#include "Service_Libs/fhss/fhss_channel.h" -#include "Service_Libs/fhss/fhss_beacon.h" -#include "platform/arm_hal_interrupt.h" -#include "randLIB.h" -#include "ns_trace.h" - -#define TRACE_GROUP "fhss" - - -bool fhss_is_broadcast_channel_cb(const fhss_api_t *api) -{ - fhss_structure_t *fhss_structure = fhss_get_object_with_api(api); - if (!fhss_structure) { - return false; - } - // FHSS is unsynchronized, broadcasts allowed - if (fhss_structure->fhss_state == FHSS_UNSYNCHRONIZED) { - return true; - } - return fhss_is_current_channel_broadcast(fhss_structure); -} - -bool fhss_use_broadcast_queue_cb(const fhss_api_t *api, bool is_broadcast_addr, int frame_type) -{ - fhss_structure_t *fhss_structure = fhss_get_object_with_api(api); - if (!fhss_structure) { - return false; - } - // Synch requests are always stored in unicast queue - if (frame_type == FHSS_SYNCH_REQUEST_FRAME) { - return false; - } - // Broadcast packets are stored in broadcast queue - return is_broadcast_addr; -} - -int fhss_tx_handle_cb(const fhss_api_t *api, bool is_broadcast_addr, uint8_t *destination_address, int frame_type, uint8_t *synch_info, uint16_t frame_length, uint8_t phy_header_length, uint8_t phy_tail_length) -{ - fhss_structure_t *fhss_structure = fhss_get_object_with_api(api); - if (!fhss_structure) { - return -2; - } - // TODO: needs some more logic to push buffer back to queue - if (frame_type == FHSS_DATA_FRAME) { - if (is_broadcast_addr == true) { - if (fhss_is_current_channel_broadcast(fhss_structure) == false) { - tr_info("Broadcast on UC channel -> Back to queue"); - return -3; - } - } - } - if (frame_type == FHSS_SYNCH_FRAME) { - if (!synch_info) { - return -4; - } - fhss_beacon_build(fhss_structure, synch_info); - } else if (fhss_check_tx_allowed(fhss_structure, is_broadcast_addr, frame_length, frame_type, phy_header_length, phy_tail_length) == false) { - return -1; - } - // If sending Beacon request on parents Unicast channel - if (frame_type == FHSS_SYNCH_REQUEST_FRAME && fhss_structure->fhss_state == FHSS_SYNCHRONIZED) { - fhss_change_to_parent_channel(fhss_structure); - } else if (frame_type == FHSS_DATA_FRAME) { - fhss_change_to_tx_channel(fhss_structure, destination_address); - } - return 0; -} - -bool fhss_check_tx_conditions_cb(const fhss_api_t *api, bool is_broadcast_addr, uint8_t handle, int frame_type, uint16_t frame_length, uint8_t phy_header_length, uint8_t phy_tail_length) -{ - fhss_structure_t *fhss_structure = fhss_get_object_with_api(api); - if (!fhss_structure) { - return false; - } - // This condition will check that message is not sent on bad channel - if (fhss_check_bad_channel(fhss_structure, handle) == false) { - return false; - } - - // This condition will check that broadcast messages are sent only broadcast channels - if (fhss_check_channel_type(fhss_structure, is_broadcast_addr, frame_type) == false) { - return false; - } - - // This condition will check that FHSS is on TX slot and there is enough time to transmit before channel or slot change - if (fhss_check_tx_allowed(fhss_structure, is_broadcast_addr, frame_length, frame_type, phy_header_length, phy_tail_length) == false) { - return false; - } - - return true; -} - -void fhss_receive_frame_cb(const fhss_api_t *api, uint16_t pan_id, uint8_t *source_address, uint32_t timestamp, uint8_t *synch_info, int frame_type) -{ - fhss_structure_t *fhss_structure = fhss_get_object_with_api(api); - if (!fhss_structure) { - return; - } - if (FHSS_SYNCH_FRAME == frame_type) { - if ((fhss_structure->fhss_state == FHSS_UNSYNCHRONIZED) || fhss_structure->synch_panid != pan_id) { - fhss_add_beacon_info(fhss_structure, pan_id, source_address, timestamp, synch_info); - } else { - if (!fhss_compare_with_synch_parent_address(fhss_structure, source_address)) { - // Synch parent address needs to be updated in case parent has changed - fhss_update_synch_parent_address(fhss_structure); - platform_enter_critical(); - // Calculate time since the Beacon was received - uint32_t elapsed_time = api->read_timestamp(api) - timestamp; - // Synchronize to given PAN - fhss_beacon_received(fhss_structure, synch_info, elapsed_time); - platform_exit_critical(); - } - } - } else if (FHSS_SYNCH_REQUEST_FRAME == frame_type) { - // If current channel is broadcast, we don't need to send another synch info on next broadcast channel. - // Only send number of MAX_SYNCH_INFOS_PER_CHANNEL_LIST synch infos per one channel list cycle - if ((fhss_structure->fhss_state == FHSS_SYNCHRONIZED) && (fhss_is_current_channel_broadcast(fhss_structure) == false) - && (fhss_structure->synch_infos_sent_counter < MAX_SYNCH_INFOS_PER_CHANNEL_LIST)) { - fhss_structure->send_synch_info_on_next_broadcast_channel = true; - } - } -} - -void fhss_data_tx_done_cb(const fhss_api_t *api, bool waiting_ack, bool tx_completed, uint8_t handle) -{ - fhss_structure_t *fhss_structure = fhss_get_object_with_api(api); - if (!fhss_structure) { - return; - } - if (waiting_ack == false) { - fhss_change_to_rx_channel(fhss_structure); - } - // Buffer was successfully transmitted. Remove stored failure handle if exists. - if (tx_completed == true) { - fhss_failed_tx_t *fhss_failed_tx = fhss_failed_handle_find(fhss_structure, handle); - if (fhss_failed_tx) { - fhss_failed_handle_remove(fhss_structure, handle); - } - } -} - -bool fhss_data_tx_fail_cb(const fhss_api_t *api, uint8_t handle, int frame_type) -{ - fhss_structure_t *fhss_structure = fhss_get_object_with_api(api); - if (!fhss_structure) { - return false; - } - // Only use channel retries when device is synchronized - if (fhss_structure->fhss_state == FHSS_UNSYNCHRONIZED) { - return false; - } - // Channel retries are disabled -> return - if (fhss_structure->fhss_configuration.fhss_number_of_channel_retries == 0) { - return false; - } - // Use channel retries only for data frames - if (FHSS_DATA_FRAME != frame_type) { - return false; - } - - fhss_failed_tx_t *fhss_failed_tx = fhss_failed_handle_find(fhss_structure, handle); - if (fhss_failed_tx) { - fhss_failed_tx->retries_done++; - if (fhss_failed_tx->retries_done >= fhss_structure->fhss_configuration.fhss_number_of_channel_retries) { - // No more retries. Return false to stop retransmitting. - fhss_failed_handle_remove(fhss_structure, handle); - return false; - } - } else { - // Create new failure handle and return true to retransmit - fhss_failed_handle_add(fhss_structure, handle); - } - return true; -} - -void fhss_synch_state_set_cb(const fhss_api_t *api, fhss_states fhss_state, uint16_t pan_id) -{ - fhss_structure_t *fhss_structure = fhss_get_object_with_api(api); - if (!fhss_structure) { - return; - } - - // State is already set - if (fhss_structure->fhss_state == fhss_state) { - tr_debug("Synch same state %u", fhss_state); - return; - } - - if (fhss_state == FHSS_UNSYNCHRONIZED) { - tr_debug("FHSS down"); - fhss_down(fhss_structure); - } else { - // Do not synchronize to current pan - if (fhss_structure->synch_panid == pan_id) { - tr_debug("Synch same panid %u", pan_id); - return; - } - uint32_t datarate = fhss_structure->callbacks.read_datarate(api); - fhss_set_datarate(fhss_structure, datarate); - uint8_t mac_address[8]; - fhss_structure->callbacks.read_mac_address(fhss_structure->fhss_api, mac_address); - fhss_structure->uc_channel_index = fhss_get_offset(fhss_structure, mac_address); - // Get Beacon info from storage - fhss_beacon_info_t *beacon_info = fhss_get_beacon_info(fhss_structure, pan_id); - if (beacon_info) { - memcpy(fhss_structure->synch_parent, beacon_info->source_address, 8); - platform_enter_critical(); - // Calculate time since the Beacon was received - uint32_t elapsed_time = api->read_timestamp(api) - beacon_info->timestamp; - // Synchronize to given PAN - fhss_beacon_received(fhss_structure, beacon_info->synch_info, elapsed_time); - platform_exit_critical(); - // Delete stored Beacon infos - fhss_flush_beacon_info_storage(fhss_structure); - fhss_structure->synch_panid = pan_id; - } else if (fhss_is_synch_root(fhss_structure) == true) { - // Synch root will start new network - fhss_start_timer(fhss_structure, fhss_structure->synch_configuration.fhss_superframe_length, fhss_superframe_handler); - } else { - tr_error("Synch info not find"); - } - } - fhss_structure->fhss_state = fhss_state; -} - -uint32_t fhss_read_timestamp_cb(const fhss_api_t *api) -{ - fhss_structure_t *fhss_structure = fhss_get_object_with_api(api); - if (!fhss_structure) { - return 0; - } - return (fhss_structure->platform_functions.fhss_get_timestamp(api) * fhss_structure->platform_functions.fhss_resolution_divider); -} - -uint16_t fhss_get_retry_period_cb(const fhss_api_t *api, uint8_t *destination_address, uint16_t phy_mtu) -{ - uint16_t retry_period = 0; - uint16_t random_number = randLIB_get_16bit(); - uint16_t rnd_mask; - - /* Generate retry back-off period. FHSS is using the known synchronization parent info to delay retransmissions upstream. - * - */ - if (phy_mtu < 128) { - // Max. random when PHY MTU below 128 is 6.4ms - rnd_mask = 0x7f; - } else if (phy_mtu < 256) { - // Max. random when PHY MTU below 256 is 12.8ms - rnd_mask = 0xff; - } else { - // Max. random when PHY MTU above 255 is 25.6ms - rnd_mask = 0x1ff; - } - - fhss_structure_t *fhss_structure = fhss_get_object_with_api(api); - if (fhss_structure) { - uint32_t datarate = fhss_structure->datarate; - uint16_t max_tx_length; - - if (datarate && phy_mtu) { - if (fhss_compare_with_synch_parent_address(fhss_structure, destination_address) == 0) { - // E.g. (1000000 / (250000bit/s / 8 bits)) * 255 bytes = 8160us - max_tx_length = ((1000000 / (datarate / 8)) * phy_mtu); - /* Retrying upstream: delay the transmission until assumed hidden node has retried downstream: - * Static period: max random + max tx length - * 50 comes from MAC timer resolution (50us) - */ - retry_period = (rnd_mask + (max_tx_length / 50)); - } - } - } - - // Add 1 to not to ever return zero value. - retry_period += ((random_number & rnd_mask) + 1); - return retry_period; -} - -int fhss_init_callbacks_cb(const fhss_api_t *api, fhss_callback_t *callbacks) -{ - fhss_structure_t *fhss_structure = fhss_get_object_with_api(api); - if (!fhss_structure || !callbacks) { - return -1; - } - fhss_structure->callbacks = *callbacks; - return 0; -} diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_mac_interface.h b/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_mac_interface.h deleted file mode 100644 index 22f63fcded8d..000000000000 --- a/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_mac_interface.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2016-2017, Arm Limited and affiliates. - * 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 FHSS_MAC_INTERFACE_H_ -#define FHSS_MAC_INTERFACE_H_ - -bool fhss_is_broadcast_channel_cb(const fhss_api_t *api); -bool fhss_use_broadcast_queue_cb(const fhss_api_t *api, bool is_broadcast_addr, int frame_type); -int fhss_tx_handle_cb(const fhss_api_t *api, bool is_broadcast_addr, uint8_t *destination_address, int frame_type, uint8_t *synch_info, uint16_t frame_length, uint8_t phy_header_length, uint8_t phy_tail_length); -bool fhss_check_tx_conditions_cb(const fhss_api_t *api, bool is_broadcast_addr, uint8_t handle, int frame_type, uint16_t frame_length, uint8_t phy_header_length, uint8_t phy_tail_length); -void fhss_receive_frame_cb(const fhss_api_t *api, uint16_t pan_id, uint8_t *source_address, uint32_t timestamp, uint8_t *synch_info, int frame_type); -void fhss_data_tx_done_cb(const fhss_api_t *api, bool waiting_ack, bool tx_completed, uint8_t handle); -bool fhss_data_tx_fail_cb(const fhss_api_t *api, uint8_t handle, int frame_type); -void fhss_synch_state_set_cb(const fhss_api_t *api, fhss_states fhss_state, uint16_t pan_id); -uint32_t fhss_read_timestamp_cb(const fhss_api_t *api); -uint16_t fhss_get_retry_period_cb(const fhss_api_t *api, uint8_t *destination_address, uint16_t phy_mtu); -int fhss_init_callbacks_cb(const fhss_api_t *api, fhss_callback_t *callbacks); - -#endif /* FHSS_MAC_INTERFACE_H_ */ diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_statistics.c b/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_statistics.c index 872298237617..2ab1702ed512 100644 --- a/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_statistics.c +++ b/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_statistics.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Arm Limited and affiliates. + * Copyright (c) 2017-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,26 +19,27 @@ #include "fhss_api.h" #include "fhss_config.h" #include "fhss.h" +#include "fhss_common.h" #include "fhss_statistics.h" void fhss_stats_update(fhss_structure_t *fhss_structure, fhss_stats_type_t type, uint32_t update_val) { - if (fhss_structure->fhss_stats_ptr) { + if (fhss_structure->bs->fhss_stats_ptr) { switch (type) { case STATS_FHSS_DRIFT_COMP: - fhss_structure->fhss_stats_ptr->fhss_drift_compensation = update_val; + fhss_structure->bs->fhss_stats_ptr->fhss_drift_compensation = update_val; break; case STATS_FHSS_HOP_COUNT: - fhss_structure->fhss_stats_ptr->fhss_hop_count = update_val; + fhss_structure->bs->fhss_stats_ptr->fhss_hop_count = update_val; break; case STATS_FHSS_SYNCH_INTERVAL: - fhss_structure->fhss_stats_ptr->fhss_synch_interval = update_val; + fhss_structure->bs->fhss_stats_ptr->fhss_synch_interval = update_val; break; case STATS_FHSS_AVG_SYNCH_FIX: - fhss_structure->fhss_stats_ptr->fhss_prev_avg_synch_fix = update_val; + fhss_structure->bs->fhss_stats_ptr->fhss_prev_avg_synch_fix = update_val; break; case STATS_FHSS_SYNCH_LOST: - fhss_structure->fhss_stats_ptr->fhss_synch_lost += update_val; + fhss_structure->bs->fhss_stats_ptr->fhss_synch_lost += update_val; break; } } diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_ws.h b/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_ws.h new file mode 100644 index 000000000000..03befff9f8fd --- /dev/null +++ b/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_ws.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2018, Arm Limited and affiliates. + * 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 FHSS_WS_H_ +#define FHSS_WS_H_ + +/* WS requires at least 19 MAC retransmissions (total 1+19=20 attempts). 802.15.4 macMaxFrameRetries is 3 (total 1+3=4 attempts). + * At least 4 channel retries must be used: (Initial channel + WS_NUMBER_OF_CHANNEL_RETRIES) * MAC attempts = (1+4)*4=20 attempts + */ +#define WS_NUMBER_OF_CHANNEL_RETRIES 4 +//TX/RX slot length in milliseconds +#define WS_MAX_TXRX_SLOT_LEN_MS 100 +typedef struct fhss_ws fhss_ws_t; + +struct fhss_ws +{ + uint8_t bc_channel; + uint16_t uc_slot; + uint16_t bc_slot; + bool is_on_bc_channel; + struct fhss_ws_configuration fhss_configuration; + const struct broadcast_timing_info *parent_bc_info; + fhss_get_neighbor_info *get_neighbor_info; +}; + +fhss_structure_t *fhss_ws_enable(fhss_api_t *fhss_api, const fhss_ws_configuration_t *fhss_configuration, const fhss_timer_t *fhss_timer); +int fhss_ws_set_callbacks(fhss_structure_t *fhss_structure); +int fhss_ws_set_parent(fhss_structure_t *fhss_structure, const uint8_t eui64[8], const broadcast_timing_info_t *bc_timing_info); +int fhss_ws_remove_parent(fhss_structure_t *fhss_structure, const uint8_t eui64[8]); +int fhss_ws_configuration_set(fhss_structure_t *fhss_structure, const fhss_ws_configuration_t *fhss_configuration); +int fhss_ws_set_hop_count(fhss_structure_t *fhss_structure, const uint8_t hop_count); + +#endif /*FHSS_WS_H_*/ diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_ws_empty_functions.c b/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_ws_empty_functions.c new file mode 100644 index 000000000000..df6bc4813cfc --- /dev/null +++ b/features/nanostack/sal-stack-nanostack/source/Service_Libs/fhss/fhss_ws_empty_functions.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2018, Arm Limited and affiliates. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "nsconfig.h" +#include "ns_types.h" +#include "fhss_api.h" +#include "fhss_config.h" +#include "fhss.h" +#include "fhss_common.h" +#include "channel_list.h" +#include "channel_functions.h" +#include "fhss_ws.h" +#include "nsdynmemLIB.h" +#include "common_functions.h" +#include "eventOS_callback_timer.h" +#include "randLIB.h" +#include + +#ifndef HAVE_WS + +fhss_structure_t *fhss_ws_enable(fhss_api_t *fhss_api, const fhss_ws_configuration_t *fhss_configuration, const fhss_timer_t *fhss_timer) +{ + (void) fhss_api; + (void) fhss_configuration; + (void) fhss_timer; + + return NULL; +} + +int fhss_ws_set_callbacks(fhss_structure_t *fhss_structure) +{ + (void) fhss_structure; + return -1; +} + +int fhss_ws_set_parent(fhss_structure_t *fhss_structure, const uint8_t eui64[8], const broadcast_timing_info_t *bc_timing_info) +{ + (void) fhss_structure; + (void) eui64; + (void) bc_timing_info; + + return -1; +} + +int fhss_ws_remove_parent(fhss_structure_t *fhss_structure, const uint8_t eui64[8]) +{ + (void) fhss_structure; + (void) eui64; + + return -1; +} + +int fhss_ws_configuration_set(fhss_structure_t *fhss_structure, const fhss_ws_configuration_t *fhss_configuration) +{ + (void) fhss_structure; + (void) fhss_configuration; + + return -1; +} + +int fhss_ws_set_hop_count(fhss_structure_t *fhss_structure, const uint8_t hop_count) +{ + (void) fhss_structure; + (void) hop_count; + + return -1; +} + +#endif // HAVE_WS + diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/mac_neighbor_table/mac_neighbor_table.c b/features/nanostack/sal-stack-nanostack/source/Service_Libs/mac_neighbor_table/mac_neighbor_table.c new file mode 100644 index 000000000000..6b1e548212c6 --- /dev/null +++ b/features/nanostack/sal-stack-nanostack/source/Service_Libs/mac_neighbor_table/mac_neighbor_table.c @@ -0,0 +1,274 @@ +/* + * Copyright (c) 2018, Arm Limited and affiliates. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include "nsconfig.h" +#include "string.h" +#include "ns_types.h" +#include "ns_trace.h" +#include "common_functions.h" +#include "nsdynmemLIB.h" +#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h" +#include "Core/include/address.h" +#include "platform/topo_trace.h" + +#define TRACE_GROUP "mnei" + +mac_neighbor_table_t *mac_neighbor_table_create(uint8_t table_size, neighbor_entry_remove_notify *remove_cb, neighbor_entry_nud_notify *nud_cb, void *user_indentifier) +{ + mac_neighbor_table_t *table_class = ns_dyn_mem_alloc(sizeof(mac_neighbor_table_t) + sizeof(mac_neighbor_table_entry_t) * table_size); + if (!table_class) { + return NULL; + } + memset(table_class, 0, sizeof(mac_neighbor_table_t)); + + mac_neighbor_table_entry_t *cur_ptr = &table_class->neighbor_entry_buffer[0]; + table_class->list_total_size = table_size; + table_class->table_user_identifier = user_indentifier; + table_class->user_nud_notify_cb = nud_cb; + table_class->user_remove_notify_cb = remove_cb; + ns_list_init(&table_class->neighbour_list); + ns_list_init(&table_class->free_list); + for (uint8_t i = 0; i< table_size; i++) { + memset(cur_ptr, 0, sizeof(mac_neighbor_table_entry_t)); + cur_ptr->index = i; + //Add to list + ns_list_add_to_end(&table_class->free_list,cur_ptr); + cur_ptr++; + } + + return table_class; + +} + +void mac_neighbor_table_delete(mac_neighbor_table_t *table_class) +{ + mac_neighbor_table_neighbor_list_clean(table_class); + ns_dyn_mem_free(table_class); +} + +static void neighbor_table_class_remove_entry(mac_neighbor_table_t *table_class, mac_neighbor_table_entry_t *entry) +{ + ns_list_remove(&table_class->neighbour_list, entry); + table_class->neighbour_list_size--; + if (entry->nud_active) { + entry->nud_active = false; + table_class->active_nud_process--; + } + + if (table_class->user_remove_notify_cb) { + table_class->user_remove_notify_cb(entry, table_class->table_user_identifier); + } + topo_trace(TOPOLOGY_MLE, entry->mac64, TOPO_REMOVE); + + + uint8_t index = entry->index; + memset(entry, 0, sizeof(mac_neighbor_table_entry_t)); + entry->index = index; + ns_list_add_to_end(&table_class->free_list,entry); +} + +void mac_neighbor_table_neighbor_list_clean(mac_neighbor_table_t *table_class) +{ + if (!table_class) { + return; + } + ns_list_foreach_safe(mac_neighbor_table_entry_t, cur, &table_class->neighbour_list) { + neighbor_table_class_remove_entry(table_class, cur); + } + topo_trace(TOPOLOGY_MLE, NULL, TOPO_CLEAR); +} + + +void mac_neighbor_table_neighbor_timeout_update(mac_neighbor_table_t *table_class, uint32_t time_update) +{ + if (!table_class) { + return; + } + + ns_list_foreach_safe(mac_neighbor_table_entry_t, cur, &table_class->neighbour_list) { + + if (cur->lifetime > time_update) { + cur->lifetime -= time_update; + if (!table_class->user_nud_notify_cb || table_class->active_nud_process > ACTIVE_NUD_PROCESS_MAX || cur->nud_active || !cur->rx_on_idle) { + continue; + } + + if (table_class->user_nud_notify_cb(cur, table_class->table_user_identifier)) { + table_class->active_nud_process++; + cur->nud_active = true; + tr_debug("Nud started index %u : %"PRIu32" time ", cur->index, cur->lifetime); + } + + } else { + tr_debug("Node index %u time out ", cur->index); + neighbor_table_class_remove_entry(table_class, cur); + } + } +} + + +mac_neighbor_table_entry_t *mac_neighbor_table_entry_allocate(mac_neighbor_table_t *table_class, const uint8_t *mac64) +{ + if (!table_class) { + return NULL; + } + mac_neighbor_table_entry_t *entry = ns_list_get_first(&table_class->free_list); + if (!entry) { + return NULL; + } + //Remove from the list + ns_list_remove(&table_class->free_list, entry); + //Add to list + ns_list_add_to_end(&table_class->neighbour_list,entry); + table_class->neighbour_list_size++; + memcpy(entry->mac64, mac64, 8); + entry->mac16 = 0xffff; + entry->rx_on_idle = true; + entry->ffd_device = true; + entry->nud_active = false; + entry->advertisment = false; + entry->connected_device = false; + entry->trusted_device = false; + entry->lifetime = NEIGHBOR_CLASS_LINK_DEFAULT_LIFETIME; + entry->link_lifetime = NEIGHBOR_CLASS_LINK_DEFAULT_LIFETIME; + entry->link_role = NORMAL_NEIGHBOUR; + topo_trace(TOPOLOGY_MLE, mac64, TOPO_ADD); + return entry; +} + +static mac_neighbor_table_entry_t *neighbor_table_class_entry_validate(mac_neighbor_table_t *table_class, mac_neighbor_table_entry_t *neighbor_entry) +{ + ns_list_foreach(mac_neighbor_table_entry_t, cur, &table_class->neighbour_list) { + if (cur == neighbor_entry) { + return cur; + } + } + return NULL; + +} + +void mac_neighbor_table_neighbor_remove(mac_neighbor_table_t *table_class, mac_neighbor_table_entry_t *neighbor_entry) +{ + mac_neighbor_table_entry_t *entry = neighbor_table_class_entry_validate(table_class, neighbor_entry); + if (entry) { + neighbor_table_class_remove_entry(table_class, entry); + } +} + + +void mac_neighbor_table_neighbor_refresh(mac_neighbor_table_t *table_class, mac_neighbor_table_entry_t *neighbor_entry, uint32_t life_time) +{ + neighbor_entry->lifetime = life_time; + neighbor_entry->link_lifetime = life_time; + if (neighbor_entry->nud_active) { + tr_debug("Node index NUD response %u : %"PRIu32" time ", neighbor_entry->index, neighbor_entry->lifetime); + neighbor_entry->nud_active = false; + table_class->active_nud_process--; + } + +} + +void mac_neighbor_table_neighbor_connected(mac_neighbor_table_t *table_class, mac_neighbor_table_entry_t *neighbor_entry) +{ + (void)table_class; + neighbor_entry->connected_device = true; +} + +void mac_neighbor_table_trusted_neighbor(mac_neighbor_table_t *table_class, mac_neighbor_table_entry_t *neighbor_entry, bool trusted_device) +{ + (void)table_class; + neighbor_entry->trusted_device = trusted_device; +} + +mac_neighbor_table_entry_t *mac_neighbor_table_address_discover(mac_neighbor_table_t *table_class, const uint8_t *address, uint8_t address_type) +{ + if (!table_class) { + return NULL; + } + uint16_t short_address; + if (address_type == ADDR_802_15_4_SHORT) { + short_address = common_read_16_bit(address); + } else if (address_type == ADDR_802_15_4_LONG) { + + } else { + return NULL; + } + + ns_list_foreach(mac_neighbor_table_entry_t, cur, &table_class->neighbour_list) { + if (address_type == ADDR_802_15_4_SHORT) { + if (cur->mac16 != 0xffff && cur->mac16 == short_address) { + return cur; + } + } else { + if (memcmp(cur->mac64, address, 8) == 0) { + return cur; + } + } + } + + return NULL; +} + +mac_neighbor_table_entry_t *mac_neighbor_table_attribute_discover(mac_neighbor_table_t *table_class, uint8_t index) +{ + ns_list_foreach(mac_neighbor_table_entry_t, cur, &table_class->neighbour_list) { + + if (cur->index == index) { + return cur; + } + } + return NULL; +} + +mac_neighbor_table_entry_t *mac_neighbor_entry_get_by_ll64(mac_neighbor_table_t *table_class, const uint8_t *ipv6Address, bool allocateNew, bool *new_entry_allocated) +{ + // Check it really is LL64 (not LL16) + if (memcmp(ipv6Address, ADDR_LINK_LOCAL_PREFIX , 8) != 0) { + return NULL; //Mot Link Local Address + } + + if (memcmp((ipv6Address + 8), ADDR_SHORT_ADR_SUFFIC , 6) == 0) { + return NULL; + } + // map + uint8_t temporary_mac64[8]; + memcpy(temporary_mac64, (ipv6Address + 8), 8); + temporary_mac64[0] ^= 2; + + return mac_neighbor_entry_get_by_mac64(table_class, temporary_mac64, allocateNew, new_entry_allocated); + +} + +mac_neighbor_table_entry_t *mac_neighbor_entry_get_by_mac64(mac_neighbor_table_t *table_class, const uint8_t *mac64, bool allocateNew, bool *new_entry_allocated) +{ + mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(table_class, mac64, ADDR_802_15_4_LONG); + if (entry || !allocateNew) { + if (new_entry_allocated) { + *new_entry_allocated = false; + } + return entry; + } + + if (new_entry_allocated) { + *new_entry_allocated = true; + } + + return mac_neighbor_table_entry_allocate(table_class, mac64); +} + + diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/mac_neighbor_table/mac_neighbor_table.h b/features/nanostack/sal-stack-nanostack/source/Service_Libs/mac_neighbor_table/mac_neighbor_table.h new file mode 100644 index 000000000000..edd10a974d96 --- /dev/null +++ b/features/nanostack/sal-stack-nanostack/source/Service_Libs/mac_neighbor_table/mac_neighbor_table.h @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2018, Arm Limited and affiliates. + * 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 MAC_NEIGHBOR_TABLE_H_ +#define MAC_NEIGHBOR_TABLE_H_ + +#include "ns_types.h" +#include "ns_list.h" + +#define NEIGHBOR_CLASS_LINK_DEFAULT_LIFETIME 240 + +#define ACTIVE_NUD_PROCESS_MAX 3 //Limit That how many activate NUD process is active in same time + +#define NORMAL_NEIGHBOUR 0 +#define SECONDARY_PARENT_NEIGHBOUR 1 +#define CHILD_NEIGHBOUR 2 +#define PRIORITY_PARENT_NEIGHBOUR 3 +/** + * Generic Neighbor table entry + */ +typedef struct mac_neighbor_table_entry { + uint8_t index; /*!< Unique Neighbour index */ + uint8_t mac64[8]; /*!< MAC64 */ + uint16_t mac16; /*!< MAC16 address for neighbor 0xffff when no 16-bit address is unknown */ + uint32_t lifetime; /*!< Life time in seconds which goes down */ + uint32_t link_lifetime; /*!< Configured link timeout*/ + bool rx_on_idle:1; /*!< True, RX on idle allways at idle state, false disable radio */ + bool ffd_device:1; /*!< True FFD device, false for RFD */ + bool advertisment:1; + bool connected_device:1; /*!< True Link is connected and data rx is accepted , False RX data is not accepted*/ + bool trusted_device:1; /*!< True mean use normal group key, false for enable pairwise key */ + bool nud_active:1; /*!< True Neighbor NUD process is active, false not active process */ + unsigned link_role:2; /*!< Link role: NORMAL_NEIGHBOUR, PRIORITY_PARENT_NEIGHBOUR, SECONDARY_PARENT_NEIGHBOUR, CHILD_NEIGHBOUR */ + ns_list_link_t link; +} mac_neighbor_table_entry_t; + +typedef NS_LIST_HEAD(mac_neighbor_table_entry_t, link) mac_neighbor_table_list_t; + +#define mac_neighbor_info(interface) ((interface)->mac_parameters->mac_neighbor_table) /*!< Helper macro for give mac neighbor class pointer from interface pointer. */ + +/** + * Remove entry notify + * + * \param entry_ptr Pointer to removed entry + * \param user_data pointer for user to detect interface + */ +typedef void neighbor_entry_remove_notify(mac_neighbor_table_entry_t *entry_ptr, void *user_data); + + +/** + * NUD entry notify + * + * \param entry_ptr Pointer to neighbor entry + * \param user_data pointer for user to detect interface + * + * \return true NUD message generated + * \return false When NUD is not generated + */ +typedef bool neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr, void *user_data); + +/** + * Neighbor table class structure + */ +typedef struct mac_neighbor_table_class { + mac_neighbor_table_list_t neighbour_list; /*!< List of active neighbors */ + mac_neighbor_table_list_t free_list; /*!< List of free neighbors entries */ + uint32_t nud_threshold; /*!< NUD threshold time which generates keep alive message */ + uint8_t list_total_size; /*!< Total number allocated neighbor entries */ + uint8_t active_nud_process; /*!< Indicate Active NUD Process */ + uint8_t neighbour_list_size; /*!< Active Neighbor list size */ + void *table_user_identifier; /*!< Table user identifier like interface pointer */ + neighbor_entry_remove_notify *user_remove_notify_cb; /*!< Neighbor Remove Callback notify */ + neighbor_entry_nud_notify *user_nud_notify_cb; /*!< Trig NUD process for neighbor */ + mac_neighbor_table_entry_t neighbor_entry_buffer[]; /*!< Pointer for allocated neighbor table entries*/ +} mac_neighbor_table_t; + + +/** + * \brief mac_neighbor_table_create Allocate Neighbour table class + * + * Call this only one's for interface + * + * \param table_size size of neighbor table + * \param remove_cb callback pointer for notify removed neighbor + * \param nud_cb Interface NUD operation trgger callback + * \param user_indentifier user identifier pointer like interface pointer + * + * \return pointer to neighbor table class when create is OK + * \return NULL when memory allocation happen + * + */ +mac_neighbor_table_t *mac_neighbor_table_create(uint8_t table_size, neighbor_entry_remove_notify *remove_cb, neighbor_entry_nud_notify *nud_cb, void *user_indentifier); + +/** + * mac_neighbor_table_delete Delete Neigbor table class + * + * \param table_class neighbor table class + */ +void mac_neighbor_table_delete(mac_neighbor_table_t *table_class); + +/** + * mac_neighbor_table_neighbor_list_clean Clean neighbour_list from giving class + */ +void mac_neighbor_table_neighbor_list_clean(mac_neighbor_table_t *table_class); + +/** + * mac_neighbor_table_neighbor_timeout_update Update Neighbor table timeout values + * + * \param table_class pointer to table class + * \param time_update in seconds + * + */ +void mac_neighbor_table_neighbor_timeout_update(mac_neighbor_table_t *table_class, uint32_t time_update); + + +/** + * mac_neighbor_table_entry_allocate Allocate Neighbour table class entry + * + * \param table_class pointer to table class + * \param mac64 neighbor 64-bit mac address + * + * \return NULL allocate fail + * \return pointer to allocated neighbor table entry + */ +mac_neighbor_table_entry_t *mac_neighbor_table_entry_allocate(mac_neighbor_table_t *table_class, const uint8_t *mac64); + +/** + * mac_neighbor_table_neighbor_remove Remove neighbor from list + * + * \param table_class pointer to table class + * \param neighbor_entry pointer to removed entry + * + */ +void mac_neighbor_table_neighbor_remove(mac_neighbor_table_t *table_class, mac_neighbor_table_entry_t *neighbor_entry); + +/** + * mac_neighbor_table_neighbor_refresh Refresh neigbor timeout and time to live values based on giving time + * + * \param table_class pointer to table class + * \param neighbor_entry pointer to refreshed entry + * \param life_time define lifetime for neighbor + */ +void mac_neighbor_table_neighbor_refresh(mac_neighbor_table_t *table_class, mac_neighbor_table_entry_t *neighbor_entry, uint32_t life_time); + +/** + * mac_neighbor_table_neighbor_connected Mark neighbour connected state and data is accepted from device + * + * Call this function when node is trusted connected + * + * \param table_class pointer to table class + * \param neighbor_entry pointer to refreshed entry + */ +void mac_neighbor_table_neighbor_connected(mac_neighbor_table_t *table_class, mac_neighbor_table_entry_t *neighbor_entry); + +/** + * mac_neighbor_table_trusted_neighbor Function for manage neighbor role at mesh network + * + * Call this function when node is trusted connected + * + * \param table_class pointer to table class + * \param neighbor_entry pointer to refreshed entry + * \param trusted_device True neigbor is part of mesh and will use group key , false enable pairwose key + */ +void mac_neighbor_table_trusted_neighbor(mac_neighbor_table_t *table_class, mac_neighbor_table_entry_t *neighbor_entry, bool trusted_device); + +/** + * mac_neighbor_table_address_discover Discover neighbor from list by address + * + * \param table_class pointer to table class + * \param address pointer to 16-bit MAC or 64-bit address for discover + * \param address_type 2 for 16-bit address and 3 for 64-bit (same than 802.15.4 define) + * + * \return pointer to discover neighbor entry if it exist + */ +mac_neighbor_table_entry_t *mac_neighbor_table_address_discover(mac_neighbor_table_t *table_class, const uint8_t *address, uint8_t address_type); + +/** + * mac_neighbor_table_attribute_discover Discover neighbor from list by attribute index + * + * \param table_class pointer to table class + * \param index neighbor index + * + * \return pointer to discover neighbor entry if it exist + */ +mac_neighbor_table_entry_t *mac_neighbor_table_attribute_discover(mac_neighbor_table_t *table_class, uint8_t index); + +mac_neighbor_table_entry_t *mac_neighbor_entry_get_by_ll64(mac_neighbor_table_t *table_class, const uint8_t *ipv6Address, bool allocateNew, bool *new_entry_allocated); + +mac_neighbor_table_entry_t *mac_neighbor_entry_get_by_mac64(mac_neighbor_table_t *table_class, const uint8_t *mac64, bool allocateNew, bool *new_entry_allocated); + +#endif /* MAC_NEIGHBOR_TABLE_H_ */ diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/mdns/ns_fnet_port.c b/features/nanostack/sal-stack-nanostack/source/Service_Libs/mdns/ns_fnet_port.c index e2cce7555c27..63e904b1911c 100644 --- a/features/nanostack/sal-stack-nanostack/source/Service_Libs/mdns/ns_fnet_port.c +++ b/features/nanostack/sal-stack-nanostack/source/Service_Libs/mdns/ns_fnet_port.c @@ -131,7 +131,7 @@ fnet_socket_t fnet_socket(fnet_address_family_t family, fnet_socket_type_t type, fnet_return_t fnet_socket_bind( fnet_socket_t s, const struct sockaddr *name, fnet_size_t namelen ) { (void)namelen; - ns_address_t ns_source_addr = {0}; + ns_address_t ns_source_addr; int8_t socket_id = (int8_t)(long)s; fnet_return_t fnet_ret_val = FNET_ERR; const struct sockaddr_in6 *namein6 = (const struct sockaddr_in6 *) name; diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/mle_service/mle_service.c b/features/nanostack/sal-stack-nanostack/source/Service_Libs/mle_service/mle_service.c index 45c5c081d3e8..459cd283aba4 100644 --- a/features/nanostack/sal-stack-nanostack/source/Service_Libs/mle_service/mle_service.c +++ b/features/nanostack/sal-stack-nanostack/source/Service_Libs/mle_service/mle_service.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -35,6 +35,7 @@ #include "Service_Libs/mle_service/mle_service_security.h" #include "Service_Libs/mle_service/mle_service_buffer.h" #include "Service_Libs/mle_service/mle_service_interface.h" +#include "Service_Libs/mle_service/mle_service_frame_counter_table.h" #include "MLE/mle.h" #include "MLE/mle_tlv.h" #include "mac_common_defines.h" @@ -413,39 +414,39 @@ static void mle_service_a_data_set(uint8_t *ptr, uint8_t *src_address, uint8_t * static buffer_t *mle_service_message_security_decode(buffer_t *buf, mle_security_header_t *securityHeader, uint8_t *security_key) { - ccm_globals_t *ccm_ptr; + ccm_globals_t ccm_ptr; uint16_t payload_len = buffer_data_length(buf); - ccm_ptr = ccm_sec_init(securityHeader->securityLevel, security_key, AES_CCM_DECRYPT, 2); - if (!ccm_ptr) { + if (!ccm_sec_init(&ccm_ptr, securityHeader->securityLevel, security_key, AES_CCM_DECRYPT, 2)) { return buffer_free(buf); - } else if (ccm_ptr->mic_len >= payload_len) { + } else if (ccm_ptr.mic_len >= payload_len) { + ccm_free(&ccm_ptr); return buffer_free(buf); } //SET Nonce buf->src_sa.address[8] ^= 2; - mle_security_aux_ccm_nonce_set(ccm_ptr->exp_nonce, &(buf->src_sa.address[8]), + mle_security_aux_ccm_nonce_set(ccm_ptr.exp_nonce, &(buf->src_sa.address[8]), securityHeader->frameCounter, securityHeader->securityLevel); buf->src_sa.address[8] ^= 2; - if (ccm_ptr->mic_len) { - payload_len -= ccm_ptr->mic_len; - buf->buf_end -= ccm_ptr->mic_len; + if (ccm_ptr.mic_len) { + payload_len -= ccm_ptr.mic_len; + buf->buf_end -= ccm_ptr.mic_len; - ccm_ptr->data_ptr = buffer_data_pointer(buf); - ccm_ptr->adata_ptr = mle_service->mle_adata; - ccm_ptr->data_len = payload_len; - ccm_ptr->adata_len = mle_service->mle_adata_length; + ccm_ptr.data_ptr = buffer_data_pointer(buf); + ccm_ptr.adata_ptr = mle_service->mle_adata; + ccm_ptr.data_len = payload_len; + ccm_ptr.adata_len = mle_service->mle_adata_length; //SET MIC - ccm_ptr->mic = ccm_ptr->data_ptr; - ccm_ptr->mic += payload_len; + ccm_ptr.mic = ccm_ptr.data_ptr; + ccm_ptr.mic += payload_len; } else { - ccm_ptr->data_len = payload_len; - ccm_ptr->data_ptr = buffer_data_pointer(buf); + ccm_ptr.data_len = payload_len; + ccm_ptr.data_ptr = buffer_data_pointer(buf); } - if (ccm_process_run(ccm_ptr) != 0) { + if (ccm_process_run(&ccm_ptr) != 0) { tr_error("MLE mic fail!"); buf = buffer_free(buf); } @@ -459,7 +460,7 @@ static buffer_t *mle_message_security_header_set(buffer_t *buf,service_instance_ //Verify first security level if (security_header->securityLevel) { //Get Security keys - ccm_globals_t *ccm_ptr; + ccm_globals_t ccm_ptr; uint16_t header_size; uint16_t data_len; data_len = buffer_data_length(buf); @@ -468,58 +469,58 @@ static buffer_t *mle_message_security_header_set(buffer_t *buf,service_instance_ goto drop_buffer; } // Init - ccm_ptr = ccm_sec_init(security_header->securityLevel, ptr, AES_CCM_ENCRYPT, 2); - if (!ccm_ptr) { + if (!ccm_sec_init(&ccm_ptr, security_header->securityLevel, ptr, AES_CCM_ENCRYPT, 2)) { goto drop_buffer; } - header_size = mle_security_aux_header_size(security_header->KeyIdMode); //SET Nonce - mle_security_aux_ccm_nonce_set(ccm_ptr->exp_nonce, srv_ptr->mac64, security_header->frameCounter, security_header->securityLevel); - if (ccm_ptr->mic_len) { - buf = buffer_headroom(buf, (ccm_ptr->mic_len + 32 + header_size)); + mle_security_aux_ccm_nonce_set(ccm_ptr.exp_nonce, srv_ptr->mac64, security_header->frameCounter, security_header->securityLevel); + if (ccm_ptr.mic_len) { + buf = buffer_headroom(buf, (ccm_ptr.mic_len + 32 + header_size)); if (buf) { uint8_t *ptr2; //Move current data to left by mic_len bytes ptr = buffer_data_pointer(buf); //Set new data pointer ptr2 = ptr; - ptr2 -= ccm_ptr->mic_len; + ptr2 -= ccm_ptr.mic_len; memmove(ptr2, ptr, data_len); //Cut Mic len - buf->buf_end -= ccm_ptr->mic_len; + buf->buf_end -= ccm_ptr.mic_len; - ptr -= header_size + ccm_ptr->mic_len; + ptr -= header_size + ccm_ptr.mic_len; ptr = mle_security_aux_header_write(ptr, security_header); ptr -= header_size; //Set pointer to Adata ptr -= (32); mle_service_a_data_set(ptr, buf->src_sa.address, buf->dst_sa.address); //Create ADATA - ccm_ptr->adata_ptr = ptr; - ccm_ptr->adata_len = (32 + header_size); + ccm_ptr.adata_ptr = ptr; + ccm_ptr.adata_len = (32 + header_size); //SET ptr to show to real payload - buf->buf_ptr -= ccm_ptr->mic_len; + buf->buf_ptr -= ccm_ptr.mic_len; } else { tr_warn("Security header alloc fail"); + ccm_free(&ccm_ptr); buf = (buffer_t *) 0; + ccm_process_run(NULL); return buf; } } ptr = buffer_data_pointer(buf); - ccm_ptr->data_ptr = ptr; - ccm_ptr->data_len = data_len; + ccm_ptr.data_ptr = ptr; + ccm_ptr.data_len = data_len; - ccm_ptr->mic = ptr; - ccm_ptr->mic += data_len; - ccm_process_run(ccm_ptr); - if (ccm_ptr->mic_len) { + ccm_ptr.mic = ptr; + ccm_ptr.mic += data_len; + ccm_process_run(&ccm_ptr); + if (ccm_ptr.mic_len) { //SET Calculated mic - buf->buf_end += ccm_ptr->mic_len; + buf->buf_end += ccm_ptr.mic_len; } buffer_data_reserve_header(buf, header_size); } @@ -655,6 +656,15 @@ static int mle_service_build_packet_send(service_instance_t *srv_ptr, mle_securi return 0; } +static mle_neighbor_security_counter_info_t *mle_service_get_neighbour_info(protocol_interface_info_entry_t *cur_interface, uint8_t *ll64) +{ + mac_neighbor_table_entry_t *neighbour = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur_interface),ll64, false, NULL); + if (!neighbour) { + return NULL; + } + return mle_service_counter_info_get(cur_interface->id, neighbour->index); +} + static void mle_service_socket_callback(void *cb) { socket_buffer_callback_t *cb_buf = cb; @@ -678,6 +688,7 @@ static void mle_service_socket_callback(void *cb) tr_warn("service handler not registerd"); goto error_handler; } + mle_msg.interface_ptr = service_handler->interface_ptr; // MLE messages are only allowed to Link local address if (!addr_is_ipv6_link_local(buf->src_sa.address) || @@ -730,7 +741,7 @@ static void mle_service_socket_callback(void *cb) /* MLE neighbour table frame counter check */ - mle_neigh_table_entry_t *neighbour = NULL; + mle_neighbor_security_counter_info_t *neighbour = NULL; uint32_t keySeq; if (securityHeader.KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) { keySeq = common_read_32_bit(securityHeader.Keysource); @@ -739,7 +750,7 @@ static void mle_service_socket_callback(void *cb) } if (mle_service->mle_frame_counter_check_enabled) { - neighbour = mle_class_discover_entry_by_ll64(service_handler->interface_id,buf->src_sa.address); + neighbour = mle_service_get_neighbour_info(service_handler->interface_ptr,buf->src_sa.address); if (neighbour){ //key pending is set - incoming frame counter will be reset when new sequence is heard or lower framecounter is heard if (neighbour->new_key_pending) { @@ -813,6 +824,7 @@ static void mle_service_socket_callback(void *cb) } } #endif + if (security_bypass) { /* Security by pass message handler call */ service_handler->recv_security_bypass_cb(service_handler->interface_id, &mle_msg); @@ -871,13 +883,13 @@ static bool mle_service_instance_timeout_handler(uint16_t ticks, service_instanc } } -int mle_service_interface_register(int8_t interface_id, mle_service_receive_cb *receive_cb, uint8_t *mac64, uint8_t challengeLength) +int mle_service_interface_register(int8_t interface_id, void *interface_ptr, mle_service_receive_cb *receive_cb, uint8_t *mac64, uint8_t challengeLength) { service_instance_t *srv_ptr; if (challengeLength < 4 || challengeLength > 32) { return -1; - } else if (!receive_cb) { + } else if (!receive_cb || !interface_ptr) { return -1; } else if (!mac64) { return -1; @@ -899,6 +911,7 @@ int mle_service_interface_register(int8_t interface_id, mle_service_receive_cb * srv_ptr->recv_cb = receive_cb; srv_ptr->challenge_length = challengeLength; + srv_ptr->interface_ptr = interface_ptr; memcpy(srv_ptr->mac64, mac64, 8); if (mle_service->mle_socket < 0) { @@ -990,8 +1003,12 @@ void mle_service_interface_unregister(int8_t interface_id) int mle_service_reset_frame_counters(int8_t interfaceId) { + service_instance_t *srv_ptr = mle_service_interface_find(interfaceId); + if (!srv_ptr) { + return -1; + } mle_service_security_set_frame_counter(interfaceId, 0); - mle_class_set_new_key_pending(interfaceId); + mle_class_set_new_key_pending(srv_ptr->interface_ptr); return 0; } @@ -1412,8 +1429,7 @@ bool mle_service_security_key_trig(int8_t interfaceId, uint8_t keyId) bool mle_service_security_set_security_key(int8_t interfaceId, const uint8_t *security_key, uint8_t keyId, bool primary) { - bool master_key_changed = false; - master_key_changed = mle_service_security_key_set(mle_service_security_params_get(interfaceId), security_key, keyId, primary); + bool master_key_changed = mle_service_security_key_set(mle_service_security_params_get(interfaceId), security_key, keyId, primary); if (master_key_changed && primary) { mle_service_reset_frame_counters(interfaceId); } diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/mle_service/mle_service_api.h b/features/nanostack/sal-stack-nanostack/source/Service_Libs/mle_service/mle_service_api.h index 2efcf8e60131..7055df99e88d 100644 --- a/features/nanostack/sal-stack-nanostack/source/Service_Libs/mle_service/mle_service_api.h +++ b/features/nanostack/sal-stack-nanostack/source/Service_Libs/mle_service/mle_service_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -114,6 +114,7 @@ typedef struct { uint8_t *packet_src_address; /*!< Packet Source address */ uint8_t *packet_dst_address; /*!< Packet Destination address */ uint8_t *data_ptr; /*!< Data pointer */ + void *interface_ptr; uint16_t data_length; /*!< Data Length */ uint16_t src_pan_id; /*!< Link source Pan-id */ uint16_t dst_pan_id; /*!< Link destination Pan-id */ @@ -132,6 +133,7 @@ uint8_t retrans_max; /*!< Define max packet TX count */ uint8_t delay; /*!< 100ms Ticks for random delay */ } mle_message_timeout_params_t; + /** * MLE service message receiver handler call back function pointer * @@ -209,13 +211,14 @@ typedef bool (mle_service_filter_cb)(int8_t interface_id, mle_message_t *mle_msg * Creates and shares socket for other mle services. * * \param interface_id Registered services interface Id. + * \param interface_ptr Pointer tointerface * \param receive_cb Message RX handler. * \param mac64 Interface 64-bit MAC. * \param challengeLength challenge length * Return values * 0, Register OK. */ -int mle_service_interface_register(int8_t interface_id, mle_service_receive_cb *receive_cb, uint8_t *mac64, uint8_t challengeLength); +int mle_service_interface_register(int8_t interface_id, void *interface_ptr, mle_service_receive_cb *receive_cb, uint8_t *mac64, uint8_t challengeLength); /* * Deletes server instance. @@ -730,6 +733,69 @@ void mle_service_set_fragmented_msg_ll_security(bool value); */ void mle_service_set_accept_invalid_frame_counter(bool value); + +/** +* Commands MLE service to allocate mle frame counter table for giving neighbor count. +* +* \param interface_id Interface ID +* \param table_size Table size +* +* \return 0 Allocate OK +* \return -1 Allocate Fail +* +*/ +int mle_service_frame_counter_table_allocate(int8_t interface_id, uint8_t table_size); + +/** +* Commands MLE service to free mle frame counter table +* +* \param interface_id Interface ID +* +* \return 0 Free OK +* \return -1 Free Fail +* +*/ +int mle_service_frame_counter_table_free(int8_t interface_id); + +/** +* Commands MLE service to add / Update frame counter to neighbor +* +* \param interface_id Interface ID +* \param attribute_index Attribute index for neighbor +* \param frame_counter MLE frame counter +* +*/ +void mle_service_frame_counter_entry_add(int8_t interface_id, uint8_t attribute_index, uint32_t frame_counter); + +/** +* Commands MLE service get mle frame counter for neighbor +* +* \param interface_id Interface ID +* \param attribute_index Attribute index for neighbor +* +* \return Stored Frame Counter, may return 0 if unknow attribute +* +*/ +uint32_t mle_service_neighbor_frame_counter_get(int8_t interface_id, uint8_t attribute_index); + +/** +* Commands MLE service frame counter new key pending state activate +* +* \param interface_id Interface ID +* \param attribute_index Attribute index for neighbor +* +*/ +void mle_service_frame_counter_entry_new_key_pending_set(int8_t interface_id, uint8_t attribute_index); + +/** +* Commands MLE service frame counter info delete +* +* \param interface_id Interface ID +* \param attribute_index Attribute index for neighbor +* +*/ +void mle_service_frame_counter_entry_delete(int8_t interface_id, uint8_t attribute_index); + #ifdef MLE_TEST /** * Set callback for MLE receiving packet filtering. diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/mle_service/mle_service_frame_counter_table.c b/features/nanostack/sal-stack-nanostack/source/Service_Libs/mle_service/mle_service_frame_counter_table.c new file mode 100644 index 000000000000..6a6d146146a3 --- /dev/null +++ b/features/nanostack/sal-stack-nanostack/source/Service_Libs/mle_service/mle_service_frame_counter_table.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2018, Arm Limited and affiliates. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "nsconfig.h" +#include +#include +#include "ns_trace.h" +#include "common_functions.h" +#include "ccmLIB.h" +#include "nsdynmemLIB.h" +#include "Core/include/address.h" +#include "Core/include/ns_buffer.h" +#include "MLE/mle.h" +#include "mac_common_defines.h" +#include "Service_Libs/mle_service/mle_service_api.h" +#include "Service_Libs/mle_service/mle_service_frame_counter_table.h" + + + +typedef struct { + mle_neighbor_security_counter_info_t *security_counter_list; + uint8_t table_size; + int8_t interface_id; + ns_list_link_t link; +} mle_service_framecounter_instance_list_t; + +typedef NS_LIST_HEAD(mle_service_framecounter_instance_list_t, link) mle_service_counter_list_t; + +static mle_service_counter_list_t srv_framecounter_instance_list; + + +static mle_service_framecounter_instance_list_t * mle_service_framecounter_params_get(int8_t interface_id) +{ + ns_list_foreach(mle_service_framecounter_instance_list_t, cur_ptr, &srv_framecounter_instance_list) { + if (cur_ptr->interface_id == interface_id) { + return cur_ptr; + } + } + return NULL; +} + +static void mle_service_framecounter_delete(mle_neighbor_security_counter_info_t *cur_ptr) +{ + cur_ptr->last_key_sequence = 0; + cur_ptr->mle_frame_counter = 0; + cur_ptr->new_key_pending = false; +} + + +mle_neighbor_security_counter_info_t *mle_service_counter_info_get(int8_t interface_id, uint8_t attribute_index) +{ + mle_service_framecounter_instance_list_t *srv_ptr = mle_service_framecounter_params_get(interface_id); + + if (!srv_ptr || !srv_ptr->security_counter_list || attribute_index >= srv_ptr->table_size) { + return NULL; + } + mle_neighbor_security_counter_info_t *entry = srv_ptr->security_counter_list + attribute_index; + return entry; +} + +int mle_service_frame_counter_table_free(int8_t interface_id) +{ + mle_service_framecounter_instance_list_t *srv_ptr = mle_service_framecounter_params_get(interface_id); + if (!srv_ptr) { + return -1; + } + ns_list_remove(&srv_framecounter_instance_list, srv_ptr); + ns_dyn_mem_free(srv_ptr->security_counter_list); + ns_dyn_mem_free(srv_ptr); + return 0; +} + +int mle_service_frame_counter_table_allocate(int8_t interface_id, uint8_t table_size) +{ + + mle_service_framecounter_instance_list_t *srv_ptr = mle_service_framecounter_params_get(interface_id); + if (!srv_ptr) { + srv_ptr = ns_dyn_mem_alloc(sizeof(mle_service_framecounter_instance_list_t)); + if (!srv_ptr) { + return -1; + } + ns_list_add_to_start(&srv_framecounter_instance_list, srv_ptr); + srv_ptr->interface_id = interface_id; + srv_ptr->table_size = 0; + srv_ptr->security_counter_list = NULL; + } + + if (srv_ptr->table_size != table_size) { + ns_dyn_mem_free(srv_ptr->security_counter_list); + srv_ptr->security_counter_list = ns_dyn_mem_alloc(sizeof(mle_neighbor_security_counter_info_t) * table_size); + } + + if (!srv_ptr->security_counter_list) { + mle_service_frame_counter_table_free(interface_id); + return -1; + } + srv_ptr->table_size = table_size; + + mle_neighbor_security_counter_info_t *cur_ptr = srv_ptr->security_counter_list; + for (uint8_t i=0; i< table_size; i++) { + mle_service_framecounter_delete(cur_ptr); + cur_ptr++; + } + return 0; +} + +void mle_service_frame_counter_entry_add(int8_t interface_id, uint8_t attribute_index, uint32_t frame_counter) +{ + mle_neighbor_security_counter_info_t * entry = mle_service_counter_info_get(interface_id, attribute_index); + if (entry) { + entry->mle_frame_counter = frame_counter; + } +} + +void mle_service_frame_counter_entry_new_key_pending_set(int8_t interface_id, uint8_t attribute_index) +{ + mle_neighbor_security_counter_info_t * entry = mle_service_counter_info_get(interface_id, attribute_index); + if (entry) { + entry->new_key_pending = true; + } +} + +void mle_service_frame_counter_entry_delete(int8_t interface_id, uint8_t attribute_index) +{ + mle_neighbor_security_counter_info_t * entry = mle_service_counter_info_get(interface_id, attribute_index); + if (entry) { + mle_service_framecounter_delete(entry); + } + +} + +uint32_t mle_service_neighbor_frame_counter_get(int8_t interface_id, uint8_t attribute_index) +{ + mle_neighbor_security_counter_info_t * entry = mle_service_counter_info_get(interface_id, attribute_index); + if (!entry) { + return 0; + } + return entry->mle_frame_counter; + +} + diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/mle_service/mle_service_frame_counter_table.h b/features/nanostack/sal-stack-nanostack/source/Service_Libs/mle_service/mle_service_frame_counter_table.h new file mode 100644 index 000000000000..afbed9d9c6a8 --- /dev/null +++ b/features/nanostack/sal-stack-nanostack/source/Service_Libs/mle_service/mle_service_frame_counter_table.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2018, Arm Limited and affiliates. + * 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 MLE_SERVICE_FRAME_COUNTER_TABLE_H_ +#define MLE_SERVICE_FRAME_COUNTER_TABLE_H_ + +#include +/* + * MLE neighbor security counter info entry for replay attack + * + */ +typedef struct { + uint32_t mle_frame_counter; /*!< Last used security frame counter */ + uint32_t last_key_sequence; /*!< Last used key sequence */ + bool new_key_pending:1; /*!< New Key is pending */ +} mle_neighbor_security_counter_info_t; + +//Internal use +mle_neighbor_security_counter_info_t *mle_service_counter_info_get(int8_t interface_id, uint8_t attribute_index); + +#endif /* MLE_SERVICE_FRAME_COUNTER_TABLE_H_ */ diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/mle_service/mle_service_interface.h b/features/nanostack/sal-stack-nanostack/source/Service_Libs/mle_service/mle_service_interface.h index e0aab504d761..32166cf34386 100644 --- a/features/nanostack/sal-stack-nanostack/source/Service_Libs/mle_service/mle_service_interface.h +++ b/features/nanostack/sal-stack-nanostack/source/Service_Libs/mle_service/mle_service_interface.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -31,6 +31,7 @@ typedef struct { mle_service_receive_cb *recv_cb; /*!< Interface message handler */ mle_service_receive_security_bypass_cb *recv_security_bypass_cb; /*!< Interface message security bypass handler */ + void *interface_ptr; uint8_t mac64[8]; /*!< Interface MAC 64 used for Security nonce and LL64 address define */ int8_t interface_id; /*!< Interface Id */ uint8_t challenge_length; /*!< Define MLE challenge length */ diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/nd_proxy/nd_proxy.c b/features/nanostack/sal-stack-nanostack/source/Service_Libs/nd_proxy/nd_proxy.c index 51b96b207946..fb58f5c4faa3 100644 --- a/features/nanostack/sal-stack-nanostack/source/Service_Libs/nd_proxy/nd_proxy.c +++ b/features/nanostack/sal-stack-nanostack/source/Service_Libs/nd_proxy/nd_proxy.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/nd_proxy/nd_proxy.h b/features/nanostack/sal-stack-nanostack/source/Service_Libs/nd_proxy/nd_proxy.h index 4ab48e23e5a2..dfc07149186d 100644 --- a/features/nanostack/sal-stack-nanostack/source/Service_Libs/nd_proxy/nd_proxy.h +++ b/features/nanostack/sal-stack-nanostack/source/Service_Libs/nd_proxy/nd_proxy.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/whiteboard/whiteboard.h b/features/nanostack/sal-stack-nanostack/source/Service_Libs/whiteboard/whiteboard.h index 86cc059a3e3e..01b9e90f1890 100644 --- a/features/nanostack/sal-stack-nanostack/source/Service_Libs/whiteboard/whiteboard.h +++ b/features/nanostack/sal-stack-nanostack/source/Service_Libs/whiteboard/whiteboard.h @@ -37,7 +37,7 @@ extern uint16_t whiteboard_size_get(void); #define whiteboard_rm_entry(id, address) #define whiteboard_table_check_address(address) NULL #define whiteboard_table_update(address, eui64, status) NULL -#define whiteboard_interface_unregister_all_address(nwk_id) -1 +#define whiteboard_interface_unregister_all_address(nwk_id) #define whiteboard_interface_address_cmp(address) false #endif diff --git a/features/nanostack/sal-stack-nanostack/source/configs/base/cfg_ethernet.h b/features/nanostack/sal-stack-nanostack/source/configs/base/cfg_ethernet.h new file mode 100644 index 000000000000..6c1b6c0156c9 --- /dev/null +++ b/features/nanostack/sal-stack-nanostack/source/configs/base/cfg_ethernet.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2016-2018, Arm Limited and affiliates. + * 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. + */ + +/* Config Flags for Ethernet Bootstrap */ + +#define HAVE_ETHERNET + +#define HAVE_IPV6_ND diff --git a/features/nanostack/sal-stack-nanostack/source/configs/base/cfg_local_socket.h b/features/nanostack/sal-stack-nanostack/source/configs/base/cfg_local_socket.h new file mode 100644 index 000000000000..4eed70c5314b --- /dev/null +++ b/features/nanostack/sal-stack-nanostack/source/configs/base/cfg_local_socket.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2016-2018, Arm Limited and affiliates. + * 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. + */ + +#define HAVE_LOCAL_SOCKET diff --git a/features/nanostack/sal-stack-nanostack/source/configs/base/cfg_lowpan_border_router.h b/features/nanostack/sal-stack-nanostack/source/configs/base/cfg_lowpan_border_router.h new file mode 100644 index 000000000000..56b598e7f140 --- /dev/null +++ b/features/nanostack/sal-stack-nanostack/source/configs/base/cfg_lowpan_border_router.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2016-2018, Arm Limited and affiliates. + * 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. + */ + +/* Config Flags for 6LoWPAN Border router */ +#include "cfg_lowpan_router.h" + +#define HAVE_RPL_ROOT +#define HAVE_RPL_DAO_HANDLING +#define HAVE_6LOWPAN_BORDER_ROUTER +#define WHITEBOARD +#define HAVE_ND_PROXY +#define MULTICAST_FORWARDING diff --git a/features/nanostack/sal-stack-nanostack/source/configs/base/cfg_lowpan_host.h b/features/nanostack/sal-stack-nanostack/source/configs/base/cfg_lowpan_host.h new file mode 100644 index 000000000000..11484d1b451b --- /dev/null +++ b/features/nanostack/sal-stack-nanostack/source/configs/base/cfg_lowpan_host.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2016-2018, Arm Limited and affiliates. + * 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. + */ + +/* Config Flags for 6LoWPAN Host */ +#define HAVE_IPV6_ND +#define HAVE_6LOWPAN_ND +#define HAVE_MPL diff --git a/features/nanostack/sal-stack-nanostack/source/configs/base/cfg_lowpan_router.h b/features/nanostack/sal-stack-nanostack/source/configs/base/cfg_lowpan_router.h new file mode 100644 index 000000000000..6dd4a93471fb --- /dev/null +++ b/features/nanostack/sal-stack-nanostack/source/configs/base/cfg_lowpan_router.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2016-2018, Arm Limited and affiliates. + * 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. + */ + +/* Config Flags for 6LoWPAN Router */ +#include "cfg_lowpan_host.h" + +#define HAVE_6LOWPAN_ROUTER +#define HAVE_RPL diff --git a/features/nanostack/sal-stack-nanostack/source/configs/base/cfg_rf_tunnel.h b/features/nanostack/sal-stack-nanostack/source/configs/base/cfg_rf_tunnel.h new file mode 100644 index 000000000000..6e6b09acb012 --- /dev/null +++ b/features/nanostack/sal-stack-nanostack/source/configs/base/cfg_rf_tunnel.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2016-2018, Arm Limited and affiliates. + * 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. + */ + +#define HAVE_RF_TUNNEL diff --git a/features/nanostack/sal-stack-nanostack/source/configs/base/cfg_thread_border_router.h b/features/nanostack/sal-stack-nanostack/source/configs/base/cfg_thread_border_router.h new file mode 100644 index 000000000000..be579f1e39b8 --- /dev/null +++ b/features/nanostack/sal-stack-nanostack/source/configs/base/cfg_thread_border_router.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2016-2018, Arm Limited and affiliates. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cfg_thread_router.h" + +#define HAVE_THREAD_BORDER_ROUTER +#define HAVE_ND_PROXY +#define MULTICAST_FORWARDING diff --git a/features/nanostack/sal-stack-nanostack/source/configs/base/cfg_thread_end_device.h b/features/nanostack/sal-stack-nanostack/source/configs/base/cfg_thread_end_device.h new file mode 100644 index 000000000000..8768095c2caa --- /dev/null +++ b/features/nanostack/sal-stack-nanostack/source/configs/base/cfg_thread_end_device.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2016-2018, Arm Limited and affiliates. + * 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. + */ + +/* Thread feature is active with minimal functionality */ +#define HAVE_THREAD + +#define HAVE_MPL diff --git a/features/nanostack/sal-stack-nanostack/source/configs/base/cfg_thread_full_end_device.h b/features/nanostack/sal-stack-nanostack/source/configs/base/cfg_thread_full_end_device.h new file mode 100644 index 000000000000..7a605f4d1dc2 --- /dev/null +++ b/features/nanostack/sal-stack-nanostack/source/configs/base/cfg_thread_full_end_device.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2016-2018, Arm Limited and affiliates. + * 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. + */ + +/** +* Thread Full End Device configuration file. +*/ +#include "cfg_thread_end_device.h" + +/* Flag to enable Thread Neighbor discovery */ +#define HAVE_THREAD_NEIGHBOR_DISCOVERY diff --git a/features/nanostack/sal-stack-nanostack/source/configs/base/cfg_thread_router.h b/features/nanostack/sal-stack-nanostack/source/configs/base/cfg_thread_router.h new file mode 100644 index 000000000000..a15d0ba5a366 --- /dev/null +++ b/features/nanostack/sal-stack-nanostack/source/configs/base/cfg_thread_router.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2016-2018, Arm Limited and affiliates. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cfg_thread_full_end_device.h" + +/* Enable DHCP server functionality */ +#define HAVE_DHCPV6_SERVER + +/* Flag for Thread router specific functionality */ +#define HAVE_THREAD_ROUTER + +/* Flag to enable Thread leader capability */ +#define HAVE_THREAD_LEADER_SERVICE diff --git a/features/nanostack/sal-stack-nanostack/source/configs/base/ethernet.cfg b/features/nanostack/sal-stack-nanostack/source/configs/base/ethernet.cfg deleted file mode 100644 index 35fd65af7aab..000000000000 --- a/features/nanostack/sal-stack-nanostack/source/configs/base/ethernet.cfg +++ /dev/null @@ -1,5 +0,0 @@ -/* Config Flags for Ethernet Bootstrap */ - -#define HAVE_ETHERNET - -#define HAVE_IPV6_ND diff --git a/features/nanostack/sal-stack-nanostack/source/configs/base/local_socket.cfg b/features/nanostack/sal-stack-nanostack/source/configs/base/local_socket.cfg deleted file mode 100644 index 570ad810fb24..000000000000 --- a/features/nanostack/sal-stack-nanostack/source/configs/base/local_socket.cfg +++ /dev/null @@ -1 +0,0 @@ -#define HAVE_LOCAL_SOCKET diff --git a/features/nanostack/sal-stack-nanostack/source/configs/base/lowpan_border_router.cfg b/features/nanostack/sal-stack-nanostack/source/configs/base/lowpan_border_router.cfg deleted file mode 100644 index 8c0a76780f25..000000000000 --- a/features/nanostack/sal-stack-nanostack/source/configs/base/lowpan_border_router.cfg +++ /dev/null @@ -1,9 +0,0 @@ -/* Config Flags for 6LoWPAN Border router */ -#include "lowpan_router.cfg" - -#define HAVE_RPL_ROOT -#define HAVE_RPL_DAO_HANDLING -#define HAVE_6LOWPAN_BORDER_ROUTER -#define WHITEBOARD -#define HAVE_ND_PROXY -#define MULTICAST_FORWARDING diff --git a/features/nanostack/sal-stack-nanostack/source/configs/base/lowpan_host.cfg b/features/nanostack/sal-stack-nanostack/source/configs/base/lowpan_host.cfg deleted file mode 100644 index 272227bd853b..000000000000 --- a/features/nanostack/sal-stack-nanostack/source/configs/base/lowpan_host.cfg +++ /dev/null @@ -1,4 +0,0 @@ -/* Config Flags for 6LoWPAN Host */ -#define HAVE_IPV6_ND -#define HAVE_6LOWPAN_ND -#define HAVE_MPL diff --git a/features/nanostack/sal-stack-nanostack/source/configs/base/lowpan_router.cfg b/features/nanostack/sal-stack-nanostack/source/configs/base/lowpan_router.cfg deleted file mode 100644 index 3ea63aba48eb..000000000000 --- a/features/nanostack/sal-stack-nanostack/source/configs/base/lowpan_router.cfg +++ /dev/null @@ -1,5 +0,0 @@ -/* Config Flags for 6LoWPAN Router */ -#include "lowpan_host.cfg" - -#define HAVE_6LOWPAN_ROUTER -#define HAVE_RPL diff --git a/features/nanostack/sal-stack-nanostack/source/configs/base/rf_tunnel.cfg b/features/nanostack/sal-stack-nanostack/source/configs/base/rf_tunnel.cfg deleted file mode 100644 index f943f1420c7e..000000000000 --- a/features/nanostack/sal-stack-nanostack/source/configs/base/rf_tunnel.cfg +++ /dev/null @@ -1 +0,0 @@ -#define HAVE_RF_TUNNEL diff --git a/features/nanostack/sal-stack-nanostack/source/configs/base/thread_border_router.cfg b/features/nanostack/sal-stack-nanostack/source/configs/base/thread_border_router.cfg deleted file mode 100644 index da67891f6f05..000000000000 --- a/features/nanostack/sal-stack-nanostack/source/configs/base/thread_border_router.cfg +++ /dev/null @@ -1,5 +0,0 @@ -#include "thread_router.cfg" - -#define HAVE_THREAD_BORDER_ROUTER -#define HAVE_ND_PROXY -#define MULTICAST_FORWARDING diff --git a/features/nanostack/sal-stack-nanostack/source/configs/base/thread_end_device.cfg b/features/nanostack/sal-stack-nanostack/source/configs/base/thread_end_device.cfg deleted file mode 100644 index eda490d8bf1f..000000000000 --- a/features/nanostack/sal-stack-nanostack/source/configs/base/thread_end_device.cfg +++ /dev/null @@ -1,5 +0,0 @@ - -/* Thread feature is active with minimal functionality */ -#define HAVE_THREAD - -#define HAVE_MPL diff --git a/features/nanostack/sal-stack-nanostack/source/configs/base/thread_full_end_device.cfg b/features/nanostack/sal-stack-nanostack/source/configs/base/thread_full_end_device.cfg deleted file mode 100644 index e515a4fffcce..000000000000 --- a/features/nanostack/sal-stack-nanostack/source/configs/base/thread_full_end_device.cfg +++ /dev/null @@ -1,7 +0,0 @@ -/** -* Thread Full End Device configuration file. -*/ -#include "thread_end_device.cfg" - -/* Flag to enable Thread Neighbor discovery */ -#define HAVE_THREAD_NEIGHBOR_DISCOVERY diff --git a/features/nanostack/sal-stack-nanostack/source/configs/base/thread_router.cfg b/features/nanostack/sal-stack-nanostack/source/configs/base/thread_router.cfg deleted file mode 100644 index e89c3b09adc7..000000000000 --- a/features/nanostack/sal-stack-nanostack/source/configs/base/thread_router.cfg +++ /dev/null @@ -1,11 +0,0 @@ - -#include "thread_full_end_device.cfg" - -/* Enable DHCP server functionality */ -#define HAVE_DHCPV6_SERVER - -/* Flag for Thread router specific functionality */ -#define HAVE_THREAD_ROUTER - -/* Flag to enable Thread leader capability */ -#define HAVE_THREAD_LEADER_SERVICE diff --git a/features/nanostack/sal-stack-nanostack/source/configs/ethernet_host.cfg b/features/nanostack/sal-stack-nanostack/source/configs/cfg_ethernet_host.h similarity index 87% rename from features/nanostack/sal-stack-nanostack/source/configs/ethernet_host.cfg rename to features/nanostack/sal-stack-nanostack/source/configs/cfg_ethernet_host.h index 9c71c41613e9..7a68772bc19a 100644 --- a/features/nanostack/sal-stack-nanostack/source/configs/ethernet_host.cfg +++ b/features/nanostack/sal-stack-nanostack/source/configs/cfg_ethernet_host.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Arm Limited and affiliates. + * Copyright (c) 2016, 2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,6 +16,6 @@ */ -#include "base/ethernet.cfg" +#include "base/cfg_ethernet.h" #define NO_RADV_TX diff --git a/features/nanostack/sal-stack-nanostack/source/configs/generic.cfg b/features/nanostack/sal-stack-nanostack/source/configs/cfg_generic.h similarity index 76% rename from features/nanostack/sal-stack-nanostack/source/configs/generic.cfg rename to features/nanostack/sal-stack-nanostack/source/configs/cfg_generic.h index ea8216f7b76c..762997f4200d 100644 --- a/features/nanostack/sal-stack-nanostack/source/configs/generic.cfg +++ b/features/nanostack/sal-stack-nanostack/source/configs/cfg_generic.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2016-2017, Arm Limited and affiliates. + * Copyright (c) 2014, 2016-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,11 +15,11 @@ * limitations under the License. */ -#include "base/thread_border_router.cfg" -#include "base/ethernet.cfg" -#include "base/lowpan_border_router.cfg" -#include "base/local_socket.cfg" -#include "base/rf_tunnel.cfg" +#include "base/cfg_thread_border_router.h" +#include "base/cfg_ethernet.h" +#include "base/cfg_lowpan_border_router.h" +#include "base/cfg_local_socket.h" +#include "base/cfg_rf_tunnel.h" #define FEA_TRACE_SUPPORT #define EXTRA_CONSISTENCY_CHECKS diff --git a/features/nanostack/sal-stack-nanostack/source/configs/lowpan_border_router.cfg b/features/nanostack/sal-stack-nanostack/source/configs/cfg_lowpan_border_router.h similarity index 81% rename from features/nanostack/sal-stack-nanostack/source/configs/lowpan_border_router.cfg rename to features/nanostack/sal-stack-nanostack/source/configs/cfg_lowpan_border_router.h index 9d99f10ff390..6ec843c10e03 100644 --- a/features/nanostack/sal-stack-nanostack/source/configs/lowpan_border_router.cfg +++ b/features/nanostack/sal-stack-nanostack/source/configs/cfg_lowpan_border_router.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, Arm Limited and affiliates. + * Copyright (c) 2015-2016, 2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,9 +15,9 @@ * limitations under the License. */ -#include "base/lowpan_border_router.cfg" -#include "base/ethernet.cfg" -#include "base/local_socket.cfg" +#include "base/cfg_lowpan_border_router.h" +#include "base/cfg_ethernet.h" +#include "base/cfg_local_socket.h" #define HAVE_AES #define FEA_TRACE_SUPPORT diff --git a/features/nanostack/sal-stack-nanostack/source/configs/lowpan_border_router_rf_tunnel.cfg b/features/nanostack/sal-stack-nanostack/source/configs/cfg_lowpan_border_router_rf_tunnel.h similarity index 81% rename from features/nanostack/sal-stack-nanostack/source/configs/lowpan_border_router_rf_tunnel.cfg rename to features/nanostack/sal-stack-nanostack/source/configs/cfg_lowpan_border_router_rf_tunnel.h index ce84ab1d779e..bad937401964 100644 --- a/features/nanostack/sal-stack-nanostack/source/configs/lowpan_border_router_rf_tunnel.cfg +++ b/features/nanostack/sal-stack-nanostack/source/configs/cfg_lowpan_border_router_rf_tunnel.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,10 +15,10 @@ * limitations under the License. */ /* This is for linux router which use RF tunnel interface */ -#include "base/lowpan_border_router.cfg" -#include "base/ethernet.cfg" -#include "base/local_socket.cfg" -#include "base/rf_tunnel.cfg" +#include "base/cfg_lowpan_border_router.h" +#include "base/cfg_ethernet.h" +#include "base/cfg_local_socket.h" +#include "base/cfg_rf_tunnel.h" #define HAVE_AES #define FEA_TRACE_SUPPORT diff --git a/features/nanostack/sal-stack-nanostack/source/configs/lowpan_border_router_rf_tunnel_ecc.cfg b/features/nanostack/sal-stack-nanostack/source/configs/cfg_lowpan_border_router_rf_tunnel_ecc.h similarity index 79% rename from features/nanostack/sal-stack-nanostack/source/configs/lowpan_border_router_rf_tunnel_ecc.cfg rename to features/nanostack/sal-stack-nanostack/source/configs/cfg_lowpan_border_router_rf_tunnel_ecc.h index 75ceaf49e0d0..63fd2ca007f0 100644 --- a/features/nanostack/sal-stack-nanostack/source/configs/lowpan_border_router_rf_tunnel_ecc.cfg +++ b/features/nanostack/sal-stack-nanostack/source/configs/cfg_lowpan_border_router_rf_tunnel_ecc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, Arm Limited and affiliates. + * Copyright (c) 2015-2016, 2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,10 +15,10 @@ * limitations under the License. */ /* This is for linux router which use RF tunnel interface */ -#include "base/lowpan_border_router.cfg" -#include "base/ethernet.cfg" -#include "base/local_socket.cfg" -#include "base/rf_tunnel.cfg" +#include "base/cfg_lowpan_border_router.h" +#include "base/cfg_ethernet.h" +#include "base/cfg_local_socket.h" +#include "base/cfg_rf_tunnel.h" #define ECC #define HAVE_AES diff --git a/features/nanostack/sal-stack-nanostack/source/configs/lowpan_border_router_rf_tunnel_ecc_release.cfg b/features/nanostack/sal-stack-nanostack/source/configs/cfg_lowpan_border_router_rf_tunnel_ecc_release.h similarity index 79% rename from features/nanostack/sal-stack-nanostack/source/configs/lowpan_border_router_rf_tunnel_ecc_release.cfg rename to features/nanostack/sal-stack-nanostack/source/configs/cfg_lowpan_border_router_rf_tunnel_ecc_release.h index f5f03eac705f..2a7ae8bf99c9 100644 --- a/features/nanostack/sal-stack-nanostack/source/configs/lowpan_border_router_rf_tunnel_ecc_release.cfg +++ b/features/nanostack/sal-stack-nanostack/source/configs/cfg_lowpan_border_router_rf_tunnel_ecc_release.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, Arm Limited and affiliates. + * Copyright (c) 2015-2016, 2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,10 +15,10 @@ * limitations under the License. */ /* This is for linux router which use RF tunnel interface */ -#include "base/lowpan_border_router.cfg" -#include "base/ethernet.cfg" -#include "base/local_socket.cfg" -#include "base/rf_tunnel.cfg" +#include "base/cfg_lowpan_border_router.h" +#include "base/cfg_ethernet.h" +#include "base/cfg_local_socket.h" +#include "base/cfg_rf_tunnel.h" #define ECC #define HAVE_AES diff --git a/features/nanostack/sal-stack-nanostack/source/configs/lowpan_host.cfg b/features/nanostack/sal-stack-nanostack/source/configs/cfg_lowpan_host.h similarity index 87% rename from features/nanostack/sal-stack-nanostack/source/configs/lowpan_host.cfg rename to features/nanostack/sal-stack-nanostack/source/configs/cfg_lowpan_host.h index f9c02bb8aa8b..03533192aa99 100644 --- a/features/nanostack/sal-stack-nanostack/source/configs/lowpan_host.cfg +++ b/features/nanostack/sal-stack-nanostack/source/configs/cfg_lowpan_host.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, Arm Limited and affiliates. + * Copyright (c) 2015-2016, 2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,7 +16,7 @@ */ -#include "base/lowpan_host.cfg" +#include "base/cfg_lowpan_host.h" #define HAVE_AES #define NO_RADV_TX diff --git a/features/nanostack/sal-stack-nanostack/source/configs/lowpan_router.cfg b/features/nanostack/sal-stack-nanostack/source/configs/cfg_lowpan_router.h similarity index 87% rename from features/nanostack/sal-stack-nanostack/source/configs/lowpan_router.cfg rename to features/nanostack/sal-stack-nanostack/source/configs/cfg_lowpan_router.h index ba5dd100e090..b119cc3e9dfa 100644 --- a/features/nanostack/sal-stack-nanostack/source/configs/lowpan_router.cfg +++ b/features/nanostack/sal-stack-nanostack/source/configs/cfg_lowpan_router.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, Arm Limited and affiliates. + * Copyright (c) 2015-2016, 2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,7 +16,7 @@ */ -#include "base/lowpan_router.cfg" +#include "base/cfg_lowpan_router.h" #define HAVE_AES #define FEA_TRACE_SUPPORT diff --git a/features/nanostack/sal-stack-nanostack/source/configs/lowpan_router_ecc.cfg b/features/nanostack/sal-stack-nanostack/source/configs/cfg_lowpan_router_ecc.h similarity index 87% rename from features/nanostack/sal-stack-nanostack/source/configs/lowpan_router_ecc.cfg rename to features/nanostack/sal-stack-nanostack/source/configs/cfg_lowpan_router_ecc.h index e637aa491124..be863e9c5bd4 100644 --- a/features/nanostack/sal-stack-nanostack/source/configs/lowpan_router_ecc.cfg +++ b/features/nanostack/sal-stack-nanostack/source/configs/cfg_lowpan_router_ecc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,7 +16,7 @@ */ -#include "base/lowpan_router.cfg" +#include "base/cfg_lowpan_router.h" #define ECC #define PANA diff --git a/features/nanostack/sal-stack-nanostack/source/configs/lowpan_router_ecc_release.cfg b/features/nanostack/sal-stack-nanostack/source/configs/cfg_lowpan_router_ecc_release.h similarity index 87% rename from features/nanostack/sal-stack-nanostack/source/configs/lowpan_router_ecc_release.cfg rename to features/nanostack/sal-stack-nanostack/source/configs/cfg_lowpan_router_ecc_release.h index 093264fdf71d..f189344917b2 100644 --- a/features/nanostack/sal-stack-nanostack/source/configs/lowpan_router_ecc_release.cfg +++ b/features/nanostack/sal-stack-nanostack/source/configs/cfg_lowpan_router_ecc_release.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,7 +16,7 @@ */ -#include "base/lowpan_router.cfg" +#include "base/cfg_lowpan_router.h" #define ECC #define PANA diff --git a/features/nanostack/sal-stack-nanostack/source/configs/nanostack_full.cfg b/features/nanostack/sal-stack-nanostack/source/configs/cfg_nanostack_full.h similarity index 88% rename from features/nanostack/sal-stack-nanostack/source/configs/nanostack_full.cfg rename to features/nanostack/sal-stack-nanostack/source/configs/cfg_nanostack_full.h index 34753d9ae9c5..9aa6ba0738f1 100644 --- a/features/nanostack/sal-stack-nanostack/source/configs/nanostack_full.cfg +++ b/features/nanostack/sal-stack-nanostack/source/configs/cfg_nanostack_full.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2016, Arm Limited and affiliates. + * Copyright (c) 2014-2016, 2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,5 +20,5 @@ * all features on mbedOS we can. */ -#include "generic.cfg" +#include "cfg_generic.h" #undef ECC diff --git a/features/nanostack/sal-stack-nanostack/source/configs/nanostack_full_debug.cfg b/features/nanostack/sal-stack-nanostack/source/configs/cfg_nanostack_full_debug.h similarity index 87% rename from features/nanostack/sal-stack-nanostack/source/configs/nanostack_full_debug.cfg rename to features/nanostack/sal-stack-nanostack/source/configs/cfg_nanostack_full_debug.h index fb4832fe9abd..980a0499e419 100644 --- a/features/nanostack/sal-stack-nanostack/source/configs/nanostack_full_debug.cfg +++ b/features/nanostack/sal-stack-nanostack/source/configs/cfg_nanostack_full_debug.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, Arm Limited and affiliates. + * Copyright (c) 2015-2016, 2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,7 +15,7 @@ * limitations under the License. */ -#include "nanostack_full.cfg" +#include "cfg_nanostack_full.h" #define FEA_TRACE_SUPPORT #define EXTRA_CONSISTENCY_CHECKS diff --git a/features/nanostack/sal-stack-nanostack/source/configs/cfg_rf_interface.h b/features/nanostack/sal-stack-nanostack/source/configs/cfg_rf_interface.h new file mode 100644 index 000000000000..e4d1787adfd6 --- /dev/null +++ b/features/nanostack/sal-stack-nanostack/source/configs/cfg_rf_interface.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2016-2018, Arm Limited and affiliates. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "base/cfg_lowpan_host.h" +#include "base/cfg_local_socket.h" +#include "base/cfg_rf_tunnel.h" + +#define NO_RADV_TX +#define NO_TCP diff --git a/features/nanostack/sal-stack-nanostack/source/configs/thread_border_router.cfg b/features/nanostack/sal-stack-nanostack/source/configs/cfg_thread_border_router.h similarity index 83% rename from features/nanostack/sal-stack-nanostack/source/configs/thread_border_router.cfg rename to features/nanostack/sal-stack-nanostack/source/configs/cfg_thread_border_router.h index a500aeda6399..bf0df9a149d8 100644 --- a/features/nanostack/sal-stack-nanostack/source/configs/thread_border_router.cfg +++ b/features/nanostack/sal-stack-nanostack/source/configs/cfg_thread_border_router.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Arm Limited and affiliates. + * Copyright (c) 2015-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,7 +15,7 @@ * limitations under the License. */ -#include "base/thread_border_router.cfg" -#include "base/ethernet.cfg" +#include "base/cfg_thread_border_router.h" +#include "base/cfg_ethernet.h" #define EXTRA_CONSISTENCY_CHECKS diff --git a/features/nanostack/sal-stack-nanostack/source/configs/thread_end_device.cfg b/features/nanostack/sal-stack-nanostack/source/configs/cfg_thread_end_device.h similarity index 88% rename from features/nanostack/sal-stack-nanostack/source/configs/thread_end_device.cfg rename to features/nanostack/sal-stack-nanostack/source/configs/cfg_thread_end_device.h index ea033ea9c042..1b7d93d89c91 100644 --- a/features/nanostack/sal-stack-nanostack/source/configs/thread_end_device.cfg +++ b/features/nanostack/sal-stack-nanostack/source/configs/cfg_thread_end_device.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Arm Limited and affiliates. + * Copyright (c) 2016, 2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,7 +15,7 @@ * limitations under the License. */ -#include "base/thread_end_device.cfg" +#include "base/cfg_thread_end_device.h" /* Code optimization for Router advertisement */ #define NO_RADV_TX diff --git a/features/nanostack/sal-stack-nanostack/source/configs/thread_full_end_device.cfg b/features/nanostack/sal-stack-nanostack/source/configs/cfg_thread_full_end_device.h similarity index 88% rename from features/nanostack/sal-stack-nanostack/source/configs/thread_full_end_device.cfg rename to features/nanostack/sal-stack-nanostack/source/configs/cfg_thread_full_end_device.h index c7f93171c8a8..92ebdccc05d3 100644 --- a/features/nanostack/sal-stack-nanostack/source/configs/thread_full_end_device.cfg +++ b/features/nanostack/sal-stack-nanostack/source/configs/cfg_thread_full_end_device.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Arm Limited and affiliates. + * Copyright (c) 2016, 2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,7 +15,7 @@ * limitations under the License. */ -#include "base/thread_full_end_device.cfg" +#include "base/cfg_thread_full_end_device.h" /* Code optimization for Router advertisement */ #define NO_RADV_TX diff --git a/features/nanostack/sal-stack-nanostack/source/configs/thread_router.cfg b/features/nanostack/sal-stack-nanostack/source/configs/cfg_thread_router.h similarity index 87% rename from features/nanostack/sal-stack-nanostack/source/configs/thread_router.cfg rename to features/nanostack/sal-stack-nanostack/source/configs/cfg_thread_router.h index 2eb2b8b13fc4..f348ccd5de65 100644 --- a/features/nanostack/sal-stack-nanostack/source/configs/thread_router.cfg +++ b/features/nanostack/sal-stack-nanostack/source/configs/cfg_thread_router.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, Arm Limited and affiliates. + * Copyright (c) 2015-2016, 2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,7 +15,7 @@ * limitations under the License. */ -#include "base/thread_router.cfg" +#include "base/cfg_thread_router.h" /* Code optimization for Router advertisement */ #define NO_RADV_TX diff --git a/features/nanostack/sal-stack-nanostack/source/configs/thread_thci.cfg b/features/nanostack/sal-stack-nanostack/source/configs/cfg_thread_thci.h similarity index 89% rename from features/nanostack/sal-stack-nanostack/source/configs/thread_thci.cfg rename to features/nanostack/sal-stack-nanostack/source/configs/cfg_thread_thci.h index 15359e5ab92e..ad66413a0a23 100644 --- a/features/nanostack/sal-stack-nanostack/source/configs/thread_thci.cfg +++ b/features/nanostack/sal-stack-nanostack/source/configs/cfg_thread_thci.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, Arm Limited and affiliates. + * Copyright (c) 2016-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,7 +17,7 @@ /* Thread test harness configuration, derived from thread_border_router to get all thread features */ -#include "thread_border_router.cfg" +#include "cfg_thread_border_router.h" #define FEA_TRACE_SUPPORT #define THREAD_THCI_SUPPORT diff --git a/features/nanostack/sal-stack-nanostack/source/configs/rf_interface.cfg b/features/nanostack/sal-stack-nanostack/source/configs/rf_interface.cfg deleted file mode 100644 index 673bd4af64b4..000000000000 --- a/features/nanostack/sal-stack-nanostack/source/configs/rf_interface.cfg +++ /dev/null @@ -1,6 +0,0 @@ -#include "base/lowpan_host.cfg" -#include "base/local_socket.cfg" -#include "base/rf_tunnel.cfg" - -#define NO_RADV_TX -#define NO_TCP diff --git a/features/nanostack/sal-stack-nanostack/source/ipv6_stack/ipv6_routing_table.c b/features/nanostack/sal-stack-nanostack/source/ipv6_stack/ipv6_routing_table.c index 9e36a43a2a26..0b47ed5b72c7 100644 --- a/features/nanostack/sal-stack-nanostack/source/ipv6_stack/ipv6_routing_table.c +++ b/features/nanostack/sal-stack-nanostack/source/ipv6_stack/ipv6_routing_table.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017, Arm Limited and affiliates. + * Copyright (c) 2012-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -1088,8 +1088,10 @@ static const char *route_src_names[] = { [ROUTE_MPL] = "MPL", [ROUTE_RIP] = "RIP", [ROUTE_THREAD] = "Thread", - [ROUTE_THREAD_BORDER_ROUTER] = "Thread BR", + [ROUTE_THREAD_BORDER_ROUTER] = "Thread Network data", [ROUTE_THREAD_PROXIED_HOST] = "Thread Proxy", + [ROUTE_THREAD_BBR] = "Thread BBR", + [ROUTE_THREAD_PROXIED_DUA_HOST] = "Thread DUA Proxy", [ROUTE_REDIRECT] = "Redirect", }; @@ -1199,6 +1201,9 @@ static void ipv6_route_entry_remove(ipv6_route_t *route) #ifdef FEA_TRACE_SUPPORT ipv6_route_print(route, trace_debug_print); #endif + if (route->info_autofree) { + ns_dyn_mem_free(route->info.info); + } if (protocol_core_buffers_in_event_queue > 0) { // Alert any buffers in the queue already routed by this source ipv6_route_source_invalidated[route->info.source] = true; @@ -1548,6 +1553,7 @@ ipv6_route_t *ipv6_route_add_metric(const uint8_t *prefix, uint8_t prefix_len, i route->lifetime = lifetime; route->metric = metric; route->info.source = source; + route->info_autofree = false; route->info.info = info; route->info.source_id = source_id; route->info.interface_id = interface_id; diff --git a/features/nanostack/sal-stack-nanostack/source/ipv6_stack/ipv6_routing_table.h b/features/nanostack/sal-stack-nanostack/source/ipv6_stack/ipv6_routing_table.h index 5d39a1cfa830..b0858c64728f 100644 --- a/features/nanostack/sal-stack-nanostack/source/ipv6_stack/ipv6_routing_table.h +++ b/features/nanostack/sal-stack-nanostack/source/ipv6_stack/ipv6_routing_table.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2012, 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -82,6 +82,7 @@ typedef enum ipv6_route_src { ROUTE_THREAD, ROUTE_THREAD_BORDER_ROUTER, ROUTE_THREAD_PROXIED_HOST, + ROUTE_THREAD_PROXIED_DUA_HOST, ROUTE_THREAD_BBR, ROUTE_REDIRECT, /* Only occurs in destination cache */ ROUTE_MAX, @@ -120,6 +121,8 @@ typedef struct ipv6_neighbour_cache { bool send_nud_probes : 1; bool recv_ns_aro : 1; bool recv_na_aro : 1; + bool use_eui64_as_slla_in_aro : 1; + bool omit_aro_success : 1; int8_t interface_id; uint8_t max_ll_len; uint8_t gc_timer; @@ -215,6 +218,7 @@ void ipv6_destination_cache_timer(uint8_t ticks); #ifdef HAVE_IPV6_ND void ipv6_destination_redirect(const uint8_t *dest_addr, const uint8_t *sender_addr, const uint8_t *redirect_addr, int8_t interface_id, addrtype_t ll_type, const uint8_t *ll_address); #endif + /* Combined Routing Table (RFC 4191) and Prefix List (RFC 4861) */ /* On-link prefixes have the on_link flag set and next_hop is unset */ typedef struct ipv6_route { @@ -222,6 +226,7 @@ typedef struct ipv6_route { bool on_link: 1; bool search_skip: 1; bool probe: 1; + bool info_autofree:1; uint8_t metric; // 0x40 = RFC 4191 pref high, 0x80 = default, 0xC0 = RFC 4191 pref low ipv6_route_info_t info; uint32_t lifetime; // (seconds); 0xFFFFFFFF means permanent diff --git a/features/nanostack/sal-stack-nanostack/source/ipv6_stack/protocol_ipv6.c b/features/nanostack/sal-stack-nanostack/source/ipv6_stack/protocol_ipv6.c index e0768701c94f..7f01fbbe51fc 100644 --- a/features/nanostack/sal-stack-nanostack/source/ipv6_stack/protocol_ipv6.c +++ b/features/nanostack/sal-stack-nanostack/source/ipv6_stack/protocol_ipv6.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017, Arm Limited and affiliates. + * Copyright (c) 2012-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -954,7 +954,7 @@ static void ipv6_interface_address_cb(protocol_interface_info_entry_t *interface } } -void ipv6_interface_slaac_handler(protocol_interface_info_entry_t *cur, uint8_t *slaacPrefix, uint8_t prefixLen, uint32_t validLifeTime, uint32_t preferredLifeTime) +void ipv6_interface_slaac_handler(protocol_interface_info_entry_t *cur, const uint8_t *slaacPrefix, uint8_t prefixLen, uint32_t validLifeTime, uint32_t preferredLifeTime) { if_address_entry_t *address_entry = icmpv6_slaac_address_add(cur, slaacPrefix, prefixLen, validLifeTime, preferredLifeTime, false, SLAAC_IID_DEFAULT); if (address_entry) { diff --git a/features/nanostack/sal-stack-nanostack/source/ipv6_stack/protocol_ipv6.h b/features/nanostack/sal-stack-nanostack/source/ipv6_stack/protocol_ipv6.h index 97715600c323..7d877ef2b2e8 100644 --- a/features/nanostack/sal-stack-nanostack/source/ipv6_stack/protocol_ipv6.h +++ b/features/nanostack/sal-stack-nanostack/source/ipv6_stack/protocol_ipv6.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -63,7 +63,7 @@ int ipv6_prefix_register(uint8_t *prefix_64, uint32_t lifetime, uint32_t prefer_ int ipv6_prefix_router_flag_activate(uint8_t *ipv6_address); void ipv6_nd_ra_advert(struct protocol_interface_info_entry *cur, const uint8_t *dest); -void ipv6_interface_slaac_handler(struct protocol_interface_info_entry *cur, uint8_t *slaacPrefix, uint8_t prefixLen, uint32_t validLifeTime, uint32_t preferredLifeTime); +void ipv6_interface_slaac_handler(struct protocol_interface_info_entry *cur, const uint8_t *slaacPrefix, uint8_t prefixLen, uint32_t validLifeTime, uint32_t preferredLifeTime); void ipv6_stack_route_advert_update(uint8_t *address, uint8_t prefixLength, uint8_t routePrefer); void ipv6_stack_route_advert_remove(uint8_t *address, uint8_t prefixLength); void ipv6_prefix_on_link_update(uint8_t *address); diff --git a/features/nanostack/sal-stack-nanostack/source/libDHCPv6/dhcp_service_api.c b/features/nanostack/sal-stack-nanostack/source/libDHCPv6/dhcp_service_api.c index 0248d1beb931..3027046fcc8b 100644 --- a/features/nanostack/sal-stack-nanostack/source/libDHCPv6/dhcp_service_api.c +++ b/features/nanostack/sal-stack-nanostack/source/libDHCPv6/dhcp_service_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017, Arm Limited and affiliates. + * Copyright (c) 2013-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -369,7 +369,7 @@ uint16_t dhcp_service_init(int8_t interface_id, dhcp_instance_type_e instance_ty break; } } - srv_ptr = ns_dyn_mem_temporary_alloc(sizeof(server_instance_t)); + srv_ptr = ns_dyn_mem_alloc(sizeof(server_instance_t)); if (id == MAX_SERVERS || srv_ptr == NULL) { tr_error("Out of server instances"); ns_dyn_mem_free(srv_ptr); diff --git a/features/nanostack/sal-stack-nanostack/source/libNET/src/multicast_api.c b/features/nanostack/sal-stack-nanostack/source/libNET/src/multicast_api.c index 2b21ad44d83e..5f1b86c63bc4 100644 --- a/features/nanostack/sal-stack-nanostack/source/libNET/src/multicast_api.c +++ b/features/nanostack/sal-stack-nanostack/source/libNET/src/multicast_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Arm Limited and affiliates. + * Copyright (c) 2017-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -185,7 +185,7 @@ int_fast8_t multicast_mpl_set_default_parameters(int8_t interface_id, uint8_t control_message_k, uint8_t control_message_timer_expirations) { - protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get(interface_id); + protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id); if (!interface) { return -1; } diff --git a/features/nanostack/sal-stack-nanostack/source/libNET/src/net_load_balance.c b/features/nanostack/sal-stack-nanostack/source/libNET/src/net_load_balance.c index ad79c2bd5fb6..e01138ccde53 100644 --- a/features/nanostack/sal-stack-nanostack/source/libNET/src/net_load_balance.c +++ b/features/nanostack/sal-stack-nanostack/source/libNET/src/net_load_balance.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, Arm Limited and affiliates. + * Copyright (c) 2016-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/features/nanostack/sal-stack-nanostack/source/libNET/src/net_test.c b/features/nanostack/sal-stack-nanostack/source/libNET/src/net_test.c index 668ba809e4bd..59dd87581496 100644 --- a/features/nanostack/sal-stack-nanostack/source/libNET/src/net_test.c +++ b/features/nanostack/sal-stack-nanostack/source/libNET/src/net_test.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, Arm Limited and affiliates. + * Copyright (c) 2016-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/features/nanostack/sal-stack-nanostack/source/libNET/src/ns_net.c b/features/nanostack/sal-stack-nanostack/source/libNET/src/ns_net.c index 88ee5ef95fba..769172a183cc 100644 --- a/features/nanostack/sal-stack-nanostack/source/libNET/src/ns_net.c +++ b/features/nanostack/sal-stack-nanostack/source/libNET/src/ns_net.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -66,6 +66,7 @@ #include "6LoWPAN/Thread/thread_routing.h" #include "6LoWPAN/Thread/thread_bootstrap.h" #include "6LoWPAN/Thread/thread_management_internal.h" +#include "6LoWPAN/ws/ws_bootstrap.h" #include "BorderRouter/border_router.h" #include "Service_Libs/mle_service/mle_service_api.h" #include "6LoWPAN/MAC/mac_data_poll.h" @@ -1071,6 +1072,8 @@ int8_t arm_nwk_interface_configure_6lowpan_bootstrap_set(int8_t interface_id, ne if (net_6lowpan_mode_extension == NET_6LOWPAN_THREAD) { ret_val = thread_node_bootstrap_init(interface_id,bootstrap_mode); + } else if (net_6lowpan_mode_extension == NET_6LOWPAN_WS) { + ret_val = ws_bootstrap_init(interface_id,bootstrap_mode); } else { ret_val = arm_6lowpan_bootstarp_bootstrap_set(interface_id,bootstrap_mode,net_6lowpan_mode_extension); } diff --git a/features/nanostack/sal-stack-nanostack/source/libNET/src/socket_api.c b/features/nanostack/sal-stack-nanostack/source/libNET/src/socket_api.c index 84d5383ba091..567fd0e71441 100644 --- a/features/nanostack/sal-stack-nanostack/source/libNET/src/socket_api.c +++ b/features/nanostack/sal-stack-nanostack/source/libNET/src/socket_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, Arm Limited and affiliates. + * Copyright (c) 2014-2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/features/nanostack/sal-stack-nanostack/source/nsconfig.h b/features/nanostack/sal-stack-nanostack/source/nsconfig.h index a0a4843c0a7b..bd7df30a6321 100644 --- a/features/nanostack/sal-stack-nanostack/source/nsconfig.h +++ b/features/nanostack/sal-stack-nanostack/source/nsconfig.h @@ -29,7 +29,7 @@ #endif #define __ns_cfg_header(x) #x -#define _ns_cfg_header(x) __ns_cfg_header(configs/x.cfg) +#define _ns_cfg_header(x) __ns_cfg_header(configs/cfg_##x.h) #define ns_cfg_header(x) _ns_cfg_header(x) diff --git a/features/nanostack/sal-stack-nanostack/sources.mk b/features/nanostack/sal-stack-nanostack/sources.mk index dac809e23ef9..0217a539d469 100644 --- a/features/nanostack/sal-stack-nanostack/sources.mk +++ b/features/nanostack/sal-stack-nanostack/sources.mk @@ -11,6 +11,7 @@ SRCS += \ source/6LoWPAN/IPHC_Decode/lowpan_context.c \ source/6LoWPAN/MAC/beacon_handler.c \ source/6LoWPAN/MAC/mac_helper.c \ + source/6LoWPAN/MAC/mac_ie_lib.c \ source/6LoWPAN/MAC/mac_response_handler.c \ source/6LoWPAN/MAC/mac_data_poll.c \ source/6LoWPAN/MAC/mac_pairwise_key.c \ @@ -84,17 +85,18 @@ SRCS += \ source/Security/TLS/tls_lib.c \ source/Security/TLS/tls_ccm_crypt.c \ source/Service_Libs/CCM_lib/ccm_security.c \ - source/Service_Libs/fhss/fhss_beacon.c \ - source/Service_Libs/fhss/fhss_beacon_tasklet.c \ source/Service_Libs/fhss/fhss_channel.c \ - source/Service_Libs/fhss/fhss_mac_interface.c \ source/Service_Libs/fhss/fhss_configuration_interface.c \ source/Service_Libs/fhss/fhss_statistics.c \ source/Service_Libs/fhss/fhss.c \ + source/Service_Libs/fhss/fhss_ws_empty_functions.c \ + source/Service_Libs/fhss/fhss_common.c \ source/Service_Libs/fhss/channel_list.c \ source/Service_Libs/fnv_hash/fnv_hash.c \ + source/Service_Libs/mac_neighbor_table/mac_neighbor_table.c \ source/Service_Libs/mle_service/mle_service.c \ source/Service_Libs/mle_service/mle_service_buffer.c \ + source/Service_Libs/mle_service/mle_service_frame_counter_table.c \ source/Service_Libs/mle_service/mle_service_interface.c \ source/Service_Libs/mle_service/mle_service_security.c \ source/Service_Libs/blacklist/blacklist.c \ @@ -117,6 +119,7 @@ SRCS += \ source/6LoWPAN/Thread/thread_common.c \ source/6LoWPAN/Thread/thread_joiner_application.c \ source/6LoWPAN/Thread/thread_leader_service.c \ + source/6LoWPAN/Thread/thread_neighbor_class.c \ source/6LoWPAN/Thread/thread_management_server.c \ source/6LoWPAN/Thread/thread_management_client.c \ source/6LoWPAN/Thread/thread_network_synch.c \ diff --git a/features/netsocket/CellularBase.h b/features/netsocket/CellularBase.h index 4570aa89671d..348324020bfc 100644 --- a/features/netsocket/CellularBase.h +++ b/features/netsocket/CellularBase.h @@ -112,7 +112,8 @@ class CellularBase: public NetworkInterface { */ virtual const char *get_gateway() = 0; - virtual CellularBase *cellularBase() { + virtual CellularBase *cellularBase() + { return this; } diff --git a/features/netsocket/DNS.h b/features/netsocket/DNS.h index 625a2cb16653..9e74744b6b48 100644 --- a/features/netsocket/DNS.h +++ b/features/netsocket/DNS.h @@ -35,7 +35,7 @@ class DNS { * @return 0 on success, negative error code on failure */ virtual nsapi_error_t gethostbyname(const char *host, - SocketAddress *address, nsapi_version_t version = NSAPI_UNSPEC) = 0; + SocketAddress *address, nsapi_version_t version = NSAPI_UNSPEC) = 0; /** Hostname translation callback (asynchronous) * @@ -75,7 +75,7 @@ class DNS { * and can be passed to cancel */ virtual nsapi_value_or_error_t gethostbyname_async(const char *host, hostbyname_cb_t callback, - nsapi_version_t version = NSAPI_UNSPEC) = 0; + nsapi_version_t version = NSAPI_UNSPEC) = 0; /** Cancels asynchronous hostname translation * diff --git a/features/netsocket/EMACInterface.cpp b/features/netsocket/EMACInterface.cpp index 3ed2cb71349a..c864ed881ed2 100644 --- a/features/netsocket/EMACInterface.cpp +++ b/features/netsocket/EMACInterface.cpp @@ -61,11 +61,11 @@ nsapi_error_t EMACInterface::connect() } return _interface->bringup(_dhcp, - _ip_address[0] ? _ip_address : 0, - _netmask[0] ? _netmask : 0, - _gateway[0] ? _gateway : 0, - DEFAULT_STACK, - _blocking); + _ip_address[0] ? _ip_address : 0, + _netmask[0] ? _netmask : 0, + _gateway[0] ? _gateway : 0, + DEFAULT_STACK, + _blocking); } nsapi_error_t EMACInterface::disconnect() diff --git a/features/netsocket/EMACInterface.h b/features/netsocket/EMACInterface.h index 8620fee02809..8db5da5c1b0d 100644 --- a/features/netsocket/EMACInterface.h +++ b/features/netsocket/EMACInterface.h @@ -36,8 +36,7 @@ * the credentials have been set. This is necessary to support specialised * applications such as 6LoWPAN mesh border routers. */ -class EMACInterface : public virtual NetworkInterface -{ +class EMACInterface : public virtual NetworkInterface { public: /** Create an EMAC-based network interface. * @@ -52,9 +51,8 @@ class EMACInterface : public virtual NetworkInterface * @param emac Reference to EMAC to use * @param stack Reference to onboard-network stack to use */ - EMACInterface( - EMAC &emac = EMAC::get_default_instance(), - OnboardNetworkStack &stack = OnboardNetworkStack::get_default_instance()); + EMACInterface(EMAC &emac = EMAC::get_default_instance(), + OnboardNetworkStack &stack = OnboardNetworkStack::get_default_instance()); /** Set a static IP address * @@ -67,8 +65,7 @@ class EMACInterface : public virtual NetworkInterface * @param gateway Null-terminated representation of the local gateway * @return 0 on success, negative error code on failure */ - virtual nsapi_error_t set_network( - const char *ip_address, const char *netmask, const char *gateway); + virtual nsapi_error_t set_network(const char *ip_address, const char *netmask, const char *gateway); /** Enable or disable DHCP on the network * @@ -94,7 +91,7 @@ class EMACInterface : public virtual NetworkInterface * Provided MAC address is intended for info or debug purposes and * may not be provided if the underlying network interface does not * provide a MAC address - * + * * @return Null-terminated representation of the local MAC address * or null if no MAC address is available */ @@ -109,7 +106,7 @@ class EMACInterface : public virtual NetworkInterface /** Get the local network mask * - * @return Null-terminated representation of the local network mask + * @return Null-terminated representation of the local network mask * or null if no network mask has been recieved */ virtual const char *get_netmask(); @@ -148,16 +145,20 @@ class EMACInterface : public virtual NetworkInterface * * @return Reference to the EMAC in use */ - EMAC &get_emac() const { return _emac; } + EMAC &get_emac() const + { + return _emac; + } - virtual EMACInterface *emacInterface() { + virtual EMACInterface *emacInterface() + { return this; } protected: /** Provide access to the underlying stack * - * @return The underlying network stack + * @return The underlying network stack */ virtual NetworkStack *get_stack(); diff --git a/features/netsocket/EthInterface.h b/features/netsocket/EthInterface.h index 3c8038c2101b..ed7a0de8181d 100644 --- a/features/netsocket/EthInterface.h +++ b/features/netsocket/EthInterface.h @@ -27,11 +27,11 @@ * * Common interface that is shared between ethernet hardware. */ -class EthInterface : public virtual NetworkInterface -{ +class EthInterface : public virtual NetworkInterface { public: - virtual EthInterface *ethInterface() { + virtual EthInterface *ethInterface() + { return this; } diff --git a/features/netsocket/EthernetInterface.h b/features/netsocket/EthernetInterface.h index d88377f4ccd8..2c8d6a8affeb 100644 --- a/features/netsocket/EthernetInterface.h +++ b/features/netsocket/EthernetInterface.h @@ -25,8 +25,7 @@ /** EthernetInterface class * Implementation of the NetworkStack for an EMAC-based Ethernet driver */ -class EthernetInterface : public EMACInterface, public EthInterface -{ +class EthernetInterface : public EMACInterface, public EthInterface { public: /** Create an EMAC-based ethernet interface. * @@ -41,9 +40,8 @@ class EthernetInterface : public EMACInterface, public EthInterface * @param emac Reference to EMAC to use * @param stack Reference to onboard-network stack to use */ - EthernetInterface( - EMAC &emac = EMAC::get_default_instance(), - OnboardNetworkStack &stack = OnboardNetworkStack::get_default_instance()) : EMACInterface(emac, stack) { } + EthernetInterface(EMAC &emac = EMAC::get_default_instance(), + OnboardNetworkStack &stack = OnboardNetworkStack::get_default_instance()) : EMACInterface(emac, stack) { } }; #endif diff --git a/features/netsocket/InternetSocket.cpp b/features/netsocket/InternetSocket.cpp index 4e44ae574b1a..da7573986e0e 100644 --- a/features/netsocket/InternetSocket.cpp +++ b/features/netsocket/InternetSocket.cpp @@ -186,7 +186,7 @@ nsapi_error_t InternetSocket::getsockopt(int level, int optname, void *optval, u } void InternetSocket::event() { - _event_flag.set(READ_FLAG|WRITE_FLAG); + _event_flag.set(READ_FLAG | WRITE_FLAG); _pending += 1; if (_callback && _pending == 1) { diff --git a/features/netsocket/InternetSocket.h b/features/netsocket/InternetSocket.h index aea5d40c0d91..511ff34b247f 100644 --- a/features/netsocket/InternetSocket.h +++ b/features/netsocket/InternetSocket.h @@ -50,7 +50,8 @@ class InternetSocket : public Socket { nsapi_error_t open(NetworkStack *stack); template - nsapi_error_t open(S *stack) { + nsapi_error_t open(S *stack) + { return open(nsapi_create_stack(stack)); } @@ -196,8 +197,8 @@ class InternetSocket : public Socket { * 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.") + "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 @@ -209,9 +210,10 @@ class InternetSocket : public Socket { */ template MBED_DEPRECATED_SINCE("mbed-os-5.1", - "The attach function does not support cv-qualifiers. Replaced by " - "attach(callback(obj, method)).") - void attach(T *obj, M method) { + "The attach function does not support cv-qualifiers. Replaced by " + "attach(callback(obj, method)).") + void attach(T *obj, M method) + { attach(mbed::callback(obj, method)); } diff --git a/features/netsocket/MeshInterface.h b/features/netsocket/MeshInterface.h index f833571cd934..e6f4efb67318 100644 --- a/features/netsocket/MeshInterface.h +++ b/features/netsocket/MeshInterface.h @@ -27,11 +27,11 @@ * * Common interface that is shared between mesh hardware */ -class MeshInterface : public virtual NetworkInterface -{ +class MeshInterface : public virtual NetworkInterface { public: - virtual MeshInterface *meshInterface() { + virtual MeshInterface *meshInterface() + { return this; } diff --git a/features/netsocket/NetworkInterface.h b/features/netsocket/NetworkInterface.h index 5c9afd57da24..7eb674df13e4 100644 --- a/features/netsocket/NetworkInterface.h +++ b/features/netsocket/NetworkInterface.h @@ -122,8 +122,7 @@ class NetworkInterface: public DNS { * @param gateway Null-terminated representation of the local gateway * @return 0 on success, negative error code on failure */ - virtual nsapi_error_t set_network( - const char *ip_address, const char *netmask, const char *gateway); + virtual nsapi_error_t set_network(const char *ip_address, const char *netmask, const char *gateway); /** Enable or disable DHCP on the network * @@ -163,7 +162,7 @@ class NetworkInterface: public DNS { * @return 0 on success, negative error code on failure */ virtual nsapi_error_t gethostbyname(const char *host, - SocketAddress *address, nsapi_version_t version = NSAPI_UNSPEC); + SocketAddress *address, nsapi_version_t version = NSAPI_UNSPEC); /** Hostname translation callback (asynchronous) * @@ -203,7 +202,7 @@ class NetworkInterface: public DNS { * and can be passed to cancel */ virtual nsapi_value_or_error_t gethostbyname_async(const char *host, hostbyname_cb_t callback, - nsapi_version_t version = NSAPI_UNSPEC); + nsapi_version_t version = NSAPI_UNSPEC); /** Cancels asynchronous hostname translation * @@ -245,27 +244,32 @@ class NetworkInterface: public DNS { virtual nsapi_error_t set_blocking(bool blocking); /** Dynamic downcast to an EthInterface */ - virtual EthInterface *ethInterface() { + virtual EthInterface *ethInterface() + { return 0; } /** Dynamic downcast to a WiFiInterface */ - virtual WiFiInterface *wifiInterface() { + virtual WiFiInterface *wifiInterface() + { return 0; } /** Dynamic downcast to a MeshInterface */ - virtual MeshInterface *meshInterface() { + virtual MeshInterface *meshInterface() + { return 0; } /** Dynamic downcast to a CellularBase */ - virtual CellularBase *cellularBase() { + virtual CellularBase *cellularBase() + { return 0; } /** Dynamic downcast to an EMACInterface */ - virtual EMACInterface *emacInterface() { + virtual EMACInterface *emacInterface() + { return 0; } diff --git a/features/netsocket/NetworkStack.cpp b/features/netsocket/NetworkStack.cpp index e36ff43cd83b..72b012d4ebb0 100644 --- a/features/netsocket/NetworkStack.cpp +++ b/features/netsocket/NetworkStack.cpp @@ -148,14 +148,13 @@ call_in_callback_cb_t NetworkStack::get_call_in_callback() } // NetworkStackWrapper class for encapsulating the raw nsapi_stack structure -class NetworkStackWrapper : public NetworkStack -{ +class NetworkStackWrapper : public NetworkStack { private: inline nsapi_stack_t *_stack() { return reinterpret_cast( - reinterpret_cast(this) - - offsetof(nsapi_stack_t, _stack_buffer)); + reinterpret_cast(this) + - offsetof(nsapi_stack_t, _stack_buffer)); } inline const nsapi_stack_api_t *_stack_api() @@ -358,7 +357,7 @@ class NetworkStackWrapper : public NetworkStack NetworkStack *nsapi_create_stack(nsapi_stack_t *stack) { MBED_STATIC_ASSERT(sizeof stack->_stack_buffer >= sizeof(NetworkStackWrapper), - "The nsapi_stack_t stack buffer must fit a NetworkStackWrapper"); + "The nsapi_stack_t stack buffer must fit a NetworkStackWrapper"); return new (stack->_stack_buffer) NetworkStackWrapper; } diff --git a/features/netsocket/NetworkStack.h b/features/netsocket/NetworkStack.h index 96acf96626c4..2ea7757dcab9 100644 --- a/features/netsocket/NetworkStack.h +++ b/features/netsocket/NetworkStack.h @@ -34,8 +34,7 @@ class OnboardNetworkStack; * for instantiating network sockets. * @addtogroup netsocket */ -class NetworkStack: public DNS -{ +class NetworkStack: public DNS { public: virtual ~NetworkStack() {}; @@ -61,7 +60,7 @@ class NetworkStack: public DNS * @return 0 on success, negative error code on failure */ virtual nsapi_error_t gethostbyname(const char *host, - SocketAddress *address, nsapi_version_t version = NSAPI_UNSPEC); + SocketAddress *address, nsapi_version_t version = NSAPI_UNSPEC); /** Hostname translation callback (asynchronous) * @@ -101,7 +100,7 @@ class NetworkStack: public DNS * and can be passed to cancel */ virtual nsapi_value_or_error_t gethostbyname_async(const char *host, hostbyname_cb_t callback, - nsapi_version_t version = NSAPI_UNSPEC); + nsapi_version_t version = NSAPI_UNSPEC); /** Cancels asynchronous hostname translation * @@ -162,7 +161,10 @@ class NetworkStack: public DNS virtual nsapi_error_t getstackopt(int level, int optname, void *optval, unsigned *optlen); /** Dynamic downcast to a OnboardNetworkStack */ - virtual OnboardNetworkStack *onboardNetworkStack() { return 0; } + virtual OnboardNetworkStack *onboardNetworkStack() + { + return 0; + } protected: friend class InternetSocket; @@ -247,7 +249,7 @@ class NetworkStack: public DNS * @return 0 on success, negative error code on failure */ virtual nsapi_error_t socket_accept(nsapi_socket_t server, - nsapi_socket_t *handle, SocketAddress *address=0) = 0; + nsapi_socket_t *handle, SocketAddress *address = 0) = 0; /** Send data over a TCP socket * @@ -264,7 +266,7 @@ class NetworkStack: public DNS * code on failure */ virtual nsapi_size_or_error_t socket_send(nsapi_socket_t handle, - const void *data, nsapi_size_t size) = 0; + const void *data, nsapi_size_t size) = 0; /** Receive data over a TCP socket * @@ -281,7 +283,7 @@ class NetworkStack: public DNS * code on failure */ virtual nsapi_size_or_error_t socket_recv(nsapi_socket_t handle, - void *data, nsapi_size_t size) = 0; + void *data, nsapi_size_t size) = 0; /** Send a packet over a UDP socket * @@ -299,7 +301,7 @@ class NetworkStack: public DNS * code on failure */ virtual nsapi_size_or_error_t socket_sendto(nsapi_socket_t handle, const SocketAddress &address, - const void *data, nsapi_size_t size) = 0; + const void *data, nsapi_size_t size) = 0; /** Receive a packet over a UDP socket * @@ -317,7 +319,7 @@ class NetworkStack: public DNS * code on failure */ virtual nsapi_size_or_error_t socket_recvfrom(nsapi_socket_t handle, SocketAddress *address, - void *buffer, nsapi_size_t size) = 0; + void *buffer, nsapi_size_t size) = 0; /** Register a callback on state change of the socket * @@ -348,7 +350,7 @@ class NetworkStack: public DNS * @return 0 on success, negative error code on failure */ virtual nsapi_error_t setsockopt(nsapi_socket_t handle, int level, - int optname, const void *optval, unsigned optlen); + int optname, const void *optval, unsigned optlen); /* Get stack-specific socket options * @@ -364,7 +366,7 @@ class NetworkStack: public DNS * @return 0 on success, negative error code on failure */ virtual nsapi_error_t getsockopt(nsapi_socket_t handle, int level, - int optname, void *optval, unsigned *optlen); + int optname, void *optval, unsigned *optlen); private: diff --git a/features/netsocket/OnboardNetworkStack.h b/features/netsocket/OnboardNetworkStack.h index 9a154c7e0fd5..35ca37b08b90 100644 --- a/features/netsocket/OnboardNetworkStack.h +++ b/features/netsocket/OnboardNetworkStack.h @@ -62,9 +62,9 @@ class OnboardNetworkStack : public NetworkStack { * @return NSAPI_ERROR_OK on success, or error code */ virtual nsapi_error_t bringup(bool dhcp, const char *ip, - const char *netmask, const char *gw, - nsapi_ip_stack_t stack = DEFAULT_STACK, - bool blocking = true) = 0; + const char *netmask, const char *gw, + nsapi_ip_stack_t stack = DEFAULT_STACK, + bool blocking = true) = 0; /** Disconnect interface from the network * diff --git a/features/netsocket/Socket.h b/features/netsocket/Socket.h index f2a055e829fb..fe560b4be7b6 100644 --- a/features/netsocket/Socket.h +++ b/features/netsocket/Socket.h @@ -115,7 +115,7 @@ class Socket { * code on failure */ virtual nsapi_size_or_error_t sendto(const SocketAddress &address, - const void *data, nsapi_size_t size) = 0; + const void *data, nsapi_size_t size) = 0; /** Receive a data from a socket * @@ -138,7 +138,7 @@ class Socket { * code on failure */ virtual nsapi_size_or_error_t recvfrom(SocketAddress *address, - void *data, nsapi_size_t size) = 0; + void *data, nsapi_size_t size) = 0; /** Bind a specific address to a socket. * diff --git a/features/netsocket/SocketAddress.cpp b/features/netsocket/SocketAddress.cpp index 4851eb16e59b..b83c690fca07 100644 --- a/features/netsocket/SocketAddress.cpp +++ b/features/netsocket/SocketAddress.cpp @@ -35,7 +35,7 @@ static bool ipv4_is_valid(const char *addr) } // Ending with '.' garuntees host - if (i > 0 && addr[i-1] == '.') { + if (i > 0 && addr[i - 1] == '.') { return false; } @@ -49,9 +49,9 @@ static bool ipv6_is_valid(const char *addr) int colons = 0; for (int i = 0; addr[i]; i++) { if (!(addr[i] >= '0' && addr[i] <= '9') && - !(addr[i] >= 'a' && addr[i] <= 'f') && - !(addr[i] >= 'A' && addr[i] <= 'F') && - addr[i] != ':') { + !(addr[i] >= 'a' && addr[i] <= 'f') && + !(addr[i] >= 'A' && addr[i] <= 'F') && + addr[i] != ':') { return false; } if (addr[i] == ':') { diff --git a/features/netsocket/SocketAddress.h b/features/netsocket/SocketAddress.h index c7cc0a097fde..5725d0cfe42f 100644 --- a/features/netsocket/SocketAddress.h +++ b/features/netsocket/SocketAddress.h @@ -49,8 +49,8 @@ class SocketAddress { */ template MBED_DEPRECATED_SINCE("mbed-os-5.1.3", - "Constructors hide possible errors. Replaced by " - "NetworkInterface::gethostbyname.") + "Constructors hide possible errors. Replaced by " + "NetworkInterface::gethostbyname.") SocketAddress(S *stack, const char *host, uint16_t port = 0) { _SocketAddress(nsapi_create_stack(stack), host, port); diff --git a/features/netsocket/TCPServer.h b/features/netsocket/TCPServer.h index d00c860af9cd..721e5de4439d 100644 --- a/features/netsocket/TCPServer.h +++ b/features/netsocket/TCPServer.h @@ -35,7 +35,7 @@ class TCPServer : public TCPSocket { * Must call open to initialize the socket on a network stack. */ MBED_DEPRECATED_SINCE("mbed-os-5.10", - "TCPServer is deprecated, use TCPSocket") + "TCPServer is deprecated, use TCPSocket") TCPServer(); /** Create a socket on a network interface @@ -47,7 +47,7 @@ class TCPServer : public TCPSocket { */ template MBED_DEPRECATED_SINCE("mbed-os-5.10", - "TCPServer is deprecated, use TCPSocket") + "TCPServer is deprecated, use TCPSocket") TCPServer(S *stack) { open(stack); @@ -59,6 +59,9 @@ class TCPServer : public TCPSocket { */ virtual ~TCPServer(); + // Allow legacy TCPServer::accept() to override inherited Socket::accept() + using TCPSocket::accept; + /** Accepts a connection on a TCP socket * * The server socket must be bound and set to listen for connections. @@ -74,7 +77,7 @@ class TCPServer : public TCPSocket { * @return 0 on success, negative error code on failure */ MBED_DEPRECATED_SINCE("mbed-os-5.10", - "TCPServer::accept() is deprecated, use Socket *Socket::accept() instead") + "TCPServer::accept() is deprecated, use Socket *Socket::accept() instead") nsapi_error_t accept(TCPSocket *connection, SocketAddress *address = NULL); }; diff --git a/features/netsocket/TCPSocket.h b/features/netsocket/TCPSocket.h index 49bef5b90473..33e0ae3033e2 100644 --- a/features/netsocket/TCPSocket.h +++ b/features/netsocket/TCPSocket.h @@ -55,10 +55,13 @@ class TCPSocket : public InternetSocket { */ virtual ~TCPSocket(); - /** Override multicast functions to return error for TCP - * - */ - virtual int join_multicast_group(const SocketAddress &address) { return NSAPI_ERROR_UNSUPPORTED; } + /** Override multicast functions to return error for TCP + * + */ + virtual int join_multicast_group(const SocketAddress &address) + { + return NSAPI_ERROR_UNSUPPORTED; + } /** Connects TCP socket to a remote host * @@ -130,7 +133,7 @@ class TCPSocket : public InternetSocket { * code on failure */ virtual nsapi_size_or_error_t sendto(const SocketAddress &address, - const void *data, nsapi_size_t size); + const void *data, nsapi_size_t size); /** Receive a data from a socket * @@ -148,7 +151,7 @@ class TCPSocket : public InternetSocket { * code on failure */ virtual nsapi_size_or_error_t recvfrom(SocketAddress *address, - void *data, nsapi_size_t size); + void *data, nsapi_size_t size); /** Accepts a connection on a socket. * diff --git a/features/netsocket/UDPSocket.cpp b/features/netsocket/UDPSocket.cpp index b798b204beab..c4f4ed45be5f 100644 --- a/features/netsocket/UDPSocket.cpp +++ b/features/netsocket/UDPSocket.cpp @@ -89,7 +89,7 @@ nsapi_size_or_error_t UDPSocket::sendto(const SocketAddress &address, const void _writers--; if (!_socket || !_writers) { - _event_flag.set(FINISHED_FLAG); + _event_flag.set(FINISHED_FLAG); } _lock.unlock(); return ret; @@ -97,8 +97,9 @@ nsapi_size_or_error_t UDPSocket::sendto(const SocketAddress &address, const void nsapi_size_or_error_t UDPSocket::send(const void *data, nsapi_size_t size) { - if (!_remote_peer) + if (!_remote_peer) { return NSAPI_ERROR_NO_ADDRESS; + } return sendto(_remote_peer, data, size); } @@ -151,7 +152,7 @@ nsapi_size_or_error_t UDPSocket::recvfrom(SocketAddress *address, void *buffer, _readers--; if (!_socket || !_readers) { - _event_flag.set(FINISHED_FLAG); + _event_flag.set(FINISHED_FLAG); } _lock.unlock(); diff --git a/features/netsocket/UDPSocket.h b/features/netsocket/UDPSocket.h index 60db9cf63786..087bb8932d3c 100644 --- a/features/netsocket/UDPSocket.h +++ b/features/netsocket/UDPSocket.h @@ -73,7 +73,7 @@ class UDPSocket : public InternetSocket { * code on failure */ virtual nsapi_size_or_error_t sendto(const char *host, uint16_t port, - const void *data, nsapi_size_t size); + const void *data, nsapi_size_t size); /** Send a packet over a UDP socket * @@ -91,7 +91,7 @@ class UDPSocket : public InternetSocket { * code on failure */ virtual nsapi_size_or_error_t sendto(const SocketAddress &address, - const void *data, nsapi_size_t size); + const void *data, nsapi_size_t size); /** Receive a datagram over a UDP socket * @@ -115,7 +115,7 @@ class UDPSocket : public InternetSocket { * code on failure */ virtual nsapi_size_or_error_t recvfrom(SocketAddress *address, - void *data, nsapi_size_t size); + void *data, nsapi_size_t size); /** Set remote peer address * diff --git a/features/netsocket/WiFiAccessPoint.h b/features/netsocket/WiFiAccessPoint.h index b590c45aa269..e74cf700560d 100644 --- a/features/netsocket/WiFiAccessPoint.h +++ b/features/netsocket/WiFiAccessPoint.h @@ -25,8 +25,7 @@ * Class that represents a WiFi Access Point * Common interface that is shared between WiFi devices */ -class WiFiAccessPoint -{ +class WiFiAccessPoint { /** WiFiAccessPoint lifetime */ public: diff --git a/features/netsocket/WiFiInterface.h b/features/netsocket/WiFiInterface.h index 0bc07516bebb..1b876d7e65ab 100644 --- a/features/netsocket/WiFiInterface.h +++ b/features/netsocket/WiFiInterface.h @@ -27,8 +27,7 @@ * Common interface that is shared between WiFi devices * @addtogroup netsocket */ -class WiFiInterface: public virtual NetworkInterface -{ +class WiFiInterface: public virtual NetworkInterface { public: /** Get the default WiFi interface. * @@ -49,7 +48,7 @@ class WiFiInterface: public virtual NetworkInterface * @return 0 on success, or error code on failure */ virtual nsapi_error_t set_credentials(const char *ssid, const char *pass, - nsapi_security_t security = NSAPI_SECURITY_NONE) = 0; + nsapi_security_t security = NSAPI_SECURITY_NONE) = 0; /** Set the WiFi network channel * @@ -76,7 +75,7 @@ class WiFiInterface: public virtual NetworkInterface * @return 0 on success, or error code on failure */ virtual nsapi_error_t connect(const char *ssid, const char *pass, - nsapi_security_t security = NSAPI_SECURITY_NONE, uint8_t channel = 0) = 0; + nsapi_security_t security = NSAPI_SECURITY_NONE, uint8_t channel = 0) = 0; /** Start the interface * @@ -106,7 +105,8 @@ class WiFiInterface: public virtual NetworkInterface */ virtual nsapi_size_or_error_t scan(WiFiAccessPoint *res, nsapi_size_t count) = 0; - virtual WiFiInterface *wifiInterface() { + virtual WiFiInterface *wifiInterface() + { return this; } diff --git a/features/netsocket/emac-drivers/TARGET_NUVOTON_EMAC/numaker_emac.cpp b/features/netsocket/emac-drivers/TARGET_NUVOTON_EMAC/numaker_emac.cpp index 93b0b147b8d2..1fa47510cb3c 100644 --- a/features/netsocket/emac-drivers/TARGET_NUVOTON_EMAC/numaker_emac.cpp +++ b/features/netsocket/emac-drivers/TARGET_NUVOTON_EMAC/numaker_emac.cpp @@ -220,9 +220,9 @@ void NUMAKER_EMAC::packet_rx() */ bool NUMAKER_EMAC::link_out(emac_mem_buf_t *buf) { - bool result; + bool result = false; emac_mem_buf_t *q; - uint8_t *buffer = numaker_eth_get_tx_buf(); + uint8_t *buffer = NULL; uint32_t framelength = 0; uint32_t bufferoffset = 0; uint32_t byteslefttocopy = 0; @@ -230,7 +230,9 @@ bool NUMAKER_EMAC::link_out(emac_mem_buf_t *buf) /* Get exclusive access */ TXLockMutex.lock(); + buffer = numaker_eth_get_tx_buf(); NU_DEBUGF(("%s ... buffer=0x%x\r\n",__FUNCTION__, buffer)); + if( buffer == NULL ) goto error; /* copy frame from buf to driver buffers */ for (q = buf; q != NULL; q = memory_manager->get_next(q)) { diff --git a/features/netsocket/emac-drivers/TARGET_Silicon_Labs/sl_emac_config.h b/features/netsocket/emac-drivers/TARGET_Silicon_Labs/sl_emac_config.h index cd60f95d4738..86c7d9938988 100644 --- a/features/netsocket/emac-drivers/TARGET_Silicon_Labs/sl_emac_config.h +++ b/features/netsocket/emac-drivers/TARGET_Silicon_Labs/sl_emac_config.h @@ -34,7 +34,12 @@ /** Timeout in milliseconds for polling the PHY link status */ #define SL_ETH_LINK_POLL_PERIOD_MS (500) /** Default Ethernet worker thread stack size in bytes */ +#include "mbed_trace.h" +#if MBED_CONF_MBED_TRACE_ENABLE == 1 +#define SL_ETH_THREAD_STACKSIZE (768) +#else #define SL_ETH_THREAD_STACKSIZE (512) +#endif /** Default Ethernet worker thread stack priority */ #define SL_ETH_THREAD_PRIORITY (osPriorityHigh) /** Name of interface */ diff --git a/features/netsocket/nsapi_dns.cpp b/features/netsocket/nsapi_dns.cpp index 60bb10a0e7df..aa2de3aafd1d 100644 --- a/features/netsocket/nsapi_dns.cpp +++ b/features/netsocket/nsapi_dns.cpp @@ -101,6 +101,7 @@ static void nsapi_dns_query_async_socket_callback_handle(NetworkStack *stack); static void nsapi_dns_query_async_response(void *ptr); static void nsapi_dns_query_async_initiate_next(void); +// *INDENT-OFF* static nsapi_addr_t dns_servers[DNS_SERVERS_SIZE] = { {NSAPI_IPv4, {8, 8, 8, 8}}, // Google {NSAPI_IPv4, {209, 244, 0, 3}}, // Level 3 @@ -110,6 +111,7 @@ static nsapi_addr_t dns_servers[DNS_SERVERS_SIZE] = { {NSAPI_IPv6, {0x20,0x01, 0x16,0x08, 0,0x10, 0,0x25, // DNS.WATCH 0,0, 0,0, 0x1c,0x04, 0xb1,0x2f}}, }; +// *INDENT-ON* #if (MBED_CONF_NSAPI_DNS_CACHE_SIZE > 0) static DNS_CACHE *dns_cache[MBED_CONF_NSAPI_DNS_CACHE_SIZE]; @@ -129,7 +131,7 @@ static bool dns_timer_running = false; extern "C" nsapi_error_t nsapi_dns_add_server(nsapi_addr_t addr) { memmove(&dns_servers[1], &dns_servers[0], - (DNS_SERVERS_SIZE-1)*sizeof(nsapi_addr_t)); + (DNS_SERVERS_SIZE - 1)*sizeof(nsapi_addr_t)); dns_servers[0] = addr; return NSAPI_ERROR_OK; @@ -377,7 +379,7 @@ static nsapi_error_t nsapi_dns_cache_find(const char *host, nsapi_version_t vers delete dns_cache[i]; dns_cache[i] = NULL; } else if ((version == NSAPI_UNSPEC || version == dns_cache[i]->address.version) && - strcmp(dns_cache[i]->host, host) == 0) { + strcmp(dns_cache[i]->host, host) == 0) { if (address) { *address = dns_cache[i]->address; } @@ -431,7 +433,7 @@ static nsapi_error_t nsapi_dns_get_server_addr(NetworkStack *stack, uint8_t *ind // core query function static nsapi_size_or_error_t nsapi_dns_query_multiple(NetworkStack *stack, const char *host, - nsapi_addr_t *addr, unsigned addr_count, nsapi_version_t version) + nsapi_addr_t *addr, unsigned addr_count, nsapi_version_t version) { // check for valid host name int host_len = host ? strlen(host) : 0; @@ -454,7 +456,7 @@ static nsapi_size_or_error_t nsapi_dns_query_multiple(NetworkStack *stack, const socket.set_timeout(MBED_CONF_NSAPI_DNS_RESPONSE_WAIT_TIME); // create network packet - uint8_t * const packet = (uint8_t *)malloc(DNS_BUFFER_SIZE); + uint8_t *const packet = (uint8_t *)malloc(DNS_BUFFER_SIZE); if (!packet) { return NSAPI_ERROR_NO_MEMORY; } @@ -538,14 +540,14 @@ static nsapi_size_or_error_t nsapi_dns_query_multiple(NetworkStack *stack, const // convenience functions for other forms of queries extern "C" nsapi_size_or_error_t nsapi_dns_query_multiple(nsapi_stack_t *stack, const char *host, - nsapi_addr_t *addr, nsapi_size_t addr_count, nsapi_version_t version) + nsapi_addr_t *addr, nsapi_size_t addr_count, nsapi_version_t version) { NetworkStack *nstack = nsapi_create_stack(stack); return nsapi_dns_query_multiple(nstack, host, addr, addr_count, version); } nsapi_size_or_error_t nsapi_dns_query_multiple(NetworkStack *stack, const char *host, - SocketAddress *addresses, nsapi_size_t addr_count, nsapi_version_t version) + SocketAddress *addresses, nsapi_size_t addr_count, nsapi_version_t version) { nsapi_addr_t *addrs = new (std::nothrow) nsapi_addr_t[addr_count]; nsapi_size_or_error_t result = nsapi_dns_query_multiple(stack, host, addrs, addr_count, version); @@ -561,7 +563,7 @@ nsapi_size_or_error_t nsapi_dns_query_multiple(NetworkStack *stack, const char * } extern "C" nsapi_error_t nsapi_dns_query(nsapi_stack_t *stack, const char *host, - nsapi_addr_t *addr, nsapi_version_t version) + nsapi_addr_t *addr, nsapi_version_t version) { NetworkStack *nstack = nsapi_create_stack(stack); nsapi_size_or_error_t result = nsapi_dns_query_multiple(nstack, host, addr, 1, version); @@ -569,7 +571,7 @@ extern "C" nsapi_error_t nsapi_dns_query(nsapi_stack_t *stack, const char *host, } nsapi_error_t nsapi_dns_query(NetworkStack *stack, const char *host, - SocketAddress *address, nsapi_version_t version) + SocketAddress *address, nsapi_version_t version) { nsapi_addr_t addr; nsapi_size_or_error_t result = nsapi_dns_query_multiple(stack, host, &addr, 1, version); @@ -578,8 +580,8 @@ nsapi_error_t nsapi_dns_query(NetworkStack *stack, const char *host, } nsapi_value_or_error_t nsapi_dns_query_async(NetworkStack *stack, const char *host, - NetworkStack::hostbyname_cb_t callback, call_in_callback_cb_t call_in_cb, - nsapi_version_t version) + NetworkStack::hostbyname_cb_t callback, call_in_callback_cb_t call_in_cb, + nsapi_version_t version) { return nsapi_dns_query_multiple_async(stack, host, callback, 0, call_in_cb, version); } @@ -600,8 +602,8 @@ nsapi_error_t nsapi_dns_call_in(call_in_callback_cb_t cb, int delay, mbed::Callb } nsapi_value_or_error_t nsapi_dns_query_multiple_async(NetworkStack *stack, const char *host, - NetworkStack::hostbyname_cb_t callback, nsapi_size_t addr_count, - call_in_callback_cb_t call_in_cb, nsapi_version_t version) + NetworkStack::hostbyname_cb_t callback, nsapi_size_t addr_count, + call_in_callback_cb_t call_in_cb, nsapi_version_t version) { dns_mutex->lock(); @@ -724,7 +726,7 @@ static void nsapi_dns_query_async_initiate_next(void) query = dns_query_queue[i]; id = dns_query_queue[i]->unique_id; } - // If some query is already ongoing do not trigger + // If some query is already ongoing do not trigger } else if (dns_query_queue[i]->state == DNS_INITIATED) { query = NULL; break; @@ -770,7 +772,7 @@ static void nsapi_dns_query_async_timeout(void) // Retries dns_query_queue[i]->socket_timeout = 0; nsapi_dns_call_in(dns_query_queue[i]->call_in_cb, 0, - mbed::callback(nsapi_dns_query_async_send, reinterpret_cast(dns_query_queue[i]->unique_id))); + mbed::callback(nsapi_dns_query_async_send, reinterpret_cast(dns_query_queue[i]->unique_id))); } } @@ -906,7 +908,7 @@ static nsapi_error_t nsapi_dns_query_async_delete(int unique_id) for (int i = 0; i < DNS_QUERY_QUEUE_SIZE; i++) { if (dns_query_queue[i] && dns_query_queue[i] != query && dns_query_queue[i]->socket && - dns_query_queue[i]->stack == query->stack) { + dns_query_queue[i]->stack == query->stack) { close_socket = false; } } diff --git a/features/netsocket/nsapi_dns.h b/features/netsocket/nsapi_dns.h index 400da5affb94..4142a00b99e4 100644 --- a/features/netsocket/nsapi_dns.h +++ b/features/netsocket/nsapi_dns.h @@ -38,7 +38,7 @@ * NSAPI_ERROR_DNS_FAILURE indicates the host could not be found */ nsapi_error_t nsapi_dns_query(nsapi_stack_t *stack, const char *host, - nsapi_addr_t *addr, nsapi_version_t version); + nsapi_addr_t *addr, nsapi_version_t version); /** Query a domain name server for multiple IP address of a given hostname * @@ -51,7 +51,7 @@ nsapi_error_t nsapi_dns_query(nsapi_stack_t *stack, const char *host, * NSAPI_ERROR_DNS_FAILURE indicates the host could not be found */ nsapi_size_or_error_t nsapi_dns_query_multiple(nsapi_stack_t *stack, const char *host, - nsapi_addr_t *addr, nsapi_size_t addr_count, nsapi_version_t version); + nsapi_addr_t *addr, nsapi_size_t addr_count, nsapi_version_t version); /** Add a domain name server to list of servers to query * @@ -75,7 +75,7 @@ typedef mbed::Callback user_ * NSAPI_ERROR_DNS_FAILURE indicates the host could not be found */ nsapi_error_t nsapi_dns_query(NetworkStack *stack, const char *host, - SocketAddress *addr, nsapi_version_t version = NSAPI_IPv4); + SocketAddress *addr, nsapi_version_t version = NSAPI_IPv4); /** Query a domain name server for an IP address of a given hostname * @@ -88,8 +88,8 @@ nsapi_error_t nsapi_dns_query(NetworkStack *stack, const char *host, * cancel, NSAPI_ERROR_DNS_FAILURE indicates the host could not be found */ nsapi_error_t nsapi_dns_query_async(NetworkStack *stack, const char *host, - NetworkStack::hostbyname_cb_t callback, call_in_callback_cb_t call_in_cb, - nsapi_version_t version = NSAPI_IPv4); + NetworkStack::hostbyname_cb_t callback, call_in_callback_cb_t call_in_cb, + nsapi_version_t version = NSAPI_IPv4); /** Query a domain name server for an IP address of a given hostname (asynchronous) * @@ -101,7 +101,7 @@ nsapi_error_t nsapi_dns_query_async(NetworkStack *stack, const char *host, * NSAPI_ERROR_DNS_FAILURE indicates the host could not be found */ extern "C" nsapi_error_t nsapi_dns_query(nsapi_stack_t *stack, const char *host, - nsapi_addr_t *addr, nsapi_version_t version = NSAPI_IPv4); + nsapi_addr_t *addr, nsapi_version_t version = NSAPI_IPv4); /** Query a domain name server for an IP address of a given hostname * @@ -114,7 +114,7 @@ extern "C" nsapi_error_t nsapi_dns_query(nsapi_stack_t *stack, const char *host, */ template nsapi_error_t nsapi_dns_query(S *stack, const char *host, - SocketAddress *addr, nsapi_version_t version = NSAPI_IPv4) + SocketAddress *addr, nsapi_version_t version = NSAPI_IPv4) { return nsapi_dns_query(nsapi_create_stack(stack), host, addr, version); } @@ -130,7 +130,7 @@ nsapi_error_t nsapi_dns_query(S *stack, const char *host, * NSAPI_ERROR_DNS_FAILURE indicates the host could not be found */ nsapi_size_or_error_t nsapi_dns_query_multiple(NetworkStack *stack, const char *host, - SocketAddress *addr, nsapi_size_t addr_count, nsapi_version_t version = NSAPI_IPv4); + SocketAddress *addr, nsapi_size_t addr_count, nsapi_version_t version = NSAPI_IPv4); /** Query a domain name server for an IP address of a given hostname (asynchronous) * @@ -144,8 +144,8 @@ nsapi_size_or_error_t nsapi_dns_query_multiple(NetworkStack *stack, const char * * cancel, NSAPI_ERROR_DNS_FAILURE indicates the host could not be found */ nsapi_size_or_error_t nsapi_dns_query_multiple_async(NetworkStack *stack, const char *host, - NetworkStack::hostbyname_cb_t callback, nsapi_size_t addr_count, - call_in_callback_cb_t call_in_cb, nsapi_version_t version = NSAPI_IPv4); + NetworkStack::hostbyname_cb_t callback, nsapi_size_t addr_count, + call_in_callback_cb_t call_in_cb, nsapi_version_t version = NSAPI_IPv4); /** Query a domain name server for multiple IP address of a given hostname * @@ -158,7 +158,7 @@ nsapi_size_or_error_t nsapi_dns_query_multiple_async(NetworkStack *stack, const * NSAPI_ERROR_DNS_FAILURE indicates the host could not be found */ extern "C" nsapi_size_or_error_t nsapi_dns_query_multiple(nsapi_stack_t *stack, const char *host, - nsapi_addr_t *addr, nsapi_size_t addr_count, nsapi_version_t version = NSAPI_IPv4); + nsapi_addr_t *addr, nsapi_size_t addr_count, nsapi_version_t version = NSAPI_IPv4); /** Query a domain name server for multiple IP address of a given hostname @@ -173,10 +173,10 @@ extern "C" nsapi_size_or_error_t nsapi_dns_query_multiple(nsapi_stack_t *stack, */ template nsapi_size_or_error_t nsapi_dns_query_multiple(S *stack, const char *host, - SocketAddress *addr, nsapi_size_t addr_count, nsapi_version_t version = NSAPI_IPv4) + SocketAddress *addr, nsapi_size_t addr_count, nsapi_version_t version = NSAPI_IPv4) { return nsapi_dns_query_multiple(nsapi_create_stack(stack), - host, addr, addr_count, version); + host, addr, addr_count, version); } /** Cancels asynchronous hostname translation diff --git a/features/netsocket/nsapi_ppp.h b/features/netsocket/nsapi_ppp.h index 4e3a284c4d3c..8d47dffe6ae0 100644 --- a/features/netsocket/nsapi_ppp.h +++ b/features/netsocket/nsapi_ppp.h @@ -47,7 +47,7 @@ nsapi_error_t nsapi_ppp_set_blocking(bool blocking); * * @return 0 on success, negative error code on failure */ -nsapi_error_t nsapi_ppp_connect(FileHandle *stream, Callback status_cb=0, const char *uname=0, const char *pwd=0, const nsapi_ip_stack_t stack=DEFAULT_STACK); +nsapi_error_t nsapi_ppp_connect(FileHandle *stream, Callback status_cb = 0, const char *uname = 0, const char *pwd = 0, const nsapi_ip_stack_t stack = DEFAULT_STACK); /** Close a PPP connection * diff --git a/features/netsocket/nsapi_types.h b/features/netsocket/nsapi_types.h index 48fca1d011b5..232236b6c665 100644 --- a/features/netsocket/nsapi_types.h +++ b/features/netsocket/nsapi_types.h @@ -64,7 +64,7 @@ enum nsapi_error { * * @enum nsapi_connection_status */ - typedef enum nsapi_connection_status { +typedef enum nsapi_connection_status { NSAPI_STATUS_LOCAL_UP = 0, /*!< local IP address set */ NSAPI_STATUS_GLOBAL_UP = 1, /*!< global IP address set */ NSAPI_STATUS_DISCONNECTED = 2, /*!< no connection to network */ @@ -79,7 +79,7 @@ enum nsapi_error { * * @enum nsapi_event */ - typedef enum nsapi_event { +typedef enum nsapi_event { NSAPI_EVENT_CONNECTION_STATUS_CHANGE = 0, /*!< network connection status has changed, the parameter = new status (nsapi_connection_status_t) */ NSAPI_EVENT_CELLULAR_STATUS_BASE = 0x1000, /*!< Cellular modem status has changed, See the enum values from enum cellular_connection_status_t in /features/cellular/framework/common/CellularCommon.h */ NSAPI_EVENT_CELLULAR_STATUS_END = 0x1FFF /*!< cellular modem status has changed, See the enum values from enum cellular_connection_status_t in /features/cellular/framework/common/CellularCommon.h */ @@ -201,8 +201,8 @@ typedef void *nsapi_socket_t; * @enum nsapi_protocol */ typedef enum nsapi_protocol { - NSAPI_TCP, /*!< Socket is of TCP type */ - NSAPI_UDP, /*!< Socket is of UDP type */ + NSAPI_TCP, /*!< Socket is of TCP type */ + NSAPI_UDP, /*!< Socket is of UDP type */ } nsapi_protocol_t; /** Enum of standardized stack option levels @@ -320,8 +320,7 @@ typedef struct nsapi_ip_mreq { * * Unsupported operations can be left as null pointers. */ -typedef struct nsapi_stack_api -{ +typedef struct nsapi_stack_api { /** Get the local IP address * * @param stack Stack handle @@ -366,7 +365,7 @@ typedef struct nsapi_stack_api * @return 0 on success, negative error code on failure */ nsapi_error_t (*setstackopt)(nsapi_stack_t *stack, int level, - int optname, const void *optval, unsigned optlen); + int optname, const void *optval, unsigned optlen); /* Get stack-specific stack options * @@ -382,7 +381,7 @@ typedef struct nsapi_stack_api * @return 0 on success, negative error code on failure */ nsapi_error_t (*getstackopt)(nsapi_stack_t *stack, int level, - int optname, void *optval, unsigned *optlen); + int optname, void *optval, unsigned *optlen); /** Opens a socket * @@ -398,7 +397,7 @@ typedef struct nsapi_stack_api * @return 0 on success, negative error code on failure */ nsapi_error_t (*socket_open)(nsapi_stack_t *stack, nsapi_socket_t *socket, - nsapi_protocol_t proto); + nsapi_protocol_t proto); /** Close the socket * @@ -423,7 +422,7 @@ typedef struct nsapi_stack_api * @return 0 on success, negative error code on failure. */ nsapi_error_t (*socket_bind)(nsapi_stack_t *stack, nsapi_socket_t socket, - nsapi_addr_t addr, uint16_t port); + nsapi_addr_t addr, uint16_t port); /** Listen for connections on a TCP socket * @@ -450,7 +449,7 @@ typedef struct nsapi_stack_api * @return 0 on success, negative error code on failure */ nsapi_error_t (*socket_connect)(nsapi_stack_t *stack, nsapi_socket_t socket, - nsapi_addr_t addr, uint16_t port); + nsapi_addr_t addr, uint16_t port); /** Accepts a connection on a TCP socket * @@ -473,7 +472,7 @@ typedef struct nsapi_stack_api * @return 0 on success, negative error code on failure */ nsapi_error_t (*socket_accept)(nsapi_stack_t *stack, nsapi_socket_t server, - nsapi_socket_t *socket, nsapi_addr_t *addr, uint16_t *port); + nsapi_socket_t *socket, nsapi_addr_t *addr, uint16_t *port); /** Send data over a TCP socket * @@ -491,7 +490,7 @@ typedef struct nsapi_stack_api * code on failure */ nsapi_size_or_error_t (*socket_send)(nsapi_stack_t *stack, nsapi_socket_t socket, - const void *data, nsapi_size_t size); + const void *data, nsapi_size_t size); /** Receive data over a TCP socket * @@ -509,7 +508,7 @@ typedef struct nsapi_stack_api * code on failure */ nsapi_size_or_error_t (*socket_recv)(nsapi_stack_t *stack, nsapi_socket_t socket, - void *data, nsapi_size_t size); + void *data, nsapi_size_t size); /** Send a packet over a UDP socket * @@ -529,7 +528,7 @@ typedef struct nsapi_stack_api * code on failure */ nsapi_size_or_error_t (*socket_sendto)(nsapi_stack_t *stack, nsapi_socket_t socket, - nsapi_addr_t addr, uint16_t port, const void *data, nsapi_size_t size); + nsapi_addr_t addr, uint16_t port, const void *data, nsapi_size_t size); /** Receive a packet over a UDP socket * @@ -549,7 +548,7 @@ typedef struct nsapi_stack_api * code on failure */ nsapi_size_or_error_t (*socket_recvfrom)(nsapi_stack_t *stack, nsapi_socket_t socket, - nsapi_addr_t *addr, uint16_t *port, void *buffer, nsapi_size_t size); + nsapi_addr_t *addr, uint16_t *port, void *buffer, nsapi_size_t size); /** Register a callback on state change of the socket * @@ -566,7 +565,7 @@ typedef struct nsapi_stack_api * @param data Argument to pass to callback */ void (*socket_attach)(nsapi_stack_t *stack, nsapi_socket_t socket, - void (*callback)(void *), void *data); + void (*callback)(void *), void *data); /* Set stack-specific socket options * @@ -583,7 +582,7 @@ typedef struct nsapi_stack_api * @return 0 on success, negative error code on failure */ nsapi_error_t (*setsockopt)(nsapi_stack_t *stack, nsapi_socket_t socket, int level, - int optname, const void *optval, unsigned optlen); + int optname, const void *optval, unsigned optlen); /* Get stack-specific socket options * @@ -600,7 +599,7 @@ typedef struct nsapi_stack_api * @return 0 on success, negative error code on failure */ nsapi_error_t (*getsockopt)(nsapi_stack_t *stack, nsapi_socket_t socket, int level, - int optname, void *optval, unsigned *optlen); + int optname, void *optval, unsigned *optlen); } nsapi_stack_api_t; diff --git a/features/nvstore/TESTS/nvstore/functionality/main.cpp b/features/nvstore/TESTS/nvstore/functionality/main.cpp index 6b390edc4819..60c5b5509c32 100644 --- a/features/nvstore/TESTS/nvstore/functionality/main.cpp +++ b/features/nvstore/TESTS/nvstore/functionality/main.cpp @@ -66,6 +66,8 @@ static const int race_test_data_size = 128; static const int race_test_min_stack_size = 768; static const int race_test_max_stack_size = 1024; +static bool nvstore_overlaps_code = false; + static void gen_random(uint8_t *s, int len) { for (int i = 0; i < len; ++i) { @@ -91,17 +93,25 @@ static void nvstore_basic_functionality_test() size_t area_size; nvstore.get_area_params(area, area_address, area_size); printf("Area %d: address 0x%08lx, size %d (0x%x)\n", area, area_address, area_size, area_size); + if (area_address < FLASHIAP_ROM_END) { + nvstore_overlaps_code = true; + } + TEST_SKIP_UNLESS_MESSAGE(!nvstore_overlaps_code, "Test skipped. NVStore region overlaps code."); } gen_random(nvstore_testing_buf_set, basic_func_max_data_size); + uint16_t max_possible_keys = nvstore.get_max_possible_keys(); + TEST_SKIP_UNLESS_MESSAGE(max_test_keys < max_possible_keys, + "Not enough possible keys for test. Test skipped."); + nvstore.set_max_keys(max_test_keys); TEST_ASSERT_EQUAL(max_test_keys, nvstore.get_max_keys()); result = nvstore.reset(); TEST_ASSERT_EQUAL(NVSTORE_SUCCESS, result); - printf("Max keys %d (out of %d possible ones)\n", nvstore.get_max_keys(), nvstore.get_max_possible_keys()); + printf("Max keys %d (out of %d possible ones)\n", nvstore.get_max_keys(), max_possible_keys); result = nvstore.set(5, 18, nvstore_testing_buf_set); TEST_ASSERT_EQUAL(NVSTORE_SUCCESS, result); @@ -481,11 +491,17 @@ static void nvstore_multi_thread_test() NVStore &nvstore = NVStore::get_instance(); + TEST_SKIP_UNLESS_MESSAGE(!nvstore_overlaps_code, "Test skipped. NVStore region overlaps code."); + ret = nvstore.reset(); TEST_ASSERT_EQUAL(NVSTORE_SUCCESS, ret); thr_test_data = new thread_test_data_t; thr_test_data->max_keys = max_test_keys / 2; + uint16_t max_possible_keys = nvstore.get_max_possible_keys(); + TEST_SKIP_UNLESS_MESSAGE(thr_test_data->max_keys < max_possible_keys, + "Not enough possible keys for test. Test skipped."); + thr_test_data->stop_threads = false; for (key = 0; key < thr_test_data->max_keys; key++) { for (i = 0; i < thr_test_num_buffs; i++) { @@ -566,6 +582,8 @@ static void nvstore_race_test() int num_threads = race_test_num_threads; uint16_t actual_len_bytes; + TEST_SKIP_UNLESS_MESSAGE(!nvstore_overlaps_code, "Test skipped. NVStore region overlaps code."); + NVStore &nvstore = NVStore::get_instance(); ret = nvstore.reset(); diff --git a/features/nvstore/source/nvstore.cpp b/features/nvstore/source/nvstore.cpp index 70c1338b4225..3fb2e1f6ad12 100644 --- a/features/nvstore/source/nvstore.cpp +++ b/features/nvstore/source/nvstore.cpp @@ -519,7 +519,7 @@ int NVStore::copy_record(uint8_t from_area, uint32_t from_offset, uint32_t to_of int NVStore::garbage_collection(uint16_t key, uint16_t flags, uint8_t owner, uint16_t buf_size, const void *buf) { - uint32_t curr_offset, new_area_offset, next_offset; + uint32_t curr_offset, new_area_offset, next_offset, curr_owner; int ret; uint8_t curr_area; @@ -534,7 +534,8 @@ int NVStore::garbage_collection(uint16_t key, uint16_t flags, uint8_t owner, uin return ret; } _offset_by_key[key] = new_area_offset | (1 - _active_area) << offs_by_key_area_bit_pos | - (((flags & set_once_flag) != 0) << offs_by_key_set_once_bit_pos); + (((flags & set_once_flag) != 0) << offs_by_key_set_once_bit_pos) | + (owner << offs_by_key_owner_bit_pos); new_area_offset = next_offset; } @@ -544,7 +545,8 @@ int NVStore::garbage_collection(uint16_t key, uint16_t flags, uint8_t owner, uin curr_offset = _offset_by_key[key]; uint16_t save_flags = curr_offset & offs_by_key_flag_mask & ~offs_by_key_area_mask; curr_area = (uint8_t)(curr_offset >> offs_by_key_area_bit_pos) & 1; - curr_offset &= ~offs_by_key_flag_mask; + curr_owner = _offset_by_key[key] & offs_by_key_owner_mask; + curr_offset &= offs_by_key_offset_mask; if ((!curr_offset) || (curr_area != _active_area)) { continue; } @@ -552,7 +554,7 @@ int NVStore::garbage_collection(uint16_t key, uint16_t flags, uint8_t owner, uin if (ret != NVSTORE_SUCCESS) { return ret; } - _offset_by_key[key] = new_area_offset | (1 - curr_area) << offs_by_key_area_bit_pos | save_flags; + _offset_by_key[key] = new_area_offset | (1 - curr_area) << offs_by_key_area_bit_pos | save_flags | curr_owner; new_area_offset = next_offset; } diff --git a/hal/LowPowerTickerWrapper.cpp b/hal/LowPowerTickerWrapper.cpp new file mode 100644 index 000000000000..70b5190d4bd8 --- /dev/null +++ b/hal/LowPowerTickerWrapper.cpp @@ -0,0 +1,295 @@ +/* mbed Microcontroller Library + * Copyright (c) 2018 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 "hal/LowPowerTickerWrapper.h" +#include "platform/Callback.h" + +LowPowerTickerWrapper::LowPowerTickerWrapper(const ticker_data_t *data, const ticker_interface_t *interface, uint32_t min_cycles_between_writes, uint32_t min_cycles_until_match) + : _intf(data->interface), _min_count_between_writes(min_cycles_between_writes + 1), _min_count_until_match(min_cycles_until_match + 1), _suspended(false) +{ + core_util_critical_section_enter(); + + this->data.interface = interface; + this->data.queue = data->queue; + _reset(); + + core_util_critical_section_exit(); +} + +void LowPowerTickerWrapper::irq_handler(ticker_irq_handler_type handler) +{ + core_util_critical_section_enter(); + + if (_suspended) { + if (handler) { + handler(&data); + } + core_util_critical_section_exit(); + return; + } + + if (_pending_fire_now || _match_check(_intf->read())) { + _timeout.detach(); + _pending_timeout = false; + _pending_match = false; + _pending_fire_now = false; + if (handler) { + handler(&data); + } + } else { + // Spurious interrupt + _intf->clear_interrupt(); + } + + core_util_critical_section_exit(); +} + +void LowPowerTickerWrapper::suspend() +{ + core_util_critical_section_enter(); + + // Wait until rescheduling is allowed + while (!_set_interrupt_allowed) { + timestamp_t current = _intf->read(); + if (((current - _last_actual_set_interrupt) & _mask) >= _min_count_between_writes) { + _set_interrupt_allowed = true; + } + } + + _reset(); + _suspended = true; + + core_util_critical_section_exit(); +} + +void LowPowerTickerWrapper::resume() +{ + core_util_critical_section_enter(); + + _suspended = false; + + core_util_critical_section_exit(); +} + +bool LowPowerTickerWrapper::timeout_pending() +{ + core_util_critical_section_enter(); + + bool pending = _pending_timeout; + + core_util_critical_section_exit(); + return pending; +} + +void LowPowerTickerWrapper::init() +{ + core_util_critical_section_enter(); + + _reset(); + _intf->init(); + + core_util_critical_section_exit(); +} + +void LowPowerTickerWrapper::free() +{ + core_util_critical_section_enter(); + + _reset(); + _intf->free(); + + core_util_critical_section_exit(); +} + +uint32_t LowPowerTickerWrapper::read() +{ + core_util_critical_section_enter(); + + timestamp_t current = _intf->read(); + if (_match_check(current)) { + _intf->fire_interrupt(); + } + + core_util_critical_section_exit(); + return current; +} + +void LowPowerTickerWrapper::set_interrupt(timestamp_t timestamp) +{ + core_util_critical_section_enter(); + + _last_set_interrupt = _intf->read(); + _cur_match_time = timestamp; + _pending_match = true; + _schedule_match(_last_set_interrupt); + + core_util_critical_section_exit(); +} + +void LowPowerTickerWrapper::disable_interrupt() +{ + core_util_critical_section_enter(); + + _intf->disable_interrupt(); + + core_util_critical_section_exit(); +} + +void LowPowerTickerWrapper::clear_interrupt() +{ + core_util_critical_section_enter(); + + _intf->clear_interrupt(); + + core_util_critical_section_exit(); +} + +void LowPowerTickerWrapper::fire_interrupt() +{ + core_util_critical_section_enter(); + + _pending_fire_now = 1; + _intf->fire_interrupt(); + + core_util_critical_section_exit(); +} + +const ticker_info_t *LowPowerTickerWrapper::get_info() +{ + + core_util_critical_section_enter(); + + const ticker_info_t *info = _intf->get_info(); + + core_util_critical_section_exit(); + return info; +} + +void LowPowerTickerWrapper::_reset() +{ + MBED_ASSERT(core_util_in_critical_section()); + + _timeout.detach(); + _pending_timeout = false; + _pending_match = false; + _pending_fire_now = false; + _set_interrupt_allowed = true; + _cur_match_time = 0; + _last_set_interrupt = 0; + _last_actual_set_interrupt = 0; + + const ticker_info_t *info = _intf->get_info(); + if (info->bits >= 32) { + _mask = 0xffffffff; + } else { + _mask = ((uint64_t)1 << info->bits) - 1; + } + + // Round us_per_tick up + _us_per_tick = (1000000 + info->frequency - 1) / info->frequency; +} + +void LowPowerTickerWrapper::_timeout_handler() +{ + core_util_critical_section_enter(); + _pending_timeout = false; + + timestamp_t current = _intf->read(); + if (_ticker_match_interval_passed(_last_set_interrupt, current, _cur_match_time)) { + _intf->fire_interrupt(); + } else { + _schedule_match(current); + } + + core_util_critical_section_exit(); +} + +bool LowPowerTickerWrapper::_match_check(timestamp_t current) +{ + MBED_ASSERT(core_util_in_critical_section()); + + if (!_pending_match) { + return false; + } + return _ticker_match_interval_passed(_last_set_interrupt, current, _cur_match_time); +} + +uint32_t LowPowerTickerWrapper::_lp_ticks_to_us(uint32_t ticks) +{ + MBED_ASSERT(core_util_in_critical_section()); + + // Add 4 microseconds to round up the micro second ticker time (which has a frequency of at least 250KHz - 4us period) + return _us_per_tick * ticks + 4; +} + +void LowPowerTickerWrapper::_schedule_match(timestamp_t current) +{ + MBED_ASSERT(core_util_in_critical_section()); + + // Check if _intf->set_interrupt is allowed + if (!_set_interrupt_allowed) { + if (((current - _last_actual_set_interrupt) & _mask) >= _min_count_between_writes) { + _set_interrupt_allowed = true; + } + } + + uint32_t cycles_until_match = (_cur_match_time - _last_set_interrupt) & _mask; + bool too_close = cycles_until_match < _min_count_until_match; + + if (!_set_interrupt_allowed) { + + // Can't use _intf->set_interrupt so use microsecond Timeout instead + + // Speed optimization - if a timer has already been scheduled + // then don't schedule it again. + if (!_pending_timeout) { + uint32_t ticks = cycles_until_match < _min_count_until_match ? cycles_until_match : _min_count_until_match; + _timeout.attach_us(mbed::callback(this, &LowPowerTickerWrapper::_timeout_handler), _lp_ticks_to_us(ticks)); + _pending_timeout = true; + } + return; + } + + if (!too_close) { + + // Schedule LP ticker + _intf->set_interrupt(_cur_match_time); + current = _intf->read(); + _last_actual_set_interrupt = current; + _set_interrupt_allowed = false; + + // Check for overflow + uint32_t new_cycles_until_match = (_cur_match_time - current) & _mask; + if (new_cycles_until_match > cycles_until_match) { + // Overflow so fire now + _intf->fire_interrupt(); + return; + } + + // Update variables with new time + cycles_until_match = new_cycles_until_match; + too_close = cycles_until_match < _min_count_until_match; + } + + if (too_close) { + + // Low power ticker incremented to less than _min_count_until_match + // so low power ticker may not fire. Use Timeout to ensure it does fire. + uint32_t ticks = cycles_until_match < _min_count_until_match ? cycles_until_match : _min_count_until_match; + _timeout.attach_us(mbed::callback(this, &LowPowerTickerWrapper::_timeout_handler), _lp_ticks_to_us(ticks)); + _pending_timeout = true; + return; + } +} diff --git a/hal/LowPowerTickerWrapper.h b/hal/LowPowerTickerWrapper.h new file mode 100644 index 000000000000..aac8d70d171d --- /dev/null +++ b/hal/LowPowerTickerWrapper.h @@ -0,0 +1,239 @@ + +/** \addtogroup hal */ +/** @{*/ +/* mbed Microcontroller Library + * Copyright (c) 2018 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_LOW_POWER_TICKER_WRAPPER_H +#define MBED_LOW_POWER_TICKER_WRAPPER_H + +#include "device.h" + +#include "hal/ticker_api.h" +#include "hal/us_ticker_api.h" +#include "drivers/Timeout.h" + + +class LowPowerTickerWrapper { +public: + + + /** + * Create a new wrapped low power ticker object + * + * @param data Low power ticker data to wrap + * @param interface new ticker interface functions + * @param min_cycles_between_writes The number of whole low power clock periods + * which must complete before subsequent calls to set_interrupt + * @param min_cycles_until_match The minimum number of whole low power clock periods + * from the current time for which the match timestamp passed to set_interrupt is + * guaranteed to fire. + * + * N = min_cycles_between_writes + * + * 0 1 N - 1 N N + 1 N + 2 N + 3 + * |-------|------...------|-------|-------|-------|-------| + * ^ ^ + * | | + * set_interrupt Next set_interrupt allowed + * + * N = min_cycles_until_match + * + * 0 1 N - 1 N N + 1 N + 2 N + 3 + * |-------|------...------|-------|-------|-------|-------| + * ^ ^ + * | | + * set_interrupt Earliest match timestamp allowed + * + * + */ + + LowPowerTickerWrapper(const ticker_data_t *data, const ticker_interface_t *interface, uint32_t min_cycles_between_writes, uint32_t min_cycles_until_match); + + /** + * Interrupt handler called by the underlying driver/hardware + * + * @param handler The callback which would normally be called by the underlying driver/hardware + */ + void irq_handler(ticker_irq_handler_type handler); + + /** + * Suspend wrapper operation and pass through interrupts. + * + * This stops to wrapper layer from using the microsecond ticker. + * This should be called before using the low power ticker APIs directly. + */ + void suspend(); + + /** + * Resume wrapper operation and filter interrupts normally + */ + void resume(); + + /** + * Check if a Timeout object is being used + * + * @return true if Timeout is used for scheduling false otherwise + */ + bool timeout_pending(); + + /* + * Implementation of ticker_init + */ + void init(); + + /* + * Implementation of free + */ + void free(); + + /* + * Implementation of read + */ + uint32_t read(); + + /* + * Implementation of set_interrupt + */ + void set_interrupt(timestamp_t timestamp); + + /* + * Implementation of disable_interrupt + */ + void disable_interrupt(); + + /* + * Implementation of clear_interrupt + */ + void clear_interrupt(); + + /* + * Implementation of fire_interrupt + */ + void fire_interrupt(); + + /* + * Implementation of get_info + */ + const ticker_info_t *get_info(); + + ticker_data_t data; + +private: + mbed::Timeout _timeout; + const ticker_interface_t *const _intf; + + /* + * The number of low power clock cycles which must pass between subsequent + * calls to intf->set_interrupt + */ + const uint32_t _min_count_between_writes; + + /* + * The minimum number of low power clock cycles in the future that + * a match value can be set to and still fire + */ + const uint32_t _min_count_until_match; + + /* + * Flag to indicate if the timer is suspended + */ + bool _suspended; + + /* + * _cur_match_time is valid and Timeout is scheduled to fire + */ + bool _pending_timeout; + + /* + * set_interrupt has been called and _cur_match_time is valid + */ + bool _pending_match; + + /* + * The function LowPowerTickerWrapper::fire_interrupt has been called + * and an interrupt is expected. + */ + bool _pending_fire_now; + + /* + * It is safe to call intf->set_interrupt + */ + bool _set_interrupt_allowed; + + /* + * Last value written by LowPowerTickerWrapper::set_interrupt + */ + timestamp_t _cur_match_time; + + /* + * Time of last call to LowPowerTickerWrapper::set_interrupt + */ + uint32_t _last_set_interrupt; + + /* + * Time of last call to intf->set_interrupt + */ + uint32_t _last_actual_set_interrupt; + + /* + * Mask of valid bits from intf->read() + */ + uint32_t _mask; + + /* + * Microsecond per low power tick (rounded up) + */ + uint32_t _us_per_tick; + + + void _reset(); + + /** + * Set the low power ticker match time when hardware is ready + * + * This event is scheduled to set the lp timer after the previous write + * has taken effect and it is safe to write a new value without blocking. + * If the time has already passed then this function fires and interrupt + * immediately. + */ + void _timeout_handler(); + + /* + * Check match time has passed + */ + bool _match_check(timestamp_t current); + + /* + * Convert low power ticks to approximate microseconds + * + * This value is always larger or equal to exact value. + */ + uint32_t _lp_ticks_to_us(uint32_t); + + /* + * Schedule a match interrupt to fire at the correct time + * + * @param current The current low power ticker time + */ + void _schedule_match(timestamp_t current); + +}; + +#endif + +/** @}*/ + + diff --git a/hal/mbed_lp_ticker_api.c b/hal/mbed_lp_ticker_api.c index f9cf2b272eab..477c1b13875d 100644 --- a/hal/mbed_lp_ticker_api.c +++ b/hal/mbed_lp_ticker_api.c @@ -14,11 +14,10 @@ * limitations under the License. */ #include "hal/lp_ticker_api.h" +#include "hal/mbed_lp_ticker_wrapper.h" #if DEVICE_LPTICKER -void lp_ticker_set_interrupt_wrapper(timestamp_t timestamp); - static ticker_event_queue_t events = { 0 }; static ticker_irq_handler_type irq_handler = ticker_irq_handler; @@ -28,13 +27,10 @@ static const ticker_interface_t lp_interface = { .read = lp_ticker_read, .disable_interrupt = lp_ticker_disable_interrupt, .clear_interrupt = lp_ticker_clear_interrupt, -#if LPTICKER_DELAY_TICKS > 0 - .set_interrupt = lp_ticker_set_interrupt_wrapper, -#else .set_interrupt = lp_ticker_set_interrupt, -#endif .fire_interrupt = lp_ticker_fire_interrupt, .get_info = lp_ticker_get_info, + .free = lp_ticker_free, }; static const ticker_data_t lp_data = { @@ -44,7 +40,11 @@ static const ticker_data_t lp_data = { const ticker_data_t *get_lp_ticker_data(void) { +#if LPTICKER_DELAY_TICKS > 0 + return get_lp_ticker_wrapper_data(&lp_data); +#else return &lp_data; +#endif } ticker_irq_handler_type set_lp_ticker_irq_handler(ticker_irq_handler_type ticker_irq_handler) @@ -58,9 +58,13 @@ ticker_irq_handler_type set_lp_ticker_irq_handler(ticker_irq_handler_type ticker void lp_ticker_irq_handler(void) { +#if LPTICKER_DELAY_TICKS > 0 + lp_ticker_wrapper_irq_handler(irq_handler); +#else if (irq_handler) { irq_handler(&lp_data); } +#endif } #endif diff --git a/hal/mbed_lp_ticker_wrapper.cpp b/hal/mbed_lp_ticker_wrapper.cpp index 9c1a2b472894..403141fceaa9 100644 --- a/hal/mbed_lp_ticker_wrapper.cpp +++ b/hal/mbed_lp_ticker_wrapper.cpp @@ -13,144 +13,115 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "hal/lp_ticker_api.h" +#include "hal/mbed_lp_ticker_wrapper.h" #if DEVICE_LPTICKER && (LPTICKER_DELAY_TICKS > 0) -#include "Timeout.h" -#include "mbed_critical.h" - -static const timestamp_t min_delta = LPTICKER_DELAY_TICKS; +#include "hal/LowPowerTickerWrapper.h" +#include "platform/mbed_critical.h" +// Do not use SingletonPtr since this must be initialized in a critical section +static LowPowerTickerWrapper *ticker_wrapper; +static uint64_t ticker_wrapper_data[(sizeof(LowPowerTickerWrapper) + 7) / 8]; static bool init = false; -static bool pending = false; -static bool timeout_pending = false; -static timestamp_t last_set_interrupt = 0; -static timestamp_t last_request = 0; -static timestamp_t next = 0; -static timestamp_t mask; -static timestamp_t reschedule_us; +static void lp_ticker_wrapper_init() +{ + ticker_wrapper->init(); +} -// Do not use SingletonPtr since this must be initialized in a critical section -static mbed::Timeout *timeout; -static uint64_t timeout_data[sizeof(mbed::Timeout) / 8]; +static uint32_t lp_ticker_wrapper_read() +{ + return ticker_wrapper->read(); +} -/** - * Initialize variables - */ -static void init_local() +static void lp_ticker_wrapper_set_interrupt(timestamp_t timestamp) { - MBED_ASSERT(core_util_in_critical_section()); + ticker_wrapper->set_interrupt(timestamp); +} - const ticker_info_t *info = lp_ticker_get_info(); - if (info->bits >= 32) { - mask = 0xffffffff; - } else { - mask = ((uint64_t)1 << info->bits) - 1; - } +static void lp_ticker_wrapper_disable_interrupt() +{ + ticker_wrapper->disable_interrupt(); +} - // Round us_per_tick up - timestamp_t us_per_tick = (1000000 + info->frequency - 1) / info->frequency; +static void lp_ticker_wrapper_clear_interrupt() +{ + ticker_wrapper->clear_interrupt(); +} - // Add 1 tick to the min delta for the case where the clock transitions after you read it - // Add 4 microseconds to round up the micro second ticker time (which has a frequency of at least 250KHz - 4us period) - reschedule_us = (min_delta + 1) * us_per_tick + 4; +static void lp_ticker_wrapper_fire_interrupt() +{ + ticker_wrapper->fire_interrupt(); +} - timeout = new (timeout_data) mbed::Timeout(); +static const ticker_info_t *lp_ticker_wrapper_get_info() +{ + return ticker_wrapper->get_info(); } -/** - * Call lp_ticker_set_interrupt with a value that is guaranteed to fire - * - * Assumptions - * -Only one low power clock tick can pass from the last read (last_read) - * -The closest an interrupt can fire is max_delta + 1 - * - * @param last_read The last value read from lp_ticker_read - * @param timestamp The timestamp to trigger the interrupt at - */ -static void set_interrupt_safe(timestamp_t last_read, timestamp_t timestamp) +static void lp_ticker_wrapper_free() { - MBED_ASSERT(core_util_in_critical_section()); - uint32_t delta = (timestamp - last_read) & mask; - if (delta < min_delta + 2) { - timestamp = (last_read + min_delta + 2) & mask; - } - lp_ticker_set_interrupt(timestamp); + ticker_wrapper->free(); } -/** - * Set the low power ticker match time when hardware is ready - * - * This event is scheduled to set the lp timer after the previous write - * has taken effect and it is safe to write a new value without blocking. - * If the time has already passed then this function fires and interrupt - * immediately. - */ -static void set_interrupt_later() +static const ticker_interface_t lp_interface = { + lp_ticker_wrapper_init, + lp_ticker_wrapper_read, + lp_ticker_wrapper_disable_interrupt, + lp_ticker_wrapper_clear_interrupt, + lp_ticker_wrapper_set_interrupt, + lp_ticker_wrapper_fire_interrupt, + lp_ticker_wrapper_free, + lp_ticker_wrapper_get_info +}; + +void lp_ticker_wrapper_irq_handler(ticker_irq_handler_type handler) { core_util_critical_section_enter(); - timestamp_t current = lp_ticker_read(); - if (_ticker_match_interval_passed(last_request, current, next)) { - lp_ticker_fire_interrupt(); - } else { - set_interrupt_safe(current, next); - last_set_interrupt = lp_ticker_read(); + if (!init) { + // Force ticker to initialize + get_lp_ticker_data(); } - timeout_pending = false; + + ticker_wrapper->irq_handler(handler); core_util_critical_section_exit(); } -/** - * Wrapper around lp_ticker_set_interrupt to prevent blocking - * - * Problems this function is solving: - * 1. Interrupt may not fire if set earlier than LPTICKER_DELAY_TICKS low power clock cycles - * 2. Setting the interrupt back-to-back will block - * - * This wrapper function prevents lp_ticker_set_interrupt from being called - * back-to-back and blocking while the first write is in progress. This function - * avoids that problem by scheduling a timeout event if the lp ticker is in the - * middle of a write operation. - * - * @param timestamp Time to call ticker irq - * @note this is a utility function and it's not required part of HAL implementation - */ -extern "C" void lp_ticker_set_interrupt_wrapper(timestamp_t timestamp) +const ticker_data_t *get_lp_ticker_wrapper_data(const ticker_data_t *data) { core_util_critical_section_enter(); if (!init) { - init_local(); + ticker_wrapper = new (ticker_wrapper_data) LowPowerTickerWrapper(data, &lp_interface, LPTICKER_DELAY_TICKS, LPTICKER_DELAY_TICKS); init = true; } - timestamp_t current = lp_ticker_read(); - if (pending) { - // Check if pending should be cleared - if (((current - last_set_interrupt) & mask) >= min_delta) { - pending = false; - } + core_util_critical_section_exit(); + + return &ticker_wrapper->data; +} + +void lp_ticker_wrapper_suspend() +{ + if (!init) { + // Force ticker to initialize + get_lp_ticker_data(); } - if (pending || timeout_pending) { - next = timestamp; - last_request = current; - if (!timeout_pending) { - timeout->attach_us(set_interrupt_later, reschedule_us); - timeout_pending = true; - } - } else { - // Schedule immediately if nothing is pending - set_interrupt_safe(current, timestamp); - last_set_interrupt = lp_ticker_read(); - pending = true; + ticker_wrapper->suspend(); +} + +void lp_ticker_wrapper_resume() +{ + if (!init) { + // Force ticker to initialize + get_lp_ticker_data(); } - core_util_critical_section_exit(); + ticker_wrapper->resume(); } #endif diff --git a/hal/mbed_lp_ticker_wrapper.h b/hal/mbed_lp_ticker_wrapper.h new file mode 100644 index 000000000000..4b317e36c27c --- /dev/null +++ b/hal/mbed_lp_ticker_wrapper.h @@ -0,0 +1,78 @@ + +/** \addtogroup hal */ +/** @{*/ +/* mbed Microcontroller Library + * Copyright (c) 2018 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_LP_TICKER_WRAPPER_H +#define MBED_LP_TICKER_WRAPPER_H + +#include "device.h" + +#if DEVICE_LPTICKER + +#include "hal/ticker_api.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*ticker_irq_handler_type)(const ticker_data_t *const); + +/** + * Interrupt handler for the wrapped lp ticker + * + * @param handler the function which would normally be called by the + * lp ticker handler when it is not wrapped + */ +void lp_ticker_wrapper_irq_handler(ticker_irq_handler_type handler); + +/** + * Get wrapped lp ticker data + * + * @param data hardware low power ticker object + * @return wrapped low power ticker object + */ +const ticker_data_t *get_lp_ticker_wrapper_data(const ticker_data_t *data); + +/** + * Suspend the wrapper layer code + * + * Pass through all interrupts to the low power ticker and stop using + * the microsecond ticker. + */ +void lp_ticker_wrapper_suspend(void); + +/** + * Resume the wrapper layer code + * + * Resume operation of the wrapper layer. Interrupts will be filtered + * as normal and the microsecond timer will be used for interrupts scheduled + * too quickly back-to-back. + */ +void lp_ticker_wrapper_resume(void); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif + +#endif + +/** @}*/ diff --git a/hal/mbed_sleep_manager.c b/hal/mbed_sleep_manager.c index d485965da676..30e2d74837ca 100644 --- a/hal/mbed_sleep_manager.c +++ b/hal/mbed_sleep_manager.c @@ -21,6 +21,7 @@ #include "mbed_error.h" #include "mbed_debug.h" #include "mbed_stats.h" +#include "us_ticker_api.h" #include "lp_ticker_api.h" #include #include @@ -183,6 +184,19 @@ bool sleep_manager_can_deep_sleep(void) return deep_sleep_lock == 0 ? true : false; } +bool sleep_manager_can_deep_sleep_test_check() +{ + const uint32_t check_time_us = 2000; + const ticker_data_t *const ticker = get_us_ticker_data(); + uint32_t start = ticker_read(ticker); + while ((ticker_read(ticker) - start) < check_time_us) { + if (sleep_manager_can_deep_sleep()) { + return true; + } + } + return false; +} + void sleep_manager_sleep_auto(void) { #ifdef MBED_SLEEP_TRACING_ENABLED diff --git a/hal/mbed_ticker_api.c b/hal/mbed_ticker_api.c index c9bf84e6827c..ad61c43659c9 100644 --- a/hal/mbed_ticker_api.c +++ b/hal/mbed_ticker_api.c @@ -32,6 +32,9 @@ static void initialize(const ticker_data_t *ticker) if (ticker->queue->initialized) { return; } + if (ticker->queue->suspended) { + return; + } ticker->interface->init(); @@ -69,6 +72,8 @@ static void initialize(const ticker_data_t *ticker) ticker->queue->max_delta = max_delta; ticker->queue->max_delta_us = max_delta_us; ticker->queue->present_time = 0; + ticker->queue->dispatching = false; + ticker->queue->suspended = false; ticker->queue->initialized = true; update_present_time(ticker); @@ -120,6 +125,9 @@ static us_timestamp_t convert_timestamp(us_timestamp_t ref, timestamp_t timestam static void update_present_time(const ticker_data_t *const ticker) { ticker_event_queue_t *queue = ticker->queue; + if (queue->suspended) { + return; + } uint32_t ticker_time = ticker->interface->read(); if (ticker_time == ticker->queue->tick_last_read) { // No work to do @@ -164,9 +172,9 @@ static void update_present_time(const ticker_data_t *const ticker) } /** - * Given the absolute timestamp compute the hal tick timestamp. + * Given the absolute timestamp compute the hal tick timestamp rounded up. */ -static timestamp_t compute_tick(const ticker_data_t *const ticker, us_timestamp_t timestamp) +static timestamp_t compute_tick_round_up(const ticker_data_t *const ticker, us_timestamp_t timestamp) { ticker_event_queue_t *queue = ticker->queue; us_timestamp_t delta_us = timestamp - queue->present_time; @@ -185,14 +193,14 @@ static timestamp_t compute_tick(const ticker_data_t *const ticker, us_timestamp_ } else if (0 != queue->frequency_shifts) { // Optimized frequencies divisible by 2 - delta = (delta_us << ticker->queue->frequency_shifts) / 1000000; + delta = ((delta_us << ticker->queue->frequency_shifts) + 1000000 - 1) / 1000000; if (delta > ticker->queue->max_delta) { delta = ticker->queue->max_delta; } } else { // General case - delta = delta_us * queue->frequency / 1000000; + delta = (delta_us * queue->frequency + 1000000 - 1) / 1000000; if (delta > ticker->queue->max_delta) { delta = ticker->queue->max_delta; } @@ -229,6 +237,12 @@ int _ticker_match_interval_passed(timestamp_t prev_tick, timestamp_t cur_tick, t static void schedule_interrupt(const ticker_data_t *const ticker) { ticker_event_queue_t *queue = ticker->queue; + if (queue->suspended || ticker->queue->dispatching) { + // Don't schedule the next interrupt until dispatching is + // finished. This prevents repeated calls to interface->set_interrupt + return; + } + update_present_time(ticker); if (ticker->queue->head) { @@ -242,14 +256,11 @@ static void schedule_interrupt(const ticker_data_t *const ticker) return; } - timestamp_t match_tick = compute_tick(ticker, match_time); - // The time has been checked to be future, but it could still round - // to the last tick as a result of us to ticks conversion - if (match_tick == queue->tick_last_read) { - // Match time has already expired so fire immediately - ticker->interface->fire_interrupt(); - return; - } + timestamp_t match_tick = compute_tick_round_up(ticker, match_time); + + // The same tick should never occur since match_tick is rounded up. + // If the same tick is returned scheduling will not work correctly. + MBED_ASSERT(match_tick != queue->tick_last_read); ticker->interface->set_interrupt(match_tick); timestamp_t cur_tick = ticker->interface->read(); @@ -278,8 +289,13 @@ void ticker_irq_handler(const ticker_data_t *const ticker) core_util_critical_section_enter(); ticker->interface->clear_interrupt(); + if (ticker->queue->suspended) { + core_util_critical_section_exit(); + return; + } /* Go through all the pending TimerEvents */ + ticker->queue->dispatching = true; while (1) { if (ticker->queue->head == NULL) { break; @@ -302,6 +318,7 @@ void ticker_irq_handler(const ticker_data_t *const ticker) break; } } + ticker->queue->dispatching = false; schedule_interrupt(ticker); @@ -421,3 +438,29 @@ int ticker_get_next_timestamp(const ticker_data_t *const data, timestamp_t *time return ret; } + +void ticker_suspend(const ticker_data_t *const ticker) +{ + core_util_critical_section_enter(); + + ticker->queue->suspended = true; + + core_util_critical_section_exit(); +} + +void ticker_resume(const ticker_data_t *const ticker) +{ + core_util_critical_section_enter(); + + ticker->queue->suspended = false; + if (ticker->queue->initialized) { + ticker->queue->tick_last_read = ticker->interface->read(); + + update_present_time(ticker); + schedule_interrupt(ticker); + } else { + initialize(ticker); + } + + core_util_critical_section_exit(); +} diff --git a/hal/mbed_us_ticker_api.c b/hal/mbed_us_ticker_api.c index 9b025fa3f840..433a0355403c 100644 --- a/hal/mbed_us_ticker_api.c +++ b/hal/mbed_us_ticker_api.c @@ -27,6 +27,7 @@ static const ticker_interface_t us_interface = { .set_interrupt = us_ticker_set_interrupt, .fire_interrupt = us_ticker_fire_interrupt, .get_info = us_ticker_get_info, + .free = us_ticker_free, }; static const ticker_data_t us_data = { diff --git a/hal/ticker_api.h b/hal/ticker_api.h index 661bd8099556..98b2786ee35f 100644 --- a/hal/ticker_api.h +++ b/hal/ticker_api.h @@ -64,6 +64,7 @@ typedef struct { void (*clear_interrupt)(void); /**< Clear interrupt function */ void (*set_interrupt)(timestamp_t timestamp); /**< Set interrupt function */ void (*fire_interrupt)(void); /**< Fire interrupt right-away */ + void (*free)(void); /**< Disable function */ const ticker_info_t *(*get_info)(void); /**< Return info about this ticker's implementation */ } ticker_interface_t; @@ -80,6 +81,8 @@ typedef struct { uint64_t tick_remainder; /**< Ticks that have not been added to base_time */ us_timestamp_t present_time; /**< Store the timestamp used for present time */ bool initialized; /**< Indicate if the instance is initialized */ + bool dispatching; /**< The function ticker_irq_handler is dispatching */ + bool suspended; /**< Indicate if the instance is suspended */ uint8_t frequency_shifts; /**< If frequency is a value of 2^n, this is n, otherwise 0 */ } ticker_event_queue_t; @@ -182,6 +185,27 @@ us_timestamp_t ticker_read_us(const ticker_data_t *const ticker); */ int ticker_get_next_timestamp(const ticker_data_t *const ticker, timestamp_t *timestamp); +/** Suspend this ticker + * + * When suspended reads will always return the same time and no + * events will be dispatched. When suspended the common layer + * will only ever call the interface function clear_interrupt() + * and that is only if ticker_irq_handler is called. + * + * + * @param ticker The ticker object. + */ +void ticker_suspend(const ticker_data_t *const ticker); + +/** Resume this ticker + * + * When resumed the ticker will ignore any time that has passed + * and continue counting up where it left off. + * + * @param ticker The ticker object. + */ +void ticker_resume(const ticker_data_t *const ticker); + /* Private functions * * @cond PRIVATE diff --git a/hal/us_ticker_api.h b/hal/us_ticker_api.h index 77f43580f0e3..e27c8051f4dc 100644 --- a/hal/us_ticker_api.h +++ b/hal/us_ticker_api.h @@ -170,6 +170,25 @@ void us_ticker_init(void); * except us_ticker_init(), calling any function other than init is undefined. * * @note This function stops the ticker from counting. + * + * Pseudo Code: + * @code + * uint32_t us_ticker_free() + * { + * // Disable timer + * TIMER_CTRL &= ~TIMER_CTRL_ENABLE_Msk; + * + * // Disable the compare interrupt + * TIMER_CTRL &= ~TIMER_CTRL_COMPARE_ENABLE_Msk; + * + * // Disable timer interrupt + * NVIC_DisableIRQ(TIMER_IRQn); + * + * // Disable clock gate so processor cannot read TIMER registers + * POWER_CTRL &= ~POWER_CTRL_TIMER_Msk; + * } + * @endcode + * */ void us_ticker_free(void); diff --git a/platform/CircularBuffer.h b/platform/CircularBuffer.h index accb3abce938..2a9a310b87a0 100644 --- a/platform/CircularBuffer.h +++ b/platform/CircularBuffer.h @@ -194,9 +194,9 @@ class CircularBuffer { private: T _pool[BufferSize]; - volatile CounterType _head; - volatile CounterType _tail; - volatile bool _full; + CounterType _head; + CounterType _tail; + bool _full; }; /**@}*/ diff --git a/platform/SharedPtr.h b/platform/SharedPtr.h new file mode 100644 index 000000000000..d6bbac813892 --- /dev/null +++ b/platform/SharedPtr.h @@ -0,0 +1,288 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2018 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 __SHAREDPTR_H__ +#define __SHAREDPTR_H__ + +#include + +#include +#include + +#include "platform/mbed_critical.h" + +/** Shared pointer class. + * + * A shared pointer is a "smart" pointer that retains ownership of an object using + * reference counting accross all smart pointers referencing that object. + * + * @code + * #include "platform/SharedPtr.h" + * + * void test() { + * struct MyStruct { int a; }; + * + * // Create shared pointer + * SharedPtr ptr( new MyStruct ); + * + * // Increase reference count + * SharedPtr ptr2( ptr ); + * + * ptr = NULL; // Reference to the struct instance is still held by ptr2 + * + * ptr2 = NULL; // The raw pointer is freed + * } + * @endcode + * + * + * It is similar to the std::shared_ptr class introduced in C++11; + * however, this is not a compatible implementation (no weak pointer, no make_shared, no custom deleters and so on.) + * + * Usage: SharedPtr ptr(new Class()) + * + * When ptr is passed around by value, the copy constructor and + * destructor manages the reference count of the raw pointer. + * If the counter reaches zero, delete is called on the raw pointer. + * + * To avoid loops, use "weak" references by calling the original + * pointer directly through ptr.get(). + */ + +template +class SharedPtr { +public: + /** + * @brief Create empty SharedPtr not pointing to anything. + * @details Used for variable declaration. + */ + SharedPtr(): _ptr(NULL), _counter(NULL) + { + } + + /** + * @brief Create new SharedPtr + * @param ptr Pointer to take control over + */ + SharedPtr(T *ptr): _ptr(ptr), _counter(NULL) + { + // Allocate counter on the heap, so it can be shared + if (_ptr != NULL) { + _counter = new uint32_t; + *_counter = 1; + } + } + + /** + * @brief Destructor. + * @details Decrement reference counter, and delete object if no longer pointed to. + */ + ~SharedPtr() + { + decrement_counter(); + } + + /** + * @brief Copy constructor. + * @details Create new SharedPtr from other SharedPtr by + * copying pointer to original object and pointer to counter. + * @param source Object being copied from. + */ + SharedPtr(const SharedPtr &source): _ptr(source._ptr), _counter(source._counter) + { + // Increment reference counter + if (_ptr != NULL) { + core_util_atomic_incr_u32(_counter, 1); + } + } + + /** + * @brief Assignment operator. + * @details Cleanup previous reference and assign new pointer and counter. + * @param source Object being assigned from. + * @return Object being assigned. + */ + SharedPtr operator=(const SharedPtr &source) + { + if (this != &source) { + // Clean up by decrementing counter + decrement_counter(); + + // Assign new values + _ptr = source.get(); + _counter = source.get_counter(); + + // Increment new counter + if (_ptr != NULL) { + core_util_atomic_incr_u32(_counter, 1); + } + } + + return *this; + } + + /** + * @brief Replaces the managed pointer with a new unmanaged pointer. + * @param[in] ptr the new raw pointer to manage. + */ + void reset(T *ptr) + { + // Clean up by decrementing counter + decrement_counter(); + + if (ptr != NULL) { + // Allocate counter on the heap, so it can be shared + _counter = new uint32_t; + *_counter = 1; + } + } + + /** + * @brief Replace the managed pointer with a NULL pointer. + */ + void reset() + { + reset(NULL); + } + + /** + * @brief Raw pointer accessor. + * @details Get raw pointer to object pointed to. + * @return Pointer. + */ + T *get() const + { + return _ptr; + } + + /** + * @brief Reference count accessor. + * @return Reference count. + */ + uint32_t use_count() const + { + if (_ptr != NULL) { + core_util_critical_section_enter(); + uint32_t current_counter = *_counter; + core_util_critical_section_exit(); + return current_counter; + } else { + return 0; + } + } + + /** + * @brief Dereference object operator. + * @details Override to return the object pointed to. + */ + T &operator*() const + { + return *_ptr; + } + + /** + * @brief Dereference object member operator. + * @details Override to return return member in object pointed to. + */ + T *operator->() const + { + return _ptr; + } + + /** + * @brief Boolean conversion operator. + * @return Whether or not the pointer is NULL. + */ + operator bool() const + { + return (_ptr != NULL); + } + +private: + /** + * @brief Get pointer to reference counter. + * @return Pointer to reference counter. + */ + uint32_t *get_counter() const + { + return _counter; + } + + /** + * @brief Decrement reference counter. + * @details If count reaches zero, free counter and delete object pointed to. + */ + void decrement_counter() + { + if (_ptr != NULL) { + uint32_t new_value = core_util_atomic_decr_u32(_counter, 1); + if (new_value == 0) { + delete _counter; + _counter = NULL; + delete _ptr; + _ptr = NULL; + } + } + } + +private: + // Pointer to shared object + T *_ptr; + + // Pointer to shared reference counter + uint32_t *_counter; +}; + +/** Non-member relational operators. + */ +template +bool operator== (const SharedPtr &lhs, const SharedPtr &rhs) +{ + return (lhs.get() == rhs.get()); +} + +template +bool operator== (const SharedPtr &lhs, U rhs) +{ + return (lhs.get() == (T *) rhs); +} + +template +bool operator== (U lhs, const SharedPtr &rhs) +{ + return ((T *) lhs == rhs.get()); +} + +/** Non-member relational operators. + */ +template +bool operator!= (const SharedPtr &lhs, const SharedPtr &rhs) +{ + return (lhs.get() != rhs.get()); +} + +template +bool operator!= (const SharedPtr &lhs, U rhs) +{ + return (lhs.get() != (T *) rhs); +} + +template +bool operator!= (U lhs, const SharedPtr &rhs) +{ + return ((T *) lhs != rhs.get()); +} + +#endif // __SHAREDPTR_H__ diff --git a/platform/mbed_error.c b/platform/mbed_error.c index d0c8ec9b5f55..f2eb431e0267 100644 --- a/platform/mbed_error.c +++ b/platform/mbed_error.c @@ -57,7 +57,7 @@ static mbed_error_ctx first_error_ctx = {0}; static mbed_error_ctx last_error_ctx = {0}; static mbed_error_hook_t error_hook = NULL; static void print_error_report(mbed_error_ctx *ctx, const char *); -static mbed_error_status_t handle_error(mbed_error_status_t error_status, unsigned int error_value, const char *filename, int line_number); +static mbed_error_status_t handle_error(mbed_error_status_t error_status, unsigned int error_value, const char *filename, int line_number, void *caller); //Helper function to halt the system static void mbed_halt_system(void) @@ -82,7 +82,7 @@ WEAK void error(const char *format, ...) } //Call handle_error/print_error_report permanently setting error_in_progress flag - handle_error(MBED_ERROR_UNKNOWN, 0, NULL, 0); + handle_error(MBED_ERROR_UNKNOWN, 0, NULL, 0, MBED_CALLER_ADDR()); ERROR_REPORT(&last_error_ctx, "Fatal Run-time error"); error_in_progress = 1; @@ -96,7 +96,7 @@ WEAK void error(const char *format, ...) } //Set an error status with the error handling system -static mbed_error_status_t handle_error(mbed_error_status_t error_status, unsigned int error_value, const char *filename, int line_number) +static mbed_error_status_t handle_error(mbed_error_status_t error_status, unsigned int error_value, const char *filename, int line_number, void *caller) { mbed_error_ctx current_error_ctx; @@ -123,7 +123,7 @@ static mbed_error_status_t handle_error(mbed_error_status_t error_status, unsign memset(¤t_error_ctx, sizeof(mbed_error_ctx), 0); //Capture error information current_error_ctx.error_status = error_status; - current_error_ctx.error_address = (uint32_t)MBED_CALLER_ADDR(); + current_error_ctx.error_address = (uint32_t)caller; current_error_ctx.error_value = error_value; #ifdef MBED_CONF_RTOS_PRESENT //Capture thread info @@ -193,14 +193,14 @@ int mbed_get_error_count(void) //Sets a fatal error mbed_error_status_t mbed_warning(mbed_error_status_t error_status, const char *error_msg, unsigned int error_value, const char *filename, int line_number) { - return handle_error(error_status, error_value, filename, line_number); + return handle_error(error_status, error_value, filename, line_number, MBED_CALLER_ADDR()); } //Sets a fatal error, this function is marked WEAK to be able to override this for some tests WEAK mbed_error_status_t mbed_error(mbed_error_status_t error_status, const char *error_msg, unsigned int error_value, const char *filename, int line_number) { //set the error reported and then halt the system - if (MBED_SUCCESS != handle_error(error_status, error_value, filename, line_number)) { + if (MBED_SUCCESS != handle_error(error_status, error_value, filename, line_number, MBED_CALLER_ADDR())) { return MBED_ERROR_FAILED_OPERATION; } diff --git a/platform/mbed_power_mgmt.h b/platform/mbed_power_mgmt.h index 5d30348dcea3..026cbf214d1b 100644 --- a/platform/mbed_power_mgmt.h +++ b/platform/mbed_power_mgmt.h @@ -122,6 +122,17 @@ void sleep_manager_unlock_deep_sleep_internal(void); */ bool sleep_manager_can_deep_sleep(void); +/** Check if the target can deep sleep within a period of time + * + * This function in intended for use in testing. The amount + * of time this functions waits for deeps sleep to be available + * is currently 2ms. This may change in the future depending + * on testing requirements. + * + * @return true if a target can go to deepsleep, false otherwise + */ +bool sleep_manager_can_deep_sleep_test_check(void); + /** Enter auto selected sleep mode. It chooses the sleep or deeepsleep modes based * on the deepsleep locking counter * diff --git a/platform/mbed_retarget.cpp b/platform/mbed_retarget.cpp index 461375938d6e..fd29f17ba71c 100644 --- a/platform/mbed_retarget.cpp +++ b/platform/mbed_retarget.cpp @@ -1196,12 +1196,10 @@ extern "C" uint32_t __HeapLimit; extern "C" int errno; // Dynamic memory allocation related syscall. -#if (defined(TARGET_NUVOTON) || defined(TWO_RAM_REGIONS)) +#if defined(TWO_RAM_REGIONS) // Overwrite _sbrk() to support two region model (heap and stack are two distinct regions). // __wrap__sbrk() is implemented in: -// TARGET_NUMAKER_PFM_NUC472 targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/TOOLCHAIN_GCC_ARM/nuc472_retarget.c -// TARGET_NUMAKER_PFM_M453 targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/TOOLCHAIN_GCC_ARM/m451_retarget.c // TARGET_STM32L4 targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L4/l4_retarget.c extern "C" void *__wrap__sbrk(int incr); extern "C" caddr_t _sbrk(int incr) diff --git a/platform/mbed_wait_api_rtos.cpp b/platform/mbed_wait_api_rtos.cpp index b5359378400f..f24f58cbddd3 100644 --- a/platform/mbed_wait_api_rtos.cpp +++ b/platform/mbed_wait_api_rtos.cpp @@ -39,11 +39,10 @@ void wait_us(int us) const ticker_data_t *const ticker = get_us_ticker_data(); uint32_t start = ticker_read(ticker); - // Use the RTOS to wait for millisecond delays if possible - int ms = us / 1000; - if ((ms > 0) && core_util_are_interrupts_enabled()) { + if ((us >= 1000) && core_util_are_interrupts_enabled()) { + // Use the RTOS to wait for millisecond delays if possible sleep_manager_lock_deep_sleep(); - Thread::wait((uint32_t)ms); + Thread::wait((uint32_t)us / 1000); sleep_manager_unlock_deep_sleep(); } // Use busy waiting for sub-millisecond delays, or for the whole diff --git a/rtos/Queue.h b/rtos/Queue.h index 0190c047f84b..ef49330c33c3 100644 --- a/rtos/Queue.h +++ b/rtos/Queue.h @@ -35,7 +35,7 @@ namespace rtos { /** \addtogroup rtos */ /** @{*/ /** - * \defgroup rtos_EventFlags EventFlags class + * \defgroup rtos_Queue Queue class * @{ */ diff --git a/rtos/TARGET_CORTEX/SysTimer.cpp b/rtos/TARGET_CORTEX/SysTimer.cpp index 0882b7cfb1ef..d3bcfc689a0a 100644 --- a/rtos/TARGET_CORTEX/SysTimer.cpp +++ b/rtos/TARGET_CORTEX/SysTimer.cpp @@ -178,6 +178,7 @@ void SysTimer::handler() } else { _set_irq_pending(); _increment_tick(); + schedule_tick(); } core_util_critical_section_exit(); diff --git a/rtos/TARGET_CORTEX/mbed_rtx_conf.h b/rtos/TARGET_CORTEX/mbed_rtx_conf.h index 3b919fc094cb..5b01177f0911 100644 --- a/rtos/TARGET_CORTEX/mbed_rtx_conf.h +++ b/rtos/TARGET_CORTEX/mbed_rtx_conf.h @@ -80,4 +80,176 @@ #define OS_IDLE_THREAD_NAME "idle_thread" #define OS_TIMER_THREAD_NAME "timer_thread" +/* Enable only the evr events we use in Mbed-OS to save flash space. */ +//Following events are used by Mbed-OS, DO NOT disable them +//#define EVR_RTX_KERNEL_ERROR_DISABLE +//#define EVR_RTX_THREAD_ERROR_DISABLE +//#define EVR_RTX_THREAD_EXIT_DISABLE +//#define EVR_RTX_THREAD_TERMINATE_DISABLE +//#define EVR_RTX_TIMER_ERROR_DISABLE +//#define EVR_RTX_EVENT_FLAGS_ERROR_DISABLE +//#define EVR_RTX_MUTEX_ERROR_DISABLE +//#define EVR_RTX_SEMAPHORE_ERROR_DISABLE +//#define EVR_RTX_MEMORY_POOL_ERROR_DISABLE +//#define EVR_RTX_MESSAGE_QUEUE_ERROR_DISABLE + +//Following events are NOT used by Mbed-OS, you may enable them if needed for debug purposes +#define EVR_RTX_MEMORY_INIT_DISABLE +#define EVR_RTX_MEMORY_ALLOC_DISABLE +#define EVR_RTX_MEMORY_FREE_DISABLE +#define EVR_RTX_MEMORY_BLOCK_INIT_DISABLE +#define EVR_RTX_MEMORY_BLOCK_ALLOC_DISABLE +#define EVR_RTX_MEMORY_BLOCK_FREE_DISABLE +#define EVR_RTX_KERNEL_INITIALIZE_DISABLE +#define EVR_RTX_KERNEL_INITIALIZE_COMPLETED_DISABLE +#define EVR_RTX_KERNEL_GET_INFO_DISABLE +#define EVR_RTX_KERNEL_INFO_RETRIEVED_DISABLE +#define EVR_RTX_KERNEL_GET_STATE_DISABLE +#define EVR_RTX_KERNEL_START_DISABLE +#define EVR_RTX_KERNEL_STARTED_DISABLE +#define EVR_RTX_KERNEL_LOCK_DISABLE +#define EVR_RTX_KERNEL_LOCKED_DISABLE +#define EVR_RTX_KERNEL_UNLOCK_DISABLE +#define EVR_RTX_KERNEL_UNLOCKED_DISABLE +#define EVR_RTX_KERNEL_RESTORE_LOCK_DISABLE +#define EVR_RTX_KERNEL_LOCK_RESTORED_DISABLE +#define EVR_RTX_KERNEL_SUSPEND_DISABLE +#define EVR_RTX_KERNEL_SUSPENDED_DISABLE +#define EVR_RTX_KERNEL_RESUME_DISABLE +#define EVR_RTX_KERNEL_RESUMED_DISABLE +#define EVR_RTX_KERNEL_GET_TICK_COUNT_DISABLE +#define EVR_RTX_KERNEL_GET_TICK_FREQ_DISABLE +#define EVR_RTX_KERNEL_GET_SYS_TIMER_COUNT_DISABLE +#define EVR_RTX_KERNEL_GET_SYS_TIMER_FREQ_DISABLE +#define EVR_RTX_THREAD_NEW_DISABLE +#define EVR_RTX_THREAD_CREATED_DISABLE +#define EVR_RTX_THREAD_GET_NAME_DISABLE +#define EVR_RTX_THREAD_GET_ID_DISABLE +#define EVR_RTX_THREAD_GET_STATE_DISABLE +#define EVR_RTX_THREAD_GET_STACK_SIZE_DISABLE +#define EVR_RTX_THREAD_GET_STACK_SPACE_DISABLE +#define EVR_RTX_THREAD_SET_PRIORITY_DISABLE +#define EVR_RTX_THREAD_GET_PRIORITY_DISABLE +#define EVR_RTX_THREAD_YIELD_DISABLE +#define EVR_RTX_THREAD_SUSPEND_DISABLE +#define EVR_RTX_THREAD_SUSPENDED_DISABLE +#define EVR_RTX_THREAD_RESUME_DISABLE +#define EVR_RTX_THREAD_RESUMED_DISABLE +#define EVR_RTX_THREAD_DETACH_DISABLE +#define EVR_RTX_THREAD_DETACHED_DISABLE +#define EVR_RTX_THREAD_JOIN_DISABLE +#define EVR_RTX_THREAD_JOIN_PENDING_DISABLE +#define EVR_RTX_THREAD_JOINED_DISABLE +#define EVR_RTX_THREAD_BLOCKED_DISABLE +#define EVR_RTX_THREAD_UNBLOCKED_DISABLE +#define EVR_RTX_THREAD_PREEMPTED_DISABLE +#define EVR_RTX_THREAD_SWITCHED_DISABLE +#define EVR_RTX_THREAD_DESTROYED_DISABLE +#define EVR_RTX_THREAD_GET_COUNT_DISABLE +#define EVR_RTX_THREAD_ENUMERATE_DISABLE +#define EVR_RTX_THREAD_FLAGS_SET_DISABLE +#define EVR_RTX_THREAD_FLAGS_SET_DONE_DISABLE +#define EVR_RTX_THREAD_FLAGS_CLEAR_DISABLE +#define EVR_RTX_THREAD_FLAGS_CLEAR_DONE_DISABLE +#define EVR_RTX_THREAD_FLAGS_GET_DISABLE +#define EVR_RTX_THREAD_FLAGS_WAIT_DISABLE +#define EVR_RTX_THREAD_FLAGS_WAIT_PENDING_DISABLE +#define EVR_RTX_THREAD_FLAGS_WAIT_TIMEOUT_DISABLE +#define EVR_RTX_THREAD_FLAGS_WAIT_COMPLETED_DISABLE +#define EVR_RTX_THREAD_FLAGS_WAIT_NOT_COMPLETED_DISABLE +#define EVR_RTX_THREAD_DELAY_DISABLE +#define EVR_RTX_THREAD_DELAY_UNTIL_DISABLE +#define EVR_RTX_THREAD_DELAY_COMPLETED_DISABLE +#define EVR_RTX_TIMER_CALLBACK_DISABLE +#define EVR_RTX_TIMER_NEW_DISABLE +#define EVR_RTX_TIMER_CREATED_DISABLE +#define EVR_RTX_TIMER_GET_NAME_DISABLE +#define EVR_RTX_TIMER_START_DISABLE +#define EVR_RTX_TIMER_STARTED_DISABLE +#define EVR_RTX_TIMER_STOP_DISABLE +#define EVR_RTX_TIMER_STOPPED_DISABLE +#define EVR_RTX_TIMER_IS_RUNNING_DISABLE +#define EVR_RTX_TIMER_DELETE_DISABLE +#define EVR_RTX_TIMER_DESTROYED_DISABLE +#define EVR_RTX_EVENT_FLAGS_NEW_DISABLE +#define EVR_RTX_EVENT_FLAGS_CREATED_DISABLE +#define EVR_RTX_EVENT_FLAGS_GET_NAME_DISABLE +#define EVR_RTX_EVENT_FLAGS_SET_DISABLE +#define EVR_RTX_EVENT_FLAGS_SET_DONE_DISABLE +#define EVR_RTX_EVENT_FLAGS_CLEAR_DISABLE +#define EVR_RTX_EVENT_FLAGS_CLEAR_DONE_DISABLE +#define EVR_RTX_EVENT_FLAGS_GET_DISABLE +#define EVR_RTX_EVENT_FLAGS_WAIT_DISABLE +#define EVR_RTX_EVENT_FLAGS_WAIT_PENDING_DISABLE +#define EVR_RTX_EVENT_FLAGS_WAIT_TIMEOUT_DISABLE +#define EVR_RTX_EVENT_FLAGS_WAIT_COMPLETED_DISABLE +#define EVR_RTX_EVENT_FLAGS_WAIT_NOT_COMPLETED_DISABLE +#define EVR_RTX_EVENT_FLAGS_DELETE_DISABLE +#define EVR_RTX_EVENT_FLAGS_DESTROYED_DISABLE +#define EVR_RTX_MUTEX_NEW_DISABLE +#define EVR_RTX_MUTEX_CREATED_DISABLE +#define EVR_RTX_MUTEX_GET_NAME_DISABLE +#define EVR_RTX_MUTEX_ACQUIRE_DISABLE +#define EVR_RTX_MUTEX_ACQUIRE_PENDING_DISABLE +#define EVR_RTX_MUTEX_ACQUIRE_TIMEOUT_DISABLE +#define EVR_RTX_MUTEX_ACQUIRED_DISABLE +#define EVR_RTX_MUTEX_NOT_ACQUIRED_DISABLE +#define EVR_RTX_MUTEX_RELEASE_DISABLE +#define EVR_RTX_MUTEX_RELEASED_DISABLE +#define EVR_RTX_MUTEX_GET_OWNER_DISABLE +#define EVR_RTX_MUTEX_DELETE_DISABLE +#define EVR_RTX_MUTEX_DESTROYED_DISABLE +#define EVR_RTX_SEMAPHORE_NEW_DISABLE +#define EVR_RTX_SEMAPHORE_CREATED_DISABLE +#define EVR_RTX_SEMAPHORE_GET_NAME_DISABLE +#define EVR_RTX_SEMAPHORE_ACQUIRE_DISABLE +#define EVR_RTX_SEMAPHORE_ACQUIRE_PENDING_DISABLE +#define EVR_RTX_SEMAPHORE_ACQUIRE_TIMEOUT_DISABLE +#define EVR_RTX_SEMAPHORE_ACQUIRED_DISABLE +#define EVR_RTX_SEMAPHORE_NOT_ACQUIRED_DISABLE +#define EVR_RTX_SEMAPHORE_RELEASE_DISABLE +#define EVR_RTX_SEMAPHORE_RELEASED_DISABLE +#define EVR_RTX_SEMAPHORE_GET_COUNT_DISABLE +#define EVR_RTX_SEMAPHORE_DELETE_DISABLE +#define EVR_RTX_SEMAPHORE_DESTROYED_DISABLE +#define EVR_RTX_MEMORY_POOL_NEW_DISABLE +#define EVR_RTX_MEMORY_POOL_CREATED_DISABLE +#define EVR_RTX_MEMORY_POOL_GET_NAME_DISABLE +#define EVR_RTX_MEMORY_POOL_ALLOC_DISABLE +#define EVR_RTX_MEMORY_POOL_ALLOC_PENDING_DISABLE +#define EVR_RTX_MEMORY_POOL_ALLOC_TIMEOUT_DISABLE +#define EVR_RTX_MEMORY_POOL_ALLOCATED_DISABLE +#define EVR_RTX_MEMORY_POOL_ALLOC_FAILED_DISABLE +#define EVR_RTX_MEMORY_POOL_FREE_DISABLE +#define EVR_RTX_MEMORY_POOL_DEALLOCATED_DISABLE +#define EVR_RTX_MEMORY_POOL_FREE_FAILED_DISABLE +#define EVR_RTX_MEMORY_POOL_GET_CAPACITY_DISABLE +#define EVR_RTX_MEMORY_POOL_GET_BLOCK_SZIE_DISABLE +#define EVR_RTX_MEMORY_POOL_GET_COUNT_DISABLE +#define EVR_RTX_MEMORY_POOL_GET_SPACE_DISABLE +#define EVR_RTX_MEMORY_POOL_DELETE_DISABLE +#define EVR_RTX_MEMORY_POOL_DESTROYED_DISABLE +#define EVR_RTX_MESSAGE_QUEUE_NEW_DISABLE +#define EVR_RTX_MESSAGE_QUEUE_CREATED_DISABLE +#define EVR_RTX_MESSAGE_QUEUE_GET_NAME_DISABLE +#define EVR_RTX_MESSAGE_QUEUE_PUT_DISABLE +#define EVR_RTX_MESSAGE_QUEUE_PUT_PENDING_DISABLE +#define EVR_RTX_MESSAGE_QUEUE_PUT_TIMEOUT_DISABLE +#define EVR_RTX_MESSAGE_QUEUE_INSERT_PENDING_DISABLE +#define EVR_RTX_MESSAGE_QUEUE_INSERTED_DISABLE +#define EVR_RTX_MESSAGE_QUEUE_NOT_INSERTED_DISABLE +#define EVR_RTX_MESSAGE_QUEUE_GET_DISABLE +#define EVR_RTX_MESSAGE_QUEUE_GET_PENDING_DISABLE +#define EVR_RTX_MESSAGE_QUEUE_GET_TIMEOUT_DISABLE +#define EVR_RTX_MESSAGE_QUEUE_RETRIEVED_DISABLE +#define EVR_RTX_MESSAGE_QUEUE_NOT_RETRIEVED_DISABLE +#define EVR_RTX_MESSAGE_QUEUE_GET_CAPACITY_DISABLE +#define EVR_RTX_MESSAGE_QUEUE_GET_MSG_SIZE_DISABLE +#define EVR_RTX_MESSAGE_QUEUE_GET_COUNT_DISABLE +#define EVR_RTX_MESSAGE_QUEUE_GET_SPACE_DISABLE +#define EVR_RTX_MESSAGE_QUEUE_RESET_DISABLE +#define EVR_RTX_MESSAGE_QUEUE_RESET_DONE_DISABLE +#define EVR_RTX_MESSAGE_QUEUE_DELETE_DISABLE +#define EVR_RTX_MESSAGE_QUEUE_DESTROYED_DISABLE + #endif /* MBED_RTX_CONF_H */ diff --git a/rtos/TARGET_CORTEX/mbed_rtx_idle.cpp b/rtos/TARGET_CORTEX/mbed_rtx_idle.cpp index 83db8253aad9..62a78475b5dc 100644 --- a/rtos/TARGET_CORTEX/mbed_rtx_idle.cpp +++ b/rtos/TARGET_CORTEX/mbed_rtx_idle.cpp @@ -63,7 +63,7 @@ void OS_Tick_Disable (void) /// Acknowledge System Timer IRQ. void OS_Tick_AcknowledgeIRQ (void) { - os_timer->schedule_tick(); + } /// Get System Timer count. diff --git a/rtos/Thread.cpp b/rtos/Thread.cpp index d8a24e3d1c9d..3fa93043d69d 100644 --- a/rtos/Thread.cpp +++ b/rtos/Thread.cpp @@ -105,7 +105,7 @@ osStatus Thread::start(Callback task) { //Fill the stack with a magic word for maximum usage checking for (uint32_t i = 0; i < (_attr.stack_size / sizeof(uint32_t)); i++) { - ((uint32_t *)_attr.stack_mem)[i] = 0xE25A2EA5; + ((uint32_t *)_attr.stack_mem)[i] = osRtxStackMagicWord; } memset(&_obj_mem, 0, sizeof(_obj_mem)); @@ -306,7 +306,7 @@ uint32_t Thread::max_stack() { #if defined(MBED_OS_BACKEND_RTX5) mbed_rtos_storage_thread_t *thread = (mbed_rtos_storage_thread_t *)_tid; uint32_t high_mark = 0; - while (((uint32_t *)(thread->stack_mem))[high_mark] == 0xE25A2EA5) + while ((((uint32_t *)(thread->stack_mem))[high_mark] == osRtxStackMagicWord) || (((uint32_t *)(thread->stack_mem))[high_mark] == osRtxStackFillPattern)) high_mark++; size = thread->stack_size - (high_mark * sizeof(uint32_t)); #else diff --git a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0/device/TOOLCHAIN_ARM_STD/MPS2.sct b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0/device/TOOLCHAIN_ARM_STD/MPS2.sct index ba2bb580ade4..585b1d054f71 100644 --- a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0/device/TOOLCHAIN_ARM_STD/MPS2.sct +++ b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0/device/TOOLCHAIN_ARM_STD/MPS2.sct @@ -1,3 +1,4 @@ +#! armcc -E ;* MPS2 CMSIS Library ;* ;* Copyright (c) 2006-2018 ARM Limited @@ -33,15 +34,31 @@ ; *** Scatter-Loading Description File *** ; ************************************************************* -LR_IROM1 0x00000000 0x00400000 { ; load region size_region - ER_IROM1 0x00000000 0x00400000 { ; load address = execution address +#include "../memory_zones.h" +#include "../cmsis_nvic.h" + +#if (defined(__stack_size__)) + #define STACK_SIZE __stack_size__ +#else + #define STACK_SIZE 0x0400 +#endif + +; The vector table is loaded at address 0x00000000 in Flash memory region. +LR_IROM1 MAPPABLE_START MAPPABLE_SIZE { + ER_IROM1 MAPPABLE_START MAPPABLE_SIZE { *.o (RESET, +First) + } +} + +LR_IROM2 ZBT_SRAM1_START ZBT_SRAM1_SIZE { ; load region size_region + ER_IROM2 ZBT_SRAM1_START ZBT_SRAM1_SIZE { ; load address = execution address *(InRoot$$Sections) .ANY (+RO) } - ; Total: 64 vectors = 256 bytes (0x100) to be reserved in RAM - RW_IRAM1 (0x20000000+0x100) (0x400000-0x100) { ; RW data + ; NVIC_VECTORS_SIZE Total: 64 vectors = 256 bytes (0x100) to be reserved in RAM + RW_IRAM1 (ZBT_SRAM2_START + NVIC_VECTORS_SIZE) (ZBT_SRAM2_SIZE - NVIC_VECTORS_SIZE) { ; RW data .ANY (+RW +ZI) } + ARM_LIB_STACK (ZBT_SRAM2_START + ZBT_SRAM2_SIZE) EMPTY - STACK_SIZE { ; Stack region growing down + } } - diff --git a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0/device/TOOLCHAIN_ARM_STD/startup_MPS2.S b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0/device/TOOLCHAIN_ARM_STD/startup_MPS2.S index 1b636342b132..25b9f2cc051d 100644 --- a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0/device/TOOLCHAIN_ARM_STD/startup_MPS2.S +++ b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0/device/TOOLCHAIN_ARM_STD/startup_MPS2.S @@ -34,38 +34,14 @@ ; CMSDK_CM0 Device ; ;****************************************************************************** -; -;-------- <<< Use Configuration Wizard in Context Menu >>> ------------------ -; - - -; Stack Configuration -; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> -; - -Stack_Size EQU 0x00004000 - - AREA STACK, NOINIT, READWRITE, ALIGN=3 -Stack_Mem SPACE Stack_Size -__initial_sp +#include "../memory_zones.h" -; Heap Configuration -; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> -; - -Heap_Size EQU 0x00001000 - - AREA HEAP, NOINIT, READWRITE, ALIGN=3 -__heap_base -Heap_Mem SPACE Heap_Size -__heap_limit - +__initial_sp EQU ZBT_SRAM2_START + ZBT_SRAM2_SIZE PRESERVE8 THUMB - ; Vector Table Mapped to Address 0 at Reset AREA RESET, DATA, READONLY @@ -115,14 +91,14 @@ __Vectors DCD __initial_sp ; Top of Stack DCD UARTTX4_Handler ; UART 4 TX Handler DCD ADCSPI_Handler ; SHIELD ADC SPI exceptions Handler DCD SHIELDSPI_Handler ; SHIELD SPI exceptions Handler - DCD PORT0_0_Handler ; GPIO Port 0 pin 0 Handler - DCD PORT0_1_Handler ; GPIO Port 0 pin 1 Handler - DCD PORT0_2_Handler ; GPIO Port 0 pin 2 Handler - DCD PORT0_3_Handler ; GPIO Port 0 pin 3 Handler - DCD PORT0_4_Handler ; GPIO Port 0 pin 4 Handler - DCD PORT0_5_Handler ; GPIO Port 0 pin 5 Handler - DCD PORT0_6_Handler ; GPIO Port 0 pin 6 Handler - DCD PORT0_7_Handler ; GPIO Port 0 pin 7 Handler + DCD PORT0_0_Handler ; GPIO Port 0 pin 0 Handler + DCD PORT0_1_Handler ; GPIO Port 0 pin 1 Handler + DCD PORT0_2_Handler ; GPIO Port 0 pin 2 Handler + DCD PORT0_3_Handler ; GPIO Port 0 pin 3 Handler + DCD PORT0_4_Handler ; GPIO Port 0 pin 4 Handler + DCD PORT0_5_Handler ; GPIO Port 0 pin 5 Handler + DCD PORT0_6_Handler ; GPIO Port 0 pin 6 Handler + DCD PORT0_7_Handler ; GPIO Port 0 pin 7 Handler __Vectors_End __Vectors_Size EQU __Vectors_End - __Vectors @@ -217,22 +193,22 @@ UARTOVF_Handler ETHERNET_Handler I2S_Handler TSC_Handler -PORT2_COMB_Handler -PORT3_COMB_Handler -UARTRX3_Handler -UARTTX3_Handler -UARTRX4_Handler -UARTTX4_Handler -ADCSPI_Handler -SHIELDSPI_Handler -PORT0_0_Handler -PORT0_1_Handler -PORT0_2_Handler -PORT0_3_Handler -PORT0_4_Handler -PORT0_5_Handler -PORT0_6_Handler -PORT0_7_Handler +PORT2_COMB_Handler +PORT3_COMB_Handler +UARTRX3_Handler +UARTTX3_Handler +UARTRX4_Handler +UARTTX4_Handler +ADCSPI_Handler +SHIELDSPI_Handler +PORT0_0_Handler +PORT0_1_Handler +PORT0_2_Handler +PORT0_3_Handler +PORT0_4_Handler +PORT0_5_Handler +PORT0_6_Handler +PORT0_7_Handler B . ENDP @@ -240,31 +216,4 @@ PORT0_7_Handler ALIGN - -; User Initial Stack & Heap - - IF :DEF:__MICROLIB - - EXPORT __initial_sp - EXPORT __heap_base - EXPORT __heap_limit - - ELSE - - IMPORT __use_two_region_memory - EXPORT __user_initial_stackheap - -__user_initial_stackheap PROC - LDR R0, = Heap_Mem - LDR R1, =(Stack_Mem + Stack_Size) - LDR R2, = (Heap_Mem + Heap_Size) - LDR R3, = Stack_Mem - BX LR - ENDP - - ALIGN - - ENDIF - - END diff --git a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0/device/TOOLCHAIN_GCC_ARM/MPS2.ld b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0/device/TOOLCHAIN_GCC_ARM/MPS2.ld index 7da273eae64b..5ed9d2801b5e 100644 --- a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0/device/TOOLCHAIN_GCC_ARM/MPS2.ld +++ b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0/device/TOOLCHAIN_GCC_ARM/MPS2.ld @@ -27,11 +27,15 @@ /* The length of the VECTORS region is a bit larger than * is necessary based on the number of exception handlers. */ + +#include "../memory_zones.h" +#include "../cmsis_nvic.h" + MEMORY { - VECTORS (rx) : ORIGIN = 0x00000000, LENGTH = 0x00000400 - FLASH (rx) : ORIGIN = 0x00000400, LENGTH = 0x00040000 - 0x00000400 - RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00020000 + VECTORS (rx) : ORIGIN = MAPPABLE_START, LENGTH = MAPPABLE_SIZE + FLASH (rx) : ORIGIN = ZBT_SRAM1_START, LENGTH = ZBT_SRAM1_SIZE + RAM (rwx) : ORIGIN = ZBT_SRAM2_START, LENGTH = ZBT_SRAM2_SIZE } /* Linker script to place sections and symbol values. Should be used together @@ -62,11 +66,10 @@ MEMORY */ ENTRY(Reset_Handler) -HEAP_SIZE = 0x4000; -STACK_SIZE = 0x1000; +STACK_SIZE = 0x400; /* Size of the vector table in SRAM */ -M_VECTOR_RAM_SIZE = 0x140; +M_VECTOR_RAM_SIZE = 0x100; SECTIONS { @@ -188,13 +191,13 @@ SECTIONS bss_size = __bss_end__ - __bss_start__; - .heap : + .heap (COPY): { . = ALIGN(8); __end__ = .; PROVIDE(end = .); __HeapBase = .; - . += HEAP_SIZE; + *(.heap*) __HeapLimit = .; __heap_limit = .; /* Add for _sbrk */ } > RAM diff --git a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0/device/TOOLCHAIN_IAR/MPS2.icf b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0/device/TOOLCHAIN_IAR/MPS2.icf index 60b104bcf3fb..936ce2e87259 100644 --- a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0/device/TOOLCHAIN_IAR/MPS2.icf +++ b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0/device/TOOLCHAIN_IAR/MPS2.icf @@ -19,25 +19,37 @@ * limitations under the License. */ -/* The RAM region doesn't start at the beginning of the RAM address - * space to create space for the vector table copied over to the RAM by mbed. - * The space left is a bit bigger than is necessary based on the number of - * interrupt handlers. +/* + * WARNING: these symbols are the same as the defines in ../memory_zones.h but + * can not be included here. Please make sure that the two definitions match. */ -/*###ICF### Section handled by ICF editor, don't touch! ****/ -/*-Editor annotation file-*/ -/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/* Code memory zones */ +define symbol MAPPABLE_START = 0x00000000; +define symbol MAPPABLE_SIZE = 0x00004000; /* 16 KiB */ +define symbol ZBT_SRAM1_START = (0x00000000 + 0x00004000); +define symbol ZBT_SRAM1_SIZE = (0x00400000 - 0x00004000); /* 4 MiB - 16 KiB */ + +/* Data memory zones */ +define symbol ZBT_SRAM2_START = 0x20000000; +define symbol ZBT_SRAM2_SIZE = 0x00400000; /* 4 MB */ + +/* NVIC vector numbers and size. */ +define symbol NVIC_NUM_VECTORS = (16 + 48); +define symbol NVIC_VECTORS_SIZE = (NVIC_NUM_VECTORS * 4); + /*-Specials-*/ -define symbol __ICFEDIT_intvec_start__ = 0x00000000; +define symbol __ICFEDIT_intvec_start__ = MAPPABLE_START; + /*-Memory Regions-*/ -define symbol __ICFEDIT_region_ROM_start__ = 0x00000000; -define symbol __ICFEDIT_region_ROM_end__ = 0x0003FFFF; -define symbol __ICFEDIT_region_RAM_start__ = 0x20000140; -define symbol __ICFEDIT_region_RAM_end__ = 0x2001FFFF; +define symbol __ICFEDIT_region_ROM_start__ = ZBT_SRAM1_START; +define symbol __ICFEDIT_region_ROM_end__ = ZBT_SRAM1_START + ZBT_SRAM1_SIZE - 1; +define symbol __ICFEDIT_region_RAM_start__ = ZBT_SRAM2_START + NVIC_VECTORS_SIZE; +define symbol __ICFEDIT_region_RAM_end__ = ZBT_SRAM2_START + ZBT_SRAM2_SIZE - 1; + /*-Sizes-*/ /* Heap and Stack size */ -define symbol __ICFEDIT_size_heap__ = 0x4000; -define symbol __ICFEDIT_size_cstack__ = 0x1000; +define symbol __ICFEDIT_size_heap__ = 0x200000; +define symbol __ICFEDIT_size_cstack__ = 0x400; /**** End of ICF editor section. ###ICF###*/ define memory mem with size = 4G; diff --git a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0/device/cmsis_nvic.c b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0/device/cmsis_nvic.c deleted file mode 100644 index 98d463113f96..000000000000 --- a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0/device/cmsis_nvic.c +++ /dev/null @@ -1,56 +0,0 @@ -/* MPS2 CMSIS Library -* -* Copyright (c) 2006-2018 ARM Limited -* 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 the copyright holder 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. -******************************************************************************* -* CMSIS-style functionality to support dynamic vectors -*******************************************************************************/ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Location of vectors in RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x00000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) -{ - // int i; - // Space for dynamic vectors, initialised to allocate in R/W - static volatile uint32_t *vectors = (uint32_t *)NVIC_FLASH_VECTOR_ADDRESS; - - // Set the vector - vectors[IRQn + 16] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) -{ - // We can always read vectors at 0x0, as the addresses are remapped - uint32_t *vectors = (uint32_t *)NVIC_FLASH_VECTOR_ADDRESS; - - // Return the vector - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0/device/cmsis_nvic.h b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0/device/cmsis_nvic.h index 08faa70cffd8..37bb7929271b 100644 --- a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0/device/cmsis_nvic.h +++ b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0/device/cmsis_nvic.h @@ -28,27 +28,20 @@ * 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. -******************************************************************************* -* CMSIS-style functionality to support dynamic vectors *******************************************************************************/ + #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#include "cmsis.h" - -#define NVIC_NUM_VECTORS (16 + 48) -#define NVIC_USER_IRQ_OFFSET 16 +#include "memory_zones.h" -#ifdef __cplusplus -extern "C" { -#endif +#define NVIC_NUM_VECTORS (16 + 48) +#define NVIC_RAM_VECTOR_ADDRESS ZBT_SRAM2_START // Location of vectors in RAM -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +/* + * Size of the whole vector table in bytes. Each vector is on 32 bits. + */ +#define NVIC_VECTORS_SIZE (NVIC_NUM_VECTORS * 4) #endif diff --git a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/memory_zones.h b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0/device/memory_zones.h similarity index 77% rename from targets/TARGET_ARM_FM/TARGET_FVP_MPS2/memory_zones.h rename to targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0/device/memory_zones.h index 53b8b10aad60..8987bc22623e 100644 --- a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/memory_zones.h +++ b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0/device/memory_zones.h @@ -32,19 +32,19 @@ /* * Code memory zones - * Please note that MPS2 on Fast Models do not simulate persistent flash memory. - * The FLASH memory zone is a 256 KiB SRAM block and named FLASH + * Please note that MPS2 on Fast Models do not implemented persistent flash memory. + * The FLASH memory can be simulated via 4MB ZBT_SRAM1 block * only to keep the same name than in the CMSDK RTL and Fast Models Reference * Guide. */ -#define FLASH_START 0x00000000 -#define FLASH_SIZE 0x00040000 /* 256 KiB */ -#define ZBT_SRAM1_START 0x00400000 -#define ZBT_SRAM1_SIZE 0x00400000 /* 4 MiB */ +#define MAPPABLE_START 0x00000000 +#define MAPPABLE_SIZE 0x00004000 /* 16 KiB */ +#define ZBT_SRAM1_START (0x00000000 + 0x00004000) +#define ZBT_SRAM1_SIZE (0x00400000 - 0x00004000) /* 4 MiB - 16 KiB*/ /* Data memory zones */ #define ZBT_SRAM2_START 0x20000000 -#define ZBT_SRAM2_SIZE 0x00800000 /* 8 MiB */ +#define ZBT_SRAM2_SIZE 0x00400000 /* 4 MiB */ #endif /* MEMORY_ZONES_H */ diff --git a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0P/device/TOOLCHAIN_ARM_STD/MPS2.sct b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0P/device/TOOLCHAIN_ARM_STD/MPS2.sct index ba2bb580ade4..585b1d054f71 100644 --- a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0P/device/TOOLCHAIN_ARM_STD/MPS2.sct +++ b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0P/device/TOOLCHAIN_ARM_STD/MPS2.sct @@ -1,3 +1,4 @@ +#! armcc -E ;* MPS2 CMSIS Library ;* ;* Copyright (c) 2006-2018 ARM Limited @@ -33,15 +34,31 @@ ; *** Scatter-Loading Description File *** ; ************************************************************* -LR_IROM1 0x00000000 0x00400000 { ; load region size_region - ER_IROM1 0x00000000 0x00400000 { ; load address = execution address +#include "../memory_zones.h" +#include "../cmsis_nvic.h" + +#if (defined(__stack_size__)) + #define STACK_SIZE __stack_size__ +#else + #define STACK_SIZE 0x0400 +#endif + +; The vector table is loaded at address 0x00000000 in Flash memory region. +LR_IROM1 MAPPABLE_START MAPPABLE_SIZE { + ER_IROM1 MAPPABLE_START MAPPABLE_SIZE { *.o (RESET, +First) + } +} + +LR_IROM2 ZBT_SRAM1_START ZBT_SRAM1_SIZE { ; load region size_region + ER_IROM2 ZBT_SRAM1_START ZBT_SRAM1_SIZE { ; load address = execution address *(InRoot$$Sections) .ANY (+RO) } - ; Total: 64 vectors = 256 bytes (0x100) to be reserved in RAM - RW_IRAM1 (0x20000000+0x100) (0x400000-0x100) { ; RW data + ; NVIC_VECTORS_SIZE Total: 64 vectors = 256 bytes (0x100) to be reserved in RAM + RW_IRAM1 (ZBT_SRAM2_START + NVIC_VECTORS_SIZE) (ZBT_SRAM2_SIZE - NVIC_VECTORS_SIZE) { ; RW data .ANY (+RW +ZI) } + ARM_LIB_STACK (ZBT_SRAM2_START + ZBT_SRAM2_SIZE) EMPTY - STACK_SIZE { ; Stack region growing down + } } - diff --git a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0P/device/TOOLCHAIN_ARM_STD/startup_MPS2.S b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0P/device/TOOLCHAIN_ARM_STD/startup_MPS2.S index b9dea8d808f2..991c6463d86e 100644 --- a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0P/device/TOOLCHAIN_ARM_STD/startup_MPS2.S +++ b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0P/device/TOOLCHAIN_ARM_STD/startup_MPS2.S @@ -34,38 +34,14 @@ ; CMSDK_CM0P Device ; ;****************************************************************************** -; -;-------- <<< Use Configuration Wizard in Context Menu >>> ------------------ -; - - -; Stack Configuration -; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> -; - -Stack_Size EQU 0x00004000 - - AREA STACK, NOINIT, READWRITE, ALIGN=3 -Stack_Mem SPACE Stack_Size -__initial_sp +#include "../memory_zones.h" -; Heap Configuration -; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> -; - -Heap_Size EQU 0x00001000 - - AREA HEAP, NOINIT, READWRITE, ALIGN=3 -__heap_base -Heap_Mem SPACE Heap_Size -__heap_limit - +__initial_sp EQU ZBT_SRAM2_START + ZBT_SRAM2_SIZE PRESERVE8 THUMB - ; Vector Table Mapped to Address 0 at Reset AREA RESET, DATA, READONLY @@ -240,31 +216,4 @@ PORT0_7_Handler ALIGN - -; User Initial Stack & Heap - - IF :DEF:__MICROLIB - - EXPORT __initial_sp - EXPORT __heap_base - EXPORT __heap_limit - - ELSE - - IMPORT __use_two_region_memory - EXPORT __user_initial_stackheap - -__user_initial_stackheap PROC - LDR R0, = Heap_Mem - LDR R1, =(Stack_Mem + Stack_Size) - LDR R2, = (Heap_Mem + Heap_Size) - LDR R3, = Stack_Mem - BX LR - ENDP - - ALIGN - - ENDIF - - END diff --git a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0P/device/TOOLCHAIN_GCC_ARM/MPS2.ld b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0P/device/TOOLCHAIN_GCC_ARM/MPS2.ld index f9167e9edd8e..647cc848eac7 100644 --- a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0P/device/TOOLCHAIN_GCC_ARM/MPS2.ld +++ b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0P/device/TOOLCHAIN_GCC_ARM/MPS2.ld @@ -27,11 +27,15 @@ /* The length of the VECTORS region is a bit larger than * is necessary based on the number of exception handlers. */ + +#include "../memory_zones.h" +#include "../cmsis_nvic.h" + MEMORY { - VECTORS (rx) : ORIGIN = 0x00000000, LENGTH = 0x00000400 - FLASH (rx) : ORIGIN = 0x00000400, LENGTH = 0x00040000 - 0x00000400 - RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00020000 + VECTORS (rx) : ORIGIN = MAPPABLE_START, LENGTH = MAPPABLE_SIZE + FLASH (rx) : ORIGIN = ZBT_SRAM1_START, LENGTH = ZBT_SRAM1_SIZE + RAM (rwx) : ORIGIN = ZBT_SRAM2_START, LENGTH = ZBT_SRAM2_SIZE } /* Linker script to place sections and symbol values. Should be used together @@ -62,11 +66,10 @@ MEMORY */ ENTRY(Reset_Handler) -HEAP_SIZE = 0x4000; -STACK_SIZE = 0x1000; +STACK_SIZE = 0x400; /* Size of the vector table in SRAM */ -M_VECTOR_RAM_SIZE = 0x140; +M_VECTOR_RAM_SIZE = NVIC_VECTORS_SIZE; SECTIONS { @@ -188,13 +191,13 @@ SECTIONS bss_size = __bss_end__ - __bss_start__; - .heap : + .heap (COPY): { . = ALIGN(8); __end__ = .; PROVIDE(end = .); __HeapBase = .; - . += HEAP_SIZE; + *(.heap*) __HeapLimit = .; __heap_limit = .; /* Add for _sbrk */ } > RAM diff --git a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0P/device/TOOLCHAIN_IAR/MPS2.icf b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0P/device/TOOLCHAIN_IAR/MPS2.icf index 60b104bcf3fb..936ce2e87259 100644 --- a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0P/device/TOOLCHAIN_IAR/MPS2.icf +++ b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0P/device/TOOLCHAIN_IAR/MPS2.icf @@ -19,25 +19,37 @@ * limitations under the License. */ -/* The RAM region doesn't start at the beginning of the RAM address - * space to create space for the vector table copied over to the RAM by mbed. - * The space left is a bit bigger than is necessary based on the number of - * interrupt handlers. +/* + * WARNING: these symbols are the same as the defines in ../memory_zones.h but + * can not be included here. Please make sure that the two definitions match. */ -/*###ICF### Section handled by ICF editor, don't touch! ****/ -/*-Editor annotation file-*/ -/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/* Code memory zones */ +define symbol MAPPABLE_START = 0x00000000; +define symbol MAPPABLE_SIZE = 0x00004000; /* 16 KiB */ +define symbol ZBT_SRAM1_START = (0x00000000 + 0x00004000); +define symbol ZBT_SRAM1_SIZE = (0x00400000 - 0x00004000); /* 4 MiB - 16 KiB */ + +/* Data memory zones */ +define symbol ZBT_SRAM2_START = 0x20000000; +define symbol ZBT_SRAM2_SIZE = 0x00400000; /* 4 MB */ + +/* NVIC vector numbers and size. */ +define symbol NVIC_NUM_VECTORS = (16 + 48); +define symbol NVIC_VECTORS_SIZE = (NVIC_NUM_VECTORS * 4); + /*-Specials-*/ -define symbol __ICFEDIT_intvec_start__ = 0x00000000; +define symbol __ICFEDIT_intvec_start__ = MAPPABLE_START; + /*-Memory Regions-*/ -define symbol __ICFEDIT_region_ROM_start__ = 0x00000000; -define symbol __ICFEDIT_region_ROM_end__ = 0x0003FFFF; -define symbol __ICFEDIT_region_RAM_start__ = 0x20000140; -define symbol __ICFEDIT_region_RAM_end__ = 0x2001FFFF; +define symbol __ICFEDIT_region_ROM_start__ = ZBT_SRAM1_START; +define symbol __ICFEDIT_region_ROM_end__ = ZBT_SRAM1_START + ZBT_SRAM1_SIZE - 1; +define symbol __ICFEDIT_region_RAM_start__ = ZBT_SRAM2_START + NVIC_VECTORS_SIZE; +define symbol __ICFEDIT_region_RAM_end__ = ZBT_SRAM2_START + ZBT_SRAM2_SIZE - 1; + /*-Sizes-*/ /* Heap and Stack size */ -define symbol __ICFEDIT_size_heap__ = 0x4000; -define symbol __ICFEDIT_size_cstack__ = 0x1000; +define symbol __ICFEDIT_size_heap__ = 0x200000; +define symbol __ICFEDIT_size_cstack__ = 0x400; /**** End of ICF editor section. ###ICF###*/ define memory mem with size = 4G; diff --git a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0P/device/cmsis_nvic.h b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0P/device/cmsis_nvic.h index a564abfc18cd..94619a9e556f 100644 --- a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0P/device/cmsis_nvic.h +++ b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0P/device/cmsis_nvic.h @@ -33,7 +33,14 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H +#include "memory_zones.h" + #define NVIC_NUM_VECTORS (16 + 48) -#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Location of vectors in RAM +#define NVIC_RAM_VECTOR_ADDRESS ZBT_SRAM2_START // Location of vectors in RAM + +/* + * Size of the whole vector table in bytes. Each vector is on 32 bits. + */ +#define NVIC_VECTORS_SIZE (NVIC_NUM_VECTORS * 4) #endif diff --git a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0P/device/memory_zones.h b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0P/device/memory_zones.h new file mode 100644 index 000000000000..8987bc22623e --- /dev/null +++ b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M0P/device/memory_zones.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2017-2018 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. + */ + +/* + * This file contains the information of memory zones for code and data on + * ARM Versatile Express Cortex-M Prototyping Systems (V2M-MPS2) TRM. + * It is used in startup code and linker scripts of supported compilers (ARM and + * GCC_ARM). + * + * WARNING: IAR does not include this file and re-define these values in + * MPS2.icf file. Please make sure that the two files share the same values. + * + * These memory zones are defined in section 4.2 of ARM V2M-MPS2 RTL and + * Fast Model Reference Guide. + */ + +#ifndef MEMORY_ZONES_H +#define MEMORY_ZONES_H + +/* + * Code memory zones + * Please note that MPS2 on Fast Models do not implemented persistent flash memory. + * The FLASH memory can be simulated via 4MB ZBT_SRAM1 block + * only to keep the same name than in the CMSDK RTL and Fast Models Reference + * Guide. + */ +#define MAPPABLE_START 0x00000000 +#define MAPPABLE_SIZE 0x00004000 /* 16 KiB */ +#define ZBT_SRAM1_START (0x00000000 + 0x00004000) +#define ZBT_SRAM1_SIZE (0x00400000 - 0x00004000) /* 4 MiB - 16 KiB*/ + +/* Data memory zones */ +#define ZBT_SRAM2_START 0x20000000 +#define ZBT_SRAM2_SIZE 0x00400000 /* 4 MiB */ + +#endif /* MEMORY_ZONES_H */ + diff --git a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M3/device/TOOLCHAIN_ARM_STD/MPS2.sct b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M3/device/TOOLCHAIN_ARM_STD/MPS2.sct index ba2bb580ade4..585b1d054f71 100644 --- a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M3/device/TOOLCHAIN_ARM_STD/MPS2.sct +++ b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M3/device/TOOLCHAIN_ARM_STD/MPS2.sct @@ -1,3 +1,4 @@ +#! armcc -E ;* MPS2 CMSIS Library ;* ;* Copyright (c) 2006-2018 ARM Limited @@ -33,15 +34,31 @@ ; *** Scatter-Loading Description File *** ; ************************************************************* -LR_IROM1 0x00000000 0x00400000 { ; load region size_region - ER_IROM1 0x00000000 0x00400000 { ; load address = execution address +#include "../memory_zones.h" +#include "../cmsis_nvic.h" + +#if (defined(__stack_size__)) + #define STACK_SIZE __stack_size__ +#else + #define STACK_SIZE 0x0400 +#endif + +; The vector table is loaded at address 0x00000000 in Flash memory region. +LR_IROM1 MAPPABLE_START MAPPABLE_SIZE { + ER_IROM1 MAPPABLE_START MAPPABLE_SIZE { *.o (RESET, +First) + } +} + +LR_IROM2 ZBT_SRAM1_START ZBT_SRAM1_SIZE { ; load region size_region + ER_IROM2 ZBT_SRAM1_START ZBT_SRAM1_SIZE { ; load address = execution address *(InRoot$$Sections) .ANY (+RO) } - ; Total: 64 vectors = 256 bytes (0x100) to be reserved in RAM - RW_IRAM1 (0x20000000+0x100) (0x400000-0x100) { ; RW data + ; NVIC_VECTORS_SIZE Total: 64 vectors = 256 bytes (0x100) to be reserved in RAM + RW_IRAM1 (ZBT_SRAM2_START + NVIC_VECTORS_SIZE) (ZBT_SRAM2_SIZE - NVIC_VECTORS_SIZE) { ; RW data .ANY (+RW +ZI) } + ARM_LIB_STACK (ZBT_SRAM2_START + ZBT_SRAM2_SIZE) EMPTY - STACK_SIZE { ; Stack region growing down + } } - diff --git a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M3/device/TOOLCHAIN_ARM_STD/startup_MPS2.S b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M3/device/TOOLCHAIN_ARM_STD/startup_MPS2.S index 10ac6225e4cf..273008bfbecd 100644 --- a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M3/device/TOOLCHAIN_ARM_STD/startup_MPS2.S +++ b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M3/device/TOOLCHAIN_ARM_STD/startup_MPS2.S @@ -34,38 +34,14 @@ ; CMSDK_CM3 Device ; ;****************************************************************************** -; -;-------- <<< Use Configuration Wizard in Context Menu >>> ------------------ -; - - -; Stack Configuration -; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> -; - -Stack_Size EQU 0x00004000 - - AREA STACK, NOINIT, READWRITE, ALIGN=3 -Stack_Mem SPACE Stack_Size -__initial_sp +#include "../memory_zones.h" -; Heap Configuration -; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> -; - -Heap_Size EQU 0x00001000 - - AREA HEAP, NOINIT, READWRITE, ALIGN=3 -__heap_base -Heap_Mem SPACE Heap_Size -__heap_limit - +__initial_sp EQU ZBT_SRAM2_START + ZBT_SRAM2_SIZE PRESERVE8 THUMB - ; Vector Table Mapped to Address 0 at Reset AREA RESET, DATA, READONLY @@ -260,31 +236,4 @@ PORT0_7_Handler ALIGN - -; User Initial Stack & Heap - - IF :DEF:__MICROLIB - - EXPORT __initial_sp - EXPORT __heap_base - EXPORT __heap_limit - - ELSE - - IMPORT __use_two_region_memory - EXPORT __user_initial_stackheap - -__user_initial_stackheap PROC - LDR R0, = Heap_Mem - LDR R1, =(Stack_Mem + Stack_Size) - LDR R2, = (Heap_Mem + Heap_Size) - LDR R3, = Stack_Mem - BX LR - ENDP - - ALIGN - - ENDIF - - END diff --git a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M3/device/TOOLCHAIN_GCC_ARM/MPS2.ld b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M3/device/TOOLCHAIN_GCC_ARM/MPS2.ld index 2518b646a33b..dc784fcae496 100644 --- a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M3/device/TOOLCHAIN_GCC_ARM/MPS2.ld +++ b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M3/device/TOOLCHAIN_GCC_ARM/MPS2.ld @@ -27,11 +27,15 @@ /* The length of the VECTORS region is a bit larger than * is necessary based on the number of exception handlers. */ + +#include "../memory_zones.h" +#include "../cmsis_nvic.h" + MEMORY { - VECTORS (rx) : ORIGIN = 0x00000000, LENGTH = 0x00000400 - FLASH (rx) : ORIGIN = 0x00000400, LENGTH = 0x00040000 - 0x00000400 - RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00020000 + VECTORS (rx) : ORIGIN = MAPPABLE_START, LENGTH = MAPPABLE_SIZE + FLASH (rx) : ORIGIN = ZBT_SRAM1_START, LENGTH = ZBT_SRAM1_SIZE + RAM (rwx) : ORIGIN = ZBT_SRAM2_START, LENGTH = ZBT_SRAM2_SIZE } /* Linker script to place sections and symbol values. Should be used together @@ -62,11 +66,10 @@ MEMORY */ ENTRY(Reset_Handler) -HEAP_SIZE = 0x4000; -STACK_SIZE = 0x1000; +STACK_SIZE = 0x400; /* Size of the vector table in SRAM */ -M_VECTOR_RAM_SIZE = 0x140; +M_VECTOR_RAM_SIZE = NVIC_VECTORS_SIZE; SECTIONS { @@ -188,13 +191,13 @@ SECTIONS bss_size = __bss_end__ - __bss_start__; - .heap : + .heap (COPY): { . = ALIGN(8); __end__ = .; PROVIDE(end = .); __HeapBase = .; - . += HEAP_SIZE; + *(.heap*) __HeapLimit = .; __heap_limit = .; /* Add for _sbrk */ } > RAM diff --git a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M3/device/TOOLCHAIN_IAR/MPS2.icf b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M3/device/TOOLCHAIN_IAR/MPS2.icf index 60b104bcf3fb..936ce2e87259 100644 --- a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M3/device/TOOLCHAIN_IAR/MPS2.icf +++ b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M3/device/TOOLCHAIN_IAR/MPS2.icf @@ -19,25 +19,37 @@ * limitations under the License. */ -/* The RAM region doesn't start at the beginning of the RAM address - * space to create space for the vector table copied over to the RAM by mbed. - * The space left is a bit bigger than is necessary based on the number of - * interrupt handlers. +/* + * WARNING: these symbols are the same as the defines in ../memory_zones.h but + * can not be included here. Please make sure that the two definitions match. */ -/*###ICF### Section handled by ICF editor, don't touch! ****/ -/*-Editor annotation file-*/ -/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/* Code memory zones */ +define symbol MAPPABLE_START = 0x00000000; +define symbol MAPPABLE_SIZE = 0x00004000; /* 16 KiB */ +define symbol ZBT_SRAM1_START = (0x00000000 + 0x00004000); +define symbol ZBT_SRAM1_SIZE = (0x00400000 - 0x00004000); /* 4 MiB - 16 KiB */ + +/* Data memory zones */ +define symbol ZBT_SRAM2_START = 0x20000000; +define symbol ZBT_SRAM2_SIZE = 0x00400000; /* 4 MB */ + +/* NVIC vector numbers and size. */ +define symbol NVIC_NUM_VECTORS = (16 + 48); +define symbol NVIC_VECTORS_SIZE = (NVIC_NUM_VECTORS * 4); + /*-Specials-*/ -define symbol __ICFEDIT_intvec_start__ = 0x00000000; +define symbol __ICFEDIT_intvec_start__ = MAPPABLE_START; + /*-Memory Regions-*/ -define symbol __ICFEDIT_region_ROM_start__ = 0x00000000; -define symbol __ICFEDIT_region_ROM_end__ = 0x0003FFFF; -define symbol __ICFEDIT_region_RAM_start__ = 0x20000140; -define symbol __ICFEDIT_region_RAM_end__ = 0x2001FFFF; +define symbol __ICFEDIT_region_ROM_start__ = ZBT_SRAM1_START; +define symbol __ICFEDIT_region_ROM_end__ = ZBT_SRAM1_START + ZBT_SRAM1_SIZE - 1; +define symbol __ICFEDIT_region_RAM_start__ = ZBT_SRAM2_START + NVIC_VECTORS_SIZE; +define symbol __ICFEDIT_region_RAM_end__ = ZBT_SRAM2_START + ZBT_SRAM2_SIZE - 1; + /*-Sizes-*/ /* Heap and Stack size */ -define symbol __ICFEDIT_size_heap__ = 0x4000; -define symbol __ICFEDIT_size_cstack__ = 0x1000; +define symbol __ICFEDIT_size_heap__ = 0x200000; +define symbol __ICFEDIT_size_cstack__ = 0x400; /**** End of ICF editor section. ###ICF###*/ define memory mem with size = 4G; diff --git a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M3/device/cmsis_nvic.h b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M3/device/cmsis_nvic.h index a564abfc18cd..37bb7929271b 100644 --- a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M3/device/cmsis_nvic.h +++ b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M3/device/cmsis_nvic.h @@ -30,10 +30,18 @@ * POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ + #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H +#include "memory_zones.h" + #define NVIC_NUM_VECTORS (16 + 48) -#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Location of vectors in RAM +#define NVIC_RAM_VECTOR_ADDRESS ZBT_SRAM2_START // Location of vectors in RAM + +/* + * Size of the whole vector table in bytes. Each vector is on 32 bits. + */ +#define NVIC_VECTORS_SIZE (NVIC_NUM_VECTORS * 4) #endif diff --git a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M3/device/memory_zones.h b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M3/device/memory_zones.h new file mode 100644 index 000000000000..8987bc22623e --- /dev/null +++ b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M3/device/memory_zones.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2017-2018 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. + */ + +/* + * This file contains the information of memory zones for code and data on + * ARM Versatile Express Cortex-M Prototyping Systems (V2M-MPS2) TRM. + * It is used in startup code and linker scripts of supported compilers (ARM and + * GCC_ARM). + * + * WARNING: IAR does not include this file and re-define these values in + * MPS2.icf file. Please make sure that the two files share the same values. + * + * These memory zones are defined in section 4.2 of ARM V2M-MPS2 RTL and + * Fast Model Reference Guide. + */ + +#ifndef MEMORY_ZONES_H +#define MEMORY_ZONES_H + +/* + * Code memory zones + * Please note that MPS2 on Fast Models do not implemented persistent flash memory. + * The FLASH memory can be simulated via 4MB ZBT_SRAM1 block + * only to keep the same name than in the CMSDK RTL and Fast Models Reference + * Guide. + */ +#define MAPPABLE_START 0x00000000 +#define MAPPABLE_SIZE 0x00004000 /* 16 KiB */ +#define ZBT_SRAM1_START (0x00000000 + 0x00004000) +#define ZBT_SRAM1_SIZE (0x00400000 - 0x00004000) /* 4 MiB - 16 KiB*/ + +/* Data memory zones */ +#define ZBT_SRAM2_START 0x20000000 +#define ZBT_SRAM2_SIZE 0x00400000 /* 4 MiB */ + +#endif /* MEMORY_ZONES_H */ + diff --git a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M4/device/TOOLCHAIN_ARM_STD/MPS2.sct b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M4/device/TOOLCHAIN_ARM_STD/MPS2.sct index ba2bb580ade4..585b1d054f71 100644 --- a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M4/device/TOOLCHAIN_ARM_STD/MPS2.sct +++ b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M4/device/TOOLCHAIN_ARM_STD/MPS2.sct @@ -1,3 +1,4 @@ +#! armcc -E ;* MPS2 CMSIS Library ;* ;* Copyright (c) 2006-2018 ARM Limited @@ -33,15 +34,31 @@ ; *** Scatter-Loading Description File *** ; ************************************************************* -LR_IROM1 0x00000000 0x00400000 { ; load region size_region - ER_IROM1 0x00000000 0x00400000 { ; load address = execution address +#include "../memory_zones.h" +#include "../cmsis_nvic.h" + +#if (defined(__stack_size__)) + #define STACK_SIZE __stack_size__ +#else + #define STACK_SIZE 0x0400 +#endif + +; The vector table is loaded at address 0x00000000 in Flash memory region. +LR_IROM1 MAPPABLE_START MAPPABLE_SIZE { + ER_IROM1 MAPPABLE_START MAPPABLE_SIZE { *.o (RESET, +First) + } +} + +LR_IROM2 ZBT_SRAM1_START ZBT_SRAM1_SIZE { ; load region size_region + ER_IROM2 ZBT_SRAM1_START ZBT_SRAM1_SIZE { ; load address = execution address *(InRoot$$Sections) .ANY (+RO) } - ; Total: 64 vectors = 256 bytes (0x100) to be reserved in RAM - RW_IRAM1 (0x20000000+0x100) (0x400000-0x100) { ; RW data + ; NVIC_VECTORS_SIZE Total: 64 vectors = 256 bytes (0x100) to be reserved in RAM + RW_IRAM1 (ZBT_SRAM2_START + NVIC_VECTORS_SIZE) (ZBT_SRAM2_SIZE - NVIC_VECTORS_SIZE) { ; RW data .ANY (+RW +ZI) } + ARM_LIB_STACK (ZBT_SRAM2_START + ZBT_SRAM2_SIZE) EMPTY - STACK_SIZE { ; Stack region growing down + } } - diff --git a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M4/device/TOOLCHAIN_ARM_STD/startup_MPS2.S b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M4/device/TOOLCHAIN_ARM_STD/startup_MPS2.S index 2a8720ff8b18..0697dc19e2eb 100644 --- a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M4/device/TOOLCHAIN_ARM_STD/startup_MPS2.S +++ b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M4/device/TOOLCHAIN_ARM_STD/startup_MPS2.S @@ -34,38 +34,14 @@ ; CMSDK_CM4 Device ; ;****************************************************************************** -; -;-------- <<< Use Configuration Wizard in Context Menu >>> ------------------ -; - - -; Stack Configuration -; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> -; - -Stack_Size EQU 0x00004000 - - AREA STACK, NOINIT, READWRITE, ALIGN=3 -Stack_Mem SPACE Stack_Size -__initial_sp +#include "../memory_zones.h" -; Heap Configuration -; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> -; - -Heap_Size EQU 0x00001000 - - AREA HEAP, NOINIT, READWRITE, ALIGN=3 -__heap_base -Heap_Mem SPACE Heap_Size -__heap_limit - +__initial_sp EQU ZBT_SRAM2_START + ZBT_SRAM2_SIZE PRESERVE8 THUMB - ; Vector Table Mapped to Address 0 at Reset AREA RESET, DATA, READONLY @@ -260,31 +236,4 @@ PORT0_7_Handler ALIGN - -; User Initial Stack & Heap - - IF :DEF:__MICROLIB - - EXPORT __initial_sp - EXPORT __heap_base - EXPORT __heap_limit - - ELSE - - IMPORT __use_two_region_memory - EXPORT __user_initial_stackheap - -__user_initial_stackheap PROC - LDR R0, = Heap_Mem - LDR R1, =(Stack_Mem + Stack_Size) - LDR R2, = (Heap_Mem + Heap_Size) - LDR R3, = Stack_Mem - BX LR - ENDP - - ALIGN - - ENDIF - - END diff --git a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M4/device/TOOLCHAIN_GCC_ARM/MPS2.ld b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M4/device/TOOLCHAIN_GCC_ARM/MPS2.ld index 2d020431a975..31e576bf98bf 100644 --- a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M4/device/TOOLCHAIN_GCC_ARM/MPS2.ld +++ b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M4/device/TOOLCHAIN_GCC_ARM/MPS2.ld @@ -27,11 +27,15 @@ /* The length of the VECTORS region is a bit larger than * is necessary based on the number of exception handlers. */ + +#include "../memory_zones.h" +#include "../cmsis_nvic.h" + MEMORY { - VECTORS (rx) : ORIGIN = 0x00000000, LENGTH = 0x00000400 - FLASH (rx) : ORIGIN = 0x00000400, LENGTH = 0x00040000 - 0x00000400 - RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00020000 + VECTORS (rx) : ORIGIN = MAPPABLE_START, LENGTH = MAPPABLE_SIZE + FLASH (rx) : ORIGIN = ZBT_SRAM1_START, LENGTH = ZBT_SRAM1_SIZE + RAM (rwx) : ORIGIN = ZBT_SRAM2_START, LENGTH = ZBT_SRAM2_SIZE } /* Linker script to place sections and symbol values. Should be used together @@ -62,11 +66,10 @@ MEMORY */ ENTRY(Reset_Handler) -HEAP_SIZE = 0x4000; -STACK_SIZE = 0x1000; +STACK_SIZE = 0x400; /* Size of the vector table in SRAM */ -M_VECTOR_RAM_SIZE = 0x140; +M_VECTOR_RAM_SIZE = NVIC_VECTORS_SIZE; SECTIONS { @@ -188,13 +191,13 @@ SECTIONS bss_size = __bss_end__ - __bss_start__; - .heap : + .heap (COPY): { . = ALIGN(8); __end__ = .; PROVIDE(end = .); __HeapBase = .; - . += HEAP_SIZE; + *(.heap*) __HeapLimit = .; __heap_limit = .; /* Add for _sbrk */ } > RAM diff --git a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M4/device/TOOLCHAIN_IAR/MPS2.icf b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M4/device/TOOLCHAIN_IAR/MPS2.icf index 60b104bcf3fb..936ce2e87259 100644 --- a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M4/device/TOOLCHAIN_IAR/MPS2.icf +++ b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M4/device/TOOLCHAIN_IAR/MPS2.icf @@ -19,25 +19,37 @@ * limitations under the License. */ -/* The RAM region doesn't start at the beginning of the RAM address - * space to create space for the vector table copied over to the RAM by mbed. - * The space left is a bit bigger than is necessary based on the number of - * interrupt handlers. +/* + * WARNING: these symbols are the same as the defines in ../memory_zones.h but + * can not be included here. Please make sure that the two definitions match. */ -/*###ICF### Section handled by ICF editor, don't touch! ****/ -/*-Editor annotation file-*/ -/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/* Code memory zones */ +define symbol MAPPABLE_START = 0x00000000; +define symbol MAPPABLE_SIZE = 0x00004000; /* 16 KiB */ +define symbol ZBT_SRAM1_START = (0x00000000 + 0x00004000); +define symbol ZBT_SRAM1_SIZE = (0x00400000 - 0x00004000); /* 4 MiB - 16 KiB */ + +/* Data memory zones */ +define symbol ZBT_SRAM2_START = 0x20000000; +define symbol ZBT_SRAM2_SIZE = 0x00400000; /* 4 MB */ + +/* NVIC vector numbers and size. */ +define symbol NVIC_NUM_VECTORS = (16 + 48); +define symbol NVIC_VECTORS_SIZE = (NVIC_NUM_VECTORS * 4); + /*-Specials-*/ -define symbol __ICFEDIT_intvec_start__ = 0x00000000; +define symbol __ICFEDIT_intvec_start__ = MAPPABLE_START; + /*-Memory Regions-*/ -define symbol __ICFEDIT_region_ROM_start__ = 0x00000000; -define symbol __ICFEDIT_region_ROM_end__ = 0x0003FFFF; -define symbol __ICFEDIT_region_RAM_start__ = 0x20000140; -define symbol __ICFEDIT_region_RAM_end__ = 0x2001FFFF; +define symbol __ICFEDIT_region_ROM_start__ = ZBT_SRAM1_START; +define symbol __ICFEDIT_region_ROM_end__ = ZBT_SRAM1_START + ZBT_SRAM1_SIZE - 1; +define symbol __ICFEDIT_region_RAM_start__ = ZBT_SRAM2_START + NVIC_VECTORS_SIZE; +define symbol __ICFEDIT_region_RAM_end__ = ZBT_SRAM2_START + ZBT_SRAM2_SIZE - 1; + /*-Sizes-*/ /* Heap and Stack size */ -define symbol __ICFEDIT_size_heap__ = 0x4000; -define symbol __ICFEDIT_size_cstack__ = 0x1000; +define symbol __ICFEDIT_size_heap__ = 0x200000; +define symbol __ICFEDIT_size_cstack__ = 0x400; /**** End of ICF editor section. ###ICF###*/ define memory mem with size = 4G; diff --git a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M4/device/cmsis_nvic.h b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M4/device/cmsis_nvic.h index a564abfc18cd..94619a9e556f 100644 --- a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M4/device/cmsis_nvic.h +++ b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M4/device/cmsis_nvic.h @@ -33,7 +33,14 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H +#include "memory_zones.h" + #define NVIC_NUM_VECTORS (16 + 48) -#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Location of vectors in RAM +#define NVIC_RAM_VECTOR_ADDRESS ZBT_SRAM2_START // Location of vectors in RAM + +/* + * Size of the whole vector table in bytes. Each vector is on 32 bits. + */ +#define NVIC_VECTORS_SIZE (NVIC_NUM_VECTORS * 4) #endif diff --git a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M4/device/memory_zones.h b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M4/device/memory_zones.h new file mode 100644 index 000000000000..8987bc22623e --- /dev/null +++ b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M4/device/memory_zones.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2017-2018 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. + */ + +/* + * This file contains the information of memory zones for code and data on + * ARM Versatile Express Cortex-M Prototyping Systems (V2M-MPS2) TRM. + * It is used in startup code and linker scripts of supported compilers (ARM and + * GCC_ARM). + * + * WARNING: IAR does not include this file and re-define these values in + * MPS2.icf file. Please make sure that the two files share the same values. + * + * These memory zones are defined in section 4.2 of ARM V2M-MPS2 RTL and + * Fast Model Reference Guide. + */ + +#ifndef MEMORY_ZONES_H +#define MEMORY_ZONES_H + +/* + * Code memory zones + * Please note that MPS2 on Fast Models do not implemented persistent flash memory. + * The FLASH memory can be simulated via 4MB ZBT_SRAM1 block + * only to keep the same name than in the CMSDK RTL and Fast Models Reference + * Guide. + */ +#define MAPPABLE_START 0x00000000 +#define MAPPABLE_SIZE 0x00004000 /* 16 KiB */ +#define ZBT_SRAM1_START (0x00000000 + 0x00004000) +#define ZBT_SRAM1_SIZE (0x00400000 - 0x00004000) /* 4 MiB - 16 KiB*/ + +/* Data memory zones */ +#define ZBT_SRAM2_START 0x20000000 +#define ZBT_SRAM2_SIZE 0x00400000 /* 4 MiB */ + +#endif /* MEMORY_ZONES_H */ + diff --git a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M7/device/TOOLCHAIN_ARM_STD/MPS2.sct b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M7/device/TOOLCHAIN_ARM_STD/MPS2.sct index 615c576d8c61..196ca9a09966 100644 --- a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M7/device/TOOLCHAIN_ARM_STD/MPS2.sct +++ b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M7/device/TOOLCHAIN_ARM_STD/MPS2.sct @@ -1,3 +1,4 @@ +#! armcc -E ;* MPS2 CMSIS Library ;* ;* Copyright (c) 2006-2018 ARM Limited @@ -33,15 +34,31 @@ ; *** Scatter-Loading Description File *** ; ************************************************************* -LR_IROM1 0x00000000 0x00400000 { ; load region size_region - ER_IROM1 0x00000000 0x00400000 { ; load address = execution address +#include "../memory_zones.h" +#include "../cmsis_nvic.h" + +#if (defined(__stack_size__)) + #define STACK_SIZE __stack_size__ +#else + #define STACK_SIZE 0x0400 +#endif + +; The vector table is loaded at address 0x00000000 in Flash memory region. +LR_IROM1 MAPPABLE_START MAPPABLE_SIZE { + ER_IROM1 MAPPABLE_START MAPPABLE_SIZE { *.o (RESET, +First) + } +} + +LR_IROM2 ZBT_SRAM1_START ZBT_SRAM1_SIZE { ; load region size_region + ER_IROM2 ZBT_SRAM1_START ZBT_SRAM1_SIZE { ; load address = execution address *(InRoot$$Sections) .ANY (+RO) } - ; Total: 64 vectors = 256 bytes (0x100) to be reserved in RAM - RW_IRAM1 (0x20000000+0x100) (0x400000-0x100) { ; RW data + ; NVIC_VECTORS_SIZE Total: 64 vectors = 256 bytes (0x100) to be reserved in RAM + RW_IRAM1 (ZBT_SRAM2_START + NVIC_VECTORS_SIZE) (ZBT_SRAM2_SIZE - NVIC_VECTORS_SIZE) { ; RW data .ANY (+RW +ZI) } + ARM_LIB_STACK (ZBT_SRAM2_START + ZBT_SRAM2_SIZE) EMPTY - STACK_SIZE { ; Stack region growing down + } } - diff --git a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M7/device/TOOLCHAIN_ARM_STD/startup_CMSDK_CM7.S b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M7/device/TOOLCHAIN_ARM_STD/startup_CMSDK_CM7.S index 03f916706587..c2f116075618 100644 --- a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M7/device/TOOLCHAIN_ARM_STD/startup_CMSDK_CM7.S +++ b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M7/device/TOOLCHAIN_ARM_STD/startup_CMSDK_CM7.S @@ -34,38 +34,14 @@ ; CMSDK_CM7 Device ; ;****************************************************************************** -; -;-------- <<< Use Configuration Wizard in Context Menu >>> ------------------ -; - - -; Stack Configuration -; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> -; - -Stack_Size EQU 0x00004000 - - AREA STACK, NOINIT, READWRITE, ALIGN=3 -Stack_Mem SPACE Stack_Size -__initial_sp +#include "../memory_zones.h" -; Heap Configuration -; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> -; - -Heap_Size EQU 0x00001000 - - AREA HEAP, NOINIT, READWRITE, ALIGN=3 -__heap_base -Heap_Mem SPACE Heap_Size -__heap_limit - +__initial_sp EQU ZBT_SRAM2_START + ZBT_SRAM2_SIZE PRESERVE8 THUMB - ; Vector Table Mapped to Address 0 at Reset AREA RESET, DATA, READONLY @@ -260,31 +236,4 @@ PORT0_7_Handler ALIGN - -; User Initial Stack & Heap - - IF :DEF:__MICROLIB - - EXPORT __initial_sp - EXPORT __heap_base - EXPORT __heap_limit - - ELSE - - IMPORT __use_two_region_memory - EXPORT __user_initial_stackheap - -__user_initial_stackheap PROC - LDR R0, = Heap_Mem - LDR R1, =(Stack_Mem + Stack_Size) - LDR R2, = (Heap_Mem + Heap_Size) - LDR R3, = Stack_Mem - BX LR - ENDP - - ALIGN - - ENDIF - - END diff --git a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M7/device/TOOLCHAIN_GCC_ARM/MPS2.ld b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M7/device/TOOLCHAIN_GCC_ARM/MPS2.ld index a1540322f0df..df16163d488c 100644 --- a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M7/device/TOOLCHAIN_GCC_ARM/MPS2.ld +++ b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M7/device/TOOLCHAIN_GCC_ARM/MPS2.ld @@ -27,11 +27,15 @@ /* The length of the VECTORS region is a bit larger than * is necessary based on the number of exception handlers. */ + +#include "../memory_zones.h" +#include "../cmsis_nvic.h" + MEMORY { - VECTORS (rx) : ORIGIN = 0x00000000, LENGTH = 0x00000400 - FLASH (rx) : ORIGIN = 0x00000400, LENGTH = 0x00040000 - 0x00000400 - RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00020000 + VECTORS (rx) : ORIGIN = MAPPABLE_START, LENGTH = MAPPABLE_SIZE + FLASH (rx) : ORIGIN = ZBT_SRAM1_START, LENGTH = ZBT_SRAM1_SIZE + RAM (rwx) : ORIGIN = ZBT_SRAM2_START, LENGTH = ZBT_SRAM2_SIZE } /* Linker script to place sections and symbol values. Should be used together @@ -62,11 +66,10 @@ MEMORY */ ENTRY(Reset_Handler) -HEAP_SIZE = 0x4000; -STACK_SIZE = 0x1000; +STACK_SIZE = 0x400; /* Size of the vector table in SRAM */ -M_VECTOR_RAM_SIZE = 0x140; +M_VECTOR_RAM_SIZE = NVIC_VECTORS_SIZE; SECTIONS { @@ -188,13 +191,13 @@ SECTIONS bss_size = __bss_end__ - __bss_start__; - .heap : + .heap (COPY): { . = ALIGN(8); __end__ = .; PROVIDE(end = .); __HeapBase = .; - . += HEAP_SIZE; + *(.heap*) __HeapLimit = .; __heap_limit = .; /* Add for _sbrk */ } > RAM diff --git a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M7/device/TOOLCHAIN_IAR/MPS2.icf b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M7/device/TOOLCHAIN_IAR/MPS2.icf index 60b104bcf3fb..936ce2e87259 100644 --- a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M7/device/TOOLCHAIN_IAR/MPS2.icf +++ b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M7/device/TOOLCHAIN_IAR/MPS2.icf @@ -19,25 +19,37 @@ * limitations under the License. */ -/* The RAM region doesn't start at the beginning of the RAM address - * space to create space for the vector table copied over to the RAM by mbed. - * The space left is a bit bigger than is necessary based on the number of - * interrupt handlers. +/* + * WARNING: these symbols are the same as the defines in ../memory_zones.h but + * can not be included here. Please make sure that the two definitions match. */ -/*###ICF### Section handled by ICF editor, don't touch! ****/ -/*-Editor annotation file-*/ -/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/* Code memory zones */ +define symbol MAPPABLE_START = 0x00000000; +define symbol MAPPABLE_SIZE = 0x00004000; /* 16 KiB */ +define symbol ZBT_SRAM1_START = (0x00000000 + 0x00004000); +define symbol ZBT_SRAM1_SIZE = (0x00400000 - 0x00004000); /* 4 MiB - 16 KiB */ + +/* Data memory zones */ +define symbol ZBT_SRAM2_START = 0x20000000; +define symbol ZBT_SRAM2_SIZE = 0x00400000; /* 4 MB */ + +/* NVIC vector numbers and size. */ +define symbol NVIC_NUM_VECTORS = (16 + 48); +define symbol NVIC_VECTORS_SIZE = (NVIC_NUM_VECTORS * 4); + /*-Specials-*/ -define symbol __ICFEDIT_intvec_start__ = 0x00000000; +define symbol __ICFEDIT_intvec_start__ = MAPPABLE_START; + /*-Memory Regions-*/ -define symbol __ICFEDIT_region_ROM_start__ = 0x00000000; -define symbol __ICFEDIT_region_ROM_end__ = 0x0003FFFF; -define symbol __ICFEDIT_region_RAM_start__ = 0x20000140; -define symbol __ICFEDIT_region_RAM_end__ = 0x2001FFFF; +define symbol __ICFEDIT_region_ROM_start__ = ZBT_SRAM1_START; +define symbol __ICFEDIT_region_ROM_end__ = ZBT_SRAM1_START + ZBT_SRAM1_SIZE - 1; +define symbol __ICFEDIT_region_RAM_start__ = ZBT_SRAM2_START + NVIC_VECTORS_SIZE; +define symbol __ICFEDIT_region_RAM_end__ = ZBT_SRAM2_START + ZBT_SRAM2_SIZE - 1; + /*-Sizes-*/ /* Heap and Stack size */ -define symbol __ICFEDIT_size_heap__ = 0x4000; -define symbol __ICFEDIT_size_cstack__ = 0x1000; +define symbol __ICFEDIT_size_heap__ = 0x200000; +define symbol __ICFEDIT_size_cstack__ = 0x400; /**** End of ICF editor section. ###ICF###*/ define memory mem with size = 4G; diff --git a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M7/device/cmsis_nvic.h b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M7/device/cmsis_nvic.h index a564abfc18cd..94619a9e556f 100644 --- a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M7/device/cmsis_nvic.h +++ b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M7/device/cmsis_nvic.h @@ -33,7 +33,14 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H +#include "memory_zones.h" + #define NVIC_NUM_VECTORS (16 + 48) -#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Location of vectors in RAM +#define NVIC_RAM_VECTOR_ADDRESS ZBT_SRAM2_START // Location of vectors in RAM + +/* + * Size of the whole vector table in bytes. Each vector is on 32 bits. + */ +#define NVIC_VECTORS_SIZE (NVIC_NUM_VECTORS * 4) #endif diff --git a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M7/device/memory_zones.h b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M7/device/memory_zones.h new file mode 100644 index 000000000000..8987bc22623e --- /dev/null +++ b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/TARGET_FVP_MPS2_M7/device/memory_zones.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2017-2018 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. + */ + +/* + * This file contains the information of memory zones for code and data on + * ARM Versatile Express Cortex-M Prototyping Systems (V2M-MPS2) TRM. + * It is used in startup code and linker scripts of supported compilers (ARM and + * GCC_ARM). + * + * WARNING: IAR does not include this file and re-define these values in + * MPS2.icf file. Please make sure that the two files share the same values. + * + * These memory zones are defined in section 4.2 of ARM V2M-MPS2 RTL and + * Fast Model Reference Guide. + */ + +#ifndef MEMORY_ZONES_H +#define MEMORY_ZONES_H + +/* + * Code memory zones + * Please note that MPS2 on Fast Models do not implemented persistent flash memory. + * The FLASH memory can be simulated via 4MB ZBT_SRAM1 block + * only to keep the same name than in the CMSDK RTL and Fast Models Reference + * Guide. + */ +#define MAPPABLE_START 0x00000000 +#define MAPPABLE_SIZE 0x00004000 /* 16 KiB */ +#define ZBT_SRAM1_START (0x00000000 + 0x00004000) +#define ZBT_SRAM1_SIZE (0x00400000 - 0x00004000) /* 4 MiB - 16 KiB*/ + +/* Data memory zones */ +#define ZBT_SRAM2_START 0x20000000 +#define ZBT_SRAM2_SIZE 0x00400000 /* 4 MiB */ + +#endif /* MEMORY_ZONES_H */ + diff --git a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/flash_api.c b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/flash_api.c index 44ba0fad2ae1..019388a145b7 100644 --- a/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/flash_api.c +++ b/targets/TARGET_ARM_FM/TARGET_FVP_MPS2/flash_api.c @@ -23,9 +23,9 @@ */ #define FLASH_PAGE_SIZE 256 -#define FLASH_OFS_START FLASH_START +#define FLASH_OFS_START ZBT_SRAM1_START #define FLASH_SECTOR_SIZE 0x1000 -#define FLASH_OFS_END (FLASH_OFS_START + FLASH_SIZE) +#define FLASH_OFS_END (ZBT_SRAM1_START + ZBT_SRAM1_SIZE) int32_t flash_init(flash_t *obj) { @@ -99,5 +99,5 @@ uint32_t flash_get_size(const flash_t *obj) { (void)obj; - return FLASH_SIZE; + return ZBT_SRAM1_SIZE; } diff --git a/targets/TARGET_ARM_FM/mbed_rtx.h b/targets/TARGET_ARM_FM/mbed_rtx.h index 16445479f636..85b1a4eee871 100644 --- a/targets/TARGET_ARM_FM/mbed_rtx.h +++ b/targets/TARGET_ARM_FM/mbed_rtx.h @@ -16,13 +16,15 @@ #ifndef MBED_MBED_RTX_H #define MBED_MBED_RTX_H +#include "memory_zones.h" #if defined(TARGET_FVP_MPS2) #ifndef INITIAL_SP -#define INITIAL_SP (0x20020000UL) +#define INITIAL_SP (ZBT_SRAM2_START + ZBT_SRAM2_SIZE) #endif + #endif /* defined(TARGET_...) */ #endif /* MBED_MBED_RTX_H */ diff --git a/targets/TARGET_ARM_SSG/TARGET_BEETLE/lp_ticker.c b/targets/TARGET_ARM_SSG/TARGET_BEETLE/lp_ticker.c index e96379af47ef..ffad5f347936 100644 --- a/targets/TARGET_ARM_SSG/TARGET_BEETLE/lp_ticker.c +++ b/targets/TARGET_ARM_SSG/TARGET_BEETLE/lp_ticker.c @@ -152,4 +152,9 @@ void lp_ticker_clear_interrupt(void) DualTimer_ClearInterrupt(DUALTIMER0); } +void lp_ticker_free(void) +{ + +} + #endif diff --git a/targets/TARGET_ARM_SSG/TARGET_BEETLE/us_ticker.c b/targets/TARGET_ARM_SSG/TARGET_BEETLE/us_ticker.c index b09ecb8ab10c..79b305242bd8 100644 --- a/targets/TARGET_ARM_SSG/TARGET_BEETLE/us_ticker.c +++ b/targets/TARGET_ARM_SSG/TARGET_BEETLE/us_ticker.c @@ -111,3 +111,8 @@ void us_ticker_disable_interrupt(void) { void us_ticker_clear_interrupt(void) { Timer_ClearInterrupt(TIMER0); } + +void us_ticker_free(void) +{ + +} diff --git a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/gpio_api.c b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/gpio_api.c index bc50273772b2..46a95c4abfdf 100644 --- a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/gpio_api.c +++ b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/gpio_api.c @@ -175,7 +175,7 @@ void gpio_init(gpio_t *obj, PinName pin) /* MCC LEDs */ obj->gpio_dev = NULL; obj->mps2_io_dev = &ARM_MPS2_IO_SCC_DEV; - obj->arm_mps2_io_write = NULL; + obj->arm_mps2_io_write = arm_mps2_io_write_leds; obj->pin_number = pin - LED1; obj->direction = PIN_OUTPUT; return; diff --git a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/lp_ticker.c b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/lp_ticker.c index 6458408610f4..6b272a00b814 100644 --- a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/lp_ticker.c +++ b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/lp_ticker.c @@ -108,6 +108,11 @@ void lp_ticker_fire_interrupt(void) cmsdk_ticker_fire_interrupt(&timer_data); } +void lp_ticker_free(void) +{ + +} + void TIMER1_IRQHandler(void) { cmsdk_ticker_irq_handler(&timer_data); diff --git a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/us_ticker.c b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/us_ticker.c index e45dd8cfec35..db472ff56de8 100644 --- a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/us_ticker.c +++ b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/us_ticker.c @@ -112,6 +112,11 @@ void us_ticker_fire_interrupt(void) cmsdk_ticker_fire_interrupt(&timer_data); } +void us_ticker_free(void) +{ + +} + void TIMER0_IRQHandler(void) { cmsdk_ticker_irq_handler(&timer_data); diff --git a/targets/TARGET_ARM_SSG/TARGET_IOTSS/us_ticker.c b/targets/TARGET_ARM_SSG/TARGET_IOTSS/us_ticker.c index 3c933462c6d2..6fb00fd1a236 100644 --- a/targets/TARGET_ARM_SSG/TARGET_IOTSS/us_ticker.c +++ b/targets/TARGET_ARM_SSG/TARGET_IOTSS/us_ticker.c @@ -87,3 +87,8 @@ void us_ticker_clear_interrupt(void) { US_TICKER_TIMER2->TimerIntClr = 0x1; } + +void us_ticker_free(void) +{ + +} diff --git a/targets/TARGET_ARM_SSG/TARGET_MPS2/serial_api.c b/targets/TARGET_ARM_SSG/TARGET_MPS2/serial_api.c index fc2625c9c1ad..8eba4b3db1bd 100644 --- a/targets/TARGET_ARM_SSG/TARGET_MPS2/serial_api.c +++ b/targets/TARGET_ARM_SSG/TARGET_MPS2/serial_api.c @@ -326,6 +326,9 @@ static void serial_irq_set_internal(serial_t *obj, SerialIrq irq, uint32_t enabl } void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) { + if (RxIrq == irq) { + uart_data[obj->index].rx_irq_set_api = enable; + } serial_irq_set_internal(obj, irq, enable); } diff --git a/targets/TARGET_ARM_SSG/TARGET_MPS2/us_ticker.c b/targets/TARGET_ARM_SSG/TARGET_MPS2/us_ticker.c index 5adf19e39c30..66f0391f5b76 100644 --- a/targets/TARGET_ARM_SSG/TARGET_MPS2/us_ticker.c +++ b/targets/TARGET_ARM_SSG/TARGET_MPS2/us_ticker.c @@ -81,3 +81,8 @@ void us_ticker_clear_interrupt(void) { US_TICKER_TIMER2->TimerIntClr = 0x1; } + +void us_ticker_free(void) +{ + +} diff --git a/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/api/us_ticker.c b/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/api/us_ticker.c index 631536700da2..e980bd68bd99 100755 --- a/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/api/us_ticker.c +++ b/targets/TARGET_Analog_Devices/TARGET_ADUCM302X/TARGET_ADUCM3029/api/us_ticker.c @@ -355,6 +355,10 @@ void us_ticker_fire_interrupt(void) event_timer(); // enable the timer and interrupt } +void us_ticker_free(void) +{ + adi_tmr_Enable(ADI_TMR_DEVICE_GP2, false); +} /* ** EOF diff --git a/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/api/us_ticker.c b/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/api/us_ticker.c index 37853a78deed..86c8a07ddc4d 100755 --- a/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/api/us_ticker.c +++ b/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/api/us_ticker.c @@ -202,12 +202,12 @@ static void event_timer() tmrConfig.nLoad = cnt; tmrConfig.nAsyncLoad = cnt; - adi_tmr_ConfigTimer(ADI_TMR_DEVICE_GP2, tmrConfig); + adi_tmr_ConfigTimer(ADI_TMR_DEVICE_GP2, &tmrConfig); adi_tmr_Enable(ADI_TMR_DEVICE_GP2, true); } else { tmrConfig.nLoad = 65535u; tmrConfig.nAsyncLoad = 65535u; - adi_tmr_ConfigTimer(ADI_TMR_DEVICE_GP2, tmrConfig); + adi_tmr_ConfigTimer(ADI_TMR_DEVICE_GP2, &tmrConfig); adi_tmr_Enable(ADI_TMR_DEVICE_GP2, true); } } @@ -274,13 +274,13 @@ void us_ticker_init(void) tmrConfig.nAsyncLoad = 0; tmrConfig.bReloading = false; tmrConfig.bSyncBypass = true; // Allow x1 prescale: requires PCLK as a clk - adi_tmr_ConfigTimer(ADI_TMR_DEVICE_GP0, tmrConfig); + adi_tmr_ConfigTimer(ADI_TMR_DEVICE_GP0, &tmrConfig); /* Configure GP1 to have a period 256 times longer than GP0 */ tmrConfig.nLoad = 0; tmrConfig.nAsyncLoad = 0; tmrConfig.ePrescaler = ADI_TMR_PRESCALER_256; // TMR1 = 26MHz/256 - adi_tmr_ConfigTimer(ADI_TMR_DEVICE_GP1, tmrConfig); + adi_tmr_ConfigTimer(ADI_TMR_DEVICE_GP1, &tmrConfig); /* Configure GP2 for doing event counts */ tmrConfig.bCountingUp = true; @@ -291,7 +291,7 @@ void us_ticker_init(void) tmrConfig.nAsyncLoad = 0; tmrConfig.bReloading = false; tmrConfig.bSyncBypass = true; // Allow x1 prescale - adi_tmr_ConfigTimer(ADI_TMR_DEVICE_GP2, tmrConfig); + adi_tmr_ConfigTimer(ADI_TMR_DEVICE_GP2, &tmrConfig); /*------------------------- GP TIMER ENABLE ------------------------------*/ @@ -353,6 +353,10 @@ void us_ticker_fire_interrupt(void) event_timer(); // enable the timer and interrupt } +void us_ticker_free(void) +{ + adi_tmr_Enable(ADI_TMR_DEVICE_GP2, false); +} /* ** EOF diff --git a/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/bsp/config/adi_tmr_config.h b/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/bsp/config/adi_tmr_config.h index 8d6ee10347f6..f6407dbc381d 100755 --- a/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/bsp/config/adi_tmr_config.h +++ b/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/bsp/config/adi_tmr_config.h @@ -2,7 +2,7 @@ * @file adi_tmr_config.h * @brief GP and RGB timer device driver configuration ----------------------------------------------------------------------------- -Copyright (c) 2016 Analog Devices, Inc. +Copyright (c) 2016-2018 Analog Devices, Inc. All rights reserved. @@ -169,7 +169,13 @@ POSSIBILITY OF SUCH DAMAGE. a value of 0 - 39. Please refer hardware reference manual to know which events can be captured by a particular GP timer. */ +#if defined(__ADUCM3029__) +#define TMR0_CFG_EVENT_CAPTURE (9u) +#elif defined(__ADUCM4050__) #define TMR0_CFG_EVENT_CAPTURE (27u) +#else +#error TMR is not ported for this processor +#endif /************************************************************* GP Timer 0 PWM0 Configuration @@ -295,8 +301,13 @@ POSSIBILITY OF SUCH DAMAGE. a value of 0 - 39. Please refer hardware reference manual to know which events can be captured by a particular GP timer. */ +#if defined(__ADUCM3029__) +#define TMR1_CFG_EVENT_CAPTURE (15u) +#elif defined(__ADUCM4050__) #define TMR1_CFG_EVENT_CAPTURE (28u) - +#else +#error TMR is not ported for this processor +#endif /************************************************************* GP Timer 1 PWM0 Configuration *************************************************************/ @@ -419,8 +430,13 @@ POSSIBILITY OF SUCH DAMAGE. a value of 0 - 39. Please refer hardware reference manual to know which events can be captured by a particular GP timer. */ +#if defined(__ADUCM3029__) +#define TMR2_CFG_EVENT_CAPTURE (6u) +#elif defined(__ADUCM4050__) #define TMR2_CFG_EVENT_CAPTURE (27u) - +#else +#error TMR is not ported for this processor +#endif /************************************************************* GP Timer 2 PWM0 Configuration *************************************************************/ @@ -451,7 +467,7 @@ POSSIBILITY OF SUCH DAMAGE. /*! @} */ - +#if defined(__ADUCM4050__) /************************************************************* RGB Timer Configuration *************************************************************/ @@ -629,7 +645,7 @@ POSSIBILITY OF SUCH DAMAGE. the PWM output remains idle. It can be any value from 0 to 65535. */ #define TMR3_CFG_PWM2_MATCH_VALUE (0u) - +#endif /*! @} */ /************************************************************* @@ -676,9 +692,17 @@ POSSIBILITY OF SUCH DAMAGE. #error "Invalid configuration" #endif +#if defined(__ADUCM3029__) +#if TMR0_CFG_EVENT_CAPTURE > 15u +#error "Invalid configuration" +#endif +#elif defined(__ADUCM4050__) #if TMR0_CFG_EVENT_CAPTURE > 39u #error "Invalid configuration" #endif +#else +#error TMR is not ported for this processor +#endif #if TMR0_CFG_ENABLE_PWM0_MATCH_MODE > 1u #error "Invalid configuration" @@ -736,9 +760,17 @@ POSSIBILITY OF SUCH DAMAGE. #error "Invalid configuration" #endif +#if defined(__ADUCM3029__) +#if TMR1_CFG_EVENT_CAPTURE > 15u +#error "Invalid configuration" +#endif +#elif defined(__ADUCM4050__) #if TMR1_CFG_EVENT_CAPTURE > 39u #error "Invalid configuration" #endif +#else +#error TMR is not ported for this processor +#endif #if TMR1_CFG_ENABLE_PWM0_MATCH_MODE > 1u #error "Invalid configuration" @@ -796,9 +828,17 @@ POSSIBILITY OF SUCH DAMAGE. #error "Invalid configuration" #endif +#if defined(__ADUCM3029__) +#if TMR2_CFG_EVENT_CAPTURE > 15u +#error "Invalid configuration" +#endif +#elif defined(__ADUCM4050__) #if TMR2_CFG_EVENT_CAPTURE > 39u #error "Invalid configuration" #endif +#else +#error TMR is not ported for this processor +#endif #if TMR2_CFG_ENABLE_PWM0_MATCH_MODE > 1u #error "Invalid configuration" @@ -812,6 +852,7 @@ POSSIBILITY OF SUCH DAMAGE. #error "Invalid configuration" #endif +#if defined(__ADUCM4050__) /************************************************************* RGB Timer Macro Validation **************************************************************/ @@ -896,6 +937,7 @@ POSSIBILITY OF SUCH DAMAGE. #error "Invalid configuration" #endif +#endif /*! @} */ diff --git a/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/bsp/drivers/tmr/adi_tmr.h b/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/bsp/drivers/tmr/adi_tmr.h index 9331593a1264..679ced224572 100755 --- a/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/bsp/drivers/tmr/adi_tmr.h +++ b/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/bsp/drivers/tmr/adi_tmr.h @@ -2,7 +2,7 @@ * @file adi_tmr.h * @brief GP and RGB timer device driver public header file ----------------------------------------------------------------------------- -Copyright (c) 2016 Analog Devices, Inc. +Copyright (c) 2016-2018 Analog Devices, Inc. All rights reserved. @@ -56,12 +56,16 @@ POSSIBILITY OF SUCH DAMAGE. * @{ */ +/* C++ linkage */ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ /*! ***************************************************************************** * \enum ADI_TMR_RESULT * Enumeration for result code returned from the timer device driver functions. - * The return value of all timer APIs returning #ADI_TMR_RESULT should always + * The return value of all timer APIs returning #ADI_TMR_RESULT should always * be tested at the application level for success or failure. *****************************************************************************/ typedef enum { @@ -97,10 +101,17 @@ typedef enum { ADI_TMR_DEVICE_GP1 = 1u, /*! General purpose timer 2 */ ADI_TMR_DEVICE_GP2 = 2u, +#if defined(__ADUCM3029__) + /*! Total number of devices (private) */ + ADI_TMR_DEVICE_NUM = 3u, +#elif defined(__ADUCM4050__) /*! RGB timer */ ADI_TMR_DEVICE_RGB = 3u, /*! Total number of devices (private) */ ADI_TMR_DEVICE_NUM = 4u, +#else +#error TMR is not ported for this processor +#endif } ADI_TMR_DEVICE; /*! @@ -110,7 +121,7 @@ typedef enum { *****************************************************************************/ typedef enum { /*! Timeout event occurred */ - ADI_TMR_EVENT_TIMEOUT = 0x01, + ADI_TMR_EVENT_TIMEOUT = 0x01, /*! Event capture event occurred */ ADI_TMR_EVENT_CAPTURE = 0x02, } ADI_TMR_EVENT; @@ -124,7 +135,7 @@ typedef enum { /*! Count every 1 source clock periods */ ADI_TMR_PRESCALER_1 = 0u, /*! Count every 16 source clock periods */ - ADI_TMR_PRESCALER_16 = 1u, + ADI_TMR_PRESCALER_16 = 1u, /*! Count every 64 source clock periods */ ADI_TMR_PRESCALER_64 = 2u, /*! Count every 256 source clock periods */ @@ -138,11 +149,11 @@ typedef enum { *****************************************************************************/ typedef enum { /*! Use periphreal clock (PCLK) */ - ADI_TMR_CLOCK_PCLK = 0u, + ADI_TMR_CLOCK_PCLK = 0u, /*! Use internal high frequency clock (HFOSC) */ - ADI_TMR_CLOCK_HFOSC = 1u, + ADI_TMR_CLOCK_HFOSC = 1u, /*! Use internal low frequency clock (LFOSC) */ - ADI_TMR_CLOCK_LFOSC = 2u, + ADI_TMR_CLOCK_LFOSC = 2u, /*! Use external low frequency clock (LFXTAL) */ ADI_TMR_CLOCK_LFXTAL = 3u, } ADI_TMR_CLOCK_SOURCE; @@ -151,7 +162,7 @@ typedef enum { ***************************************************************************** * \enum ADI_TMR_PWM_OUTPUT * RGB PWM outputs, used to specify which PWM output to configure. For the GP - * timers only #ADI_TMR_PWM_OUTPUT_0 is allowed. The RGB timer has all three + * timers only #ADI_TMR_PWM_OUTPUT_0 is allowed. The RGB timer has all three * outputs. *****************************************************************************/ typedef enum { @@ -168,7 +179,7 @@ typedef enum { /*! ***************************************************************************** * \struct ADI_TMR_CONFIG - * Configuration structure to fill and pass to #adi_tmr_ConfigTimer when + * Configuration structure to fill and pass to #adi_tmr_ConfigTimer when * configuring the GP or RGB timer *****************************************************************************/ typedef struct { @@ -180,7 +191,7 @@ typedef struct { ADI_TMR_PRESCALER ePrescaler; /*! Clock source */ ADI_TMR_CLOCK_SOURCE eClockSource; - /*! Load value (only relent in periodic mode) */ + /*! Load value (only relevant in periodic mode) */ uint16_t nLoad; /*! Asynchronous load value (only relevant in periodic mode, and when PCLK is used) */ uint16_t nAsyncLoad; @@ -193,7 +204,7 @@ typedef struct { /*! ***************************************************************************** * \struct ADI_TMR_EVENT_CONFIG - * Configuration structure to fill and pass to #adi_tmr_ConfigEvent when + * Configuration structure to fill and pass to #adi_tmr_ConfigEvent when * configuring event capture *****************************************************************************/ typedef struct { @@ -208,7 +219,7 @@ typedef struct { /*! ***************************************************************************** * \struct ADI_TMR_PWM_CONFIG - * Configuration structure to fill and pass to #adi_tmr_ConfigPwm when + * Configuration structure to fill and pass to #adi_tmr_ConfigPwm when * configuring pulse width modulation output *****************************************************************************/ typedef struct { @@ -232,9 +243,9 @@ typedef struct { ADI_TMR_RESULT adi_tmr_Init (ADI_TMR_DEVICE const eDevice, ADI_CALLBACK const pfCallback, void * const pCBParam, bool bEnableInt); /* Configuration interface functions */ -ADI_TMR_RESULT adi_tmr_ConfigTimer (ADI_TMR_DEVICE const eDevice, ADI_TMR_CONFIG timerConfig); -ADI_TMR_RESULT adi_tmr_ConfigEvent (ADI_TMR_DEVICE const eDevice, ADI_TMR_EVENT_CONFIG eventConfig); -ADI_TMR_RESULT adi_tmr_ConfigPwm (ADI_TMR_DEVICE const eDevice, ADI_TMR_PWM_CONFIG pwmConfig ); +ADI_TMR_RESULT adi_tmr_ConfigTimer (ADI_TMR_DEVICE const eDevice, ADI_TMR_CONFIG* timerConfig); +ADI_TMR_RESULT adi_tmr_ConfigEvent (ADI_TMR_DEVICE const eDevice, ADI_TMR_EVENT_CONFIG* eventConfig); +ADI_TMR_RESULT adi_tmr_ConfigPwm (ADI_TMR_DEVICE const eDevice, ADI_TMR_PWM_CONFIG* pwmConfig ); /* Timer start and stop */ ADI_TMR_RESULT adi_tmr_Enable (ADI_TMR_DEVICE const eDevice, bool bEnable); @@ -246,7 +257,9 @@ ADI_TMR_RESULT adi_tmr_GetCaptureCount (ADI_TMR_DEVICE const eDevice, uint16_t * /* Reload function */ ADI_TMR_RESULT adi_tmr_Reload (ADI_TMR_DEVICE const eDevice); - +#ifdef __cplusplus +} +#endif /*! @} */ diff --git a/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/bsp/tmr/adi_tmr.c b/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/bsp/tmr/adi_tmr.c index b7153b79a8d0..57352b1f6756 100755 --- a/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/bsp/tmr/adi_tmr.c +++ b/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/bsp/tmr/adi_tmr.c @@ -2,7 +2,7 @@ * @file adi_tmr.c * @brief GP and RGB timer device driver implementation ----------------------------------------------------------------------------- -Copyright (c) 2016 Analog Devices, Inc. +Copyright (c) 2016-2018 Analog Devices, Inc. All rights reserved. @@ -86,7 +86,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "adi_tmr_data.c" #endif - +#if defined(__ADUCM4050__) /* In adi_tmr_ConfigPwm, the bit positions for just PWM0 are used for PWM1 and PWM2 to simplify the code. Check here to make sure this is safe. */ #if BITP_TMR_RGB_PWM0CTL_IDLESTATE != BITP_TMR_RGB_PWM1CTL_IDLESTATE #error "Bit positions for PWM0 and PWM1 do not match. Fix adi_tmr_ConfigPwm." @@ -100,17 +100,36 @@ POSSIBILITY OF SUCH DAMAGE. #if BITP_TMR_RGB_PWM0CTL_MATCH != BITP_TMR_RGB_PWM2CTL_MATCH #error "Bit positions for PWM0 and PWM2 do not match. Fix adi_tmr_ConfigPwm." #endif +#endif /*__ADUCM4050__*/ /*! Number of events that can be captured */ +#if defined(__ADUCM3029__) +#define ADI_TMR_NUM_EVENTS (16u) +#elif defined(__ADUCM4050__) #define ADI_TMR_NUM_EVENTS (40u) +#else +#error TMR is not ported for this processor +#endif /*! \cond PRIVATE */ /* Since the RGB typedef is a superset of the GP typedef, treat the GP timers as RGB timers and restrict top register access */ +#if defined(__ADUCM3029__) +static ADI_TMR_TypeDef * adi_tmr_registers[ADI_TMR_DEVICE_NUM] = {pADI_TMR0, pADI_TMR1, pADI_TMR2}; +#elif defined(__ADUCM4050__) static ADI_TMR_RGB_TypeDef * adi_tmr_registers[ADI_TMR_DEVICE_NUM] = {(ADI_TMR_RGB_TypeDef *) pADI_TMR0, (ADI_TMR_RGB_TypeDef *) pADI_TMR1, (ADI_TMR_RGB_TypeDef *) pADI_TMR2, pADI_TMR_RGB}; +#else +#error TMR is not ported for this processor +#endif /* Interrupt enums */ +#if defined(__ADUCM3029__) +static const IRQn_Type adi_tmr_interrupt[ADI_TMR_DEVICE_NUM] = {TMR0_EVT_IRQn, TMR1_EVT_IRQn, TMR2_EVT_IRQn}; +#elif defined(__ADUCM4050__) static const IRQn_Type adi_tmr_interrupt[ADI_TMR_DEVICE_NUM] = {TMR0_EVT_IRQn, TMR1_EVT_IRQn, TMR2_EVT_IRQn, TMR_RGB_EVT_IRQn}; +#else +#error TMR is not ported for this processor +#endif /* Private data that the driver needs to retain between function calls */ static ADI_CALLBACK adi_tmr_callbacks[ADI_TMR_DEVICE_NUM]; @@ -121,8 +140,9 @@ static void CommonIntHandler (ADI_TMR_DEVICE const eDevice); void GP_Tmr0_Int_Handler(void); void GP_Tmr1_Int_Handler(void); void GP_Tmr2_Int_Handler(void); +#if defined(__ADUCM4050__) void RGB_Tmr_Int_Handler(void); - +#endif /*! \endcond */ @@ -181,10 +201,10 @@ ADI_TMR_RESULT adi_tmr_Init(ADI_TMR_DEVICE const eDevice, ADI_CALLBACK const pfC adi_tmr_registers[eDevice]->CTL = aTimerCtlConfig [eDevice]; adi_tmr_registers[eDevice]->LOAD = aTimerLoadConfig [eDevice]; adi_tmr_registers[eDevice]->ALOAD = aTimerALoadConfig [eDevice]; - adi_tmr_registers[eDevice]->EVENTSELECT = aTimerEventConfig [eDevice]; adi_tmr_registers[eDevice]->PWM0CTL = aTimerPwmCtlConfig [eDevice]; adi_tmr_registers[eDevice]->PWM0MATCH = aTimerPwmMatchConfig[eDevice]; - +#if defined(__ADUCM4050__) + adi_tmr_registers[eDevice]->EVENTSELECT = aTimerEventConfig [eDevice]; /* IF(Initializing the RGB timer, there are 2 other PWM outputs to configure) */ if (eDevice == ADI_TMR_DEVICE_RGB) { /* The array is bumped by 1 to get to the 5th entry in the static config array, which contains RGB PWM1 */ @@ -194,6 +214,7 @@ ADI_TMR_RESULT adi_tmr_Init(ADI_TMR_DEVICE const eDevice, ADI_CALLBACK const pfC adi_tmr_registers[eDevice]->PWM2CTL = aTimerPwmCtlConfig [eDevice+2u]; adi_tmr_registers[eDevice]->PWM2MATCH = aTimerPwmMatchConfig[eDevice+2u]; } /* ENDIF */ +#endif #endif return ADI_TMR_SUCCESS; @@ -219,7 +240,7 @@ ADI_TMR_RESULT adi_tmr_Init(ADI_TMR_DEVICE const eDevice, ADI_CALLBACK const pfC * - #ADI_TMR_SUCCESS Function call completed successfully * */ -ADI_TMR_RESULT adi_tmr_ConfigTimer(ADI_TMR_DEVICE const eDevice, ADI_TMR_CONFIG timerConfig) { +ADI_TMR_RESULT adi_tmr_ConfigTimer(ADI_TMR_DEVICE const eDevice, ADI_TMR_CONFIG * timerConfig) { uint16_t nTemp; #ifdef ADI_DEBUG /* IF(Bad device input parameter) */ @@ -227,7 +248,7 @@ ADI_TMR_RESULT adi_tmr_ConfigTimer(ADI_TMR_DEVICE const eDevice, ADI_TMR_CONFIG return ADI_TMR_BAD_DEVICE_NUM; } /* ENDIF */ /* IF(Bad configuration, cannot enable reloading while in free running mode) */ - if ((timerConfig.bPeriodic == false) && (timerConfig.bReloading == true)) { + if ((timerConfig->bPeriodic == false) && (timerConfig->bReloading == true)) { return ADI_TMR_BAD_RELOAD_CONFIGURATION; } /* ENDIF */ /* IF(The timer is already running) */ @@ -236,8 +257,8 @@ ADI_TMR_RESULT adi_tmr_ConfigTimer(ADI_TMR_DEVICE const eDevice, ADI_TMR_CONFIG } /* ENDIF */ #endif /* Set the load registers */ - adi_tmr_registers[eDevice]->LOAD = timerConfig.nLoad; - adi_tmr_registers[eDevice]->ALOAD = timerConfig.nAsyncLoad; + adi_tmr_registers[eDevice]->LOAD = timerConfig->nLoad; + adi_tmr_registers[eDevice]->ALOAD = timerConfig->nAsyncLoad; /* IF(Busy bit does not clear after waiting) */ if (ADI_TMR_SUCCESS != WaitForStatusBit(eDevice, (uint16_t) BITM_TMR_RGB_STAT_BUSY)) { @@ -249,26 +270,26 @@ ADI_TMR_RESULT adi_tmr_ConfigTimer(ADI_TMR_DEVICE const eDevice, ADI_TMR_CONFIG nTemp &= (uint16_t) (BITM_TMR_RGB_CTL_EVTEN | BITM_TMR_RGB_CTL_RSTEN); /* Setup the prescaler and the clock source */ - nTemp |= (uint16_t)(((uint16_t) timerConfig.ePrescaler ) << BITP_TMR_RGB_CTL_PRE); - nTemp |= (uint16_t)(((uint16_t) timerConfig.eClockSource) << BITP_TMR_RGB_CTL_CLK); + nTemp |= (uint16_t)(((uint16_t) timerConfig->ePrescaler ) << BITP_TMR_RGB_CTL_PRE); + nTemp |= (uint16_t)(((uint16_t) timerConfig->eClockSource) << BITP_TMR_RGB_CTL_CLK); /* IF(Periodic mode) */ - if (timerConfig.bPeriodic == true) { + if (timerConfig->bPeriodic == true) { nTemp |= (1u << BITP_TMR_RGB_CTL_MODE); } /* ENDIF */ /* IF(Counting up) */ - if (timerConfig.bCountingUp == true) { + if (timerConfig->bCountingUp == true) { nTemp |= (1u << BITP_TMR_RGB_CTL_UP); } /* ENDIF */ /* IF(Reloading is enabled) */ - if (timerConfig.bReloading == true) { + if (timerConfig->bReloading == true) { nTemp |= (1u << BITP_TMR_RGB_CTL_RLD); } /* ENDIF */ /* IF(Sync bypass is enabled) */ - if (timerConfig.bSyncBypass == true) { + if (timerConfig->bSyncBypass == true) { nTemp |= (1u << BITP_TMR_RGB_CTL_SYNCBYP); } /* ENDIF */ @@ -301,14 +322,14 @@ ADI_TMR_RESULT adi_tmr_ConfigTimer(ADI_TMR_DEVICE const eDevice, ADI_TMR_CONFIG * - #ADI_TMR_SUCCESS Function call completed successfully * */ -ADI_TMR_RESULT adi_tmr_ConfigEvent(ADI_TMR_DEVICE const eDevice, ADI_TMR_EVENT_CONFIG eventConfig) { +ADI_TMR_RESULT adi_tmr_ConfigEvent(ADI_TMR_DEVICE const eDevice, ADI_TMR_EVENT_CONFIG * eventConfig) { #ifdef ADI_DEBUG /* IF(Bad device input parameter) */ if (eDevice >= ADI_TMR_DEVICE_NUM) { return ADI_TMR_BAD_DEVICE_NUM; } /* ENDIF */ /* IF(Bad event input parameter) */ - if (eventConfig.nEventID >= ADI_TMR_NUM_EVENTS) { + if (eventConfig->nEventID >= ADI_TMR_NUM_EVENTS) { return ADI_TMR_BAD_EVENT_ID; } /* ENDIF */ /* IF(The timer is already running) */ @@ -316,9 +337,10 @@ ADI_TMR_RESULT adi_tmr_ConfigEvent(ADI_TMR_DEVICE const eDevice, ADI_TMR_EVENT_C return ADI_TMR_OPERATION_NOT_ALLOWED; } /* ENDIF */ #endif +#if defined(__ADUCM4050__) /* Set the event number */ - adi_tmr_registers[eDevice]->EVENTSELECT = (uint16_t) eventConfig.nEventID; - + adi_tmr_registers[eDevice]->EVENTSELECT = (uint16_t) eventConfig->nEventID; +#endif /* IF(Busy bit does not clear after waiting) */ if (ADI_TMR_SUCCESS != WaitForStatusBit(eDevice, (uint16_t) BITM_TMR_RGB_STAT_BUSY)) { return ADI_TMR_DEVICE_BUSY; @@ -328,15 +350,20 @@ ADI_TMR_RESULT adi_tmr_ConfigEvent(ADI_TMR_DEVICE const eDevice, ADI_TMR_EVENT_C adi_tmr_registers[eDevice]->CTL &= (uint16_t) ~(BITM_TMR_RGB_CTL_EVTEN | BITM_TMR_RGB_CTL_RSTEN); /* IF(Turning event capture on) */ - if (eventConfig.bEnable == true) { + if (eventConfig->bEnable == true) { adi_tmr_registers[eDevice]->CTL |= (uint16_t) BITM_TMR_RGB_CTL_EVTEN; } /* ENDIF */ /* IF(Enabling reset on event capture) */ - if (eventConfig.bPrescaleReset == true) { + if (eventConfig->bPrescaleReset == true) { adi_tmr_registers[eDevice]->CTL |= (uint16_t) BITM_TMR_RGB_CTL_RSTEN; } /* ENDIF */ +#if defined(__ADUCM3029__) + /* Write the event index */ + adi_tmr_registers[eDevice]->CTL |= (uint16_t) (((uint16_t) eventConfig->nEventID) << BITP_TMR_CTL_EVTRANGE); +#endif + return ADI_TMR_SUCCESS; } @@ -364,7 +391,7 @@ ADI_TMR_RESULT adi_tmr_ConfigEvent(ADI_TMR_DEVICE const eDevice, ADI_TMR_EVENT_C * - #ADI_TMR_SUCCESS Function call completed successfully * */ -ADI_TMR_RESULT adi_tmr_ConfigPwm(ADI_TMR_DEVICE const eDevice, ADI_TMR_PWM_CONFIG pwmConfig) { +ADI_TMR_RESULT adi_tmr_ConfigPwm(ADI_TMR_DEVICE const eDevice, ADI_TMR_PWM_CONFIG * pwmConfig) { uint16_t nControl = 0u; #ifdef ADI_DEBUG /* IF(Bad device input parameter) */ @@ -375,35 +402,38 @@ ADI_TMR_RESULT adi_tmr_ConfigPwm(ADI_TMR_DEVICE const eDevice, ADI_TMR_PWM_CONFI if ((adi_tmr_registers[eDevice]->CTL & BITM_TMR_RGB_CTL_EN) == BITM_TMR_RGB_CTL_EN) { return ADI_TMR_OPERATION_NOT_ALLOWED; } /* ENDIF */ +#if defined(__ADUCM4050__) /* IF(Bad PWM output and device combo OR bad PWM output) */ - if (((eDevice != ADI_TMR_DEVICE_RGB) && (pwmConfig.eOutput != ADI_TMR_PWM_OUTPUT_0)) || (pwmConfig.eOutput >= ADI_TMR_PWM_OUTPUT_NUM)) { + if (((eDevice != ADI_TMR_DEVICE_RGB) && (pwmConfig->eOutput != ADI_TMR_PWM_OUTPUT_0)) || (pwmConfig->eOutput >= ADI_TMR_PWM_OUTPUT_NUM)) { return ADI_TMR_BAD_PWM_NUM; } /* ENDIF */ +#endif #endif /* IF(Idle high is set) */ - if (pwmConfig.bIdleHigh == true) { + if (pwmConfig->bIdleHigh == true) { nControl = (1u << ((uint16_t) BITP_TMR_RGB_PWM0CTL_IDLESTATE)); } /* ENDIF */ /* IF(Match mode is enabled) */ - if (pwmConfig.bMatch == true) { + if (pwmConfig->bMatch == true) { nControl |= (1u << ((uint16_t) BITP_TMR_RGB_PWM0CTL_MATCH)); } /* ENDIF */ - + /* IF(PWM output 0) */ - if (pwmConfig.eOutput == ADI_TMR_PWM_OUTPUT_0) { + if (pwmConfig->eOutput == ADI_TMR_PWM_OUTPUT_0) { adi_tmr_registers[eDevice]->PWM0CTL = nControl; - adi_tmr_registers[eDevice]->PWM0MATCH = pwmConfig.nMatchValue; + adi_tmr_registers[eDevice]->PWM0MATCH = pwmConfig->nMatchValue; +#if defined(__ADUCM4050__) /* IF(PWM output 1) */ - } else if (pwmConfig.eOutput == ADI_TMR_PWM_OUTPUT_1) { + } else if (pwmConfig->eOutput == ADI_TMR_PWM_OUTPUT_1) { adi_tmr_registers[eDevice]->PWM1CTL = nControl; - adi_tmr_registers[eDevice]->PWM1MATCH = pwmConfig.nMatchValue; + adi_tmr_registers[eDevice]->PWM1MATCH = pwmConfig->nMatchValue; /* ELSE(PWM output 2) */ } else { adi_tmr_registers[eDevice]->PWM2CTL = nControl; - adi_tmr_registers[eDevice]->PWM2MATCH = pwmConfig.nMatchValue; + adi_tmr_registers[eDevice]->PWM2MATCH = pwmConfig->nMatchValue; +#endif } /* ENDIF */ - return ADI_TMR_SUCCESS; } @@ -599,13 +629,13 @@ void GP_Tmr2_Int_Handler(void) { CommonIntHandler(ADI_TMR_DEVICE_GP2); ISR_EPILOG() } - +#if defined(__ADUCM4050__) void RGB_Tmr_Int_Handler(void) { ISR_PROLOG() CommonIntHandler(ADI_TMR_DEVICE_RGB); ISR_EPILOG() } - +#endif /*! \endcond */ /*! @} */ diff --git a/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/bsp/tmr/adi_tmr_data.c b/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/bsp/tmr/adi_tmr_data.c index 31b2dbe8fc8a..9363e284a0de 100755 --- a/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/bsp/tmr/adi_tmr_data.c +++ b/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/bsp/tmr/adi_tmr_data.c @@ -51,6 +51,34 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +/* Macro mapping from ADuCM4050 to ADuCM3029 */ +#if defined(__ADUCM3029__) +#define BITM_TMR_RGB_CTL_EN BITM_TMR_CTL_EN +#define PWM0CTL PWMCTL +#define PWM0MATCH PWMMATCH +#define BITM_TMR_RGB_STAT_BUSY BITM_TMR_STAT_BUSY +#define BITM_TMR_RGB_CTL_EVTEN BITM_TMR_CTL_EVTEN +#define BITM_TMR_RGB_CTL_RSTEN BITM_TMR_CTL_RSTEN +#define BITP_TMR_RGB_CTL_RSTEN BITP_TMR_CTL_RSTEN +#define BITP_TMR_RGB_CTL_EVTEN BITP_TMR_CTL_EVTEN +#define BITP_TMR_RGB_CTL_PRE BITP_TMR_CTL_PRE +#define BITP_TMR_RGB_CTL_CLK BITP_TMR_CTL_CLK +#define BITP_TMR_RGB_CTL_MODE BITP_TMR_CTL_MODE +#define BITP_TMR_RGB_CTL_UP BITP_TMR_CTL_UP +#define BITP_TMR_RGB_CTL_RLD BITP_TMR_CTL_RLD +#define BITP_TMR_RGB_CTL_SYNCBYP BITP_TMR_CTL_SYNCBYP +#define BITP_TMR_RGB_PWM0CTL_IDLESTATE BITP_TMR_PWMCTL_IDLESTATE +#define BITP_TMR_RGB_PWM0CTL_MATCH BITP_TMR_PWMCTL_MATCH +#define BITM_TMR_RGB_CLRINT_TIMEOUT BITM_TMR_CLRINT_TIMEOUT +#define BITM_TMR_RGB_STAT_PDOK BITM_TMR_STAT_PDOK +#define BITM_TMR_RGB_STAT_TIMEOUT BITM_TMR_STAT_TIMEOUT +#define BITM_TMR_RGB_STAT_CAPTURE BITM_TMR_STAT_CAPTURE +#define BITM_TMR_RGB_CLRINT_EVTCAPT BITM_TMR_CLRINT_EVTCAPT +#define BITM_TMR_RGB_CLRINT_TIMEOUT BITM_TMR_CLRINT_TIMEOUT +#define BITM_TMR_RGB_CTL_RLD BITM_TMR_CTL_RLD +#endif /*__ADUCM3029__*/ + +#ifndef TARGET_Analog_Devices /* CTL register static configuration */ static uint16_t aTimerCtlConfig[] = { @@ -80,7 +108,7 @@ static uint16_t aTimerCtlConfig[] = (TMR2_CFG_ENABLE_SYNC_BYPASS << BITP_TMR_RGB_CTL_SYNCBYP) | (TMR2_CFG_ENABLE_PRESCALE_RESET << BITP_TMR_RGB_CTL_RSTEN) | (TMR2_CFG_ENABLE_EVENT_CAPTURE << BITP_TMR_RGB_CTL_EVTEN), - +#if defined(__ADUCM4050__) (TMR3_CFG_COUNT_UP << BITP_TMR_RGB_CTL_UP) | (TMR3_CFG_MODE << BITP_TMR_RGB_CTL_MODE) | (TMR3_CFG_PRESCALE_FACTOR << BITP_TMR_RGB_CTL_PRE) | @@ -89,6 +117,7 @@ static uint16_t aTimerCtlConfig[] = (TMR3_CFG_ENABLE_SYNC_BYPASS << BITP_TMR_RGB_CTL_SYNCBYP) | (TMR3_CFG_ENABLE_PRESCALE_RESET << BITP_TMR_RGB_CTL_RSTEN) | (TMR3_CFG_ENABLE_EVENT_CAPTURE << BITP_TMR_RGB_CTL_EVTEN), +#endif }; /* LOAD register static configuration */ @@ -97,7 +126,9 @@ static uint16_t aTimerLoadConfig[] = TMR0_CFG_LOAD_VALUE, TMR1_CFG_LOAD_VALUE, TMR2_CFG_LOAD_VALUE, +#if defined(__ADUCM4050__) TMR3_CFG_LOAD_VALUE, +#endif }; /* Asynchronous LOAD static configuraton */ @@ -106,10 +137,13 @@ static uint16_t aTimerALoadConfig[] = TMR0_CFG_ASYNC_LOAD_VALUE, TMR1_CFG_ASYNC_LOAD_VALUE, TMR2_CFG_ASYNC_LOAD_VALUE, +#if defined(__ADUCM4050__) TMR3_CFG_ASYNC_LOAD_VALUE, +#endif }; /* EVENTSELECT static configuration */ +#if defined(__ADUCM4050__) static uint16_t aTimerEventConfig[] = { TMR0_CFG_EVENT_CAPTURE, @@ -117,6 +151,7 @@ static uint16_t aTimerEventConfig[] = TMR2_CFG_EVENT_CAPTURE, TMR3_CFG_EVENT_CAPTURE, }; +#endif /* PWM CTL static configuration */ static uint16_t aTimerPwmCtlConfig[] = @@ -129,7 +164,7 @@ static uint16_t aTimerPwmCtlConfig[] = (TMR2_CFG_PWM0_IDLE_STATE << BITP_TMR_RGB_PWM0CTL_IDLESTATE) | (TMR2_CFG_PWM0_MATCH_VALUE << BITP_TMR_RGB_PWM0CTL_MATCH), - +#if defined(__ADUCM4050__) (TMR3_CFG_PWM0_IDLE_STATE << BITP_TMR_RGB_PWM0CTL_IDLESTATE) | (TMR3_CFG_PWM0_MATCH_VALUE << BITP_TMR_RGB_PWM0CTL_MATCH), @@ -138,6 +173,7 @@ static uint16_t aTimerPwmCtlConfig[] = (TMR3_CFG_PWM2_IDLE_STATE << BITP_TMR_RGB_PWM2CTL_IDLESTATE) | (TMR3_CFG_PWM2_MATCH_VALUE << BITP_TMR_RGB_PWM2CTL_MATCH), +#endif }; /* PWM MATCH static configuration */ @@ -145,10 +181,12 @@ static uint16_t aTimerPwmMatchConfig[] = { TMR0_CFG_PWM0_MATCH_VALUE, TMR1_CFG_PWM0_MATCH_VALUE, TMR2_CFG_PWM0_MATCH_VALUE, +#if defined(__ADUCM4050__) TMR3_CFG_PWM0_MATCH_VALUE, TMR3_CFG_PWM1_MATCH_VALUE, TMR3_CFG_PWM2_MATCH_VALUE +#endif }; - +#endif #endif /* ADI_TMR_DATA */ diff --git a/targets/TARGET_Atmel/TARGET_SAM_CortexM0P/us_ticker.c b/targets/TARGET_Atmel/TARGET_SAM_CortexM0P/us_ticker.c index 4fb0880ca970..568aa89ef0d7 100644 --- a/targets/TARGET_Atmel/TARGET_SAM_CortexM0P/us_ticker.c +++ b/targets/TARGET_Atmel/TARGET_SAM_CortexM0P/us_ticker.c @@ -167,3 +167,8 @@ void us_ticker_clear_interrupt(void) tc_clear_interrupt(&us_ticker_module, TC_CALLBACK_CC_CHANNEL0); NVIC_ClearPendingIRQ(TICKER_COUNTER_IRQn); } + +void us_ticker_free(void) +{ + +} diff --git a/targets/TARGET_Atmel/TARGET_SAM_CortexM4/lp_ticker.c b/targets/TARGET_Atmel/TARGET_SAM_CortexM4/lp_ticker.c index 1524b90cb73f..507c44c95043 100644 --- a/targets/TARGET_Atmel/TARGET_SAM_CortexM4/lp_ticker.c +++ b/targets/TARGET_Atmel/TARGET_SAM_CortexM4/lp_ticker.c @@ -131,3 +131,8 @@ void lp_ticker_clear_interrupt(void) { NVIC_ClearPendingIRQ(TICKER_COUNTER_IRQn2); } + +void lp_ticker_free(void) +{ + +} diff --git a/targets/TARGET_Atmel/TARGET_SAM_CortexM4/us_ticker.c b/targets/TARGET_Atmel/TARGET_SAM_CortexM4/us_ticker.c index dad8e9dd6e9e..8f6d6e65ca5d 100644 --- a/targets/TARGET_Atmel/TARGET_SAM_CortexM4/us_ticker.c +++ b/targets/TARGET_Atmel/TARGET_SAM_CortexM4/us_ticker.c @@ -186,3 +186,8 @@ void us_ticker_clear_interrupt(void) { NVIC_ClearPendingIRQ(TICKER_COUNTER_IRQn1); } + +void us_ticker_free(void) +{ + +} diff --git a/targets/TARGET_Freescale/TARGET_K20XX/TARGET_K20D50M/us_ticker.c b/targets/TARGET_Freescale/TARGET_K20XX/TARGET_K20D50M/us_ticker.c index 4ea164b13640..7f1d16a056bf 100644 --- a/targets/TARGET_Freescale/TARGET_K20XX/TARGET_K20D50M/us_ticker.c +++ b/targets/TARGET_Freescale/TARGET_K20XX/TARGET_K20D50M/us_ticker.c @@ -158,3 +158,8 @@ void us_ticker_fire_interrupt(void) { NVIC_SetPendingIRQ(PIT_TICKER_IRQ); } + +void us_ticker_free(void) +{ + +} diff --git a/targets/TARGET_Freescale/TARGET_K20XX/TARGET_TEENSY3_1/us_ticker.c b/targets/TARGET_Freescale/TARGET_K20XX/TARGET_TEENSY3_1/us_ticker.c index 143e1383fc98..8995ad720519 100644 --- a/targets/TARGET_Freescale/TARGET_K20XX/TARGET_TEENSY3_1/us_ticker.c +++ b/targets/TARGET_Freescale/TARGET_K20XX/TARGET_TEENSY3_1/us_ticker.c @@ -81,3 +81,8 @@ void us_ticker_fire_interrupt(void) { NVIC_SetPendingIRQ(PIT3_IRQn); } + +void us_ticker_free(void) +{ + +} diff --git a/targets/TARGET_Freescale/TARGET_KLXX/us_ticker.c b/targets/TARGET_Freescale/TARGET_KLXX/us_ticker.c index ffd9cc05c414..f314c2c135e3 100644 --- a/targets/TARGET_Freescale/TARGET_KLXX/us_ticker.c +++ b/targets/TARGET_Freescale/TARGET_KLXX/us_ticker.c @@ -223,3 +223,8 @@ void us_ticker_fire_interrupt(void) #endif } + +void us_ticker_free(void) +{ + +} diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/us_ticker.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/us_ticker.c index 1666223e1074..18716dd88703 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/us_ticker.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/us_ticker.c @@ -136,3 +136,8 @@ void us_ticker_fire_interrupt(void) { NVIC_SetPendingIRQ(PIT3_IRQn); } + +void us_ticker_free(void) +{ + +} diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K82F/us_ticker.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K82F/us_ticker.c index 1666223e1074..9d3b9f1f66a0 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K82F/us_ticker.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K82F/us_ticker.c @@ -136,3 +136,16 @@ void us_ticker_fire_interrupt(void) { NVIC_SetPendingIRQ(PIT3_IRQn); } + +void us_ticker_free(void) +{ + PIT_StopTimer(PIT, kPIT_Chnl_3); + PIT_StopTimer(PIT, kPIT_Chnl_2); + PIT_StopTimer(PIT, kPIT_Chnl_1); + PIT_StopTimer(PIT, kPIT_Chnl_0); + + PIT_DisableInterrupts(PIT, kPIT_Chnl_3, kPIT_TimerInterruptEnable); + NVIC_DisableIRQ(PIT3_IRQn); + + us_ticker_inited = false; +} diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/us_ticker.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/us_ticker.c index 3b784bc08e14..b77cbf6479d5 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/us_ticker.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/us_ticker.c @@ -152,3 +152,8 @@ void us_ticker_fire_interrupt(void) NVIC_SetPendingIRQ(TPM2_IRQn); } + +void us_ticker_free(void) +{ + +} diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/us_ticker.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/us_ticker.c index 3b784bc08e14..b77cbf6479d5 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/us_ticker.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/us_ticker.c @@ -152,3 +152,8 @@ void us_ticker_fire_interrupt(void) NVIC_SetPendingIRQ(TPM2_IRQn); } + +void us_ticker_free(void) +{ + +} diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/us_ticker.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/us_ticker.c index 456855c4fff2..1fa17b15514c 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/us_ticker.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/us_ticker.c @@ -137,3 +137,8 @@ void us_ticker_fire_interrupt(void) NVIC_SetPendingIRQ(PIT0_IRQn); } +void us_ticker_free(void) +{ + +} + diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/us_ticker.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/us_ticker.c index 1666223e1074..9d3b9f1f66a0 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/us_ticker.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/us_ticker.c @@ -136,3 +136,16 @@ void us_ticker_fire_interrupt(void) { NVIC_SetPendingIRQ(PIT3_IRQn); } + +void us_ticker_free(void) +{ + PIT_StopTimer(PIT, kPIT_Chnl_3); + PIT_StopTimer(PIT, kPIT_Chnl_2); + PIT_StopTimer(PIT, kPIT_Chnl_1); + PIT_StopTimer(PIT, kPIT_Chnl_0); + + PIT_DisableInterrupts(PIT, kPIT_Chnl_3, kPIT_TimerInterruptEnable); + NVIC_DisableIRQ(PIT3_IRQn); + + us_ticker_inited = false; +} diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/us_ticker.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/us_ticker.c index fb2eba2aea5b..864abec9f941 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/us_ticker.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/us_ticker.c @@ -152,3 +152,14 @@ void us_ticker_fire_interrupt(void) NVIC_SetPendingIRQ(TPM2_IRQn); } + +void us_ticker_free(void) +{ + PIT_StopTimer(PIT, kPIT_Chnl_1); + PIT_StopTimer(PIT, kPIT_Chnl_0); + + TPM_DisableInterrupts(TPM2, kTPM_TimeOverflowInterruptEnable); + NVIC_DisableIRQ(TPM2_IRQn); + + us_ticker_inited = false; +} diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/us_ticker.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/us_ticker.c index 1666223e1074..9d3b9f1f66a0 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/us_ticker.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/us_ticker.c @@ -136,3 +136,16 @@ void us_ticker_fire_interrupt(void) { NVIC_SetPendingIRQ(PIT3_IRQn); } + +void us_ticker_free(void) +{ + PIT_StopTimer(PIT, kPIT_Chnl_3); + PIT_StopTimer(PIT, kPIT_Chnl_2); + PIT_StopTimer(PIT, kPIT_Chnl_1); + PIT_StopTimer(PIT, kPIT_Chnl_0); + + PIT_DisableInterrupts(PIT, kPIT_Chnl_3, kPIT_TimerInterruptEnable); + NVIC_DisableIRQ(PIT3_IRQn); + + us_ticker_inited = false; +} diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K24F/us_ticker.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K24F/us_ticker.c index 1666223e1074..18716dd88703 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K24F/us_ticker.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K24F/us_ticker.c @@ -136,3 +136,8 @@ void us_ticker_fire_interrupt(void) { NVIC_SetPendingIRQ(PIT3_IRQn); } + +void us_ticker_free(void) +{ + +} diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_SDT64B/PeripheralNames.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_SDT64B/PeripheralNames.h new file mode 100644 index 000000000000..65d2b635b81d --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_SDT64B/PeripheralNames.h @@ -0,0 +1,137 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + OSC32KCLK = 0, +} RTCName; + +typedef enum { + UART_0 = 0, + UART_1 = 1, + UART_2 = 2, + UART_3 = 3, + UART_4 = 4, +} UARTName; + +#define STDIO_UART_TX USBTX +#define STDIO_UART_RX USBRX +#define STDIO_UART UART_0 + +typedef enum { + I2C_0 = 0, + I2C_1 = 1, + I2C_2 = 2, +} I2CName; + +#define TPM_SHIFT 8 +typedef enum { + PWM_1 = (0 << TPM_SHIFT) | (0), // FTM0 CH0 + PWM_2 = (0 << TPM_SHIFT) | (1), // FTM0 CH1 + PWM_3 = (0 << TPM_SHIFT) | (2), // FTM0 CH2 + PWM_4 = (0 << TPM_SHIFT) | (3), // FTM0 CH3 + PWM_5 = (0 << TPM_SHIFT) | (4), // FTM0 CH4 + PWM_6 = (0 << TPM_SHIFT) | (5), // FTM0 CH5 + PWM_7 = (0 << TPM_SHIFT) | (6), // FTM0 CH6 + PWM_8 = (0 << TPM_SHIFT) | (7), // FTM0 CH7 + PWM_9 = (1 << TPM_SHIFT) | (0), // FTM1 CH0 + PWM_10 = (1 << TPM_SHIFT) | (1), // FTM1 CH1 + PWM_11 = (1 << TPM_SHIFT) | (2), // FTM1 CH2 + PWM_12 = (1 << TPM_SHIFT) | (3), // FTM1 CH3 + PWM_13 = (1 << TPM_SHIFT) | (4), // FTM1 CH4 + PWM_14 = (1 << TPM_SHIFT) | (5), // FTM1 CH5 + PWM_15 = (1 << TPM_SHIFT) | (6), // FTM1 CH6 + PWM_16 = (1 << TPM_SHIFT) | (7), // FTM1 CH7 + PWM_17 = (2 << TPM_SHIFT) | (0), // FTM2 CH0 + PWM_18 = (2 << TPM_SHIFT) | (1), // FTM2 CH1 + PWM_19 = (2 << TPM_SHIFT) | (2), // FTM2 CH2 + PWM_20 = (2 << TPM_SHIFT) | (3), // FTM2 CH3 + PWM_21 = (2 << TPM_SHIFT) | (4), // FTM2 CH4 + PWM_22 = (2 << TPM_SHIFT) | (5), // FTM2 CH5 + PWM_23 = (2 << TPM_SHIFT) | (6), // FTM2 CH6 + PWM_24 = (2 << TPM_SHIFT) | (7), // FTM2 CH7 + PWM_25 = (3 << TPM_SHIFT) | (0), // FTM3 CH0 + PWM_26 = (3 << TPM_SHIFT) | (1), // FTM3 CH1 + PWM_27 = (3 << TPM_SHIFT) | (2), // FTM3 CH2 + PWM_28 = (3 << TPM_SHIFT) | (3), // FTM3 CH3 + PWM_29 = (3 << TPM_SHIFT) | (4), // FTM3 CH4 + PWM_30 = (3 << TPM_SHIFT) | (5), // FTM3 CH5 + PWM_31 = (3 << TPM_SHIFT) | (6), // FTM3 CH6 + PWM_32 = (3 << TPM_SHIFT) | (7), // FTM3 CH7 +} PWMName; + +#define ADC_INSTANCE_SHIFT 8 +#define ADC_B_CHANNEL_SHIFT 5 +typedef enum { + ADC0_SE4b = (0 << ADC_INSTANCE_SHIFT) | (1 << ADC_B_CHANNEL_SHIFT) | 4, + ADC0_SE5b = (0 << ADC_INSTANCE_SHIFT) | (1 << ADC_B_CHANNEL_SHIFT) | 5, + ADC0_SE6b = (0 << ADC_INSTANCE_SHIFT) | (1 << ADC_B_CHANNEL_SHIFT) | 6, + ADC0_SE7b = (0 << ADC_INSTANCE_SHIFT) | (1 << ADC_B_CHANNEL_SHIFT) | 7, + ADC0_SE8 = (0 << ADC_INSTANCE_SHIFT) | 8, + ADC0_SE9 = (0 << ADC_INSTANCE_SHIFT) | 9, + ADC0_SE12 = (0 << ADC_INSTANCE_SHIFT) | 12, + ADC0_SE13 = (0 << ADC_INSTANCE_SHIFT) | 13, + ADC0_SE14 = (0 << ADC_INSTANCE_SHIFT) | 14, + ADC0_SE15 = (0 << ADC_INSTANCE_SHIFT) | 15, + ADC0_SE16 = (0 << ADC_INSTANCE_SHIFT) | 16, + ADC0_SE17 = (0 << ADC_INSTANCE_SHIFT) | 17, + ADC0_SE18 = (0 << ADC_INSTANCE_SHIFT) | 18, + ADC0_SE21 = (0 << ADC_INSTANCE_SHIFT) | 21, + ADC0_SE22 = (0 << ADC_INSTANCE_SHIFT) | 22, + ADC0_SE23 = (0 << ADC_INSTANCE_SHIFT) | 23, + ADC1_SE4a = (1 << ADC_INSTANCE_SHIFT) | 4, + ADC1_SE5a = (1 << ADC_INSTANCE_SHIFT) | 5, + ADC1_SE6a = (1 << ADC_INSTANCE_SHIFT) | 6, + ADC1_SE7a = (1 << ADC_INSTANCE_SHIFT) | 7, + ADC1_SE4b = (1 << ADC_INSTANCE_SHIFT) | (1 << ADC_B_CHANNEL_SHIFT) | 4, + ADC1_SE5b = (1 << ADC_INSTANCE_SHIFT) | (1 << ADC_B_CHANNEL_SHIFT) | 5, + ADC1_SE6b = (1 << ADC_INSTANCE_SHIFT) | (1 << ADC_B_CHANNEL_SHIFT) | 6, + ADC1_SE7b = (1 << ADC_INSTANCE_SHIFT) | (1 << ADC_B_CHANNEL_SHIFT) | 7, + ADC1_SE8 = (1 << ADC_INSTANCE_SHIFT) | 8, + ADC1_SE9 = (1 << ADC_INSTANCE_SHIFT) | 9, + ADC1_SE12 = (1 << ADC_INSTANCE_SHIFT) | 12, + ADC1_SE13 = (1 << ADC_INSTANCE_SHIFT) | 13, + ADC1_SE14 = (1 << ADC_INSTANCE_SHIFT) | 14, + ADC1_SE15 = (1 << ADC_INSTANCE_SHIFT) | 15, + ADC1_SE16 = (1 << ADC_INSTANCE_SHIFT) | 16, + ADC1_SE17 = (1 << ADC_INSTANCE_SHIFT) | 17, + ADC1_SE18 = (1 << ADC_INSTANCE_SHIFT) | 18, + ADC1_SE23 = (1 << ADC_INSTANCE_SHIFT) | 23, +} ADCName; + +typedef enum { + DAC_0 = 0 +} DACName; + + +typedef enum { + SPI_0 = 0, + SPI_1 = 1, + SPI_2 = 2, +} SPIName; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_SDT64B/PeripheralPins.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_SDT64B/PeripheralPins.c new file mode 100644 index 000000000000..c2bb8f627e2c --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_SDT64B/PeripheralPins.c @@ -0,0 +1,242 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "PeripheralPins.h" + +/************RTC***************/ +const PinMap PinMap_RTC[] = { + {NC, OSC32KCLK, 0}, +}; + +/************ADC***************/ +const PinMap PinMap_ADC[] = { + {PTA17, ADC1_SE17, 0}, + {PTB0 , ADC0_SE8 , 0}, + {PTB1 , ADC0_SE9 , 0}, + {PTB2 , ADC0_SE12, 0}, + {PTB3 , ADC0_SE13, 0}, + {PTB6 , ADC1_SE12, 0}, + {PTB7 , ADC1_SE13, 0}, + {PTB10, ADC1_SE14, 0}, + {PTB11, ADC1_SE15, 0}, + {PTC0 , ADC0_SE14, 0}, + {PTC1 , ADC0_SE15, 0}, + {PTC2, ADC0_SE4b, 0}, + {PTC8, ADC1_SE4b, 0}, + {PTC9, ADC1_SE5b, 0}, + {PTC10, ADC1_SE6b, 0}, + {PTC11, ADC1_SE7b, 0}, + {PTD1, ADC0_SE5b, 0}, + {PTD5, ADC0_SE6b, 0}, + {PTD6, ADC0_SE7b, 0}, + {PTE0, ADC1_SE4a, 0}, + {PTE1, ADC1_SE5a, 0}, + {PTE2, ADC1_SE6a, 0}, + {PTE3, ADC1_SE7a, 0}, + //{PTE24, ADC0_SE17, 0}, //I2C pull up + //{PTE25, ADC0_SE18, 0}, //I2C pull up + {NC , NC , 0} +}; + +/************DAC***************/ +const PinMap PinMap_DAC[] = { + {DAC0_OUT, DAC_0, 0}, + {NC , NC , 0} +}; + +/************I2C***************/ +const PinMap PinMap_I2C_SDA[] = { + {PTE25, I2C_0, 5}, + {PTB1 , I2C_0, 2}, + {PTB3 , I2C_0, 2}, + {PTC11, I2C_1, 2}, + {PTA13, I2C_2, 5}, + {PTD3 , I2C_0, 7}, + {PTE0 , I2C_1, 6}, + {NC , NC , 0} +}; + +const PinMap PinMap_I2C_SCL[] = { + {PTE24, I2C_0, 5}, + {PTB0 , I2C_0, 2}, + {PTB2 , I2C_0, 2}, + {PTC10, I2C_1, 2}, + {PTA12, I2C_2, 5}, + {PTA14, I2C_2, 5}, + {PTD2 , I2C_0, 7}, + {PTE1 , I2C_1, 6}, + {NC , NC , 0} +}; + +/************UART***************/ +const PinMap PinMap_UART_TX[] = { + {PTB17, UART_0, 3}, + {PTC17, UART_3, 3}, + {PTD7 , UART_0, 3}, + {PTD3 , UART_2, 3}, + {PTC4 , UART_1, 3}, + {PTC15, UART_4, 3}, + {PTB11, UART_3, 3}, + {PTA14, UART_0, 3}, + {PTE24, UART_4, 3}, + {PTE4 , UART_3, 3}, + {PTE0, UART_1, 3}, + {NC , NC , 0} +}; + +const PinMap PinMap_UART_RX[] = { + {PTB16, UART_0, 3}, + {PTE1 , UART_1, 3}, + {PTE5 , UART_3, 3}, + {PTE25, UART_4, 3}, + {PTA15, UART_0, 3}, + {PTC16, UART_3, 3}, + {PTB10, UART_3, 3}, + {PTC3 , UART_1, 3}, + {PTC14, UART_4, 3}, + {PTD2 , UART_2, 3}, + {PTD6 , UART_0, 3}, + {NC , NC , 0} +}; + +const PinMap PinMap_UART_CTS[] = { + {PTB13, UART_3, 2}, + {PTE2 , UART_1, 3}, + {PTE6 , UART_3, 3}, + {PTE26, UART_4, 3}, + {PTA0 , UART_0, 2}, + {PTA16, UART_0, 3}, + {PTB3 , UART_0, 3}, + {PTB9 , UART_3, 3}, + {PTC2 , UART_1, 3}, + {PTC13, UART_4, 3}, + {PTC19, UART_3, 3}, + {PTD1 , UART_2, 3}, + {PTD5 , UART_0, 3}, + {NC , NC , 0} +}; + +const PinMap PinMap_UART_RTS[] = { + {PTB12, UART_3, 2}, + {PTE3 , UART_1, 3}, + {PTE7 , UART_3, 3}, + {PTE27, UART_4, 3}, + {PTA17, UART_0, 3}, + {PTB8 , UART_3, 3}, + {PTC1 , UART_1, 3}, + {PTC12, UART_4, 3}, + {PTC18, UART_3, 3}, + {PTD0 , UART_2, 3}, + {PTD4 , UART_0, 3}, + {PTA3 , UART_0, 2}, + {PTB2 , UART_0, 3}, + {NC , NC , 0} +}; + +/************SPI***************/ +const PinMap PinMap_SPI_SCLK[] = { + {PTD1 , SPI_0, 2}, + {PTE2 , SPI_1, 2}, + {PTA15, SPI_0, 2}, + {PTB11, SPI_1, 2}, + {PTB21, SPI_2, 2}, + {PTC5 , SPI_0, 2}, + {PTD5 , SPI_1, 7}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_MOSI[] = { + {PTD2 , SPI_0, 2}, + {PTE1 , SPI_1, 2}, + {PTE3 , SPI_1, 7}, + {PTA16, SPI_0, 2}, + {PTB16, SPI_1, 2}, + {PTB22, SPI_2, 2}, + {PTC6 , SPI_0, 2}, + {PTD6 , SPI_1, 7}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_MISO[] = { + {PTD3 , SPI_0, 2}, + {PTE1 , SPI_1, 7}, + {PTE3 , SPI_1, 2}, + {PTA17, SPI_0, 2}, + {PTB17, SPI_1, 2}, + {PTB23, SPI_2, 2}, + {PTC7 , SPI_0, 2}, + {PTD7 , SPI_1, 7}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_SSEL[] = { + {PTD0 , SPI_0, 2}, + {PTE4 , SPI_1, 2}, + {PTA14, SPI_0, 2}, + {PTB10, SPI_1, 2}, + {PTB20, SPI_2, 2}, + {PTC4 , SPI_0, 2}, + {PTD4 , SPI_1, 7}, + {NC , NC , 0} +}; + +/************PWM***************/ +const PinMap PinMap_PWM[] = { + {PTA0 , PWM_6 , 3}, + {PTA1 , PWM_7 , 3}, + {PTA2 , PWM_8 , 3}, + {PTA3 , PWM_1 , 3}, + {PTA4 , PWM_2 , 3}, + {PTA5 , PWM_3 , 3}, + {PTA6 , PWM_4 , 3}, + {PTA7 , PWM_5 , 3}, + {PTA8 , PWM_9 , 3}, + {PTA9 , PWM_10, 3}, + {PTA10, PWM_17, 3}, + {PTA11, PWM_18, 3}, + {PTA12, PWM_9 , 3}, + {PTA13, PWM_10, 3}, + + {PTB0 , PWM_9 , 3}, + {PTB1 , PWM_10, 3}, + {PTB18, PWM_17, 3}, + {PTB19, PWM_18, 3}, + + {PTC1 , PWM_1 , 4}, + {PTC2 , PWM_2 , 4}, + {PTC3 , PWM_3 , 4}, + {PTC4 , PWM_4 , 4}, + {PTC5 , PWM_3 , 7}, + {PTC8 , PWM_29, 3}, + {PTC9 , PWM_30, 3}, + {PTC10, PWM_31, 3}, + {PTC11, PWM_32, 3}, + + {PTD0 , PWM_25, 4}, + {PTD1 , PWM_26, 4}, + {PTD2 , PWM_27, 4}, + {PTD3 , PWM_28, 4}, + {PTD4 , PWM_5 , 4}, + {PTD5 , PWM_6 , 4}, + {PTD6 , PWM_7 , 4}, + {PTD4 , PWM_5 , 4}, + {PTD7 , PWM_8 , 4}, + + {PTE5 , PWM_25, 6}, + {PTE6 , PWM_26, 6}, + + {NC , NC , 0} +}; diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_SDT64B/PinNames.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_SDT64B/PinNames.h new file mode 100644 index 000000000000..af4b262b3e31 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_SDT64B/PinNames.h @@ -0,0 +1,318 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define DAC0_OUT 0xFEFE /* DAC does not have Pin Name in RM */ +#define NOT_CONNECTED (int)0xFFFFFFFF +#define GPIO_PORT_SHIFT 12 + +typedef enum { + PTA0 = (0 << GPIO_PORT_SHIFT | 0 ), + PTA1 = (0 << GPIO_PORT_SHIFT | 1 ), + PTA2 = (0 << GPIO_PORT_SHIFT | 2 ), + PTA3 = (0 << GPIO_PORT_SHIFT | 3 ), + PTA4 = (0 << GPIO_PORT_SHIFT | 4 ), + PTA5 = (0 << GPIO_PORT_SHIFT | 5 ), + PTA6 = (0 << GPIO_PORT_SHIFT | 6 ), + PTA7 = (0 << GPIO_PORT_SHIFT | 7 ), + PTA8 = (0 << GPIO_PORT_SHIFT | 8 ), + PTA9 = (0 << GPIO_PORT_SHIFT | 9 ), + PTA10 = (0 << GPIO_PORT_SHIFT | 10), + PTA11 = (0 << GPIO_PORT_SHIFT | 11), + PTA12 = (0 << GPIO_PORT_SHIFT | 12), + PTA13 = (0 << GPIO_PORT_SHIFT | 13), + PTA14 = (0 << GPIO_PORT_SHIFT | 14), + PTA15 = (0 << GPIO_PORT_SHIFT | 15), + PTA16 = (0 << GPIO_PORT_SHIFT | 16), + PTA17 = (0 << GPIO_PORT_SHIFT | 17), + PTA18 = (0 << GPIO_PORT_SHIFT | 18), + PTA19 = (0 << GPIO_PORT_SHIFT | 19), + PTA20 = (0 << GPIO_PORT_SHIFT | 20), + PTA21 = (0 << GPIO_PORT_SHIFT | 21), + PTA22 = (0 << GPIO_PORT_SHIFT | 22), + PTA23 = (0 << GPIO_PORT_SHIFT | 23), + PTA24 = (0 << GPIO_PORT_SHIFT | 24), + PTA25 = (0 << GPIO_PORT_SHIFT | 25), + PTA26 = (0 << GPIO_PORT_SHIFT | 26), + PTA27 = (0 << GPIO_PORT_SHIFT | 27), + PTA28 = (0 << GPIO_PORT_SHIFT | 28), + PTA29 = (0 << GPIO_PORT_SHIFT | 29), + PTA30 = (0 << GPIO_PORT_SHIFT | 30), + PTA31 = (0 << GPIO_PORT_SHIFT | 31), + PTB0 = (1 << GPIO_PORT_SHIFT | 0 ), + PTB1 = (1 << GPIO_PORT_SHIFT | 1 ), + PTB2 = (1 << GPIO_PORT_SHIFT | 2 ), + PTB3 = (1 << GPIO_PORT_SHIFT | 3 ), + PTB4 = (1 << GPIO_PORT_SHIFT | 4 ), + PTB5 = (1 << GPIO_PORT_SHIFT | 5 ), + PTB6 = (1 << GPIO_PORT_SHIFT | 6 ), + PTB7 = (1 << GPIO_PORT_SHIFT | 7 ), + PTB8 = (1 << GPIO_PORT_SHIFT | 8 ), + PTB9 = (1 << GPIO_PORT_SHIFT | 9 ), + PTB10 = (1 << GPIO_PORT_SHIFT | 10), + PTB11 = (1 << GPIO_PORT_SHIFT | 11), + PTB12 = (1 << GPIO_PORT_SHIFT | 12), + PTB13 = (1 << GPIO_PORT_SHIFT | 13), + PTB14 = (1 << GPIO_PORT_SHIFT | 14), + PTB15 = (1 << GPIO_PORT_SHIFT | 15), + PTB16 = (1 << GPIO_PORT_SHIFT | 16), + PTB17 = (1 << GPIO_PORT_SHIFT | 17), + PTB18 = (1 << GPIO_PORT_SHIFT | 18), + PTB19 = (1 << GPIO_PORT_SHIFT | 19), + PTB20 = (1 << GPIO_PORT_SHIFT | 20), + PTB21 = (1 << GPIO_PORT_SHIFT | 21), + PTB22 = (1 << GPIO_PORT_SHIFT | 22), + PTB23 = (1 << GPIO_PORT_SHIFT | 23), + PTB24 = (1 << GPIO_PORT_SHIFT | 24), + PTB25 = (1 << GPIO_PORT_SHIFT | 25), + PTB26 = (1 << GPIO_PORT_SHIFT | 26), + PTB27 = (1 << GPIO_PORT_SHIFT | 27), + PTB28 = (1 << GPIO_PORT_SHIFT | 28), + PTB29 = (1 << GPIO_PORT_SHIFT | 29), + PTB30 = (1 << GPIO_PORT_SHIFT | 30), + PTB31 = (1 << GPIO_PORT_SHIFT | 31), + PTC0 = (2 << GPIO_PORT_SHIFT | 0 ), + PTC1 = (2 << GPIO_PORT_SHIFT | 1 ), + PTC2 = (2 << GPIO_PORT_SHIFT | 2 ), + PTC3 = (2 << GPIO_PORT_SHIFT | 3 ), + PTC4 = (2 << GPIO_PORT_SHIFT | 4 ), + PTC5 = (2 << GPIO_PORT_SHIFT | 5 ), + PTC6 = (2 << GPIO_PORT_SHIFT | 6 ), + PTC7 = (2 << GPIO_PORT_SHIFT | 7 ), + PTC8 = (2 << GPIO_PORT_SHIFT | 8 ), + PTC9 = (2 << GPIO_PORT_SHIFT | 9 ), + PTC10 = (2 << GPIO_PORT_SHIFT | 10), + PTC11 = (2 << GPIO_PORT_SHIFT | 11), + PTC12 = (2 << GPIO_PORT_SHIFT | 12), + PTC13 = (2 << GPIO_PORT_SHIFT | 13), + PTC14 = (2 << GPIO_PORT_SHIFT | 14), + PTC15 = (2 << GPIO_PORT_SHIFT | 15), + PTC16 = (2 << GPIO_PORT_SHIFT | 16), + PTC17 = (2 << GPIO_PORT_SHIFT | 17), + PTC18 = (2 << GPIO_PORT_SHIFT | 18), + PTC19 = (2 << GPIO_PORT_SHIFT | 19), + PTC20 = (2 << GPIO_PORT_SHIFT | 20), + PTC21 = (2 << GPIO_PORT_SHIFT | 21), + PTC22 = (2 << GPIO_PORT_SHIFT | 22), + PTC23 = (2 << GPIO_PORT_SHIFT | 23), + PTC24 = (2 << GPIO_PORT_SHIFT | 24), + PTC25 = (2 << GPIO_PORT_SHIFT | 25), + PTC26 = (2 << GPIO_PORT_SHIFT | 26), + PTC27 = (2 << GPIO_PORT_SHIFT | 27), + PTC28 = (2 << GPIO_PORT_SHIFT | 28), + PTC29 = (2 << GPIO_PORT_SHIFT | 29), + PTC30 = (2 << GPIO_PORT_SHIFT | 30), + PTC31 = (2 << GPIO_PORT_SHIFT | 31), + PTD0 = (3 << GPIO_PORT_SHIFT | 0 ), + PTD1 = (3 << GPIO_PORT_SHIFT | 1 ), + PTD2 = (3 << GPIO_PORT_SHIFT | 2 ), + PTD3 = (3 << GPIO_PORT_SHIFT | 3 ), + PTD4 = (3 << GPIO_PORT_SHIFT | 4 ), + PTD5 = (3 << GPIO_PORT_SHIFT | 5 ), + PTD6 = (3 << GPIO_PORT_SHIFT | 6 ), + PTD7 = (3 << GPIO_PORT_SHIFT | 7 ), + PTD8 = (3 << GPIO_PORT_SHIFT | 8 ), + PTD9 = (3 << GPIO_PORT_SHIFT | 9 ), + PTD10 = (3 << GPIO_PORT_SHIFT | 10), + PTD11 = (3 << GPIO_PORT_SHIFT | 11), + PTD12 = (3 << GPIO_PORT_SHIFT | 12), + PTD13 = (3 << GPIO_PORT_SHIFT | 13), + PTD14 = (3 << GPIO_PORT_SHIFT | 14), + PTD15 = (3 << GPIO_PORT_SHIFT | 15), + PTD16 = (3 << GPIO_PORT_SHIFT | 16), + PTD17 = (3 << GPIO_PORT_SHIFT | 17), + PTD18 = (3 << GPIO_PORT_SHIFT | 18), + PTD19 = (3 << GPIO_PORT_SHIFT | 19), + PTD20 = (3 << GPIO_PORT_SHIFT | 20), + PTD21 = (3 << GPIO_PORT_SHIFT | 21), + PTD22 = (3 << GPIO_PORT_SHIFT | 22), + PTD23 = (3 << GPIO_PORT_SHIFT | 23), + PTD24 = (3 << GPIO_PORT_SHIFT | 24), + PTD25 = (3 << GPIO_PORT_SHIFT | 25), + PTD26 = (3 << GPIO_PORT_SHIFT | 26), + PTD27 = (3 << GPIO_PORT_SHIFT | 27), + PTD28 = (3 << GPIO_PORT_SHIFT | 28), + PTD29 = (3 << GPIO_PORT_SHIFT | 29), + PTD30 = (3 << GPIO_PORT_SHIFT | 30), + PTD31 = (3 << GPIO_PORT_SHIFT | 31), + PTE0 = (4 << GPIO_PORT_SHIFT | 0 ), + PTE1 = (4 << GPIO_PORT_SHIFT | 1 ), + PTE2 = (4 << GPIO_PORT_SHIFT | 2 ), + PTE3 = (4 << GPIO_PORT_SHIFT | 3 ), + PTE4 = (4 << GPIO_PORT_SHIFT | 4 ), + PTE5 = (4 << GPIO_PORT_SHIFT | 5 ), + PTE6 = (4 << GPIO_PORT_SHIFT | 6 ), + PTE7 = (4 << GPIO_PORT_SHIFT | 7 ), + PTE8 = (4 << GPIO_PORT_SHIFT | 8 ), + PTE9 = (4 << GPIO_PORT_SHIFT | 9 ), + PTE10 = (4 << GPIO_PORT_SHIFT | 10), + PTE11 = (4 << GPIO_PORT_SHIFT | 11), + PTE12 = (4 << GPIO_PORT_SHIFT | 12), + PTE13 = (4 << GPIO_PORT_SHIFT | 13), + PTE14 = (4 << GPIO_PORT_SHIFT | 14), + PTE15 = (4 << GPIO_PORT_SHIFT | 15), + PTE16 = (4 << GPIO_PORT_SHIFT | 16), + PTE17 = (4 << GPIO_PORT_SHIFT | 17), + PTE18 = (4 << GPIO_PORT_SHIFT | 18), + PTE19 = (4 << GPIO_PORT_SHIFT | 19), + PTE20 = (4 << GPIO_PORT_SHIFT | 20), + PTE21 = (4 << GPIO_PORT_SHIFT | 21), + PTE22 = (4 << GPIO_PORT_SHIFT | 22), + PTE23 = (4 << GPIO_PORT_SHIFT | 23), + PTE24 = (4 << GPIO_PORT_SHIFT | 24), + PTE25 = (4 << GPIO_PORT_SHIFT | 25), + PTE26 = (4 << GPIO_PORT_SHIFT | 26), + PTE27 = (4 << GPIO_PORT_SHIFT | 27), + PTE28 = (4 << GPIO_PORT_SHIFT | 28), + PTE29 = (4 << GPIO_PORT_SHIFT | 29), + PTE30 = (4 << GPIO_PORT_SHIFT | 30), + PTE31 = (4 << GPIO_PORT_SHIFT | 31), + + // Analog + A0 = PTB6, + A1 = PTB7, + A2 = DAC0_OUT, + //A3 = DAC1_OUT, + + // General Pin Input Output (GPIO) + GPIO0 = PTC1, + GPIO1 = PTC5, + GPIO2 = PTD6, + GPIO3 = PTC9, + GPIO4 = PTC3, + GPIO5 = PTC6, + GPIO6 = NOT_CONNECTED, + + // Pulse Width Modulation (PWM) + PWM0 = GPIO2, + PWM1 = GPIO3, + PWM2 = GPIO0, + PWM3 = GPIO1, + + // LEDs + LED0 = GPIO0, + LED1 = GPIO1, + LED2 = GPIO2, + + LED_RED = LED0, + LED_GREEN = LED1, + LED_BLUE = LED2, + + // USB bridge and SWD UART connected UART pins + USBTX = PTC15, + USBRX = PTC14, + + // UART pins + UART0_RX = PTD8, + UART0_TX = PTD9, + UART0_CTS = PTD11, + UART0_RTS = PTD10, + + UART1_RX = USBRX, + UART1_TX = USBTX, + UART1_CTS = PTC13, + UART1_RTS = PTC12, + + UART2_RX = PTC16, + UART2_TX = PTC17, + UART2_CTS = PTC19, + UART2_RTS = PTC18, + + // I2C pins + I2C0_SCL = PTC10, + I2C0_SDA = PTC11, + + I2C1_SCL = PTB2, + I2C1_SDA = PTB3, + + I2C2_SCL = NOT_CONNECTED, + I2C2_SDA = NOT_CONNECTED, + + // SPI pins + SPI0_SCK = PTB11, + SPI0_MOSI = PTB16, + SPI0_MISO = PTB17, + SPI0_SS0 = PTB10, + SPI0_SS1 = PTB9, + SPI0_SS2 = PTB8, + + SPI1_SCK = PTB21, + SPI1_MOSI = PTB22, + SPI1_MISO = PTB23, + SPI1_SS0 = PTB20, + SPI1_SS1 = PTB19, + SPI1_SS2 = PTB18, + + SPI2_SCK = PTD1, + SPI2_MOSI = PTD2, + SPI2_MISO = PTD3, + SPI2_SS0 = PTD0, + SPI2_SS1 = PTD4, + SPI2_SS2 = PTD5, + + SPI3_SCK = NOT_CONNECTED, + SPI3_MOSI = NOT_CONNECTED, + SPI3_MISO = NOT_CONNECTED, + SPI3_SS0 = NOT_CONNECTED, + SPI3_SS1 = NOT_CONNECTED, + SPI3_SS2 = NOT_CONNECTED, + + // SWD UART + SWD_TGT_TX = UART1_TX, + SWD_TGT_RX = UART1_RX, + SWD_TGT_CTS = UART1_CTS, + SWD_TGT_RTS = UART1_RTS, + + // Generics + SERIAL_TX = UART0_TX, + SERIAL_RX = UART0_RX, + I2C_SCL = I2C0_SCL, + I2C_SDA = I2C0_SDA, + SPI_MOSI = SPI0_MOSI, + SPI_MISO = SPI0_MISO, + SPI_SCK = SPI0_SCK, + SPI_CS = SPI0_SS0, + PWM_OUT = PWM0, + + // Not connected + NC = NOT_CONNECTED +} PinName; + + +typedef enum { + PullNone = 0, + PullDown = 1, + PullUp = 2, + PullDefault = PullUp +} PinMode; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_SDT64B/crc.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_SDT64B/crc.c new file mode 100644 index 000000000000..7e2d7e7c5166 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_SDT64B/crc.c @@ -0,0 +1,234 @@ +/********************************************************************** + * + * Filename: crc.c + * + * Description: Slow and fast implementations of the CRC standards. + * + * Notes: The parameters for each supported CRC standard are + * defined in the header file crc.h. The implementations + * here should stand up to further additions to that list. + * + * + * Copyright (c) 2000 by Michael Barr. This software is placed into + * the public domain and may be used for any purpose. However, this + * notice must not be changed or removed and no warranty is either + * expressed or implied by its publication or distribution. + **********************************************************************/ + +#include "crc.h" + + +/* + * Derive parameters from the standard-specific parameters in crc.h. + */ +#define WIDTH (8 * sizeof(crc)) +#define TOPBIT (1 << (WIDTH - 1)) + +#if (REFLECT_DATA == TRUE) +#undef REFLECT_DATA +#define REFLECT_DATA(X) ((unsigned char) reflect((X), 8)) +#else +#undef REFLECT_DATA +#define REFLECT_DATA(X) (X) +#endif + +#if (REFLECT_REMAINDER == TRUE) +#undef REFLECT_REMAINDER +#define REFLECT_REMAINDER(X) ((crc) reflect((X), WIDTH)) +#else +#undef REFLECT_REMAINDER +#define REFLECT_REMAINDER(X) (X) +#endif + + +/********************************************************************* + * + * Function: reflect() + * + * Description: Reorder the bits of a binary sequence, by reflecting + * them about the middle position. + * + * Notes: No checking is done that nBits <= 32. + * + * Returns: The reflection of the original data. + * + *********************************************************************/ +static unsigned long +reflect(unsigned long data, unsigned char nBits) +{ + unsigned long reflection = 0x00000000; + unsigned char bit; + + /* + * Reflect the data about the center bit. + */ + for (bit = 0; bit < nBits; ++bit) + { + /* + * If the LSB bit is set, set the reflection of it. + */ + if (data & 0x01) + { + reflection |= (1 << ((nBits - 1) - bit)); + } + + data = (data >> 1); + } + + return (reflection); + +} /* reflect() */ + + +/********************************************************************* + * + * Function: crcSlow() + * + * Description: Compute the CRC of a given message. + * + * Notes: + * + * Returns: The CRC of the message. + * + *********************************************************************/ +crc +crcSlow(unsigned char const message[], int nBytes) +{ + crc remainder = INITIAL_REMAINDER; + int byte; + unsigned char bit; + + + /* + * Perform modulo-2 division, a byte at a time. + */ + for (byte = 0; byte < nBytes; ++byte) + { + /* + * Bring the next byte into the remainder. + */ + remainder ^= (REFLECT_DATA(message[byte]) << (WIDTH - 8)); + + /* + * Perform modulo-2 division, a bit at a time. + */ + for (bit = 8; bit > 0; --bit) + { + /* + * Try to divide the current data bit. + */ + if (remainder & TOPBIT) + { + remainder = (remainder << 1) ^ POLYNOMIAL; + } + else + { + remainder = (remainder << 1); + } + } + } + + /* + * The final remainder is the CRC result. + */ + return (REFLECT_REMAINDER(remainder) ^ FINAL_XOR_VALUE); + +} /* crcSlow() */ + + +crc crcTable[256]; + + +/********************************************************************* + * + * Function: crcInit() + * + * Description: Populate the partial CRC lookup table. + * + * Notes: This function must be rerun any time the CRC standard + * is changed. If desired, it can be run "offline" and + * the table results stored in an embedded system's ROM. + * + * Returns: None defined. + * + *********************************************************************/ +void +crcInit(void) +{ + crc remainder; + int dividend; + unsigned char bit; + + + /* + * Compute the remainder of each possible dividend. + */ + for (dividend = 0; dividend < 256; ++dividend) + { + /* + * Start with the dividend followed by zeros. + */ + remainder = dividend << (WIDTH - 8); + + /* + * Perform modulo-2 division, a bit at a time. + */ + for (bit = 8; bit > 0; --bit) + { + /* + * Try to divide the current data bit. + */ + if (remainder & TOPBIT) + { + remainder = (remainder << 1) ^ POLYNOMIAL; + } + else + { + remainder = (remainder << 1); + } + } + + /* + * Store the result into the table. + */ + crcTable[dividend] = remainder; + } + +} /* crcInit() */ + + +/********************************************************************* + * + * Function: crcFast() + * + * Description: Compute the CRC of a given message. + * + * Notes: crcInit() must be called first. + * + * Returns: The CRC of the message. + * + *********************************************************************/ +crc +crcFast(unsigned char const message[], int nBytes) +{ + crc remainder = INITIAL_REMAINDER; + unsigned char data; + int byte; + + + /* + * Divide the message by the polynomial, a byte at a time. + */ + for (byte = 0; byte < nBytes; ++byte) + { + data = REFLECT_DATA(message[byte]) ^ (remainder >> (WIDTH - 8)); + remainder = crcTable[data] ^ (remainder << 8); + } + + /* + * The final remainder is the CRC. + */ + return (REFLECT_REMAINDER(remainder) ^ FINAL_XOR_VALUE); + +} /* crcFast() */ + diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_SDT64B/crc.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_SDT64B/crc.h new file mode 100644 index 000000000000..fae66ae4bcc6 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_SDT64B/crc.h @@ -0,0 +1,77 @@ +/********************************************************************** + * + * Filename: crc.h + * + * Description: A header file describing the various CRC standards. + * + * Notes: + * + * + * Copyright (c) 2000 by Michael Barr. This software is placed into + * the public domain and may be used for any purpose. However, this + * notice must not be changed or removed and no warranty is either + * expressed or implied by its publication or distribution. + **********************************************************************/ + +#ifndef _crc_h +#define _crc_h + + +#define FALSE 0 +#define TRUE !FALSE + +/* + * Select the CRC standard from the list that follows. + */ +#define CRC16 + + +#if defined(CRC_CCITT) + +typedef unsigned short crc; + +#define CRC_NAME "CRC-CCITT" +#define POLYNOMIAL 0x1021 +#define INITIAL_REMAINDER 0xFFFF +#define FINAL_XOR_VALUE 0x0000 +#define REFLECT_DATA FALSE +#define REFLECT_REMAINDER FALSE +#define CHECK_VALUE 0x29B1 + +#elif defined(CRC16) + +typedef unsigned short crc; + +#define CRC_NAME "CRC-16" +#define POLYNOMIAL 0x8005 +#define INITIAL_REMAINDER 0x0000 +#define FINAL_XOR_VALUE 0x0000 +#define REFLECT_DATA TRUE +#define REFLECT_REMAINDER TRUE +#define CHECK_VALUE 0xBB3D + +#elif defined(CRC32) + +typedef unsigned long crc; + +#define CRC_NAME "CRC-32" +#define POLYNOMIAL 0x04C11DB7 +#define INITIAL_REMAINDER 0xFFFFFFFF +#define FINAL_XOR_VALUE 0xFFFFFFFF +#define REFLECT_DATA TRUE +#define REFLECT_REMAINDER TRUE +#define CHECK_VALUE 0xCBF43926 + +#else + +#error "One of CRC_CCITT, CRC16, or CRC32 must be #define'd." + +#endif + + +void crcInit(void); +crc crcSlow(unsigned char const message[], int nBytes); +crc crcFast(unsigned char const message[], int nBytes); + + +#endif /* _crc_h */ diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_SDT64B/device.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_SDT64B/device.h new file mode 100644 index 000000000000..29a4e7a0b189 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_SDT64B/device.h @@ -0,0 +1,39 @@ +// The 'features' section in 'target.json' is now used to create the device's hardware preprocessor switches. +// Check the 'features' section of the target description in 'targets.json' for more details. +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + + + + + + + + + + + +#define DEVICE_ID_LENGTH 24 + + + + + +#include "objects.h" + +#endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_SDT64B/fsl_clock_config.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_SDT64B/fsl_clock_config.c new file mode 100644 index 000000000000..9ceaef0a1aea --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_SDT64B/fsl_clock_config.c @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of Freescale Semiconductor, Inc. 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 "fsl_common.h" +#include "fsl_smc.h" +#include "fsl_clock_config.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! @brief Clock configuration structure. */ +typedef struct _clock_config +{ + mcg_config_t mcgConfig; /*!< MCG configuration. */ + sim_clock_config_t simConfig; /*!< SIM configuration. */ + osc_config_t oscConfig; /*!< OSC configuration. */ + uint32_t coreClock; /*!< core clock frequency. */ +} clock_config_t; + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* System clock frequency. */ +extern uint32_t SystemCoreClock; + +/* Configuration for enter VLPR mode. Core clock = 4MHz. */ +const clock_config_t g_defaultClockConfigVlpr = { + .mcgConfig = + { + .mcgMode = kMCG_ModeBLPI, /* Work in BLPI mode. */ + .irclkEnableMode = kMCG_IrclkEnable, /* MCGIRCLK enable. */ + .ircs = kMCG_IrcFast, /* Select IRC4M. */ + .fcrdiv = 0U, /* FCRDIV is 0. */ + + .frdiv = 0U, + .drs = kMCG_DrsLow, /* Low frequency range. */ + .dmx32 = kMCG_Dmx32Default, /* DCO has a default range of 25%. */ + .oscsel = kMCG_OscselOsc, /* Select OSC. */ + + .pll0Config = + { + .enableMode = 0U, /* Don't eanble PLL. */ + .prdiv = 0U, + .vdiv = 0U, + }, + }, + .simConfig = + { + .pllFllSel = 3U, /* PLLFLLSEL select IRC48MCLK. */ + .er32kSrc = 2U, /* ERCLK32K selection, use RTC. */ + .clkdiv1 = 0x00040000U, /* SIM_CLKDIV1. */ + }, + .oscConfig = {.freq = BOARD_XTAL0_CLK_HZ, + .capLoad = 0, + .workMode = kOSC_ModeExt, + .oscerConfig = + { + .enableMode = kOSC_ErClkEnable, +#if (defined(FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER) && FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER) + .erclkDiv = 0U, +#endif + }}, + .coreClock = 4000000U, /* Core clock frequency */ +}; + +/* Configuration for enter RUN mode. Core clock = 120MHz. */ +const clock_config_t g_defaultClockConfigRun = { + .mcgConfig = + { + .mcgMode = kMCG_ModePEE, /* Work in PEE mode. */ + .irclkEnableMode = kMCG_IrclkEnable, /* MCGIRCLK enable. */ + .ircs = kMCG_IrcSlow, /* Select IRC32k. */ + .fcrdiv = 0U, /* FCRDIV is 0. */ + + .frdiv = 7U, + .drs = kMCG_DrsLow, /* Low frequency range. */ + .dmx32 = kMCG_Dmx32Default, /* DCO has a default range of 25%. */ + .oscsel = kMCG_OscselOsc, /* Select OSC. */ + + .pll0Config = + { + .enableMode = 0U, .prdiv = 0x13U, .vdiv = 0x18U, + }, + }, + .simConfig = + { + .pllFllSel = 1U, /* PLLFLLSEL select PLL. */ + .er32kSrc = 2U, /* ERCLK32K selection, use RTC. */ + .clkdiv1 = 0x01140000U, /* SIM_CLKDIV1. */ + }, + .oscConfig = {.freq = BOARD_XTAL0_CLK_HZ, + .capLoad = 0, + .workMode = kOSC_ModeExt, + .oscerConfig = + { + .enableMode = kOSC_ErClkEnable, +#if (defined(FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER) && FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER) + .erclkDiv = 0U, +#endif + }}, + .coreClock = 120000000U, /* Core clock frequency */ +}; + +/******************************************************************************* + * Code + ******************************************************************************/ +/* + * How to setup clock using clock driver functions: + * + * 1. CLOCK_SetSimSafeDivs, to make sure core clock, bus clock, flexbus clock + * and flash clock are in allowed range during clock mode switch. + * + * 2. Call CLOCK_Osc0Init to setup OSC clock, if it is used in target mode. + * + * 3. Set MCG configuration, MCG includes three parts: FLL clock, PLL clock and + * internal reference clock(MCGIRCLK). Follow the steps to setup: + * + * 1). Call CLOCK_BootToXxxMode to set MCG to target mode. + * + * 2). If target mode is FBI/BLPI/PBI mode, the MCGIRCLK has been configured + * correctly. For other modes, need to call CLOCK_SetInternalRefClkConfig + * explicitly to setup MCGIRCLK. + * + * 3). Don't need to configure FLL explicitly, because if target mode is FLL + * mode, then FLL has been configured by the function CLOCK_BootToXxxMode, + * if the target mode is not FLL mode, the FLL is disabled. + * + * 4). If target mode is PEE/PBE/PEI/PBI mode, then the related PLL has been + * setup by CLOCK_BootToXxxMode. In FBE/FBI/FEE/FBE mode, the PLL could + * be enabled independently, call CLOCK_EnablePll0 explicitly in this case. + * + * 4. Call CLOCK_SetSimConfig to set the clock configuration in SIM. + */ + +void BOARD_BootClockVLPR(void) +{ + CLOCK_SetSimSafeDivs(); + + CLOCK_BootToBlpiMode(g_defaultClockConfigVlpr.mcgConfig.fcrdiv, g_defaultClockConfigVlpr.mcgConfig.ircs, + g_defaultClockConfigVlpr.mcgConfig.irclkEnableMode); + + CLOCK_SetSimConfig(&g_defaultClockConfigVlpr.simConfig); + + SystemCoreClock = g_defaultClockConfigVlpr.coreClock; + + SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); + SMC_SetPowerModeVlpr(SMC, false); + while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateVlpr) + { + } +} + +void BOARD_BootClockRUN(void) +{ + CLOCK_SetSimSafeDivs(); + + CLOCK_InitOsc0(&g_defaultClockConfigRun.oscConfig); + CLOCK_SetXtal0Freq(BOARD_XTAL0_CLK_HZ); + + CLOCK_BootToPeeMode(g_defaultClockConfigRun.mcgConfig.oscsel, kMCG_PllClkSelPll0, + &g_defaultClockConfigRun.mcgConfig.pll0Config); + + CLOCK_SetInternalRefClkConfig(g_defaultClockConfigRun.mcgConfig.irclkEnableMode, + g_defaultClockConfigRun.mcgConfig.ircs, g_defaultClockConfigRun.mcgConfig.fcrdiv); + + CLOCK_SetSimConfig(&g_defaultClockConfigRun.simConfig); + + SystemCoreClock = g_defaultClockConfigRun.coreClock; +} diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_SDT64B/fsl_clock_config.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_SDT64B/fsl_clock_config.h new file mode 100644 index 000000000000..050c3ab79b00 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_SDT64B/fsl_clock_config.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of Freescale Semiconductor, Inc. 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 _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +/******************************************************************************* + * DEFINITION + ******************************************************************************/ +#define BOARD_XTAL0_CLK_HZ 50000000U +#define BOARD_XTAL32K_CLK_HZ 32768U + +/******************************************************************************* + * API + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +void BOARD_BootClockVLPR(void); +void BOARD_BootClockRUN(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_SDT64B/fsl_phy.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_SDT64B/fsl_phy.c new file mode 100644 index 000000000000..7faf4e87c68f --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_SDT64B/fsl_phy.c @@ -0,0 +1,315 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder 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 "fsl_phy.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Defines the timeout macro. */ +#define PHY_TIMEOUT_COUNT 0xFFFFFU + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! + * @brief Get the ENET instance from peripheral base address. + * + * @param base ENET peripheral base address. + * @return ENET instance. + */ +extern uint32_t ENET_GetInstance(ENET_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Pointers to enet clocks for each instance. */ +extern clock_ip_name_t s_enetClock[FSL_FEATURE_SOC_ENET_COUNT]; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/******************************************************************************* + * Code + ******************************************************************************/ + +status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz) +{ + uint32_t counter = PHY_TIMEOUT_COUNT; + uint32_t idReg = 0; + status_t result = kStatus_Success; + uint32_t instance = ENET_GetInstance(base); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Set SMI first. */ + CLOCK_EnableClock(s_enetClock[instance]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + ENET_SetSMI(base, srcClock_Hz, false); + + /* Initialization after PHY stars to work. */ + while ((idReg != PHY_CONTROL_ID1) && (counter != 0)) + { + PHY_Read(base, phyAddr, PHY_ID1_REG, &idReg); + counter --; + } + + if (!counter) + { + return kStatus_Fail; + } + + /* Reset PHY. */ + result = PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, PHY_BCTL_RESET_MASK); + + return result; +} + +status_t PHY_AutoNegotiation(ENET_Type *base, uint32_t phyAddr) +{ + status_t result = kStatus_Success; + uint32_t bssReg; + uint32_t counter = PHY_TIMEOUT_COUNT; + + /* Set the negotiation. */ + result = PHY_Write(base, phyAddr, PHY_AUTONEG_ADVERTISE_REG, + (PHY_100BASETX_FULLDUPLEX_MASK | PHY_100BASETX_HALFDUPLEX_MASK | + PHY_10BASETX_FULLDUPLEX_MASK | PHY_10BASETX_HALFDUPLEX_MASK | 0x1U)); + if (result == kStatus_Success) + { + result = PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, + (PHY_BCTL_AUTONEG_MASK | PHY_BCTL_RESTART_AUTONEG_MASK)); + if (result == kStatus_Success) + { + /* Check auto negotiation complete. */ + while (counter --) + { + result = PHY_Read(base, phyAddr, PHY_BASICSTATUS_REG, &bssReg); + if ( result == kStatus_Success) + { + if ((bssReg & PHY_BSTATUS_AUTONEGCOMP_MASK) != 0) + { + break; + } + } + + if (!counter) + { + return kStatus_PHY_AutoNegotiateFail; + } + } + } + } + + return result; +} + +status_t PHY_Write(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t data) +{ + uint32_t counter; + + /* Clear the SMI interrupt event. */ + ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); + + /* Starts a SMI write command. */ + ENET_StartSMIWrite(base, phyAddr, phyReg, kENET_MiiWriteValidFrame, data); + + /* Wait for SMI complete. */ + for (counter = PHY_TIMEOUT_COUNT; counter > 0; counter--) + { + if (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK) + { + break; + } + } + + /* Check for timeout. */ + if (!counter) + { + return kStatus_PHY_SMIVisitTimeout; + } + + /* Clear MII interrupt event. */ + ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); + + return kStatus_Success; +} + +status_t PHY_Read(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t *dataPtr) +{ + assert(dataPtr); + + uint32_t counter; + + /* Clear the MII interrupt event. */ + ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); + + /* Starts a SMI read command operation. */ + ENET_StartSMIRead(base, phyAddr, phyReg, kENET_MiiReadValidFrame); + + /* Wait for MII complete. */ + for (counter = PHY_TIMEOUT_COUNT; counter > 0; counter--) + { + if (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK) + { + break; + } + } + + /* Check for timeout. */ + if (!counter) + { + return kStatus_PHY_SMIVisitTimeout; + } + + /* Get data from MII register. */ + *dataPtr = ENET_ReadSMIData(base); + + /* Clear MII interrupt event. */ + ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); + + return kStatus_Success; +} + +status_t PHY_EnableLoopback(ENET_Type *base, uint32_t phyAddr, phy_loop_t mode, bool enable) +{ + status_t result; + uint32_t data = 0; + + /* Set the loop mode. */ + if (enable) + { + if (mode == kPHY_LocalLoop) + { + /* First read the current status in control register. */ + result = PHY_Read(base, phyAddr, PHY_BASICCONTROL_REG, &data); + if (result == kStatus_Success) + { + return PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, (data | PHY_BCTL_LOOP_MASK)); + } + } + else + { + /* First read the current status in control register. */ + result = PHY_Read(base, phyAddr, PHY_CONTROL2_REG, &data); + if (result == kStatus_Success) + { + return PHY_Write(base, phyAddr, PHY_CONTROL2_REG, (data | PHY_CTL2_REMOTELOOP_MASK)); + } + } + } + else + { + /* Disable the loop mode. */ + if (mode == kPHY_LocalLoop) + { + /* First read the current status in the basic control register. */ + result = PHY_Read(base, phyAddr, PHY_BASICCONTROL_REG, &data); + if (result == kStatus_Success) + { + return PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, (data & ~PHY_BCTL_LOOP_MASK)); + } + } + else + { + /* First read the current status in control one register. */ + result = PHY_Read(base, phyAddr, PHY_CONTROL2_REG, &data); + if (result == kStatus_Success) + { + return PHY_Write(base, phyAddr, PHY_CONTROL2_REG, (data & ~PHY_CTL2_REMOTELOOP_MASK)); + } + } + } + return result; +} + +status_t PHY_GetLinkStatus(ENET_Type *base, uint32_t phyAddr, bool *status) +{ + assert(status); + + status_t result = kStatus_Success; + uint32_t data; + + /* Read the basic status register. */ + result = PHY_Read(base, phyAddr, PHY_BASICSTATUS_REG, &data); + if (result == kStatus_Success) + { + if (!(PHY_BSTATUS_LINKSTATUS_MASK & data)) + { + /* link down. */ + *status = false; + } + else + { + /* link up. */ + *status = true; + } + } + return result; +} + +status_t PHY_GetLinkSpeedDuplex(ENET_Type *base, uint32_t phyAddr, phy_speed_t *speed, phy_duplex_t *duplex) +{ + assert(duplex); + + status_t result = kStatus_Success; + uint32_t data, ctlReg; + + /* Read the control two register. */ + result = PHY_Read(base, phyAddr, PHY_CONTROL1_REG, &ctlReg); + if (result == kStatus_Success) + { + data = ctlReg & PHY_CTL1_SPEEDUPLX_MASK; + if ((PHY_CTL1_10FULLDUPLEX_MASK == data) || (PHY_CTL1_100FULLDUPLEX_MASK == data)) + { + /* Full duplex. */ + *duplex = kPHY_FullDuplex; + } + else + { + /* Half duplex. */ + *duplex = kPHY_HalfDuplex; + } + + data = ctlReg & PHY_CTL1_SPEEDUPLX_MASK; + if ((PHY_CTL1_100HALFDUPLEX_MASK == data) || (PHY_CTL1_100FULLDUPLEX_MASK == data)) + { + /* 100M speed. */ + *speed = kPHY_Speed100M; + } + else + { /* 10M speed. */ + *speed = kPHY_Speed10M; + } + } + + return result; +} diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_SDT64B/fsl_phy.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_SDT64B/fsl_phy.h new file mode 100644 index 000000000000..5512477d101c --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_SDT64B/fsl_phy.h @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of Freescale Semiconductor, Inc. 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 _FSL_PHY_H_ +#define _FSL_PHY_H_ + +#include "fsl_enet.h" + +/*! + * @addtogroup phy_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief PHY driver version */ +#define FSL_PHY_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */ + +/*! @brief Defines the PHY registers. */ +#define PHY_BASICCONTROL_REG 0x00U /*!< The PHY basic control register. */ +#define PHY_BASICSTATUS_REG 0x01U /*!< The PHY basic status register. */ +#define PHY_ID1_REG 0x02U /*!< The PHY ID one register. */ +#define PHY_ID2_REG 0x03U /*!< The PHY ID two register. */ +#define PHY_AUTONEG_ADVERTISE_REG 0x04U /*!< The PHY auto-negotiate advertise register. */ +#define PHY_CONTROL1_REG 0x1EU /*!< The PHY control one register. */ +#define PHY_CONTROL2_REG 0x1FU /*!< The PHY control two register. */ + +#define PHY_CONTROL_ID1 0x22U /*!< The PHY ID1*/ + +/*! @brief Defines the mask flag in basic control register. */ +#define PHY_BCTL_DUPLEX_MASK 0x0100U /*!< The PHY duplex bit mask. */ +#define PHY_BCTL_RESTART_AUTONEG_MASK 0x0200U /*!< The PHY restart auto negotiation mask. */ +#define PHY_BCTL_AUTONEG_MASK 0x1000U /*!< The PHY auto negotiation bit mask. */ +#define PHY_BCTL_SPEED_MASK 0x2000U /*!< The PHY speed bit mask. */ +#define PHY_BCTL_LOOP_MASK 0x4000U /*!< The PHY loop bit mask. */ +#define PHY_BCTL_RESET_MASK 0x8000U /*!< The PHY reset bit mask. */ + +/*!@brief Defines the mask flag of operation mode in control two register*/ +#define PHY_CTL2_REMOTELOOP_MASK 0x0004U /*!< The PHY remote loopback mask. */ +#define PHY_CTL1_10HALFDUPLEX_MASK 0x0001U /*!< The PHY 10M half duplex mask. */ +#define PHY_CTL1_100HALFDUPLEX_MASK 0x0002U /*!< The PHY 100M half duplex mask. */ +#define PHY_CTL1_10FULLDUPLEX_MASK 0x0005U /*!< The PHY 10M full duplex mask. */ +#define PHY_CTL1_100FULLDUPLEX_MASK 0x0006U /*!< The PHY 100M full duplex mask. */ +#define PHY_CTL1_SPEEDUPLX_MASK 0x0007U /*!< The PHY speed and duplex mask. */ + +/*! @brief Defines the mask flag in basic status register. */ +#define PHY_BSTATUS_LINKSTATUS_MASK 0x0004U /*!< The PHY link status mask. */ +#define PHY_BSTATUS_AUTONEGABLE_MASK 0x0008U /*!< The PHY auto-negotiation ability mask. */ +#define PHY_BSTATUS_AUTONEGCOMP_MASK 0x0020U /*!< The PHY auto-negotiation complete mask. */ + +/*! @brief Defines the mask flag in PHY auto-negotiation advertise register. */ +#define PHY_100BaseT4_ABILITY_MASK 0x200U /*!< The PHY have the T4 ability. */ +#define PHY_100BASETX_FULLDUPLEX_MASK 0x100U /*!< The PHY has the 100M full duplex ability.*/ +#define PHY_100BASETX_HALFDUPLEX_MASK 0x080U /*!< The PHY has the 100M full duplex ability.*/ +#define PHY_10BASETX_FULLDUPLEX_MASK 0x040U /*!< The PHY has the 10M full duplex ability.*/ +#define PHY_10BASETX_HALFDUPLEX_MASK 0x020U /*!< The PHY has the 10M full duplex ability.*/ + +/*! @brief Defines the PHY status. */ +enum _phy_status +{ + kStatus_PHY_SMIVisitTimeout = MAKE_STATUS(kStatusGroup_PHY, 1), /*!< ENET PHY SMI visit timeout. */ + kStatus_PHY_AutoNegotiateFail = MAKE_STATUS(kStatusGroup_PHY, 2) /*!< ENET PHY AutoNegotiate Fail. */ +}; + +/*! @brief Defines the PHY link speed. This is align with the speed for ENET MAC. */ +typedef enum _phy_speed +{ + kPHY_Speed10M = 0U, /*!< ENET PHY 10M speed. */ + kPHY_Speed100M /*!< ENET PHY 100M speed. */ +} phy_speed_t; + +/*! @brief Defines the PHY link duplex. */ +typedef enum _phy_duplex +{ + kPHY_HalfDuplex = 0U, /*!< ENET PHY half duplex. */ + kPHY_FullDuplex /*!< ENET PHY full duplex. */ +} phy_duplex_t; + +/*! @brief Defines the PHY loopback mode. */ +typedef enum _phy_loop +{ + kPHY_LocalLoop = 0U, /*!< ENET PHY local loopback. */ + kPHY_RemoteLoop /*!< ENET PHY remote loopback. */ +} phy_loop_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name PHY Driver + * @{ + */ + +/*! + * @brief Initializes PHY. + * + * This function initialize the SMI interface and initialize PHY. + * The SMI is the MII management interface between PHY and MAC, which should be + * firstly initialized before any other operation for PHY. + * + * @param base ENET peripheral base address. + * @param phyAddr The PHY address. + * @param srcClock_Hz The module clock frequency - system clock for MII management interface - SMI. + * @retval kStatus_Success PHY initialize success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz); + +/*! + * @brief Initiates auto negotiation. + * + * @param base ENET peripheral base address. + * @param phyAddr The PHY address. + * @retval kStatus_Success PHY auto negotiation success + * @retval kStatus_PHY_AutoNegotiateFail PHY auto negotiate fail + */ +status_t PHY_AutoNegotiation(ENET_Type *base, uint32_t phyAddr); + +/*! + * @brief PHY Write function. This function write data over the SMI to + * the specified PHY register. This function is called by all PHY interfaces. + * + * @param base ENET peripheral base address. + * @param phyAddr The PHY address. + * @param phyReg The PHY register. + * @param data The data written to the PHY register. + * @retval kStatus_Success PHY write success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_Write(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t data); + +/*! + * @brief PHY Read function. This interface read data over the SMI from the + * specified PHY register. This function is called by all PHY interfaces. + * + * @param base ENET peripheral base address. + * @param phyAddr The PHY address. + * @param phyReg The PHY register. + * @param dataPtr The address to store the data read from the PHY register. + * @retval kStatus_Success PHY read success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_Read(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t *dataPtr); + +/*! + * @brief Enables/disables PHY loopback. + * + * @param base ENET peripheral base address. + * @param phyAddr The PHY address. + * @param mode The loopback mode to be enabled, please see "phy_loop_t". + * the two loopback mode should not be both set. when one loopback mode is set + * the other one should be disabled. + * @param enable True to enable, false to disable. + * @retval kStatus_Success PHY loopback success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_EnableLoopback(ENET_Type *base, uint32_t phyAddr, phy_loop_t mode, bool enable); + +/*! + * @brief Gets the PHY link status. + * + * @param base ENET peripheral base address. + * @param phyAddr The PHY address. + * @param status The link up or down status of the PHY. + * - true the link is up. + * - false the link is down. + * @retval kStatus_Success PHY get link status success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_GetLinkStatus(ENET_Type *base, uint32_t phyAddr, bool *status); + +/*! + * @brief Gets the PHY link speed and duplex. + * + * @param base ENET peripheral base address. + * @param phyAddr The PHY address. + * @param speed The address of PHY link speed. + * @param duplex The link duplex of PHY. + * @retval kStatus_Success PHY get link speed and duplex success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_GetLinkSpeedDuplex(ENET_Type *base, uint32_t phyAddr, phy_speed_t *speed, phy_duplex_t *duplex); + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_PHY_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_SDT64B/mbed_overrides.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_SDT64B/mbed_overrides.c new file mode 100644 index 000000000000..3c62ed7ca4a4 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_SDT64B/mbed_overrides.c @@ -0,0 +1,80 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "gpio_api.h" + +#define CRC16 +#include "crc.h" +#include "fsl_clock_config.h" + +// called before main +void mbed_sdk_init() +{ + BOARD_BootClockRUN(); +} + +// Change the NMI pin to an input. This allows NMI pin to +// be used as a low power mode wakeup. The application will +// need to change the pin back to NMI_b or wakeup only occurs once! +void NMI_Handler(void) +{ + gpio_t gpio; + gpio_init_in(&gpio, PTA4); +} + +// Enable the RTC oscillator if available on the board +void rtc_setup_oscillator(RTC_Type *base) +{ + /* Enable the RTC oscillator */ + RTC->CR |= RTC_CR_OSCE_MASK; +} + +// Provide ethernet devices with a semi-unique MAC address from the UUID +void mbed_mac_address(char *mac) +{ + uint16_t MAC[3]; // 3 16 bits words for the MAC + + // get UID via SIM_UID macros defined in the K64F MCU CMSIS header file + uint32_t UID[4]; + UID[0] = SIM->UIDH; + UID[1] = SIM->UIDMH; + UID[2] = SIM->UIDML; + UID[3] = SIM->UIDL; + + // generate three CRC16's using different slices of the UUID + MAC[0] = crcSlow((const uint8_t *)UID, 8); // most significant half-word + MAC[1] = crcSlow((const uint8_t *)UID, 12); + MAC[2] = crcSlow((const uint8_t *)UID, 16); // least significant half word + + // The network stack expects an array of 6 bytes + // so we copy, and shift and copy from the half-word array to the byte array + mac[0] = MAC[0] >> 8; + mac[1] = MAC[0]; + mac[2] = MAC[1] >> 8; + mac[3] = MAC[1]; + mac[4] = MAC[2] >> 8; + mac[5] = MAC[2]; + + // We want to force bits [1:0] of the most significant byte [0] + // to be "10" + // http://en.wikipedia.org/wiki/MAC_address + + mac[0] |= 0x02; // force bit 1 to a "1" = "Locally Administered" + mac[0] &= 0xFE; // force bit 0 to a "0" = Unicast + +} + + + diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/pwmout_api.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/pwmout_api.c index eac2f8eda7a9..1ba19270b67c 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/pwmout_api.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/pwmout_api.c @@ -124,8 +124,25 @@ void pwmout_period_us(pwmout_t* obj, int us) FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT]; float dc = pwmout_read(obj); - // Stop FTM clock to ensure instant update of MOD register - base->MOD = FTM_MOD_MOD((pwm_clock_mhz * (float)us) - 1); + uint32_t pwm_base_clock; + uint32_t clkdiv = 0; + pwm_base_clock = CLOCK_GetFreq(kCLOCK_BusClk); + pwm_clock_mhz = (float) pwm_base_clock / 1000000.0f; + uint32_t mod = (pwm_clock_mhz * (float) us) - 1; + while (mod > 0xFFFF) { + ++clkdiv; + pwm_clock_mhz /= 2.0f; + mod = (pwm_clock_mhz * (float) us) - 1; + if (clkdiv == 7) { + break; + } + } + uint32_t SC = base->SC & ~FTM_SC_PS_MASK; + SC |= FTM_SC_PS((ftm_clock_prescale_t) clkdiv); + base->SC = SC; + + //Stop FTM clock to ensure instant update of MOD register + base->MOD = FTM_MOD_MOD(mod); pwmout_write(obj, dc); } diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/us_ticker.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/us_ticker.c index 1666223e1074..bc753d2ff34b 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/us_ticker.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/us_ticker.c @@ -70,6 +70,7 @@ void us_ticker_init(void) PIT_StopTimer(PIT, kPIT_Chnl_2); PIT_SetTimerPeriod(PIT, kPIT_Chnl_2, busClock / 1000000 - 1); PIT_SetTimerChainMode(PIT, kPIT_Chnl_3, true); + PIT_ClearStatusFlags(PIT, kPIT_Chnl_3, PIT_TFLG_TIF_MASK); NVIC_SetVector(PIT3_IRQn, (uint32_t) pit_isr); NVIC_EnableIRQ(PIT3_IRQn); PIT_DisableInterrupts(PIT, kPIT_Chnl_3, kPIT_TimerInterruptEnable); @@ -136,3 +137,16 @@ void us_ticker_fire_interrupt(void) { NVIC_SetPendingIRQ(PIT3_IRQn); } + +void us_ticker_free(void) +{ + PIT_StartTimer(PIT, kPIT_Chnl_3); + PIT_StartTimer(PIT, kPIT_Chnl_2); + PIT_StartTimer(PIT, kPIT_Chnl_1); + PIT_StartTimer(PIT, kPIT_Chnl_0); + + PIT_DisableInterrupts(PIT, kPIT_Chnl_3, kPIT_TimerInterruptEnable); + NVIC_DisableIRQ(PIT3_IRQn); + + us_ticker_inited = false; +} diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/api/lp_ticker.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/api/lp_ticker.c index 9d493eac7c93..9f836db8d54a 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/api/lp_ticker.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/api/lp_ticker.c @@ -69,6 +69,7 @@ void lp_ticker_init(void) lp_ticker_inited = true; } else { LPTMR_DisableInterrupts(LPTMR0, kLPTMR_TimerInterruptEnable); + NVIC_EnableIRQ(LPTMR0_IRQn); } } @@ -117,4 +118,12 @@ void lp_ticker_clear_interrupt(void) LPTMR_ClearStatusFlags(LPTMR0, kLPTMR_TimerCompareFlag); } +void lp_ticker_free(void) +{ +#ifndef FEATURE_UVISOR + LPTMR_DisableInterrupts(LPTMR0, kLPTMR_TimerInterruptEnable); + NVIC_DisableIRQ(LPTMR0_IRQn); +#endif +} + #endif /* DEVICE_LPTICKER */ diff --git a/targets/TARGET_Freescale/mbed_rtx.h b/targets/TARGET_Freescale/mbed_rtx.h index 3602d0436f51..507c042e2e34 100644 --- a/targets/TARGET_Freescale/mbed_rtx.h +++ b/targets/TARGET_Freescale/mbed_rtx.h @@ -89,6 +89,12 @@ #define INITIAL_SP (0x20030000UL) #endif +#elif defined(TARGET_SDT64B) + +#ifndef INITIAL_SP +#define INITIAL_SP (0x20030000UL) +#endif + #elif defined(TARGET_KW24D) #ifndef INITIAL_SP diff --git a/targets/TARGET_Maxim/TARGET_MAX32600/rtc_api.c b/targets/TARGET_Maxim/TARGET_MAX32600/rtc_api.c index 981a1b64cdb9..ad0d4b85dc09 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32600/rtc_api.c +++ b/targets/TARGET_Maxim/TARGET_MAX32600/rtc_api.c @@ -255,3 +255,8 @@ uint32_t lp_ticker_read(void) { return rtc_read64(); } + +void lp_ticker_free(void) +{ + +} diff --git a/targets/TARGET_Maxim/TARGET_MAX32600/us_ticker.c b/targets/TARGET_Maxim/TARGET_MAX32600/us_ticker.c index 46acd8213819..dfea1a050ef1 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32600/us_ticker.c +++ b/targets/TARGET_Maxim/TARGET_MAX32600/us_ticker.c @@ -268,3 +268,8 @@ void us_ticker_set(timestamp_t timestamp) NVIC_SetPendingIRQ(US_TIMER_IRQn); } } + +void us_ticker_free(void) +{ + +} diff --git a/targets/TARGET_Maxim/TARGET_MAX32610/rtc_api.c b/targets/TARGET_Maxim/TARGET_MAX32610/rtc_api.c index 67bd74ce3c04..1a083349c2c7 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32610/rtc_api.c +++ b/targets/TARGET_Maxim/TARGET_MAX32610/rtc_api.c @@ -252,3 +252,8 @@ inline uint32_t lp_ticker_read(void) { return rtc_read64(); } + +void lp_ticker_free(void) +{ + +} diff --git a/targets/TARGET_Maxim/TARGET_MAX32610/us_ticker.c b/targets/TARGET_Maxim/TARGET_MAX32610/us_ticker.c index 97257af3fbdb..668c150bb591 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32610/us_ticker.c +++ b/targets/TARGET_Maxim/TARGET_MAX32610/us_ticker.c @@ -268,3 +268,8 @@ void us_ticker_set(timestamp_t timestamp) NVIC_SetPendingIRQ(US_TIMER_IRQn); } } + +void us_ticker_free(void) +{ + +} diff --git a/targets/TARGET_Maxim/TARGET_MAX32620/rtc_api.c b/targets/TARGET_Maxim/TARGET_MAX32620/rtc_api.c index d4e15e567c45..e6aa21468787 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32620/rtc_api.c +++ b/targets/TARGET_Maxim/TARGET_MAX32620/rtc_api.c @@ -306,3 +306,8 @@ inline uint32_t lp_ticker_read(void) { return rtc_read64(); } + +void lp_ticker_free(void) +{ + +} diff --git a/targets/TARGET_Maxim/TARGET_MAX32620/us_ticker.c b/targets/TARGET_Maxim/TARGET_MAX32620/us_ticker.c index 2762e2e14af3..6047576e29c4 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32620/us_ticker.c +++ b/targets/TARGET_Maxim/TARGET_MAX32620/us_ticker.c @@ -299,3 +299,8 @@ void us_ticker_set(timestamp_t timestamp) NVIC_SetPendingIRQ(US_TIMER_IRQn); } } + +void us_ticker_free(void) +{ + +} diff --git a/targets/TARGET_Maxim/TARGET_MAX32620C/TARGET_SDT32620B/PeripheralNames.h b/targets/TARGET_Maxim/TARGET_MAX32620C/TARGET_SDT32620B/PeripheralNames.h new file mode 100644 index 000000000000..9d4d4a687b07 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32620C/TARGET_SDT32620B/PeripheralNames.h @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * 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 MAXIM INTEGRATED 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. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + UART_0 = MXC_BASE_UART0, + UART_1 = MXC_BASE_UART1, + UART_2 = MXC_BASE_UART2, + UART_3 = MXC_BASE_UART3, + STDIO_UART = UART_1 +} UARTName; + +typedef enum { + I2C_0 = MXC_BASE_I2CM0, + I2C_1 = MXC_BASE_I2CM1, + I2C_2 = MXC_BASE_I2CM2 +} I2CName; + +typedef enum { + SPI_0 = MXC_BASE_SPIM0, + SPI_1 = MXC_BASE_SPIM1, + SPI_2 = MXC_BASE_SPIM2 +} SPIName; + +typedef enum { + PWM_0 = MXC_BASE_PT0, + PWM_1 = MXC_BASE_PT1, + PWM_2 = MXC_BASE_PT2, + PWM_3 = MXC_BASE_PT3, + PWM_4 = MXC_BASE_PT4, + PWM_5 = MXC_BASE_PT5, + PWM_6 = MXC_BASE_PT6, + PWM_7 = MXC_BASE_PT7, + PWM_8 = MXC_BASE_PT8, + PWM_9 = MXC_BASE_PT9, + PWM_10 = MXC_BASE_PT10, + PWM_11 = MXC_BASE_PT11, + PWM_12 = MXC_BASE_PT12, + PWM_13 = MXC_BASE_PT13, + PWM_14 = MXC_BASE_PT14, + PWM_15 = MXC_BASE_PT15 +} PWMName; + +typedef enum { + ADC = MXC_BASE_ADC +} ADCName; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_Maxim/TARGET_MAX32620C/TARGET_SDT32620B/PinNames.h b/targets/TARGET_Maxim/TARGET_MAX32620C/TARGET_SDT32620B/PinNames.h new file mode 100644 index 000000000000..94884dd909f2 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32620C/TARGET_SDT32620B/PinNames.h @@ -0,0 +1,198 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * 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 MAXIM INTEGRATED 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. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" +#include "gpio_regs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT = MXC_V_GPIO_OUT_MODE_NORMAL_HIGH_Z, + PIN_OUTPUT = MXC_V_GPIO_OUT_MODE_NORMAL +} PinDirection; + +#define PORT_SHIFT 12 +#define PINNAME_TO_PORT(name) ((unsigned int)(name) >> PORT_SHIFT) +#define PINNAME_TO_PIN(name) ((unsigned int)(name) & ~(0xFFFFFFFF << PORT_SHIFT)) + +#define NOT_CONNECTED (int)0xFFFFFFFF + +typedef enum { + P0_0 = (0 << PORT_SHIFT), P0_1, P0_2, P0_3, P0_4, P0_5, P0_6, P0_7, + P1_0 = (1 << PORT_SHIFT), P1_1, P1_2, P1_3, P1_4, P1_5, P1_6, P1_7, + P2_0 = (2 << PORT_SHIFT), P2_1, P2_2, P2_3, P2_4, P2_5, P2_6, P2_7, + P3_0 = (3 << PORT_SHIFT), P3_1, P3_2, P3_3, P3_4, P3_5, P3_6, P3_7, + P4_0 = (4 << PORT_SHIFT), P4_1, P4_2, P4_3, P4_4, P4_5, P4_6, P4_7, + P5_0 = (5 << PORT_SHIFT), P5_1, P5_2, P5_3, P5_4, P5_5, P5_6, P5_7, + P6_0 = (6 << PORT_SHIFT), + + // Analog input pins + AIN_0 = (0xA << PORT_SHIFT), AIN_1, AIN_2, AIN_3, AIN_4, AIN_5, AIN_6, AIN_7, AIN_8, AIN_9, AIN_10, AIN_11, + + // Analog + A0 = AIN_0, + A1 = AIN_1, + A2 = AIN_2, + A3 = AIN_3, + + // General Pin Input Output (GPIO) + GPIO0 = P1_4, + GPIO1 = P1_5, + GPIO2 = P4_0, + GPIO3 = P4_1, + GPIO4 = P4_2, + GPIO5 = P4_3, + GPIO6 = P5_6, + + //Purse Width Modulation (PWM) + PWM0 = GPIO2, + PWM1 = GPIO3, + PWM2 = GPIO0, + PWM3 = GPIO1, + + // LEDs + LED0 = GPIO0, + LED1 = GPIO1, + LED2 = GPIO2, + LED3 = NOT_CONNECTED, + LED4 = NOT_CONNECTED, + + LED_RED = LED0, + LED_GREEN = LED1, + LED_BLUE = LED2, + + // USB bridge and SWD UART connected UART pins + USBTX = P2_1, + USBRX = P2_0, + STDIO_UART_TX = USBTX, + STDIO_UART_RX = USBRX, + + // UART pins + UART0_RX = P0_0, + UART0_TX = P0_1, + UART0_CTS = P0_2, + UART0_RTS = P0_3, + + UART1_RX = P2_0, + UART1_TX = P2_1, + UART1_CTS = P2_2, + UART1_RTS = P2_3, + + UART2_RX = P3_0, + UART2_TX = P3_1, + UART2_CTS = P3_2, + UART2_RTS = P3_3, + + // I2C pins + I2C0_SCL = P1_7, + I2C0_SDA = P1_6, + + I2C1_SCL = P3_5, + I2C1_SDA = P3_4, + + I2C2_SCL = P6_0, + I2C2_SDA = P5_7, + + // SPI pins + SPI0_SCK = P0_4, + SPI0_MOSI = P0_5, + SPI0_MISO = P0_6, + SPI0_SS0 = P0_7, + SPI0_SS1 = P4_4, + SPI0_SS2 = P4_5, + + SPI1_SCK = P1_0, + SPI1_MOSI = P1_1, + SPI1_MISO = P1_2, + SPI1_SS0 = P1_3, + SPI1_SS1 = P3_6, + SPI1_SS2 = P3_7, + + SPI2_SCK = P2_4, + SPI2_MOSI = P2_5, + SPI2_MISO = P2_6, + SPI2_SS0 = P2_7, + SPI2_SS1 = P4_6, + SPI2_SS2 = P4_7, + + SPI3_SCK = P5_0, + SPI3_MOSI = P5_1, + SPI3_MISO = P5_2, + SPI3_SS0 = P5_3, + SPI3_SS1 = P5_4, + SPI3_SS2 = P5_5, + + // SWD UART + SWD_TGT_TX = UART1_TX, + SWD_TGT_RX = UART1_RX, + SWD_TGT_CTS = UART1_CTS, + SWD_TGT_RTS = UART1_RTS, + + // Generics + SERIAL_TX = UART0_TX, + SERIAL_RX = UART0_RX, + I2C_SCL = I2C0_SCL, + I2C_SDA = I2C0_SDA, + SPI_MOSI = SPI0_MOSI, + SPI_MISO = SPI0_MISO, + SPI_SCK = SPI0_SCK, + SPI_CS = SPI0_SS0, + PWM_OUT = PWM0, + + // Not connected + NC = NOT_CONNECTED +} PinName; + +typedef enum { + PullUp, + PullDown, + OpenDrain, + PullNone, + PullDefault = PullUp +} PinMode; + +typedef enum { + LED_ON = 0, + LED_OFF = 1 +} LedStates; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/TARGET_MAX32625PICO_BASE/PeripheralNames.h b/targets/TARGET_Maxim/TARGET_MAX32625/TARGET_MAX32625PICO/PeripheralNames.h similarity index 100% rename from targets/TARGET_Maxim/TARGET_MAX32625/TARGET_MAX32625PICO_BASE/PeripheralNames.h rename to targets/TARGET_Maxim/TARGET_MAX32625/TARGET_MAX32625PICO/PeripheralNames.h diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/TARGET_MAX32625PICO_BASE/PinNames.h b/targets/TARGET_Maxim/TARGET_MAX32625/TARGET_MAX32625PICO/PinNames.h similarity index 100% rename from targets/TARGET_Maxim/TARGET_MAX32625/TARGET_MAX32625PICO_BASE/PinNames.h rename to targets/TARGET_Maxim/TARGET_MAX32625/TARGET_MAX32625PICO/PinNames.h diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/TARGET_MAX32625PICO_BASE/low_level_init.c b/targets/TARGET_Maxim/TARGET_MAX32625/TARGET_MAX32625PICO/low_level_init.c similarity index 100% rename from targets/TARGET_Maxim/TARGET_MAX32625/TARGET_MAX32625PICO_BASE/low_level_init.c rename to targets/TARGET_Maxim/TARGET_MAX32625/TARGET_MAX32625PICO/low_level_init.c diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/TARGET_SDT32625B/PeripheralNames.h b/targets/TARGET_Maxim/TARGET_MAX32625/TARGET_SDT32625B/PeripheralNames.h new file mode 100644 index 000000000000..4686ef9c91f8 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/TARGET_SDT32625B/PeripheralNames.h @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * 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 MAXIM INTEGRATED 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. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + UART_0 = MXC_BASE_UART0, + UART_1 = MXC_BASE_UART1, + UART_2 = MXC_BASE_UART2, + STDIO_UART = UART_1 +} UARTName; + +typedef enum { + I2C_0 = MXC_BASE_I2CM0, + I2C_1 = MXC_BASE_I2CM1 +} I2CName; + +typedef enum { + SPI_0 = MXC_BASE_SPIM0, + SPI_1 = MXC_BASE_SPIM1, + SPI_2 = MXC_BASE_SPIM2 +} SPIName; + +typedef enum { + PWM_0 = MXC_BASE_PT0, + PWM_1 = MXC_BASE_PT1, + PWM_2 = MXC_BASE_PT2, + PWM_3 = MXC_BASE_PT3, + PWM_4 = MXC_BASE_PT4, + PWM_5 = MXC_BASE_PT5, + PWM_6 = MXC_BASE_PT6, + PWM_7 = MXC_BASE_PT7, + PWM_8 = MXC_BASE_PT8, + PWM_9 = MXC_BASE_PT9, + PWM_10 = MXC_BASE_PT10, + PWM_11 = MXC_BASE_PT11, + PWM_12 = MXC_BASE_PT12, + PWM_13 = MXC_BASE_PT13, + PWM_14 = MXC_BASE_PT14, + PWM_15 = MXC_BASE_PT15 +} PWMName; + +typedef enum { + ADC = MXC_BASE_ADC +} ADCName; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/TARGET_SDT32625B/PinNames.h b/targets/TARGET_Maxim/TARGET_MAX32625/TARGET_SDT32625B/PinNames.h new file mode 100644 index 000000000000..8183adb46959 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/TARGET_SDT32625B/PinNames.h @@ -0,0 +1,196 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * 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 MAXIM INTEGRATED 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. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" +#include "gpio_regs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT = 0, /* MXC_V_GPIO_OUT_MODE_HIGH_Z,*/ + PIN_OUTPUT = 1 /* MXC_V_GPIO_OUT_MODE_NORMAL_DRIVE */ +} PinDirection; + +#define PORT_SHIFT 12 +#define PINNAME_TO_PORT(name) ((unsigned int)(name) >> PORT_SHIFT) +#define PINNAME_TO_PIN(name) ((unsigned int)(name) & ~(0xFFFFFFFF << PORT_SHIFT)) + +#define NOT_CONNECTED (int)0xFFFFFFFF + +typedef enum { + P0_0 = (0 << PORT_SHIFT), P0_1, P0_2, P0_3, P0_4, P0_5, P0_6, P0_7, + P1_0 = (1 << PORT_SHIFT), P1_1, P1_2, P1_3, P1_4, P1_5, P1_6, P1_7, + P2_0 = (2 << PORT_SHIFT), P2_1, P2_2, P2_3, P2_4, P2_5, P2_6, P2_7, + P3_0 = (3 << PORT_SHIFT), P3_1, P3_2, P3_3, P3_4, P3_5, P3_6, P3_7, + P4_0 = (4 << PORT_SHIFT), P4_1, P4_2, P4_3, P4_4, P4_5, P4_6, P4_7, + + // Analog input pins + AIN_0 = (0xA << PORT_SHIFT), AIN_1, AIN_2, AIN_3, AIN_4, AIN_5, AIN_6, AIN_7, AIN_8, AIN_9, + + // Analog + A0 = AIN_0, + A1 = AIN_1, + A2 = AIN_2, + A3 = AIN_3, + + // General Pin Input Output (GPIO) + GPIO0 = P1_4, + GPIO1 = P1_5, + GPIO2 = P4_0, + GPIO3 = P4_1, + GPIO4 = P4_2, + GPIO5 = P4_3, + GPIO6 = NOT_CONNECTED, + + //Purse Width Modulation (PWM) + PWM0 = GPIO2, + PWM1 = GPIO3, + PWM2 = GPIO0, + PWM3 = GPIO1, + + // LEDs + LED0 = GPIO0, + LED1 = GPIO1, + LED2 = GPIO2, + LED3 = NOT_CONNECTED, + LED4 = NOT_CONNECTED, + + LED_RED = LED0, + LED_GREEN = LED1, + LED_BLUE = LED2, + + // USB bridge and SWD UART connected UART pins + USBTX = P2_1, + USBRX = P2_0, + STDIO_UART_TX = USBTX, + STDIO_UART_RX = USBRX, + + // UART pins + UART0_RX = P0_0, + UART0_TX = P0_1, + UART0_CTS = P0_2, + UART0_RTS = P0_3, + + UART1_RX = P2_0, + UART1_TX = P2_1, + UART1_CTS = P2_2, + UART1_RTS = P2_3, + + UART2_RX = P3_0, + UART2_TX = P3_1, + UART2_CTS = P3_2, + UART2_RTS = P3_3, + + // I2C pins + I2C0_SCL = P1_7, + I2C0_SDA = P1_6, + + I2C1_SCL = P3_5, + I2C1_SDA = P3_4, + + I2C2_SCL = NOT_CONNECTED, + I2C2_SDA = NOT_CONNECTED, + + // SPI pins + SPI0_SCK = P0_4, + SPI0_MOSI = P0_5, + SPI0_MISO = P0_6, + SPI0_SS0 = P0_7, + SPI0_SS1 = P4_4, + SPI0_SS2 = P4_5, + + SPI1_SCK = P1_0, + SPI1_MOSI = P1_1, + SPI1_MISO = P1_2, + SPI1_SS0 = P1_3, + SPI1_SS1 = P3_6, + SPI1_SS2 = P3_7, + + SPI2_SCK = P2_4, + SPI2_MOSI = P2_5, + SPI2_MISO = P2_6, + SPI2_SS0 = P2_7, + SPI2_SS1 = P4_6, + SPI2_SS2 = P4_7, + + SPI3_SCK = NOT_CONNECTED, + SPI3_MOSI = NOT_CONNECTED, + SPI3_MISO = NOT_CONNECTED, + SPI3_SS0 = NOT_CONNECTED, + SPI3_SS1 = NOT_CONNECTED, + SPI3_SS2 = NOT_CONNECTED, + + // SWD UART + SWD_TGT_TX = UART1_TX, + SWD_TGT_RX = UART1_RX, + SWD_TGT_CTS = UART1_CTS, + SWD_TGT_RTS = UART1_RTS, + + // Generics + SERIAL_TX = UART0_TX, + SERIAL_RX = UART0_RX, + I2C_SCL = I2C0_SCL, + I2C_SDA = I2C0_SDA, + SPI_MOSI = SPI0_MOSI, + SPI_MISO = SPI0_MISO, + SPI_SCK = SPI0_SCK, + SPI_CS = SPI0_SS0, + PWM_OUT = PWM0, + + // Not connected + NC = NOT_CONNECTED +} PinName; + +typedef enum { + PullUp, + PullDown, + OpenDrain, + PullNone, + PullDefault = PullUp +} PinMode; + +typedef enum { + LED_ON = 0, + LED_OFF = 1 +} LedStates; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_ARM_STD/TARGET_MAX32625_BOOT/MAX32625.sct b/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_ARM_STD/TARGET_MAX32625_BOOT/MAX32625.sct index 9d1329923bc2..83525ba4fe28 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_ARM_STD/TARGET_MAX32625_BOOT/MAX32625.sct +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_ARM_STD/TARGET_MAX32625_BOOT/MAX32625.sct @@ -1,9 +1,18 @@ +#! armcc -E ; MAX32625 ; 512KB FLASH (0x80000) @ 0x000000000 ; 160KB RAM (0x28000) @ 0x20000000 -LR_IROM1 0x000010000 0x70000 { ; load region size_region - ER_IROM1 0x000010000 0x70000 { ; load address = execution address +#if !defined(MBED_APP_START) + #define MBED_APP_START 0x00010000 +#endif + +#if !defined(MBED_APP_SIZE) + #define MBED_APP_SIZE 0x00070000 +#endif + +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_Maxim/TARGET_MAX32625/device/TOOLCHAIN_GCC_ARM/TARGET_MAX32625_BOOT/max32625.ld b/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_GCC_ARM/TARGET_MAX32625_BOOT/max32625.ld index f9d978a8e8b6..dee71737a85e 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_GCC_ARM/TARGET_MAX32625_BOOT/max32625.ld +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_GCC_ARM/TARGET_MAX32625_BOOT/max32625.ld @@ -31,9 +31,17 @@ ******************************************************************************* */ +#if !defined(MBED_APP_START) + #define MBED_APP_START 0x00010000 +#endif + +#if !defined(MBED_APP_SIZE) + #define MBED_APP_SIZE 0x00070000 +#endif + MEMORY { - FLASH (rx) : ORIGIN = 0x00010000, LENGTH = 0x00070000 + FLASH (rx) : ORIGIN = MBED_APP_START, LENGTH = MBED_APP_SIZE RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00028000 } diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_IAR/TARGET_MAX32625_BOOT/MAX32625.icf b/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_IAR/TARGET_MAX32625_BOOT/MAX32625.icf index 622cf2839d79..716245bf71b1 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_IAR/TARGET_MAX32625_BOOT/MAX32625.icf +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/TOOLCHAIN_IAR/TARGET_MAX32625_BOOT/MAX32625.icf @@ -1,7 +1,14 @@ +if (!isdefinedsymbol(MBED_APP_START)) { + define symbol MBED_APP_START = 0x00010000; +} +if (!isdefinedsymbol(MBED_APP_SIZE)) { + define symbol MBED_APP_SIZE = 0x00070000; +} + /* [ROM] */ -define symbol __intvec_start__ = 0x00010000; -define symbol __region_ROM_start__ = 0x00010000; -define symbol __region_ROM_end__ = 0x0007FFFF; +define symbol __intvec_start__ = MBED_APP_START; +define symbol __region_ROM_start__ = MBED_APP_START; +define symbol __region_ROM_end__ = MBED_APP_START + MBED_APP_SIZE - 1; /* [RAM] Vector table dynamic copy: 68 vectors * 4 bytes = 272 (0x110) bytes */ define symbol __NVIC_start__ = 0x00010000; diff --git a/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/us_ticker.c b/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/us_ticker.c index 45dab1a706fa..da10954257da 100644 --- a/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/us_ticker.c +++ b/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/us_ticker.c @@ -318,6 +318,11 @@ void us_ticker_clear_interrupt(void) NRF_RTC1->EVENTS_COMPARE[0] = 0; } +void us_ticker_free(void) +{ + +} + #if defined (__CC_ARM) /* ARMCC Compiler */ diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF51/TARGET_MCU_NRF51822_UNIFIED/TARGET_SDT51822B/PinNames.h b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF51/TARGET_MCU_NRF51822_UNIFIED/TARGET_SDT51822B/PinNames.h new file mode 100644 index 000000000000..46005eaf5268 --- /dev/null +++ b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF51/TARGET_MCU_NRF51822_UNIFIED/TARGET_SDT51822B/PinNames.h @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2013 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. + * + */ + +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define NOT_CONNECTED (int)0xFFFFFFFF +#define PORT_SHIFT 3 + +typedef enum { + p0 = 0, + p1 = 1, + p2 = 2, + p3 = 3, + p4 = 4, + p5 = 5, + p6 = 6, + p7 = 7, + p8 = 8, + p9 = 9, + p10 = 10, + p11 = 11, + p12 = 12, + p13 = 13, + p14 = 14, + p15 = 15, + p16 = 16, + p17 = 17, + p18 = 18, + p19 = 19, + p20 = 20, + p21 = 21, + p22 = 22, + p23 = 23, + p24 = 24, + p25 = 25, + p26 = 26, + p27 = 27, + p28 = 28, + p29 = 29, + p30 = 30, + + P0_0 = p0, + P0_1 = p1, + P0_2 = p2, + P0_3 = p3, + P0_4 = p4, + P0_5 = p5, + P0_6 = p6, + P0_7 = p7, + + P0_8 = p8, + P0_9 = p9, + P0_10 = p10, + P0_11 = p11, + P0_12 = p12, + P0_13 = p13, + P0_14 = p14, + P0_15 = p15, + + P0_16 = p16, + P0_17 = p17, + P0_18 = p18, + P0_19 = p19, + P0_20 = p20, + P0_21 = p21, + P0_22 = p22, + P0_23 = p23, + + P0_24 = p24, + P0_25 = p25, + P0_26 = p26, + P0_27 = p27, + P0_28 = p28, + P0_29 = p29, + P0_30 = p30, + + // Analog + A0 = P0_1, + A1 = P0_2, + A2 = P0_3, + A3 = P0_4, + + // General Pin Input Output (GPIO) + GPIO0 = P0_5, + GPIO1 = P0_7, + GPIO2 = P0_12, + GPIO3 = NOT_CONNECTED, + GPIO4 = NOT_CONNECTED, + GPIO5 = NOT_CONNECTED, + GPIO6 = NOT_CONNECTED, + + //Purse Width Modulation (PWM) + PWM0 = GPIO2, + PWM1 = GPIO3, + PWM2 = GPIO0, + PWM3 = GPIO1, + + // LEDs + LED0 = GPIO0, + LED1 = GPIO1, + LED2 = GPIO2, + + LED_RED = LED0, + LED_GREEN = LED1, + LED_BLUE = LED2, + + // USB bridge and SWD UART connected UART pins + USBTX = P0_9, + USBRX = P0_11, + + // UART pins + UART0_RX = NOT_CONNECTED, + UART0_TX = NOT_CONNECTED, + UART0_CTS = NOT_CONNECTED, + UART0_RTS = NOT_CONNECTED, + + UART1_RX = P0_11, + UART1_TX = P0_9, + UART1_CTS = P0_10, + UART1_RTS = P0_8, + + RX_PIN_NUMBER = p11, + TX_PIN_NUMBER = p9, + CTS_PIN_NUMBER = p10, + RTS_PIN_NUMBER = p8, + + + UART2_RX = NOT_CONNECTED, + UART2_TX = NOT_CONNECTED, + UART2_CTS = NOT_CONNECTED, + UART2_RTS = NOT_CONNECTED, + + // I2C pins + I2C0_SCL = P0_20, + I2C0_SDA = P0_19, + + I2C1_SCL = P0_30, + I2C1_SDA = P0_29, + + I2C2_SCL = NOT_CONNECTED, + I2C2_SDA = NOT_CONNECTED, + + // SPI pins + SPI0_SCK = P0_18, + SPI0_MOSI = P0_15, + SPI0_MISO = P0_16, + SPI0_SS0 = P0_17, + SPI0_SS1 = P0_14, + SPI0_SS2 = P0_13, + + SPI1_SCK = P0_25, + SPI1_MOSI = P0_23, + SPI1_MISO = P0_24, + SPI1_SS0 = P0_22, + SPI1_SS1 = P0_21, + SPI1_SS2 = P0_28, + + SPI2_SCK = NOT_CONNECTED, + SPI2_MOSI = NOT_CONNECTED, + SPI2_MISO = NOT_CONNECTED, + SPI2_SS0 = NOT_CONNECTED, + SPI2_SS1 = NOT_CONNECTED, + SPI2_SS2 = NOT_CONNECTED, + + SPI3_SCK = NOT_CONNECTED, + SPI3_MOSI = NOT_CONNECTED, + SPI3_MISO = NOT_CONNECTED, + SPI3_SS0 = NOT_CONNECTED, + SPI3_SS1 = NOT_CONNECTED, + SPI3_SS2 = NOT_CONNECTED, + + // SWD UART + SWD_TGT_TX = UART1_TX, + SWD_TGT_RX = UART1_RX, + SWD_TGT_CTS = UART1_CTS, + SWD_TGT_RTS = UART1_RTS, + + // Generics + SERIAL_TX = UART1_TX, + SERIAL_RX = UART1_RX, + I2C_SCL = I2C0_SCL, + I2C_SDA = I2C0_SDA, + SPI_MOSI = SPI0_MOSI, + SPI_MISO = SPI0_MISO, + SPI_SCK = SPI0_SCK, + SPI_CS = SPI0_SS0, + PWM_OUT = PWM0, + + // Not connected + NC = NOT_CONNECTED +} PinName; + +typedef enum { + PullNone = 0, + PullDown = 1, + PullUp = 3, + PullDefault = PullUp +} PinMode; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF51/TARGET_MCU_NRF51822_UNIFIED/TARGET_SDT51822B/device.h b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF51/TARGET_MCU_NRF51822_UNIFIED/TARGET_SDT51822B/device.h new file mode 100644 index 000000000000..2427e752ea99 --- /dev/null +++ b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF51/TARGET_MCU_NRF51822_UNIFIED/TARGET_SDT51822B/device.h @@ -0,0 +1,38 @@ +// The 'features' section in 'target.json' is now used to create the device's hardware preprocessor switches. +// Check the 'features' section of the target description in 'targets.json' for more details. +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + + + + + + + + + + + + + + + + +#include "objects.h" + +#endif diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52832/TARGET_SDT52832B/PinNames.h b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52832/TARGET_SDT52832B/PinNames.h new file mode 100644 index 000000000000..3d0c4461c9bf --- /dev/null +++ b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52832/TARGET_SDT52832B/PinNames.h @@ -0,0 +1,258 @@ +/* + * Copyright (c) 2016 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. + * + */ + +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define NOT_CONNECTED (int)0xFFFFFFFF +#define PORT_SHIFT 3 + +typedef enum { + p0 = 0, + p1 = 1, + p2 = 2, + p3 = 3, + p4 = 4, + p5 = 5, + p6 = 6, + p7 = 7, + p8 = 8, + p9 = 9, + p10 = 10, + p11 = 11, + p12 = 12, + p13 = 13, + p14 = 14, + p15 = 15, + p16 = 16, + p17 = 17, + p18 = 18, + p19 = 19, + p20 = 20, + p21 = 21, + p22 = 22, + p23 = 23, + p24 = 24, + p25 = 25, + p26 = 26, + p27 = 27, + p28 = 28, + p29 = 29, + p30 = 30, + p31 = 31, + + P0_0 = p0, + P0_1 = p1, + P0_2 = p2, + P0_3 = p3, + P0_4 = p4, + P0_5 = p5, + P0_6 = p6, + P0_7 = p7, + + P0_8 = p8, + P0_9 = p9, + P0_10 = p10, + P0_11 = p11, + P0_12 = p12, + P0_13 = p13, + P0_14 = p14, + P0_15 = p15, + + P0_16 = p16, + P0_17 = p17, + P0_18 = p18, + P0_19 = p19, + P0_20 = p20, + P0_21 = p21, + P0_22 = p22, + P0_23 = p23, + + P0_24 = p24, + P0_25 = p25, + P0_26 = p26, + P0_27 = p27, + P0_28 = p28, + P0_29 = p29, + P0_30 = p30, + P0_31 = p31, + + RX_PIN_NUMBER = p8, + TX_PIN_NUMBER = p6, + CTS_PIN_NUMBER = p7, + RTS_PIN_NUMBER = p5, + + // mBed interface Pins + STDIO_UART_TX = TX_PIN_NUMBER, + STDIO_UART_RX = RX_PIN_NUMBER, + STDIO_UART_CTS = CTS_PIN_NUMBER, + STDIO_UART_RTS = RTS_PIN_NUMBER, + + // Analog + A0 = P0_2, + A1 = P0_3, + A2 = P0_4, + A3 = P0_28, + + // General Pin Input Output (GPIO) + GPIO0 = P0_9, + GPIO1 = P0_10, + GPIO2 = P0_17, + GPIO3 = P0_29, + GPIO4 = NOT_CONNECTED, + GPIO5 = NOT_CONNECTED, + GPIO6 = NOT_CONNECTED, + + //Purse Width Modulation (PWM) + PWM0 = GPIO2, + PWM1 = GPIO3, + PWM2 = GPIO0, + PWM3 = GPIO1, + + // LEDs + LED0 = GPIO0, + LED1 = GPIO1, + LED2 = GPIO2, + + LED_RED = LED0, + LED_GREEN = LED1, + LED_BLUE = LED2, + + // USB bridge and SWD UART connected UART pins + USBTX = TX_PIN_NUMBER, + USBRX = RX_PIN_NUMBER, + + // UART pins + UART0_RX = NOT_CONNECTED, + UART0_TX = NOT_CONNECTED, + UART0_CTS = NOT_CONNECTED, + UART0_RTS = NOT_CONNECTED, + + UART1_RX = P0_8, + UART1_TX = P0_6, + UART1_CTS = P0_7, + UART1_RTS = P0_5, + + UART2_RX = NOT_CONNECTED, + UART2_TX = NOT_CONNECTED, + UART2_CTS = NOT_CONNECTED, + UART2_RTS = NOT_CONNECTED, + + // I2C pins + I2C0_SCL = P0_27, + I2C0_SDA = P0_26, + + I2C1_SCL = P0_31, + I2C1_SDA = P0_30, + + I2C2_SCL = NOT_CONNECTED, + I2C2_SDA = NOT_CONNECTED, + + // SPI pins + SPI0_SCK = P0_14, + SPI0_MOSI = P0_12, + SPI0_MISO = P0_13, + SPI0_SS0 = P0_11, + SPI0_SS1 = P0_15, + SPI0_SS2 = P0_16, + + SPI1_SCK = P0_25, + SPI1_MOSI = P0_23, + SPI1_MISO = P0_24, + SPI1_SS0 = P0_22, + SPI1_SS1 = P0_19, + SPI1_SS2 = P0_20, + + SPI2_SCK = NOT_CONNECTED, + SPI2_MOSI = NOT_CONNECTED, + SPI2_MISO = NOT_CONNECTED, + SPI2_SS0 = NOT_CONNECTED, + SPI2_SS1 = NOT_CONNECTED, + SPI2_SS2 = NOT_CONNECTED, + + SPI3_SCK = NOT_CONNECTED, + SPI3_MOSI = NOT_CONNECTED, + SPI3_MISO = NOT_CONNECTED, + SPI3_SS0 = NOT_CONNECTED, + SPI3_SS1 = NOT_CONNECTED, + SPI3_SS2 = NOT_CONNECTED, + + // SWD UART + SWD_TGT_TX = UART1_TX, + SWD_TGT_RX = UART1_RX, + SWD_TGT_CTS = UART1_CTS, + SWD_TGT_RTS = UART1_RTS, + + // Generics + SERIAL_TX = UART1_TX, + SERIAL_RX = UART1_RX, + I2C_SCL = I2C0_SCL, + I2C_SDA = I2C0_SDA, + SPI_MOSI = SPI0_MOSI, + SPI_MISO = SPI0_MISO, + SPI_SCK = SPI0_SCK, + SPI_CS = SPI0_SS0, + PWM_OUT = PWM0, + + // Not connected + NC = NOT_CONNECTED +} PinName; + +typedef enum { + PullNone = 0, + PullDown = 1, + PullUp = 3, + PullDefault = PullUp +} PinMode; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52832/TARGET_SDT52832B/device.h b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52832/TARGET_SDT52832B/device.h new file mode 100644 index 000000000000..2427e752ea99 --- /dev/null +++ b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52832/TARGET_SDT52832B/device.h @@ -0,0 +1,38 @@ +// The 'features' section in 'target.json' is now used to create the device's hardware preprocessor switches. +// Check the 'features' section of the target description in 'targets.json' for more details. +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + + + + + + + + + + + + + + + + +#include "objects.h" + +#endif diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_SDK_14_2/drivers_nrf/twi_master/nrf_drv_twi.c b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_SDK_14_2/drivers_nrf/twi_master/nrf_drv_twi.c index c6ec4059e077..1bf33a2160c4 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_SDK_14_2/drivers_nrf/twi_master/nrf_drv_twi.c +++ b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_SDK_14_2/drivers_nrf/twi_master/nrf_drv_twi.c @@ -345,7 +345,6 @@ void nrf_drv_twi_uninit(nrf_drv_twi_t const * p_instance) nrf_drv_common_irq_disable(nrf_drv_get_IRQn((void *)p_instance->reg.p_twi)); ) } - nrf_drv_twi_disable(p_instance); #if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) nrf_drv_common_per_res_release(p_instance->reg.p_regs); diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/common_rtc.c b/targets/TARGET_NORDIC/TARGET_NRF5x/common_rtc.c index 86ec48802295..126c33f2086d 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5x/common_rtc.c +++ b/targets/TARGET_NORDIC/TARGET_NRF5x/common_rtc.c @@ -180,6 +180,15 @@ void common_rtc_init(void) m_common_rtc_enabled = true; } +void common_rtc_free() +{ + nrf_rtc_task_trigger(COMMON_RTC_INSTANCE, NRF_RTC_TASK_STOP); + nrf_rtc_int_disable(COMMON_RTC_INSTANCE, LP_TICKER_INT_MASK); + NVIC_DisableIRQ(nrf_drv_get_IRQn(COMMON_RTC_INSTANCE)); + + m_common_rtc_enabled = false; +} + void common_rtc_set_interrupt(uint32_t ticks_count, uint32_t cc_channel, uint32_t int_mask) { diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/lp_ticker.c b/targets/TARGET_NORDIC/TARGET_NRF5x/lp_ticker.c index 9e197d8555ea..837a7fb5a373 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5x/lp_ticker.c +++ b/targets/TARGET_NORDIC/TARGET_NRF5x/lp_ticker.c @@ -36,8 +36,7 @@ void lp_ticker_init(void) void lp_ticker_free(void) { - // A common counter is used for RTC, lp_ticker and us_ticker, so it can't be - // disabled here, but this does not cause any extra cost. + common_rtc_free(); } uint32_t lp_ticker_read() diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/us_ticker.c b/targets/TARGET_NORDIC/TARGET_NRF5x/us_ticker.c index 4d17b910d1a2..7ab6b2f6109d 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5x/us_ticker.c +++ b/targets/TARGET_NORDIC/TARGET_NRF5x/us_ticker.c @@ -140,8 +140,7 @@ void us_ticker_clear_interrupt(void) void us_ticker_free(void) { nrf_timer_task_trigger(NRF_TIMER1, NRF_TIMER_TASK_STOP); - nrf_timer_int_disable(NRF_TIMER1, nrf_timer_compare_int_get(NRF_TIMER_CC_CHANNEL0)); - + NVIC_DisableIRQ(TIMER1_IRQn); us_ticker_initialized = false; } diff --git a/targets/TARGET_NUVOTON/TARGET_M2351/TARGET_NUMAKER_PFM_M2351/PeripheralNames.h b/targets/TARGET_NUVOTON/TARGET_M2351/PeripheralNames.h similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_M2351/TARGET_NUMAKER_PFM_M2351/PeripheralNames.h rename to targets/TARGET_NUVOTON/TARGET_M2351/PeripheralNames.h diff --git a/targets/TARGET_NUVOTON/TARGET_M2351/TARGET_NUMAKER_PFM_M2351/PeripheralPins.c b/targets/TARGET_NUVOTON/TARGET_M2351/PeripheralPins.c similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_M2351/TARGET_NUMAKER_PFM_M2351/PeripheralPins.c rename to targets/TARGET_NUVOTON/TARGET_M2351/PeripheralPins.c diff --git a/targets/TARGET_NUVOTON/TARGET_M2351/TARGET_NUMAKER_PFM_M2351/PeripheralPins.h b/targets/TARGET_NUVOTON/TARGET_M2351/PeripheralPins.h similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_M2351/TARGET_NUMAKER_PFM_M2351/PeripheralPins.h rename to targets/TARGET_NUVOTON/TARGET_M2351/PeripheralPins.h diff --git a/targets/TARGET_NUVOTON/TARGET_M2351/TARGET_NUMAKER_PFM_M2351/PinNames.h b/targets/TARGET_NUVOTON/TARGET_M2351/PinNames.h similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_M2351/TARGET_NUMAKER_PFM_M2351/PinNames.h rename to targets/TARGET_NUVOTON/TARGET_M2351/PinNames.h diff --git a/targets/TARGET_NUVOTON/TARGET_M2351/TARGET_NUMAKER_PFM_M2351/PortNames.h b/targets/TARGET_NUVOTON/TARGET_M2351/PortNames.h similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_M2351/TARGET_NUMAKER_PFM_M2351/PortNames.h rename to targets/TARGET_NUVOTON/TARGET_M2351/PortNames.h diff --git a/targets/TARGET_NUVOTON/TARGET_M2351/TARGET_NUMAKER_PFM_M2351/device.h b/targets/TARGET_NUVOTON/TARGET_M2351/device.h similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_M2351/TARGET_NUMAKER_PFM_M2351/device.h rename to targets/TARGET_NUVOTON/TARGET_M2351/device.h diff --git a/targets/TARGET_NUVOTON/TARGET_M2351/device/TOOLCHAIN_ARM_MICRO/sys.cpp b/targets/TARGET_NUVOTON/TARGET_M2351/device/TOOLCHAIN_ARM_MICRO/sys.cpp deleted file mode 100644 index abf213c62ba7..000000000000 --- a/targets/TARGET_NUVOTON/TARGET_M2351/device/TOOLCHAIN_ARM_MICRO/sys.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* mbed Microcontroller Library - stackheap - * Copyright (C) 2009-2011 ARM Limited. All rights reserved. - * - * Setup a fixed single stack/heap memory model, - * between the top of the RW/ZI region and the stackpointer - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) -#include -#endif - -#include -#include - -extern char Image$$ARM_LIB_STACK$$ZI$$Limit[]; -extern char Image$$ARM_LIB_HEAP$$Base[]; -extern char Image$$ARM_LIB_HEAP$$ZI$$Limit[]; -extern __value_in_regs struct __initial_stackheap _mbed_user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) { - - struct __initial_stackheap r; - r.heap_base = (uint32_t)Image$$ARM_LIB_HEAP$$Base; - r.heap_limit = (uint32_t)Image$$ARM_LIB_HEAP$$ZI$$Limit; - return r; -} - -#ifdef __cplusplus -} -#endif diff --git a/targets/TARGET_NUVOTON/TARGET_M2351/device/TOOLCHAIN_ARM_STD/sys.cpp b/targets/TARGET_NUVOTON/TARGET_M2351/device/TOOLCHAIN_ARM_STD/sys.cpp deleted file mode 100644 index abf213c62ba7..000000000000 --- a/targets/TARGET_NUVOTON/TARGET_M2351/device/TOOLCHAIN_ARM_STD/sys.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* mbed Microcontroller Library - stackheap - * Copyright (C) 2009-2011 ARM Limited. All rights reserved. - * - * Setup a fixed single stack/heap memory model, - * between the top of the RW/ZI region and the stackpointer - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) -#include -#endif - -#include -#include - -extern char Image$$ARM_LIB_STACK$$ZI$$Limit[]; -extern char Image$$ARM_LIB_HEAP$$Base[]; -extern char Image$$ARM_LIB_HEAP$$ZI$$Limit[]; -extern __value_in_regs struct __initial_stackheap _mbed_user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) { - - struct __initial_stackheap r; - r.heap_base = (uint32_t)Image$$ARM_LIB_HEAP$$Base; - r.heap_limit = (uint32_t)Image$$ARM_LIB_HEAP$$ZI$$Limit; - return r; -} - -#ifdef __cplusplus -} -#endif diff --git a/targets/TARGET_NUVOTON/TARGET_M2351/device/TOOLCHAIN_GCC_ARM/m2351_retarget.c b/targets/TARGET_NUVOTON/TARGET_M2351/device/TOOLCHAIN_GCC_ARM/m2351_retarget.c index 3ffbda526819..eb09b0281d7f 100644 --- a/targets/TARGET_NUVOTON/TARGET_M2351/device/TOOLCHAIN_GCC_ARM/m2351_retarget.c +++ b/targets/TARGET_NUVOTON/TARGET_M2351/device/TOOLCHAIN_GCC_ARM/m2351_retarget.c @@ -18,18 +18,20 @@ extern uint32_t __mbed_krbs_start; #define NU_HEAP_ALIGN 4 -/** - * The default implementation of _sbrk() (in common/retarget.cpp) for GCC_ARM requires one-region model (heap and stack share one region), which doesn't - * fit two-region model (heap and stack are two distinct regions), for example, NUMAKER-PFM-NUC472 locates heap on external SRAM. Define __wrap__sbrk() to - * override the default _sbrk(). It is expected to get called through gcc hooking mechanism ('-Wl,--wrap,_sbrk') or in _sbrk(). +/* Support heap with two-region model + * + * The default implementation of _sbrk() (in mbed_retarget.cpp) for GCC_ARM requires one-region + * model (heap and stack share one region), which doesn't fit two-region model (heap and stack + * are two distinct regions), e.g., stack in internal SRAM/heap in external SRAM on NUMAKER_PFM_NUC472. + * Hence, override _sbrk() here to support heap with two-region model. */ -void *__wrap__sbrk(int incr) +void *_sbrk(int incr) { static uint32_t heap_ind = (uint32_t) &__mbed_sbrk_start; uint32_t heap_ind_old = NU_ALIGN_UP(heap_ind, NU_HEAP_ALIGN); uint32_t heap_ind_new = NU_ALIGN_UP(heap_ind_old + incr, NU_HEAP_ALIGN); - if (heap_ind_new > &__mbed_krbs_start) { + if (heap_ind_new > (uint32_t) &__mbed_krbs_start) { errno = ENOMEM; return (void *) -1; } diff --git a/targets/TARGET_NUVOTON/TARGET_M2351/TARGET_NUMAKER_PFM_M2351/mbed_overrides.c b/targets/TARGET_NUVOTON/TARGET_M2351/mbed_overrides.c similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_M2351/TARGET_NUMAKER_PFM_M2351/mbed_overrides.c rename to targets/TARGET_NUVOTON/TARGET_M2351/mbed_overrides.c diff --git a/targets/TARGET_NUVOTON/TARGET_M2351/TARGET_NUMAKER_PFM_M2351/objects.h b/targets/TARGET_NUVOTON/TARGET_M2351/objects.h similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_M2351/TARGET_NUMAKER_PFM_M2351/objects.h rename to targets/TARGET_NUVOTON/TARGET_M2351/objects.h diff --git a/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/PeripheralNames.h b/targets/TARGET_NUVOTON/TARGET_M451/PeripheralNames.h similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/PeripheralNames.h rename to targets/TARGET_NUVOTON/TARGET_M451/PeripheralNames.h diff --git a/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/PeripheralPins.c b/targets/TARGET_NUVOTON/TARGET_M451/PeripheralPins.c similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/PeripheralPins.c rename to targets/TARGET_NUVOTON/TARGET_M451/PeripheralPins.c diff --git a/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/PeripheralPins.h b/targets/TARGET_NUVOTON/TARGET_M451/PeripheralPins.h similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/PeripheralPins.h rename to targets/TARGET_NUVOTON/TARGET_M451/PeripheralPins.h diff --git a/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/PinNames.h b/targets/TARGET_NUVOTON/TARGET_M451/PinNames.h similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/PinNames.h rename to targets/TARGET_NUVOTON/TARGET_M451/PinNames.h diff --git a/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/PortNames.h b/targets/TARGET_NUVOTON/TARGET_M451/PortNames.h similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/PortNames.h rename to targets/TARGET_NUVOTON/TARGET_M451/PortNames.h diff --git a/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/device.h b/targets/TARGET_NUVOTON/TARGET_M451/device.h similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/device.h rename to targets/TARGET_NUVOTON/TARGET_M451/device.h diff --git a/targets/TARGET_NUVOTON/TARGET_M451/device/TOOLCHAIN_ARM_MICRO/sys.cpp b/targets/TARGET_NUVOTON/TARGET_M451/device/TOOLCHAIN_ARM_MICRO/sys.cpp deleted file mode 100644 index abf213c62ba7..000000000000 --- a/targets/TARGET_NUVOTON/TARGET_M451/device/TOOLCHAIN_ARM_MICRO/sys.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* mbed Microcontroller Library - stackheap - * Copyright (C) 2009-2011 ARM Limited. All rights reserved. - * - * Setup a fixed single stack/heap memory model, - * between the top of the RW/ZI region and the stackpointer - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) -#include -#endif - -#include -#include - -extern char Image$$ARM_LIB_STACK$$ZI$$Limit[]; -extern char Image$$ARM_LIB_HEAP$$Base[]; -extern char Image$$ARM_LIB_HEAP$$ZI$$Limit[]; -extern __value_in_regs struct __initial_stackheap _mbed_user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) { - - struct __initial_stackheap r; - r.heap_base = (uint32_t)Image$$ARM_LIB_HEAP$$Base; - r.heap_limit = (uint32_t)Image$$ARM_LIB_HEAP$$ZI$$Limit; - return r; -} - -#ifdef __cplusplus -} -#endif diff --git a/targets/TARGET_NUVOTON/TARGET_M451/device/TOOLCHAIN_ARM_STD/sys.cpp b/targets/TARGET_NUVOTON/TARGET_M451/device/TOOLCHAIN_ARM_STD/sys.cpp deleted file mode 100644 index abf213c62ba7..000000000000 --- a/targets/TARGET_NUVOTON/TARGET_M451/device/TOOLCHAIN_ARM_STD/sys.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* mbed Microcontroller Library - stackheap - * Copyright (C) 2009-2011 ARM Limited. All rights reserved. - * - * Setup a fixed single stack/heap memory model, - * between the top of the RW/ZI region and the stackpointer - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) -#include -#endif - -#include -#include - -extern char Image$$ARM_LIB_STACK$$ZI$$Limit[]; -extern char Image$$ARM_LIB_HEAP$$Base[]; -extern char Image$$ARM_LIB_HEAP$$ZI$$Limit[]; -extern __value_in_regs struct __initial_stackheap _mbed_user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) { - - struct __initial_stackheap r; - r.heap_base = (uint32_t)Image$$ARM_LIB_HEAP$$Base; - r.heap_limit = (uint32_t)Image$$ARM_LIB_HEAP$$ZI$$Limit; - return r; -} - -#ifdef __cplusplus -} -#endif diff --git a/targets/TARGET_NUVOTON/TARGET_M451/device/TOOLCHAIN_GCC_ARM/m451_retarget.c b/targets/TARGET_NUVOTON/TARGET_M451/device/TOOLCHAIN_GCC_ARM/m451_retarget.c index c45bd8207e00..bec0577d65d9 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/device/TOOLCHAIN_GCC_ARM/m451_retarget.c +++ b/targets/TARGET_NUVOTON/TARGET_M451/device/TOOLCHAIN_GCC_ARM/m451_retarget.c @@ -18,18 +18,20 @@ extern uint32_t __mbed_krbs_start; #define NU_HEAP_ALIGN 32 -/** - * The default implementation of _sbrk() (in common/retarget.cpp) for GCC_ARM requires one-region model (heap and stack share one region), which doesn't - * fit two-region model (heap and stack are two distinct regions), for example, NUMAKER-PFM-NUC472 locates heap on external SRAM. Define __wrap__sbrk() to - * override the default _sbrk(). It is expected to get called through gcc hooking mechanism ('-Wl,--wrap,_sbrk') or in _sbrk(). +/* Support heap with two-region model + * + * The default implementation of _sbrk() (in mbed_retarget.cpp) for GCC_ARM requires one-region + * model (heap and stack share one region), which doesn't fit two-region model (heap and stack + * are two distinct regions), e.g., stack in internal SRAM/heap in external SRAM on NUMAKER_PFM_NUC472. + * Hence, override _sbrk() here to support heap with two-region model. */ -void *__wrap__sbrk(int incr) +void *_sbrk(int incr) { static uint32_t heap_ind = (uint32_t) &__mbed_sbrk_start; uint32_t heap_ind_old = NU_ALIGN_UP(heap_ind, NU_HEAP_ALIGN); uint32_t heap_ind_new = NU_ALIGN_UP(heap_ind_old + incr, NU_HEAP_ALIGN); - if (heap_ind_new > &__mbed_krbs_start) { + if (heap_ind_new > (uint32_t) &__mbed_krbs_start) { errno = ENOMEM; return (void *) -1; } diff --git a/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/mbed_overrides.c b/targets/TARGET_NUVOTON/TARGET_M451/mbed_overrides.c similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/mbed_overrides.c rename to targets/TARGET_NUVOTON/TARGET_M451/mbed_overrides.c diff --git a/targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/objects.h b/targets/TARGET_NUVOTON/TARGET_M451/objects.h similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/objects.h rename to targets/TARGET_NUVOTON/TARGET_M451/objects.h diff --git a/targets/TARGET_NUVOTON/TARGET_M480/TARGET_NUMAKER_PFM_M487/PeripheralNames.h b/targets/TARGET_NUVOTON/TARGET_M480/PeripheralNames.h similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_M480/TARGET_NUMAKER_PFM_M487/PeripheralNames.h rename to targets/TARGET_NUVOTON/TARGET_M480/PeripheralNames.h diff --git a/targets/TARGET_NUVOTON/TARGET_M480/TARGET_NUMAKER_PFM_M487/PeripheralPins.c b/targets/TARGET_NUVOTON/TARGET_M480/PeripheralPins.c similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_M480/TARGET_NUMAKER_PFM_M487/PeripheralPins.c rename to targets/TARGET_NUVOTON/TARGET_M480/PeripheralPins.c diff --git a/targets/TARGET_NUVOTON/TARGET_M480/TARGET_NUMAKER_PFM_M487/PeripheralPins.h b/targets/TARGET_NUVOTON/TARGET_M480/PeripheralPins.h similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_M480/TARGET_NUMAKER_PFM_M487/PeripheralPins.h rename to targets/TARGET_NUVOTON/TARGET_M480/PeripheralPins.h diff --git a/targets/TARGET_NUVOTON/TARGET_M480/TARGET_NUMAKER_PFM_M487/PinNames.h b/targets/TARGET_NUVOTON/TARGET_M480/PinNames.h similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_M480/TARGET_NUMAKER_PFM_M487/PinNames.h rename to targets/TARGET_NUVOTON/TARGET_M480/PinNames.h diff --git a/targets/TARGET_NUVOTON/TARGET_M480/TARGET_NUMAKER_PFM_M487/PortNames.h b/targets/TARGET_NUVOTON/TARGET_M480/PortNames.h similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_M480/TARGET_NUMAKER_PFM_M487/PortNames.h rename to targets/TARGET_NUVOTON/TARGET_M480/PortNames.h diff --git a/targets/TARGET_NUVOTON/TARGET_M480/TARGET_NUMAKER_PFM_M487/device.h b/targets/TARGET_NUVOTON/TARGET_M480/device.h similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_M480/TARGET_NUMAKER_PFM_M487/device.h rename to targets/TARGET_NUVOTON/TARGET_M480/device.h diff --git a/targets/TARGET_NUVOTON/TARGET_M480/device/TOOLCHAIN_ARM_MICRO/sys.cpp b/targets/TARGET_NUVOTON/TARGET_M480/device/TOOLCHAIN_ARM_MICRO/sys.cpp deleted file mode 100644 index abf213c62ba7..000000000000 --- a/targets/TARGET_NUVOTON/TARGET_M480/device/TOOLCHAIN_ARM_MICRO/sys.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* mbed Microcontroller Library - stackheap - * Copyright (C) 2009-2011 ARM Limited. All rights reserved. - * - * Setup a fixed single stack/heap memory model, - * between the top of the RW/ZI region and the stackpointer - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) -#include -#endif - -#include -#include - -extern char Image$$ARM_LIB_STACK$$ZI$$Limit[]; -extern char Image$$ARM_LIB_HEAP$$Base[]; -extern char Image$$ARM_LIB_HEAP$$ZI$$Limit[]; -extern __value_in_regs struct __initial_stackheap _mbed_user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) { - - struct __initial_stackheap r; - r.heap_base = (uint32_t)Image$$ARM_LIB_HEAP$$Base; - r.heap_limit = (uint32_t)Image$$ARM_LIB_HEAP$$ZI$$Limit; - return r; -} - -#ifdef __cplusplus -} -#endif diff --git a/targets/TARGET_NUVOTON/TARGET_M480/device/TOOLCHAIN_ARM_STD/sys.cpp b/targets/TARGET_NUVOTON/TARGET_M480/device/TOOLCHAIN_ARM_STD/sys.cpp deleted file mode 100644 index abf213c62ba7..000000000000 --- a/targets/TARGET_NUVOTON/TARGET_M480/device/TOOLCHAIN_ARM_STD/sys.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* mbed Microcontroller Library - stackheap - * Copyright (C) 2009-2011 ARM Limited. All rights reserved. - * - * Setup a fixed single stack/heap memory model, - * between the top of the RW/ZI region and the stackpointer - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) -#include -#endif - -#include -#include - -extern char Image$$ARM_LIB_STACK$$ZI$$Limit[]; -extern char Image$$ARM_LIB_HEAP$$Base[]; -extern char Image$$ARM_LIB_HEAP$$ZI$$Limit[]; -extern __value_in_regs struct __initial_stackheap _mbed_user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) { - - struct __initial_stackheap r; - r.heap_base = (uint32_t)Image$$ARM_LIB_HEAP$$Base; - r.heap_limit = (uint32_t)Image$$ARM_LIB_HEAP$$ZI$$Limit; - return r; -} - -#ifdef __cplusplus -} -#endif diff --git a/targets/TARGET_NUVOTON/TARGET_M480/device/TOOLCHAIN_GCC_ARM/m480_retarget.c b/targets/TARGET_NUVOTON/TARGET_M480/device/TOOLCHAIN_GCC_ARM/m480_retarget.c index 7802ab5ca06b..378fcec9ba38 100644 --- a/targets/TARGET_NUVOTON/TARGET_M480/device/TOOLCHAIN_GCC_ARM/m480_retarget.c +++ b/targets/TARGET_NUVOTON/TARGET_M480/device/TOOLCHAIN_GCC_ARM/m480_retarget.c @@ -18,12 +18,14 @@ extern uint32_t __mbed_krbs_start; #define NU_HEAP_ALIGN 32 -/** - * The default implementation of _sbrk() (in common/retarget.cpp) for GCC_ARM requires one-region model (heap and stack share one region), which doesn't - * fit two-region model (heap and stack are two distinct regions), for example, NUMAKER-PFM-NUC472 locates heap on external SRAM. Define __wrap__sbrk() to - * override the default _sbrk(). It is expected to get called through gcc hooking mechanism ('-Wl,--wrap,_sbrk') or in _sbrk(). +/* Support heap with two-region model + * + * The default implementation of _sbrk() (in mbed_retarget.cpp) for GCC_ARM requires one-region + * model (heap and stack share one region), which doesn't fit two-region model (heap and stack + * are two distinct regions), e.g., stack in internal SRAM/heap in external SRAM on NUMAKER_PFM_NUC472. + * Hence, override _sbrk() here to support heap with two-region model. */ -void *__wrap__sbrk(int incr) +void *_sbrk(int incr) { static uint32_t heap_ind = (uint32_t) &__mbed_sbrk_start; uint32_t heap_ind_old = NU_ALIGN_UP(heap_ind, NU_HEAP_ALIGN); diff --git a/targets/TARGET_NUVOTON/TARGET_M480/TARGET_NUMAKER_PFM_M487/mbed_overrides.c b/targets/TARGET_NUVOTON/TARGET_M480/mbed_overrides.c similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_M480/TARGET_NUMAKER_PFM_M487/mbed_overrides.c rename to targets/TARGET_NUVOTON/TARGET_M480/mbed_overrides.c diff --git a/targets/TARGET_NUVOTON/TARGET_M480/TARGET_NUMAKER_PFM_M487/objects.h b/targets/TARGET_NUVOTON/TARGET_M480/objects.h similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_M480/TARGET_NUMAKER_PFM_M487/objects.h rename to targets/TARGET_NUVOTON/TARGET_M480/objects.h diff --git a/targets/TARGET_NUVOTON/TARGET_NANO100/TARGET_NUMAKER_PFM_NANO130/PeripheralNames.h b/targets/TARGET_NUVOTON/TARGET_NANO100/PeripheralNames.h similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_NANO100/TARGET_NUMAKER_PFM_NANO130/PeripheralNames.h rename to targets/TARGET_NUVOTON/TARGET_NANO100/PeripheralNames.h diff --git a/targets/TARGET_NUVOTON/TARGET_NANO100/TARGET_NUMAKER_PFM_NANO130/PeripheralPins.c b/targets/TARGET_NUVOTON/TARGET_NANO100/PeripheralPins.c similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_NANO100/TARGET_NUMAKER_PFM_NANO130/PeripheralPins.c rename to targets/TARGET_NUVOTON/TARGET_NANO100/PeripheralPins.c diff --git a/targets/TARGET_NUVOTON/TARGET_NANO100/TARGET_NUMAKER_PFM_NANO130/PeripheralPins.h b/targets/TARGET_NUVOTON/TARGET_NANO100/PeripheralPins.h similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_NANO100/TARGET_NUMAKER_PFM_NANO130/PeripheralPins.h rename to targets/TARGET_NUVOTON/TARGET_NANO100/PeripheralPins.h diff --git a/targets/TARGET_NUVOTON/TARGET_NANO100/TARGET_NUMAKER_PFM_NANO130/PinNames.h b/targets/TARGET_NUVOTON/TARGET_NANO100/PinNames.h similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_NANO100/TARGET_NUMAKER_PFM_NANO130/PinNames.h rename to targets/TARGET_NUVOTON/TARGET_NANO100/PinNames.h diff --git a/targets/TARGET_NUVOTON/TARGET_NANO100/TARGET_NUMAKER_PFM_NANO130/PortNames.h b/targets/TARGET_NUVOTON/TARGET_NANO100/PortNames.h similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_NANO100/TARGET_NUMAKER_PFM_NANO130/PortNames.h rename to targets/TARGET_NUVOTON/TARGET_NANO100/PortNames.h diff --git a/targets/TARGET_NUVOTON/TARGET_NANO100/TARGET_NUMAKER_PFM_NANO130/device.h b/targets/TARGET_NUVOTON/TARGET_NANO100/device.h similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_NANO100/TARGET_NUMAKER_PFM_NANO130/device.h rename to targets/TARGET_NUVOTON/TARGET_NANO100/device.h diff --git a/targets/TARGET_NUVOTON/TARGET_NANO100/device/TOOLCHAIN_ARM_MICRO/sys.cpp b/targets/TARGET_NUVOTON/TARGET_NANO100/device/TOOLCHAIN_ARM_MICRO/sys.cpp deleted file mode 100644 index abf213c62ba7..000000000000 --- a/targets/TARGET_NUVOTON/TARGET_NANO100/device/TOOLCHAIN_ARM_MICRO/sys.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* mbed Microcontroller Library - stackheap - * Copyright (C) 2009-2011 ARM Limited. All rights reserved. - * - * Setup a fixed single stack/heap memory model, - * between the top of the RW/ZI region and the stackpointer - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) -#include -#endif - -#include -#include - -extern char Image$$ARM_LIB_STACK$$ZI$$Limit[]; -extern char Image$$ARM_LIB_HEAP$$Base[]; -extern char Image$$ARM_LIB_HEAP$$ZI$$Limit[]; -extern __value_in_regs struct __initial_stackheap _mbed_user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) { - - struct __initial_stackheap r; - r.heap_base = (uint32_t)Image$$ARM_LIB_HEAP$$Base; - r.heap_limit = (uint32_t)Image$$ARM_LIB_HEAP$$ZI$$Limit; - return r; -} - -#ifdef __cplusplus -} -#endif diff --git a/targets/TARGET_NUVOTON/TARGET_NANO100/device/TOOLCHAIN_ARM_STD/sys.cpp b/targets/TARGET_NUVOTON/TARGET_NANO100/device/TOOLCHAIN_ARM_STD/sys.cpp deleted file mode 100644 index abf213c62ba7..000000000000 --- a/targets/TARGET_NUVOTON/TARGET_NANO100/device/TOOLCHAIN_ARM_STD/sys.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* mbed Microcontroller Library - stackheap - * Copyright (C) 2009-2011 ARM Limited. All rights reserved. - * - * Setup a fixed single stack/heap memory model, - * between the top of the RW/ZI region and the stackpointer - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) -#include -#endif - -#include -#include - -extern char Image$$ARM_LIB_STACK$$ZI$$Limit[]; -extern char Image$$ARM_LIB_HEAP$$Base[]; -extern char Image$$ARM_LIB_HEAP$$ZI$$Limit[]; -extern __value_in_regs struct __initial_stackheap _mbed_user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) { - - struct __initial_stackheap r; - r.heap_base = (uint32_t)Image$$ARM_LIB_HEAP$$Base; - r.heap_limit = (uint32_t)Image$$ARM_LIB_HEAP$$ZI$$Limit; - return r; -} - -#ifdef __cplusplus -} -#endif diff --git a/targets/TARGET_NUVOTON/TARGET_NANO100/device/TOOLCHAIN_GCC_ARM/nano100_retarget.c b/targets/TARGET_NUVOTON/TARGET_NANO100/device/TOOLCHAIN_GCC_ARM/nano100_retarget.c index e07e2cdfb9b9..1c60c0bd1b15 100644 --- a/targets/TARGET_NUVOTON/TARGET_NANO100/device/TOOLCHAIN_GCC_ARM/nano100_retarget.c +++ b/targets/TARGET_NUVOTON/TARGET_NANO100/device/TOOLCHAIN_GCC_ARM/nano100_retarget.c @@ -18,18 +18,20 @@ extern uint32_t __mbed_krbs_start; #define NU_HEAP_ALIGN 4 -/** - * The default implementation of _sbrk() (in common/retarget.cpp) for GCC_ARM requires one-region model (heap and stack share one region), which doesn't - * fit two-region model (heap and stack are two distinct regions), for example, NUMAKER-PFM-NUC472 locates heap on external SRAM. Define __wrap__sbrk() to - * override the default _sbrk(). It is expected to get called through gcc hooking mechanism ('-Wl,--wrap,_sbrk') or in _sbrk(). +/* Support heap with two-region model + * + * The default implementation of _sbrk() (in mbed_retarget.cpp) for GCC_ARM requires one-region + * model (heap and stack share one region), which doesn't fit two-region model (heap and stack + * are two distinct regions), e.g., stack in internal SRAM/heap in external SRAM on NUMAKER_PFM_NUC472. + * Hence, override _sbrk() here to support heap with two-region model. */ -void *__wrap__sbrk(int incr) +void *_sbrk(int incr) { static uint32_t heap_ind = (uint32_t) &__mbed_sbrk_start; uint32_t heap_ind_old = NU_ALIGN_UP(heap_ind, NU_HEAP_ALIGN); uint32_t heap_ind_new = NU_ALIGN_UP(heap_ind_old + incr, NU_HEAP_ALIGN); - if (heap_ind_new > &__mbed_krbs_start) { + if (heap_ind_new > (uint32_t) &__mbed_krbs_start) { errno = ENOMEM; return (void *) -1; } diff --git a/targets/TARGET_NUVOTON/TARGET_NANO100/TARGET_NUMAKER_PFM_NANO130/mbed_overrides.c b/targets/TARGET_NUVOTON/TARGET_NANO100/mbed_overrides.c similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_NANO100/TARGET_NUMAKER_PFM_NANO130/mbed_overrides.c rename to targets/TARGET_NUVOTON/TARGET_NANO100/mbed_overrides.c diff --git a/targets/TARGET_NUVOTON/TARGET_NANO100/TARGET_NUMAKER_PFM_NANO130/objects.h b/targets/TARGET_NUVOTON/TARGET_NANO100/objects.h similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_NANO100/TARGET_NUMAKER_PFM_NANO130/objects.h rename to targets/TARGET_NUVOTON/TARGET_NANO100/objects.h diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralNames.h b/targets/TARGET_NUVOTON/TARGET_NUC472/PeripheralNames.h similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralNames.h rename to targets/TARGET_NUVOTON/TARGET_NUC472/PeripheralNames.h diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralPins.c b/targets/TARGET_NUVOTON/TARGET_NUC472/PeripheralPins.c similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralPins.c rename to targets/TARGET_NUVOTON/TARGET_NUC472/PeripheralPins.c diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralPins.h b/targets/TARGET_NUVOTON/TARGET_NUC472/PeripheralPins.h similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PeripheralPins.h rename to targets/TARGET_NUVOTON/TARGET_NUC472/PeripheralPins.h diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PinNames.h b/targets/TARGET_NUVOTON/TARGET_NUC472/PinNames.h similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PinNames.h rename to targets/TARGET_NUVOTON/TARGET_NUC472/PinNames.h diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PortNames.h b/targets/TARGET_NUVOTON/TARGET_NUC472/PortNames.h similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/PortNames.h rename to targets/TARGET_NUVOTON/TARGET_NUC472/PortNames.h diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/device.h b/targets/TARGET_NUVOTON/TARGET_NUC472/device.h similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/device.h rename to targets/TARGET_NUVOTON/TARGET_NUC472/device.h diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/device/NUC472_442.h b/targets/TARGET_NUVOTON/TARGET_NUC472/device/NUC472_442.h index 00af9638dea8..6d44e48957bd 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/device/NUC472_442.h +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/device/NUC472_442.h @@ -24427,8 +24427,11 @@ typedef struct { #define SYS_IPRST0_USBHRST_Pos (4) /*!< SYS IPRST0: USBHRST Position */ #define SYS_IPRST0_USBHRST_Msk (0x1ul << SYS_IPRST0_USBHRST_Pos) /*!< SYS IPRST0: USBHRST Mask */ -#define SYS_IPRST0_SDHRST_Pos (5) /*!< SYS IPRST0: SDHRST Position */ -#define SYS_IPRST0_SDHRST_Msk (0x1ul << SYS_IPRST0_SDHRST_Pos) /*!< SYS IPRST0: SDHRST Mask */ +#define SYS_IPRST0_EMACRST_Pos (5) /*!< SYS_T::IPRST0: EMACRST Position */ +#define SYS_IPRST0_EMACRST_Msk (0x1ul << SYS_IPRST0_EMACRST_Pos) /*!< SYS_T::IPRST0: EMACRST Mask */ + +#define SYS_IPRST0_SDHRST_Pos (6) /*!< SYS_T::IPRST0: SDHRST Position */ +#define SYS_IPRST0_SDHRST_Msk (0x1ul << SYS_IPRST0_SDHRST_Pos) /*!< SYS_T::IPRST0: SDHRST Mask */ #define SYS_IPRST0_SDHOST_RST_Pos (6) /*!< SYS IPRST0: SDHOST_RST Position */ #define SYS_IPRST0_SDHOST_RST_Msk (0x1ul << SYS_IPRST0_SDHOST_RST_Pos) /*!< SYS IPRST0: SDHOST_RST Mask */ diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_ARM_MICRO/sys.cpp b/targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_ARM_MICRO/sys.cpp deleted file mode 100644 index abf213c62ba7..000000000000 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_ARM_MICRO/sys.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* mbed Microcontroller Library - stackheap - * Copyright (C) 2009-2011 ARM Limited. All rights reserved. - * - * Setup a fixed single stack/heap memory model, - * between the top of the RW/ZI region and the stackpointer - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) -#include -#endif - -#include -#include - -extern char Image$$ARM_LIB_STACK$$ZI$$Limit[]; -extern char Image$$ARM_LIB_HEAP$$Base[]; -extern char Image$$ARM_LIB_HEAP$$ZI$$Limit[]; -extern __value_in_regs struct __initial_stackheap _mbed_user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) { - - struct __initial_stackheap r; - r.heap_base = (uint32_t)Image$$ARM_LIB_HEAP$$Base; - r.heap_limit = (uint32_t)Image$$ARM_LIB_HEAP$$ZI$$Limit; - return r; -} - -#ifdef __cplusplus -} -#endif diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_ARM_STD/sys.cpp b/targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_ARM_STD/sys.cpp deleted file mode 100644 index abf213c62ba7..000000000000 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_ARM_STD/sys.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* mbed Microcontroller Library - stackheap - * Copyright (C) 2009-2011 ARM Limited. All rights reserved. - * - * Setup a fixed single stack/heap memory model, - * between the top of the RW/ZI region and the stackpointer - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) -#include -#endif - -#include -#include - -extern char Image$$ARM_LIB_STACK$$ZI$$Limit[]; -extern char Image$$ARM_LIB_HEAP$$Base[]; -extern char Image$$ARM_LIB_HEAP$$ZI$$Limit[]; -extern __value_in_regs struct __initial_stackheap _mbed_user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) { - - struct __initial_stackheap r; - r.heap_base = (uint32_t)Image$$ARM_LIB_HEAP$$Base; - r.heap_limit = (uint32_t)Image$$ARM_LIB_HEAP$$ZI$$Limit; - return r; -} - -#ifdef __cplusplus -} -#endif diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_GCC_ARM/nuc472_retarget.c b/targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_GCC_ARM/nuc472_retarget.c index 273b3df84106..bb418a7d6969 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_GCC_ARM/nuc472_retarget.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/device/TOOLCHAIN_GCC_ARM/nuc472_retarget.c @@ -18,18 +18,20 @@ extern uint32_t __mbed_krbs_start; #define NU_HEAP_ALIGN 32 -/** - * The default implementation of _sbrk() (in common/retarget.cpp) for GCC_ARM requires one-region model (heap and stack share one region), which doesn't - * fit two-region model (heap and stack are two distinct regions), for example, NUMAKER-PFM-NUC472 locates heap on external SRAM. Define __wrap__sbrk() to - * override the default _sbrk(). It is expected to get called through gcc hooking mechanism ('-Wl,--wrap,_sbrk') or in _sbrk(). +/* Support heap with two-region model + * + * The default implementation of _sbrk() (in mbed_retarget.cpp) for GCC_ARM requires one-region + * model (heap and stack share one region), which doesn't fit two-region model (heap and stack + * are two distinct regions), e.g., stack in internal SRAM/heap in external SRAM on NUMAKER_PFM_NUC472. + * Hence, override _sbrk() here to support heap with two-region model. */ -void *__wrap__sbrk(int incr) +void *_sbrk(int incr) { static uint32_t heap_ind = (uint32_t) &__mbed_sbrk_start; uint32_t heap_ind_old = NU_ALIGN_UP(heap_ind, NU_HEAP_ALIGN); uint32_t heap_ind_new = NU_ALIGN_UP(heap_ind_old + incr, NU_HEAP_ALIGN); - if (heap_ind_new > &__mbed_krbs_start) { + if (heap_ind_new > (uint32_t) &__mbed_krbs_start) { errno = ENOMEM; return (void *) -1; } diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/mbed_overrides.c b/targets/TARGET_NUVOTON/TARGET_NUC472/mbed_overrides.c similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/mbed_overrides.c rename to targets/TARGET_NUVOTON/TARGET_NUC472/mbed_overrides.c diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/objects.h b/targets/TARGET_NUVOTON/TARGET_NUC472/objects.h similarity index 100% rename from targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/objects.h rename to targets/TARGET_NUVOTON/TARGET_NUC472/objects.h diff --git a/targets/TARGET_NUVOTON/TOOLCHAIN_ARM/sys.cpp b/targets/TARGET_NUVOTON/TOOLCHAIN_ARM/sys.cpp new file mode 100644 index 000000000000..5a4f05d96e8b --- /dev/null +++ b/targets/TARGET_NUVOTON/TOOLCHAIN_ARM/sys.cpp @@ -0,0 +1,74 @@ +/* mbed Microcontroller Library - stackheap + * Copyright (C) 2009-2011 ARM Limited. All rights reserved. + * + * Setup a fixed single stack/heap memory model, + * between the top of the RW/ZI region and the stackpointer + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) +#include +#endif + +#include +#include + +extern char Image$$ARM_LIB_STACK$$ZI$$Limit[]; +extern char Image$$ARM_LIB_HEAP$$Base[]; +extern char Image$$ARM_LIB_HEAP$$ZI$$Limit[]; +extern __value_in_regs struct __initial_stackheap _mbed_user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) { + + struct __initial_stackheap r; + r.heap_base = (uint32_t)Image$$ARM_LIB_HEAP$$Base; + r.heap_limit = (uint32_t)Image$$ARM_LIB_HEAP$$ZI$$Limit; + return r; +} + +#if !defined(MBED_CONF_RTOS_PRESENT) || !MBED_CONF_RTOS_PRESENT + +/* The single region memory model would check stack collision at run time, verifying that + * the heap pointer is underneath the stack pointer. With two-region memory model/RTOS-less or + * multiple threads(stacks)/RTOS, the check gets meaningless and we must disable it. */ +#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) +__asm(".global __use_two_region_memory\n\t"); +__asm(".global __use_no_semihosting\n\t"); +#else +#pragma import(__use_two_region_memory) +#endif + +/* Fix __user_setup_stackheap and ARM_LIB_STACK/ARM_LIB_HEAP cannot co-exist in RTOS-less build + * + * According AN241 (http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0241b/index.html), + * __rt_entry has the following call sequence: + * 1. _platform_pre_stackheap_init + * 2. __user_setup_stackheap or setup the Stack Pointer (SP) by another method + * 3. _platform_post_stackheap_init + * 4. __rt_lib_init + * 5. _platform_post_lib_init + * 6. main() + * 7. exit() + * + * Per our check, when __user_setup_stackheap and ARM_LIB_STACK/ARM_LIB_HEAP co-exist, neither + * does __user_setup_stackheap get called and nor is ARM_LIB_HEAP used to get heap base/limit, + * which are required to pass to __rt_lib_init later. To fix the issue, by subclass'ing + * __rt_lib_init, heap base/limit are replaced with Image$$ARM_LIB_HEAP$$ZI$$Base/Limit if + * ARM_LIB_HEAP region is defined in scatter file. + * + * The overriding __rt_lib_init is needed only for rtos-less code. For rtos code, __rt_entry is + * overridden and the overriding __rt_lib_init here gets meaningless. + */ +extern __value_in_regs struct __argc_argv $Super$$__rt_lib_init(unsigned heapbase, unsigned heaptop); + +__value_in_regs struct __argc_argv $Sub$$__rt_lib_init (unsigned heapbase, unsigned heaptop) +{ + return $Super$$__rt_lib_init((unsigned) Image$$ARM_LIB_HEAP$$Base, (unsigned) Image$$ARM_LIB_HEAP$$ZI$$Limit); +} + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/targets/TARGET_NUVOTON/mbed_rtx.h b/targets/TARGET_NUVOTON/mbed_rtx.h index 6983b2e78b33..137e4c1a2460 100644 --- a/targets/TARGET_NUVOTON/mbed_rtx.h +++ b/targets/TARGET_NUVOTON/mbed_rtx.h @@ -31,14 +31,14 @@ #define ISR_STACK_START ((unsigned char*)Image$$ARM_LIB_STACK$$ZI$$Base) #define ISR_STACK_SIZE ((uint32_t)Image$$ARM_LIB_STACK$$ZI$$Length) #elif defined(__GNUC__) - extern uint32_t __StackTop[]; - extern uint32_t __StackLimit[]; - extern uint32_t __end__[]; - extern uint32_t __HeapLimit[]; - #define HEAP_START ((unsigned char*)__end__) - #define HEAP_SIZE ((uint32_t)((uint32_t)__HeapLimit - (uint32_t)HEAP_START)) - #define ISR_STACK_START ((unsigned char*)__StackLimit) - #define ISR_STACK_SIZE ((uint32_t)((uint32_t)__StackTop - (uint32_t)__StackLimit)) + extern uint32_t __StackTop; + extern uint32_t __StackLimit; + extern uint32_t __end__; + extern uint32_t __HeapLimit; + #define HEAP_START ((unsigned char*) &__end__) + #define HEAP_SIZE ((uint32_t) ((uint32_t) &__HeapLimit - (uint32_t) HEAP_START)) + #define ISR_STACK_START ((unsigned char*) &__StackLimit) + #define ISR_STACK_SIZE ((uint32_t)((uint32_t) &__StackTop - (uint32_t) &__StackLimit)) #elif defined(__ICCARM__) /* No region declarations needed */ #else diff --git a/targets/TARGET_NXP/TARGET_LPC11U6X/us_ticker.c b/targets/TARGET_NXP/TARGET_LPC11U6X/us_ticker.c index 726386b3a01b..6dd9dd70d7df 100644 --- a/targets/TARGET_NXP/TARGET_LPC11U6X/us_ticker.c +++ b/targets/TARGET_NXP/TARGET_LPC11U6X/us_ticker.c @@ -65,3 +65,8 @@ void us_ticker_disable_interrupt(void) { void us_ticker_clear_interrupt(void) { US_TICKER_TIMER->IR = 1; } + +void us_ticker_free(void) +{ + +} diff --git a/targets/TARGET_NXP/TARGET_LPC11UXX/us_ticker.c b/targets/TARGET_NXP/TARGET_LPC11UXX/us_ticker.c index 074b3edfbf70..5299b4a7bbc2 100644 --- a/targets/TARGET_NXP/TARGET_LPC11UXX/us_ticker.c +++ b/targets/TARGET_NXP/TARGET_LPC11UXX/us_ticker.c @@ -65,3 +65,8 @@ void us_ticker_disable_interrupt(void) { void us_ticker_clear_interrupt(void) { US_TICKER_TIMER->IR = 1; } + +void us_ticker_free(void) +{ + +} diff --git a/targets/TARGET_NXP/TARGET_LPC11XX_11CXX/us_ticker.c b/targets/TARGET_NXP/TARGET_LPC11XX_11CXX/us_ticker.c index a3fcf32ed5a0..b0430f365436 100644 --- a/targets/TARGET_NXP/TARGET_LPC11XX_11CXX/us_ticker.c +++ b/targets/TARGET_NXP/TARGET_LPC11XX_11CXX/us_ticker.c @@ -65,3 +65,8 @@ void us_ticker_disable_interrupt(void) { void us_ticker_clear_interrupt(void) { US_TICKER_TIMER->IR = 1; } + +void us_ticker_free(void) +{ + +} diff --git a/targets/TARGET_NXP/TARGET_LPC13XX/us_ticker.c b/targets/TARGET_NXP/TARGET_LPC13XX/us_ticker.c index dd321198a69b..70e99983b4ea 100644 --- a/targets/TARGET_NXP/TARGET_LPC13XX/us_ticker.c +++ b/targets/TARGET_NXP/TARGET_LPC13XX/us_ticker.c @@ -65,3 +65,8 @@ void us_ticker_disable_interrupt(void) { void us_ticker_clear_interrupt(void) { US_TICKER_TIMER->IR = 1; } + +void us_ticker_free(void) +{ + +} diff --git a/targets/TARGET_NXP/TARGET_LPC15XX/us_ticker.c b/targets/TARGET_NXP/TARGET_LPC15XX/us_ticker.c index 120a55934642..6dea97b59458 100644 --- a/targets/TARGET_NXP/TARGET_LPC15XX/us_ticker.c +++ b/targets/TARGET_NXP/TARGET_LPC15XX/us_ticker.c @@ -86,3 +86,8 @@ void us_ticker_clear_interrupt(void) { // Clear SCT3 event 0 interrupt flag LPC_SCT3->EVFLAG = (1 << 0); } + +void us_ticker_free(void) +{ + +} diff --git a/targets/TARGET_NXP/TARGET_LPC176X/us_ticker.c b/targets/TARGET_NXP/TARGET_LPC176X/us_ticker.c index 5b1b0b723790..2cb9ae645fba 100644 --- a/targets/TARGET_NXP/TARGET_LPC176X/us_ticker.c +++ b/targets/TARGET_NXP/TARGET_LPC176X/us_ticker.c @@ -77,3 +77,11 @@ void us_ticker_disable_interrupt(void) { void us_ticker_clear_interrupt(void) { US_TICKER_TIMER->IR = 1; } + +void us_ticker_free(void) +{ + US_TICKER_TIMER->TCR = 0; + + US_TICKER_TIMER->MCR &= ~1; + NVIC_DisableIRQ(US_TICKER_TIMER_IRQn); +} diff --git a/targets/TARGET_NXP/TARGET_LPC408X/us_ticker.c b/targets/TARGET_NXP/TARGET_LPC408X/us_ticker.c index e9bd036ff156..97093cb0893d 100644 --- a/targets/TARGET_NXP/TARGET_LPC408X/us_ticker.c +++ b/targets/TARGET_NXP/TARGET_LPC408X/us_ticker.c @@ -67,3 +67,8 @@ void us_ticker_disable_interrupt(void) { void us_ticker_clear_interrupt(void) { US_TICKER_TIMER->IR = 1; } + +void us_ticker_free(void) +{ + +} diff --git a/targets/TARGET_NXP/TARGET_LPC43XX/us_ticker.c b/targets/TARGET_NXP/TARGET_LPC43XX/us_ticker.c index f509324fa36b..fb21b0e64abe 100644 --- a/targets/TARGET_NXP/TARGET_LPC43XX/us_ticker.c +++ b/targets/TARGET_NXP/TARGET_LPC43XX/us_ticker.c @@ -67,3 +67,8 @@ void us_ticker_disable_interrupt(void) { void us_ticker_clear_interrupt(void) { US_TICKER_TIMER->IR = 1; } + +void us_ticker_free(void) +{ + +} diff --git a/targets/TARGET_NXP/TARGET_LPC81X/us_ticker.c b/targets/TARGET_NXP/TARGET_LPC81X/us_ticker.c index 075505fc4663..b99a72a4746c 100644 --- a/targets/TARGET_NXP/TARGET_LPC81X/us_ticker.c +++ b/targets/TARGET_NXP/TARGET_LPC81X/us_ticker.c @@ -136,3 +136,8 @@ void us_ticker_clear_interrupt() { ticker_expired_count_us += ticker_fullcount_us; } } + +void us_ticker_free(void) +{ + +} diff --git a/targets/TARGET_NXP/TARGET_LPC82X/us_ticker.c b/targets/TARGET_NXP/TARGET_LPC82X/us_ticker.c index 4c441682912b..c4a4b03bd844 100644 --- a/targets/TARGET_NXP/TARGET_LPC82X/us_ticker.c +++ b/targets/TARGET_NXP/TARGET_LPC82X/us_ticker.c @@ -109,3 +109,8 @@ void us_ticker_clear_interrupt() { ticker_expired_count_us += ticker_fullcount_us; } } + +void us_ticker_free(void) +{ + +} diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/i2c_api.c b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/i2c_api.c index 5584ad9ab193..13425a654cc5 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/i2c_api.c +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/i2c_api.c @@ -23,8 +23,6 @@ #include "fsl_lpi2c.h" #include "PeripheralPins.h" -/* 7 bit IIC addr - R/W flag not included */ -static int i2c_address = 0; /* Array of I2C peripheral base address. */ static LPI2C_Type *const i2c_addrs[] = LPI2C_BASE_PTRS; @@ -37,7 +35,7 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) uint32_t i2c_sda = pinmap_peripheral(sda, PinMap_I2C_SDA); uint32_t i2c_scl = pinmap_peripheral(scl, PinMap_I2C_SCL); obj->instance = pinmap_merge(i2c_sda, i2c_scl); - obj->next_repeated_start = 0; + MBED_ASSERT((int)obj->instance != NC); lpi2c_master_config_t master_config; @@ -50,26 +48,43 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) pinmap_pinout(sda, PinMap_I2C_SDA); pinmap_pinout(scl, PinMap_I2C_SCL); + pin_mode(sda, PullUp_22K); + pin_mode(scl, PullUp_22K); + pin_mode_opendrain(sda, true); pin_mode_opendrain(scl, true); } int i2c_start(i2c_t *obj) { - if (LPI2C_MasterStart(i2c_addrs[obj->instance], 0, kLPI2C_Write) != kStatus_Success) { - return 1; - } + LPI2C_Type *base = i2c_addrs[obj->instance]; + int status = 0; - return 0; + obj->address_set = 0; + + /* Clear all flags. */ + LPI2C_MasterClearStatusFlags(base, kLPI2C_MasterEndOfPacketFlag | + kLPI2C_MasterStopDetectFlag | + kLPI2C_MasterNackDetectFlag | + kLPI2C_MasterArbitrationLostFlag | + kLPI2C_MasterFifoErrFlag | + kLPI2C_MasterPinLowTimeoutFlag | + kLPI2C_MasterDataMatchFlag); + + /* Turn off auto-stop option. */ + base->MCFGR1 &= ~LPI2C_MCFGR1_AUTOSTOP_MASK; + + return status; } int i2c_stop(i2c_t *obj) { - obj->next_repeated_start = 0; if (LPI2C_MasterStop(i2c_addrs[obj->instance]) != kStatus_Success) { return 1; } + obj->address_set = 0; + return 0; } @@ -78,7 +93,7 @@ void i2c_frequency(i2c_t *obj, int hz) uint32_t busClock; busClock = i2c_get_clock(); - LPI2C_MasterSetBaudRate(i2c_addrs[obj->instance], hz, busClock); + LPI2C_MasterSetBaudRate(i2c_addrs[obj->instance], busClock, hz); } int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) @@ -86,19 +101,14 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) LPI2C_Type *base = i2c_addrs[obj->instance]; lpi2c_master_transfer_t master_xfer; - i2c_address = address >> 1; memset(&master_xfer, 0, sizeof(master_xfer)); master_xfer.slaveAddress = address >> 1; master_xfer.direction = kLPI2C_Read; master_xfer.data = (uint8_t *)data; master_xfer.dataSize = length; - if (obj->next_repeated_start) { - master_xfer.flags |= kLPI2C_TransferRepeatedStartFlag; - } if (!stop) { master_xfer.flags |= kLPI2C_TransferNoStopFlag; } - obj->next_repeated_start = master_xfer.flags & kLPI2C_TransferNoStopFlag ? 1 : 0; /* The below function will issue a STOP signal at the end of the transfer. * This is required by the hardware in order to receive the last byte @@ -120,11 +130,20 @@ int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) return I2C_ERROR_NO_SLAVE; } + /* Wait till START has been flushed out of the FIFO */ + while (!(base->MSR & kLPI2C_MasterBusBusyFlag)) { + } + + /* Send the STOP signal */ + base->MTDR = LPI2C_MTDR_CMD(0x2U); + + /* Wait till STOP has been sent successfully */ + while (!(base->MSR & kLPI2C_MasterStopDetectFlag)) { + } + if (base->MSR & kLPI2C_MasterNackDetectFlag) { - i2c_stop(obj); return I2C_ERROR_NO_SLAVE; } else { - i2c_stop(obj); return length; } } @@ -134,13 +153,9 @@ int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) master_xfer.direction = kLPI2C_Write; master_xfer.data = (uint8_t *)data; master_xfer.dataSize = length; - if (obj->next_repeated_start) { - master_xfer.flags |= kLPI2C_TransferRepeatedStartFlag; - } if (!stop) { master_xfer.flags |= kLPI2C_TransferNoStopFlag; } - obj->next_repeated_start = master_xfer.flags & kLPI2C_TransferNoStopFlag ? 1 : 0; if (LPI2C_MasterTransferBlocking(base, &master_xfer) != kStatus_Success) { return I2C_ERROR_NO_SLAVE; @@ -161,11 +176,10 @@ int i2c_byte_read(i2c_t *obj, int last) lpi2c_master_transfer_t master_xfer; memset(&master_xfer, 0, sizeof(master_xfer)); - master_xfer.slaveAddress = i2c_address; master_xfer.direction = kLPI2C_Read; master_xfer.data = &data; master_xfer.dataSize = 1; - master_xfer.flags = kLPI2C_TransferNoStopFlag; + master_xfer.flags = kLPI2C_TransferNoStopFlag | kLPI2C_TransferNoStartFlag; if (LPI2C_MasterTransferBlocking(base, &master_xfer) != kStatus_Success) { return I2C_ERROR_NO_SLAVE; @@ -176,21 +190,37 @@ int i2c_byte_read(i2c_t *obj, int last) int i2c_byte_write(i2c_t *obj, int data) { LPI2C_Type *base = i2c_addrs[obj->instance]; - lpi2c_master_transfer_t master_xfer; - status_t ret_value; - - memset(&master_xfer, 0, sizeof(master_xfer)); - master_xfer.slaveAddress = i2c_address; - master_xfer.direction = kLPI2C_Write; - master_xfer.data = &data; - master_xfer.dataSize = 1; - master_xfer.flags = kLPI2C_TransferNoStopFlag; + uint32_t status; + size_t txCount; + size_t txFifoSize = FSL_FEATURE_LPI2C_FIFO_SIZEn(base); + + /* Clear error flags. */ + LPI2C_MasterClearStatusFlags(base, LPI2C_MasterGetStatusFlags(base)); + + /* Wait till there is room in the TX FIFO */ + do { + /* Get the number of words in the tx fifo and compute empty slots. */ + LPI2C_MasterGetFifoCounts(base, NULL, &txCount); + txCount = txFifoSize - txCount; + } while (!txCount); + + if (!obj->address_set) { + obj->address_set = 1; + /* Issue start command. */ + base->MTDR = LPI2C_MTDR_CMD(0x4U) | LPI2C_MTDR_DATA(data); + } else { + /* Write byte into LPI2C master data register. */ + base->MTDR = data; + } - ret_value = LPI2C_MasterTransferBlocking(base, &master_xfer); + /* Wait till data is pushed out of the FIFO */ + while (!(base->MSR & kLPI2C_MasterTxReadyFlag)) { + } - if (ret_value == kStatus_Success) { + status = LPI2C_MasterCheckAndClearError(base, LPI2C_MasterGetStatusFlags(base)); + if (status == kStatus_Success) { return 1; - } else if (ret_value == kStatus_LPI2C_Nak) { + } else if (status == kStatus_LPI2C_Nak) { return 0; } else { return 2; diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/lp_ticker.c b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/lp_ticker.c index 25be648495b7..e4f79853e7df 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/lp_ticker.c +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/lp_ticker.c @@ -112,4 +112,9 @@ void lp_ticker_clear_interrupt(void) GPT_ClearStatusFlags(GPT2, kGPT_OutputCompare1Flag); } +void lp_ticker_free(void) +{ + +} + #endif /* DEVICE_LPTICKER */ diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/objects.h b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/objects.h index b66380b99b94..f451465d4de2 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/objects.h +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/objects.h @@ -50,7 +50,7 @@ struct analogin_s { struct i2c_s { uint32_t instance; - uint8_t next_repeated_start; + uint8_t address_set; }; struct spi_s { diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/pinmap.c b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/pinmap.c index 9ccc1bd5673d..0f85ff05207d 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/pinmap.c +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/pinmap.c @@ -54,7 +54,8 @@ void pin_function(PinName pin, int function) } /* Write to the mux register */ - *((volatile uint32_t *)muxregister) = IOMUXC_SW_MUX_CTL_PAD_MUX_MODE(function); + *((volatile uint32_t *)muxregister) = IOMUXC_SW_MUX_CTL_PAD_MUX_MODE(function) | + IOMUXC_SW_MUX_CTL_PAD_SION((function >> SION_BIT_SHIFT) & 0x1); /* If required write to the input daisy register */ daisyregister = (function >> DAISY_REG_SHIFT) & 0xFFF; diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/sleep.c b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/sleep.c index 2b5307a99d48..59f01d78a40f 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/sleep.c +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/sleep.c @@ -17,23 +17,29 @@ #include "cmsis.h" #include "fsl_clock.h" -static void stop(void) -{ - SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; - __asm("WFI"); -} +extern void vPortPRE_SLEEP_PROCESSING(clock_mode_t powermode); +extern void vPortPOST_SLEEP_PROCESSING(clock_mode_t powermode); + void hal_sleep(void) { - CLOCK_SetMode(kCLOCK_ModeWait); + vPortPRE_SLEEP_PROCESSING(kCLOCK_ModeWait); - stop(); + __DSB(); + __WFI(); + __ISB(); + + vPortPOST_SLEEP_PROCESSING(kCLOCK_ModeWait); } void hal_deepsleep(void) { - CLOCK_SetMode(kCLOCK_ModeStop); + vPortPRE_SLEEP_PROCESSING(kCLOCK_ModeStop); + + __DSB(); + __WFI(); + __ISB(); - stop(); + vPortPOST_SLEEP_PROCESSING(kCLOCK_ModeStop); } diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/us_ticker.c b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/us_ticker.c index 188209d049a1..d3ac80b26c9f 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/us_ticker.c +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/us_ticker.c @@ -140,3 +140,8 @@ void us_ticker_fire_interrupt(void) { NVIC_SetPendingIRQ(PIT_IRQn); } + +void us_ticker_free(void) +{ + +} diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC/us_ticker.c b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC/us_ticker.c index 9c033c3690d3..763e08773982 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC/us_ticker.c +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC/us_ticker.c @@ -97,3 +97,11 @@ void us_ticker_fire_interrupt(void) { NVIC_SetPendingIRQ(CTIMER1_IRQn); } + +void us_ticker_free(void) +{ + CTIMER_StopTimer(CTIMER1); + CTIMER1->MCR &= ~1; + NVIC_DisableIRQ(CTIMER1_IRQn); + us_ticker_inited = false; +} diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/PeripheralNames.h b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/PeripheralNames.h index d230a607925a..cda975898e58 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/PeripheralNames.h +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/PeripheralNames.h @@ -37,6 +37,7 @@ typedef enum { #define STDIO_UART_RX USBRX #define STDIO_UART UART_1 +#define SION_BIT_SHIFT (3) #define DAISY_REG_SHIFT (4) #define DAISY_REG_VALUE_SHIFT (16) diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/PeripheralPins.c b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/PeripheralPins.c index db5a02e48636..fb5889835de1 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/PeripheralPins.c +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/PeripheralPins.c @@ -39,12 +39,12 @@ const PinMap PinMap_DAC[] = { /************I2C***************/ const PinMap PinMap_I2C_SDA[] = { - {GPIO_AD_B1_01, I2C_1, ((1U << DAISY_REG_VALUE_SHIFT) | (0x4D0 << DAISY_REG_SHIFT) | 3)}, + {GPIO_AD_B1_01, I2C_1, ((1U << DAISY_REG_VALUE_SHIFT) | (0x4D0 << DAISY_REG_SHIFT) | (1U << SION_BIT_SHIFT) | 3)}, {NC , NC , 0} }; const PinMap PinMap_I2C_SCL[] = { - {GPIO_AD_B1_00, I2C_1, ((1U << DAISY_REG_VALUE_SHIFT) | (0x4CC << DAISY_REG_SHIFT) | 3)}, + {GPIO_AD_B1_00, I2C_1, ((1U << DAISY_REG_VALUE_SHIFT) | (0x4CC << DAISY_REG_SHIFT) | (1U << SION_BIT_SHIFT) | 3)}, {NC , NC , 0} }; diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/lpm.c b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/lpm.c new file mode 100644 index 000000000000..35d2d4ede9a5 --- /dev/null +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/lpm.c @@ -0,0 +1,753 @@ +/* + * The Clear BSD License + * Copyright 2017 NXP + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted (subject to the limitations in the disclaimer below) provided + * that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. + * 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 "lpm.h" +#include "fsl_gpc.h" +#include "fsl_dcdc.h" +#include "fsl_gpt.h" +#include "fsl_lpuart.h" +#include "fsl_iomuxc.h" +#include "fsl_clock_config.h" +#include "serial_api.h" +#include "mbed_critical.h" +#include "cmsis.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define LPM_GPC_IMR_NUM (sizeof(GPC->IMR) / sizeof(GPC->IMR[0])) + +typedef struct _lpm_clock_context +{ + uint32_t armDiv; + uint32_t ahbDiv; + uint32_t ipgDiv; + uint32_t perDiv; + uint32_t perSel; + uint32_t periphSel; + uint32_t preperiphSel; + uint32_t pfd480; + uint32_t pfd528; + uint32_t pllArm_loopdiv; + uint32_t pllArm; + uint32_t pllSys; + uint32_t pllUsb1; + uint32_t pllUsb2; + uint32_t pllAudio; + uint32_t pllVideo; + uint32_t pllEnet; + uint32_t is_valid; +} lpm_clock_context_t; + +/******************************************************************************* + * Variables + ******************************************************************************/ + +static lpm_clock_context_t s_clockContext; +static uint32_t s_DllBackupValue = 0; + +/******************************************************************************* + * Code + ******************************************************************************/ + +void BOARD_SetLPClockGate(void) +{ + CCM->CCGR0 = 0x0F4000C5U; + CCM->CCGR1 = 0x541C0000U; + CCM->CCGR2 = 0x00150010U; + CCM->CCGR3 = 0x50040130U; + CCM->CCGR4 = 0x00005514U; + CCM->CCGR5 = 0x51001105U; + CCM->CCGR6 = 0x005405C0U; +} + +void BOARD_ResetLPClockGate(void) +{ + CCM->CCGR0 = 0xFFFFFFFFU; + CCM->CCGR1 = 0xFFFFFFFFU; + CCM->CCGR2 = 0xFFFFFFFFU; + CCM->CCGR3 = 0xFFFFFFFFU; + CCM->CCGR4 = 0xFFFFFFFFU; + CCM->CCGR5 = 0xFFFFFFFFU; + CCM->CCGR6 = 0xFFFFFFFFU; +} + +void LPM_SwitchToRcOSC(void) +{ + /* Switch to RC-OSC */ + XTALOSC24M->LOWPWR_CTRL_SET = XTALOSC24M_LOWPWR_CTRL_SET_OSC_SEL_MASK; + /* Turn off XTAL-OSC */ + CCM_ANALOG->MISC0_SET = CCM_ANALOG_MISC0_XTAL_24M_PWD_MASK; /* Power down */ + + /* Wait CCM operation finishes */ + CLOCK_CCM_HANDSHAKE_WAIT(); + /* Take some delay */ + LPM_DELAY(40); +} + +void LPM_SwitchToXtalOSC(void) +{ + /* Restore XTAL-OSC and enable detector */ + CCM_ANALOG->MISC0_CLR = CCM_ANALOG_MISC0_XTAL_24M_PWD_MASK; /* Power up */ + while ((XTALOSC24M->LOWPWR_CTRL & XTALOSC24M_LOWPWR_CTRL_XTALOSC_PWRUP_STAT_MASK) == 0) + { + } + CCM_ANALOG->MISC0_SET = CCM_ANALOG_MISC0_OSC_XTALOK_EN_MASK; /* detect freq */ + while ((CCM_ANALOG->MISC0 & CCM_ANALOG_MISC0_OSC_XTALOK_MASK) == 0) + { + } + CCM_ANALOG->MISC0_CLR = CCM_ANALOG_MISC0_OSC_XTALOK_EN_MASK; + + /* Switch to XTAL-OSC */ + XTALOSC24M->LOWPWR_CTRL_CLR = XTALOSC24M_LOWPWR_CTRL_CLR_OSC_SEL_MASK; + /* Turn off XTAL-OSC detector */ + CCM_ANALOG->MISC0_CLR = CCM_ANALOG_MISC0_OSC_XTALOK_EN_MASK; + + /* Wait CCM operation finishes */ + CLOCK_CCM_HANDSHAKE_WAIT(); + /* Take some delay */ + LPM_DELAY(40); +} + +void LPM_SwitchBandgap(void) +{ + /* Switch bandgap */ + PMU->MISC0_SET = 0x00000004; + XTALOSC24M->LOWPWR_CTRL_SET = XTALOSC24M_LOWPWR_CTRL_LPBG_SEL_MASK; + PMU->MISC0_SET = CCM_ANALOG_MISC0_REFTOP_PWD_MASK; + + /* Wait CCM operation finishes */ + CLOCK_CCM_HANDSHAKE_WAIT(); + /* Take some delay */ + LPM_DELAY(40); +} + +void LPM_RestoreBandgap(void) +{ + /* Restore bandgap */ + /* Turn on regular bandgap and wait for stable */ + PMU->MISC0_CLR = CCM_ANALOG_MISC0_REFTOP_PWD_MASK; + while ((PMU->MISC0 & PMU_MISC0_REFTOP_VBGUP_MASK) == 0) + { + } + /* Low power band gap disable */ + XTALOSC24M->LOWPWR_CTRL_CLR = XTALOSC24M_LOWPWR_CTRL_LPBG_SEL_MASK; + PMU->MISC0_CLR = 0x00000004; + + /* Wait CCM operation finishes */ + CLOCK_CCM_HANDSHAKE_WAIT(); + /* Take some delay */ + LPM_DELAY(40); +} + +void LPM_EnableWakeupSource(uint32_t irq) +{ + GPC_EnableIRQ(GPC, irq); +} + +void LPM_DisableWakeupSource(uint32_t irq) +{ + GPC_DisableIRQ(GPC, irq); +} + +/* + * ERR007265: CCM: When improper low-power sequence is used, + * the SoC enters low power mode before the ARM core executes WFI. + * + * Software workaround: + * 1) Software should trigger IRQ #41 (GPR_IRQ) to be always pending + * by setting IOMUX_GPR1_GINT. + * 2) Software should then unmask IRQ #41 in GPC before setting CCM + * Low-Power mode. + * 3) Software should mask IRQ #41 right after CCM Low-Power mode + * is set (set bits 0-1 of CCM_CLPCR). + */ +static void LPM_SetClockMode(clock_mode_t mode, uint32_t clpcr) +{ + switch (mode) + { + case kCLOCK_ModeRun: + CCM->CLPCR = clpcr; + break; + default: + LPM_EnableWakeupSource(GPR_IRQ_IRQn); + CCM->CLPCR = clpcr; + LPM_DisableWakeupSource(GPR_IRQ_IRQn); + break; + } +} + +void LPM_SwitchFlexspiClock(clock_mode_t powermode) +{ + while (!((FLEXSPI->STS0 & FLEXSPI_STS0_ARBIDLE_MASK) && (FLEXSPI->STS0 & FLEXSPI_STS0_SEQIDLE_MASK))) + { + ; + } + FLEXSPI->MCR0 |= FLEXSPI_MCR0_MDIS_MASK; + /* Disable clock gate of flexspi. */ + CCM->CCGR6 &= (~CCM_CCGR6_CG5_MASK); + + /* Periph_clk output will be used as SEMC clock root */ + CLOCK_SET_MUX(kCLOCK_SemcMux, 0x0); + /* Set post divider for SEMC clock as 0. */ + CLOCK_SET_DIV(kCLOCK_SemcDiv, 0x0); + + /* Wait CCM operation finishes */ + while (CCM->CDHIPR != 0) + { + } + + /* Semc_clk_root_pre will be used as flexspi clock. */ + CLOCK_SET_MUX(kCLOCK_FlexspiMux, 0x0); + /* Set divider for flexspi clock root 0. */ + CLOCK_SET_DIV(kCLOCK_FlexspiDiv, 0x0); + + /* Enable clock gate of flexspi. */ + CCM->CCGR6 |= (CCM_CCGR6_CG5_MASK); + + if (kCLOCK_ModeStop == powermode) { + FLEXSPI->DLLCR[0] = FLEXSPI_DLLCR_OVRDEN(1) | FLEXSPI_DLLCR_OVRDVAL(19); + } else { + FLEXSPI->DLLCR[0] = 0x79; + } + FLEXSPI->MCR0 &= ~FLEXSPI_MCR0_MDIS_MASK; + FLEXSPI->MCR0 |= FLEXSPI_MCR0_SWRESET_MASK; + + while (FLEXSPI->MCR0 & FLEXSPI_MCR0_SWRESET_MASK) { + } + + while (!((FLEXSPI->STS0 & FLEXSPI_STS0_ARBIDLE_MASK) && (FLEXSPI->STS0 & FLEXSPI_STS0_SEQIDLE_MASK))) { + } + + /* Take some delay */ + LPM_DELAY(40); +} + +void LPM_RestoreFlexspiClock(void) +{ + while (!((FLEXSPI->STS0 & FLEXSPI_STS0_ARBIDLE_MASK) && (FLEXSPI->STS0 & FLEXSPI_STS0_SEQIDLE_MASK))) + { + ; + } + FLEXSPI->MCR0 |= FLEXSPI_MCR0_MDIS_MASK; + /* Disable clock gate of flexspi. */ + CCM->CCGR6 &= (~CCM_CCGR6_CG5_MASK); + + /* PLL3 PFD0 will be used as flexspi clock. */ + CLOCK_SET_MUX(kCLOCK_FlexspiMux, 0x3); + /* Set divider for flexspi clock root 0. */ + CLOCK_SET_DIV(kCLOCK_FlexspiDiv, 0x0); + + /* Enable clock gate of flexspi. */ + CCM->CCGR6 |= (CCM_CCGR6_CG5_MASK); + + /* PLL2 PFD2 output will be used as SEMC clock root */ + CLOCK_SET_MUX(kCLOCK_SemcMux, 0x1); + /* Set post divider for SEMC clock as 1. */ + CLOCK_SET_DIV(kCLOCK_SemcDiv, 0x1); + + /* Wait CCM operation finishes */ + while (CCM->CDHIPR != 0) + { + } + + FLEXSPI->DLLCR[0] = s_DllBackupValue; + FLEXSPI->MCR0 &= ~FLEXSPI_MCR0_MDIS_MASK; + FLEXSPI->MCR0 |= FLEXSPI_MCR0_SWRESET_MASK; + while (FLEXSPI->MCR0 & FLEXSPI_MCR0_SWRESET_MASK) + { + } + while (!((FLEXSPI->STS0 & FLEXSPI_STS0_ARBIDLE_MASK) && (FLEXSPI->STS0 & FLEXSPI_STS0_SEQIDLE_MASK))) + { + ; + } + /* Take some delay */ + LPM_DELAY(40); +} + +void LPM_DisablePLLs(clock_mode_t powermode) +{ + s_clockContext.pfd480 = CCM_ANALOG->PFD_480; + s_clockContext.pfd528 = CCM_ANALOG->PFD_528; + s_clockContext.pllSys = CCM_ANALOG->PLL_SYS; + s_clockContext.pllUsb1 = CCM_ANALOG->PLL_USB1; + s_clockContext.pllUsb2 = CCM_ANALOG->PLL_USB2; + s_clockContext.pllAudio = CCM_ANALOG->PLL_AUDIO; + s_clockContext.pllVideo = CCM_ANALOG->PLL_VIDEO; + s_clockContext.pllEnet = CCM_ANALOG->PLL_ENET; + s_clockContext.pllArm_loopdiv = + (CCM_ANALOG->PLL_ARM & CCM_ANALOG_PLL_ARM_DIV_SELECT_MASK) >> CCM_ANALOG_PLL_ARM_DIV_SELECT_SHIFT; + s_clockContext.pllArm = CCM_ANALOG->PLL_ARM; + s_clockContext.periphSel = CLOCK_GetMux(kCLOCK_PeriphMux); + s_clockContext.ipgDiv = CLOCK_GetDiv(kCLOCK_IpgDiv); + s_clockContext.ahbDiv = CLOCK_GetDiv(kCLOCK_AhbDiv); + s_clockContext.perSel = CLOCK_GetMux(kCLOCK_PerclkMux); + s_clockContext.perDiv = CLOCK_GetDiv(kCLOCK_PerclkDiv); + s_clockContext.preperiphSel = CLOCK_GetMux(kCLOCK_PrePeriphMux); + s_clockContext.armDiv = CLOCK_GetDiv(kCLOCK_ArmDiv); + s_clockContext.is_valid = 1; + + /* Power off USB2 PLL */ + CCM_ANALOG->PLL_USB2_SET = CCM_ANALOG_PLL_USB2_BYPASS_MASK; + CCM_ANALOG->PLL_USB2_CLR = CCM_ANALOG_PLL_USB2_POWER_MASK; + /* Power off AUDIO PLL */ + CCM_ANALOG->PLL_AUDIO_SET = CCM_ANALOG_PLL_AUDIO_BYPASS_MASK; + CCM_ANALOG->PLL_AUDIO_SET = CCM_ANALOG_PLL_AUDIO_POWERDOWN_MASK; + /* Power off VIDEO PLL */ + CCM_ANALOG->PLL_VIDEO_SET = CCM_ANALOG_PLL_VIDEO_BYPASS_MASK; + CCM_ANALOG->PLL_VIDEO_SET = CCM_ANALOG_PLL_VIDEO_POWERDOWN_MASK; + /* Power off ENET PLL */ + CCM_ANALOG->PLL_ENET_SET = CCM_ANALOG_PLL_ENET_BYPASS_MASK; + CCM_ANALOG->PLL_ENET_SET = CCM_ANALOG_PLL_ENET_POWERDOWN_MASK; + + if (kCLOCK_ModeWait == powermode) { + CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 1); + CLOCK_SetDiv(kCLOCK_PeriphClk2Div, 0); + CLOCK_SetMux(kCLOCK_PeriphMux, 1); + CLOCK_SetDiv(kCLOCK_IpgDiv, 0); + CLOCK_SetDiv(kCLOCK_AhbDiv, 0); + + /*ARM PLL as clksource*/ + /* 24 * 88 / 2 / 8 = 132MHz */ + CCM_ANALOG->PLL_ARM_CLR = CCM_ANALOG_PLL_ARM_POWERDOWN_MASK; + CCM_ANALOG->PLL_ARM_SET = CCM_ANALOG_PLL_ARM_ENABLE_MASK | CCM_ANALOG_PLL_ARM_BYPASS_MASK; + CCM_ANALOG->PLL_ARM_CLR = CCM_ANALOG_PLL_ARM_DIV_SELECT_MASK; + CCM_ANALOG->PLL_ARM_SET = CCM_ANALOG_PLL_ARM_DIV_SELECT(88); + CLOCK_SetDiv(kCLOCK_ArmDiv, 7); + CCM_ANALOG->PLL_ARM_CLR = CCM_ANALOG_PLL_ARM_BYPASS_MASK; + + /*Select ARM_PLL for pre_periph_clock */ + CLOCK_SetMux(kCLOCK_PrePeriphMux, 3); + CLOCK_SetMux(kCLOCK_PeriphMux, 0); + + /* SET AHB, IPG to 33MHz */ + CLOCK_SetDiv(kCLOCK_IpgDiv, 0); + CLOCK_SetDiv(kCLOCK_AhbDiv, 3); + + /*Set PERCLK to 33MHz*/ + //CLOCK_SetMux(kCLOCK_PerclkMux, 0); + //CLOCK_SetDiv(kCLOCK_PerclkDiv, 0); + } else { + CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 1); + CLOCK_SetDiv(kCLOCK_PeriphClk2Div, 0); + CLOCK_SetMux(kCLOCK_PeriphMux, 1); + CLOCK_SetDiv(kCLOCK_IpgDiv, 0); + CLOCK_SetDiv(kCLOCK_AhbDiv, 0); + + /*ARM PLL as clksource*/ + CCM_ANALOG->PLL_ARM |= CCM_ANALOG_PLL_ARM_ENABLE_MASK | CCM_ANALOG_PLL_ARM_BYPASS_MASK; + /* Power off ARM PLL */ + CCM_ANALOG->PLL_ARM_SET = CCM_ANALOG_PLL_ARM_POWERDOWN_MASK; + + /*Select ARM_PLL for pre_periph_clock */ + CLOCK_SetDiv(kCLOCK_ArmDiv, 0x0); + CLOCK_SetMux(kCLOCK_PrePeriphMux, 0x3); + CLOCK_SetMux(kCLOCK_PeriphMux, 0x0); + + /* SET AHB, IPG to 12MHz */ + CLOCK_SetDiv(kCLOCK_IpgDiv, 0); + CLOCK_SetDiv(kCLOCK_AhbDiv, 1); + + /*Set PERCLK to 12Mhz*/ + //CLOCK_SetMux(kCLOCK_PerclkMux, 0x0); + //CLOCK_SetDiv(kCLOCK_PerclkDiv, 0x0); + } + + core_util_critical_section_enter(); + LPM_SwitchFlexspiClock(powermode); + core_util_critical_section_exit(); + + CLOCK_DeinitUsb1Pfd(kCLOCK_Pfd0); + CLOCK_DeinitUsb1Pfd(kCLOCK_Pfd1); + CLOCK_DeinitUsb1Pfd(kCLOCK_Pfd2); + CLOCK_DeinitUsb1Pfd(kCLOCK_Pfd3); + + /* Power off USB1 PLL */ + CCM_ANALOG->PLL_USB1_SET = CCM_ANALOG_PLL_USB1_BYPASS_MASK; + CCM_ANALOG->PLL_USB1_CLR = CCM_ANALOG_PLL_USB1_POWER_MASK; + + CLOCK_DeinitSysPfd(kCLOCK_Pfd0); + CLOCK_DeinitSysPfd(kCLOCK_Pfd1); + CLOCK_DeinitSysPfd(kCLOCK_Pfd2); + CLOCK_DeinitSysPfd(kCLOCK_Pfd3); + + /* When need to close PLL, we need to use bypass clock first and then power it down. */ + /* Power off SYS PLL */ + CCM_ANALOG->PLL_SYS_SET = CCM_ANALOG_PLL_SYS_BYPASS_MASK; + CCM_ANALOG->PLL_SYS_SET = CCM_ANALOG_PLL_SYS_POWERDOWN_MASK; +} + +void LPM_RestorePLLs(void) +{ + if (s_clockContext.is_valid) + { + /* Bypass PLL first */ + CCM_ANALOG->PLL_USB1 = (CCM_ANALOG->PLL_USB1 & (~CCM_ANALOG_PLL_USB1_BYPASS_CLK_SRC_MASK)) | + CCM_ANALOG_PLL_USB1_BYPASS_MASK; + + CCM_ANALOG->PLL_USB1 = (CCM_ANALOG->PLL_USB1 & (~CCM_ANALOG_PLL_USB1_DIV_SELECT_MASK)) | + CCM_ANALOG_PLL_USB1_ENABLE_MASK | CCM_ANALOG_PLL_USB1_POWER_MASK | + CCM_ANALOG_PLL_USB1_EN_USB_CLKS_MASK; + + while ((CCM_ANALOG->PLL_USB1 & CCM_ANALOG_PLL_USB1_LOCK_MASK) == 0) + { + } + + /* Disable Bypass */ + CCM_ANALOG->PLL_USB1 &= ~CCM_ANALOG_PLL_USB1_BYPASS_MASK; + + /* Restore USB1 PLL PFD */ + CCM_ANALOG->PFD_480 = s_clockContext.pfd480; + CCM_ANALOG->PFD_480_CLR = CCM_ANALOG_PFD_480_PFD0_CLKGATE_MASK; + + /* Disable Usb1 PLL output for USBPHY1. */ + CCM_ANALOG->PLL_USB1 &= ~CCM_ANALOG_PLL_USB1_EN_USB_CLKS_MASK; + + /* When need to enable PLL, we need to use bypass clock first and then switch pll back. */ + /* Power on SYS PLL and wait for locked */ + CCM_ANALOG->PLL_SYS_SET = CCM_ANALOG_PLL_SYS_BYPASS_MASK; + CCM_ANALOG->PLL_SYS_CLR = CCM_ANALOG_PLL_SYS_POWERDOWN_MASK; + CCM_ANALOG->PLL_SYS = s_clockContext.pllSys; + + while ((CCM_ANALOG->PLL_SYS & CCM_ANALOG_PLL_SYS_LOCK_MASK) == 0) + { + } + + /* Restore SYS PLL PFD */ + CCM_ANALOG->PFD_528 = s_clockContext.pfd528; + CCM_ANALOG->PFD_528_CLR = CCM_ANALOG_PFD_528_PFD2_CLKGATE_MASK; + + core_util_critical_section_enter(); + LPM_RestoreFlexspiClock(); + core_util_critical_section_exit(); + } else { + return; + } + + CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 0); + CLOCK_SetDiv(kCLOCK_PeriphClk2Div, 0); + CLOCK_SetMux(kCLOCK_PeriphMux, 1); + CLOCK_SetDiv(kCLOCK_IpgDiv, 0x3); + CLOCK_SetDiv(kCLOCK_AhbDiv, 0x0); + + /* ARM PLL as clksource*/ + CCM_ANALOG->PLL_ARM_CLR = CCM_ANALOG_PLL_ARM_POWERDOWN_MASK; + CCM_ANALOG->PLL_ARM_SET = CCM_ANALOG_PLL_ARM_ENABLE_MASK | CCM_ANALOG_PLL_ARM_BYPASS_MASK; + + CLOCK_SetDiv(kCLOCK_ArmDiv, s_clockContext.armDiv); + CCM_ANALOG->PLL_ARM_CLR = CCM_ANALOG_PLL_ARM_DIV_SELECT_MASK; + CCM_ANALOG->PLL_ARM_SET = CCM_ANALOG_PLL_ARM_DIV_SELECT(s_clockContext.pllArm_loopdiv); + if ((s_clockContext.pllArm & CCM_ANALOG_PLL_ARM_BYPASS_MASK) == 0) + { + while ((CCM_ANALOG->PLL_ARM & CCM_ANALOG_PLL_ARM_LOCK_MASK) == 0) + { + } + } + if ((s_clockContext.pllArm & CCM_ANALOG_PLL_ARM_BYPASS_MASK) == 0) + { + CCM_ANALOG->PLL_ARM_CLR = CCM_ANALOG_PLL_ARM_BYPASS_MASK; + } + + /* Restore AHB and IPG div */ + CCM->CBCDR = (CCM->CBCDR & ~(CCM_CBCDR_AHB_PODF_MASK | CCM_CBCDR_IPG_PODF_MASK | CCM_CBCDR_PERIPH_CLK_SEL_MASK)) | + CCM_CBCDR_AHB_PODF(s_clockContext.ahbDiv) | CCM_CBCDR_IPG_PODF(s_clockContext.ipgDiv) | + CCM_CBCDR_PERIPH_CLK_SEL(s_clockContext.periphSel); + + /* Restore Periphral clock */ + CCM->CSCMR1 = (CCM->CSCMR1 & ~CCM_CSCMR1_PERCLK_PODF_MASK) | CCM_CSCMR1_PERCLK_PODF(s_clockContext.perDiv) | + CCM_CSCMR1_PERCLK_CLK_SEL(s_clockContext.perSel); + + /* Switch clocks back */ + CCM->CBCMR = + (CCM->CBCMR & ~CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK) | CCM_CBCMR_PRE_PERIPH_CLK_SEL(s_clockContext.preperiphSel); + + /* Wait CCM operation finishes */ + while (CCM->CDHIPR != 0) + { + } + + /* Restore USB2 PLL */ + CCM_ANALOG->PLL_USB2_SET = CCM_ANALOG_PLL_USB2_BYPASS_MASK; + CCM_ANALOG->PLL_USB2_SET = CCM_ANALOG_PLL_USB2_POWER_MASK; + CCM_ANALOG->PLL_USB2 = s_clockContext.pllUsb2; + if ((CCM_ANALOG->PLL_USB2 & CCM_ANALOG_PLL_USB2_POWER_MASK) != 0) + { + while ((CCM_ANALOG->PLL_USB2 & CCM_ANALOG_PLL_USB2_LOCK_MASK) == 0) + { + } + } + + /* Restore AUDIO PLL */ + CCM_ANALOG->PLL_AUDIO_SET = CCM_ANALOG_PLL_AUDIO_BYPASS_MASK; + CCM_ANALOG->PLL_AUDIO_CLR = CCM_ANALOG_PLL_AUDIO_POWERDOWN_MASK; + CCM_ANALOG->PLL_AUDIO = s_clockContext.pllAudio; + if ((CCM_ANALOG->PLL_AUDIO & CCM_ANALOG_PLL_AUDIO_POWERDOWN_MASK) == 0) + { + while ((CCM_ANALOG->PLL_AUDIO & CCM_ANALOG_PLL_AUDIO_LOCK_MASK) == 0) + { + } + } + + /* Restore VIDEO PLL */ + CCM_ANALOG->PLL_VIDEO_SET = CCM_ANALOG_PLL_VIDEO_BYPASS_MASK; + CCM_ANALOG->PLL_VIDEO_CLR = CCM_ANALOG_PLL_VIDEO_POWERDOWN_MASK; + CCM_ANALOG->PLL_VIDEO = s_clockContext.pllVideo; + if ((CCM_ANALOG->PLL_VIDEO & CCM_ANALOG_PLL_VIDEO_POWERDOWN_MASK) == 0) + { + while ((CCM_ANALOG->PLL_VIDEO & CCM_ANALOG_PLL_VIDEO_LOCK_MASK) == 0) + { + } + } + + /* Restore ENET PLL */ + CCM_ANALOG->PLL_ENET_SET = CCM_ANALOG_PLL_ENET_BYPASS_MASK; + CCM_ANALOG->PLL_ENET_SET = CCM_ANALOG_PLL_ENET_POWERDOWN_MASK; + CCM_ANALOG->PLL_ENET = s_clockContext.pllEnet; + if ((CCM_ANALOG->PLL_ENET & CCM_ANALOG_PLL_ENET_POWERDOWN_MASK) == 0) + { + while ((CCM_ANALOG->PLL_ENET & CCM_ANALOG_PLL_ENET_LOCK_MASK) == 0) + { + } + } + + s_clockContext.is_valid = 0; +} + +static void LPM_SystemIdle(clock_mode_t powermode) +{ + /* Switch DCDC to use DCDC internal OSC */ + DCDC_SetClockSource(DCDC, kDCDC_ClockInternalOsc); + + /* Power down USBPHY */ + USBPHY1->CTRL = 0xFFFFFFFF; + USBPHY2->CTRL = 0xFFFFFFFF; + + LPM_DisablePLLs(powermode); + + /* Enable weak 2P5 and turn off regular 2P5 */ + PMU->REG_2P5 &= ~PMU_REG_2P5_ENABLE_LINREG_MASK; + PMU->REG_2P5 |= PMU_REG_2P5_ENABLE_WEAK_LINREG_MASK; + + /* Enable weak 1P1 and turn off regular 1P1 */ + PMU->REG_1P1 &= ~PMU_REG_1P1_ENABLE_LINREG_MASK; + PMU->REG_1P1 |= PMU_REG_1P1_ENABLE_WEAK_LINREG_MASK; + + core_util_critical_section_enter(); + LPM_SwitchToRcOSC(); + core_util_critical_section_exit(); + + /* Lower OSC current by 37.5% */ + CCM_ANALOG->MISC0_SET = CCM_ANALOG_MISC0_OSC_I_MASK; + /* Enable FET ODRIVE */ + PMU->REG_CORE_SET = PMU_REG_CORE_FET_ODRIVE_MASK; + /* Disconnect vdd_high_in and connect vdd_snvs_in */ + CCM_ANALOG->MISC0_SET = CCM_ANALOG_MISC0_DISCON_HIGH_SNVS_MASK; + + DCDC_AdjustTargetVoltage(DCDC, 0x6, 0x1); + + core_util_critical_section_enter(); + LPM_SwitchBandgap(); + core_util_critical_section_exit(); + + /* RBC = 0; Enable COSC, OSC COUNT = 0xAF */ + CCM->CCR = (CCM_CCR_COSC_EN_MASK | CCM_CCR_OSCNT(0xAF)); +} + +void LPM_SystemRestoreIdle(void) +{ + DCDC_AdjustTargetVoltage(DCDC, 0x12, 0x1); + + /* Switch DCDC to use DCDC internal OSC */ + DCDC_SetClockSource(DCDC, kDCDC_ClockExternalOsc); + + /* Disconnect vdd_snvs_in and connect vdd_high_in */ + CCM_ANALOG->MISC0_CLR = CCM_ANALOG_MISC0_DISCON_HIGH_SNVS_MASK; + /* Increase OSC current to normal */ + CCM_ANALOG->MISC0_CLR = CCM_ANALOG_MISC0_OSC_I_MASK; + + core_util_critical_section_enter(); + LPM_SwitchToXtalOSC(); + LPM_RestoreBandgap(); + core_util_critical_section_exit(); + + /* Disable FET ODRIVE */ + PMU->REG_CORE_CLR = PMU_REG_CORE_FET_ODRIVE_MASK; + + /* Enable regular 2P5 and wait for stable */ + PMU->REG_2P5_SET = PMU_REG_2P5_ENABLE_LINREG_MASK; + while ((PMU->REG_2P5 & PMU_REG_2P5_OK_VDD2P5_MASK) == 0) + { + } + /* Turn off weak 2P5 */ + PMU->REG_2P5_CLR = PMU_REG_2P5_ENABLE_WEAK_LINREG_MASK; + + /* Enable regular 1P1 and wait for stable */ + PMU->REG_1P1_SET = PMU_REG_1P1_ENABLE_LINREG_MASK; + while ((PMU->REG_1P1 & PMU_REG_1P1_OK_VDD1P1_MASK) == 0) + { + } + /* Turn off weak 1P1 */ + PMU->REG_1P1_CLR = PMU_REG_1P1_ENABLE_WEAK_LINREG_MASK; + + LPM_RestorePLLs(); +} + +bool LPM_Init(void) +{ + uint32_t i; + uint32_t tmp_reg = 0; + + CLOCK_SetMode(kCLOCK_ModeRun); + + CCM->CGPR |= CCM_CGPR_INT_MEM_CLK_LPM_MASK; + + /* Enable RC OSC. It needs at least 4ms to be stable, so self tuning need to be enabled. */ + XTALOSC24M->LOWPWR_CTRL |= XTALOSC24M_LOWPWR_CTRL_RC_OSC_EN_MASK; + /* Configure RC OSC */ + XTALOSC24M->OSC_CONFIG0 = XTALOSC24M_OSC_CONFIG0_RC_OSC_PROG_CUR(0x4) | XTALOSC24M_OSC_CONFIG0_SET_HYST_MINUS(0x2) | + XTALOSC24M_OSC_CONFIG0_RC_OSC_PROG(0xA7) | XTALOSC24M_OSC_CONFIG0_START_MASK | + XTALOSC24M_OSC_CONFIG0_ENABLE_MASK; + XTALOSC24M->OSC_CONFIG1 = XTALOSC24M_OSC_CONFIG1_COUNT_RC_CUR(0x40) | XTALOSC24M_OSC_CONFIG1_COUNT_RC_TRG(0x2DC); + /* Take some delay */ + LPM_DELAY(40); + /* Add some hysteresis */ + tmp_reg = XTALOSC24M->OSC_CONFIG0; + tmp_reg &= ~(XTALOSC24M_OSC_CONFIG0_HYST_PLUS_MASK | XTALOSC24M_OSC_CONFIG0_HYST_MINUS_MASK); + tmp_reg |= XTALOSC24M_OSC_CONFIG0_HYST_PLUS(3) | XTALOSC24M_OSC_CONFIG0_HYST_MINUS(3); + XTALOSC24M->OSC_CONFIG0 = tmp_reg; + /* Set COUNT_1M_TRG */ + tmp_reg = XTALOSC24M->OSC_CONFIG2; + tmp_reg &= ~XTALOSC24M_OSC_CONFIG2_COUNT_1M_TRG_MASK; + tmp_reg |= XTALOSC24M_OSC_CONFIG2_COUNT_1M_TRG(0x2d7); + XTALOSC24M->OSC_CONFIG2 = tmp_reg; + /* Hardware requires to read OSC_CONFIG0 or OSC_CONFIG1 to make OSC_CONFIG2 write work */ + tmp_reg = XTALOSC24M->OSC_CONFIG1; + XTALOSC24M->OSC_CONFIG1 = tmp_reg; + + s_DllBackupValue = FLEXSPI->DLLCR[0]; + + /* ERR007265 */ + IOMUXC_GPR->GPR1 |= IOMUXC_GPR_GPR1_GINT_MASK; + + /* Initialize GPC to mask all IRQs */ + for (i = 0; i < LPM_GPC_IMR_NUM; i++) { + GPC->IMR[i] = 0xFFFFFFFFU; + } + + return true; +} + +void LPM_Deinit(void) +{ + /* ERR007265 */ + IOMUXC_GPR->GPR1 &= ~IOMUXC_GPR_GPR1_GINT_MASK; +} + +void vPortPRE_SLEEP_PROCESSING(clock_mode_t powermode) +{ + uint32_t clpcr; + + clpcr = CCM->CLPCR & (~(CCM_CLPCR_LPM_MASK | CCM_CLPCR_ARM_CLK_DIS_ON_LPM_MASK)); + + switch (powermode) + { + case kCLOCK_ModeWait: +#if 0 + LPM_EnableWakeupSource(PIT_IRQn); + + LPM_SetClockMode(kCLOCK_ModeWait, clpcr | CCM_CLPCR_LPM(kCLOCK_ModeWait) | + CCM_CLPCR_ARM_CLK_DIS_ON_LPM_MASK | CCM_CLPCR_STBY_COUNT_MASK | 0x1C | + 0x08280000); + IOMUXC_GPR->GPR8 = 0xaaaaaaaa; + IOMUXC_GPR->GPR12 = 0x0000000a; +#endif + break; + case kCLOCK_ModeStop: + LPM_EnableWakeupSource(GPT2_IRQn); + + LPM_SetClockMode(kCLOCK_ModeWait, clpcr | CCM_CLPCR_LPM(kCLOCK_ModeWait) | + CCM_CLPCR_ARM_CLK_DIS_ON_LPM_MASK | CCM_CLPCR_STBY_COUNT_MASK | 0x1C | + 0x08280000); + BOARD_SetLPClockGate(); + LPM_SystemIdle(powermode); + IOMUXC_GPR->GPR8 = 0xaaaaaaaa; + IOMUXC_GPR->GPR12 = 0x0000000a; + break; + default: + assert(false); + break; + } +} + +void vPortPOST_SLEEP_PROCESSING(clock_mode_t powermode) +{ + uint32_t clpcr; + + clpcr = CCM->CLPCR & (~(CCM_CLPCR_LPM_MASK | CCM_CLPCR_ARM_CLK_DIS_ON_LPM_MASK)); + + switch (powermode) + { + case kCLOCK_ModeWait: +#if 0 + + IOMUXC_GPR->GPR8 = 0x00000000; + IOMUXC_GPR->GPR12 = 0x00000000; + LPM_SetClockMode(kCLOCK_ModeRun, clpcr); + + LPM_DisableWakeupSource(PIT_IRQn); +#endif + + break; + case kCLOCK_ModeStop: + __NOP(); + __NOP(); + __NOP(); + __NOP(); + IOMUXC_GPR->GPR8 = 0x00000000; + IOMUXC_GPR->GPR12 = 0x00000000; + /* Interrupt occurs before system idle */ + LPM_SystemRestoreIdle(); + BOARD_ResetLPClockGate(); + + LPM_SetClockMode(kCLOCK_ModeRun, clpcr); + + LPM_DisableWakeupSource(GPT2_IRQn); + + break; + default: + assert(false); + break; + } +} + diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/lpm.h b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/lpm.h new file mode 100644 index 000000000000..c1b9a787447a --- /dev/null +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/lpm.h @@ -0,0 +1,153 @@ +/* + * The Clear BSD License + * Copyright 2017 NXP + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted (subject to the limitations in the disclaimer below) provided + * that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. + * 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 _LPM_H_ +#define _LPM_H_ + +#include "fsl_clock.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +extern void vPortGPTIsr(void); + +#define vPortGptIsr GPT1_IRQHandler + +#define CLOCK_SET_MUX(mux, value) \ + \ +do \ + { \ + CCM_TUPLE_REG(CCM, mux) = (CCM_TUPLE_REG(CCM, mux) & (~CCM_TUPLE_MASK(mux))) | \ + (((uint32_t)((value) << CCM_TUPLE_SHIFT(mux))) & CCM_TUPLE_MASK(mux)); \ + while (CCM->CDHIPR != 0) \ + { \ + } \ + \ +} \ + while (0) + +#define CLOCK_SET_DIV(divider, value) \ + \ +do \ + { \ + CCM_TUPLE_REG(CCM, divider) = (CCM_TUPLE_REG(CCM, divider) & (~CCM_TUPLE_MASK(divider))) | \ + (((uint32_t)((value) << CCM_TUPLE_SHIFT(divider))) & CCM_TUPLE_MASK(divider)); \ + while (CCM->CDHIPR != 0) \ + { \ + } \ + \ +} \ + while (0) + +#define CLOCK_CCM_HANDSHAKE_WAIT() \ + \ +do \ + { \ + while (CCM->CDHIPR != 0) \ + { \ + } \ + \ +} \ + while (0) + +#define LPM_DELAY(value) \ + \ +do \ + { \ + for (uint32_t i = 0; i < 5 * value; i++) \ + { \ + __NOP(); \ + } \ + \ +} \ + while (0) + +#define ROM_CODE_ENTRY_ADDR (0x200000U) + +/*! @name Time sensitive region */ +/* @{ */ +#if defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1) +#if (defined(__ICCARM__)) +#define AT_QUICKACCESS_SECTION_CODE(func) __ramfunc func +#elif(defined(__ARMCC_VERSION)) +#define AT_QUICKACCESS_SECTION_CODE(func) __attribute__((section("RamFunction"))) func +#elif defined(__MCUXPRESSO) +#define AT_QUICKACCESS_SECTION_CODE(func) __attribute__((section(".ramfunc.$SRAM_ITC"))) func +#elif(defined(__GNUC__)) +#define AT_QUICKACCESS_SECTION_CODE(func) __attribute__((section("RamFunction"))) func +#else +#error Toolchain not supported. +#endif /* defined(__ICCARM__) */ +#else +#if (defined(__ICCARM__)) +#define AT_QUICKACCESS_SECTION_CODE(func) func +#elif(defined(__ARMCC_VERSION)) +#define AT_QUICKACCESS_SECTION_CODE(func) func +#elif(defined(__MCUXPRESSO)) +#define AT_QUICKACCESS_SECTION_CODE(func) func +#elif(defined(__GNUC__)) +#define AT_QUICKACCESS_SECTION_CODE(func) func +#else +#error Toolchain not supported. +#endif +#endif /* __FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE */ + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +AT_QUICKACCESS_SECTION_CODE(void LPM_SwitchFlexspiClock(clock_mode_t powermode)); +AT_QUICKACCESS_SECTION_CODE(void LPM_RestoreFlexspiClock(void)); + +/* Initialize the Low Power Management */ +bool LPM_Init(void); + +/* Deinitialize the Low Power Management */ +void LPM_Deinit(void); + +/* Enable wakeup source in low power mode */ +void LPM_EnableWakeupSource(uint32_t irq); + +/* Disable wakeup source in low power mode */ +void LPM_DisableWakeupSource(uint32_t irq); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _LPM_H_ */ diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/mbed_overrides.c b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/mbed_overrides.c index ca9b6e10a1c6..d27ee85a3411 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/mbed_overrides.c +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/mbed_overrides.c @@ -14,9 +14,9 @@ * limitations under the License. */ #include "pinmap.h" - #include "fsl_clock_config.h" #include "fsl_clock.h" +#include "lpm.h" #define LPSPI_CLOCK_SOURCE_DIVIDER (7U) #define LPI2C_CLOCK_SOURCE_DIVIDER (5U) @@ -124,11 +124,39 @@ void BOARD_ConfigMPU(void) SCB_EnableICache(); } +#if defined(TOOLCHAIN_GCC_ARM) +extern uint32_t __ram_function_flash_start[]; +#define __RAM_FUNCTION_FLASH_START __ram_function_flash_start +extern uint32_t __ram_function_ram_start[]; +#define __RAM_FUNCTION_RAM_START __ram_function_ram_start +extern uint32_t __ram_function_size[]; +#define __RAM_FUNCTION_SIZE __ram_function_size +void Board_CopyToRam() +{ + unsigned char *source; + unsigned char *destiny; + unsigned int size; + + source = (unsigned char *)(__RAM_FUNCTION_FLASH_START); + destiny = (unsigned char *)(__RAM_FUNCTION_RAM_START); + size = (unsigned long)(__RAM_FUNCTION_SIZE); + + while (size--) + { + *destiny++ = *source++; + } +} +#endif + // called before main void mbed_sdk_init() { BOARD_ConfigMPU(); BOARD_BootClockRUN(); +#if defined(TOOLCHAIN_GCC_ARM) + Board_CopyToRam(); +#endif + LPM_Init(); } void spi_setup_clock() diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/device/TOOLCHAIN_ARM_STD/MIMXRT1052xxxxx.sct b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/device/TOOLCHAIN_ARM_STD/MIMXRT1052xxxxx.sct index 4f310217c9ad..5f6808f434f6 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/device/TOOLCHAIN_ARM_STD/MIMXRT1052xxxxx.sct +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/device/TOOLCHAIN_ARM_STD/MIMXRT1052xxxxx.sct @@ -77,6 +77,9 @@ #define m_text_start 0x60002400 #define m_text_size 0x03FFDC00 +#define m_text2_start 0x00000000 +#define m_text2_size 0x00020000 + #define m_data_start 0x80000000 #define m_data_size 0x01E00000 @@ -139,6 +142,9 @@ LR_IROM1 m_flash_config_start m_text_start+m_text_size-m_flash_config_start { } ARM_LIB_STACK m_data_start+m_data_size EMPTY -Stack_Size { ; Stack region growing down } + RW_m_ram_text m_text2_start UNINIT m_text2_size { ; load address = execution address + * (RamFunction) + } RW_m_ncache m_ncache_start m_ncache_size { ; ncache RW data * (NonCacheable.init) * (NonCacheable) diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/device/TOOLCHAIN_GCC_ARM/MIMXRT1052xxxxx.ld b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/device/TOOLCHAIN_GCC_ARM/MIMXRT1052xxxxx.ld index d39ceb05e1fb..6cd4cd0bced6 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/device/TOOLCHAIN_GCC_ARM/MIMXRT1052xxxxx.ld +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/device/TOOLCHAIN_GCC_ARM/MIMXRT1052xxxxx.ld @@ -72,6 +72,7 @@ MEMORY m_ivt (RX) : ORIGIN = 0x60001000, LENGTH = 0x00001000 m_interrupts (RX) : ORIGIN = 0x60002000, LENGTH = 0x00000400 m_text (RX) : ORIGIN = 0x60002400, LENGTH = 0x03FFDC00 + m_text2 (RX) : ORIGIN = 0x00000000, LENGTH = 0x00020000 m_data (RW) : ORIGIN = 0x80000000, LENGTH = 0x01E00000 m_ncache (RW) : ORIGIN = 0x81E00000, LENGTH = 0x00200000 m_data2 (RW) : ORIGIN = 0x20000000, LENGTH = 0x00020000 @@ -225,7 +226,21 @@ SECTIONS __data_end__ = .; /* define a global symbol at data end */ } > m_data - __NDATA_ROM = __DATA_ROM + (__data_end__ - __data_start__); + __ram_function_flash_start = __DATA_ROM + (__data_end__ - __data_start__); /* Symbol is used by startup for TCM data initialization */ + + .ram_function : AT(__ram_function_flash_start) + { + . = ALIGN(32); + __ram_function_ram_start = .; + *(RamFunction) + . = ALIGN(128); + __ram_function_ram_end = .; + } > m_text2 + + __ram_function_size = SIZEOF(.ram_function); + + __NDATA_ROM = __ram_function_flash_start + SIZEOF(.ram_function); + .ncache.init : AT(__NDATA_ROM) { __noncachedata_start__ = .; /* create a global symbol at ncache data start */ diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/device/TOOLCHAIN_IAR/MIMXRT1052xxxxx.icf b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/device/TOOLCHAIN_IAR/MIMXRT1052xxxxx.icf index 7bc7fe409c10..f96e9c40ce95 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/device/TOOLCHAIN_IAR/MIMXRT1052xxxxx.icf +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/device/TOOLCHAIN_IAR/MIMXRT1052xxxxx.icf @@ -67,6 +67,9 @@ define symbol m_interrupts_end = 0x600023FF; define symbol m_text_start = 0x60002400; define symbol m_text_end = 0x63FFFFFF; +define symbol m_text2_start = 0x00000000; +define symbol m_text2_end = 0x0001FFFF; + define symbol m_interrupts_ram_start = 0x20000000; define symbol m_interrupts_ram_end = 0x20000000 + __ram_vector_table_offset__; @@ -108,6 +111,8 @@ define memory mem with size = 4G; define region TEXT_region = mem:[from m_interrupts_start to m_interrupts_end] | mem:[from m_text_start to m_text_end]; +define region TEXT2_region = mem:[from m_text2_start to m_text2_end]; + define region DATA_region = mem:[from m_data_start to m_data_end]; define region DATA2_region = mem:[from m_data2_start to m_data2_end]; define region DATA3_region = mem:[from m_data3_start to m_data3_end-__size_cstack__]; @@ -139,4 +144,5 @@ place in DATA3_region { block ZI }; place in DATA3_region { last block HEAP }; place in CSTACK_region { block CSTACK }; place in NCACHE_region { block NCACHE_VAR }; +place in TEXT2_region { section .textrw}; place in m_interrupts_ram_region { section m_interrupts_ram }; diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/drivers/fsl_common.h b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/drivers/fsl_common.h index a53dbc2713d1..28d5df5b5849 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/drivers/fsl_common.h +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/drivers/fsl_common.h @@ -3,7 +3,7 @@ * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. * Copyright 2016-2017 NXP * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, * are permitted (subject to the limitations in the disclaimer below) provided * that the following conditions are met: @@ -149,7 +149,7 @@ enum _status_groups kStatusGroup_LPC_MINISPI = 76, /*!< Group number for LPC_MINISPI status codes. */ kStatusGroup_NOTIFIER = 98, /*!< Group number for NOTIFIER status codes. */ kStatusGroup_DebugConsole = 99, /*!< Group number for debug console status codes. */ - kStatusGroup_SEMC = 100, /*!< Group number for SEMC status codes. */ + kStatusGroup_SEMC = 100, /*!< Group number for SEMC status codes. */ kStatusGroup_ApplicationRangeStart = 101, /*!< Starting number for application groups. */ }; @@ -347,35 +347,6 @@ _Pragma("diag_suppress=Pm120") /* @} */ /*! @name Time sensitive region */ -/* @{ */ -#if defined(FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE) && FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE -#if (defined(__ICCARM__)) -#define AT_QUICKACCESS_SECTION_CODE(func) func @"CodeQuickAccess" -#define AT_QUICKACCESS_SECTION_DATA(func) func @"DataQuickAccess" -#elif(defined(__ARMCC_VERSION)) -#define AT_QUICKACCESS_SECTION_CODE(func) __attribute__((section("CodeQuickAccess"))) func -#define AT_QUICKACCESS_SECTION_DATA(func) __attribute__((section("DataQuickAccess"))) func -#elif(defined(__GNUC__)) -#define AT_QUICKACCESS_SECTION_CODE(func) __attribute__((section("CodeQuickAccess"))) func -#define AT_QUICKACCESS_SECTION_DATA(func) __attribute__((section("DataQuickAccess"))) func -#else -#error Toolchain not supported. -#endif /* defined(__ICCARM__) */ -#else -#if (defined(__ICCARM__)) -#define AT_QUICKACCESS_SECTION_CODE(func) func -#define AT_QUICKACCESS_SECTION_DATA(func) func -#elif(defined(__ARMCC_VERSION)) -#define AT_QUICKACCESS_SECTION_CODE(func) func -#define AT_QUICKACCESS_SECTION_DATA(func) func -#elif(defined(__GNUC__)) -#define AT_QUICKACCESS_SECTION_CODE(func) func -#define AT_QUICKACCESS_SECTION_DATA(func) func -#else -#error Toolchain not supported. -#endif -#endif /* __FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE */ -/* @} */ /******************************************************************************* * API @@ -557,15 +528,15 @@ _Pragma("diag_suppress=Pm120") * @param size The length required to malloc. * @param alignbytes The alignment size. * @retval The allocated memory. - */ + */ void *SDK_Malloc(size_t size, size_t alignbytes); - + /*! * @brief Free memory. * * @param ptr The memory to be release. - */ - void SDK_Free(void *ptr); + */ + void SDK_Free(void *ptr); #if defined(__cplusplus) } 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 e0b07b9cbce1..8ae3b1a341fb 100644 --- a/targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_us_ticker_api.c +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_us_ticker_api.c @@ -203,3 +203,8 @@ void us_ticker_set_interrupt(timestamp_t timestamp) // we set the full reminder of 16 bit, the next ISR will do the upper part ticker_set(delta & 0xFFFF); } + +void us_ticker_free(void) +{ + +} diff --git a/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_GR_LYCHEE/PeripheralPins.c b/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_GR_LYCHEE/PeripheralPins.c index c94ebdfe68b1..6ddd72e4380f 100644 --- a/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_GR_LYCHEE/PeripheralPins.c +++ b/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_GR_LYCHEE/PeripheralPins.c @@ -250,11 +250,6 @@ const PinMap PinMap_PWM[] = { {P7_0 , PWM_TIOC2A, 5}, {P9_4 , PWM_TIOC2A, 5}, /* for 208QFP */ {P2_6 , PWM_TIOC2A, 3}, - {P6_7 , PWM_TIOC3A, 5}, - {P2_5 , PWM_TIOC3A, 3}, - {P3_11 , PWM_TIOC3A, 3}, - {P6_9 , PWM_TIOC3C, 5}, - {P3_12 , PWM_TIOC3C, 3}, {P5_8 , PWM_TIOC4A, 3}, {P2_4 , PWM_TIOC4A, 3}, {P5_10 , PWM_TIOC4C, 3}, diff --git a/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_GR_LYCHEE/device/TOOLCHAIN_ARM_STD/MBRZA1LU.sct b/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_GR_LYCHEE/device/TOOLCHAIN_ARM_STD/MBRZA1LU.sct index 726e6708d10b..1b44ff564b7d 100644 --- a/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_GR_LYCHEE/device/TOOLCHAIN_ARM_STD/MBRZA1LU.sct +++ b/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_GR_LYCHEE/device/TOOLCHAIN_ARM_STD/MBRZA1LU.sct @@ -23,7 +23,7 @@ LOAD_TTB __TTB_BASE __TTB_SIZE ; Page 0 of On-Chip Data Retention RAM { } ; Level-1 Translation Table for MMU } -SFLASH MBED_APP_START MBED_APP_SIZE ; load region size_region +LR_IROM1 MBED_APP_START MBED_APP_SIZE ; load region size_region { #if (MBED_APP_START == 0x18000000) BOOT_LOADER_BEGIN MBED_APP_START FIXED diff --git a/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_GR_LYCHEE/device/os_tick_ostm.c b/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_GR_LYCHEE/device/os_tick_ostm.c index 89420e51f2f9..8dd0d0769751 100644 --- a/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_GR_LYCHEE/device/os_tick_ostm.c +++ b/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_GR_LYCHEE/device/os_tick_ostm.c @@ -192,5 +192,9 @@ uint32_t OS_Tick_GetOverflow (void) return (IRQ_GetPending(OSTM_IRQn)); } +// Get Cortex-A9 OS Timer interrupt number +IRQn_ID_t mbed_get_a9_tick_irqn(){ + return OSTMI0TINT_IRQn; +} #endif diff --git a/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_GR_LYCHEE/mbed_drv_cfg.h b/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_GR_LYCHEE/mbed_drv_cfg.h index e20cb8838392..dad976cd3d13 100644 --- a/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_GR_LYCHEE/mbed_drv_cfg.h +++ b/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_GR_LYCHEE/mbed_drv_cfg.h @@ -34,10 +34,13 @@ #define RENESAS_RZ_A1_P0_CLK CM1_RENESAS_RZ_A1_P0_CLK +#define LP_TICKER_MTU2_CH 3 + /* flash (W25Q64JV) */ #define FLASH_BASE (0x18000000UL) /**< Flash Base Address */ #define FLASH_SIZE (0x00800000UL) /**< Available Flash Memory */ #define FLASH_PAGE_SIZE 256 /**< Flash Memory page size (interleaving off) */ + /**< Maximum size per one writing is 256 byte and minimum size per one writing is 1 byte */ #define FLASH_SECTOR_SIZE 4096 /**< Flash Memory sector size (interleaving off) */ #endif diff --git a/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_RZ_A1H/PeripheralPins.c b/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_RZ_A1H/PeripheralPins.c index bfc94f513aaf..0af90e3778bc 100644 --- a/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_RZ_A1H/PeripheralPins.c +++ b/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_RZ_A1H/PeripheralPins.c @@ -276,17 +276,13 @@ const PinMap PinMap_PWM[] = { {P4_4 , PWM_TIOC4A, 3}, {P4_6 , PWM_TIOC4C, 3}, {P5_0 , PWM_TIOC0A, 6}, - {P5_3 , PWM_TIOC3C, 6}, {P5_5 , PWM_TIOC0C, 6}, {P7_2 , PWM_TIOC0C, 7}, {P7_4 , PWM_TIOC1A, 7}, {P7_6 , PWM_TIOC2A, 7}, - {P7_10 , PWM_TIOC3C, 7}, {P7_12 , PWM_TIOC4A, 7}, {P7_14 , PWM_TIOC4C, 7}, {P8_8 , PWM_TIOC1A, 5}, - {P8_10 , PWM_TIOC3A, 4}, - {P8_12 , PWM_TIOC3C, 4}, {P8_14 , PWM_TIOC2A, 4}, {P11_0 , PWM_TIOC4A, 2}, {P11_2 , PWM_TIOC4C, 2}, diff --git a/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_RZ_A1H/device/TOOLCHAIN_ARM_STD/MBRZA1H.sct b/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_RZ_A1H/device/TOOLCHAIN_ARM_STD/MBRZA1H.sct index 2336a3a2f8ec..b429f79cc7ae 100644 --- a/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_RZ_A1H/device/TOOLCHAIN_ARM_STD/MBRZA1H.sct +++ b/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_RZ_A1H/device/TOOLCHAIN_ARM_STD/MBRZA1H.sct @@ -23,7 +23,7 @@ LOAD_TTB __TTB_BASE __TTB_SIZE ; Page 0 of On-Chip Data Retention RAM { } ; Level-1 Translation Table for MMU } -SFLASH MBED_APP_START MBED_APP_SIZE ; load region size_region +LR_IROM1 MBED_APP_START MBED_APP_SIZE ; load region size_region { #if (MBED_APP_START == 0x18000000) BOOT_LOADER_BEGIN MBED_APP_START FIXED diff --git a/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_RZ_A1H/mbed_drv_cfg.h b/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_RZ_A1H/mbed_drv_cfg.h index 1033832fbdcc..1a86f60f54f8 100644 --- a/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_RZ_A1H/mbed_drv_cfg.h +++ b/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_RZ_A1H/mbed_drv_cfg.h @@ -34,10 +34,13 @@ #define RENESAS_RZ_A1_P0_CLK CM0_RENESAS_RZ_A1_P0_CLK +#define LP_TICKER_MTU2_CH 3 + /* flash (MX25L6433FM2I) */ #define FLASH_BASE (0x18000000UL) /**< Flash Base Address */ #define FLASH_SIZE (0x00800000UL) /**< Available Flash Memory */ #define FLASH_PAGE_SIZE 256 /**< Flash Memory page size (interleaving off) */ + /**< Maximum size per one writing is 256 byte and minimum size per one writing is 1 byte */ #define FLASH_SECTOR_SIZE 4096 /**< Flash Memory sector size (interleaving off) */ #endif diff --git a/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_VK_RZ_A1H/device/TOOLCHAIN_ARM_STD/VKRZA1H.sct b/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_VK_RZ_A1H/device/TOOLCHAIN_ARM_STD/VKRZA1H.sct index fafb1bae3314..036fcc727aaa 100644 --- a/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_VK_RZ_A1H/device/TOOLCHAIN_ARM_STD/VKRZA1H.sct +++ b/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_VK_RZ_A1H/device/TOOLCHAIN_ARM_STD/VKRZA1H.sct @@ -16,7 +16,7 @@ LOAD_TTB __TTB_BASE __TTB_SIZE ; Page 0 of On-Chip Data Retention RAM { } ; Level-1 Translation Table for MMU } -SFLASH __ROM_BASE __ROM_SIZE ; load region size_region +LR_IROM1 __ROM_BASE __ROM_SIZE ; load region size_region { VECTORS __VECTOR_BASE FIXED { diff --git a/targets/TARGET_RENESAS/TARGET_RZ_A1XX/flash_api.c b/targets/TARGET_RENESAS/TARGET_RZ_A1XX/flash_api.c index 6e902ae99a73..5db7a2c75ade 100644 --- a/targets/TARGET_RENESAS/TARGET_RZ_A1XX/flash_api.c +++ b/targets/TARGET_RENESAS/TARGET_RZ_A1XX/flash_api.c @@ -167,7 +167,7 @@ uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address) uint32_t flash_get_page_size(const flash_t *obj) { - return FLASH_PAGE_SIZE; + return 1; } uint32_t flash_get_start_address(const flash_t *obj) @@ -222,48 +222,71 @@ int32_t _sector_erase(uint32_t addr) int32_t _page_program(uint32_t addr, const uint8_t * buf, int32_t size) { int32_t ret; + int32_t program_size; + int32_t remainder; + int32_t idx = 0; spi_mode(); - /* ---- Write enable ---- */ - ret = write_enable(); /* WREN Command */ - if (ret != 0) { - ex_mode(); - return ret; - } + while (size > 0) { + if (size > FLASH_PAGE_SIZE) { + program_size = FLASH_PAGE_SIZE; + } else { + program_size = size; + } + remainder = FLASH_PAGE_SIZE - (addr % FLASH_PAGE_SIZE); + if ((remainder != 0) && (program_size > remainder)) { + program_size = remainder; + } - /* ----------- 1. Command, Address ---------------*/ - /* ---- spimd_reg init ---- */ - clear_spimd_reg(&spimd_reg); + /* ---- Write enable ---- */ + ret = write_enable(); /* WREN Command */ + if (ret != 0) { + ex_mode(); + return ret; + } - /* ---- command ---- */ - spimd_reg.cde = SPIBSC_OUTPUT_ENABLE; - spimd_reg.cdb = SPIBSC_1BIT; - spimd_reg.cmd = SFLASHCMD_PAGE_PROGRAM; + /* ----------- 1. Command, Address ---------------*/ + /* ---- spimd_reg init ---- */ + clear_spimd_reg(&spimd_reg); - /* ---- address ---- */ - spimd_reg.ade = SPIBSC_OUTPUT_ADDR_24; - spimd_reg.addre = SPIBSC_SDR_TRANS; /* SDR */ - spimd_reg.adb = SPIBSC_1BIT; - spimd_reg.addr = addr; + /* ---- command ---- */ + spimd_reg.cde = SPIBSC_OUTPUT_ENABLE; + spimd_reg.cdb = SPIBSC_1BIT; + spimd_reg.cmd = SFLASHCMD_PAGE_PROGRAM; - /* ---- Others ---- */ - spimd_reg.sslkp = SPIBSC_SPISSL_KEEP; /* SPBSSL level */ + /* ---- address ---- */ + spimd_reg.ade = SPIBSC_OUTPUT_ADDR_24; + spimd_reg.addre = SPIBSC_SDR_TRANS; /* SDR */ + spimd_reg.adb = SPIBSC_1BIT; + spimd_reg.addr = addr; - ret = spibsc_transfer(&spimd_reg); /* Command,Address */ - if (ret != 0) { - ex_mode(); - return ret; - } + /* ---- Others ---- */ + spimd_reg.sslkp = SPIBSC_SPISSL_KEEP; /* SPBSSL level */ - /* ----------- 2. Data ---------------*/ - ret = data_send(SPIBSC_1BIT, SPIBSC_SPISSL_NEGATE, buf, size); - if (ret != 0) { - ex_mode(); - return ret; - } + ret = spibsc_transfer(&spimd_reg); /* Command,Address */ + if (ret != 0) { + ex_mode(); + return ret; + } - ret = busy_wait(); + /* ----------- 2. Data ---------------*/ + ret = data_send(SPIBSC_1BIT, SPIBSC_SPISSL_NEGATE, &buf[idx], program_size); + if (ret != 0) { + ex_mode(); + return ret; + } + + ret = busy_wait(); + if (ret != 0) { + ex_mode(); + return ret; + } + + addr += program_size; + idx += program_size; + size -= program_size; + } ex_mode(); return ret; diff --git a/targets/TARGET_RENESAS/TARGET_RZ_A1XX/lp_ticker.c b/targets/TARGET_RENESAS/TARGET_RZ_A1XX/lp_ticker.c new file mode 100644 index 000000000000..1edbf34d2b23 --- /dev/null +++ b/targets/TARGET_RENESAS/TARGET_RZ_A1XX/lp_ticker.c @@ -0,0 +1,124 @@ +/* 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. + */ +#if DEVICE_LPTICKER +#include "lp_ticker_api.h" +#include "mtu2_iobitmask.h" +#include "mbed_drv_cfg.h" +#include "mtu2.h" + +#if (LP_TICKER_MTU2_CH == 2) + #define LP_TICKER_TIMER_IRQn (TGI2A_IRQn) + #define MTU2TCR (MTU2TCR_2) + #define MTU2TCNT (MTU2TCNT_2) + #define MTU2TIER (MTU2TIER_2) + #define MTU2TGRA (MTU2TGRA_2) + #define MTU2TSR (MTU2TSR_2) + #define MTU2_TSTR_CST MTU2_TSTR_CST2 + #define MTU2_TCR_TPSC (0x07) +#elif (LP_TICKER_MTU2_CH == 3) + #define LP_TICKER_TIMER_IRQn (TGI3A_IRQn) + #define MTU2TCR (MTU2TCR_3) + #define MTU2TCNT (MTU2TCNT_3) + #define MTU2TIER (MTU2TIER_3) + #define MTU2TGRA (MTU2TGRA_3) + #define MTU2TSR (MTU2TSR_3) + #define MTU2_TSTR_CST MTU2_TSTR_CST3 + #define MTU2_TCR_TPSC (0x05) +#elif (LP_TICKER_MTU2_CH == 4) + #define LP_TICKER_TIMER_IRQn (TGI4A_IRQn) + #define MTU2TCR (MTU2TCR_4) + #define MTU2TCNT (MTU2TCNT_4) + #define MTU2TIER (MTU2TIER_4) + #define MTU2TGRA (MTU2TGRA_4) + #define MTU2TSR (MTU2TSR_4) + #define MTU2_TSTR_CST MTU2_TSTR_CST4 + #define MTU2_TCR_TPSC (0x05) +#else + #error "Invalid number : LP_TICKER_MTU2_CH (2-4)" +#endif + +static int lp_ticker_inited = 0; + +void lp_ticker_init(void) +{ + GIC_DisableIRQ(LP_TICKER_TIMER_IRQn); + GIC_ClearPendingIRQ(LP_TICKER_TIMER_IRQn); + + /* Power Control for Peripherals */ + mtu2_init(); + + if (lp_ticker_inited) return; + lp_ticker_inited = 1; + + MTU2TCR = MTU2_TCR_TPSC; + MTU2TSTR |= MTU2_TSTR_CST; + MTU2TIER |= MTU2_TIER_n_TGIEA; + + // INTC settings + InterruptHandlerRegister(LP_TICKER_TIMER_IRQn, (void (*)(uint32_t))lp_ticker_irq_handler); + GIC_SetPriority(LP_TICKER_TIMER_IRQn, 5); + GIC_SetConfiguration(LP_TICKER_TIMER_IRQn, 3); +} + +void lp_ticker_free(void) +{ + GIC_DisableIRQ(LP_TICKER_TIMER_IRQn); + GIC_ClearPendingIRQ(LP_TICKER_TIMER_IRQn); + + MTU2TIER &= ~MTU2_TIER_n_TGIEA; + lp_ticker_inited = 0; + mtu2_free(); +} + +uint32_t lp_ticker_read() +{ + return (uint32_t)MTU2TCNT; +} + +void lp_ticker_set_interrupt(timestamp_t timestamp) +{ + MTU2TSR = (MTU2TSR & 0xFE); + MTU2TGRA = (uint16_t)timestamp; + GIC_EnableIRQ(LP_TICKER_TIMER_IRQn); +} + +void lp_ticker_fire_interrupt(void) +{ + GIC_SetPendingIRQ(LP_TICKER_TIMER_IRQn); + GIC_EnableIRQ(LP_TICKER_TIMER_IRQn); +} + +void lp_ticker_disable_interrupt(void) +{ + GIC_DisableIRQ(LP_TICKER_TIMER_IRQn); +} + +void lp_ticker_clear_interrupt(void) +{ + MTU2TSR = (MTU2TSR & 0xFE); + GIC_ClearPendingIRQ(LP_TICKER_TIMER_IRQn); +} + +const ticker_info_t* lp_ticker_get_info() +{ + static const ticker_info_t info = { + (uint32_t)((float)RENESAS_RZ_A1_P0_CLK / 1024.0f + 0.5f), + 16 + }; + return &info; +} + +#endif // DEVICE_LPTICKER diff --git a/targets/TARGET_RENESAS/TARGET_RZ_A1XX/mtu2.c b/targets/TARGET_RENESAS/TARGET_RZ_A1XX/mtu2.c new file mode 100644 index 000000000000..196cd11d9c14 --- /dev/null +++ b/targets/TARGET_RENESAS/TARGET_RZ_A1XX/mtu2.c @@ -0,0 +1,43 @@ +/* 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. + */ + +#include "mbed_drv_cfg.h" + +#if (defined(FUMC_MTU2_PWM) || defined(DEVICE_LPTICKER)) +#include "mtu2.h" + +static int mtu2_used_cnt = 0; + +void mtu2_init(void) +{ + if (mtu2_used_cnt == 0) { + CPGSTBCR3 &= ~(CPG_STBCR3_BIT_MSTP33); + } + if (mtu2_used_cnt < 256) { + mtu2_used_cnt++; + } +} + +void mtu2_free(void) +{ + if (mtu2_used_cnt > 0) { + mtu2_used_cnt--; + } + if (mtu2_used_cnt == 0) { + CPGSTBCR3 |= (CPG_STBCR3_BIT_MSTP33); + } +} +#endif diff --git a/targets/TARGET_RENESAS/TARGET_RZ_A1XX/mtu2.h b/targets/TARGET_RENESAS/TARGET_RZ_A1XX/mtu2.h new file mode 100644 index 000000000000..43cda3ef53a5 --- /dev/null +++ b/targets/TARGET_RENESAS/TARGET_RZ_A1XX/mtu2.h @@ -0,0 +1,34 @@ +/* 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 MTU2_H +#define MTU2_H + +#include "device.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void mtu2_init(void); +void mtu2_free(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/targets/TARGET_RENESAS/TARGET_RZ_A1XX/pwmout_api.c b/targets/TARGET_RENESAS/TARGET_RZ_A1XX/pwmout_api.c index 0bed1c4aa39a..6ffae0a9649a 100644 --- a/targets/TARGET_RENESAS/TARGET_RZ_A1XX/pwmout_api.c +++ b/targets/TARGET_RENESAS/TARGET_RZ_A1XX/pwmout_api.c @@ -21,6 +21,7 @@ #include "iodefine.h" #include "gpio_addrdefine.h" #include "mbed_drv_cfg.h" +#include "mtu2.h" #define MTU2_PWM_OFFSET 0x20 @@ -208,7 +209,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) { int tmp_pwm; // power on - CPGSTBCR3 &= ~(CPG_STBCR3_BIT_MSTP33); + mtu2_init(); obj->pwm = pwm; tmp_pwm = (int)(obj->pwm - MTU2_PWM_OFFSET); @@ -274,6 +275,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) { void pwmout_free(pwmout_t* obj) { pwmout_write(obj, 0); + mtu2_free(); } void pwmout_write(pwmout_t* obj, float value) { diff --git a/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_ARM_STD/rtl8195a.sct b/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_ARM_STD/rtl8195a.sct index 6080041b2f31..835483f38d76 100644 --- a/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_ARM_STD/rtl8195a.sct +++ b/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_ARM_STD/rtl8195a.sct @@ -17,7 +17,7 @@ LR_IRAM 0x10007000 (0x70000 - 0x7000) { *rtl8195a_init*.o(.image2.validate.rodata*) } - ER_IRAM +0 FIXED { + LR_IROM1 +0 FIXED { *(.ARM.exidx) *(.init_array) *rtl8195a_crypto*.o (+RO) @@ -55,7 +55,7 @@ LR_TCM 0x1FFF0000 0x10000 { } } -LR_DRAM 0x30000000 0x200000 { +LR_IROM1 0x30000000 0x200000 { ER_DRAM +0 FIXED { .ANY (+RO) diff --git a/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/us_ticker.c b/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/us_ticker.c index 91d7f40027cd..81bff2a2faa0 100644 --- a/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/us_ticker.c +++ b/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/us_ticker.c @@ -119,3 +119,8 @@ void us_ticker_disable_interrupt(void) void us_ticker_clear_interrupt(void) { } + +void us_ticker_free(void) +{ + HalTimerOp.HalTimerDis((u32)TimerAdapter.TimerId); +} diff --git a/targets/TARGET_Realtek/TARGET_AMEBA/rtw_emac.cpp b/targets/TARGET_Realtek/TARGET_AMEBA/rtw_emac.cpp index f6596cd4b6e1..5b243a623ee8 100644 --- a/targets/TARGET_Realtek/TARGET_AMEBA/rtw_emac.cpp +++ b/targets/TARGET_Realtek/TARGET_AMEBA/rtw_emac.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#if DEVICE_EMAC +#if defined(CONFIG_MBED_ENABLED) #include #include "mbed_assert.h" diff --git a/targets/TARGET_Realtek/TARGET_AMEBA/sdk/common/api/wifi/wifi_conf.c b/targets/TARGET_Realtek/TARGET_AMEBA/sdk/common/api/wifi/wifi_conf.c index 6b6cb0f93749..4902ada8648b 100644 --- a/targets/TARGET_Realtek/TARGET_AMEBA/sdk/common/api/wifi/wifi_conf.c +++ b/targets/TARGET_Realtek/TARGET_AMEBA/sdk/common/api/wifi/wifi_conf.c @@ -66,7 +66,7 @@ extern int inic_stop(void); /****************************************************** * Variables Declarations ******************************************************/ -#if !DEVICE_EMAC +#if !defined(CONFIG_MBED_ENABLED) extern struct netif xnetif[NET_IF_NUM]; #endif /****************************************************** @@ -975,10 +975,10 @@ int wifi_on(rtw_mode_t mode) } #if CONFIG_LWIP_LAYER - #if !DEVICE_EMAC + #if !defined(CONFIG_MBED_ENABLED) netif_set_up(&xnetif[0]); if(mode == RTW_MODE_STA_AP) { - netif_set_up(&xnetif[1]); + netif_set_up(&xnetif[1]); } #endif #endif @@ -1004,7 +1004,7 @@ int wifi_off(void) #ifndef CONFIG_MBED_ENABLED dhcps_deinit(); #endif -#if !DEVICE_EMAC +#if !defined(CONFIG_MBED_ENABLED) LwIP_DHCP(0, DHCP_STOP); netif_set_down(&xnetif[0]); netif_set_down(&xnetif[1]); @@ -1048,7 +1048,7 @@ int wifi_off_fastly(void) #ifndef CONFIG_MBED_ENABLED dhcps_deinit(); #endif -#if !DEVICE_EMAC +#if !defined(CONFIG_MBED_ENABLED) LwIP_DHCP(0, DHCP_STOP); #endif #endif @@ -1676,7 +1676,7 @@ int wifi_restart_ap( int channel) { unsigned char idx = 0; -#if !DEVICE_EMAC +#if !defined(CONFIG_MBED_ENABLED) ip_addr_t ipaddr; ip_addr_t netmask; ip_addr_t gw; @@ -1706,7 +1706,7 @@ int wifi_restart_ap( else #endif { -#if !DEVICE_EMAC +#if !defined(CONFIG_MBED_ENABLED) IP4_ADDR(&ipaddr, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1 , NETMASK_ADDR2, NETMASK_ADDR3); IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); @@ -1756,7 +1756,7 @@ int wifi_restart_ap( #if (INCLUDE_uxTaskGetStackHighWaterMark == 1) printf("\r\nWebServer Thread: High Water Mark is %ld\n", uxTaskGetStackHighWaterMark(NULL)); #endif -#if !DEVICE_EMAC +#if !defined(CONFIG_MBED_ENABLED) // start dhcp server dhcps_init(&xnetif[idx]); #endif @@ -1779,12 +1779,12 @@ struct wifi_autoreconnect_param { static void wifi_autoreconnect_thread(void *param) { -#if !DEVICE_EMAC && CONFIG_LWIP_LAYER +#if !defined(CONFIG_MBED_ENABLED) && CONFIG_LWIP_LAYER int ret = RTW_ERROR; #endif struct wifi_autoreconnect_param *reconnect_param = (struct wifi_autoreconnect_param *) param; WIFI_CONF_MSG("\n\rauto reconnect ...\n"); -#if !DEVICE_EMAC && CONFIG_LWIP_LAYER +#if !defined(CONFIG_MBED_ENABLED) && CONFIG_LWIP_LAYER ret = #endif wifi_connect(reconnect_param->ssid, @@ -1794,7 +1794,7 @@ static void wifi_autoreconnect_thread(void *param) reconnect_param->password_len, reconnect_param->key_id, NULL); -#if !DEVICE_EMAC && CONFIG_LWIP_LAYER +#if !defined(CONFIG_MBED_ENABLED) && CONFIG_LWIP_LAYER if(ret == RTW_SUCCESS) { #if ATCMD_VER == ATVER_2 if (dhcp_mode_sta == 2){ diff --git a/targets/TARGET_Realtek/TARGET_AMEBA/sdk/common/drivers/wlan/realtek/src/osdep/lwip_intf.c b/targets/TARGET_Realtek/TARGET_AMEBA/sdk/common/drivers/wlan/realtek/src/osdep/lwip_intf.c index 9ab5a593e994..aa036bca40a8 100644 --- a/targets/TARGET_Realtek/TARGET_AMEBA/sdk/common/drivers/wlan/realtek/src/osdep/lwip_intf.c +++ b/targets/TARGET_Realtek/TARGET_AMEBA/sdk/common/drivers/wlan/realtek/src/osdep/lwip_intf.c @@ -20,7 +20,7 @@ #include #include -#if !DEVICE_EMAC +#if !defined(CONFIG_MBED_ENABLED) #include #include #endif @@ -32,7 +32,7 @@ // External Reference //----- ------------------------------------------------------------------ #if (CONFIG_LWIP_LAYER == 1) -#if DEVICE_EMAC +#if defined(CONFIG_MBED_ENABLED) extern struct netif *xnetif[]; #else extern struct netif xnetif[]; //LWIP netif @@ -52,7 +52,7 @@ void rltk_wlan_set_netif_info(int idx_wlan, void * dev, unsigned char * dev_addr) { #if (CONFIG_LWIP_LAYER == 1) -#if DEVICE_EMAC +#if defined(CONFIG_MBED_ENABLED) //rtw_memcpy(xnetif[idx_wlan]->hwaddr, dev_addr, 6); //set netif hwaddr later #else @@ -156,7 +156,7 @@ void rltk_wlan_recv(int idx, struct eth_drv_sg *sg_list, int sg_len) int netif_is_valid_IP(int idx, unsigned char *ip_dest) { #if CONFIG_LWIP_LAYER == 1 -#if DEVICE_EMAC +#if defined(CONFIG_MBED_ENABLED) return 1; #else struct netif *pnetif = &xnetif[idx]; @@ -188,7 +188,7 @@ int netif_is_valid_IP(int idx, unsigned char *ip_dest) } DBG_TRACE("invalid IP: %d.%d.%d.%d ",ip_dest[0],ip_dest[1],ip_dest[2],ip_dest[3]); -#endif +#endif #ifdef CONFIG_DONT_CARE_TP if (pnetif->flags & NETIF_FLAG_IPSWITCH) { return 1; @@ -199,7 +199,7 @@ int netif_is_valid_IP(int idx, unsigned char *ip_dest) #endif } -#if DEVICE_EMAC +#if defined(CONFIG_MBED_ENABLED) #else int netif_get_idx(struct netif *pnetif) @@ -240,7 +240,7 @@ void set_callback_func(emac_callback p, void *data) { void netif_rx(int idx, unsigned int len) { #if (CONFIG_LWIP_LAYER == 1) -#if DEVICE_EMAC +#if defined(CONFIG_MBED_ENABLED) emac_callback_func(emac_callback_data, NULL, len); #else ethernetif_recv(&xnetif[idx], len); @@ -255,7 +255,7 @@ void netif_rx(int idx, unsigned int len) void netif_post_sleep_processing(void) { #if (CONFIG_LWIP_LAYER == 1) -#if DEVICE_EMAC +#if defined(CONFIG_MBED_ENABLED) #else lwip_POST_SLEEP_PROCESSING(); //For FreeRTOS tickless to enable Lwip ARP timer when leaving IPS - Alex Fang #endif @@ -265,7 +265,7 @@ void netif_post_sleep_processing(void) void netif_pre_sleep_processing(void) { #if (CONFIG_LWIP_LAYER == 1) -#if DEVICE_EMAC +#if defined(CONFIG_MBED_ENABLED) #else lwip_PRE_SLEEP_PROCESSING(); #endif diff --git a/targets/TARGET_Realtek/TARGET_AMEBA/sdk/common/drivers/wlan/realtek/src/osdep/lwip_intf.h b/targets/TARGET_Realtek/TARGET_AMEBA/sdk/common/drivers/wlan/realtek/src/osdep/lwip_intf.h index 233335f93336..5892aba322e8 100644 --- a/targets/TARGET_Realtek/TARGET_AMEBA/sdk/common/drivers/wlan/realtek/src/osdep/lwip_intf.h +++ b/targets/TARGET_Realtek/TARGET_AMEBA/sdk/common/drivers/wlan/realtek/src/osdep/lwip_intf.h @@ -28,7 +28,7 @@ struct netif; //----- ------------------------------------------------------------------ // Ethernet Buffer //----- ------------------------------------------------------------------ -#if DEVICE_EMAC +#if defined(CONFIG_MBED_ENABLED) struct eth_drv_sg { unsigned int buf; unsigned int len; @@ -66,7 +66,7 @@ void netif_rx(int idx, unsigned int len); void netif_post_sleep_processing(void); void netif_pre_sleep_processing(void); #if (CONFIG_LWIP_LAYER == 1) -#if !DEVICE_EMAC +#if !defined(CONFIG_MBED_ENABLED) extern void ethernetif_recv(struct netif *netif, int total_len); #endif extern void lwip_PRE_SLEEP_PROCESSING(void); diff --git a/targets/TARGET_Realtek/TARGET_AMEBA/sdk/common/network/dhcp/dhcps.c b/targets/TARGET_Realtek/TARGET_AMEBA/sdk/common/network/dhcp/dhcps.c new file mode 100644 index 000000000000..f3c82a4b778d --- /dev/null +++ b/targets/TARGET_Realtek/TARGET_AMEBA/sdk/common/network/dhcp/dhcps.c @@ -0,0 +1,757 @@ +/****************************************************************************** + * Copyright (c) 2013-2016 Realtek Semiconductor Corp. + * + * 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 "osdep_service.h" +#include "dhcps.h" +#include "tcpip.h" + +//static struct dhcp_server_state dhcp_server_state_machine; +static uint8_t dhcp_server_state_machine = DHCP_SERVER_STATE_IDLE; +/* recorded the client MAC addr(default sudo mac) */ +//static uint8_t dhcps_record_first_client_mac[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; +/* recorded transaction ID (default sudo id)*/ +static uint8_t dhcp_recorded_xid[4] = {0xff, 0xff, 0xff, 0xff}; + +/* UDP Protocol Control Block(PCB) */ +static struct udp_pcb *dhcps_pcb; + +static ip_addr_t dhcps_send_broadcast_address; +static ip_addr_t dhcps_local_address; +static ip_addr_t dhcps_pool_start; +static ip_addr_t dhcps_pool_end; +static ip_addr_t dhcps_local_mask; +static ip_addr_t dhcps_local_gateway; +static ip_addr_t dhcps_network_id; +static ip_addr_t dhcps_subnet_broadcast; +static ip_addr_t dhcps_allocated_client_address; +static int dhcps_addr_pool_set = 0; +static ip_addr_t dhcps_addr_pool_start; +static ip_addr_t dhcps_addr_pool_end; +#if 1 +static ip_addr_t dhcps_owned_first_ip; +static ip_addr_t dhcps_owned_last_ip; +static uint8_t dhcps_num_of_available_ips; +#endif +static struct dhcp_msg *dhcp_message_repository; +static int dhcp_message_total_options_lenth; + +/* allocated IP range */ +static struct table ip_table; +static ip_addr_t client_request_ip; +static uint8_t client_addr[6]; + +static _mutex dhcps_ip_table_semaphore; + +static struct netif * dhcps_netif = NULL; +/** + * @brief latch the specific ip in the ip table. + * @param d the specific index + * @retval None. + */ +#if (!IS_USE_FIXED_IP) +static void mark_ip_in_table(uint8_t d) +{ +#if (debug_dhcps) + printf("\r\nmark ip %d\r\n",d); +#endif + rtw_mutex_get_timeout(&dhcps_ip_table_semaphore, RTW_MAX_DELAY); + if (0 < d && d <= 32) { + ip_table.ip_range[0] = MARK_RANGE1_IP_BIT(ip_table, d); +#if (debug_dhcps) + printf("\r\n ip_table.ip_range[0] = 0x%x\r\n",ip_table.ip_range[0]); +#endif + } else if (32 < d && d <= 64) { + ip_table.ip_range[1] = MARK_RANGE2_IP_BIT(ip_table, (d - 32)); +#if (debug_dhcps) + printf("\r\n ip_table.ip_range[1] = 0x%x\r\n",ip_table.ip_range[1]); +#endif + } else if (64 < d && d <= 96) { + ip_table.ip_range[2] = MARK_RANGE3_IP_BIT(ip_table, (d - 64)); +#if (debug_dhcps) + printf("\r\n ip_table.ip_range[2] = 0x%x\r\n",ip_table.ip_range[2]); +#endif + } else if (96 < d && d <= 128) { + ip_table.ip_range[3] = MARK_RANGE4_IP_BIT(ip_table, (d - 96)); +#if (debug_dhcps) + printf("\r\n ip_table.ip_range[3] = 0x%x\r\n",ip_table.ip_range[3]); +#endif + } else if(128 < d && d <= 160) { + ip_table.ip_range[4] = MARK_RANGE5_IP_BIT(ip_table, d); +#if (debug_dhcps) + printf("\r\n ip_table.ip_range[4] = 0x%x\r\n",ip_table.ip_range[4]); +#endif + } else if (160 < d && d <= 192) { + ip_table.ip_range[5] = MARK_RANGE6_IP_BIT(ip_table, (d - 160)); +#if (debug_dhcps) + printf("\r\n ip_table.ip_range[5] = 0x%x\r\n",ip_table.ip_range[5]); +#endif + } else if (192 < d && d <= 224) { + ip_table.ip_range[6] = MARK_RANGE7_IP_BIT(ip_table, (d - 192)); +#if (debug_dhcps) + printf("\r\n ip_table.ip_range[6] = 0x%x\r\n",ip_table.ip_range[6]); +#endif + } else if (224 < d) { + ip_table.ip_range[7] = MARK_RANGE8_IP_BIT(ip_table, (d - 224)); +#if (debug_dhcps) + printf("\r\n ip_table.ip_range[7] = 0x%x\r\n",ip_table.ip_range[7]); +#endif + } else { + printf("\r\n Request ip over the range(1-128) \r\n"); + } + rtw_mutex_put(&dhcps_ip_table_semaphore); + +} +#ifdef CONFIG_DHCPS_KEPT_CLIENT_INFO +static void save_client_addr(ip_addr_t *client_ip, uint8_t *hwaddr) +{ + uint8_t d = (uint8_t)ip4_addr4(client_ip); + + rtw_mutex_get_timeout(&dhcps_ip_table_semaphore, RTW_MAX_DELAY); + memcpy(ip_table.client_mac[d], hwaddr, 6); +#if (debug_dhcps) + printf("\r\n%s: ip %d.%d.%d.%d, hwaddr %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", __func__, + ip4_addr1(client_ip), ip4_addr2(client_ip), ip4_addr3(client_ip), ip4_addr4(client_ip), + hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]); +#endif + rtw_mutex_put(&dhcps_ip_table_semaphore); +} + +static uint8_t check_client_request_ip(ip_addr_t *client_req_ip, uint8_t *hwaddr) +{ + int ip_addr4 = 0, i; + +#if (debug_dhcps) + printf("\r\n%s: ip %d.%d.%d.%d, hwaddr %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", __func__, + ip4_addr1(client_req_ip), ip4_addr2(client_req_ip), ip4_addr3(client_req_ip), ip4_addr4(client_req_ip), + hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]); +#endif + + rtw_mutex_get_timeout(&dhcps_ip_table_semaphore, RTW_MAX_DELAY); + for(i=DHCP_POOL_START;i<=DHCP_POOL_END;i++) + { + //printf("client[%d] = %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",i,ip_table.client_mac[i][0],ip_table.client_mac[i][0],ip_table.client_mac[i][1],ip_table.client_mac[i][2],ip_table.client_mac[i][3],ip_table.client_mac[i][4],ip_table.client_mac[i][5]); + if(memcmp(ip_table.client_mac[i], hwaddr, 6) == 0){ + if((ip_table.ip_range[i/32]>>(i%32-1)) & 1){ + ip_addr4 = i; + break; + } + } + } + rtw_mutex_put(&dhcps_ip_table_semaphore); + + if(i == DHCP_POOL_END+1) + ip_addr4 = 0; + + return ip_addr4; +} + +#if debug_dhcps +static void dump_client_table() +{ +#if 0 + int i; + uint8_t *p = NULL; + printf("\r\nip_range: %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x", + ip_table.ip_range[0], ip_table.ip_range[1], ip_table.ip_range[2], ip_table.ip_range[3], + ip_table.ip_range[4], ip_table.ip_range[5], ip_table.ip_range[6], ip_table.ip_range[7]); + for(i=1; i<=DHCPS_MAX_CLIENT_NUM; i++) + { + p = ip_table.client_mac[i]; + printf("\r\nClient[%d]: %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x", + i, p[0], p[1], p[2], p[3], p[4], p[5]); + } + printf("\r\n"); +#endif +} +#endif +#endif //CONFIG_DHCPS_KEPT_CLIENT_INFO +#endif + +/** + * @brief get one usable ip from the ip table of dhcp server. + * @param: None + * @retval the usable index which represent the ip4_addr(ip) of allocated ip addr. + */ +#if (!IS_USE_FIXED_IP) +static uint8_t search_next_ip(void) +{ + uint8_t range_count, offset_count; + uint8_t start, end; + uint8_t max_count; + if(dhcps_addr_pool_set){ + start = (uint8_t)ip4_addr4(&dhcps_addr_pool_start); + end = (uint8_t)ip4_addr4(&dhcps_addr_pool_end); + }else{ + start = 0; + end = 255; + } + rtw_mutex_get_timeout(&dhcps_ip_table_semaphore, RTW_MAX_DELAY); + for (range_count = 0; range_count < (max_count = 8); range_count++) { + for (offset_count = 0;offset_count < 32; offset_count++) { + if ((((ip_table.ip_range[range_count] >> offset_count) & 0x01) == 0) + &&(((range_count * 32) + (offset_count + 1)) >= start) + &&(((range_count * 32) + (offset_count + 1)) <= end)) { + rtw_mutex_put(&dhcps_ip_table_semaphore); + return ((range_count * 32) + (offset_count + 1)); + } + } + } + rtw_mutex_put(&dhcps_ip_table_semaphore); + return 0; +} +#endif + +/** + * @brief fill in the option field with message type of a dhcp message. + * @param msg_option_base_addr: the addr be filled start. + * message_type: the type code you want to fill in + * @retval the start addr of the next dhcp option. + */ +static uint8_t *add_msg_type(uint8_t *msg_option_base_addr, uint8_t message_type) +{ + uint8_t *option_start; + msg_option_base_addr[0] = DHCP_OPTION_CODE_MSG_TYPE; + msg_option_base_addr[1] = DHCP_OPTION_LENGTH_ONE; + msg_option_base_addr[2] = message_type; + option_start = msg_option_base_addr + 3; + if (DHCP_MESSAGE_TYPE_NAK == message_type) + *option_start++ = DHCP_OPTION_CODE_END; + return option_start; +} + + +static uint8_t *fill_one_option_content(uint8_t *option_base_addr, + uint8_t option_code, uint8_t option_length, void *copy_info) +{ + uint8_t *option_data_base_address; + uint8_t *next_option_start_address = NULL; + option_base_addr[0] = option_code; + option_base_addr[1] = option_length; + option_data_base_address = option_base_addr + 2; + switch (option_length) { + case DHCP_OPTION_LENGTH_FOUR: + memcpy(option_data_base_address, copy_info, DHCP_OPTION_LENGTH_FOUR); + next_option_start_address = option_data_base_address + 4; + break; + case DHCP_OPTION_LENGTH_TWO: + memcpy(option_data_base_address, copy_info, DHCP_OPTION_LENGTH_TWO); + next_option_start_address = option_data_base_address + 2; + break; + case DHCP_OPTION_LENGTH_ONE: + memcpy(option_data_base_address, copy_info, DHCP_OPTION_LENGTH_ONE); + next_option_start_address = option_data_base_address + 1; + break; + } + + return next_option_start_address; +} + +/** + * @brief fill in the needed content of the dhcp offer message. + * @param optptr the addr which the tail of dhcp magic field. + * @retval the addr represent to add the end of option. + */ +static void add_offer_options(uint8_t *option_start_address) +{ + uint8_t *temp_option_addr; + /* add DHCP options 1. + The subnet mask option specifies the client's subnet mask */ + temp_option_addr = fill_one_option_content(option_start_address, + DHCP_OPTION_CODE_SUBNET_MASK, DHCP_OPTION_LENGTH_FOUR, + (void *)&dhcps_local_mask); + + /* add DHCP options 3 (i.e router(gateway)). The time server option + specifies a list of RFC 868 [6] time servers available to the client. */ + temp_option_addr = fill_one_option_content(temp_option_addr, + DHCP_OPTION_CODE_ROUTER, DHCP_OPTION_LENGTH_FOUR, + (void *)&dhcps_local_address); + + /* add DHCP options 6 (i.e DNS). + The option specifies a list of DNS servers available to the client. */ + //temp_option_addr = fill_one_option_content(temp_option_addr, + // DHCP_OPTION_CODE_DNS_SERVER, DHCP_OPTION_LENGTH_FOUR, + // (void *)&dhcps_local_address); + /* add DHCP options 51. + This option is used to request a lease time for the IP address. */ + temp_option_addr = fill_one_option_content(temp_option_addr, + DHCP_OPTION_CODE_LEASE_TIME, DHCP_OPTION_LENGTH_FOUR, + (void *)&dhcp_option_lease_time); + /* add DHCP options 54. + The identifier is the IP address of the selected server. */ + temp_option_addr = fill_one_option_content(temp_option_addr, + DHCP_OPTION_CODE_SERVER_ID, DHCP_OPTION_LENGTH_FOUR, + (void *)&dhcps_local_address); + /* add DHCP options 28. + This option specifies the broadcast address in use on client's subnet.*/ + temp_option_addr = fill_one_option_content(temp_option_addr, + DHCP_OPTION_CODE_BROADCAST_ADDRESS, DHCP_OPTION_LENGTH_FOUR, + (void *)&dhcps_subnet_broadcast); + /* add DHCP options 26. + This option specifies the Maximum transmission unit to use */ + temp_option_addr = fill_one_option_content(temp_option_addr, + DHCP_OPTION_CODE_INTERFACE_MTU, DHCP_OPTION_LENGTH_TWO, + (void *) &dhcp_option_interface_mtu);//dhcp_option_interface_mtu_576); + /* add DHCP options 31. + This option specifies whether or not the client should solicit routers */ + temp_option_addr = fill_one_option_content(temp_option_addr, + DHCP_OPTION_CODE_PERFORM_ROUTER_DISCOVERY, DHCP_OPTION_LENGTH_ONE, + NULL); + *temp_option_addr++ = DHCP_OPTION_CODE_END; + +} + + +/** + * @brief fill in common content of a dhcp message. + * @param m the pointer which point to the dhcp message store in. + * @retval None. + */ +static void dhcps_initialize_message(struct dhcp_msg *dhcp_message_repository) +{ + + dhcp_message_repository->op = DHCP_MESSAGE_OP_REPLY; + dhcp_message_repository->htype = DHCP_MESSAGE_HTYPE; + dhcp_message_repository->hlen = DHCP_MESSAGE_HLEN; + dhcp_message_repository->hops = 0; + memcpy((char *)dhcp_recorded_xid, (char *) dhcp_message_repository->xid, + sizeof(dhcp_message_repository->xid)); + dhcp_message_repository->secs = 0; + dhcp_message_repository->flags = htons(BOOTP_BROADCAST); + + memcpy((char *)dhcp_message_repository->yiaddr, + (char *)&dhcps_allocated_client_address, + sizeof(dhcp_message_repository->yiaddr)); + + memset((char *)dhcp_message_repository->ciaddr, 0, + sizeof(dhcp_message_repository->ciaddr)); + memset((char *)dhcp_message_repository->siaddr, 0, + sizeof(dhcp_message_repository->siaddr)); + memset((char *)dhcp_message_repository->giaddr, 0, + sizeof(dhcp_message_repository->giaddr)); + memset((char *)dhcp_message_repository->sname, 0, + sizeof(dhcp_message_repository->sname)); + memset((char *)dhcp_message_repository->file, 0, + sizeof(dhcp_message_repository->file)); + memset((char *)dhcp_message_repository->options, 0, + dhcp_message_total_options_lenth); + memcpy((char *)dhcp_message_repository->options, (char *)dhcp_magic_cookie, + sizeof(dhcp_magic_cookie)); +} + +/** + * @brief init and fill in the needed content of dhcp offer message. + * @param packet_buffer packet buffer for UDP. + * @retval None. + */ +static void dhcps_send_offer(struct pbuf *packet_buffer) +{ + uint8_t temp_ip = 0; + dhcp_message_repository = (struct dhcp_msg *)packet_buffer->payload; +#if (!IS_USE_FIXED_IP) + temp_ip = check_client_request_ip(&client_request_ip, client_addr); + /* create new client ip */ + if(temp_ip == 0) + temp_ip = search_next_ip(); +#if (debug_dhcps) + printf("\r\n temp_ip = %d",temp_ip); +#endif + if (temp_ip == 0) { +#if 0 + memset(&ip_table, 0, sizeof(struct table)); + mark_ip_in_table((uint8_t)ip4_addr4(&dhcps_local_address)); + printf("\r\n reset ip table!!\r\n"); +#endif + printf("\r\n No useable ip!!!!\r\n"); + } + printf("\n\r[%d]DHCP assign ip = %d.%d.%d.%d\n", rtw_get_current_time(), ip4_addr1(&dhcps_network_id),ip4_addr2(&dhcps_network_id),ip4_addr3(&dhcps_network_id),temp_ip); + IP4_ADDR(&dhcps_allocated_client_address, (ip4_addr1(&dhcps_network_id)), + ip4_addr2(&dhcps_network_id), ip4_addr3(&dhcps_network_id), temp_ip); +#endif + dhcps_initialize_message(dhcp_message_repository); + add_offer_options(add_msg_type(&dhcp_message_repository->options[4], + DHCP_MESSAGE_TYPE_OFFER)); + udp_sendto_if(dhcps_pcb, packet_buffer, + &dhcps_send_broadcast_address, DHCP_CLIENT_PORT, dhcps_netif); +} + +/** + * @brief init and fill in the needed content of dhcp nak message. + * @param packet buffer packet buffer for UDP. + * @retval None. + */ +static void dhcps_send_nak(struct pbuf *packet_buffer) +{ + dhcp_message_repository = (struct dhcp_msg *)packet_buffer->payload; + dhcps_initialize_message(dhcp_message_repository); + add_msg_type(&dhcp_message_repository->options[4], DHCP_MESSAGE_TYPE_NAK); + udp_sendto_if(dhcps_pcb, packet_buffer, + &dhcps_send_broadcast_address, DHCP_CLIENT_PORT, dhcps_netif); +} + +/** + * @brief init and fill in the needed content of dhcp ack message. + * @param packet buffer packet buffer for UDP. + * @retval None. + */ +static void dhcps_send_ack(struct pbuf *packet_buffer) +{ + dhcp_message_repository = (struct dhcp_msg *)packet_buffer->payload; + dhcps_initialize_message(dhcp_message_repository); + add_offer_options(add_msg_type(&dhcp_message_repository->options[4], + DHCP_MESSAGE_TYPE_ACK)); + udp_sendto_if(dhcps_pcb, packet_buffer, + &dhcps_send_broadcast_address, DHCP_CLIENT_PORT, dhcps_netif); +} + +/** + * @brief according by the input message type to reflect the correspond state. + * @param option_message_type the input server state + * @retval the server state which already transfer to. + */ +uint8_t dhcps_handle_state_machine_change(uint8_t option_message_type) +{ + switch (option_message_type) { + case DHCP_MESSAGE_TYPE_DECLINE: + #if (debug_dhcps) + printf("\r\nget message DHCP_MESSAGE_TYPE_DECLINE\n"); + #endif + dhcp_server_state_machine = DHCP_SERVER_STATE_IDLE; + break; + case DHCP_MESSAGE_TYPE_DISCOVER: + #if (debug_dhcps) + printf("\r\nget message DHCP_MESSAGE_TYPE_DISCOVER\n"); + #endif + if (dhcp_server_state_machine == DHCP_SERVER_STATE_IDLE) { + dhcp_server_state_machine = DHCP_SERVER_STATE_OFFER; + } + break; + case DHCP_MESSAGE_TYPE_REQUEST: + #if (debug_dhcps) + printf("\r\n[%d]get message DHCP_MESSAGE_TYPE_REQUEST\n", rtw_get_current_time()); + #endif +#if (!IS_USE_FIXED_IP) +#if (debug_dhcps) + printf("\r\ndhcp_server_state_machine=%d", dhcp_server_state_machine); + printf("\r\ndhcps_allocated_client_address=%d.%d.%d.%d", + ip4_addr1(&dhcps_allocated_client_address), + ip4_addr2(&dhcps_allocated_client_address), + ip4_addr3(&dhcps_allocated_client_address), + ip4_addr4(&dhcps_allocated_client_address)); + printf("\r\nclient_request_ip=%d.%d.%d.%d\n", + ip4_addr1(&client_request_ip), + ip4_addr2(&client_request_ip), + ip4_addr3(&client_request_ip), + ip4_addr4(&client_request_ip)); +#endif + if (dhcp_server_state_machine == DHCP_SERVER_STATE_OFFER) { + if (ip4_addr4(&dhcps_allocated_client_address) != 0) { + if (memcmp((void *)&dhcps_allocated_client_address, (void *)&client_request_ip, 4) == 0) { + dhcp_server_state_machine = DHCP_SERVER_STATE_ACK; + } else { + dhcp_server_state_machine = DHCP_SERVER_STATE_NAK; + } + } else { + dhcp_server_state_machine = DHCP_SERVER_STATE_NAK; + } + } else if(dhcp_server_state_machine == DHCP_SERVER_STATE_IDLE){ + uint8_t ip_addr4 = check_client_request_ip(&client_request_ip, client_addr); + if(ip_addr4 > 0){ + IP4_ADDR(&dhcps_allocated_client_address, (ip4_addr1(&dhcps_network_id)), + ip4_addr2(&dhcps_network_id), ip4_addr3(&dhcps_network_id), ip_addr4); + dhcp_server_state_machine = DHCP_SERVER_STATE_ACK; + }else{ + dhcp_server_state_machine = DHCP_SERVER_STATE_NAK; + } + } else { + dhcp_server_state_machine = DHCP_SERVER_STATE_NAK; + } +#else + if (!(dhcp_server_state_machine == DHCP_SERVER_STATE_ACK || + dhcp_server_state_machine == DHCP_SERVER_STATE_NAK)) { + dhcp_server_state_machine = DHCP_SERVER_STATE_NAK; + } +#endif + break; + case DHCP_MESSAGE_TYPE_RELEASE: + printf("get message DHCP_MESSAGE_TYPE_RELEASE\n"); + dhcp_server_state_machine = DHCP_SERVER_STATE_IDLE; + break; + } + + return dhcp_server_state_machine; +} +/** + * @brief parse the dhcp message option part. + * @param optptr: the addr of the first option field. + * len: the total length of all option fields. + * @retval dhcp server state. + */ +static uint8_t dhcps_handle_msg_options(uint8_t *option_start, int16_t total_option_length) +{ + + int16_t option_message_type = 0; + uint8_t *option_end = option_start + total_option_length; + //dhcp_server_state_machine = DHCP_SERVER_STATE_IDLE; + + /* begin process the dhcp option info */ + while (option_start < option_end) { + switch ((uint8_t)*option_start) { + case DHCP_OPTION_CODE_MSG_TYPE: + option_message_type = *(option_start + 2); // 2 => code(1)+lenth(1) + break; + case DHCP_OPTION_CODE_REQUEST_IP_ADDRESS : +#if IS_USE_FIXED_IP + if (memcmp((char *)&dhcps_allocated_client_address, + (char *)option_start + 2, 4) == 0) + dhcp_server_state_machine = DHCP_SERVER_STATE_ACK; + else + dhcp_server_state_machine = DHCP_SERVER_STATE_NAK; +#else + memcpy((char *)&client_request_ip, (char *)option_start + 2, 4); +#endif + break; + } + // calculate the options offset to get next option's base addr + option_start += option_start[1] + 2; // optptr[1]: length value + (code(1)+ Len(1)) + } + return dhcps_handle_state_machine_change(option_message_type); +} + +/** + * @brief get message from buffer then check whether it is dhcp related or not. + * if yes , parse it more to undersatnd the client's request. + * @param same as recv callback function definition + * @retval if message is dhcp related then return dhcp server state, + * otherwise return 0 + */ +static uint8_t dhcps_check_msg_and_handle_options(struct pbuf *packet_buffer) +{ + int dhcp_message_option_offset; + dhcp_message_repository = (struct dhcp_msg *)packet_buffer->payload; + dhcp_message_option_offset = ((int)dhcp_message_repository->options + - (int)packet_buffer->payload); + dhcp_message_total_options_lenth = (packet_buffer->len + - dhcp_message_option_offset); + memcpy(client_addr, dhcp_message_repository->chaddr, 6); + /* check the magic number,if correct parse the content of options */ + if (memcmp((char *)dhcp_message_repository->options, + (char *)dhcp_magic_cookie, sizeof(dhcp_magic_cookie)) == 0) { + return dhcps_handle_msg_options(&dhcp_message_repository->options[4], + (dhcp_message_total_options_lenth - 4)); + } + + return 0; +} + + +/** + * @brief handle imcoming dhcp message and response message to client + * @param same as recv callback function definition + * @retval None + */ +static void dhcps_receive_udp_packet_handler(void *arg, struct udp_pcb *udp_pcb, +struct pbuf *udp_packet_buffer, ip_addr_t *sender_addr, uint16_t sender_port) +{ + int16_t total_length_of_packet_buffer; + struct pbuf *merged_packet_buffer = NULL; + + dhcp_message_repository = (struct dhcp_msg *)udp_packet_buffer->payload; + if (udp_packet_buffer == NULL) { + printf("\n\r Error!!!! System doesn't allocate any buffer \n\r"); + return; + } + if (sender_port == DHCP_CLIENT_PORT) { + total_length_of_packet_buffer = udp_packet_buffer->tot_len; + if (udp_packet_buffer->next != NULL) { + merged_packet_buffer = pbuf_coalesce(udp_packet_buffer, + PBUF_TRANSPORT); + if (merged_packet_buffer->tot_len != + total_length_of_packet_buffer) { + pbuf_free(udp_packet_buffer); + return; + } + } + switch (dhcps_check_msg_and_handle_options(udp_packet_buffer)) { + case DHCP_SERVER_STATE_OFFER: + #if (debug_dhcps) + printf("%s DHCP_SERVER_STATE_OFFER\n",__func__); + #endif + dhcps_send_offer(udp_packet_buffer); + break; + case DHCP_SERVER_STATE_ACK: + #if (debug_dhcps) + printf("%s DHCP_SERVER_STATE_ACK\n",__func__); + #endif + dhcps_send_ack(udp_packet_buffer); +#if (!IS_USE_FIXED_IP) + mark_ip_in_table((uint8_t)ip4_addr4(&dhcps_allocated_client_address)); + #ifdef CONFIG_DHCPS_KEPT_CLIENT_INFO + save_client_addr(&dhcps_allocated_client_address, client_addr); + memset(&client_request_ip, 0, sizeof(client_request_ip)); + memset(&client_addr, 0, sizeof(client_addr)); + memset(&dhcps_allocated_client_address, 0, sizeof(dhcps_allocated_client_address)); + #if (debug_dhcps) + dump_client_table(); + #endif + #endif +#endif + dhcp_server_state_machine = DHCP_SERVER_STATE_IDLE; + break; + case DHCP_SERVER_STATE_NAK: + #if (debug_dhcps) + printf("%s DHCP_SERVER_STATE_NAK\n",__func__); + #endif + dhcps_send_nak(udp_packet_buffer); + dhcp_server_state_machine = DHCP_SERVER_STATE_IDLE; + break; + case DHCP_OPTION_CODE_END: + #if (debug_dhcps) + printf("%s DHCP_OPTION_CODE_END\n",__func__); + #endif + break; + } + } + + /* free the UDP connection, so we can accept new clients */ + udp_disconnect(udp_pcb); + + /* Free the packet buffer */ + if (merged_packet_buffer != NULL) + pbuf_free(merged_packet_buffer); + else + pbuf_free(udp_packet_buffer); +} + +void dhcps_set_addr_pool(int addr_pool_set, ip_addr_t * addr_pool_start, ip_addr_t *addr_pool_end) +{ + //uint8_t *ip; + if(addr_pool_set){ + dhcps_addr_pool_set = 1; + + memcpy(&dhcps_addr_pool_start, addr_pool_start, + sizeof(ip_addr_t)); + //ip = &dhcps_addr_pool_start; + //ip[3] = 100; + memcpy(&dhcps_addr_pool_end, addr_pool_end, + sizeof(ip_addr_t)); + //ip = &dhcps_addr_pool_end; + //ip[3] = 200; + }else{ + dhcps_addr_pool_set = 0; + } +} +/** + * @brief Initialize dhcp server. + * @param None. + * @retval None. + * Note, for now,we assume the server latch ip 192.168.1.1 and support dynamic + * or fixed IP allocation. + */ +void dhcps_init(struct netif * pnetif) +{ + uint8_t *ip; +// printf("dhcps_init,wlan:%c\n\r",pnetif->name[1]); +#ifdef CONFIG_DHCPS_KEPT_CLIENT_INFO + memset(&ip_table, 0, sizeof(struct table)); +// int i = 0; +// for(i=0; i< DHCPS_MAX_CLIENT_NUM+2; i++) +// memset(ip_table.client_mac[i], 0, 6); +// dump_client_table(); +#endif + + dhcps_netif = pnetif; + + if (dhcps_pcb != NULL) { + udp_remove(dhcps_pcb); + dhcps_pcb = NULL; + } + + dhcps_pcb = udp_new(); + if (dhcps_pcb == NULL) { + printf("\n\r Error!!!upd_new error \n\r"); + return; + } + IP4_ADDR(&dhcps_send_broadcast_address, 255, 255, 255, 255); + /* get net info from net interface */ + + memcpy(&dhcps_local_address, &pnetif->ip_addr, + sizeof(ip_addr_t)); + memcpy(&dhcps_local_mask, &pnetif->netmask, + sizeof(ip_addr_t)); + + memcpy(&dhcps_local_gateway, &pnetif->gw, + sizeof(ip_addr_t)); + + /* calculate the usable network ip range */ + dhcps_network_id.addr = ((pnetif->ip_addr.addr) & + (pnetif->netmask.addr)); + + dhcps_subnet_broadcast.addr = ((dhcps_network_id.addr | + ~(pnetif->netmask.addr))); +#if 1 + dhcps_owned_first_ip.addr = htonl((ntohl(dhcps_network_id.addr) + 1)); + dhcps_owned_last_ip.addr = htonl(ntohl(dhcps_subnet_broadcast.addr) - 1); + dhcps_num_of_available_ips = ((ntohl(dhcps_owned_last_ip.addr) + - ntohl(dhcps_owned_first_ip.addr)) + 1); +#endif + +#if IS_USE_FIXED_IP + IP4_ADDR(&dhcps_allocated_client_address, ip4_addr1(&dhcps_local_address) + , ip4_addr2(&dhcps_local_address), ip4_addr3(&dhcps_local_address), + (ip4_addr4(&dhcps_local_address)) + 1 ); +#else + if (dhcps_ip_table_semaphore != NULL) { + rtw_mutex_free(&dhcps_ip_table_semaphore); + dhcps_ip_table_semaphore = NULL; + } + rtw_mutex_init(&dhcps_ip_table_semaphore); + + //dhcps_ip_table = (struct ip_table *)(pvPortMalloc(sizeof(struct ip_table))); + memset(&ip_table, 0, sizeof(struct table)); + mark_ip_in_table((uint8_t)ip4_addr4(&dhcps_local_address)); + mark_ip_in_table((uint8_t)ip4_addr4(&dhcps_local_gateway)); +#if 0 + for (i = 1; i < ip4_addr4(&dhcps_local_address); i++) { + mark_ip_in_table(i); + } +#endif +#endif + + memcpy(&dhcps_pool_start,&dhcps_local_address,sizeof(ip_addr_t)); + ip = (uint8_t *)&dhcps_pool_start; + ip[3] = DHCP_POOL_START; + memcpy(&dhcps_pool_end,&dhcps_local_address,sizeof(ip_addr_t)); + ip = (uint8_t *)&dhcps_pool_end; + ip[3] = DHCP_POOL_END; + + dhcps_set_addr_pool(1,&dhcps_pool_start,&dhcps_pool_end); + + udp_bind(dhcps_pcb, IP_ADDR_ANY, DHCP_SERVER_PORT); + udp_recv(dhcps_pcb, (udp_recv_fn)dhcps_receive_udp_packet_handler, NULL); +} + +void dhcps_deinit(void) +{ + if (dhcps_pcb != NULL) { + udp_remove(dhcps_pcb); + dhcps_pcb = NULL; + } + if (dhcps_ip_table_semaphore != NULL) { + rtw_mutex_free(&dhcps_ip_table_semaphore); + dhcps_ip_table_semaphore = NULL; + } +} + diff --git a/targets/TARGET_Realtek/TARGET_AMEBA/sdk/common/network/dhcp/dhcps.h b/targets/TARGET_Realtek/TARGET_AMEBA/sdk/common/network/dhcp/dhcps.h new file mode 100644 index 000000000000..7370e7cd246a --- /dev/null +++ b/targets/TARGET_Realtek/TARGET_AMEBA/sdk/common/network/dhcp/dhcps.h @@ -0,0 +1,159 @@ +/****************************************************************************** + * Copyright (c) 2013-2016 Realtek Semiconductor Corp. + * + * 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 __DHCPS_H__ +#define __DHCPS_H__ + +#include "lwip/arch.h" +#include "lwip/netif.h" +#include "lwip/udp.h" +#include "lwip/stats.h" +#include "lwip/sys.h" +#include "lwip/ip_addr.h" +#include + + +#define CONFIG_DHCPS_KEPT_CLIENT_INFO + +#define DHCP_POOL_START 100 +#define DHCP_POOL_END 200 + +#define DHCPS_MAX_CLIENT_NUM (DHCP_POOL_END-DHCP_POOL_START+1) + +#define IS_USE_FIXED_IP 0 +#define debug_dhcps 0 + +/* dhcp server states */ +#define DHCP_SERVER_STATE_OFFER (1) +#define DHCP_SERVER_STATE_DECLINE (2) +#define DHCP_SERVER_STATE_ACK (3) +#define DHCP_SERVER_STATE_NAK (4) +#define DHCP_SERVER_STATE_IDLE (5) + + +#define BOOTP_BROADCAST (0x8000) + +#define DHCP_MESSAGE_OP_REQUEST (1) +#define DHCP_MESSAGE_OP_REPLY (2) + +#define DHCP_MESSAGE_HTYPE (1) +#define DHCP_MESSAGE_HLEN (6) + +#define DHCP_SERVER_PORT (67) +#define DHCP_CLIENT_PORT (68) + +#define DHCP_MESSAGE_TYPE_DISCOVER (1) +#define DHCP_MESSAGE_TYPE_OFFER (2) +#define DHCP_MESSAGE_TYPE_REQUEST (3) +#define DHCP_MESSAGE_TYPE_DECLINE (4) +#define DHCP_MESSAGE_TYPE_ACK (5) +#define DHCP_MESSAGE_TYPE_NAK (6) +#define DHCP_MESSAGE_TYPE_RELEASE (7) + +#define DHCP_OPTION_LENGTH_ONE (1) +#define DHCP_OPTION_LENGTH_TWO (2) +#define DHCP_OPTION_LENGTH_THREE (3) +#define DHCP_OPTION_LENGTH_FOUR (4) + +#define DHCP_OPTION_CODE_SUBNET_MASK (1) +#define DHCP_OPTION_CODE_ROUTER (3) +#define DHCP_OPTION_CODE_DNS_SERVER (6) +#define DHCP_OPTION_CODE_INTERFACE_MTU (26) +#define DHCP_OPTION_CODE_BROADCAST_ADDRESS (28) +#define DHCP_OPTION_CODE_PERFORM_ROUTER_DISCOVERY (31) +#define DHCP_OPTION_CODE_REQUEST_IP_ADDRESS (50) +#define DHCP_OPTION_CODE_LEASE_TIME (51) +#define DHCP_OPTION_CODE_MSG_TYPE (53) +#define DHCP_OPTION_CODE_SERVER_ID (54) +#define DHCP_OPTION_CODE_REQ_LIST (55) +#define DHCP_OPTION_CODE_END (255) + +#define IP_FREE_TO_USE (1) +#define IP_ALREADY_IN_USE (0) + +#define HW_ADDRESS_LENGTH (6) + +/* Reference by RFC 2131 */ +struct dhcp_msg { + uint8_t op; /* Message op code/message type. 1 = BOOTREQUEST, 2 = BOOTREPLY */ + uint8_t htype; /* Hardware address type */ + uint8_t hlen; /* Hardware address length */ + uint8_t hops; /* Client sets to zero, optionally used by relay agents + when booting via a relay agent */ + uint8_t xid[4]; /* Transaction ID, a random number chosen by the client, + used by the client and server to associate messages and + responses between a client and a server */ + uint16_t secs; /* Filled in by client, seconds elapsed since client began address + acquisition or renewal process.*/ + uint16_t flags; /* bit 0: Broadcast flag, bit 1~15:MBZ must 0*/ + uint8_t ciaddr[4]; /* Client IP address; only filled in if client is in BOUND, + RENEW or REBINDING state and can respond to ARP requests. */ + uint8_t yiaddr[4]; /* 'your' (client) IP address */ + uint8_t siaddr[4]; /* IP address of next server to use in bootstrap; + returned in DHCPOFFER, DHCPACK by server. */ + uint8_t giaddr[4]; /* Relay agent IP address, used in booting via a relay agent.*/ + uint8_t chaddr[16]; /* Client hardware address */ + uint8_t sname[64]; /* Optional server host name, null terminated string.*/ + uint8_t file[128]; /* Boot file name, null terminated string; "generic" name or + null in DHCPDISCOVER, fully qualified directory-path name in DHCPOFFER.*/ + uint8_t options[312]; /* Optional parameters field. reference the RFC 2132 */ +}; + +/* use this to check whether the message is dhcp related or not */ +static const uint8_t dhcp_magic_cookie[4] = {99, 130, 83, 99}; +static const uint8_t dhcp_option_lease_time[] = {0x00, 0x00, 0x1c, 0x20}; //1 day +//static const uint8_t dhcp_option_lease_time[] = {0x00, 0x00, 0x0e, 0x10}; // one hour +//static const uint8_t dhcp_option_interface_mtu_576[] = {0x02, 0x40}; +static const uint8_t dhcp_option_interface_mtu[] = {0x05, 0xDC}; + +struct table { + uint32_t ip_range[8]; +#ifdef CONFIG_DHCPS_KEPT_CLIENT_INFO + uint8_t client_mac[256][6]; +#endif +}; + +struct address_pool{ + uint32_t start; + uint32_t end; +}; + +/* 01~32 */ +#define MARK_RANGE1_IP_BIT(table, ip) ((table.ip_range[0]) | (1 << ((ip) - 1))) +/* 33~64 */ +#define MARK_RANGE2_IP_BIT(table, ip) ((table.ip_range[1]) | (1 << ((ip) - 1))) +/* 65~96 */ +#define MARK_RANGE3_IP_BIT(table, ip) ((table.ip_range[2]) | (1 << ((ip) - 1))) +/* 97~128 */ +#define MARK_RANGE4_IP_BIT(table, ip) ((table.ip_range[3]) | (1 << ((ip) - 1))) +/* 129~160 */ +#define MARK_RANGE5_IP_BIT(table, ip) ((table.ip_range[4]) | (1 << ((ip) - 1))) +/* 161~192 */ +#define MARK_RANGE6_IP_BIT(table, ip) ((table.ip_range[5]) | (1 << ((ip) - 1))) +/* 193~224 */ +#define MARK_RANGE7_IP_BIT(table, ip) ((table.ip_range[6]) | (1 << ((ip) - 1))) +/* 225~255 */ +#define MARK_RANGE8_IP_BIT(table, ip) ((table.ip_range[7]) | (1 << ((ip) - 1))) + +/* expose API */ +void dhcps_set_addr_pool(int addr_pool_set, ip_addr_t * addr_pool_start, ip_addr_t *addr_pool_end); +void dhcps_init(struct netif * pnetif); +void dhcps_deinit(void); + +extern struct netif *netif_default; + +#endif /*__DHCPS_H__*/ + diff --git a/targets/TARGET_Realtek/mbed_rtx.h b/targets/TARGET_Realtek/mbed_rtx.h index 1da2503cd2c6..934726af5684 100644 --- a/targets/TARGET_Realtek/mbed_rtx.h +++ b/targets/TARGET_Realtek/mbed_rtx.h @@ -1,3 +1,4 @@ + /* mbed Microcontroller Library * Copyright (c) 2013-2016 Realtek Semiconductor Corp. * @@ -40,4 +41,4 @@ #endif #endif -#endif +#endif \ No newline at end of file diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_DISCO_F051R8/device/system_clock.c b/targets/TARGET_STM/TARGET_STM32F0/TARGET_DISCO_F051R8/device/system_clock.c index 72fa4b7e7d49..a402b09e6fbc 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_DISCO_F051R8/device/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_DISCO_F051R8/device/system_clock.c @@ -29,7 +29,7 @@ */ #include "stm32f0xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" #define USE_PLL_HSE_EXTC 0x8 // Use external clock (ST Link MCO) #define USE_PLL_HSE_XTAL 0x4 // Use external xtal (X3 on board) @@ -138,8 +138,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while(1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F030R8/device/system_clock.c b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F030R8/device/system_clock.c index fe5ebfe73bf7..f097f610a3e5 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F030R8/device/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F030R8/device/system_clock.c @@ -29,7 +29,7 @@ */ #include "stm32f0xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" #define USE_PLL_HSE_EXTC 0x8 // Use external clock (ST Link MCO) #define USE_PLL_HSE_XTAL 0x4 // Use external xtal (X3 on board - not provided by default) @@ -138,8 +138,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while(1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F031K6/device/system_clock.c b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F031K6/device/system_clock.c index 6b57adbc6e77..2f6a4adfd659 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F031K6/device/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F031K6/device/system_clock.c @@ -29,7 +29,7 @@ */ #include "stm32f0xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" #define USE_PLL_HSE_EXTC 0x8 // Use external clock (ST Link MCO - not connected by default) #define USE_PLL_HSE_XTAL 0x4 // Use external xtal (X3 on board - not provided by default) @@ -138,8 +138,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while(1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/device/system_clock.c b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/device/system_clock.c index 26a57fb07e58..0b23593191cc 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/device/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/device/system_clock.c @@ -29,7 +29,7 @@ */ #include "stm32f0xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" #define USE_PLL_HSE_EXTC 0x8 // Use external clock (ST Link MCO - not connected by default) #define USE_PLL_HSE_XTAL 0x4 // Use external xtal (X3 on board - not provided by default) @@ -138,8 +138,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while(1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F070RB/device/system_clock.c b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F070RB/device/system_clock.c index 0cc1885a6f65..9790182e8895 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F070RB/device/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F070RB/device/system_clock.c @@ -29,7 +29,7 @@ */ #include "stm32f0xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" #define USE_PLL_HSE_EXTC 0x8 // Use external clock (ST Link MCO) #define USE_PLL_HSE_XTAL 0x4 // Use external xtal (X3 on board - not provided by default) @@ -138,8 +138,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while(1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F072RB/device/system_clock.c b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F072RB/device/system_clock.c index f33cb6931e2c..ad7c7c279435 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F072RB/device/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F072RB/device/system_clock.c @@ -29,7 +29,7 @@ */ #include "stm32f0xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" #define USE_PLL_HSE_EXTC 0x8 // Use external clock (ST Link MCO) #define USE_PLL_HSE_XTAL 0x4 // Use external xtal (X3 on board - not provided by default) @@ -138,8 +138,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while(1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F091RC/device/system_clock.c b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F091RC/device/system_clock.c index 8034b2e194b8..10a70fe8608e 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F091RC/device/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F091RC/device/system_clock.c @@ -29,7 +29,7 @@ */ #include "stm32f0xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" #define USE_PLL_HSE_EXTC 0x8 // Use external clock (ST Link MCO) #define USE_PLL_HSE_XTAL 0x4 // Use external xtal (X3 on board - not provided by default) @@ -138,8 +138,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while(1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F0/device.h b/targets/TARGET_STM/TARGET_STM32F0/device.h index b6131682750f..93edfb5237a0 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/device.h +++ b/targets/TARGET_STM/TARGET_STM32F0/device.h @@ -36,5 +36,7 @@ #define DEVICE_ID_LENGTH 24 #include "objects.h" +/* WORKAROUND waiting for mbed-os issue 4408 to be addressed */ +#include "stm32f0xx_ll_usart.h" #endif diff --git a/targets/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/device/system_clock.c b/targets/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/device/system_clock.c index 370937ae1b8f..abbadf5c65ec 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/device/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/device/system_clock.c @@ -35,7 +35,7 @@ */ #include "stm32f1xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -145,8 +145,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while(1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F1/device.h b/targets/TARGET_STM/TARGET_STM32F1/device.h index b6131682750f..645517f59cc3 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device.h @@ -36,5 +36,7 @@ #define DEVICE_ID_LENGTH 24 #include "objects.h" +/* WORKAROUND waiting for mbed-os issue 4408 to be addressed */ +#include "stm32f1xx_ll_usart.h" #endif diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/Release_Notes_stm32cubef1.html b/targets/TARGET_STM/TARGET_STM32F1/device/Release_Notes_stm32cubef1.html new file mode 100644 index 000000000000..b439fe6356fd --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F1/device/Release_Notes_stm32cubef1.html @@ -0,0 +1,1736 @@ + + + + + + + + +Release Notes for STM32CubeF1 Firmware Package + +
+


+

+
+ + + + + + +
+ + + + + + +
+

Release +Notes for STM32CubeF1 Firmware Package

+

Copyright 2017 +STMicroelectronics

+

+
+

 

+ + + + + + + + + +
+

+STMCube is an STMicroelectronics original initiative to ease developers +life by reducing development efforts, time and cos
t. +STM32Cube covers STM32 portfolio.

+
+

+STM32Cube Version 1.x includes:
+
    +
      +
    • The +STM32CubeMX, a graphical software configuration tool that allows to +generate C initialization code using graphical wizards.
    • +
    • A +comprehensive embedded software platform, delivered per series (such as +STM32CubeF1 for STM32F1 series)
    • +
        +
      • The +STM32Cube HAL, an STM32 abstraction layer embedded software, ensuring +maximized portability across STM32 portfolio
      • +
      +
        +
      • A +consistent set of middleware components such as RTOS, USB, TCP/IP, +Graphics
      • +
      +
    +
+
All +embedded software utilities come with a full set of examples.
+
+
+
    +
  • The +STM32Cube firmware solution offers a straightforward API with a modular +architecture, making it simple to fine tune custom applications and +scalable to +fit most requirements
  • +
+     
+         
+
+
    +
  • +

    The +HAL +(Hardware Abstraction Layer) drivers provided within this +package supports +the following STM32F100xx + STM32F101xx, STM32F102xx, STM32F103xx, STM32F105xx and STM32F107xx +Series.

    +
  • +
  • The +STM32CubeF1 firmware package comes with an updater utility, STM32CubeUpdater, +that can be configured for automatic +or on-demand checks for new firmware package updates (new +releases or/and patches).
  • +
+
    +
  • For quick getting started with the +STM32CubeF1 firmware package, refer to UM1847 and you can +download firmware updates and all the latest documentation from www.st.com/stm32cube
  • +
  • Below +links to +the most useful documents
    +
    • Latest release of STM32CubeF1 Firmware package.
    • UM1847: Getting started with STM32CubeF1 for STM32F1 Series.
    • UM1853: STM32CubeF1 Nucleo demonstration firmware.
    • UM1850: Description of STM32F1xx HAL drivers.
    • UM1734: STM32Cube USB Device library.
    • UM1720: STM32Cube USB host library.
    • UM1721: Developing Applications on STM32Cube with FatFs.
    • UM1722: Developing Applications on STM32Cube with RTOS.
    • UM1713: Developing applications on STM32Cube with LwIP TCP/IP stack.
    • UM1709: STM32Cube Ethernet IAP example.
+ + +

Update +History

+

V1.6.1 / 09-March-2018

Main Changes

  • Patch release to fix issues in GPIO, RCC, SMARTCARD, I2C and Generic HAL/LL drivers

Contents

V1.6.0 / 12-May-2017

Main Changes

  • General update to fix known defects and several implementations enhancement
  • \HAL
    • stm32f1xx_hal_conf_template.h fix typo: update to refer to stm32f1xx_hal_mmc.h instead of  stm32f4xx_hal_mmc.h
    • stm32f1xx_hal_mmc.c add missing () to fix compilation warning detected with SW4STM32 when extra feature is enabled.
    • stm32f1xx_ll_system.h: fix typo in LL_DBGMCU_APB1_GRP1_I2C1_STOP and LL_DBGMCU_APB1_GRP1_I2C2_STOP literals definition
  • \Projects
    • General updates to be compliant with Linux platforms
  • For the complete list of changes, please refer to the release notes of each firmware component

Contents


Development Toolchains and Compilers

  • IAR Embedded Workbench for ARM (EWARM) toolchain v7.80.4
  • RealView +Microcontroller Development Kit (MDK-ARM) toolchain V5.23 
  • Atollic +TrueSTUDIO STM32 (TrueSTUDIO) toolchain V5.5.2
  • System +Workbench for STM32 (SW4STM32) toolchain V1.13

Supported +Devices and EVAL boards

+
  • STM32F1xx +Value, Access, USB, Performance, OTG & Ethernet Lines
  • STM3210E-Eval +board RevD
  • STM3210C-Eval +board RevC
  • STM32VL-Discovery +board RevC
  • STM32F1xx-Nucleo +board RevC
+
+
+

Known +Limitations
+

+
  • SW4STM32 projects aren't provided for STM32VL-Discovery board because it embeds STLinv1 version that is not hardware supported by SW4STM32 toolchain.

V1.5.0 / 14-April-2017

Main Changes

  • Add Low Layer drivers under Drivers\STM32F1xx_HAL_Driver
    • Low Layer drivers allow performance and memory footprint optimization
      • Low +Layer drivers APIs provide register level programming: they require +deep knowledge of peripherals described in STM32F1xx Reference Manuals
      • Low Layer drivers are available for: ADC, Cortex, +CRC, DAC, DMA, EXTI, GPIO, I2C, IWDG, PWR, RCC, RNG, RTC, +SPI, TIM, USART, WWDG peripherals and additionnal Low Level Bus, System +and Utilities APIs. 
      • Low Layer drivers APIs are implemented as static inline function in new Inc/stm32f1xx_ll_ppp.h files for PPP peripherals, there is no configuration file and each stm32f1xx_ll_ppp.h file must be included in user code.
      • Refer to UM1847 for Low Layer presentation and UM1850 for API list
  • General update to fix known defects and several implementations enhancement
  • \HAL
    • Add Low Layer drivers under Drivers\STM32F1xx_HAL_Driver
    • Add new MMC HAL driver
    • The following changes done on the HAL drivers require an update on the application code based on older HAL versions
      • HAL UART, USART, IRDA, SMARTCARD, SPI, I2C,FMPI2C, QSPI (referenced as PPP here below) drivers
        • Add PPP error management during DMA process. This requires the following updates on user application:
          • Configure and enable the PPP IRQ in HAL_PPP_MspInit() function
          • In stm32f1xx_it.c file, PPP_IRQHandler() function: add a call to HAL_PPP_IRQHandler() function
          • Add customize the Error Callback API: HAL_PPP_ErrorCallback()
      • HAL SD driver:
        • Overall rework of the driver for a more efficient implementation
          • Modify initialization API and structures
          • Modify Read / Write sequences: separate transfer process and SD Cards state management 
          • Adding interrupt mode for Read / Write operations
          • Update the HAL_SD_IRQHandler function by optimizing the management of interrupt errors
        • Refer to the following example to identify the changes: BSP example and USB_Device/MSC_Standalone application
      • HAL NAND driver:
        • Modify NAND_AddressTypeDef, NAND_DeviceConfigTypeDef and NAND_HandleTypeDef structures fields
        • Add new HAL_NAND_ConfigDevice API
      • HAL CEC driver:  Overall driver rework with compatibility break versus previous HAL version
        • Remove HAL CEC polling Process functions: HAL_CEC_Transmit() and HAL_CEC_Receive()
        • Remove +HAL CEC receive interrupt process function HAL_CEC_Receive_IT() +and enable the "receive"  mode during the Init phase
        • Rename HAL_CEC_GetReceivedFrameSize() funtion to HAL_CEC_GetLastReceivedFrameSize()
        • Add new HAL APIs: HAL_CEC_SetDeviceAddress() and HAL_CEC_ChangeRxBuffer()
        • Remove the 'InitiatorAddress' +field from the CEC_InitTypeDef structure and manage +it as a parameter in the HAL_CEC_Transmit_IT() function
        • Add new parameter 'RxFrameSize' in HAL_CEC_RxCpltCallback() function
        • Move CEC Rx buffer pointer from CEC_HandleTypeDef structure to CEC_InitTypeDef structure
      • HAL IWDG driver: rework overall driver for better implementation
        • Remove HAL_IWDG_Start(), HAL_IWDG_MspInit() and HAL_IWDG_GetState() APIs
      • HAL WWDG driver: rework overall driver for better implementation
        • Remove HAL_WWDG_Start(), HAL_WWDG_Start_IT(), HAL_WWDG_MspDeInit() and HAL_WWDG_GetState() APIs 
        • Update the HAL_WWDG_Refresh(WWDG_HandleTypeDef *hwwdg, uint32_t counter)  function and API  by removing the  "counter" parameter
  • \CMSIS
    • Fix known defects and several implementation enhancement
    • General update to support Low layer drivers (LL)
  • \Middleware
    • Update STemWin Library V5.32 with a new build with EWARM V7.80
    • Upgrade to use new version of LwIP V2.0.0
      • Note:  Applications based on previous version LwIP V1.4.1 +require update to cope with the upgrade to the currently used V2.0.0. +For details please refer to its Release Note and to the updated LwIP +applications provided by this firmware package.
    • Update to new version of FreeRTOS V9.0.0
    • Update FatFS to implement changes on sd_diskio.c file to be aligned with HAL SD driver and BSP drivers API changes.
  • \Projects
    • General updates to fix known defects and enhancements implementation
    • Add Low Layer examples and MIX examples on the STM32F103RB-Nucleo, STM32F10E-EVAL boards
    • Update overall projects to be aligned with latest version of HAL, BSP and Middleware drivers
    • Add HAL_TimeBase RTC examples on all the supported boards
    • Add I2C_TwoBoards_RestartAdvComIT and  I2C_TwoBoards_RestartComIT Examples
  • For the complete list of changes, please refer to the release notes of each firmware component

Contents


Development Toolchains and Compilers

  • IAR Embedded Workbench for ARM (EWARM) toolchain v7.80.4
  • RealView +Microcontroller Development Kit (MDK-ARM) toolchain V5.23 
  • Atollic +TrueSTUDIO STM32 (TrueSTUDIO) toolchain V5.5.2
  • System +Workbench for STM32 (SW4STM32) toolchain V1.13

Supported +Devices and EVAL boards

+
  • STM32F1xx +Value, Access, USB, Performance, OTG & Ethernet Lines
  • STM3210E-Eval +board RevD
  • STM3210C-Eval +board RevC
  • STM32VL-Discovery +board RevC
  • STM32F1xx-Nucleo +board RevC
+
+
+

Known +Limitations
+

+
  • None

V1.4.0 / 29-April-2016

+

Main +Changes

+
  • Maintenance release to fix known defects and several enhancements +implementation.
  • HAL
    • HAL RCC
      • Add suffix U for defines equals to 0xFFFFFFFF (fix MISRA error 10.6)
      • Optimization of HAL_RCC_ClockConfig().
      • Replace aAPBAHBPrescTable by APBPrescTable and AHBPrescTable defined inside system_stm32f1xx.c.
      • When using HAL_RCC_OscConfig +to activate LSE, if LSE is already ON, it remains in its state ON. +Previously, it was turned OFF then ON in all cases.
      • The backup domain is no more reset when changing the RTC clock source from reset value.
      • Correct strange behavior in HAL_RCCEx_PeriphCLKConfig.
    • HAL UART
      • Correct the macro UART_BRR_SAMPLING16
    • HAL SMARTCARD
      • Correct the macro SMARTCARD_BRR
    • HAL IRDA
      • Correct the macro IRDA_BRR
      • EIE bit is no more activated in transmit (this bit only triggers errors in reception)
      • EIE bit is reset at the end of the reception.
    • HAL DMA
      • Add macro __HAL_DMA_GET_COUNTER to get the number of remaining data units in the current channel.
    • HAL FSMC
      • Adapt FSMC_NAND_Init behavior to the others STM32 series by reseting the bit FSMC_PCRx_PBKEN.
  • CMSIS
    • Add _Pos and _Msk defines to be used with _VAL2FLD(field, value) and _FLD2VAL(field, value). 
      • The previous naming are kept for backward compatibility.
    • Add APBPrescTable constant to list APB prescalers values.
  • BSP +STM32F1xx_Nucleo
    • Add support for 4 Gb sd cards.
  • BSP +STM3210E_EVAL
    • Set the NVIC priority to the lowest possible to not interfere with user settings.
  • BSP +STM3210C_EVAL
    • Set the NVIC priority to the lowest possible to not interfere with user settings.
  • Middlewares
    • Update to FreeRTOS +V8.2.3.
    • Update to STM32 USB Device Library V2.4.2
  • Others
    • Add latest version of STM32CubeUpdater (V4.10.0).
+ + +
+

Development +Toolchains and Compilers

+
  • IAR Embedded +Workbench for ARM (EWARM) toolchain V7.20 + ST-LINK
  • RealView +Microcontroller Development Kit (MDK-ARM) toolchain V5.17 ST-LINK
  • Atollic +TrueSTUDIO STM32 (TrueSTUDIO) toolchain V5.1.1 + ST-LINK
  • System +Workbench for STM32 (SW4STM32) toolchain V1.5.0 + ST-LINK
+
+
+

Supported +Devices and EVAL boards

+
  • STM32F1xx +Value, Access, USB, Performance, OTG & Ethernet Lines
  • STM3210E-Eval +board RevD
  • STM3210C-Eval +board RevC
  • STM32VL-Discovery +board RevC
  • STM32F1xx-Nucleo +board RevC
+
+
+

Known +Limitations
+

+
  • None

V1.3.1 / 11-January-2016

+

Main +Changes

+
  • Patch release to fix issue in HAL driver:
    • Remove the #if defined(USE_HAL_LEGACY) condition to include Legacy/stm32_hal_legacy.h by default, in stm32f1xx_hal_def.h.

Contents

V1.3.0 +/ 18-December-2015

+ +

Main +Changes

+
  • Maintenance release to fix known defects and several enhancements +implementation.
  • HAL
    • Insure that do {} while(0)  are used in in multi statement macros. (hal eth and pcd)
    • Manage simultaneous errors in IRQHandler. (hal uart, smartcard, usart and uart)
    • To +ensure the full compatibility of the GPIO interfaces across all the +STM32 families, the gpio speed definition have been renamed:
      • GPIO_SPEED_LOW to GPIO_SPEED_FREQ_LOW
      • GPIO_SPEED_MEDIUM to GPIO_SPEED_FREQ_MEDIUM
      • GPIO_SPEED_HIGH to GPIO_SPEED_FREQ_HIGH
      • aliases are created to keep backward compatibility
    • Reduce the default timeout value for the startup of the HSE form 5s to 100ms.
    • Update HAL weak empty callbacks to prevent unused argument compilation warnings with some compilers.
  • CMSIS
    • Align bit name across all STM32 families (EXTI, WWDG) and keeping backward compatibility with aliases.
  • Middlewares
    • Update to CMSIS V4.5.
  • Projects
    • Update all Keil project from Keil V4 to Keil V5.
    • Update all SW4STM32 projects to version 1.5.0.
  • Others
    • Add latest version of STM32CubeUpdater (V4.10.0).
+ + +
+

Development +Toolchains and Compilers

+
  • IAR Embedded +Workbench for ARM (EWARM) toolchain V7.20 + ST-LINK
  • RealView +Microcontroller Development Kit (MDK-ARM) toolchain V5.17 ST-LINK
  • Atollic +TrueSTUDIO STM32 (TrueSTUDIO) toolchain V5.1.1 + ST-LINK
  • System +Workbench for STM32 (SW4STM32) toolchain V1.5.0 + ST-LINK
+
+
+

Supported +Devices and EVAL boards

+
  • STM32F1xx +Value, Access, USB, Performance, OTG & Ethernet Lines
  • STM3210E-Eval +board RevD
  • STM3210C-Eval +board RevC
  • STM32VL-Discovery +board RevC
  • STM32F1xx-Nucleo +board RevC
+
+
+

Known +Limitations
+

+
  • None

V1.2.0 +/ 31-July-2015

+ +

Main +Changes

+
    +
  • Maintenance release.
  • +
  • Fix known defects and several enhancements +implementation.
  • +
  • \Projects
  • +
      +
    • Adding new projects to introduce the FreeRTOS +V8.2.1
    • +
        +
      • FreeRTOS_SignalFromISR (thread signaling from +an interrupt)
      • +
      • FreeRTOS_Signal (thread signaling)
      • +
      • FreeRTOS_Mail (mail queues)
      • +
      +
    • Adding +new application IAP for STM3210E_EVAL board.
      +
    • +
    +
  • \FatFs
  • +
      +
    • Upgrade to +use FatFs R0.11.
    • +
    • Add new APIs +FATFS_LinkDriverEx() and FATFS_UnLinkDriverEx() to manage USB Key Disk +having
      +     multi-lun capability. These +APIs are equivalent to FATFS_LinkDriver() and FATFS_UnLinkDriver()
      +     with "lun" parameter set to 0.
    • +
    • ff_conf.h: +add new define "_USE_BUFF_WO_ALIGNMENT".
    • +
    • Important +note:
      +      For application code +based on previous FatFs version; when moving to R0.11
      +      the changes that +need to be done is to update ffconf.h file, taking
      +      ffconf_template.h +file as reference.
    • +
    +
  • \STM32 USB Host and STM32 USB Device Library
  • +
      +
    • This new versions implements only bug fixes +with minor enhancements, it doesn’t impact neither the APIs nor the +behavior of applications developed so far.
    • +
    +
  • \STemWin
  • +
      +
    • Upgrade +to use SEGGER emWin version V5.28, for more +details about the +changes in this version refer to "Revision History" section in STemWin528.pdf document
    • +
    +
  • \FreeRTOS
  • +
      +
    • No changes in file naming/set of sources +files.
    • +
    • Align +Port.c for CM7, CM4 and CM3  to M0  regarding +function +“vPortSuppressTicksAndSleep : Same implementation for CM7, CM4 and CM3 +as CM0
    • +
    • Macros “configPRE_SLEEP_PROCESSING” and + “configPOST_SLEEP_PROCESSING are now passing the parameter +ulExpectedIdleTime by pointer
    • +
    • Adding implementation for APIs “osSignalSet” +and “osSignalWait”.
    • +
    • API changes on CMSIS-RTOS (osDelayUntil()).
    • +
    • Internal enhancements and bug fixes.
    • +
    +
+ + +
    +
      +
    • CMSIS-DSP +V1.4.5
    • +
    +
+ +
    +
      +
    • CMSIS-RTOS +V1.02 (unchanged)
    • +
    +
+ +

Contents

+ + + +
+

Development +Toolchains and Compilers

+
    +
  • IAR Embedded +Workbench for ARM (EWARM) toolchain V7.20 + ST-LINK
  • +
  • RealView +Microcontroller Development Kit (MDK-ARM) toolchain V5.10 ST-LINK
  • +
      +
    • Important +note: some of MDK-ARM projects were +created with previous version like v4.73. If you are using +MDK-ARM v5.10 (and later) you have to install a legacy patch to be able +to open projects built with v4.73, here is the download link
    • +
    +
  • Atollic +TrueSTUDIO STM32 (TrueSTUDIO) toolchain V5.1.1 + ST-LINK
  • +
  • System +Workbench for STM32 (SW4STM32) toolchain V1.2.0 + ST-LINK
  • +
+
+
+

Supported +Devices and EVAL boards

+
    +
  • STM32F1xx +Value, Access, USB, Performance, OTG & Ethernet Lines
  • +
  • STM3210E-Eval +board RevD
  • +
  • STM3210C-Eval +board RevC
  • +
  • STM32VL-Discovery +board RevC
  • +
  • STM32F1xx-Nucleo +board RevC
  • +
+
+
+

Known +Limitations
+

+
    +
  • None
  • +
+

V1.1.0 +/ 05-June-2015

+

Main +Changes +

+
    +
  • Add support of System Workbench +for STM32 (SW4STM32) toolchain
  • +
+
    +
  • \HAL
    +
  • +
      +
    • No +changes
    • +
    +
  • \Middlewares
    +
  • +
      +
    • No +changes
    • +
    +
  • \BSP
    +
  • +
      +
    • No +changes
    • +
    +
  • \Projects
    +
  • +
      +
    • Add projects for SW4STM32 toolchain
    • +
    +
+

Contents

+ + + + + +

Development +Toolchains and Compilers

+
    +
  • IAR Embedded +Workbench for ARM (EWARM) toolchain V7.20 + ST-LINK
  • +
  • RealView +Microcontroller Development Kit (MDK-ARM) toolchain V5.10 ST-LINK
  • +
  • Atollic +TrueSTUDIO STM32 (TrueSTUDIO) toolchain V5.1.1 + ST-LINK
  • +
  • System +Workbench for STM32 (SW4STM32) toolchain V1.2.0 + ST-LINK
  • +
    +
    +
+

Supported +Devices and EVAL boards

+
    +
  • STM32F1xx +Value, Access, USB, Performance, OTG & Ethernet Lines
  • +
  • STM3210E-Eval +board RevD
  • +
  • STM3210C-Eval +board RevC
  • +
  • STM32VL-Discovery +board RevC
  • +
  • STM32F1xx-Nucleo +board RevC
  • +
+
+
+

Known +Limitations
+

+
    +
  • None
  • +
+

V1.0.0 +/ 17-December-2014

+

Main +Changes

+
    +
  • First +official release of STM32CubeF1 (STM32Cube for STM32F1 Series)
  • +
+

+

Contents

+ + + + + +
+

STM32Cube_FW_F1 + Projects (details)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Board

+
+

Examples

+
+

Applications

+
+

Demonstration

+
+

STM3210E-EVAL

+
+

30

+
+

8

+
+

N/A

+
+

STM3210C-EVAL

+
+

17

+
+

19

+
+

N/A

+
+

STM32VL-Discovery

+
+

16

+
+

N/A

+
+

N/A

+
+

NUCLEO-F103RB

+
+

24

+
+

3

+
+

1

+
+
+ +

Development +Toolchains and Compilers

+
    +
  • IAR Embedded +Workbench for ARM (EWARM) toolchain V7.20 + ST-LINK
  • +
  • RealView +Microcontroller Development Kit (MDK-ARM) toolchain V5.10 ST-LINK
  • +
  • Atollic +TrueSTUDIO STM32 (TrueSTUDIO) toolchain V5.1.1 + ST-LINK
  • +
    +
    +
+

Supported +Devices and EVAL boards

+
    +
  • STM32F1xx +Value, Access, USB, Performance, OTG & Ethernet Lines
  • +
  • STM3210E-Eval +board RevD
  • +
  • STM3210C-Eval +board RevC
  • +
  • STM32VL-Discovery +board RevC
  • +
  • STM32F1xx-Nucleo +board RevC
  • +
+
+
+

Known +Limitations
+

+
    +
  • None
  • +
+ +

License

+

Licensed +under MCD-ST Liberty SW License Agreement V2, (the "License"); You may +not use this package +except in compliance with the License. You may obtain a copy of the +License at:
+
+

+ +
+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.
+
+
+

For +complete documentation on STM32 Microcontrollers visit www.st.com/STM32
+

+
+

+
+
+

 

+
+ \ No newline at end of file diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/Release_Notes_stm32f1xx_hal.html b/targets/TARGET_STM/TARGET_STM32F1/device/Release_Notes_stm32f1xx_hal.html index c026d296fc51..0c01dc529caa 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/Release_Notes_stm32f1xx_hal.html +++ b/targets/TARGET_STM/TARGET_STM32F1/device/Release_Notes_stm32f1xx_hal.html @@ -920,7 +920,13 @@

Update History

-

V1.1.0 / 14-April-2017

  • Add Low Layer drivers allowing performance and footprint optimization
    • Low +

      V1.1.2 / 09-March-2018

      • General updates to fix known defects and enhancements implementation
      • Remove Date and version from header files
      • HAL Generic update
        • stm32f1xx_hal_def.h file changes:
          • Update UNUSED() macro implementation to avoid GCC warning
            • The warning is detected when the UNUSED() macro is called from C++ file
          • Update __weak and __packed defined values for ARM compiler
          • Update __ALIGN_BEGIN and __ALIGN_END defined values for ARM compiler
          • Update to make RAMFUNC define as generic type instead of HAL_StatusTypdef type
        • stm32f1xx_hal.c/.h file changes:
          • Update HAL driver to allow user to change systick period to 1ms, 10 ms or 100 ms:
            • Add the following APIs:  
              • HAL_GetTickPrio(): Returns a tick priority
              • HAL_SetTickFreq(): Sets new tick frequency
              • HAL_GetTickFreq(): Returns tick frequency
            • Add HAL_TickFreqTypeDef enumeration for the different Tick Frequencies: 10 Hz, 100 Hz and
              1KHz (default)
        • stm32f1xx_hal_conf_template.h file changes:
          • Fix wrong defined value of LSI
      • HAL GPIO update
        • Rework AFIO remap macros to avoid issue with Read-modify-write sequence on AFIO_MAPR register
      • HAL I2C update
        • Fix wrong check of data size in HAL_I2C_Slave Receive() API
        • Add a check on the minimum allowed PCLK1 frequency in HAL_I2C_Init() API
        • Fix I2C_SPEED_FAST() and I2C_SPEED_STANDARD() speed calculation macros to not let I2C SCL to go beyond
          400KHz in some conditions
      • HAL RCC update
        • Update HAL_RCC_DeInit() and LL_RCC_DeInit() APIs to
          • Be able to return HAL/LL status
          • Add checks for HSI, PLL and PLLI2S  ready before modifying RCC CFGR registers
          • Clear all interrupt flags
          • Initialize systick interrupt period
        • Update HAL_RCC_GetSysClockFreq() to avoid risk of rounding error which may leads to a wrong returned value. 

      • HAL SMARTCARD update
        • Update data processing in HAL smartcard transmit/receive processes(Polling/IT) to fix memory corruption issue.
      • LL GPIO update
        • Fix wrong management of GPIO pin position in LL_GPIO_Init() API when configuring GPIOx_CRH register
        • Fix wrong check conditions on GPIO mode in LL_GPIO_Init() API
      • LL I2C update
        • Rename +IS_I2C_CLOCK_SPEED() and IS_I2C_DUTY_CYCLE() respectively to +IS_LL_I2C_CLOCK_SPEED() and IS_LL_I2C_DUTY_CYCLE() to avoid +incompatible macros redefinition.
      • LL RCC update 
        • Add LL_RCC_PLL_SetMainSource() macro to configure PLL main clock source

      V1.1.1 / 12-May-2017

      • General updates to fix known defects and enhancements implementation
      • HAL Generic update
        • stm32f1xx_hal_conf_template.h fix typo: update to refer to stm32f1xx_hal_mmc.h instead of  stm32f4xx_hal_mmc.h
      • LL SYSTEM update
        • LL_DBGMCU_APB1_GRP1_I2C1_STOP and LL_DBGMCU_APB1_GRP1_I2C2_STOP literals are retarget to an available literals
        • LL_DBGMCU_APB1_GRP1_RTC_STOP literal is not available for all STM32F1 devices
      • HAL MMC update
        • Add missing () to fix compilation warning detected with SW4STM32 when extra feature is enabled.
      • HAL I2C update
        • Update +HAL I2C processes to manage correctly the I2C state to allow the +possibility to call HAL_I2C_Master_Sequential_Receive_IT() followed by +a call HAL_I2C_Master_Sequential_Transmit_IT()

      V1.1.0 / 14-April-2017

      • Add Low Layer drivers allowing performance and footprint optimization
        • Low Layer drivers APIs provide register level programming: require deep knowledge of peripherals described in STM32F1xx Reference Manuals
        • Low Layer drivers are available for: ADC, Cortex, CRC, DAC, DMA, EXTI, GPIO, I2C, IWDG, PWR, RCC, RTC, SPI, TIM, diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32_assert_template.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32_assert_template.h index d3c6502c9c8b..4ae7e25d83ef 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32_assert_template.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32_assert_template.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32_assert.h * @author MCD Application Team - * @version $VERSION$ - * @date $DATE$ * @brief STM32 assert template file. * This file should be copied to the application folder and renamed * to stm32_assert.h. diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32_hal_legacy.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32_hal_legacy.h index 6cc1ce6c2b84..af3311053b87 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32_hal_legacy.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32_hal_legacy.h @@ -2,8 +2,8 @@ ****************************************************************************** * @file stm32_hal_legacy.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 + * @version V1.1.1 + * @date 12-May-2017 * @brief This file contains aliases definition for the STM32Cube HAL constants * macros and functions maintained for legacy purpose. ****************************************************************************** diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal.c index 59a582077081..16f923dba277 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief HAL module driver. * This is the common part of the HAL initialization * @@ -13,9 +11,9 @@ ============================================================================== [..] The common HAL driver contains a set of generic and common APIs that can be - used by the PPP peripheral drivers and the user to start using the HAL. + used by the PPP peripheral drivers and the user to start using the HAL. [..] - The HAL contains two APIs' categories: + The HAL contains two APIs' categories: (+) Common HAL APIs (+) Services HAL APIs @@ -71,11 +69,11 @@ * @{ */ /** - * @brief STM32F1xx HAL Driver version number V1.1.0 + * @brief STM32F1xx HAL Driver version number V1.1.2 */ #define __STM32F1xx_HAL_VERSION_MAIN (0x01U) /*!< [31:24] main version */ #define __STM32F1xx_HAL_VERSION_SUB1 (0x01U) /*!< [23:16] sub1 version */ -#define __STM32F1xx_HAL_VERSION_SUB2 (0x00U) /*!< [15:8] sub2 version */ +#define __STM32F1xx_HAL_VERSION_SUB2 (0x02U) /*!< [15:8] sub2 version */ #define __STM32F1xx_HAL_VERSION_RC (0x00U) /*!< [7:0] release candidate */ #define __STM32F1xx_HAL_VERSION ((__STM32F1xx_HAL_VERSION_MAIN << 24)\ |(__STM32F1xx_HAL_VERSION_SUB1 << 16)\ @@ -95,6 +93,8 @@ * @{ */ __IO uint32_t uwTick; +uint32_t uwTickPrio = (1UL << __NVIC_PRIO_BITS); /* Invalid PRIO */ +HAL_TickFreqTypeDef uwTickFreq = HAL_TICK_FREQ_DEFAULT; /* 1KHz */ /** * @} */ @@ -105,7 +105,7 @@ __IO uint32_t uwTick; * @{ */ -/** @defgroup HAL_Exported_Functions_Group1 Initialization and de-initialization Functions +/** @defgroup HAL_Exported_Functions_Group1 Initialization and de-initialization Functions * @brief Initialization and de-initialization functions * @verbatim @@ -113,33 +113,33 @@ __IO uint32_t uwTick; ##### Initialization and de-initialization functions ##### =============================================================================== [..] This section provides functions allowing to: - (+) Initializes the Flash interface, the NVIC allocation and initial clock - configuration. It initializes the source of time base also when timeout - is needed and the backup domain when enabled. + (+) Initializes the Flash interface, the NVIC allocation and initial clock + configuration. It initializes the systick also when timeout is needed + and the backup domain when enabled. (+) de-Initializes common part of the HAL. - (+) Configure The time base source to have 1ms time base with a dedicated - Tick interrupt priority. - (++) Systick timer is used by default as source of time base, but user - can eventually implement his proper time base source (a general purpose - timer for example or other time source), keeping in mind that Time base - duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and + (+) Configure The time base source to have 1ms time base with a dedicated + Tick interrupt priority. + (++) SysTick timer is used by default as source of time base, but user + can eventually implement his proper time base source (a general purpose + timer for example or other time source), keeping in mind that Time base + duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and handled in milliseconds basis. - (++) Time base configuration function (HAL_InitTick ()) is called automatically - at the beginning of the program after reset by HAL_Init() or at any time - when clock is configured, by HAL_RCC_ClockConfig(). - (++) Source of time base is configured to generate interrupts at regular - time intervals. Care must be taken if HAL_Delay() is called from a - peripheral ISR process, the Tick interrupt line must have higher priority - (numerically lower) than the peripheral interrupt. Otherwise the caller - ISR process will be blocked. - (++) functions affecting time base configurations are declared as __weak + (++) Time base configuration function (HAL_InitTick ()) is called automatically + at the beginning of the program after reset by HAL_Init() or at any time + when clock is configured, by HAL_RCC_ClockConfig(). + (++) Source of time base is configured to generate interrupts at regular + time intervals. Care must be taken if HAL_Delay() is called from a + peripheral ISR process, the Tick interrupt line must have higher priority + (numerically lower) than the peripheral interrupt. Otherwise the caller + ISR process will be blocked. + (++) functions affecting time base configurations are declared as __weak to make override possible in case of other implementations in user file. @endverbatim * @{ */ /** - * @brief This function is used to initialize the HAL Library; it must be the first + * @brief This function is used to initialize the HAL Library; it must be the first * instruction to be executed in the main program (before to call any other * HAL function), it performs the following: * Configure the Flash prefetch. @@ -147,9 +147,9 @@ __IO uint32_t uwTick; * which is clocked by the HSI (at this stage, the clock is not yet * configured and thus the system is running from the internal HSI at 16 MHz). * Set NVIC Group Priority to 4. - * Calls the HAL_MspInit() callback function defined in user file - * "stm32f1xx_hal_msp.c" to do the global low level hardware initialization - * + * Calls the HAL_MspInit() callback function defined in user file + * "stm32f1xx_hal_msp.c" to do the global low level hardware initialization + * * @note SysTick is used as time base for the HAL_Delay() function, the application * need to ensure that the SysTick time base is always set to 1 millisecond * to have correct HAL operation. @@ -172,7 +172,7 @@ HAL_StatusTypeDef HAL_Init(void) /* Set Interrupt Group Priority */ HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); - /* Use systick as time base source and configure 1ms tick (default clock after Reset is MSI) */ + /* Use systick as time base source and configure 1ms tick (default clock after Reset is HSI) */ HAL_InitTick(TICK_INT_PRIORITY); /* Init the low level hardware */ @@ -183,7 +183,7 @@ HAL_StatusTypeDef HAL_Init(void) } /** - * @brief This function de-Initializes common part of the HAL and stops the source + * @brief This function de-Initializes common part of the HAL and stops the systick. * of time base. * @note This function is optional. * @retval HAL status @@ -201,21 +201,21 @@ HAL_StatusTypeDef HAL_DeInit(void) __HAL_RCC_AHB_FORCE_RESET(); __HAL_RCC_AHB_RELEASE_RESET(); #endif - + /* De-Init the low level hardware */ HAL_MspDeInit(); - + /* Return function status */ return HAL_OK; } /** - * @brief Initializes the MSP. + * @brief Initialize the MSP. * @retval None */ __weak void HAL_MspInit(void) { - /* NOTE : This function Should not be modified, when the callback is needed, + /* NOTE : This function should not be modified, when the callback is needed, the HAL_MspInit could be implemented in the user file */ } @@ -226,34 +226,45 @@ __weak void HAL_MspInit(void) */ __weak void HAL_MspDeInit(void) { - /* NOTE : This function Should not be modified, when the callback is needed, + /* NOTE : This function should not be modified, when the callback is needed, the HAL_MspDeInit could be implemented in the user file */ } /** - * @brief This function configures the source of the time base. - * The time source is configured to have 1ms time base with a dedicated + * @brief This function configures the source of the time base. + * The time source is configured to have 1ms time base with a dedicated * Tick interrupt priority. * @note This function is called automatically at the beginning of program after - * reset by HAL_Init() or at any time when clock is reconfigured by HAL_RCC_ClockConfig(). - * @note In the default implementation, SysTick timer is the source of time base. - * It is used to generate interrupts at regular time intervals. - * Care must be taken if HAL_Delay() is called from a peripheral ISR process, - * The the SysTick interrupt must have higher priority (numerically lower) + * reset by HAL_Init() or at any time when clock is reconfigured by HAL_RCC_ClockConfig(). + * @note In the default implementation, SysTick timer is the source of time base. + * It is used to generate interrupts at regular time intervals. + * Care must be taken if HAL_Delay() is called from a peripheral ISR process, + * The SysTick interrupt must have higher priority (numerically lower) * than the peripheral interrupt. Otherwise the caller ISR process will be blocked. * The function is declared as __weak to be overwritten in case of other * implementation in user file. - * @param TickPriority: Tick interrupt priority. + * @param TickPriority Tick interrupt priority. * @retval HAL status */ __weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) { - /*Configure the SysTick to have interrupt in 1ms time basis*/ - HAL_SYSTICK_Config(SystemCoreClock/1000U); + /* Configure the SysTick to have interrupt in 1ms time basis*/ + if (HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)) > 0U) + { + return HAL_ERROR; + } - /*Configure the SysTick IRQ priority */ - HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority ,0U); + /* Configure the SysTick IRQ priority */ + if (TickPriority < (1UL << __NVIC_PRIO_BITS)) + { + HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U); + uwTickPrio = TickPriority; + } + else + { + return HAL_ERROR; + } /* Return function status */ return HAL_OK; @@ -263,7 +274,7 @@ __weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) * @} */ -/** @defgroup HAL_Exported_Functions_Group2 HAL Control functions +/** @defgroup HAL_Exported_Functions_Group2 HAL Control functions * @brief HAL Control functions * @verbatim @@ -290,19 +301,19 @@ __weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) * @brief This function is called to increment a global variable "uwTick" * used as application time base. * @note In the default implementation, this variable is incremented each 1ms - * in Systick ISR. - * @note This function is declared as __weak to be overwritten in case of other + * in SysTick ISR. + * @note This function is declared as __weak to be overwritten in case of other * implementations in user file. * @retval None */ __weak void HAL_IncTick(void) { - uwTick++; + uwTick += uwTickFreq; } /** * @brief Provides a tick value in millisecond. - * @note This function is declared as __weak to be overwritten in case of other + * @note This function is declared as __weak to be overwritten in case of other * implementations in user file. * @retval tick value */ @@ -312,28 +323,66 @@ __weak uint32_t HAL_GetTick(void) } /** - * @brief This function provides minimum delay (in milliseconds) based + * @brief This function returns a tick priority. + * @retval tick priority + */ +uint32_t HAL_GetTickPrio(void) +{ + return uwTickPrio; +} + +/** + * @brief Set new tick Freq. + * @retval Status + */ +HAL_StatusTypeDef HAL_SetTickFreq(HAL_TickFreqTypeDef Freq) +{ + HAL_StatusTypeDef status = HAL_OK; + assert_param(IS_TICKFREQ(Freq)); + + if (uwTickFreq != Freq) + { + uwTickFreq = Freq; + + /* Apply the new tick Freq */ + status = HAL_InitTick(uwTickPrio); + } + + return status; +} + +/** + * @brief Return tick frequency. + * @retval tick period in Hz + */ +HAL_TickFreqTypeDef HAL_GetTickFreq(void) +{ + return uwTickFreq; +} + +/** + * @brief This function provides minimum delay (in milliseconds) based * on variable incremented. * @note In the default implementation , SysTick timer is the source of time base. * It is used to generate interrupts at regular time intervals where uwTick * is incremented. * @note This function is declared as __weak to be overwritten in case of other * implementations in user file. - * @param Delay: specifies the delay time length, in milliseconds. + * @param Delay specifies the delay time length, in milliseconds. * @retval None */ -__weak void HAL_Delay(__IO uint32_t Delay) +__weak void HAL_Delay(uint32_t Delay) { uint32_t tickstart = HAL_GetTick(); uint32_t wait = Delay; - - /* Add a period to guarantee minimum wait */ + + /* Add a freq to guarantee minimum wait */ if (wait < HAL_MAX_DELAY) { - wait++; + wait += (uint32_t)(uwTickFreq); } - - while((HAL_GetTick() - tickstart) < wait) + + while ((HAL_GetTick() - tickstart) < wait) { } } @@ -342,7 +391,7 @@ __weak void HAL_Delay(__IO uint32_t Delay) * @brief Suspend Tick increment. * @note In the default implementation , SysTick timer is the source of time base. It is * used to generate interrupts at regular time intervals. Once HAL_SuspendTick() - * is called, the SysTick interrupt will be disabled and so Tick increment + * is called, the SysTick interrupt will be disabled and so Tick increment * is suspended. * @note This function is declared as __weak to be overwritten in case of other * implementations in user file. @@ -351,14 +400,14 @@ __weak void HAL_Delay(__IO uint32_t Delay) __weak void HAL_SuspendTick(void) { /* Disable SysTick Interrupt */ - CLEAR_BIT(SysTick->CTRL,SysTick_CTRL_TICKINT_Msk); + CLEAR_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk); } /** * @brief Resume Tick increment. * @note In the default implementation , SysTick timer is the source of time base. It is * used to generate interrupts at regular time intervals. Once HAL_ResumeTick() - * is called, the SysTick interrupt will be enabled and so Tick increment + * is called, the SysTick interrupt will be enabled and so Tick increment * is resumed. * @note This function is declared as __weak to be overwritten in case of other * implementations in user file. @@ -367,16 +416,16 @@ __weak void HAL_SuspendTick(void) __weak void HAL_ResumeTick(void) { /* Enable SysTick Interrupt */ - SET_BIT(SysTick->CTRL,SysTick_CTRL_TICKINT_Msk); + SET_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk); } /** * @brief Returns the HAL revision - * @retval version : 0xXYZR (8bits for each decimal, R for RC) + * @retval version 0xXYZR (8bits for each decimal, R for RC) */ uint32_t HAL_GetHalVersion(void) { - return __STM32F1xx_HAL_VERSION; + return __STM32F1xx_HAL_VERSION; } /** @@ -385,14 +434,14 @@ uint32_t HAL_GetHalVersion(void) * STM32F101xC/D/E and STM32F103xC/D/E, * STM32F101xF/G and STM32F103xF/G * STM32F10xx4 and STM32F10xx6 - * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in + * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in * debug mode (not accessible by the user software in normal mode). * Refer to errata sheet of these devices for more details. * @retval Device revision identifier */ uint32_t HAL_GetREVID(void) { - return((DBGMCU->IDCODE) >> DBGMCU_IDCODE_REV_ID_Pos); + return ((DBGMCU->IDCODE) >> DBGMCU_IDCODE_REV_ID_Pos); } /** @@ -401,14 +450,14 @@ uint32_t HAL_GetREVID(void) * STM32F101xC/D/E and STM32F103xC/D/E, * STM32F101xF/G and STM32F103xF/G * STM32F10xx4 and STM32F10xx6 - * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in + * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in * debug mode (not accessible by the user software in normal mode). * Refer to errata sheet of these devices for more details. * @retval Device identifier */ uint32_t HAL_GetDEVID(void) { - return((DBGMCU->IDCODE) & IDCODE_DEVID_MASK); + return ((DBGMCU->IDCODE) & IDCODE_DEVID_MASK); } /** @@ -426,7 +475,7 @@ void HAL_DBGMCU_EnableDBGSleepMode(void) * STM32F101xC/D/E and STM32F103xC/D/E, * STM32F101xF/G and STM32F103xF/G * STM32F10xx4 and STM32F10xx6 - * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in + * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in * debug mode (not accessible by the user software in normal mode). * Refer to errata sheet of these devices for more details. * @retval None @@ -442,18 +491,18 @@ void HAL_DBGMCU_DisableDBGSleepMode(void) * STM32F101xC/D/E and STM32F103xC/D/E, * STM32F101xF/G and STM32F103xF/G * STM32F10xx4 and STM32F10xx6 - * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in + * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in * debug mode (not accessible by the user software in normal mode). * Refer to errata sheet of these devices for more details. * Note: On all STM32F1 devices: - * If the system tick timer interrupt is enabled during the Stop mode + * If the system tick timer interrupt is enabled during the Stop mode * debug (DBG_STOP bit set in the DBGMCU_CR register ), it will wakeup * the system from Stop mode. - * Workaround: To debug the Stop mode, disable the system tick timer + * Workaround: To debug the Stop mode, disable the system tick timer * interrupt. * Refer to errata sheet of these devices for more details. * Note: On all STM32F1 devices: - * If the system tick timer interrupt is enabled during the Stop mode + * If the system tick timer interrupt is enabled during the Stop mode * debug (DBG_STOP bit set in the DBGMCU_CR register ), it will wakeup * the system from Stop mode. * Workaround: To debug the Stop mode, disable the system tick timer @@ -472,7 +521,7 @@ void HAL_DBGMCU_EnableDBGStopMode(void) * STM32F101xC/D/E and STM32F103xC/D/E, * STM32F101xF/G and STM32F103xF/G * STM32F10xx4 and STM32F10xx6 - * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in + * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in * debug mode (not accessible by the user software in normal mode). * Refer to errata sheet of these devices for more details. * @retval None @@ -488,7 +537,7 @@ void HAL_DBGMCU_DisableDBGStopMode(void) * STM32F101xC/D/E and STM32F103xC/D/E, * STM32F101xF/G and STM32F103xF/G * STM32F10xx4 and STM32F10xx6 - * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in + * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in * debug mode (not accessible by the user software in normal mode). * Refer to errata sheet of these devices for more details. * @retval None @@ -504,7 +553,7 @@ void HAL_DBGMCU_EnableDBGStandbyMode(void) * STM32F101xC/D/E and STM32F103xC/D/E, * STM32F101xF/G and STM32F103xF/G * STM32F10xx4 and STM32F10xx6 - * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in + * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in * debug mode (not accessible by the user software in normal mode). * Refer to errata sheet of these devices for more details. * @retval None @@ -516,7 +565,7 @@ void HAL_DBGMCU_DisableDBGStandbyMode(void) /** * @brief Return the unique device identifier (UID based on 96 bits) - * @param UID: pointer to 3 words array. + * @param UID pointer to 3 words array. * @retval Device identifier */ void HAL_GetUID(uint32_t *UID) diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal.h index d48fb278a033..224c6462430e 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal.h @@ -2,9 +2,7 @@ ****************************************************************************** * @file stm32f1xx_hal.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 - * @brief This file contains all the functions prototypes for the HAL + * @brief This file contains all the functions prototypes for the HAL * module driver. ****************************************************************************** * @attention @@ -34,14 +32,14 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** - */ + */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM32F1xx_HAL_H #define __STM32F1xx_HAL_H #ifdef __cplusplus - extern "C" { +extern "C" { #endif /* Includes ------------------------------------------------------------------*/ @@ -53,44 +51,65 @@ /** @addtogroup HAL * @{ - */ + */ /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/ +/** @defgroup HAL_Exported_Constants HAL Exported Constants + * @{ + */ + +/** @defgroup HAL_TICK_FREQ Tick Frequency + * @{ + */ +typedef enum +{ + HAL_TICK_FREQ_10HZ = 100U, + HAL_TICK_FREQ_100HZ = 10U, + HAL_TICK_FREQ_1KHZ = 1U, + HAL_TICK_FREQ_DEFAULT = HAL_TICK_FREQ_1KHZ +} HAL_TickFreqTypeDef; +/** + * @} + */ + +/** + * @} + */ /* Exported macro ------------------------------------------------------------*/ /** @defgroup HAL_Exported_Macros HAL Exported Macros * @{ */ /** @defgroup DBGMCU_Freeze_Unfreeze Freeze Unfreeze Peripherals in Debug mode - * @brief Freeze/Unfreeze Peripherals in Debug mode + * @brief Freeze/Unfreeze Peripherals in Debug mode * Note: On devices STM32F10xx8 and STM32F10xxB, * STM32F101xC/D/E and STM32F103xC/D/E, * STM32F101xF/G and STM32F103xF/G * STM32F10xx4 and STM32F10xx6 - * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in + * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in * debug mode (not accessible by the user software in normal mode). * Refer to errata sheet of these devices for more details. * @{ */ - + /* Peripherals on APB1 */ /** - * @brief TIM2 Peripherals Debug mode + * @brief TIM2 Peripherals Debug mode */ #define __HAL_DBGMCU_FREEZE_TIM2() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM2_STOP) #define __HAL_DBGMCU_UNFREEZE_TIM2() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM2_STOP) /** - * @brief TIM3 Peripherals Debug mode + * @brief TIM3 Peripherals Debug mode */ #define __HAL_DBGMCU_FREEZE_TIM3() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM3_STOP) #define __HAL_DBGMCU_UNFREEZE_TIM3() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM3_STOP) #if defined (DBGMCU_CR_DBG_TIM4_STOP) /** - * @brief TIM4 Peripherals Debug mode + * @brief TIM4 Peripherals Debug mode */ #define __HAL_DBGMCU_FREEZE_TIM4() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM4_STOP) #define __HAL_DBGMCU_UNFREEZE_TIM4() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM4_STOP) @@ -98,7 +117,7 @@ #if defined (DBGMCU_CR_DBG_TIM5_STOP) /** - * @brief TIM5 Peripherals Debug mode + * @brief TIM5 Peripherals Debug mode */ #define __HAL_DBGMCU_FREEZE_TIM5() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM5_STOP) #define __HAL_DBGMCU_UNFREEZE_TIM5() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM5_STOP) @@ -106,7 +125,7 @@ #if defined (DBGMCU_CR_DBG_TIM6_STOP) /** - * @brief TIM6 Peripherals Debug mode + * @brief TIM6 Peripherals Debug mode */ #define __HAL_DBGMCU_FREEZE_TIM6() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM6_STOP) #define __HAL_DBGMCU_UNFREEZE_TIM6() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM6_STOP) @@ -114,7 +133,7 @@ #if defined (DBGMCU_CR_DBG_TIM7_STOP) /** - * @brief TIM7 Peripherals Debug mode + * @brief TIM7 Peripherals Debug mode */ #define __HAL_DBGMCU_FREEZE_TIM7() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM7_STOP) #define __HAL_DBGMCU_UNFREEZE_TIM7() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM7_STOP) @@ -122,7 +141,7 @@ #if defined (DBGMCU_CR_DBG_TIM12_STOP) /** - * @brief TIM12 Peripherals Debug mode + * @brief TIM12 Peripherals Debug mode */ #define __HAL_DBGMCU_FREEZE_TIM12() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM12_STOP) #define __HAL_DBGMCU_UNFREEZE_TIM12() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM12_STOP) @@ -130,7 +149,7 @@ #if defined (DBGMCU_CR_DBG_TIM13_STOP) /** - * @brief TIM13 Peripherals Debug mode + * @brief TIM13 Peripherals Debug mode */ #define __HAL_DBGMCU_FREEZE_TIM13() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM13_STOP) #define __HAL_DBGMCU_UNFREEZE_TIM13() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM13_STOP) @@ -138,33 +157,33 @@ #if defined (DBGMCU_CR_DBG_TIM14_STOP) /** - * @brief TIM14 Peripherals Debug mode + * @brief TIM14 Peripherals Debug mode */ #define __HAL_DBGMCU_FREEZE_TIM14() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM14_STOP) #define __HAL_DBGMCU_UNFREEZE_TIM14() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM14_STOP) #endif /** - * @brief WWDG Peripherals Debug mode + * @brief WWDG Peripherals Debug mode */ #define __HAL_DBGMCU_FREEZE_WWDG() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_WWDG_STOP) #define __HAL_DBGMCU_UNFREEZE_WWDG() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_WWDG_STOP) /** - * @brief IWDG Peripherals Debug mode + * @brief IWDG Peripherals Debug mode */ #define __HAL_DBGMCU_FREEZE_IWDG() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_IWDG_STOP) #define __HAL_DBGMCU_UNFREEZE_IWDG() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_IWDG_STOP) /** - * @brief I2C1 Peripherals Debug mode + * @brief I2C1 Peripherals Debug mode */ #define __HAL_DBGMCU_FREEZE_I2C1_TIMEOUT() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_I2C1_SMBUS_TIMEOUT) #define __HAL_DBGMCU_UNFREEZE_I2C1_TIMEOUT() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_I2C1_SMBUS_TIMEOUT) #if defined (DBGMCU_CR_DBG_I2C2_SMBUS_TIMEOUT) /** - * @brief I2C2 Peripherals Debug mode + * @brief I2C2 Peripherals Debug mode */ #define __HAL_DBGMCU_FREEZE_I2C2_TIMEOUT() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_I2C2_SMBUS_TIMEOUT) #define __HAL_DBGMCU_UNFREEZE_I2C2_TIMEOUT() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_I2C2_SMBUS_TIMEOUT) @@ -172,7 +191,7 @@ #if defined (DBGMCU_CR_DBG_CAN1_STOP) /** - * @brief CAN1 Peripherals Debug mode + * @brief CAN1 Peripherals Debug mode */ #define __HAL_DBGMCU_FREEZE_CAN1() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_CAN1_STOP) #define __HAL_DBGMCU_UNFREEZE_CAN1() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_CAN1_STOP) @@ -180,16 +199,16 @@ #if defined (DBGMCU_CR_DBG_CAN2_STOP) /** - * @brief CAN2 Peripherals Debug mode + * @brief CAN2 Peripherals Debug mode */ #define __HAL_DBGMCU_FREEZE_CAN2() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_CAN2_STOP) #define __HAL_DBGMCU_UNFREEZE_CAN2() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_CAN2_STOP) -#endif - +#endif + /* Peripherals on APB2 */ #if defined (DBGMCU_CR_DBG_TIM1_STOP) /** - * @brief TIM1 Peripherals Debug mode + * @brief TIM1 Peripherals Debug mode */ #define __HAL_DBGMCU_FREEZE_TIM1() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM1_STOP) #define __HAL_DBGMCU_UNFREEZE_TIM1() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM1_STOP) @@ -197,7 +216,7 @@ #if defined (DBGMCU_CR_DBG_TIM8_STOP) /** - * @brief TIM8 Peripherals Debug mode + * @brief TIM8 Peripherals Debug mode */ #define __HAL_DBGMCU_FREEZE_TIM8() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM8_STOP) #define __HAL_DBGMCU_UNFREEZE_TIM8() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM8_STOP) @@ -205,7 +224,7 @@ #if defined (DBGMCU_CR_DBG_TIM9_STOP) /** - * @brief TIM9 Peripherals Debug mode + * @brief TIM9 Peripherals Debug mode */ #define __HAL_DBGMCU_FREEZE_TIM9() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM9_STOP) #define __HAL_DBGMCU_UNFREEZE_TIM9() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM9_STOP) @@ -213,7 +232,7 @@ #if defined (DBGMCU_CR_DBG_TIM10_STOP) /** - * @brief TIM10 Peripherals Debug mode + * @brief TIM10 Peripherals Debug mode */ #define __HAL_DBGMCU_FREEZE_TIM10() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM10_STOP) #define __HAL_DBGMCU_UNFREEZE_TIM10() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM10_STOP) @@ -221,7 +240,7 @@ #if defined (DBGMCU_CR_DBG_TIM11_STOP) /** - * @brief TIM11 Peripherals Debug mode + * @brief TIM11 Peripherals Debug mode */ #define __HAL_DBGMCU_FREEZE_TIM11() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM11_STOP) #define __HAL_DBGMCU_UNFREEZE_TIM11() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM11_STOP) @@ -230,7 +249,7 @@ #if defined (DBGMCU_CR_DBG_TIM15_STOP) /** - * @brief TIM15 Peripherals Debug mode + * @brief TIM15 Peripherals Debug mode */ #define __HAL_DBGMCU_FREEZE_TIM15() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM15_STOP) #define __HAL_DBGMCU_UNFREEZE_TIM15() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM15_STOP) @@ -238,7 +257,7 @@ #if defined (DBGMCU_CR_DBG_TIM16_STOP) /** - * @brief TIM16 Peripherals Debug mode + * @brief TIM16 Peripherals Debug mode */ #define __HAL_DBGMCU_FREEZE_TIM16() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM16_STOP) #define __HAL_DBGMCU_UNFREEZE_TIM16() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM16_STOP) @@ -246,7 +265,7 @@ #if defined (DBGMCU_CR_DBG_TIM17_STOP) /** - * @brief TIM17 Peripherals Debug mode + * @brief TIM17 Peripherals Debug mode */ #define __HAL_DBGMCU_FREEZE_TIM17() SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM17_STOP) #define __HAL_DBGMCU_UNFREEZE_TIM17() CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_TIM17_STOP) @@ -256,6 +275,12 @@ * @} */ +/** @defgroup HAL_Private_Macros HAL Private Macros + * @{ + */ +#define IS_TICKFREQ(FREQ) (((FREQ) == HAL_TICK_FREQ_10HZ) || \ + ((FREQ) == HAL_TICK_FREQ_100HZ) || \ + ((FREQ) == HAL_TICK_FREQ_1KHZ)) /** * @} */ @@ -272,7 +297,7 @@ HAL_StatusTypeDef HAL_Init(void); HAL_StatusTypeDef HAL_DeInit(void); void HAL_MspInit(void); void HAL_MspDeInit(void); -HAL_StatusTypeDef HAL_InitTick (uint32_t TickPriority); +HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority); /** * @} */ @@ -282,8 +307,11 @@ HAL_StatusTypeDef HAL_InitTick (uint32_t TickPriority); */ /* Peripheral Control functions ************************************************/ void HAL_IncTick(void); -void HAL_Delay(__IO uint32_t Delay); +void HAL_Delay(uint32_t Delay); uint32_t HAL_GetTick(void); +uint32_t HAL_GetTickPrio(void); +HAL_StatusTypeDef HAL_SetTickFreq(HAL_TickFreqTypeDef Freq); +HAL_TickFreqTypeDef HAL_GetTickFreq(void); void HAL_SuspendTick(void); void HAL_ResumeTick(void); uint32_t HAL_GetHalVersion(void); @@ -326,8 +354,8 @@ void HAL_GetUID(uint32_t *UID); /** * @} - */ - + */ + #ifdef __cplusplus } #endif diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_adc.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_adc.c index ddc0776f94bf..6e4c54dd8ff0 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_adc.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_adc.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_adc.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief This file provides firmware functions to manage the following * functionalities of the Analog to Digital Convertor (ADC) * peripheral: diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_adc.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_adc.h index 4d2ed4135875..d4f0d9a95c25 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_adc.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_adc.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_adc.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file containing functions prototypes of ADC HAL library. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_adc_ex.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_adc_ex.c index df0cacf3fa84..7ab6aa80fed0 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_adc_ex.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_adc_ex.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_adc_ex.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief This file provides firmware functions to manage the following * functionalities of the Analog to Digital Convertor (ADC) * peripheral: diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_adc_ex.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_adc_ex.h index eba417077a0f..a9de51ccb354 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_adc_ex.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_adc_ex.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_adc_ex.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of ADC HAL extension module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_can.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_can.c index 9eccce65384c..518fb11767b2 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_can.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_can.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_can.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief CAN HAL module driver. * This file provides firmware functions to manage the following * functionalities of the Controller Area Network (CAN) peripheral: diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_can.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_can.h index 9be1de209ada..df28b55a11bd 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_can.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_can.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_can.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of CAN HAL module. ****************************************************************************** * @attention @@ -557,7 +555,7 @@ typedef struct * @param __HANDLE__: specifies the CAN Handle. * @param __FLAG__: specifies the flag to check. * This parameter can be one of the following values: - * @arg CAN_FLAG_RQCP0: Request MailBox0 Flag + * @arg CAN_FLAG_RQCP0: Request MailBox0 Flag // MBED patch * @arg CAN_FLAG_RQCP1: Request MailBox1 Flag * @arg CAN_FLAG_RQCP2: Request MailBox2 Flag * @arg CAN_FLAG_TXOK0: Transmission OK MailBox0 Flag @@ -591,7 +589,7 @@ typedef struct * @param __HANDLE__: specifies the CAN Handle. * @param __FLAG__: specifies the flag to check. * This parameter can be one of the following values: - * @arg CAN_FLAG_RQCP0: Request MailBox0 Flag + * @arg CAN_FLAG_RQCP0: Request MailBox0 Flag // MBED patch * @arg CAN_FLAG_RQCP1: Request MailBox1 Flag * @arg CAN_FLAG_RQCP2: Request MailBox2 Flag * @arg CAN_FLAG_TXOK0: Transmission OK MailBox0 Flag diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_can_ex.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_can_ex.h index 69995b52d0d7..2d66feb9f6d8 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_can_ex.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_can_ex.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_can_ex.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of CAN HAL Extension module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_cec.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_cec.c index 96c61ac39ad0..9d7fa5f1bc43 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_cec.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_cec.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_cec.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief CEC HAL module driver. * This file provides firmware functions to manage the following * functionalities of the High Definition Multimedia Interface diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_cec.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_cec.h index eb1fd35d359d..7551529e7958 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_cec.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_cec.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_cec.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of CEC HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_conf.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_conf.h index 58474b9f87dc..55aad36197a4 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_conf.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_conf.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_conf.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief HAL configuration template file. * This file should be copied to the application folder and renamed * to stm32f1xx_hal_conf.h. @@ -35,14 +33,14 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** - */ + */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM32F1xx_HAL_CONF_H #define __STM32F1xx_HAL_CONF_H #ifdef __cplusplus - extern "C" { +extern "C" { #endif /* Exported types ------------------------------------------------------------*/ @@ -50,7 +48,7 @@ /* ########################## Module Selection ############################## */ /** - * @brief This is the list of modules to be used in the HAL driver + * @brief This is the list of modules to be used in the HAL driver */ #define HAL_MODULE_ENABLED #define HAL_ADC_MODULE_ENABLED @@ -89,34 +87,34 @@ /** * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. * 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). + * (when HSE is used as system clock source, directly or through the PLL). */ -#if !defined (HSE_VALUE) +#if !defined (HSE_VALUE) #if defined(USE_STM3210C_EVAL) - #define HSE_VALUE 25000000U /*!< Value of the External oscillator in Hz */ +#define HSE_VALUE 25000000U /*!< Value of the External oscillator in Hz */ #else - #define HSE_VALUE 8000000U /*!< Value of the External oscillator in Hz */ +#define HSE_VALUE 8000000U /*!< Value of the External oscillator in Hz */ #endif #endif /* HSE_VALUE */ #if !defined (HSE_STARTUP_TIMEOUT) - #define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */ +#define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */ #endif /* HSE_STARTUP_TIMEOUT */ /** * @brief Internal High Speed oscillator (HSI) value. * This value is used by the RCC HAL module to compute the system frequency - * (when HSI is used as system clock source, directly or through the PLL). + * (when HSI is used as system clock source, directly or through the PLL). */ #if !defined (HSI_VALUE) - #define HSI_VALUE 8000000U /*!< Value of the Internal oscillator in Hz */ +#define HSI_VALUE 8000000U /*!< Value of the Internal oscillator in Hz */ #endif /* HSI_VALUE */ /** * @brief Internal Low Speed oscillator (LSI) value. */ -#if !defined (LSI_VALUE) - #define LSI_VALUE 40000U /*!< LSI Typical Value in Hz */ +#if !defined (LSI_VALUE) +#define LSI_VALUE 32000U /*!< LSI Typical Value in Hz */ #endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz The real value may vary depending on the variations in voltage and temperature. */ @@ -125,11 +123,11 @@ * This value is used by the UART, RTC HAL module to compute the system frequency */ #if !defined (LSE_VALUE) - #define LSE_VALUE 32768U /*!< Value of the External Low Speed oscillator in Hz */ +#define LSE_VALUE 32768U /*!< Value of the External Low Speed oscillator in Hz */ #endif /* LSE_VALUE */ #if !defined (LSE_STARTUP_TIMEOUT) - #define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */ +#define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */ #endif /* LSE_STARTUP_TIMEOUT */ /* Tip: To avoid modifying this file each time you need to use different HSE, @@ -138,7 +136,7 @@ /* ########################### System Configuration ######################### */ /** * @brief This is the HAL system configuration section - */ + */ #define VDD_VALUE 3300U /*!< Value of VDD in mv */ #define TICK_INT_PRIORITY 0x0FU /*!< tick interrupt priority */ #define USE_RTOS 0U @@ -146,7 +144,7 @@ /* ########################## Assert Selection ############################## */ /** - * @brief Uncomment the line below to expanse the "assert_param" macro in the + * @brief Uncomment the line below to expanse the "assert_param" macro in the * HAL drivers code */ /* #define USE_FULL_ASSERT 1U */ @@ -163,7 +161,7 @@ #define MAC_ADDR4 0U #define MAC_ADDR5 0U -/* Definition of the Ethernet driver buffers size and count */ +/* Definition of the Ethernet driver buffers size and count */ #define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ #define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ #define ETH_RXBUFNB 8U /* 8 Rx buffers of size ETH_RX_BUF_SIZE */ @@ -171,9 +169,9 @@ /* Section 2: PHY configuration section */ -/* DP83848 PHY Address*/ +/* DP83848 PHY Address*/ #define DP83848_PHY_ADDRESS 0x01U -/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ +/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ #define PHY_RESET_DELAY 0x000000FFU /* PHY Configuration delay */ #define PHY_CONFIG_DELAY 0x00000FFFU @@ -185,7 +183,7 @@ #define PHY_BCR ((uint16_t)0x0000) /*!< Transceiver Basic Control Register */ #define PHY_BSR ((uint16_t)0x0001) /*!< Transceiver Basic Status Register */ - + #define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */ #define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */ #define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */ @@ -200,13 +198,13 @@ #define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */ #define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */ #define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */ - + /* Section 4: Extended PHY Registers */ #define PHY_SR ((uint16_t)0x0010) /*!< PHY status register Offset */ #define PHY_MICR ((uint16_t)0x0011) /*!< MII Interrupt Control Register */ #define PHY_MISR ((uint16_t)0x0012) /*!< MII Interrupt Status and Misc. Control Register */ - + #define PHY_LINK_STATUS ((uint16_t)0x0001) /*!< PHY Link mask */ #define PHY_SPEED_STATUS ((uint16_t)0x0002) /*!< PHY Speed mask */ #define PHY_DUPLEX_STATUS ((uint16_t)0x0004) /*!< PHY Duplex mask */ @@ -228,139 +226,150 @@ /* Includes ------------------------------------------------------------------*/ /** - * @brief Include module's header file + * @brief Include module's header file */ #ifdef HAL_RCC_MODULE_ENABLED - #include "stm32f1xx_hal_rcc.h" +#include "stm32f1xx_hal_rcc.h" #endif /* HAL_RCC_MODULE_ENABLED */ #ifdef HAL_GPIO_MODULE_ENABLED - #include "stm32f1xx_hal_gpio.h" +#include "stm32f1xx_hal_gpio.h" #endif /* HAL_GPIO_MODULE_ENABLED */ - + #ifdef HAL_DMA_MODULE_ENABLED - #include "stm32f1xx_hal_dma.h" +#include "stm32f1xx_hal_dma.h" #endif /* HAL_DMA_MODULE_ENABLED */ - + #ifdef HAL_ETH_MODULE_ENABLED - #include "stm32f1xx_hal_eth.h" -#endif /* HAL_ETH_MODULE_ENABLED */ - +#include "stm32f1xx_hal_eth.h" +#endif /* HAL_ETH_MODULE_ENABLED */ + #ifdef HAL_CAN_MODULE_ENABLED - #include "stm32f1xx_hal_can.h" +#include "stm32f1xx_hal_can.h" #endif /* HAL_CAN_MODULE_ENABLED */ #ifdef HAL_CEC_MODULE_ENABLED - #include "stm32f1xx_hal_cec.h" +#include "stm32f1xx_hal_cec.h" #endif /* HAL_CEC_MODULE_ENABLED */ #ifdef HAL_CORTEX_MODULE_ENABLED - #include "stm32f1xx_hal_cortex.h" +#include "stm32f1xx_hal_cortex.h" #endif /* HAL_CORTEX_MODULE_ENABLED */ #ifdef HAL_ADC_MODULE_ENABLED - #include "stm32f1xx_hal_adc.h" +#include "stm32f1xx_hal_adc.h" #endif /* HAL_ADC_MODULE_ENABLED */ #ifdef HAL_CRC_MODULE_ENABLED - #include "stm32f1xx_hal_crc.h" +#include "stm32f1xx_hal_crc.h" #endif /* HAL_CRC_MODULE_ENABLED */ #ifdef HAL_DAC_MODULE_ENABLED - #include "stm32f1xx_hal_dac.h" +#include "stm32f1xx_hal_dac.h" #endif /* HAL_DAC_MODULE_ENABLED */ #ifdef HAL_FLASH_MODULE_ENABLED - #include "stm32f1xx_hal_flash.h" +#include "stm32f1xx_hal_flash.h" #endif /* HAL_FLASH_MODULE_ENABLED */ #ifdef HAL_SRAM_MODULE_ENABLED - #include "stm32f1xx_hal_sram.h" +#include "stm32f1xx_hal_sram.h" #endif /* HAL_SRAM_MODULE_ENABLED */ #ifdef HAL_NOR_MODULE_ENABLED - #include "stm32f1xx_hal_nor.h" +#include "stm32f1xx_hal_nor.h" #endif /* HAL_NOR_MODULE_ENABLED */ #ifdef HAL_I2C_MODULE_ENABLED - #include "stm32f1xx_hal_i2c.h" +#include "stm32f1xx_hal_i2c.h" #endif /* HAL_I2C_MODULE_ENABLED */ #ifdef HAL_I2S_MODULE_ENABLED - #include "stm32f1xx_hal_i2s.h" +#include "stm32f1xx_hal_i2s.h" #endif /* HAL_I2S_MODULE_ENABLED */ #ifdef HAL_IWDG_MODULE_ENABLED - #include "stm32f1xx_hal_iwdg.h" +#include "stm32f1xx_hal_iwdg.h" #endif /* HAL_IWDG_MODULE_ENABLED */ #ifdef HAL_PWR_MODULE_ENABLED - #include "stm32f1xx_hal_pwr.h" +#include "stm32f1xx_hal_pwr.h" #endif /* HAL_PWR_MODULE_ENABLED */ #ifdef HAL_RTC_MODULE_ENABLED - #include "stm32f1xx_hal_rtc.h" +#include "stm32f1xx_hal_rtc.h" #endif /* HAL_RTC_MODULE_ENABLED */ #ifdef HAL_PCCARD_MODULE_ENABLED - #include "stm32f1xx_hal_pccard.h" -#endif /* HAL_PCCARD_MODULE_ENABLED */ +#include "stm32f1xx_hal_pccard.h" +#endif /* HAL_PCCARD_MODULE_ENABLED */ #ifdef HAL_SD_MODULE_ENABLED - #include "stm32f1xx_hal_sd.h" -#endif /* HAL_SD_MODULE_ENABLED */ +#include "stm32f1xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ #ifdef HAL_NAND_MODULE_ENABLED - #include "stm32f1xx_hal_nand.h" -#endif /* HAL_NAND_MODULE_ENABLED */ +#include "stm32f1xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ #ifdef HAL_SPI_MODULE_ENABLED - #include "stm32f1xx_hal_spi.h" +#include "stm32f1xx_hal_spi.h" #endif /* HAL_SPI_MODULE_ENABLED */ #ifdef HAL_TIM_MODULE_ENABLED - #include "stm32f1xx_hal_tim.h" +#include "stm32f1xx_hal_tim.h" #endif /* HAL_TIM_MODULE_ENABLED */ #ifdef HAL_UART_MODULE_ENABLED - #include "stm32f1xx_hal_uart.h" +#include "stm32f1xx_hal_uart.h" #endif /* HAL_UART_MODULE_ENABLED */ #ifdef HAL_USART_MODULE_ENABLED - #include "stm32f1xx_hal_usart.h" +#include "stm32f1xx_hal_usart.h" #endif /* HAL_USART_MODULE_ENABLED */ #ifdef HAL_IRDA_MODULE_ENABLED - #include "stm32f1xx_hal_irda.h" +#include "stm32f1xx_hal_irda.h" #endif /* HAL_IRDA_MODULE_ENABLED */ #ifdef HAL_SMARTCARD_MODULE_ENABLED - #include "stm32f1xx_hal_smartcard.h" +#include "stm32f1xx_hal_smartcard.h" #endif /* HAL_SMARTCARD_MODULE_ENABLED */ #ifdef HAL_WWDG_MODULE_ENABLED - #include "stm32f1xx_hal_wwdg.h" +#include "stm32f1xx_hal_wwdg.h" #endif /* HAL_WWDG_MODULE_ENABLED */ #ifdef HAL_PCD_MODULE_ENABLED - #include "stm32f1xx_hal_pcd.h" +#include "stm32f1xx_hal_pcd.h" #endif /* HAL_PCD_MODULE_ENABLED */ #ifdef HAL_HCD_MODULE_ENABLED - #include "stm32f1xx_hal_hcd.h" +#include "stm32f1xx_hal_hcd.h" #endif /* HAL_HCD_MODULE_ENABLED */ #ifdef HAL_MMC_MODULE_ENABLED - #include "stm32f1xx_hal_mmc.h" +#include "stm32f1xx_hal_mmc.h" #endif /* HAL_MMC_MODULE_ENABLED */ /* Exported macro ------------------------------------------------------------*/ #ifdef USE_FULL_ASSERT -/* ALL MBED targets use same stm32_assert.h */ +// MBED patch: all targets use the same assert file #include "stm32_assert.h" +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ +//#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ +//void assert_failed(uint8_t *file, uint32_t line); #else - #define assert_param(expr) ((void)0U) +#define assert_param(expr) ((void)0U) #endif /* USE_FULL_ASSERT */ diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_cortex.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_cortex.c index eaa8c73cf2a4..189d3f44afd7 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_cortex.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_cortex.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_cortex.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief CORTEX HAL module driver. * This file provides firmware functions to manage the following * functionalities of the CORTEX: diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_cortex.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_cortex.h index f7fedadf0b57..179f452c2c73 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_cortex.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_cortex.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_cortex.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of CORTEX HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_crc.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_crc.c index ab491e39b2e6..60dd16a53ad9 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_crc.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_crc.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_crc.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief CRC HAL module driver. * This file provides firmware functions to manage the following * functionalities of the Cyclic Redundancy Check (CRC) peripheral: diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_crc.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_crc.h index 155f387eeae5..4d0f1366ab7f 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_crc.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_crc.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_crc.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of CRC HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_dac.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_dac.c index 1c84042343d1..6f53a379bc49 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_dac.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_dac.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_dac.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief DAC HAL module driver. * This file provides firmware functions to manage the following * functionalities of the Digital to Analog Converter (DAC) peripheral: diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_dac.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_dac.h index 9487a1ef7e6f..63996c9f1b97 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_dac.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_dac.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_dac.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of DAC HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_dac_ex.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_dac_ex.c index 188cefb7d788..08dda245ad52 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_dac_ex.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_dac_ex.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_dac_ex.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief DAC HAL module driver. * This file provides firmware functions to manage the following * functionalities of DAC extension peripheral: diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_dac_ex.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_dac_ex.h index 1fc977ee4d1d..0d81441c2bc8 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_dac_ex.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_dac_ex.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_dac_ex.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of DAC HAL Extension module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_def.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_def.h index be4adf42f4f2..4b76438d7cc5 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_def.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_def.h @@ -2,10 +2,8 @@ ****************************************************************************** * @file stm32f1xx_hal_def.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 - * @brief This file contains HAL common defines, enumeration, macros and - * structures definitions. + * @brief This file contains HAL common defines, enumeration, macros and + * structures definitions. ****************************************************************************** * @attention * @@ -41,22 +39,22 @@ #define __STM32F1xx_HAL_DEF #ifdef __cplusplus - extern "C" { +extern "C" { #endif /* Includes ------------------------------------------------------------------*/ #include "stm32f1xx.h" #if defined(USE_HAL_LEGACY) -#include "stm32_hal_legacy.h" +#include "stm32_hal_legacy.h" // MBED patch #endif #include /* Exported types ------------------------------------------------------------*/ -/** - * @brief HAL Status structures definition - */ -typedef enum +/** + * @brief HAL Status structures definition + */ +typedef enum { HAL_OK = 0x00U, HAL_ERROR = 0x01U, @@ -64,13 +62,13 @@ typedef enum HAL_TIMEOUT = 0x03U } HAL_StatusTypeDef; -/** - * @brief HAL Lock structures definition +/** + * @brief HAL Lock structures definition */ -typedef enum +typedef enum { HAL_UNLOCKED = 0x00U, - HAL_LOCKED = 0x01U + HAL_LOCKED = 0x01U } HAL_LockTypeDef; /* Exported macro ------------------------------------------------------------*/ @@ -85,15 +83,15 @@ typedef enum (__DMA_HANDLE__).Parent = (__HANDLE__); \ } while(0U) -#define UNUSED(x) ((void)(x)) +#define UNUSED(X) (void)X /* To avoid gcc/g++ warnings */ /** @brief Reset the Handle's State field. * @param __HANDLE__: specifies the Peripheral Handle. - * @note This macro can be used for the following purpose: + * @note This macro can be used for the following purpose: * - When the Handle is declared as local variable; before passing it as parameter - * to HAL_PPP_Init() for the first time, it is mandatory to use this macro + * to HAL_PPP_Init() for the first time, it is mandatory to use this macro * to set to 0 the Handle's "State" field. - * Otherwise, "State" field may have any random value and the first time the function + * Otherwise, "State" field may have any random value and the first time the function * HAL_PPP_Init() is called, the low level hardware initialization will be missed * (i.e. HAL_PPP_MspInit() will not be executed). * - When there is a need to reconfigure the low level hardware: instead of calling @@ -105,10 +103,10 @@ typedef enum #define __HAL_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = 0U) #if (USE_RTOS == 1U) - /* Reserved for future use */ - #error "USE_RTOS should be 0 in the current HAL release" +/* Reserved for future use */ +#error "USE_RTOS should be 0 in the current HAL release" #else - #define __HAL_LOCK(__HANDLE__) \ +#define __HAL_LOCK(__HANDLE__) \ do{ \ if((__HANDLE__)->Lock == HAL_LOCKED) \ { \ @@ -120,82 +118,82 @@ typedef enum } \ }while (0U) - #define __HAL_UNLOCK(__HANDLE__) \ +#define __HAL_UNLOCK(__HANDLE__) \ do{ \ (__HANDLE__)->Lock = HAL_UNLOCKED; \ }while (0U) #endif /* USE_RTOS */ -#if defined ( __GNUC__ ) && !defined ( __CC_ARM ) - #ifndef __weak - #define __weak __attribute__((weak)) - #endif /* __weak */ - #ifndef __packed - #define __packed __attribute__((__packed__)) - #endif /* __packed */ +#if defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */ +#ifndef __weak +#define __weak __attribute__((weak)) +#endif /* __weak */ +#ifndef __packed +#define __packed __attribute__((__packed__)) +#endif /* __packed */ #endif /* __GNUC__ */ /* Macro to get variable aligned on 4-bytes, for __ICCARM__ the directive "#pragma data_alignment=4" must be used instead */ -#if defined (__GNUC__) /* GNU Compiler */ - #ifndef __ALIGN_END - #define __ALIGN_END __attribute__ ((aligned (4))) - #endif /* __ALIGN_END */ - #ifndef __ALIGN_BEGIN - #define __ALIGN_BEGIN - #endif /* __ALIGN_BEGIN */ +#if defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */ +#ifndef __ALIGN_END +#define __ALIGN_END __attribute__ ((aligned (4))) +#endif /* __ALIGN_END */ +#ifndef __ALIGN_BEGIN +#define __ALIGN_BEGIN +#endif /* __ALIGN_BEGIN */ #else - #ifndef __ALIGN_END - #define __ALIGN_END - #endif /* __ALIGN_END */ - #ifndef __ALIGN_BEGIN - #if defined (__CC_ARM) /* ARM Compiler */ - #define __ALIGN_BEGIN __align(4) - #elif defined (__ICCARM__) /* IAR Compiler */ - #define __ALIGN_BEGIN - #endif /* __CC_ARM */ - #endif /* __ALIGN_BEGIN */ +#ifndef __ALIGN_END +#define __ALIGN_END +#endif /* __ALIGN_END */ +#ifndef __ALIGN_BEGIN +#if defined (__CC_ARM) /* ARM Compiler */ +#define __ALIGN_BEGIN __align(4) +#elif defined (__ICCARM__) /* IAR Compiler */ +#define __ALIGN_BEGIN +#endif /* __CC_ARM */ +#endif /* __ALIGN_BEGIN */ #endif /* __GNUC__ */ -/** +/** * @brief __RAM_FUNC definition - */ + */ #if defined ( __CC_ARM ) /* ARM Compiler ------------ - RAM functions are defined using the toolchain options. + RAM functions are defined using the toolchain options. Functions that are executed in RAM should reside in a separate source module. - Using the 'Options for File' dialog you can simply change the 'Code / Const' + Using the 'Options for File' dialog you can simply change the 'Code / Const' area of a module to a memory space in physical RAM. Available memory areas are declared in the 'Target' tab of the 'Options for Target' - dialog. + dialog. */ -#define __RAM_FUNC HAL_StatusTypeDef +#define __RAM_FUNC #elif defined ( __ICCARM__ ) /* ICCARM Compiler --------------- - RAM functions are defined using a specific toolchain keyword "__ramfunc". + RAM functions are defined using a specific toolchain keyword "__ramfunc". */ -#define __RAM_FUNC __ramfunc HAL_StatusTypeDef +#define __RAM_FUNC __ramfunc #elif defined ( __GNUC__ ) /* GNU Compiler ------------ - RAM functions are defined using a specific toolchain attribute + RAM functions are defined using a specific toolchain attribute "__attribute__((section(".RamFunc")))". */ -#define __RAM_FUNC HAL_StatusTypeDef __attribute__((section(".RamFunc"))) +#define __RAM_FUNC __attribute__((section(".RamFunc"))) #endif -/** +/** * @brief __NOINLINE definition - */ + */ #if defined ( __CC_ARM ) || defined ( __GNUC__ ) -/* ARM & GNUCompiler - ---------------- +/* ARM & GNUCompiler + ---------------- */ #define __NOINLINE __attribute__ ( (noinline) ) diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_dma.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_dma.c index 2b271fccf2b2..d7fa7575cb6c 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_dma.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_dma.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_dma.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief DMA HAL module driver. * This file provides firmware functions to manage the following * functionalities of the Direct Memory Access (DMA) peripheral: @@ -869,7 +867,7 @@ static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t /* Configure DMA Channel data length */ hdma->Instance->CNDTR = DataLength; - /* Peripheral to Memory */ + /* Memory to Peripheral */ if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH) { /* Configure DMA Channel destination address */ @@ -878,7 +876,7 @@ static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t /* Configure DMA Channel source address */ hdma->Instance->CMAR = SrcAddress; } - /* Memory to Peripheral */ + /* Peripheral to Memory */ else { /* Configure DMA Channel source address */ diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_dma.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_dma.h index 03521b9b3f8f..41f5549142ba 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_dma.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_dma.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_dma.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of DMA HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_dma_ex.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_dma_ex.h index 6f03958bd635..b9a9e6cd8bfa 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_dma_ex.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_dma_ex.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_dma_ex.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of DMA HAL extension module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_eth.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_eth.c index 429d8c271d24..77c690581918 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_eth.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_eth.c @@ -2,14 +2,12 @@ ****************************************************************************** * @file stm32f1xx_hal_eth.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief ETH HAL module driver. - * This file provides firmware functions to manage the following + * This file provides firmware functions to manage the following * functionalities of the Ethernet (ETH) peripheral: * + Initialization and de-initialization functions * + IO operation functions - * + Peripheral Control functions + * + Peripheral Control functions * + Peripheral State and Errors functions * @verbatim @@ -19,21 +17,21 @@ [..] (#)Declare a ETH_HandleTypeDef handle structure, for example: ETH_HandleTypeDef heth; - + (#)Fill parameters of Init structure in heth handle - - (#)Call HAL_ETH_Init() API to initialize the Ethernet peripheral (MAC, DMA, ...) + + (#)Call HAL_ETH_Init() API to initialize the Ethernet peripheral (MAC, DMA, ...) (#)Initialize the ETH low level resources through the HAL_ETH_MspInit() API: - (##) Enable the Ethernet interface clock using + (##) Enable the Ethernet interface clock using (+++) __HAL_RCC_ETHMAC_CLK_ENABLE(); (+++) __HAL_RCC_ETHMACTX_CLK_ENABLE(); (+++) __HAL_RCC_ETHMACRX_CLK_ENABLE(); - + (##) Initialize the related GPIO clocks (##) Configure Ethernet pin-out - (##) Configure Ethernet NVIC interrupt (IT mode) - + (##) Configure Ethernet NVIC interrupt (IT mode) + (#)Initialize Ethernet DMA Descriptors in chain mode and point to allocated buffers: (##) HAL_ETH_DMATxDescListInit(); for Transmission process (##) HAL_ETH_DMARxDescListInit(); for Reception process @@ -41,11 +39,11 @@ (#)Enable MAC and DMA transmission and reception: (##) HAL_ETH_Start(); - (#)Prepare ETH DMA TX Descriptors and give the hand to ETH DMA to transfer + (#)Prepare ETH DMA TX Descriptors and give the hand to ETH DMA to transfer the frame to MAC TX FIFO: (##) HAL_ETH_TransmitFrame(); - (#)Poll for a received frame in ETH RX DMA Descriptors and get received + (#)Poll for a received frame in ETH RX DMA Descriptors and get received frame parameters (##) HAL_ETH_GetReceivedFrame(); (should be called into an infinite loop) @@ -53,18 +51,18 @@ (##) HAL_ETH_GetReceivedFrame_IT(); (called in IT mode only) (#) Communicate with external PHY device: - (##) Read a specific register from the PHY + (##) Read a specific register from the PHY HAL_ETH_ReadPHYRegister(); (##) Write data to a specific RHY register: HAL_ETH_WritePHYRegister(); (#) Configure the Ethernet MAC after ETH peripheral initialization HAL_ETH_ConfigMAC(); all MAC parameters should be filled. - + (#) Configure the Ethernet DMA after ETH peripheral initialization HAL_ETH_ConfigDMA(); all DMA parameters should be filled. - - -@- The PTP protocol and the DMA descriptors ring mode are not supported + + -@- The PTP protocol and the DMA descriptors ring mode are not supported in this driver @endverbatim @@ -96,7 +94,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** - */ + */ /* Includes ------------------------------------------------------------------*/ #include "stm32f1xx_hal.h" @@ -153,10 +151,10 @@ static void ETH_Delay(uint32_t mdelay); * @{ */ -/** @defgroup ETH_Exported_Functions_Group1 Initialization and de-initialization functions - * @brief Initialization and Configuration functions +/** @defgroup ETH_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions * - @verbatim + @verbatim =============================================================================== ##### Initialization and de-initialization functions ##### =============================================================================== @@ -181,213 +179,215 @@ HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth) uint32_t hclk = 60000000U; uint32_t tickstart = 0U; uint32_t err = ETH_SUCCESS; - + /* Check the ETH peripheral state */ - if(heth == NULL) + if (heth == NULL) { return HAL_ERROR; } - + /* Check parameters */ assert_param(IS_ETH_AUTONEGOTIATION(heth->Init.AutoNegotiation)); assert_param(IS_ETH_RX_MODE(heth->Init.RxMode)); assert_param(IS_ETH_CHECKSUM_MODE(heth->Init.ChecksumMode)); - assert_param(IS_ETH_MEDIA_INTERFACE(heth->Init.MediaInterface)); - - if(heth->State == HAL_ETH_STATE_RESET) + assert_param(IS_ETH_MEDIA_INTERFACE(heth->Init.MediaInterface)); + + if (heth->State == HAL_ETH_STATE_RESET) { /* Allocate lock resource and initialize it */ heth->Lock = HAL_UNLOCKED; /* Init the low level hardware : GPIO, CLOCK, NVIC. */ HAL_ETH_MspInit(heth); } - + /* Select MII or RMII Mode*/ AFIO->MAPR &= ~(AFIO_MAPR_MII_RMII_SEL); AFIO->MAPR |= (uint32_t)heth->Init.MediaInterface; - + /* Ethernet Software reset */ /* Set the SWR bit: resets all MAC subsystem internal registers and logic */ /* After reset all the registers holds their respective reset values */ (heth->Instance)->DMABMR |= ETH_DMABMR_SR; - + /* Get tick */ tickstart = HAL_GetTick(); - + /* Wait for software reset */ while (((heth->Instance)->DMABMR & ETH_DMABMR_SR) != (uint32_t)RESET) { /* Check for the Timeout */ - if((HAL_GetTick() - tickstart ) > ETH_TIMEOUT_SWRESET) - { - heth->State= HAL_ETH_STATE_TIMEOUT; - + if ((HAL_GetTick() - tickstart) > ETH_TIMEOUT_SWRESET) + { + heth->State = HAL_ETH_STATE_TIMEOUT; + /* Process Unlocked */ __HAL_UNLOCK(heth); - - /* Note: The SWR is not performed if the ETH_RX_CLK or the ETH_TX_CLK are + + /* Note: The SWR is not performed if the ETH_RX_CLK or the ETH_TX_CLK are not available, please check your external PHY or the IO configuration */ return HAL_TIMEOUT; } } - + /*-------------------------------- MAC Initialization ----------------------*/ /* Get the ETHERNET MACMIIAR value */ tmpreg1 = (heth->Instance)->MACMIIAR; /* Clear CSR Clock Range CR[2:0] bits */ tmpreg1 &= ETH_MACMIIAR_CR_MASK; - + /* Get hclk frequency value */ hclk = HAL_RCC_GetHCLKFreq(); - + /* Set CR bits depending on hclk value */ - if((hclk >= 20000000U)&&(hclk < 35000000U)) + if ((hclk >= 20000000U) && (hclk < 35000000U)) { /* CSR Clock Range between 20-35 MHz */ tmpreg1 |= (uint32_t)ETH_MACMIIAR_CR_DIV16; } - else if((hclk >= 35000000U)&&(hclk < 60000000U)) + else if ((hclk >= 35000000U) && (hclk < 60000000U)) { - /* CSR Clock Range between 35-60 MHz */ + /* CSR Clock Range between 35-60 MHz */ tmpreg1 |= (uint32_t)ETH_MACMIIAR_CR_DIV26; - } + } else { - /* CSR Clock Range between 60-72 MHz */ + /* CSR Clock Range between 60-72 MHz */ tmpreg1 |= (uint32_t)ETH_MACMIIAR_CR_DIV42; - } - + } + /* Write to ETHERNET MAC MIIAR: Configure the ETHERNET CSR Clock Range */ (heth->Instance)->MACMIIAR = (uint32_t)tmpreg1; - + /*-------------------- PHY initialization and configuration ----------------*/ /* Put the PHY in reset mode */ - if((HAL_ETH_WritePHYRegister(heth, PHY_BCR, PHY_RESET)) != HAL_OK) + if ((HAL_ETH_WritePHYRegister(heth, PHY_BCR, PHY_RESET)) != HAL_OK) { /* In case of write timeout */ err = ETH_ERROR; - + /* Config MAC and DMA */ ETH_MACDMAConfig(heth, err); - + /* Set the ETH peripheral state to READY */ heth->State = HAL_ETH_STATE_READY; - + /* Return HAL_ERROR */ return HAL_ERROR; } - + /* Delay to assure PHY reset */ HAL_Delay(PHY_RESET_DELAY); - - if((heth->Init).AutoNegotiation != ETH_AUTONEGOTIATION_DISABLE) + + if ((heth->Init).AutoNegotiation != ETH_AUTONEGOTIATION_DISABLE) { /* Get tick */ tickstart = HAL_GetTick(); - + /* We wait for linked status */ do { HAL_ETH_ReadPHYRegister(heth, PHY_BSR, &phyreg); - + /* Check for the Timeout */ - if((HAL_GetTick() - tickstart ) > ETH_TIMEOUT_LINKED_STATE) + if ((HAL_GetTick() - tickstart) > ETH_TIMEOUT_LINKED_STATE) { /* In case of write timeout */ err = ETH_ERROR; - + /* Config MAC and DMA */ ETH_MACDMAConfig(heth, err); - - heth->State= HAL_ETH_STATE_READY; - + + heth->State = HAL_ETH_STATE_READY; + /* Process Unlocked */ __HAL_UNLOCK(heth); - + return HAL_TIMEOUT; } - } while (((phyreg & PHY_LINKED_STATUS) != PHY_LINKED_STATUS)); + } + while (((phyreg & PHY_LINKED_STATUS) != PHY_LINKED_STATUS)); + - /* Enable Auto-Negotiation */ - if((HAL_ETH_WritePHYRegister(heth, PHY_BCR, PHY_AUTONEGOTIATION)) != HAL_OK) + if ((HAL_ETH_WritePHYRegister(heth, PHY_BCR, PHY_AUTONEGOTIATION)) != HAL_OK) { /* In case of write timeout */ err = ETH_ERROR; - + /* Config MAC and DMA */ ETH_MACDMAConfig(heth, err); - + /* Set the ETH peripheral state to READY */ heth->State = HAL_ETH_STATE_READY; - + /* Return HAL_ERROR */ - return HAL_ERROR; + return HAL_ERROR; } - + /* Get tick */ tickstart = HAL_GetTick(); - + /* Wait until the auto-negotiation will be completed */ do { HAL_ETH_ReadPHYRegister(heth, PHY_BSR, &phyreg); - + /* Check for the Timeout */ - if((HAL_GetTick() - tickstart ) > ETH_TIMEOUT_AUTONEGO_COMPLETED) + if ((HAL_GetTick() - tickstart) > ETH_TIMEOUT_AUTONEGO_COMPLETED) { /* In case of write timeout */ err = ETH_ERROR; - + /* Config MAC and DMA */ ETH_MACDMAConfig(heth, err); - - heth->State= HAL_ETH_STATE_READY; - + + heth->State = HAL_ETH_STATE_READY; + /* Process Unlocked */ __HAL_UNLOCK(heth); - + return HAL_TIMEOUT; } - - } while (((phyreg & PHY_AUTONEGO_COMPLETE) != PHY_AUTONEGO_COMPLETE)); - + + } + while (((phyreg & PHY_AUTONEGO_COMPLETE) != PHY_AUTONEGO_COMPLETE)); + /* Read the result of the auto-negotiation */ - if((HAL_ETH_ReadPHYRegister(heth, PHY_SR, &phyreg)) != HAL_OK) + if ((HAL_ETH_ReadPHYRegister(heth, PHY_SR, &phyreg)) != HAL_OK) { /* In case of write timeout */ err = ETH_ERROR; - + /* Config MAC and DMA */ ETH_MACDMAConfig(heth, err); - + /* Set the ETH peripheral state to READY */ heth->State = HAL_ETH_STATE_READY; - + /* Return HAL_ERROR */ - return HAL_ERROR; + return HAL_ERROR; } - + /* Configure the MAC with the Duplex Mode fixed by the auto-negotiation process */ - if((phyreg & PHY_DUPLEX_STATUS) != (uint32_t)RESET) + if ((phyreg & PHY_DUPLEX_STATUS) != (uint32_t)RESET) { /* Set Ethernet duplex mode to Full-duplex following the auto-negotiation */ - (heth->Init).DuplexMode = ETH_MODE_FULLDUPLEX; + (heth->Init).DuplexMode = ETH_MODE_FULLDUPLEX; } else { /* Set Ethernet duplex mode to Half-duplex following the auto-negotiation */ - (heth->Init).DuplexMode = ETH_MODE_HALFDUPLEX; + (heth->Init).DuplexMode = ETH_MODE_HALFDUPLEX; } /* Configure the MAC with the speed fixed by the auto-negotiation process */ - if((phyreg & PHY_SPEED_STATUS) == PHY_SPEED_STATUS) - { + if ((phyreg & PHY_SPEED_STATUS) == PHY_SPEED_STATUS) + { /* Set Ethernet speed to 10M following the auto-negotiation */ - (heth->Init).Speed = ETH_SPEED_10M; + (heth->Init).Speed = ETH_SPEED_10M; } else - { - /* Set Ethernet speed to 100M following the auto-negotiation */ + { + /* Set Ethernet speed to 100M following the auto-negotiation */ (heth->Init).Speed = ETH_SPEED_100M; } } @@ -396,40 +396,40 @@ HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth) /* Check parameters */ assert_param(IS_ETH_SPEED(heth->Init.Speed)); assert_param(IS_ETH_DUPLEX_MODE(heth->Init.DuplexMode)); - + /* Set MAC Speed and Duplex Mode */ - if(HAL_ETH_WritePHYRegister(heth, PHY_BCR, ((uint16_t)((heth->Init).DuplexMode >> 3U) | - (uint16_t)((heth->Init).Speed >> 1U))) != HAL_OK) + if (HAL_ETH_WritePHYRegister(heth, PHY_BCR, ((uint16_t)((heth->Init).DuplexMode >> 3U) | + (uint16_t)((heth->Init).Speed >> 1U))) != HAL_OK) { /* In case of write timeout */ err = ETH_ERROR; - + /* Config MAC and DMA */ ETH_MACDMAConfig(heth, err); - + /* Set the ETH peripheral state to READY */ heth->State = HAL_ETH_STATE_READY; - + /* Return HAL_ERROR */ return HAL_ERROR; - } - + } + /* Delay to assure PHY configuration */ HAL_Delay(PHY_CONFIG_DELAY); } - + /* Config MAC and DMA */ ETH_MACDMAConfig(heth, err); - + /* Set ETH HAL State to Ready */ - heth->State= HAL_ETH_STATE_READY; - + heth->State = HAL_ETH_STATE_READY; + /* Return function status */ return HAL_OK; } /** - * @brief De-Initializes the ETH peripheral. + * @brief De-Initializes the ETH peripheral. * @param heth: pointer to a ETH_HandleTypeDef structure that contains * the configuration information for ETHERNET module * @retval HAL status @@ -438,12 +438,12 @@ HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth) { /* Set the ETH peripheral state to BUSY */ heth->State = HAL_ETH_STATE_BUSY; - + /* De-Init the low level hardware : GPIO, CLOCK, NVIC. */ HAL_ETH_MspDeInit(heth); - + /* Set ETH HAL state to Disabled */ - heth->State= HAL_ETH_STATE_RESET; + heth->State = HAL_ETH_STATE_RESET; /* Release Lock */ __HAL_UNLOCK(heth); @@ -455,8 +455,8 @@ HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth) /** * @brief Initializes the DMA Tx descriptors in chain mode. * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param DMATxDescTab: Pointer to the first Tx desc list + * the configuration information for ETHERNET module + * @param DMATxDescTab: Pointer to the first Tx desc list * @param TxBuff: Pointer to the first TxBuffer list * @param TxBuffCount: Number of the used Tx desc in the list * @retval HAL status @@ -465,56 +465,56 @@ HAL_StatusTypeDef HAL_ETH_DMATxDescListInit(ETH_HandleTypeDef *heth, ETH_DMADesc { uint32_t i = 0U; ETH_DMADescTypeDef *dmatxdesc; - + /* Process Locked */ __HAL_LOCK(heth); - + /* Set the ETH peripheral state to BUSY */ heth->State = HAL_ETH_STATE_BUSY; - + /* Set the DMATxDescToSet pointer with the first one of the DMATxDescTab list */ heth->TxDesc = DMATxDescTab; - - /* Fill each DMATxDesc descriptor with the right values */ - for(i=0U; i < TxBuffCount; i++) + + /* Fill each DMATxDesc descriptor with the right values */ + for (i = 0U; i < TxBuffCount; i++) { /* Get the pointer on the ith member of the Tx Desc list */ dmatxdesc = DMATxDescTab + i; - + /* Set Second Address Chained bit */ - dmatxdesc->Status = ETH_DMATXDESC_TCH; - + dmatxdesc->Status = ETH_DMATXDESC_TCH; + /* Set Buffer1 address pointer */ - dmatxdesc->Buffer1Addr = (uint32_t)(&TxBuff[i*ETH_TX_BUF_SIZE]); - + dmatxdesc->Buffer1Addr = (uint32_t)(&TxBuff[i * ETH_TX_BUF_SIZE]); + if ((heth->Init).ChecksumMode == ETH_CHECKSUM_BY_HARDWARE) { /* Set the DMA Tx descriptors checksum insertion */ dmatxdesc->Status |= ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL; } - + /* Initialize the next descriptor with the Next Descriptor Polling Enable */ - if(i < (TxBuffCount-1U)) + if (i < (TxBuffCount - 1U)) { /* Set next descriptor address register with next descriptor base address */ - dmatxdesc->Buffer2NextDescAddr = (uint32_t)(DMATxDescTab+i+1U); + dmatxdesc->Buffer2NextDescAddr = (uint32_t)(DMATxDescTab + i + 1U); } else { - /* For last descriptor, set next descriptor address register equal to the first descriptor base address */ - dmatxdesc->Buffer2NextDescAddr = (uint32_t) DMATxDescTab; + /* For last descriptor, set next descriptor address register equal to the first descriptor base address */ + dmatxdesc->Buffer2NextDescAddr = (uint32_t) DMATxDescTab; } } - + /* Set Transmit Descriptor List Address Register */ (heth->Instance)->DMATDLAR = (uint32_t) DMATxDescTab; - + /* Set ETH HAL State to Ready */ - heth->State= HAL_ETH_STATE_READY; - + heth->State = HAL_ETH_STATE_READY; + /* Process Unlocked */ __HAL_UNLOCK(heth); - + /* Return function status */ return HAL_OK; } @@ -522,8 +522,8 @@ HAL_StatusTypeDef HAL_ETH_DMATxDescListInit(ETH_HandleTypeDef *heth, ETH_DMADesc /** * @brief Initializes the DMA Rx descriptors in chain mode. * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param DMARxDescTab: Pointer to the first Rx desc list + * the configuration information for ETHERNET module + * @param DMARxDescTab: Pointer to the first Rx desc list * @param RxBuff: Pointer to the first RxBuffer list * @param RxBuffCount: Number of the used Rx desc in the list * @retval HAL status @@ -532,59 +532,59 @@ HAL_StatusTypeDef HAL_ETH_DMARxDescListInit(ETH_HandleTypeDef *heth, ETH_DMADesc { uint32_t i = 0U; ETH_DMADescTypeDef *DMARxDesc; - + /* Process Locked */ __HAL_LOCK(heth); - + /* Set the ETH peripheral state to BUSY */ heth->State = HAL_ETH_STATE_BUSY; - + /* Set the Ethernet RxDesc pointer with the first one of the DMARxDescTab list */ - heth->RxDesc = DMARxDescTab; - + heth->RxDesc = DMARxDescTab; + /* Fill each DMARxDesc descriptor with the right values */ - for(i=0U; i < RxBuffCount; i++) + for (i = 0U; i < RxBuffCount; i++) { /* Get the pointer on the ith member of the Rx Desc list */ - DMARxDesc = DMARxDescTab+i; - + DMARxDesc = DMARxDescTab + i; + /* Set Own bit of the Rx descriptor Status */ DMARxDesc->Status = ETH_DMARXDESC_OWN; - + /* Set Buffer1 size and Second Address Chained bit */ - DMARxDesc->ControlBufferSize = ETH_DMARXDESC_RCH | ETH_RX_BUF_SIZE; - + DMARxDesc->ControlBufferSize = ETH_DMARXDESC_RCH | ETH_RX_BUF_SIZE; + /* Set Buffer1 address pointer */ - DMARxDesc->Buffer1Addr = (uint32_t)(&RxBuff[i*ETH_RX_BUF_SIZE]); - - if((heth->Init).RxMode == ETH_RXINTERRUPT_MODE) + DMARxDesc->Buffer1Addr = (uint32_t)(&RxBuff[i * ETH_RX_BUF_SIZE]); + + if ((heth->Init).RxMode == ETH_RXINTERRUPT_MODE) { /* Enable Ethernet DMA Rx Descriptor interrupt */ DMARxDesc->ControlBufferSize &= ~ETH_DMARXDESC_DIC; } - + /* Initialize the next descriptor with the Next Descriptor Polling Enable */ - if(i < (RxBuffCount-1U)) + if (i < (RxBuffCount - 1U)) { /* Set next descriptor address register with next descriptor base address */ - DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab+i+1U); + DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab + i + 1U); } else { - /* For last descriptor, set next descriptor address register equal to the first descriptor base address */ - DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab); + /* For last descriptor, set next descriptor address register equal to the first descriptor base address */ + DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab); } } - + /* Set Receive Descriptor List Address Register */ (heth->Instance)->DMARDLAR = (uint32_t) DMARxDescTab; - + /* Set ETH HAL State to Ready */ - heth->State= HAL_ETH_STATE_READY; - + heth->State = HAL_ETH_STATE_READY; + /* Process Unlocked */ __HAL_UNLOCK(heth); - + /* Return function status */ return HAL_OK; } @@ -623,13 +623,13 @@ __weak void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth) * @} */ -/** @defgroup ETH_Exported_Functions_Group2 IO operation functions - * @brief Data transfers functions +/** @defgroup ETH_Exported_Functions_Group2 IO operation functions + * @brief Data transfers functions * - @verbatim + @verbatim ============================================================================== ##### IO operation functions ##### - ============================================================================== + ============================================================================== [..] This section provides functions allowing to: (+) Transmit a frame HAL_ETH_TransmitFrame(); @@ -642,12 +642,12 @@ __weak void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth) HAL_ETH_WritePHYRegister(); @endverbatim - + * @{ */ /** - * @brief Sends an Ethernet frame. + * @brief Sends an Ethernet frame. * @param heth: pointer to a ETH_HandleTypeDef structure that contains * the configuration information for ETHERNET module * @param FrameLength: Amount of data to be sent @@ -656,82 +656,94 @@ __weak void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth) HAL_StatusTypeDef HAL_ETH_TransmitFrame(ETH_HandleTypeDef *heth, uint32_t FrameLength) { uint32_t bufcount = 0U, size = 0U, i = 0U; - + + /* Process Locked */ + // MBED patch + //__HAL_LOCK(heth); + /* Set the ETH peripheral state to BUSY */ heth->State = HAL_ETH_STATE_BUSY; - - if (FrameLength == 0U) + + if (FrameLength == 0U) { /* Set ETH HAL state to READY */ heth->State = HAL_ETH_STATE_READY; - - return HAL_ERROR; - } - + + /* Process Unlocked */ + // MBED patch + //__HAL_UNLOCK(heth); + + return HAL_ERROR; + } + /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */ - if(((heth->TxDesc)->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET) - { + if (((heth->TxDesc)->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET) + { /* OWN bit set */ heth->State = HAL_ETH_STATE_BUSY_TX; - + + /* Process Unlocked */ + // MBED patch + //__HAL_UNLOCK(heth); + return HAL_ERROR; } - + /* Get the number of needed Tx buffers for the current frame */ if (FrameLength > ETH_TX_BUF_SIZE) { - bufcount = FrameLength/ETH_TX_BUF_SIZE; - if (FrameLength % ETH_TX_BUF_SIZE) + bufcount = FrameLength / ETH_TX_BUF_SIZE; + if (FrameLength % ETH_TX_BUF_SIZE) { bufcount++; } } - else - { + else + { bufcount = 1U; } if (bufcount == 1U) { /* Set LAST and FIRST segment */ - heth->TxDesc->Status |=ETH_DMATXDESC_FS|ETH_DMATXDESC_LS; + heth->TxDesc->Status |= ETH_DMATXDESC_FS | ETH_DMATXDESC_LS; /* Set frame size */ heth->TxDesc->ControlBufferSize = (FrameLength & ETH_DMATXDESC_TBS1); /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */ heth->TxDesc->Status |= ETH_DMATXDESC_OWN; /* Point to next descriptor */ - heth->TxDesc= (ETH_DMADescTypeDef *)(heth->TxDesc->Buffer2NextDescAddr); + heth->TxDesc = (ETH_DMADescTypeDef *)(heth->TxDesc->Buffer2NextDescAddr); } else { - for (i=0U; i< bufcount; i++) + for (i = 0U; i < bufcount; i++) { /* Clear FIRST and LAST segment bits */ heth->TxDesc->Status &= ~(ETH_DMATXDESC_FS | ETH_DMATXDESC_LS); - - if (i == 0U) + + if (i == 0U) { /* Setting the first segment bit */ - heth->TxDesc->Status |= ETH_DMATXDESC_FS; + heth->TxDesc->Status |= ETH_DMATXDESC_FS; } - + /* Program size */ heth->TxDesc->ControlBufferSize = (ETH_TX_BUF_SIZE & ETH_DMATXDESC_TBS1); - - if (i == (bufcount-1U)) + + if (i == (bufcount - 1U)) { /* Setting the last segment bit */ heth->TxDesc->Status |= ETH_DMATXDESC_LS; - size = FrameLength - (bufcount-1U)*ETH_TX_BUF_SIZE; + size = FrameLength - (bufcount - 1U) * ETH_TX_BUF_SIZE; heth->TxDesc->ControlBufferSize = (size & ETH_DMATXDESC_TBS1); } - + /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */ heth->TxDesc->Status |= ETH_DMATXDESC_OWN; /* point to next descriptor */ heth->TxDesc = (ETH_DMADescTypeDef *)(heth->TxDesc->Buffer2NextDescAddr); } } - + /* When Tx Buffer unavailable flag is set: clear it and resume transmission */ if (((heth->Instance)->DMASR & ETH_DMASR_TBUS) != (uint32_t)RESET) { @@ -740,16 +752,20 @@ HAL_StatusTypeDef HAL_ETH_TransmitFrame(ETH_HandleTypeDef *heth, uint32_t FrameL /* Resume DMA transmission*/ (heth->Instance)->DMATPDR = 0U; } - + /* Set ETH HAL State to Ready */ heth->State = HAL_ETH_STATE_READY; - + + /* Process Unlocked */ + // MBED patch + //__HAL_UNLOCK(heth); + /* Return function status */ return HAL_OK; } /** - * @brief Checks for received frames. + * @brief Checks for received frames. * @param heth: pointer to a ETH_HandleTypeDef structure that contains * the configuration information for ETHERNET module * @retval HAL status @@ -757,70 +773,82 @@ HAL_StatusTypeDef HAL_ETH_TransmitFrame(ETH_HandleTypeDef *heth, uint32_t FrameL HAL_StatusTypeDef HAL_ETH_GetReceivedFrame(ETH_HandleTypeDef *heth) { uint32_t framelength = 0U; - + + /* Process Locked */ + // MBED patch + //__HAL_LOCK(heth); + /* Check the ETH state to BUSY */ heth->State = HAL_ETH_STATE_BUSY; - + /* Check if segment is not owned by DMA */ /* (((heth->RxDesc->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET) && ((heth->RxDesc->Status & ETH_DMARXDESC_LS) != (uint32_t)RESET)) */ - if(((heth->RxDesc->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET)) + if (((heth->RxDesc->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET)) { /* Check if last segment */ - if(((heth->RxDesc->Status & ETH_DMARXDESC_LS) != (uint32_t)RESET)) + if (((heth->RxDesc->Status & ETH_DMARXDESC_LS) != (uint32_t)RESET)) { /* increment segment count */ (heth->RxFrameInfos).SegCount++; - + /* Check if last segment is first segment: one segment contains the frame */ if ((heth->RxFrameInfos).SegCount == 1U) { - (heth->RxFrameInfos).FSRxDesc =heth->RxDesc; + (heth->RxFrameInfos).FSRxDesc = heth->RxDesc; } - + heth->RxFrameInfos.LSRxDesc = heth->RxDesc; - + /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */ framelength = (((heth->RxDesc)->Status & ETH_DMARXDESC_FL) >> ETH_DMARXDESC_FRAMELENGTHSHIFT) - 4U; heth->RxFrameInfos.length = framelength; - + /* Get the address of the buffer start address */ heth->RxFrameInfos.buffer = ((heth->RxFrameInfos).FSRxDesc)->Buffer1Addr; /* point to next descriptor */ - heth->RxDesc = (ETH_DMADescTypeDef*) ((heth->RxDesc)->Buffer2NextDescAddr); - + heth->RxDesc = (ETH_DMADescTypeDef *)((heth->RxDesc)->Buffer2NextDescAddr); + /* Set HAL State to Ready */ heth->State = HAL_ETH_STATE_READY; - + + /* Process Unlocked */ + // MBED patch + //__HAL_UNLOCK(heth); + /* Return function status */ return HAL_OK; } /* Check if first segment */ - else if((heth->RxDesc->Status & ETH_DMARXDESC_FS) != (uint32_t)RESET) + else if ((heth->RxDesc->Status & ETH_DMARXDESC_FS) != (uint32_t)RESET) { (heth->RxFrameInfos).FSRxDesc = heth->RxDesc; (heth->RxFrameInfos).LSRxDesc = NULL; (heth->RxFrameInfos).SegCount = 1U; /* Point to next descriptor */ - heth->RxDesc = (ETH_DMADescTypeDef*) (heth->RxDesc->Buffer2NextDescAddr); + heth->RxDesc = (ETH_DMADescTypeDef *)(heth->RxDesc->Buffer2NextDescAddr); } - /* Check if intermediate segment */ + /* Check if intermediate segment */ else { (heth->RxFrameInfos).SegCount++; /* Point to next descriptor */ - heth->RxDesc = (ETH_DMADescTypeDef*) (heth->RxDesc->Buffer2NextDescAddr); - } + heth->RxDesc = (ETH_DMADescTypeDef *)(heth->RxDesc->Buffer2NextDescAddr); + } } - + /* Set ETH HAL State to Ready */ heth->State = HAL_ETH_STATE_READY; - + + /* Process Unlocked */ + // MBED patch + //__HAL_UNLOCK(heth); + /* Return function status */ return HAL_ERROR; } /** - * @brief Gets the Received frame in interrupt mode. + * @brief Gets the Received frame in interrupt mode. * @param heth: pointer to a ETH_HandleTypeDef structure that contains * the configuration information for ETHERNET module * @retval HAL status @@ -828,24 +856,28 @@ HAL_StatusTypeDef HAL_ETH_GetReceivedFrame(ETH_HandleTypeDef *heth) HAL_StatusTypeDef HAL_ETH_GetReceivedFrame_IT(ETH_HandleTypeDef *heth) { uint32_t descriptorscancounter = 0U; - + + /* Process Locked */ + // MBED patch + //__HAL_LOCK(heth); + /* Set ETH HAL State to BUSY */ heth->State = HAL_ETH_STATE_BUSY; - + /* Scan descriptors owned by CPU */ while (((heth->RxDesc->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET) && (descriptorscancounter < ETH_RXBUFNB)) { /* Just for security */ descriptorscancounter++; - + /* Check if first segment in frame */ - /* ((heth->RxDesc->Status & ETH_DMARXDESC_FS) != (uint32_t)RESET) && ((heth->RxDesc->Status & ETH_DMARXDESC_LS) == (uint32_t)RESET)) */ - if((heth->RxDesc->Status & (ETH_DMARXDESC_FS | ETH_DMARXDESC_LS)) == (uint32_t)ETH_DMARXDESC_FS) - { + /* ((heth->RxDesc->Status & ETH_DMARXDESC_FS) != (uint32_t)RESET) && ((heth->RxDesc->Status & ETH_DMARXDESC_LS) == (uint32_t)RESET)) */ + if ((heth->RxDesc->Status & (ETH_DMARXDESC_FS | ETH_DMARXDESC_LS)) == (uint32_t)ETH_DMARXDESC_FS) + { heth->RxFrameInfos.FSRxDesc = heth->RxDesc; - heth->RxFrameInfos.SegCount = 1U; + heth->RxFrameInfos.SegCount = 1U; /* Point to next descriptor */ - heth->RxDesc = (ETH_DMADescTypeDef*) (heth->RxDesc->Buffer2NextDescAddr); + heth->RxDesc = (ETH_DMADescTypeDef *)(heth->RxDesc->Buffer2NextDescAddr); } /* Check if intermediate segment */ /* ((heth->RxDesc->Status & ETH_DMARXDESC_LS) == (uint32_t)RESET)&& ((heth->RxDesc->Status & ETH_DMARXDESC_FS) == (uint32_t)RESET)) */ @@ -854,35 +886,39 @@ HAL_StatusTypeDef HAL_ETH_GetReceivedFrame_IT(ETH_HandleTypeDef *heth) /* Increment segment count */ (heth->RxFrameInfos.SegCount)++; /* Point to next descriptor */ - heth->RxDesc = (ETH_DMADescTypeDef*)(heth->RxDesc->Buffer2NextDescAddr); + heth->RxDesc = (ETH_DMADescTypeDef *)(heth->RxDesc->Buffer2NextDescAddr); } /* Should be last segment */ else - { + { /* Last segment */ heth->RxFrameInfos.LSRxDesc = heth->RxDesc; - + /* Increment segment count */ (heth->RxFrameInfos.SegCount)++; - + /* Check if last segment is first segment: one segment contains the frame */ if ((heth->RxFrameInfos.SegCount) == 1U) { heth->RxFrameInfos.FSRxDesc = heth->RxDesc; } - + /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */ heth->RxFrameInfos.length = (((heth->RxDesc)->Status & ETH_DMARXDESC_FL) >> ETH_DMARXDESC_FRAMELENGTHSHIFT) - 4U; - - /* Get the address of the buffer start address */ - heth->RxFrameInfos.buffer =((heth->RxFrameInfos).FSRxDesc)->Buffer1Addr; - - /* Point to next descriptor */ - heth->RxDesc = (ETH_DMADescTypeDef*) (heth->RxDesc->Buffer2NextDescAddr); - + + /* Get the address of the buffer start address */ + heth->RxFrameInfos.buffer = ((heth->RxFrameInfos).FSRxDesc)->Buffer1Addr; + + /* Point to next descriptor */ + heth->RxDesc = (ETH_DMADescTypeDef *)(heth->RxDesc->Buffer2NextDescAddr); + /* Set HAL State to Ready */ heth->State = HAL_ETH_STATE_READY; - + + /* Process Unlocked */ + // MBED patch + //__HAL_UNLOCK(heth); + /* Return function status */ return HAL_OK; } @@ -890,7 +926,11 @@ HAL_StatusTypeDef HAL_ETH_GetReceivedFrame_IT(ETH_HandleTypeDef *heth) /* Set HAL State to Ready */ heth->State = HAL_ETH_STATE_READY; - + + /* Process Unlocked */ + // MBED patch + //__HAL_UNLOCK(heth); + /* Return function status */ return HAL_ERROR; } @@ -904,52 +944,52 @@ HAL_StatusTypeDef HAL_ETH_GetReceivedFrame_IT(ETH_HandleTypeDef *heth) void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth) { /* Frame received */ - if (__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_R)) + if (__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_R)) { /* Receive complete callback */ HAL_ETH_RxCpltCallback(heth); - - /* Clear the Eth DMA Rx IT pending bits */ + + /* Clear the Eth DMA Rx IT pending bits */ __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_IT_R); /* Set HAL State to Ready */ heth->State = HAL_ETH_STATE_READY; - + /* Process Unlocked */ __HAL_UNLOCK(heth); } /* Frame transmitted */ - else if (__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_T)) + else if (__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_T)) { /* Transfer complete callback */ HAL_ETH_TxCpltCallback(heth); - + /* Clear the Eth DMA Tx IT pending bits */ __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_IT_T); /* Set HAL State to Ready */ heth->State = HAL_ETH_STATE_READY; - + /* Process Unlocked */ __HAL_UNLOCK(heth); } - + /* Clear the interrupt flags */ __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_IT_NIS); - + /* ETH DMA Error */ - if(__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_AIS)) + if (__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_AIS)) { /* Ethernet Error callback */ HAL_ETH_ErrorCallback(heth); /* Clear the interrupt flags */ __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_FLAG_AIS); - + /* Set HAL State to Ready */ heth->State = HAL_ETH_STATE_READY; - + /* Process Unlocked */ __HAL_UNLOCK(heth); } @@ -967,7 +1007,7 @@ __weak void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth) UNUSED(heth); /* NOTE : This function Should not be modified, when the callback is needed, the HAL_ETH_TxCpltCallback could be implemented in the user file - */ + */ } /** @@ -982,7 +1022,7 @@ __weak void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth) UNUSED(heth); /* NOTE : This function Should not be modified, when the callback is needed, the HAL_ETH_TxCpltCallback could be implemented in the user file - */ + */ } /** @@ -997,78 +1037,78 @@ __weak void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth) UNUSED(heth); /* NOTE : This function Should not be modified, when the callback is needed, the HAL_ETH_TxCpltCallback could be implemented in the user file - */ + */ } /** * @brief Reads a PHY register * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param PHYReg: PHY register address, is the index of one of the 32 PHY register. - * This parameter can be one of the following values: - * PHY_BCR: Transceiver Basic Control Register, - * PHY_BSR: Transceiver Basic Status Register. + * the configuration information for ETHERNET module + * @param PHYReg: PHY register address, is the index of one of the 32 PHY register. + * This parameter can be one of the following values: + * PHY_BCR: Transceiver Basic Control Register, + * PHY_BSR: Transceiver Basic Status Register. * More PHY register could be read depending on the used PHY - * @param RegValue: PHY register value + * @param RegValue: PHY register value * @retval HAL status */ HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint16_t PHYReg, uint32_t *RegValue) { - uint32_t tmpreg1 = 0U; + uint32_t tmpreg1 = 0U; uint32_t tickstart = 0U; - + /* Check parameters */ assert_param(IS_ETH_PHY_ADDRESS(heth->Init.PhyAddress)); - + /* Check the ETH peripheral state */ - if(heth->State == HAL_ETH_STATE_BUSY_RD) + if (heth->State == HAL_ETH_STATE_BUSY_RD) { return HAL_BUSY; } /* Set ETH HAL State to BUSY_RD */ heth->State = HAL_ETH_STATE_BUSY_RD; - + /* Get the ETHERNET MACMIIAR value */ tmpreg1 = heth->Instance->MACMIIAR; - + /* Keep only the CSR Clock Range CR[2:0] bits value */ tmpreg1 &= ~ETH_MACMIIAR_CR_MASK; - + /* Prepare the MII address register value */ - tmpreg1 |=(((uint32_t)heth->Init.PhyAddress << 11U) & ETH_MACMIIAR_PA); /* Set the PHY device address */ - tmpreg1 |=(((uint32_t)PHYReg<<6U) & ETH_MACMIIAR_MR); /* Set the PHY register address */ + tmpreg1 |= (((uint32_t)heth->Init.PhyAddress << 11U) & ETH_MACMIIAR_PA); /* Set the PHY device address */ + tmpreg1 |= (((uint32_t)PHYReg << 6U) & ETH_MACMIIAR_MR); /* Set the PHY register address */ tmpreg1 &= ~ETH_MACMIIAR_MW; /* Set the read mode */ tmpreg1 |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */ - + /* Write the result value into the MII Address register */ heth->Instance->MACMIIAR = tmpreg1; - + /* Get tick */ tickstart = HAL_GetTick(); - + /* Check for the Busy flag */ - while((tmpreg1 & ETH_MACMIIAR_MB) == ETH_MACMIIAR_MB) + while ((tmpreg1 & ETH_MACMIIAR_MB) == ETH_MACMIIAR_MB) { /* Check for the Timeout */ - if((HAL_GetTick() - tickstart ) > PHY_READ_TO) + if ((HAL_GetTick() - tickstart) > PHY_READ_TO) { - heth->State= HAL_ETH_STATE_READY; - + heth->State = HAL_ETH_STATE_READY; + /* Process Unlocked */ __HAL_UNLOCK(heth); - + return HAL_TIMEOUT; } - + tmpreg1 = heth->Instance->MACMIIAR; } - + /* Get MACMIIDR value */ *RegValue = (uint16_t)(heth->Instance->MACMIIDR); - + /* Set ETH HAL State to READY */ heth->State = HAL_ETH_STATE_READY; - + /* Return function status */ return HAL_OK; } @@ -1076,10 +1116,10 @@ HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint16_t PHYR /** * @brief Writes to a PHY register. * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @param PHYReg: PHY register address, is the index of one of the 32 PHY register. - * This parameter can be one of the following values: - * PHY_BCR: Transceiver Control Register. + * the configuration information for ETHERNET module + * @param PHYReg: PHY register address, is the index of one of the 32 PHY register. + * This parameter can be one of the following values: + * PHY_BCR: Transceiver Control Register. * More PHY register could be written depending on the used PHY * @param RegValue: the value to write * @retval HAL status @@ -1088,61 +1128,61 @@ HAL_StatusTypeDef HAL_ETH_WritePHYRegister(ETH_HandleTypeDef *heth, uint16_t PHY { uint32_t tmpreg1 = 0U; uint32_t tickstart = 0U; - + /* Check parameters */ assert_param(IS_ETH_PHY_ADDRESS(heth->Init.PhyAddress)); - + /* Check the ETH peripheral state */ - if(heth->State == HAL_ETH_STATE_BUSY_WR) + if (heth->State == HAL_ETH_STATE_BUSY_WR) { return HAL_BUSY; } /* Set ETH HAL State to BUSY_WR */ heth->State = HAL_ETH_STATE_BUSY_WR; - + /* Get the ETHERNET MACMIIAR value */ tmpreg1 = heth->Instance->MACMIIAR; - + /* Keep only the CSR Clock Range CR[2:0] bits value */ tmpreg1 &= ~ETH_MACMIIAR_CR_MASK; - + /* Prepare the MII register address value */ - tmpreg1 |=(((uint32_t)heth->Init.PhyAddress<<11U) & ETH_MACMIIAR_PA); /* Set the PHY device address */ - tmpreg1 |=(((uint32_t)PHYReg<<6U) & ETH_MACMIIAR_MR); /* Set the PHY register address */ + tmpreg1 |= (((uint32_t)heth->Init.PhyAddress << 11U) & ETH_MACMIIAR_PA); /* Set the PHY device address */ + tmpreg1 |= (((uint32_t)PHYReg << 6U) & ETH_MACMIIAR_MR); /* Set the PHY register address */ tmpreg1 |= ETH_MACMIIAR_MW; /* Set the write mode */ tmpreg1 |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */ - + /* Give the value to the MII data register */ heth->Instance->MACMIIDR = (uint16_t)RegValue; - + /* Write the result value into the MII Address register */ heth->Instance->MACMIIAR = tmpreg1; - + /* Get tick */ tickstart = HAL_GetTick(); - + /* Check for the Busy flag */ - while((tmpreg1 & ETH_MACMIIAR_MB) == ETH_MACMIIAR_MB) + while ((tmpreg1 & ETH_MACMIIAR_MB) == ETH_MACMIIAR_MB) { /* Check for the Timeout */ - if((HAL_GetTick() - tickstart ) > PHY_WRITE_TO) + if ((HAL_GetTick() - tickstart) > PHY_WRITE_TO) { - heth->State= HAL_ETH_STATE_READY; - + heth->State = HAL_ETH_STATE_READY; + /* Process Unlocked */ __HAL_UNLOCK(heth); - + return HAL_TIMEOUT; } - + tmpreg1 = heth->Instance->MACMIIAR; } - + /* Set ETH HAL State to READY */ heth->State = HAL_ETH_STATE_READY; - + /* Return function status */ - return HAL_OK; + return HAL_OK; } /** @@ -1150,16 +1190,16 @@ HAL_StatusTypeDef HAL_ETH_WritePHYRegister(ETH_HandleTypeDef *heth, uint16_t PHY */ /** @defgroup ETH_Exported_Functions_Group3 Peripheral Control functions - * @brief Peripheral Control functions + * @brief Peripheral Control functions * -@verbatim +@verbatim =============================================================================== ##### Peripheral Control functions ##### - =============================================================================== + =============================================================================== [..] This section provides functions allowing to: (+) Enable MAC and DMA transmission and reception. HAL_ETH_Start(); - (+) Disable MAC and DMA transmission and reception. + (+) Disable MAC and DMA transmission and reception. HAL_ETH_Stop(); (+) Set the MAC configuration in runtime mode HAL_ETH_ConfigMAC(); @@ -1168,82 +1208,82 @@ HAL_StatusTypeDef HAL_ETH_WritePHYRegister(ETH_HandleTypeDef *heth, uint16_t PHY @endverbatim * @{ - */ - - /** - * @brief Enables Ethernet MAC and DMA reception/transmission - * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module - * @retval HAL status */ + +/** + * @brief Enables Ethernet MAC and DMA reception/transmission + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ HAL_StatusTypeDef HAL_ETH_Start(ETH_HandleTypeDef *heth) -{ +{ /* Process Locked */ __HAL_LOCK(heth); - + /* Set the ETH peripheral state to BUSY */ heth->State = HAL_ETH_STATE_BUSY; - + /* Enable transmit state machine of the MAC for transmission on the MII */ ETH_MACTransmissionEnable(heth); - + /* Enable receive state machine of the MAC for reception from the MII */ ETH_MACReceptionEnable(heth); - + /* Flush Transmit FIFO */ ETH_FlushTransmitFIFO(heth); - + /* Start DMA transmission */ ETH_DMATransmissionEnable(heth); - + /* Start DMA reception */ ETH_DMAReceptionEnable(heth); - + /* Set the ETH state to READY*/ - heth->State= HAL_ETH_STATE_READY; - + heth->State = HAL_ETH_STATE_READY; + /* Process Unlocked */ __HAL_UNLOCK(heth); - + /* Return function status */ return HAL_OK; } /** - * @brief Stop Ethernet MAC and DMA reception/transmission + * @brief Stop Ethernet MAC and DMA reception/transmission * @param heth: pointer to a ETH_HandleTypeDef structure that contains * the configuration information for ETHERNET module * @retval HAL status */ HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth) -{ +{ /* Process Locked */ __HAL_LOCK(heth); - + /* Set the ETH peripheral state to BUSY */ heth->State = HAL_ETH_STATE_BUSY; - + /* Stop DMA transmission */ ETH_DMATransmissionDisable(heth); - + /* Stop DMA reception */ ETH_DMAReceptionDisable(heth); - + /* Disable receive state machine of the MAC for reception from the MII */ ETH_MACReceptionDisable(heth); - + /* Flush Transmit FIFO */ ETH_FlushTransmitFIFO(heth); - + /* Disable transmit state machine of the MAC for transmission on the MII */ ETH_MACTransmissionDisable(heth); - + /* Set the ETH state*/ heth->State = HAL_ETH_STATE_READY; - + /* Process Unlocked */ __HAL_UNLOCK(heth); - + /* Return function status */ return HAL_OK; } @@ -1252,22 +1292,22 @@ HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth) * @brief Set ETH MAC Configuration. * @param heth: pointer to a ETH_HandleTypeDef structure that contains * the configuration information for ETHERNET module - * @param macconf: MAC Configuration structure + * @param macconf: MAC Configuration structure * @retval HAL status */ HAL_StatusTypeDef HAL_ETH_ConfigMAC(ETH_HandleTypeDef *heth, ETH_MACInitTypeDef *macconf) { uint32_t tmpreg1 = 0U; - + /* Process Locked */ __HAL_LOCK(heth); - + /* Set the ETH peripheral state to BUSY */ - heth->State= HAL_ETH_STATE_BUSY; - + heth->State = HAL_ETH_STATE_BUSY; + assert_param(IS_ETH_SPEED(heth->Init.Speed)); - assert_param(IS_ETH_DUPLEX_MODE(heth->Init.DuplexMode)); - + assert_param(IS_ETH_DUPLEX_MODE(heth->Init.DuplexMode)); + if (macconf != NULL) { /* Check the parameters */ @@ -1298,128 +1338,128 @@ HAL_StatusTypeDef HAL_ETH_ConfigMAC(ETH_HandleTypeDef *heth, ETH_MACInitTypeDef assert_param(IS_ETH_TRANSMIT_FLOWCONTROL(macconf->TransmitFlowControl)); assert_param(IS_ETH_VLAN_TAG_COMPARISON(macconf->VLANTagComparison)); assert_param(IS_ETH_VLAN_TAG_IDENTIFIER(macconf->VLANTagIdentifier)); - + /*------------------------ ETHERNET MACCR Configuration --------------------*/ /* Get the ETHERNET MACCR value */ tmpreg1 = (heth->Instance)->MACCR; /* Clear WD, PCE, PS, TE and RE bits */ tmpreg1 &= ETH_MACCR_CLEAR_MASK; - - tmpreg1 |= (uint32_t)(macconf->Watchdog | - macconf->Jabber | - macconf->InterFrameGap | - macconf->CarrierSense | - (heth->Init).Speed | - macconf->ReceiveOwn | - macconf->LoopbackMode | - (heth->Init).DuplexMode | - macconf->ChecksumOffload | - macconf->RetryTransmission | - macconf->AutomaticPadCRCStrip | - macconf->BackOffLimit | - macconf->DeferralCheck); - + + tmpreg1 |= (uint32_t)(macconf->Watchdog | + macconf->Jabber | + macconf->InterFrameGap | + macconf->CarrierSense | + (heth->Init).Speed | + macconf->ReceiveOwn | + macconf->LoopbackMode | + (heth->Init).DuplexMode | + macconf->ChecksumOffload | + macconf->RetryTransmission | + macconf->AutomaticPadCRCStrip | + macconf->BackOffLimit | + macconf->DeferralCheck); + /* Write to ETHERNET MACCR */ (heth->Instance)->MACCR = (uint32_t)tmpreg1; - + /* Wait until the write operation will be taken into account : at least four TX_CLK/RX_CLK clock cycles */ tmpreg1 = (heth->Instance)->MACCR; HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACCR = tmpreg1; - - /*----------------------- ETHERNET MACFFR Configuration --------------------*/ - /* Write to ETHERNET MACFFR */ - (heth->Instance)->MACFFR = (uint32_t)(macconf->ReceiveAll | + (heth->Instance)->MACCR = tmpreg1; + + /*----------------------- ETHERNET MACFFR Configuration --------------------*/ + /* Write to ETHERNET MACFFR */ + (heth->Instance)->MACFFR = (uint32_t)(macconf->ReceiveAll | macconf->SourceAddrFilter | macconf->PassControlFrames | - macconf->BroadcastFramesReception | + macconf->BroadcastFramesReception | macconf->DestinationAddrFilter | macconf->PromiscuousMode | macconf->MulticastFramesFilter | macconf->UnicastFramesFilter); - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACFFR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACFFR = tmpreg1; - - /*--------------- ETHERNET MACHTHR and MACHTLR Configuration ---------------*/ - /* Write to ETHERNET MACHTHR */ - (heth->Instance)->MACHTHR = (uint32_t)macconf->HashTableHigh; - - /* Write to ETHERNET MACHTLR */ - (heth->Instance)->MACHTLR = (uint32_t)macconf->HashTableLow; - /*----------------------- ETHERNET MACFCR Configuration --------------------*/ - - /* Get the ETHERNET MACFCR value */ - tmpreg1 = (heth->Instance)->MACFCR; - /* Clear xx bits */ - tmpreg1 &= ETH_MACFCR_CLEAR_MASK; - - tmpreg1 |= (uint32_t)((macconf->PauseTime << 16U) | + + /* Wait until the write operation will be taken into account : + at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = (heth->Instance)->MACFFR; + HAL_Delay(ETH_REG_WRITE_DELAY); + (heth->Instance)->MACFFR = tmpreg1; + + /*--------------- ETHERNET MACHTHR and MACHTLR Configuration ---------------*/ + /* Write to ETHERNET MACHTHR */ + (heth->Instance)->MACHTHR = (uint32_t)macconf->HashTableHigh; + + /* Write to ETHERNET MACHTLR */ + (heth->Instance)->MACHTLR = (uint32_t)macconf->HashTableLow; + /*----------------------- ETHERNET MACFCR Configuration --------------------*/ + + /* Get the ETHERNET MACFCR value */ + tmpreg1 = (heth->Instance)->MACFCR; + /* Clear xx bits */ + tmpreg1 &= ETH_MACFCR_CLEAR_MASK; + + tmpreg1 |= (uint32_t)((macconf->PauseTime << 16U) | macconf->ZeroQuantaPause | macconf->PauseLowThreshold | - macconf->UnicastPauseFrameDetect | + macconf->UnicastPauseFrameDetect | macconf->ReceiveFlowControl | - macconf->TransmitFlowControl); - - /* Write to ETHERNET MACFCR */ - (heth->Instance)->MACFCR = (uint32_t)tmpreg1; - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACFCR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACFCR = tmpreg1; - - /*----------------------- ETHERNET MACVLANTR Configuration -----------------*/ - (heth->Instance)->MACVLANTR = (uint32_t)(macconf->VLANTagComparison | - macconf->VLANTagIdentifier); - - /* Wait until the write operation will be taken into account : - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACVLANTR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACVLANTR = tmpreg1; + macconf->TransmitFlowControl); + + /* Write to ETHERNET MACFCR */ + (heth->Instance)->MACFCR = (uint32_t)tmpreg1; + + /* Wait until the write operation will be taken into account : + at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = (heth->Instance)->MACFCR; + HAL_Delay(ETH_REG_WRITE_DELAY); + (heth->Instance)->MACFCR = tmpreg1; + + /*----------------------- ETHERNET MACVLANTR Configuration -----------------*/ + (heth->Instance)->MACVLANTR = (uint32_t)(macconf->VLANTagComparison | + macconf->VLANTagIdentifier); + + /* Wait until the write operation will be taken into account : + at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = (heth->Instance)->MACVLANTR; + HAL_Delay(ETH_REG_WRITE_DELAY); + (heth->Instance)->MACVLANTR = tmpreg1; } else /* macconf == NULL : here we just configure Speed and Duplex mode */ { /*------------------------ ETHERNET MACCR Configuration --------------------*/ /* Get the ETHERNET MACCR value */ tmpreg1 = (heth->Instance)->MACCR; - + /* Clear FES and DM bits */ tmpreg1 &= ~(0x00004800U); - + tmpreg1 |= (uint32_t)(heth->Init.Speed | heth->Init.DuplexMode); - + /* Write to ETHERNET MACCR */ (heth->Instance)->MACCR = (uint32_t)tmpreg1; - + /* Wait until the write operation will be taken into account: at least four TX_CLK/RX_CLK clock cycles */ tmpreg1 = (heth->Instance)->MACCR; HAL_Delay(ETH_REG_WRITE_DELAY); (heth->Instance)->MACCR = tmpreg1; } - + /* Set the ETH state to Ready */ - heth->State= HAL_ETH_STATE_READY; - + heth->State = HAL_ETH_STATE_READY; + /* Process Unlocked */ __HAL_UNLOCK(heth); - + /* Return function status */ - return HAL_OK; + return HAL_OK; } /** * @brief Sets ETH DMA Configuration. * @param heth: pointer to a ETH_HandleTypeDef structure that contains * the configuration information for ETHERNET module - * @param dmaconf: DMA Configuration structure + * @param dmaconf: DMA Configuration structure * @retval HAL status */ HAL_StatusTypeDef HAL_ETH_ConfigDMA(ETH_HandleTypeDef *heth, ETH_DMAInitTypeDef *dmaconf) @@ -1428,9 +1468,9 @@ HAL_StatusTypeDef HAL_ETH_ConfigDMA(ETH_HandleTypeDef *heth, ETH_DMAInitTypeDef /* Process Locked */ __HAL_LOCK(heth); - + /* Set the ETH peripheral state to BUSY */ - heth->State= HAL_ETH_STATE_BUSY; + heth->State = HAL_ETH_STATE_BUSY; /* Check parameters */ assert_param(IS_ETH_DROP_TCPIP_CHECKSUM_FRAME(dmaconf->DropTCPIPChecksumErrorFrame)); @@ -1448,22 +1488,22 @@ HAL_StatusTypeDef HAL_ETH_ConfigDMA(ETH_HandleTypeDef *heth, ETH_DMAInitTypeDef assert_param(IS_ETH_TXDMA_BURST_LENGTH(dmaconf->TxDMABurstLength)); assert_param(IS_ETH_DMA_DESC_SKIP_LENGTH(dmaconf->DescriptorSkipLength)); assert_param(IS_ETH_DMA_ARBITRATION_ROUNDROBIN_RXTX(dmaconf->DMAArbitration)); - + /*----------------------- ETHERNET DMAOMR Configuration --------------------*/ /* Get the ETHERNET DMAOMR value */ tmpreg1 = (heth->Instance)->DMAOMR; /* Clear xx bits */ tmpreg1 &= ETH_DMAOMR_CLEAR_MASK; - tmpreg1 |= (uint32_t)(dmaconf->DropTCPIPChecksumErrorFrame | - dmaconf->ReceiveStoreForward | - dmaconf->FlushReceivedFrame | - dmaconf->TransmitStoreForward | - dmaconf->TransmitThresholdControl | - dmaconf->ForwardErrorFrames | - dmaconf->ForwardUndersizedGoodFrames | - dmaconf->ReceiveThresholdControl | - dmaconf->SecondFrameOperate); + tmpreg1 |= (uint32_t)(dmaconf->DropTCPIPChecksumErrorFrame | + dmaconf->ReceiveStoreForward | + dmaconf->FlushReceivedFrame | + dmaconf->TransmitStoreForward | + dmaconf->TransmitThresholdControl | + dmaconf->ForwardErrorFrames | + dmaconf->ForwardUndersizedGoodFrames | + dmaconf->ReceiveThresholdControl | + dmaconf->SecondFrameOperate); /* Write to ETHERNET DMAOMR */ (heth->Instance)->DMAOMR = (uint32_t)tmpreg1; @@ -1475,47 +1515,47 @@ HAL_StatusTypeDef HAL_ETH_ConfigDMA(ETH_HandleTypeDef *heth, ETH_DMAInitTypeDef (heth->Instance)->DMAOMR = tmpreg1; /*----------------------- ETHERNET DMABMR Configuration --------------------*/ - (heth->Instance)->DMABMR = (uint32_t)(dmaconf->AddressAlignedBeats | - dmaconf->FixedBurst | - dmaconf->RxDMABurstLength | /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */ - dmaconf->TxDMABurstLength | - (dmaconf->DescriptorSkipLength << 2U) | - dmaconf->DMAArbitration | - ETH_DMABMR_USP); /* Enable use of separate PBL for Rx and Tx */ - - /* Wait until the write operation will be taken into account: - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->DMABMR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->DMABMR = tmpreg1; - - /* Set the ETH state to Ready */ - heth->State= HAL_ETH_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(heth); - - /* Return function status */ - return HAL_OK; + (heth->Instance)->DMABMR = (uint32_t)(dmaconf->AddressAlignedBeats | + dmaconf->FixedBurst | + dmaconf->RxDMABurstLength | /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */ + dmaconf->TxDMABurstLength | + (dmaconf->DescriptorSkipLength << 2U) | + dmaconf->DMAArbitration | + ETH_DMABMR_USP); /* Enable use of separate PBL for Rx and Tx */ + + /* Wait until the write operation will be taken into account: + at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = (heth->Instance)->DMABMR; + HAL_Delay(ETH_REG_WRITE_DELAY); + (heth->Instance)->DMABMR = tmpreg1; + + /* Set the ETH state to Ready */ + heth->State = HAL_ETH_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(heth); + + /* Return function status */ + return HAL_OK; } /** * @} */ -/** @defgroup ETH_Exported_Functions_Group4 Peripheral State functions - * @brief Peripheral State functions +/** @defgroup ETH_Exported_Functions_Group4 Peripheral State functions + * @brief Peripheral State functions * - @verbatim + @verbatim =============================================================================== ##### Peripheral State functions ##### - =============================================================================== + =============================================================================== [..] - This subsection permits to get in run-time the status of the peripheral + This subsection permits to get in run-time the status of the peripheral and the data flow. (+) Get the ETH handle state: HAL_ETH_GetState(); - + @endverbatim * @{ @@ -1528,7 +1568,7 @@ HAL_StatusTypeDef HAL_ETH_ConfigDMA(ETH_HandleTypeDef *heth, ETH_DMAInitTypeDef * @retval HAL state */ HAL_ETH_StateTypeDef HAL_ETH_GetState(ETH_HandleTypeDef *heth) -{ +{ /* Return ETH state */ return heth->State; } @@ -1536,11 +1576,11 @@ HAL_ETH_StateTypeDef HAL_ETH_GetState(ETH_HandleTypeDef *heth) /** * @} */ - + /** * @} */ - + /** @addtogroup ETH_Private_Functions * @{ */ @@ -1557,16 +1597,16 @@ static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err) ETH_MACInitTypeDef macinit; ETH_DMAInitTypeDef dmainit; uint32_t tmpreg1 = 0U; - + if (err != ETH_SUCCESS) /* Auto-negotiation failed */ { /* Set Ethernet duplex mode to Full-duplex */ (heth->Init).DuplexMode = ETH_MODE_FULLDUPLEX; - + /* Set Ethernet speed to 100M */ (heth->Init).Speed = ETH_SPEED_100M; } - + /* Ethernet MAC default initialization **************************************/ macinit.Watchdog = ETH_WATCHDOG_ENABLE; macinit.Jabber = ETH_JABBER_ENABLE; @@ -1574,7 +1614,7 @@ static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err) macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE; macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE; macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE; - if(heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE) + if (heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE) { macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE; } @@ -1604,7 +1644,7 @@ static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err) macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE; macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT; macinit.VLANTagIdentifier = 0x0U; - + /*------------------------ ETHERNET MACCR Configuration --------------------*/ /* Get the ETHERNET MACCR value */ tmpreg1 = (heth->Instance)->MACCR; @@ -1614,39 +1654,39 @@ static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err) /* Set the JD: bit according to ETH Jabber value */ /* Set the IFG bit according to ETH InterFrameGap value */ /* Set the DCRS bit according to ETH CarrierSense value */ - /* Set the FES bit according to ETH Speed value */ - /* Set the DO bit according to ETH ReceiveOwn value */ + /* Set the FES bit according to ETH Speed value */ + /* Set the DO bit according to ETH ReceiveOwn value */ /* Set the LM bit according to ETH LoopbackMode value */ - /* Set the DM bit according to ETH Mode value */ + /* Set the DM bit according to ETH Mode value */ /* Set the IPCO bit according to ETH ChecksumOffload value */ /* Set the DR bit according to ETH RetryTransmission value */ /* Set the ACS bit according to ETH AutomaticPadCRCStrip value */ /* Set the BL bit according to ETH BackOffLimit value */ /* Set the DC bit according to ETH DeferralCheck value */ - tmpreg1 |= (uint32_t)(macinit.Watchdog | - macinit.Jabber | - macinit.InterFrameGap | - macinit.CarrierSense | - (heth->Init).Speed | - macinit.ReceiveOwn | - macinit.LoopbackMode | - (heth->Init).DuplexMode | - macinit.ChecksumOffload | - macinit.RetryTransmission | - macinit.AutomaticPadCRCStrip | - macinit.BackOffLimit | - macinit.DeferralCheck); - + tmpreg1 |= (uint32_t)(macinit.Watchdog | + macinit.Jabber | + macinit.InterFrameGap | + macinit.CarrierSense | + (heth->Init).Speed | + macinit.ReceiveOwn | + macinit.LoopbackMode | + (heth->Init).DuplexMode | + macinit.ChecksumOffload | + macinit.RetryTransmission | + macinit.AutomaticPadCRCStrip | + macinit.BackOffLimit | + macinit.DeferralCheck); + /* Write to ETHERNET MACCR */ (heth->Instance)->MACCR = (uint32_t)tmpreg1; - + /* Wait until the write operation will be taken into account: at least four TX_CLK/RX_CLK clock cycles */ tmpreg1 = (heth->Instance)->MACCR; HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACCR = tmpreg1; - - /*----------------------- ETHERNET MACFFR Configuration --------------------*/ + (heth->Instance)->MACCR = tmpreg1; + + /*----------------------- ETHERNET MACFFR Configuration --------------------*/ /* Set the RA bit according to ETH ReceiveAll value */ /* Set the SAF and SAIF bits according to ETH SourceAddrFilter value */ /* Set the PCF bit according to ETH PassControlFrames value */ @@ -1655,148 +1695,148 @@ static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err) /* Set the PR bit according to ETH PromiscuousMode value */ /* Set the PM, HMC and HPF bits according to ETH MulticastFramesFilter value */ /* Set the HUC and HPF bits according to ETH UnicastFramesFilter value */ - /* Write to ETHERNET MACFFR */ - (heth->Instance)->MACFFR = (uint32_t)(macinit.ReceiveAll | + /* Write to ETHERNET MACFFR */ + (heth->Instance)->MACFFR = (uint32_t)(macinit.ReceiveAll | macinit.SourceAddrFilter | macinit.PassControlFrames | - macinit.BroadcastFramesReception | + macinit.BroadcastFramesReception | macinit.DestinationAddrFilter | macinit.PromiscuousMode | macinit.MulticastFramesFilter | macinit.UnicastFramesFilter); - - /* Wait until the write operation will be taken into account: - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACFFR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACFFR = tmpreg1; - - /*--------------- ETHERNET MACHTHR and MACHTLR Configuration --------------*/ - /* Write to ETHERNET MACHTHR */ - (heth->Instance)->MACHTHR = (uint32_t)macinit.HashTableHigh; - - /* Write to ETHERNET MACHTLR */ - (heth->Instance)->MACHTLR = (uint32_t)macinit.HashTableLow; - /*----------------------- ETHERNET MACFCR Configuration -------------------*/ - - /* Get the ETHERNET MACFCR value */ - tmpreg1 = (heth->Instance)->MACFCR; - /* Clear xx bits */ - tmpreg1 &= ETH_MACFCR_CLEAR_MASK; - - /* Set the PT bit according to ETH PauseTime value */ - /* Set the DZPQ bit according to ETH ZeroQuantaPause value */ - /* Set the PLT bit according to ETH PauseLowThreshold value */ - /* Set the UP bit according to ETH UnicastPauseFrameDetect value */ - /* Set the RFE bit according to ETH ReceiveFlowControl value */ - /* Set the TFE bit according to ETH TransmitFlowControl value */ - tmpreg1 |= (uint32_t)((macinit.PauseTime << 16U) | + + /* Wait until the write operation will be taken into account: + at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = (heth->Instance)->MACFFR; + HAL_Delay(ETH_REG_WRITE_DELAY); + (heth->Instance)->MACFFR = tmpreg1; + + /*--------------- ETHERNET MACHTHR and MACHTLR Configuration --------------*/ + /* Write to ETHERNET MACHTHR */ + (heth->Instance)->MACHTHR = (uint32_t)macinit.HashTableHigh; + + /* Write to ETHERNET MACHTLR */ + (heth->Instance)->MACHTLR = (uint32_t)macinit.HashTableLow; + /*----------------------- ETHERNET MACFCR Configuration -------------------*/ + + /* Get the ETHERNET MACFCR value */ + tmpreg1 = (heth->Instance)->MACFCR; + /* Clear xx bits */ + tmpreg1 &= ETH_MACFCR_CLEAR_MASK; + + /* Set the PT bit according to ETH PauseTime value */ + /* Set the DZPQ bit according to ETH ZeroQuantaPause value */ + /* Set the PLT bit according to ETH PauseLowThreshold value */ + /* Set the UP bit according to ETH UnicastPauseFrameDetect value */ + /* Set the RFE bit according to ETH ReceiveFlowControl value */ + /* Set the TFE bit according to ETH TransmitFlowControl value */ + tmpreg1 |= (uint32_t)((macinit.PauseTime << 16U) | macinit.ZeroQuantaPause | macinit.PauseLowThreshold | - macinit.UnicastPauseFrameDetect | + macinit.UnicastPauseFrameDetect | macinit.ReceiveFlowControl | - macinit.TransmitFlowControl); - - /* Write to ETHERNET MACFCR */ - (heth->Instance)->MACFCR = (uint32_t)tmpreg1; - - /* Wait until the write operation will be taken into account: - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACFCR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACFCR = tmpreg1; - - /*----------------------- ETHERNET MACVLANTR Configuration ----------------*/ - /* Set the ETV bit according to ETH VLANTagComparison value */ - /* Set the VL bit according to ETH VLANTagIdentifier value */ - (heth->Instance)->MACVLANTR = (uint32_t)(macinit.VLANTagComparison | - macinit.VLANTagIdentifier); - - /* Wait until the write operation will be taken into account: - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->MACVLANTR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->MACVLANTR = tmpreg1; - - /* Ethernet DMA default initialization ************************************/ - dmainit.DropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE; - dmainit.ReceiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE; - dmainit.FlushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE; - dmainit.TransmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE; - dmainit.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES; - dmainit.ForwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE; - dmainit.ForwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE; - dmainit.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES; - dmainit.SecondFrameOperate = ETH_SECONDFRAMEOPERARTE_ENABLE; - dmainit.AddressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE; - dmainit.FixedBurst = ETH_FIXEDBURST_ENABLE; - dmainit.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT; - dmainit.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT; - dmainit.DescriptorSkipLength = 0x0U; - dmainit.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1; - - /* Get the ETHERNET DMAOMR value */ - tmpreg1 = (heth->Instance)->DMAOMR; - /* Clear xx bits */ - tmpreg1 &= ETH_DMAOMR_CLEAR_MASK; - - /* Set the DT bit according to ETH DropTCPIPChecksumErrorFrame value */ - /* Set the RSF bit according to ETH ReceiveStoreForward value */ - /* Set the DFF bit according to ETH FlushReceivedFrame value */ - /* Set the TSF bit according to ETH TransmitStoreForward value */ - /* Set the TTC bit according to ETH TransmitThresholdControl value */ - /* Set the FEF bit according to ETH ForwardErrorFrames value */ - /* Set the FUF bit according to ETH ForwardUndersizedGoodFrames value */ - /* Set the RTC bit according to ETH ReceiveThresholdControl value */ - /* Set the OSF bit according to ETH SecondFrameOperate value */ - tmpreg1 |= (uint32_t)(dmainit.DropTCPIPChecksumErrorFrame | - dmainit.ReceiveStoreForward | - dmainit.FlushReceivedFrame | - dmainit.TransmitStoreForward | - dmainit.TransmitThresholdControl | - dmainit.ForwardErrorFrames | - dmainit.ForwardUndersizedGoodFrames | - dmainit.ReceiveThresholdControl | - dmainit.SecondFrameOperate); - - /* Write to ETHERNET DMAOMR */ - (heth->Instance)->DMAOMR = (uint32_t)tmpreg1; - - /* Wait until the write operation will be taken into account: - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->DMAOMR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->DMAOMR = tmpreg1; - - /*----------------------- ETHERNET DMABMR Configuration ------------------*/ - /* Set the AAL bit according to ETH AddressAlignedBeats value */ - /* Set the FB bit according to ETH FixedBurst value */ - /* Set the RPBL and 4*PBL bits according to ETH RxDMABurstLength value */ - /* Set the PBL and 4*PBL bits according to ETH TxDMABurstLength value */ - /* Set the DSL bit according to ETH DesciptorSkipLength value */ - /* Set the PR and DA bits according to ETH DMAArbitration value */ - (heth->Instance)->DMABMR = (uint32_t)(dmainit.AddressAlignedBeats | - dmainit.FixedBurst | - dmainit.RxDMABurstLength | /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */ - dmainit.TxDMABurstLength | - (dmainit.DescriptorSkipLength << 2U) | - dmainit.DMAArbitration | - ETH_DMABMR_USP); /* Enable use of separate PBL for Rx and Tx */ - - /* Wait until the write operation will be taken into account: - at least four TX_CLK/RX_CLK clock cycles */ - tmpreg1 = (heth->Instance)->DMABMR; - HAL_Delay(ETH_REG_WRITE_DELAY); - (heth->Instance)->DMABMR = tmpreg1; - - if((heth->Init).RxMode == ETH_RXINTERRUPT_MODE) - { - /* Enable the Ethernet Rx Interrupt */ - __HAL_ETH_DMA_ENABLE_IT((heth), ETH_DMA_IT_NIS | ETH_DMA_IT_R); - } - - /* Initialize MAC address in ethernet MAC */ - ETH_MACAddressConfig(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr); + macinit.TransmitFlowControl); + + /* Write to ETHERNET MACFCR */ + (heth->Instance)->MACFCR = (uint32_t)tmpreg1; + + /* Wait until the write operation will be taken into account: + at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = (heth->Instance)->MACFCR; + HAL_Delay(ETH_REG_WRITE_DELAY); + (heth->Instance)->MACFCR = tmpreg1; + + /*----------------------- ETHERNET MACVLANTR Configuration ----------------*/ + /* Set the ETV bit according to ETH VLANTagComparison value */ + /* Set the VL bit according to ETH VLANTagIdentifier value */ + (heth->Instance)->MACVLANTR = (uint32_t)(macinit.VLANTagComparison | + macinit.VLANTagIdentifier); + + /* Wait until the write operation will be taken into account: + at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = (heth->Instance)->MACVLANTR; + HAL_Delay(ETH_REG_WRITE_DELAY); + (heth->Instance)->MACVLANTR = tmpreg1; + + /* Ethernet DMA default initialization ************************************/ + dmainit.DropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE; + dmainit.ReceiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE; + dmainit.FlushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE; + dmainit.TransmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE; + dmainit.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES; + dmainit.ForwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE; + dmainit.ForwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE; + dmainit.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES; + dmainit.SecondFrameOperate = ETH_SECONDFRAMEOPERARTE_ENABLE; + dmainit.AddressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE; + dmainit.FixedBurst = ETH_FIXEDBURST_ENABLE; + dmainit.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT; + dmainit.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT; + dmainit.DescriptorSkipLength = 0x0U; + dmainit.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1; + + /* Get the ETHERNET DMAOMR value */ + tmpreg1 = (heth->Instance)->DMAOMR; + /* Clear xx bits */ + tmpreg1 &= ETH_DMAOMR_CLEAR_MASK; + + /* Set the DT bit according to ETH DropTCPIPChecksumErrorFrame value */ + /* Set the RSF bit according to ETH ReceiveStoreForward value */ + /* Set the DFF bit according to ETH FlushReceivedFrame value */ + /* Set the TSF bit according to ETH TransmitStoreForward value */ + /* Set the TTC bit according to ETH TransmitThresholdControl value */ + /* Set the FEF bit according to ETH ForwardErrorFrames value */ + /* Set the FUF bit according to ETH ForwardUndersizedGoodFrames value */ + /* Set the RTC bit according to ETH ReceiveThresholdControl value */ + /* Set the OSF bit according to ETH SecondFrameOperate value */ + tmpreg1 |= (uint32_t)(dmainit.DropTCPIPChecksumErrorFrame | + dmainit.ReceiveStoreForward | + dmainit.FlushReceivedFrame | + dmainit.TransmitStoreForward | + dmainit.TransmitThresholdControl | + dmainit.ForwardErrorFrames | + dmainit.ForwardUndersizedGoodFrames | + dmainit.ReceiveThresholdControl | + dmainit.SecondFrameOperate); + + /* Write to ETHERNET DMAOMR */ + (heth->Instance)->DMAOMR = (uint32_t)tmpreg1; + + /* Wait until the write operation will be taken into account: + at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = (heth->Instance)->DMAOMR; + HAL_Delay(ETH_REG_WRITE_DELAY); + (heth->Instance)->DMAOMR = tmpreg1; + + /*----------------------- ETHERNET DMABMR Configuration ------------------*/ + /* Set the AAL bit according to ETH AddressAlignedBeats value */ + /* Set the FB bit according to ETH FixedBurst value */ + /* Set the RPBL and 4*PBL bits according to ETH RxDMABurstLength value */ + /* Set the PBL and 4*PBL bits according to ETH TxDMABurstLength value */ + /* Set the DSL bit according to ETH DesciptorSkipLength value */ + /* Set the PR and DA bits according to ETH DMAArbitration value */ + (heth->Instance)->DMABMR = (uint32_t)(dmainit.AddressAlignedBeats | + dmainit.FixedBurst | + dmainit.RxDMABurstLength | /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */ + dmainit.TxDMABurstLength | + (dmainit.DescriptorSkipLength << 2U) | + dmainit.DMAArbitration | + ETH_DMABMR_USP); /* Enable use of separate PBL for Rx and Tx */ + + /* Wait until the write operation will be taken into account: + at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = (heth->Instance)->DMABMR; + HAL_Delay(ETH_REG_WRITE_DELAY); + (heth->Instance)->DMABMR = tmpreg1; + + if ((heth->Init).RxMode == ETH_RXINTERRUPT_MODE) + { + /* Enable the Ethernet Rx Interrupt */ + __HAL_ETH_DMA_ENABLE_IT((heth), ETH_DMA_IT_NIS | ETH_DMA_IT_R); + } + + /* Initialize MAC address in ethernet MAC */ + ETH_MACAddressConfig(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr); } /** @@ -1805,8 +1845,8 @@ static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err) * the configuration information for ETHERNET module * @param MacAddr: The MAC address to configure * This parameter can be one of the following values: - * @arg ETH_MAC_Address0: MAC Address0 - * @arg ETH_MAC_Address1: MAC Address1 + * @arg ETH_MAC_Address0: MAC Address0 + * @arg ETH_MAC_Address1: MAC Address1 * @arg ETH_MAC_Address2: MAC Address2 * @arg ETH_MAC_Address3: MAC Address3 * @param Addr: Pointer to MAC address buffer data (6 bytes) @@ -1815,20 +1855,20 @@ static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err) static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr) { uint32_t tmpreg1; - + /* Prevent unused argument(s) compilation warning */ UNUSED(heth); /* Check the parameters */ assert_param(IS_ETH_MAC_ADDRESS0123(MacAddr)); - + /* Calculate the selected MAC address high register */ tmpreg1 = ((uint32_t)Addr[5U] << 8U) | (uint32_t)Addr[4U]; /* Load the selected MAC address high register */ (*(__IO uint32_t *)((uint32_t)(ETH_MAC_ADDR_HBASE + MacAddr))) = tmpreg1; /* Calculate the selected MAC address low register */ tmpreg1 = ((uint32_t)Addr[3U] << 24U) | ((uint32_t)Addr[2U] << 16U) | ((uint32_t)Addr[1U] << 8U) | Addr[0U]; - + /* Load the selected MAC address low register */ (*(__IO uint32_t *)((uint32_t)(ETH_MAC_ADDR_LBASE + MacAddr))) = tmpreg1; } @@ -1836,16 +1876,16 @@ static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint /** * @brief Enables the MAC transmission. * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module + * the configuration information for ETHERNET module * @retval None */ static void ETH_MACTransmissionEnable(ETH_HandleTypeDef *heth) -{ +{ __IO uint32_t tmpreg1 = 0U; - + /* Enable the MAC transmission */ (heth->Instance)->MACCR |= ETH_MACCR_TE; - + /* Wait until the write operation will be taken into account: at least four TX_CLK/RX_CLK clock cycles */ tmpreg1 = (heth->Instance)->MACCR; @@ -1856,16 +1896,16 @@ static void ETH_MACTransmissionEnable(ETH_HandleTypeDef *heth) /** * @brief Disables the MAC transmission. * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module + * the configuration information for ETHERNET module * @retval None */ static void ETH_MACTransmissionDisable(ETH_HandleTypeDef *heth) -{ +{ __IO uint32_t tmpreg1 = 0U; - + /* Disable the MAC transmission */ (heth->Instance)->MACCR &= ~ETH_MACCR_TE; - + /* Wait until the write operation will be taken into account: at least four TX_CLK/RX_CLK clock cycles */ tmpreg1 = (heth->Instance)->MACCR; @@ -1876,16 +1916,16 @@ static void ETH_MACTransmissionDisable(ETH_HandleTypeDef *heth) /** * @brief Enables the MAC reception. * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module + * the configuration information for ETHERNET module * @retval None */ static void ETH_MACReceptionEnable(ETH_HandleTypeDef *heth) -{ +{ __IO uint32_t tmpreg1 = 0U; - + /* Enable the MAC reception */ (heth->Instance)->MACCR |= ETH_MACCR_RE; - + /* Wait until the write operation will be taken into account: at least four TX_CLK/RX_CLK clock cycles */ tmpreg1 = (heth->Instance)->MACCR; @@ -1896,16 +1936,16 @@ static void ETH_MACReceptionEnable(ETH_HandleTypeDef *heth) /** * @brief Disables the MAC reception. * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module + * the configuration information for ETHERNET module * @retval None */ static void ETH_MACReceptionDisable(ETH_HandleTypeDef *heth) -{ +{ __IO uint32_t tmpreg1 = 0U; - + /* Disable the MAC reception */ - (heth->Instance)->MACCR &= ~ETH_MACCR_RE; - + (heth->Instance)->MACCR &= ~ETH_MACCR_RE; + /* Wait until the write operation will be taken into account: at least four TX_CLK/RX_CLK clock cycles */ tmpreg1 = (heth->Instance)->MACCR; @@ -1916,23 +1956,23 @@ static void ETH_MACReceptionDisable(ETH_HandleTypeDef *heth) /** * @brief Enables the DMA transmission. * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module + * the configuration information for ETHERNET module * @retval None */ static void ETH_DMATransmissionEnable(ETH_HandleTypeDef *heth) { /* Enable the DMA transmission */ - (heth->Instance)->DMAOMR |= ETH_DMAOMR_ST; + (heth->Instance)->DMAOMR |= ETH_DMAOMR_ST; } /** * @brief Disables the DMA transmission. * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module + * the configuration information for ETHERNET module * @retval None */ static void ETH_DMATransmissionDisable(ETH_HandleTypeDef *heth) -{ +{ /* Disable the DMA transmission */ (heth->Instance)->DMAOMR &= ~ETH_DMAOMR_ST; } @@ -1940,23 +1980,23 @@ static void ETH_DMATransmissionDisable(ETH_HandleTypeDef *heth) /** * @brief Enables the DMA reception. * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module + * the configuration information for ETHERNET module * @retval None */ static void ETH_DMAReceptionEnable(ETH_HandleTypeDef *heth) -{ +{ /* Enable the DMA reception */ - (heth->Instance)->DMAOMR |= ETH_DMAOMR_SR; + (heth->Instance)->DMAOMR |= ETH_DMAOMR_SR; } /** * @brief Disables the DMA reception. * @param heth: pointer to a ETH_HandleTypeDef structure that contains - * the configuration information for ETHERNET module + * the configuration information for ETHERNET module * @retval None */ static void ETH_DMAReceptionDisable(ETH_HandleTypeDef *heth) -{ +{ /* Disable the DMA reception */ (heth->Instance)->DMAOMR &= ~ETH_DMAOMR_SR; } @@ -1970,10 +2010,10 @@ static void ETH_DMAReceptionDisable(ETH_HandleTypeDef *heth) static void ETH_FlushTransmitFIFO(ETH_HandleTypeDef *heth) { __IO uint32_t tmpreg1 = 0U; - + /* Set the Flush Transmit FIFO bit */ (heth->Instance)->DMAOMR |= ETH_DMAOMR_FTF; - + /* Wait until the write operation will be taken into account: at least four TX_CLK/RX_CLK clock cycles */ tmpreg1 = (heth->Instance)->DMAOMR; @@ -1989,10 +2029,10 @@ static void ETH_FlushTransmitFIFO(ETH_HandleTypeDef *heth) static void ETH_Delay(uint32_t mdelay) { __IO uint32_t Delay = mdelay * (SystemCoreClock / 8U / 1000U); - do + do { __NOP(); - } + } while (Delay --); } diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_eth.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_eth.h index cb2f3c85ba4a..b211a176a5e0 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_eth.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_eth.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_eth.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of ETH HAL module. ****************************************************************************** * @attention @@ -33,14 +31,14 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** - */ + */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM32F1xx_HAL_ETH_H #define __STM32F1xx_HAL_ETH_H #ifdef __cplusplus - extern "C" { +extern "C" { #endif /* Includes ------------------------------------------------------------------*/ @@ -49,12 +47,12 @@ /** @addtogroup STM32F1xx_HAL_Driver * @{ */ -#if defined (STM32F107xC) +#if defined (STM32F107xC) /** @addtogroup ETH * @{ - */ - + */ + /** @addtogroup ETH_Private_Macros * @{ */ @@ -266,7 +264,7 @@ ((BUFFER) == ETH_DMARXDESC_BUFFER2)) #define IS_ETH_PMT_GET_FLAG(FLAG) (((FLAG) == ETH_PMT_FLAG_WUFR) || \ ((FLAG) == ETH_PMT_FLAG_MPR)) -#define IS_ETH_DMA_FLAG(FLAG) ((((FLAG) & 0xC7FE1800U) == 0x00U) && ((FLAG) != 0x00U)) +#define IS_ETH_DMA_FLAG(FLAG) ((((FLAG) & 0xC7FE1800U) == 0x00U) && ((FLAG) != 0x00U)) #define IS_ETH_DMA_GET_FLAG(FLAG) (((FLAG) == ETH_DMA_FLAG_TST) || ((FLAG) == ETH_DMA_FLAG_PMT) || \ ((FLAG) == ETH_DMA_FLAG_MMC) || ((FLAG) == ETH_DMA_FLAG_DATATRANSFERERROR) || \ ((FLAG) == ETH_DMA_FLAG_READWRITEERROR) || ((FLAG) == ETH_DMA_FLAG_ACCESSERROR) || \ @@ -355,18 +353,18 @@ /* ETHERNET Missed frames counter Shift */ #define ETH_DMA_RX_OVERFLOW_MISSEDFRAMES_COUNTERSHIFT 17U - /** - * @} - */ +/** + * @} + */ -/* Exported types ------------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ /** @defgroup ETH_Exported_Types ETH Exported Types * @{ */ -/** - * @brief HAL State structures definition - */ +/** + * @brief HAL State structures definition + */ typedef enum { HAL_ETH_STATE_RESET = 0x00U, /*!< Peripheral not yet Initialized or disabled */ @@ -379,10 +377,10 @@ typedef enum HAL_ETH_STATE_BUSY_RD = 0x82U, /*!< Read process is ongoing */ HAL_ETH_STATE_TIMEOUT = 0x03U, /*!< Timeout state */ HAL_ETH_STATE_ERROR = 0x04U /*!< Reception process is ongoing */ -}HAL_ETH_StateTypeDef; +} HAL_ETH_StateTypeDef; -/** - * @brief ETH Init Structure definition +/** + * @brief ETH Init Structure definition */ typedef struct @@ -397,34 +395,34 @@ typedef struct uint32_t DuplexMode; /*!< Selects the MAC duplex mode: Half-Duplex or Full-Duplex mode This parameter can be a value of @ref ETH_Duplex_Mode */ - + uint16_t PhyAddress; /*!< Ethernet PHY address. This parameter must be a number between Min_Data = 0 and Max_Data = 32 */ - + uint8_t *MACAddr; /*!< MAC Address of used Hardware: must be pointer on an array of 6 bytes */ - + uint32_t RxMode; /*!< Selects the Ethernet Rx mode: Polling mode, Interrupt mode. This parameter can be a value of @ref ETH_Rx_Mode */ - - uint32_t ChecksumMode; /*!< Selects if the checksum is check by hardware or by software. + + uint32_t ChecksumMode; /*!< Selects if the checksum is check by hardware or by software. This parameter can be a value of @ref ETH_Checksum_Mode */ - - uint32_t MediaInterface; /*!< Selects the media-independent interface or the reduced media-independent interface. + + uint32_t MediaInterface; /*!< Selects the media-independent interface or the reduced media-independent interface. This parameter can be a value of @ref ETH_Media_Interface */ } ETH_InitTypeDef; - /** - * @brief ETH MAC Configuration Structure definition - */ +/** + * @brief ETH MAC Configuration Structure definition + */ typedef struct { uint32_t Watchdog; /*!< Selects or not the Watchdog timer When enabled, the MAC allows no more then 2048 bytes to be received. When disabled, the MAC can receive up to 16384 bytes. - This parameter can be a value of @ref ETH_Watchdog */ + This parameter can be a value of @ref ETH_Watchdog */ uint32_t Jabber; /*!< Selects or not Jabber timer When enabled, the MAC allows no more then 2048 bytes to be sent. @@ -432,7 +430,7 @@ typedef struct This parameter can be a value of @ref ETH_Jabber */ uint32_t InterFrameGap; /*!< Selects the minimum IFG between frames during transmission. - This parameter can be a value of @ref ETH_Inter_Frame_Gap */ + This parameter can be a value of @ref ETH_Inter_Frame_Gap */ uint32_t CarrierSense; /*!< Selects or not the Carrier Sense. This parameter can be a value of @ref ETH_Carrier_Sense */ @@ -440,62 +438,62 @@ typedef struct uint32_t ReceiveOwn; /*!< Selects or not the ReceiveOwn, ReceiveOwn allows the reception of frames when the TX_EN signal is asserted in Half-Duplex mode. - This parameter can be a value of @ref ETH_Receive_Own */ + This parameter can be a value of @ref ETH_Receive_Own */ uint32_t LoopbackMode; /*!< Selects or not the internal MAC MII Loopback mode. - This parameter can be a value of @ref ETH_Loop_Back_Mode */ + This parameter can be a value of @ref ETH_Loop_Back_Mode */ uint32_t ChecksumOffload; /*!< Selects or not the IPv4 checksum checking for received frame payloads' TCP/UDP/ICMP headers. - This parameter can be a value of @ref ETH_Checksum_Offload */ + This parameter can be a value of @ref ETH_Checksum_Offload */ uint32_t RetryTransmission; /*!< Selects or not the MAC attempt retries transmission, based on the settings of BL, when a collision occurs (Half-Duplex mode). This parameter can be a value of @ref ETH_Retry_Transmission */ uint32_t AutomaticPadCRCStrip; /*!< Selects or not the Automatic MAC Pad/CRC Stripping. - This parameter can be a value of @ref ETH_Automatic_Pad_CRC_Strip */ + This parameter can be a value of @ref ETH_Automatic_Pad_CRC_Strip */ uint32_t BackOffLimit; /*!< Selects the BackOff limit value. This parameter can be a value of @ref ETH_Back_Off_Limit */ uint32_t DeferralCheck; /*!< Selects or not the deferral check function (Half-Duplex mode). - This parameter can be a value of @ref ETH_Deferral_Check */ + This parameter can be a value of @ref ETH_Deferral_Check */ uint32_t ReceiveAll; /*!< Selects or not all frames reception by the MAC (No filtering). - This parameter can be a value of @ref ETH_Receive_All */ + This parameter can be a value of @ref ETH_Receive_All */ uint32_t SourceAddrFilter; /*!< Selects the Source Address Filter mode. This parameter can be a value of @ref ETH_Source_Addr_Filter */ uint32_t PassControlFrames; /*!< Sets the forwarding mode of the control frames (including unicast and multicast PAUSE frames) - This parameter can be a value of @ref ETH_Pass_Control_Frames */ + This parameter can be a value of @ref ETH_Pass_Control_Frames */ uint32_t BroadcastFramesReception; /*!< Selects or not the reception of Broadcast Frames. This parameter can be a value of @ref ETH_Broadcast_Frames_Reception */ uint32_t DestinationAddrFilter; /*!< Sets the destination filter mode for both unicast and multicast frames. - This parameter can be a value of @ref ETH_Destination_Addr_Filter */ + This parameter can be a value of @ref ETH_Destination_Addr_Filter */ uint32_t PromiscuousMode; /*!< Selects or not the Promiscuous Mode This parameter can be a value of @ref ETH_Promiscuous_Mode */ uint32_t MulticastFramesFilter; /*!< Selects the Multicast Frames filter mode: None/HashTableFilter/PerfectFilter/PerfectHashTableFilter. - This parameter can be a value of @ref ETH_Multicast_Frames_Filter */ + This parameter can be a value of @ref ETH_Multicast_Frames_Filter */ uint32_t UnicastFramesFilter; /*!< Selects the Unicast Frames filter mode: HashTableFilter/PerfectFilter/PerfectHashTableFilter. - This parameter can be a value of @ref ETH_Unicast_Frames_Filter */ + This parameter can be a value of @ref ETH_Unicast_Frames_Filter */ uint32_t HashTableHigh; /*!< This field holds the higher 32 bits of Hash table. This parameter must be a number between Min_Data = 0x0 and Max_Data = 0xFFFFFFFFU */ uint32_t HashTableLow; /*!< This field holds the lower 32 bits of Hash table. - This parameter must be a number between Min_Data = 0x0 and Max_Data = 0xFFFFFFFFU */ + This parameter must be a number between Min_Data = 0x0 and Max_Data = 0xFFFFFFFFU */ - uint32_t PauseTime; /*!< This field holds the value to be used in the Pause Time field in the transmit control frame. + uint32_t PauseTime; /*!< This field holds the value to be used in the Pause Time field in the transmit control frame. This parameter must be a number between Min_Data = 0x0 and Max_Data = 0xFFFFU */ uint32_t ZeroQuantaPause; /*!< Selects or not the automatic generation of Zero-Quanta Pause Control frames. - This parameter can be a value of @ref ETH_Zero_Quanta_Pause */ + This parameter can be a value of @ref ETH_Zero_Quanta_Pause */ uint32_t PauseLowThreshold; /*!< This field configures the threshold of the PAUSE to be checked for automatic retransmission of PAUSE Frame. @@ -503,7 +501,7 @@ typedef struct uint32_t UnicastPauseFrameDetect; /*!< Selects or not the MAC detection of the Pause frames (with MAC Address0 unicast address and unique multicast address). - This parameter can be a value of @ref ETH_Unicast_Pause_Frame_Detect */ + This parameter can be a value of @ref ETH_Unicast_Pause_Frame_Detect */ uint32_t ReceiveFlowControl; /*!< Enables or disables the MAC to decode the received Pause frame and disable its transmitter for a specified time (Pause Time) @@ -511,33 +509,33 @@ typedef struct uint32_t TransmitFlowControl; /*!< Enables or disables the MAC to transmit Pause frames (Full-Duplex mode) or the MAC back-pressure operation (Half-Duplex mode) - This parameter can be a value of @ref ETH_Transmit_Flow_Control */ + This parameter can be a value of @ref ETH_Transmit_Flow_Control */ uint32_t VLANTagComparison; /*!< Selects the 12-bit VLAN identifier or the complete 16-bit VLAN tag for comparison and filtering. - This parameter can be a value of @ref ETH_VLAN_Tag_Comparison */ + This parameter can be a value of @ref ETH_VLAN_Tag_Comparison */ uint32_t VLANTagIdentifier; /*!< Holds the VLAN tag identifier for receive frames */ } ETH_MACInitTypeDef; -/** - * @brief ETH DMA Configuration Structure definition +/** + * @brief ETH DMA Configuration Structure definition */ typedef struct { - uint32_t DropTCPIPChecksumErrorFrame; /*!< Selects or not the Dropping of TCP/IP Checksum Error Frames. - This parameter can be a value of @ref ETH_Drop_TCP_IP_Checksum_Error_Frame */ + uint32_t DropTCPIPChecksumErrorFrame; /*!< Selects or not the Dropping of TCP/IP Checksum Error Frames. + This parameter can be a value of @ref ETH_Drop_TCP_IP_Checksum_Error_Frame */ uint32_t ReceiveStoreForward; /*!< Enables or disables the Receive store and forward mode. - This parameter can be a value of @ref ETH_Receive_Store_Forward */ + This parameter can be a value of @ref ETH_Receive_Store_Forward */ uint32_t FlushReceivedFrame; /*!< Enables or disables the flushing of received frames. - This parameter can be a value of @ref ETH_Flush_Received_Frame */ + This parameter can be a value of @ref ETH_Flush_Received_Frame */ uint32_t TransmitStoreForward; /*!< Enables or disables Transmit store and forward mode. - This parameter can be a value of @ref ETH_Transmit_Store_Forward */ + This parameter can be a value of @ref ETH_Transmit_Store_Forward */ uint32_t TransmitThresholdControl; /*!< Selects or not the Transmit Threshold Control. This parameter can be a value of @ref ETH_Transmit_Threshold_Control */ @@ -563,7 +561,7 @@ typedef struct This parameter can be a value of @ref ETH_Fixed_Burst */ uint32_t RxDMABurstLength; /*!< Indicates the maximum number of beats to be transferred in one Rx DMA transaction. - This parameter can be a value of @ref ETH_Rx_DMA_Burst_Length */ + This parameter can be a value of @ref ETH_Rx_DMA_Burst_Length */ uint32_t TxDMABurstLength; /*!< Indicates the maximum number of beats to be transferred in one Tx DMA transaction. This parameter can be a value of @ref ETH_Tx_DMA_Burst_Length */ @@ -572,70 +570,70 @@ typedef struct This parameter must be a number between Min_Data = 0 and Max_Data = 32 */ uint32_t DMAArbitration; /*!< Selects the DMA Tx/Rx arbitration. - This parameter can be a value of @ref ETH_DMA_Arbitration */ + This parameter can be a value of @ref ETH_DMA_Arbitration */ } ETH_DMAInitTypeDef; -/** +/** * @brief ETH DMA Descriptors data structure definition - */ + */ -typedef struct +typedef struct { __IO uint32_t Status; /*!< Status */ - + uint32_t ControlBufferSize; /*!< Control and Buffer1, Buffer2 lengths */ - + uint32_t Buffer1Addr; /*!< Buffer1 address pointer */ - + uint32_t Buffer2NextDescAddr; /*!< Buffer2 or next descriptor address pointer */ } ETH_DMADescTypeDef; -/** +/** * @brief Received Frame Informations structure definition - */ -typedef struct + */ +typedef struct { ETH_DMADescTypeDef *FSRxDesc; /*!< First Segment Rx Desc */ - + ETH_DMADescTypeDef *LSRxDesc; /*!< Last Segment Rx Desc */ - + uint32_t SegCount; /*!< Segment count */ - + uint32_t length; /*!< Frame length */ - + uint32_t buffer; /*!< Frame buffer */ } ETH_DMARxFrameInfos; -/** - * @brief ETH Handle Structure definition +/** + * @brief ETH Handle Structure definition */ - + typedef struct { ETH_TypeDef *Instance; /*!< Register base address */ - + ETH_InitTypeDef Init; /*!< Ethernet Init Configuration */ - + uint32_t LinkStatus; /*!< Ethernet link status */ - + ETH_DMADescTypeDef *RxDesc; /*!< Rx descriptor to Get */ - + ETH_DMADescTypeDef *TxDesc; /*!< Tx descriptor to Set */ - + ETH_DMARxFrameInfos RxFrameInfos; /*!< last Rx frame infos */ - + __IO HAL_ETH_StateTypeDef State; /*!< ETH communication state */ - + HAL_LockTypeDef Lock; /*!< ETH Lock */ } ETH_HandleTypeDef; - /** - * @} - */ +/** + * @} + */ /* Exported constants --------------------------------------------------------*/ /** @defgroup ETH_Exported_Constants ETH Exported Constants @@ -644,72 +642,72 @@ typedef struct /** @defgroup ETH_Buffers_setting ETH Buffers setting * @{ - */ + */ #define ETH_MAX_PACKET_SIZE 1524U /*!< ETH_HEADER + ETH_EXTRA + ETH_VLAN_TAG + ETH_MAX_ETH_PAYLOAD + ETH_CRC */ #define ETH_HEADER 14U /*!< 6 byte Dest addr, 6 byte Src addr, 2 byte length/type */ #define ETH_CRC 4U /*!< Ethernet CRC */ -#define ETH_EXTRA 2U /*!< Extra bytes in some cases */ +#define ETH_EXTRA 2U /*!< Extra bytes in some cases */ #define ETH_VLAN_TAG 4U /*!< optional 802.1q VLAN Tag */ #define ETH_MIN_ETH_PAYLOAD 46U /*!< Minimum Ethernet payload size */ #define ETH_MAX_ETH_PAYLOAD 1500U /*!< Maximum Ethernet payload size */ -#define ETH_JUMBO_FRAME_PAYLOAD 9000U /*!< Jumbo frame payload size */ +#define ETH_JUMBO_FRAME_PAYLOAD 9000U /*!< Jumbo frame payload size */ - /* Ethernet driver receive buffers are organized in a chained linked-list, when - an ethernet packet is received, the Rx-DMA will transfer the packet from RxFIFO - to the driver receive buffers memory. +/* Ethernet driver receive buffers are organized in a chained linked-list, when + an ethernet packet is received, the Rx-DMA will transfer the packet from RxFIFO + to the driver receive buffers memory. - Depending on the size of the received ethernet packet and the size of - each ethernet driver receive buffer, the received packet can take one or more - ethernet driver receive buffer. + Depending on the size of the received ethernet packet and the size of + each ethernet driver receive buffer, the received packet can take one or more + ethernet driver receive buffer. - In below are defined the size of one ethernet driver receive buffer ETH_RX_BUF_SIZE - and the total count of the driver receive buffers ETH_RXBUFNB. + In below are defined the size of one ethernet driver receive buffer ETH_RX_BUF_SIZE + and the total count of the driver receive buffers ETH_RXBUFNB. - The configured value for ETH_RX_BUF_SIZE and ETH_RXBUFNB are only provided as - example, they can be reconfigured in the application layer to fit the application - needs */ + The configured value for ETH_RX_BUF_SIZE and ETH_RXBUFNB are only provided as + example, they can be reconfigured in the application layer to fit the application + needs */ /* Here we configure each Ethernet driver receive buffer to fit the Max size Ethernet packet */ #ifndef ETH_RX_BUF_SIZE - #define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE +#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE #endif -/* 5 Ethernet driver receive buffers are used (in a chained linked list)*/ +/* 5 Ethernet driver receive buffers are used (in a chained linked list)*/ #ifndef ETH_RXBUFNB - #define ETH_RXBUFNB 5U /* 5 Rx buffers of size ETH_RX_BUF_SIZE */ +#define ETH_RXBUFNB 5U /* 5 Rx buffers of size ETH_RX_BUF_SIZE */ #endif - /* Ethernet driver transmit buffers are organized in a chained linked-list, when - an ethernet packet is transmitted, Tx-DMA will transfer the packet from the - driver transmit buffers memory to the TxFIFO. +/* Ethernet driver transmit buffers are organized in a chained linked-list, when + an ethernet packet is transmitted, Tx-DMA will transfer the packet from the + driver transmit buffers memory to the TxFIFO. - Depending on the size of the Ethernet packet to be transmitted and the size of - each ethernet driver transmit buffer, the packet to be transmitted can take - one or more ethernet driver transmit buffer. + Depending on the size of the Ethernet packet to be transmitted and the size of + each ethernet driver transmit buffer, the packet to be transmitted can take + one or more ethernet driver transmit buffer. - In below are defined the size of one ethernet driver transmit buffer ETH_TX_BUF_SIZE - and the total count of the driver transmit buffers ETH_TXBUFNB. + In below are defined the size of one ethernet driver transmit buffer ETH_TX_BUF_SIZE + and the total count of the driver transmit buffers ETH_TXBUFNB. - The configured value for ETH_TX_BUF_SIZE and ETH_TXBUFNB are only provided as - example, they can be reconfigured in the application layer to fit the application - needs */ + The configured value for ETH_TX_BUF_SIZE and ETH_TXBUFNB are only provided as + example, they can be reconfigured in the application layer to fit the application + needs */ /* Here we configure each Ethernet driver transmit buffer to fit the Max size Ethernet packet */ -#ifndef ETH_TX_BUF_SIZE - #define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE +#ifndef ETH_TX_BUF_SIZE +#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE #endif -/* 5 ethernet driver transmit buffers are used (in a chained linked list)*/ +/* 5 ethernet driver transmit buffers are used (in a chained linked list)*/ #ifndef ETH_TXBUFNB - #define ETH_TXBUFNB 5U /* 5 Tx buffers of size ETH_TX_BUF_SIZE */ +#define ETH_TXBUFNB 5U /* 5 Tx buffers of size ETH_TX_BUF_SIZE */ #endif - /** - * @} - */ +/** + * @} + */ /** @defgroup ETH_DMA_TX_Descriptor ETH DMA TX Descriptor * @{ @@ -728,9 +726,9 @@ typedef struct ----------------------------------------------------------------------------------------------- */ -/** +/** * @brief Bit definition of TDES0 register: DMA Tx descriptor status register - */ + */ #define ETH_DMATXDESC_OWN 0x80000000U /*!< OWN bit: descriptor is owned by DMA engine */ #define ETH_DMATXDESC_IC 0x40000000U /*!< Interrupt on Completion */ #define ETH_DMATXDESC_LS 0x20000000U /*!< Last Segment */ @@ -739,10 +737,10 @@ typedef struct #define ETH_DMATXDESC_DP 0x04000000U /*!< Disable Padding */ #define ETH_DMATXDESC_TTSE 0x02000000U /*!< Transmit Time Stamp Enable */ #define ETH_DMATXDESC_CIC 0x00C00000U /*!< Checksum Insertion Control: 4 cases */ -#define ETH_DMATXDESC_CIC_BYPASS 0x00000000U /*!< Do Nothing: Checksum Engine is bypassed */ -#define ETH_DMATXDESC_CIC_IPV4HEADER 0x00400000U /*!< IPV4 header Checksum Insertion */ -#define ETH_DMATXDESC_CIC_TCPUDPICMP_SEGMENT 0x00800000U /*!< TCP/UDP/ICMP Checksum Insertion calculated over segment only */ -#define ETH_DMATXDESC_CIC_TCPUDPICMP_FULL 0x00C00000U /*!< TCP/UDP/ICMP Checksum Insertion fully calculated */ +#define ETH_DMATXDESC_CIC_BYPASS 0x00000000U /*!< Do Nothing: Checksum Engine is bypassed */ +#define ETH_DMATXDESC_CIC_IPV4HEADER 0x00400000U /*!< IPV4 header Checksum Insertion */ +#define ETH_DMATXDESC_CIC_TCPUDPICMP_SEGMENT 0x00800000U /*!< TCP/UDP/ICMP Checksum Insertion calculated over segment only */ +#define ETH_DMATXDESC_CIC_TCPUDPICMP_FULL 0x00C00000U /*!< TCP/UDP/ICMP Checksum Insertion fully calculated */ #define ETH_DMATXDESC_TER 0x00200000U /*!< Transmit End of Ring */ #define ETH_DMATXDESC_TCH 0x00100000U /*!< Second Address Chained */ #define ETH_DMATXDESC_TTSS 0x00020000U /*!< Tx Time Stamp Status */ @@ -761,25 +759,25 @@ typedef struct #define ETH_DMATXDESC_UF 0x00000002U /*!< Underflow Error: late data arrival from the memory */ #define ETH_DMATXDESC_DB 0x00000001U /*!< Deferred Bit */ -/** +/** * @brief Bit definition of TDES1 register - */ + */ #define ETH_DMATXDESC_TBS2 0x1FFF0000U /*!< Transmit Buffer2 Size */ #define ETH_DMATXDESC_TBS1 0x00001FFFU /*!< Transmit Buffer1 Size */ -/** +/** * @brief Bit definition of TDES2 register - */ + */ #define ETH_DMATXDESC_B1AP 0xFFFFFFFFU /*!< Buffer1 Address Pointer */ -/** +/** * @brief Bit definition of TDES3 register - */ + */ #define ETH_DMATXDESC_B2AP 0xFFFFFFFFU /*!< Buffer2 Address Pointer */ /** * @} - */ + */ /** @defgroup ETH_DMA_RX_Descriptor ETH DMA RX Descriptor * @{ */ @@ -797,9 +795,9 @@ typedef struct --------------------------------------------------------------------------------------------------------------------- */ -/** +/** * @brief Bit definition of RDES0 register: DMA Rx descriptor status register - */ + */ #define ETH_DMARXDESC_OWN 0x80000000U /*!< OWN bit: descriptor is owned by DMA engine */ #define ETH_DMARXDESC_AFM 0x40000000U /*!< DA Filter Fail for the rx frame */ #define ETH_DMARXDESC_FL 0x3FFF0000U /*!< Receive descriptor frame length */ @@ -810,8 +808,8 @@ typedef struct #define ETH_DMARXDESC_OE 0x00000800U /*!< Overflow Error: Frame was damaged due to buffer overflow */ #define ETH_DMARXDESC_VLAN 0x00000400U /*!< VLAN Tag: received frame is a VLAN frame */ #define ETH_DMARXDESC_FS 0x00000200U /*!< First descriptor of the frame */ -#define ETH_DMARXDESC_LS 0x00000100U /*!< Last descriptor of the frame */ -#define ETH_DMARXDESC_IPV4HCE 0x00000080U /*!< IPC Checksum Error: Rx Ipv4 header checksum error */ +#define ETH_DMARXDESC_LS 0x00000100U /*!< Last descriptor of the frame */ +#define ETH_DMARXDESC_IPV4HCE 0x00000080U /*!< IPC Checksum Error: Rx Ipv4 header checksum error */ #define ETH_DMARXDESC_LC 0x00000040U /*!< Late collision occurred during reception */ #define ETH_DMARXDESC_FT 0x00000020U /*!< Frame type - Ethernet, otherwise 802.3 */ #define ETH_DMARXDESC_RWT 0x00000010U /*!< Receive Watchdog Timeout: watchdog timer expired during reception */ @@ -820,40 +818,40 @@ typedef struct #define ETH_DMARXDESC_CE 0x00000002U /*!< CRC error */ #define ETH_DMARXDESC_MAMPCE 0x00000001U /*!< Rx MAC Address/Payload Checksum Error: Rx MAC address matched/ Rx Payload Checksum Error */ -/** +/** * @brief Bit definition of RDES1 register - */ + */ #define ETH_DMARXDESC_DIC 0x80000000U /*!< Disable Interrupt on Completion */ #define ETH_DMARXDESC_RBS2 0x1FFF0000U /*!< Receive Buffer2 Size */ #define ETH_DMARXDESC_RER 0x00008000U /*!< Receive End of Ring */ #define ETH_DMARXDESC_RCH 0x00004000U /*!< Second Address Chained */ #define ETH_DMARXDESC_RBS1 0x00001FFFU /*!< Receive Buffer1 Size */ -/** - * @brief Bit definition of RDES2 register - */ +/** + * @brief Bit definition of RDES2 register + */ #define ETH_DMARXDESC_B1AP 0xFFFFFFFFU /*!< Buffer1 Address Pointer */ -/** - * @brief Bit definition of RDES3 register - */ +/** + * @brief Bit definition of RDES3 register + */ #define ETH_DMARXDESC_B2AP 0xFFFFFFFFU /*!< Buffer2 Address Pointer */ /** * @} */ - /** @defgroup ETH_AutoNegotiation ETH AutoNegotiation - * @{ - */ +/** @defgroup ETH_AutoNegotiation ETH AutoNegotiation + * @{ + */ #define ETH_AUTONEGOTIATION_ENABLE 0x00000001U #define ETH_AUTONEGOTIATION_DISABLE 0x00000000U /** * @} */ -/** @defgroup ETH_Speed ETH Speed +/** @defgroup ETH_Speed ETH Speed * @{ - */ + */ #define ETH_SPEED_10M 0x00000000U #define ETH_SPEED_100M 0x00004000U @@ -862,7 +860,7 @@ typedef struct */ /** @defgroup ETH_Duplex_Mode ETH Duplex Mode * @{ - */ + */ #define ETH_MODE_FULLDUPLEX 0x00000800U #define ETH_MODE_HALFDUPLEX 0x00000000U /** @@ -870,7 +868,7 @@ typedef struct */ /** @defgroup ETH_Rx_Mode ETH Rx Mode * @{ - */ + */ #define ETH_RXPOLLING_MODE 0x00000000U #define ETH_RXINTERRUPT_MODE 0x00000001U /** @@ -879,7 +877,7 @@ typedef struct /** @defgroup ETH_Checksum_Mode ETH Checksum Mode * @{ - */ + */ #define ETH_CHECKSUM_BY_HARDWARE 0x00000000U #define ETH_CHECKSUM_BY_SOFTWARE 0x00000001U /** @@ -888,7 +886,7 @@ typedef struct /** @defgroup ETH_Media_Interface ETH Media Interface * @{ - */ + */ #define ETH_MEDIA_INTERFACE_MII 0x00000000U #define ETH_MEDIA_INTERFACE_RMII ((uint32_t)AFIO_MAPR_MII_RMII_SEL) @@ -898,7 +896,7 @@ typedef struct /** @defgroup ETH_Watchdog ETH Watchdog * @{ - */ + */ #define ETH_WATCHDOG_ENABLE 0x00000000U #define ETH_WATCHDOG_DISABLE 0x00800000U /** @@ -907,16 +905,16 @@ typedef struct /** @defgroup ETH_Jabber ETH Jabber * @{ - */ + */ #define ETH_JABBER_ENABLE 0x00000000U #define ETH_JABBER_DISABLE 0x00400000U /** * @} */ -/** @defgroup ETH_Inter_Frame_Gap ETH Inter Frame Gap +/** @defgroup ETH_Inter_Frame_Gap ETH Inter Frame Gap * @{ - */ + */ #define ETH_INTERFRAMEGAP_96BIT 0x00000000U /*!< minimum IFG between frames during transmission is 96Bit */ #define ETH_INTERFRAMEGAP_88BIT 0x00020000U /*!< minimum IFG between frames during transmission is 88Bit */ #define ETH_INTERFRAMEGAP_80BIT 0x00040000U /*!< minimum IFG between frames during transmission is 80Bit */ @@ -931,25 +929,25 @@ typedef struct /** @defgroup ETH_Carrier_Sense ETH Carrier Sense * @{ - */ + */ #define ETH_CARRIERSENCE_ENABLE 0x00000000U #define ETH_CARRIERSENCE_DISABLE 0x00010000U /** * @} */ -/** @defgroup ETH_Receive_Own ETH Receive Own +/** @defgroup ETH_Receive_Own ETH Receive Own * @{ - */ + */ #define ETH_RECEIVEOWN_ENABLE 0x00000000U #define ETH_RECEIVEOWN_DISABLE 0x00002000U /** * @} */ -/** @defgroup ETH_Loop_Back_Mode ETH Loop Back Mode +/** @defgroup ETH_Loop_Back_Mode ETH Loop Back Mode * @{ - */ + */ #define ETH_LOOPBACKMODE_ENABLE 0x00001000U #define ETH_LOOPBACKMODE_DISABLE 0x00000000U /** @@ -958,7 +956,7 @@ typedef struct /** @defgroup ETH_Checksum_Offload ETH Checksum Offload * @{ - */ + */ #define ETH_CHECKSUMOFFLAOD_ENABLE 0x00000400U #define ETH_CHECKSUMOFFLAOD_DISABLE 0x00000000U /** @@ -967,7 +965,7 @@ typedef struct /** @defgroup ETH_Retry_Transmission ETH Retry Transmission * @{ - */ + */ #define ETH_RETRYTRANSMISSION_ENABLE 0x00000000U #define ETH_RETRYTRANSMISSION_DISABLE 0x00000200U /** @@ -976,7 +974,7 @@ typedef struct /** @defgroup ETH_Automatic_Pad_CRC_Strip ETH Automatic Pad CRC Strip * @{ - */ + */ #define ETH_AUTOMATICPADCRCSTRIP_ENABLE 0x00000080U #define ETH_AUTOMATICPADCRCSTRIP_DISABLE 0x00000000U /** @@ -985,7 +983,7 @@ typedef struct /** @defgroup ETH_Back_Off_Limit ETH Back Off Limit * @{ - */ + */ #define ETH_BACKOFFLIMIT_10 0x00000000U #define ETH_BACKOFFLIMIT_8 0x00000020U #define ETH_BACKOFFLIMIT_4 0x00000040U @@ -1005,7 +1003,7 @@ typedef struct /** @defgroup ETH_Receive_All ETH Receive All * @{ - */ + */ #define ETH_RECEIVEALL_ENABLE 0x80000000U #define ETH_RECEIVEAll_DISABLE 0x00000000U /** @@ -1014,7 +1012,7 @@ typedef struct /** @defgroup ETH_Source_Addr_Filter ETH Source Addr Filter * @{ - */ + */ #define ETH_SOURCEADDRFILTER_NORMAL_ENABLE 0x00000200U #define ETH_SOURCEADDRFILTER_INVERSE_ENABLE 0x00000300U #define ETH_SOURCEADDRFILTER_DISABLE 0x00000000U @@ -1024,17 +1022,17 @@ typedef struct /** @defgroup ETH_Pass_Control_Frames ETH Pass Control Frames * @{ - */ + */ #define ETH_PASSCONTROLFRAMES_BLOCKALL 0x00000040U /*!< MAC filters all control frames from reaching the application */ #define ETH_PASSCONTROLFRAMES_FORWARDALL 0x00000080U /*!< MAC forwards all control frames to application even if they fail the Address Filter */ -#define ETH_PASSCONTROLFRAMES_FORWARDPASSEDADDRFILTER 0x000000C0U /*!< MAC forwards control frames that pass the Address Filter. */ +#define ETH_PASSCONTROLFRAMES_FORWARDPASSEDADDRFILTER 0x000000C0U /*!< MAC forwards control frames that pass the Address Filter. */ /** * @} */ /** @defgroup ETH_Broadcast_Frames_Reception ETH Broadcast Frames Reception * @{ - */ + */ #define ETH_BROADCASTFRAMESRECEPTION_ENABLE 0x00000000U #define ETH_BROADCASTFRAMESRECEPTION_DISABLE 0x00000020U /** @@ -1043,7 +1041,7 @@ typedef struct /** @defgroup ETH_Destination_Addr_Filter ETH Destination Addr Filter * @{ - */ + */ #define ETH_DESTINATIONADDRFILTER_NORMAL 0x00000000U #define ETH_DESTINATIONADDRFILTER_INVERSE 0x00000008U /** @@ -1052,7 +1050,7 @@ typedef struct /** @defgroup ETH_Promiscuous_Mode ETH Promiscuous Mode * @{ - */ + */ #define ETH_PROMISCUOUS_MODE_ENABLE 0x00000001U #define ETH_PROMISCUOUS_MODE_DISABLE 0x00000000U /** @@ -1061,7 +1059,7 @@ typedef struct /** @defgroup ETH_Multicast_Frames_Filter ETH Multicast Frames Filter * @{ - */ + */ #define ETH_MULTICASTFRAMESFILTER_PERFECTHASHTABLE 0x00000404U #define ETH_MULTICASTFRAMESFILTER_HASHTABLE 0x00000004U #define ETH_MULTICASTFRAMESFILTER_PERFECT 0x00000000U @@ -1072,7 +1070,7 @@ typedef struct /** @defgroup ETH_Unicast_Frames_Filter ETH Unicast Frames Filter * @{ - */ + */ #define ETH_UNICASTFRAMESFILTER_PERFECTHASHTABLE 0x00000402U #define ETH_UNICASTFRAMESFILTER_HASHTABLE 0x00000002U #define ETH_UNICASTFRAMESFILTER_PERFECT 0x00000000U @@ -1080,9 +1078,9 @@ typedef struct * @} */ -/** @defgroup ETH_Zero_Quanta_Pause ETH Zero Quanta Pause +/** @defgroup ETH_Zero_Quanta_Pause ETH Zero Quanta Pause * @{ - */ + */ #define ETH_ZEROQUANTAPAUSE_ENABLE 0x00000000U #define ETH_ZEROQUANTAPAUSE_DISABLE 0x00000080U /** @@ -1091,7 +1089,7 @@ typedef struct /** @defgroup ETH_Pause_Low_Threshold ETH Pause Low Threshold * @{ - */ + */ #define ETH_PAUSELOWTHRESHOLD_MINUS4 0x00000000U /*!< Pause time minus 4 slot times */ #define ETH_PAUSELOWTHRESHOLD_MINUS28 0x00000010U /*!< Pause time minus 28 slot times */ #define ETH_PAUSELOWTHRESHOLD_MINUS144 0x00000020U /*!< Pause time minus 144 slot times */ @@ -1102,7 +1100,7 @@ typedef struct /** @defgroup ETH_Unicast_Pause_Frame_Detect ETH Unicast Pause Frame Detect * @{ - */ + */ #define ETH_UNICASTPAUSEFRAMEDETECT_ENABLE 0x00000008U #define ETH_UNICASTPAUSEFRAMEDETECT_DISABLE 0x00000000U /** @@ -1111,7 +1109,7 @@ typedef struct /** @defgroup ETH_Receive_Flow_Control ETH Receive Flow Control * @{ - */ + */ #define ETH_RECEIVEFLOWCONTROL_ENABLE 0x00000004U #define ETH_RECEIVEFLOWCONTROL_DISABLE 0x00000000U /** @@ -1120,7 +1118,7 @@ typedef struct /** @defgroup ETH_Transmit_Flow_Control ETH Transmit Flow Control * @{ - */ + */ #define ETH_TRANSMITFLOWCONTROL_ENABLE 0x00000002U #define ETH_TRANSMITFLOWCONTROL_DISABLE 0x00000000U /** @@ -1129,7 +1127,7 @@ typedef struct /** @defgroup ETH_VLAN_Tag_Comparison ETH VLAN Tag Comparison * @{ - */ + */ #define ETH_VLANTAGCOMPARISON_12BIT 0x00010000U #define ETH_VLANTAGCOMPARISON_16BIT 0x00000000U /** @@ -1138,7 +1136,7 @@ typedef struct /** @defgroup ETH_MAC_addresses ETH MAC addresses * @{ - */ + */ #define ETH_MAC_ADDRESS0 0x00000000U #define ETH_MAC_ADDRESS1 0x00000008U #define ETH_MAC_ADDRESS2 0x00000010U @@ -1147,9 +1145,9 @@ typedef struct * @} */ -/** @defgroup ETH_MAC_addresses_filter_SA_DA ETH MAC addresses filter SA DA +/** @defgroup ETH_MAC_addresses_filter_SA_DA ETH MAC addresses filter SA DA * @{ - */ + */ #define ETH_MAC_ADDRESSFILTER_SA 0x00000000U #define ETH_MAC_ADDRESSFILTER_DA 0x00000008U /** @@ -1158,7 +1156,7 @@ typedef struct /** @defgroup ETH_MAC_addresses_filter_Mask_bytes ETH MAC addresses filter Mask bytes * @{ - */ + */ #define ETH_MAC_ADDRESSMASK_BYTE6 0x20000000U /*!< Mask MAC Address high reg bits [15:8] */ #define ETH_MAC_ADDRESSMASK_BYTE5 0x10000000U /*!< Mask MAC Address high reg bits [7:0] */ #define ETH_MAC_ADDRESSMASK_BYTE4 0x08000000U /*!< Mask MAC Address low reg bits [31:24] */ @@ -1171,7 +1169,7 @@ typedef struct /** @defgroup ETH_Drop_TCP_IP_Checksum_Error_Frame ETH Drop TCP IP Checksum Error Frame * @{ - */ + */ #define ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE 0x00000000U #define ETH_DROPTCPIPCHECKSUMERRORFRAME_DISABLE 0x04000000U /** @@ -1180,7 +1178,7 @@ typedef struct /** @defgroup ETH_Receive_Store_Forward ETH Receive Store Forward * @{ - */ + */ #define ETH_RECEIVESTOREFORWARD_ENABLE 0x02000000U #define ETH_RECEIVESTOREFORWARD_DISABLE 0x00000000U /** @@ -1189,7 +1187,7 @@ typedef struct /** @defgroup ETH_Flush_Received_Frame ETH Flush Received Frame * @{ - */ + */ #define ETH_FLUSHRECEIVEDFRAME_ENABLE 0x00000000U #define ETH_FLUSHRECEIVEDFRAME_DISABLE 0x01000000U /** @@ -1198,7 +1196,7 @@ typedef struct /** @defgroup ETH_Transmit_Store_Forward ETH Transmit Store Forward * @{ - */ + */ #define ETH_TRANSMITSTOREFORWARD_ENABLE 0x00200000U #define ETH_TRANSMITSTOREFORWARD_DISABLE 0x00000000U /** @@ -1207,7 +1205,7 @@ typedef struct /** @defgroup ETH_Transmit_Threshold_Control ETH Transmit Threshold Control * @{ - */ + */ #define ETH_TRANSMITTHRESHOLDCONTROL_64BYTES 0x00000000U /*!< threshold level of the MTL Transmit FIFO is 64 Bytes */ #define ETH_TRANSMITTHRESHOLDCONTROL_128BYTES 0x00004000U /*!< threshold level of the MTL Transmit FIFO is 128 Bytes */ #define ETH_TRANSMITTHRESHOLDCONTROL_192BYTES 0x00008000U /*!< threshold level of the MTL Transmit FIFO is 192 Bytes */ @@ -1222,7 +1220,7 @@ typedef struct /** @defgroup ETH_Forward_Error_Frames ETH Forward Error Frames * @{ - */ + */ #define ETH_FORWARDERRORFRAMES_ENABLE 0x00000080U #define ETH_FORWARDERRORFRAMES_DISABLE 0x00000000U /** @@ -1231,7 +1229,7 @@ typedef struct /** @defgroup ETH_Forward_Undersized_Good_Frames ETH Forward Undersized Good Frames * @{ - */ + */ #define ETH_FORWARDUNDERSIZEDGOODFRAMES_ENABLE 0x00000040U #define ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE 0x00000000U /** @@ -1240,7 +1238,7 @@ typedef struct /** @defgroup ETH_Receive_Threshold_Control ETH Receive Threshold Control * @{ - */ + */ #define ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES 0x00000000U /*!< threshold level of the MTL Receive FIFO is 64 Bytes */ #define ETH_RECEIVEDTHRESHOLDCONTROL_32BYTES 0x00000008U /*!< threshold level of the MTL Receive FIFO is 32 Bytes */ #define ETH_RECEIVEDTHRESHOLDCONTROL_96BYTES 0x00000010U /*!< threshold level of the MTL Receive FIFO is 96 Bytes */ @@ -1251,16 +1249,16 @@ typedef struct /** @defgroup ETH_Second_Frame_Operate ETH Second Frame Operate * @{ - */ + */ #define ETH_SECONDFRAMEOPERARTE_ENABLE 0x00000004U #define ETH_SECONDFRAMEOPERARTE_DISABLE 0x00000000U /** * @} */ -/** @defgroup ETH_Address_Aligned_Beats ETH Address Aligned Beats +/** @defgroup ETH_Address_Aligned_Beats ETH Address Aligned Beats * @{ - */ + */ #define ETH_ADDRESSALIGNEDBEATS_ENABLE 0x02000000U #define ETH_ADDRESSALIGNEDBEATS_DISABLE 0x00000000U /** @@ -1269,7 +1267,7 @@ typedef struct /** @defgroup ETH_Fixed_Burst ETH Fixed Burst * @{ - */ + */ #define ETH_FIXEDBURST_ENABLE 0x00010000U #define ETH_FIXEDBURST_DISABLE 0x00000000U /** @@ -1278,7 +1276,7 @@ typedef struct /** @defgroup ETH_Rx_DMA_Burst_Length ETH Rx DMA Burst Length * @{ - */ + */ #define ETH_RXDMABURSTLENGTH_1BEAT 0x00020000U /*!< maximum number of beats to be transferred in one RxDMA transaction is 1 */ #define ETH_RXDMABURSTLENGTH_2BEAT 0x00040000U /*!< maximum number of beats to be transferred in one RxDMA transaction is 2 */ #define ETH_RXDMABURSTLENGTH_4BEAT 0x00080000U /*!< maximum number of beats to be transferred in one RxDMA transaction is 4 */ @@ -1297,7 +1295,7 @@ typedef struct /** @defgroup ETH_Tx_DMA_Burst_Length ETH Tx DMA Burst Length * @{ - */ + */ #define ETH_TXDMABURSTLENGTH_1BEAT 0x00000100U /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 1 */ #define ETH_TXDMABURSTLENGTH_2BEAT 0x00000200U /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 2 */ #define ETH_TXDMABURSTLENGTH_4BEAT 0x00000400U /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 4 */ @@ -1317,7 +1315,7 @@ typedef struct /** @defgroup ETH_DMA_Arbitration ETH DMA Arbitration * @{ - */ + */ #define ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1 0x00000000U #define ETH_DMAARBITRATION_ROUNDROBIN_RXTX_2_1 0x00004000U #define ETH_DMAARBITRATION_ROUNDROBIN_RXTX_3_1 0x00008000U @@ -1329,7 +1327,7 @@ typedef struct /** @defgroup ETH_DMA_Tx_descriptor_segment ETH DMA Tx descriptor segment * @{ - */ + */ #define ETH_DMATXDESC_LASTSEGMENTS 0x40000000U /*!< Last Segment */ #define ETH_DMATXDESC_FIRSTSEGMENT 0x20000000U /*!< First Segment */ /** @@ -1338,7 +1336,7 @@ typedef struct /** @defgroup ETH_DMA_Tx_descriptor_Checksum_Insertion_Control ETH DMA Tx descriptor Checksum Insertion Control * @{ - */ + */ #define ETH_DMATXDESC_CHECKSUMBYPASS 0x00000000U /*!< Checksum engine bypass */ #define ETH_DMATXDESC_CHECKSUMIPV4HEADER 0x00400000U /*!< IPv4 header checksum insertion */ #define ETH_DMATXDESC_CHECKSUMTCPUDPICMPSEGMENT 0x00800000U /*!< TCP/UDP/ICMP checksum insertion. Pseudo header checksum is assumed to be present */ @@ -1347,9 +1345,9 @@ typedef struct * @} */ -/** @defgroup ETH_DMA_Rx_descriptor_buffers ETH DMA Rx descriptor buffers +/** @defgroup ETH_DMA_Rx_descriptor_buffers ETH DMA Rx descriptor buffers * @{ - */ + */ #define ETH_DMARXDESC_BUFFER1 0x00000000U /*!< DMA Rx Desc Buffer1 */ #define ETH_DMARXDESC_BUFFER2 0x00000001U /*!< DMA Rx Desc Buffer2 */ /** @@ -1358,7 +1356,7 @@ typedef struct /** @defgroup ETH_PMT_Flags ETH PMT Flags * @{ - */ + */ #define ETH_PMT_FLAG_WUFFRPR 0x80000000U /*!< Wake-Up Frame Filter Register Pointer Reset */ #define ETH_PMT_FLAG_WUFR 0x00000040U /*!< Wake-Up Frame Received */ #define ETH_PMT_FLAG_MPR 0x00000020U /*!< Magic Packet Received */ @@ -1368,7 +1366,7 @@ typedef struct /** @defgroup ETH_MMC_Tx_Interrupts ETH MMC Tx Interrupts * @{ - */ + */ #define ETH_MMC_IT_TGF 0x00200000U /*!< When Tx good frame counter reaches half the maximum value */ #define ETH_MMC_IT_TGFMSC 0x00008000U /*!< When Tx good multi col counter reaches half the maximum value */ #define ETH_MMC_IT_TGFSC 0x00004000U /*!< When Tx good single col counter reaches half the maximum value */ @@ -1388,7 +1386,7 @@ typedef struct /** @defgroup ETH_MAC_Flags ETH MAC Flags * @{ - */ + */ #define ETH_MAC_FLAG_TST 0x00000200U /*!< Time stamp trigger flag (on MAC) */ #define ETH_MAC_FLAG_MMCT 0x00000040U /*!< MMC transmit flag */ #define ETH_MAC_FLAG_MMCR 0x00000020U /*!< MMC receive flag */ @@ -1400,7 +1398,7 @@ typedef struct /** @defgroup ETH_DMA_Flags ETH DMA Flags * @{ - */ + */ #define ETH_DMA_FLAG_TST 0x20000000U /*!< Time-stamp trigger interrupt (on DMA) */ #define ETH_DMA_FLAG_PMT 0x10000000U /*!< PMT interrupt (on DMA) */ #define ETH_DMA_FLAG_MMC 0x08000000U /*!< MMC interrupt (on DMA) */ @@ -1426,9 +1424,9 @@ typedef struct * @} */ -/** @defgroup ETH_MAC_Interrupts ETH MAC Interrupts +/** @defgroup ETH_MAC_Interrupts ETH MAC Interrupts * @{ - */ + */ #define ETH_MAC_IT_TST 0x00000200U /*!< Time stamp trigger interrupt (on MAC) */ #define ETH_MAC_IT_MMCT 0x00000040U /*!< MMC transmit interrupt */ #define ETH_MAC_IT_MMCR 0x00000020U /*!< MMC receive interrupt */ @@ -1438,9 +1436,9 @@ typedef struct * @} */ -/** @defgroup ETH_DMA_Interrupts ETH DMA Interrupts +/** @defgroup ETH_DMA_Interrupts ETH DMA Interrupts * @{ - */ + */ #define ETH_DMA_IT_TST 0x20000000U /*!< Time-stamp trigger interrupt (on DMA) */ #define ETH_DMA_IT_PMT 0x10000000U /*!< PMT interrupt (on DMA) */ #define ETH_DMA_IT_MMC 0x08000000U /*!< MMC interrupt (on DMA) */ @@ -1463,9 +1461,9 @@ typedef struct * @} */ -/** @defgroup ETH_DMA_transmit_process_state ETH DMA transmit process state +/** @defgroup ETH_DMA_transmit_process_state ETH DMA transmit process state * @{ - */ + */ #define ETH_DMA_TRANSMITPROCESS_STOPPED 0x00000000U /*!< Stopped - Reset or Stop Tx Command issued */ #define ETH_DMA_TRANSMITPROCESS_FETCHING 0x00100000U /*!< Running - fetching the Tx descriptor */ #define ETH_DMA_TRANSMITPROCESS_WAITING 0x00200000U /*!< Running - waiting for status */ @@ -1475,12 +1473,12 @@ typedef struct /** * @} - */ + */ -/** @defgroup ETH_DMA_receive_process_state ETH DMA receive process state +/** @defgroup ETH_DMA_receive_process_state ETH DMA receive process state * @{ - */ + */ #define ETH_DMA_RECEIVEPROCESS_STOPPED 0x00000000U /*!< Stopped - Reset or Stop Rx Command issued */ #define ETH_DMA_RECEIVEPROCESS_FETCHING 0x00020000U /*!< Running - fetching the Rx descriptor */ #define ETH_DMA_RECEIVEPROCESS_WAITING 0x00060000U /*!< Running - waiting for packet */ @@ -1494,16 +1492,16 @@ typedef struct /** @defgroup ETH_DMA_overflow ETH DMA overflow * @{ - */ + */ #define ETH_DMA_OVERFLOW_RXFIFOCOUNTER 0x10000000U /*!< Overflow bit for FIFO overflow counter */ #define ETH_DMA_OVERFLOW_MISSEDFRAMECOUNTER 0x00010000U /*!< Overflow bit for missed frame counter */ /** * @} - */ + */ /** @defgroup ETH_EXTI_LINE_WAKEUP ETH EXTI LINE WAKEUP * @{ - */ + */ #define ETH_EXTI_LINE_WAKEUP 0x00080000U /*!< External interrupt line 19 Connected to the ETH EXTI Line */ /** @@ -1519,14 +1517,14 @@ typedef struct * @brief macros to handle interrupts and specific clock configurations * @{ */ - + /** @brief Reset ETH handle state * @param __HANDLE__: specifies the ETH handle. * @retval None */ #define __HAL_ETH_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_ETH_STATE_RESET) -/** +/** * @brief Checks whether the specified ETHERNET DMA Tx Desc flag is set or not. * @param __HANDLE__: ETH Handle * @param __FLAG__: specifies the flag of TDES0 to check. @@ -1565,7 +1563,7 @@ typedef struct /** * @brief Returns the specified ETHERNET DMA Tx Desc collision count. - * @param __HANDLE__: ETH Handle + * @param __HANDLE__: ETH Handle * @retval The Transmit descriptor collision counter value. */ #define __HAL_ETH_DMATXDESC_GET_COLLISION_COUNT(__HANDLE__) (((__HANDLE__)->TxDesc->Status & ETH_DMATXDESC_CC) >> ETH_DMATXDESC_COLLISION_COUNTSHIFT) @@ -1579,21 +1577,21 @@ typedef struct /** * @brief Enables the specified DMA Tx Desc Transmit interrupt. - * @param __HANDLE__: ETH Handle + * @param __HANDLE__: ETH Handle * @retval None */ #define __HAL_ETH_DMATXDESC_ENABLE_IT(__HANDLE__) ((__HANDLE__)->TxDesc->Status |= ETH_DMATXDESC_IC) /** * @brief Disables the specified DMA Tx Desc Transmit interrupt. - * @param __HANDLE__: ETH Handle + * @param __HANDLE__: ETH Handle * @retval None */ #define __HAL_ETH_DMATXDESC_DISABLE_IT(__HANDLE__) ((__HANDLE__)->TxDesc->Status &= ~ETH_DMATXDESC_IC) /** * @brief Selects the specified ETHERNET DMA Tx Desc Checksum Insertion. - * @param __HANDLE__: ETH Handle + * @param __HANDLE__: ETH Handle * @param __CHECKSUM__: specifies is the DMA Tx desc checksum insertion. * This parameter can be one of the following values: * @arg ETH_DMATXDESC_CHECKSUMBYPASS : Checksum bypass @@ -1606,40 +1604,40 @@ typedef struct /** * @brief Enables the DMA Tx Desc CRC. - * @param __HANDLE__: ETH Handle + * @param __HANDLE__: ETH Handle * @retval None */ #define __HAL_ETH_DMATXDESC_CRC_ENABLE(__HANDLE__) ((__HANDLE__)->TxDesc->Status &= ~ETH_DMATXDESC_DC) /** * @brief Disables the DMA Tx Desc CRC. - * @param __HANDLE__: ETH Handle + * @param __HANDLE__: ETH Handle * @retval None */ #define __HAL_ETH_DMATXDESC_CRC_DISABLE(__HANDLE__) ((__HANDLE__)->TxDesc->Status |= ETH_DMATXDESC_DC) /** * @brief Enables the DMA Tx Desc padding for frame shorter than 64 bytes. - * @param __HANDLE__: ETH Handle + * @param __HANDLE__: ETH Handle * @retval None */ #define __HAL_ETH_DMATXDESC_SHORT_FRAME_PADDING_ENABLE(__HANDLE__) ((__HANDLE__)->TxDesc->Status &= ~ETH_DMATXDESC_DP) /** * @brief Disables the DMA Tx Desc padding for frame shorter than 64 bytes. - * @param __HANDLE__: ETH Handle + * @param __HANDLE__: ETH Handle * @retval None */ #define __HAL_ETH_DMATXDESC_SHORT_FRAME_PADDING_DISABLE(__HANDLE__) ((__HANDLE__)->TxDesc->Status |= ETH_DMATXDESC_DP) -/** +/** * @brief Enables the specified ETHERNET MAC interrupts. * @param __HANDLE__ : ETH Handle * @param __INTERRUPT__: specifies the ETHERNET MAC interrupt sources to be * enabled or disabled. * This parameter can be any combination of the following values: - * @arg ETH_MAC_IT_TST : Time stamp trigger interrupt - * @arg ETH_MAC_IT_PMT : PMT interrupt + * @arg ETH_MAC_IT_TST : Time stamp trigger interrupt + * @arg ETH_MAC_IT_PMT : PMT interrupt * @retval None */ #define __HAL_ETH_MAC_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->MACIMR |= (__INTERRUPT__)) @@ -1650,7 +1648,7 @@ typedef struct * @param __INTERRUPT__: specifies the ETHERNET MAC interrupt sources to be * enabled or disabled. * This parameter can be any combination of the following values: - * @arg ETH_MAC_IT_TST : Time stamp trigger interrupt + * @arg ETH_MAC_IT_TST : Time stamp trigger interrupt * @arg ETH_MAC_IT_PMT : PMT interrupt * @retval None */ @@ -1689,16 +1687,16 @@ typedef struct * @param __HANDLE__: ETH Handle * @param __FLAG__: specifies the flag to check. * This parameter can be one of the following values: - * @arg ETH_MAC_FLAG_TST : Time stamp trigger flag - * @arg ETH_MAC_FLAG_MMCT : MMC transmit flag - * @arg ETH_MAC_FLAG_MMCR : MMC receive flag - * @arg ETH_MAC_FLAG_MMC : MMC flag - * @arg ETH_MAC_FLAG_PMT : PMT flag + * @arg ETH_MAC_FLAG_TST : Time stamp trigger flag + * @arg ETH_MAC_FLAG_MMCT : MMC transmit flag + * @arg ETH_MAC_FLAG_MMCR : MMC receive flag + * @arg ETH_MAC_FLAG_MMC : MMC flag + * @arg ETH_MAC_FLAG_PMT : PMT flag * @retval The state of ETHERNET MAC flag. */ #define __HAL_ETH_MAC_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->MACSR &( __FLAG__)) == ( __FLAG__)) -/** +/** * @brief Enables the specified ETHERNET DMA interrupts. * @param __HANDLE__ : ETH Handle * @param __INTERRUPT__: specifies the ETHERNET DMA interrupt sources to be @@ -1754,12 +1752,12 @@ typedef struct /** * @brief Set the DMA Receive status watchdog timer register value * @param __HANDLE__: ETH Handle - * @param __VALUE__: DMA Receive status watchdog timer register value + * @param __VALUE__: DMA Receive status watchdog timer register value * @retval None */ #define __HAL_ETH_SET_RECEIVE_WATCHDOG_TIMER(__HANDLE__, __VALUE__) ((__HANDLE__)->Instance->DMARSWTR = (__VALUE__)) -/** +/** * @brief Enables any unicast packet filtered by the MAC address * recognition to be a wake-up frame. * @param __HANDLE__: ETH Handle. @@ -1822,14 +1820,14 @@ typedef struct * @param __HANDLE__: ETH Handle. * @param __FLAG__: specifies the flag to check. * This parameter can be one of the following values: - * @arg ETH_PMT_FLAG_WUFFRPR : Wake-Up Frame Filter Register Pointer Reset - * @arg ETH_PMT_FLAG_WUFR : Wake-Up Frame Received + * @arg ETH_PMT_FLAG_WUFFRPR : Wake-Up Frame Filter Register Pointer Reset + * @arg ETH_PMT_FLAG_WUFR : Wake-Up Frame Received * @arg ETH_PMT_FLAG_MPR : Magic Packet Received * @retval The new state of ETHERNET PMT Flag (SET or RESET). */ #define __HAL_ETH_GET_PMT_FLAG_STATUS(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->MACPMTCSR &( __FLAG__)) == ( __FLAG__)) -/** +/** * @brief Preset and Initialize the MMC counters to almost-full value: 0xFFFF_FFF0 (full - 16) * @param __HANDLE__: ETH Handle. * @retval None @@ -1897,9 +1895,9 @@ typedef struct * @brief Enables the specified ETHERNET MMC Rx interrupts. * @param __HANDLE__: ETH Handle. * @param __INTERRUPT__: specifies the ETHERNET MMC interrupt sources to be enabled or disabled. - * This parameter can be one of the following values: - * @arg ETH_MMC_IT_RGUF : When Rx good unicast frames counter reaches half the maximum value - * @arg ETH_MMC_IT_RFAE : When Rx alignment error counter reaches half the maximum value + * This parameter can be one of the following values: + * @arg ETH_MMC_IT_RGUF : When Rx good unicast frames counter reaches half the maximum value + * @arg ETH_MMC_IT_RFAE : When Rx alignment error counter reaches half the maximum value * @arg ETH_MMC_IT_RFCE : When Rx crc error counter reaches half the maximum value * @retval None */ @@ -1908,9 +1906,9 @@ typedef struct * @brief Disables the specified ETHERNET MMC Rx interrupts. * @param __HANDLE__: ETH Handle. * @param __INTERRUPT__: specifies the ETHERNET MMC interrupt sources to be enabled or disabled. - * This parameter can be one of the following values: - * @arg ETH_MMC_IT_RGUF : When Rx good unicast frames counter reaches half the maximum value - * @arg ETH_MMC_IT_RFAE : When Rx alignment error counter reaches half the maximum value + * This parameter can be one of the following values: + * @arg ETH_MMC_IT_RGUF : When Rx good unicast frames counter reaches half the maximum value + * @arg ETH_MMC_IT_RFAE : When Rx alignment error counter reaches half the maximum value * @arg ETH_MMC_IT_RFCE : When Rx crc error counter reaches half the maximum value * @retval None */ @@ -1919,10 +1917,10 @@ typedef struct * @brief Enables the specified ETHERNET MMC Tx interrupts. * @param __HANDLE__: ETH Handle. * @param __INTERRUPT__: specifies the ETHERNET MMC interrupt sources to be enabled or disabled. - * This parameter can be one of the following values: - * @arg ETH_MMC_IT_TGF : When Tx good frame counter reaches half the maximum value - * @arg ETH_MMC_IT_TGFMSC: When Tx good multi col counter reaches half the maximum value - * @arg ETH_MMC_IT_TGFSC : When Tx good single col counter reaches half the maximum value + * This parameter can be one of the following values: + * @arg ETH_MMC_IT_TGF : When Tx good frame counter reaches half the maximum value + * @arg ETH_MMC_IT_TGFMSC: When Tx good multi col counter reaches half the maximum value + * @arg ETH_MMC_IT_TGFSC : When Tx good single col counter reaches half the maximum value * @retval None */ #define __HAL_ETH_MMC_TX_IT_ENABLE(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->MMCRIMR &= ~ (__INTERRUPT__)) @@ -1931,10 +1929,10 @@ typedef struct * @brief Disables the specified ETHERNET MMC Tx interrupts. * @param __HANDLE__: ETH Handle. * @param __INTERRUPT__: specifies the ETHERNET MMC interrupt sources to be enabled or disabled. - * This parameter can be one of the following values: - * @arg ETH_MMC_IT_TGF : When Tx good frame counter reaches half the maximum value - * @arg ETH_MMC_IT_TGFMSC: When Tx good multi col counter reaches half the maximum value - * @arg ETH_MMC_IT_TGFSC : When Tx good single col counter reaches half the maximum value + * This parameter can be one of the following values: + * @arg ETH_MMC_IT_TGF : When Tx good frame counter reaches half the maximum value + * @arg ETH_MMC_IT_TGFMSC: When Tx good multi col counter reaches half the maximum value + * @arg ETH_MMC_IT_TGFSC : When Tx good single col counter reaches half the maximum value * @retval None */ #define __HAL_ETH_MMC_TX_IT_DISABLE(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->MMCRIMR |= (__INTERRUPT__)) @@ -2039,7 +2037,7 @@ HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth); HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth); void HAL_ETH_MspInit(ETH_HandleTypeDef *heth); void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth); -HAL_StatusTypeDef HAL_ETH_DMATxDescListInit(ETH_HandleTypeDef *heth, ETH_DMADescTypeDef *DMATxDescTab, uint8_t* TxBuff, uint32_t TxBuffCount); +HAL_StatusTypeDef HAL_ETH_DMATxDescListInit(ETH_HandleTypeDef *heth, ETH_DMADescTypeDef *DMATxDescTab, uint8_t *TxBuff, uint32_t TxBuffCount); HAL_StatusTypeDef HAL_ETH_DMARxDescListInit(ETH_HandleTypeDef *heth, ETH_DMADescTypeDef *DMARxDescTab, uint8_t *RxBuff, uint32_t RxBuffCount); /** @@ -2078,7 +2076,7 @@ HAL_StatusTypeDef HAL_ETH_ConfigMAC(ETH_HandleTypeDef *heth, ETH_MACInitTypeDef HAL_StatusTypeDef HAL_ETH_ConfigDMA(ETH_HandleTypeDef *heth, ETH_DMAInitTypeDef *dmaconf); /** * @} - */ + */ /* Peripheral State functions ************************************************/ @@ -2102,7 +2100,7 @@ HAL_ETH_StateTypeDef HAL_ETH_GetState(ETH_HandleTypeDef *heth); /** * @} */ - + #ifdef __cplusplus } #endif diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_flash.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_flash.c index 2bbb626f145b..adfdfa1f0e72 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_flash.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_flash.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_flash.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief FLASH HAL module driver. * This file provides firmware functions to manage the following * functionalities of the internal FLASH memory: @@ -674,31 +672,36 @@ __weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue) */ HAL_StatusTypeDef HAL_FLASH_Unlock(void) { - if (HAL_IS_BIT_SET(FLASH->CR, FLASH_CR_LOCK)) + HAL_StatusTypeDef status = HAL_OK; + + if(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != RESET) { /* Authorize the FLASH Registers access */ WRITE_REG(FLASH->KEYR, FLASH_KEY1); WRITE_REG(FLASH->KEYR, FLASH_KEY2); - } - else - { - return HAL_ERROR; - } + /* Verify Flash is unlocked */ + if(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != RESET) + { + status = HAL_ERROR; + } + } #if defined(FLASH_BANK2_END) - if (HAL_IS_BIT_SET(FLASH->CR2, FLASH_CR2_LOCK)) + if(READ_BIT(FLASH->CR2, FLASH_CR2_LOCK) != RESET) { /* Authorize the FLASH BANK2 Registers access */ WRITE_REG(FLASH->KEYR2, FLASH_KEY1); WRITE_REG(FLASH->KEYR2, FLASH_KEY2); + + /* Verify Flash BANK2 is unlocked */ + if(READ_BIT(FLASH->CR2, FLASH_CR2_LOCK) != RESET) + { + status = HAL_ERROR; + } } - else - { - return HAL_ERROR; - } - #endif /* FLASH_BANK2_END */ - return HAL_OK; + + return status; } /** diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_flash.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_flash.h index 3016b5495913..5d349e0d6b5f 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_flash.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_flash.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_flash.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of Flash HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_flash_ex.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_flash_ex.c index 1662f173d155..5c75678c48d7 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_flash_ex.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_flash_ex.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_flash_ex.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Extended FLASH HAL module driver. * * This file provides firmware functions to manage the following diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_flash_ex.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_flash_ex.h index 9dd06f54b238..d0dc716ace2b 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_flash_ex.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_flash_ex.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_flash_ex.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of Flash HAL Extended module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_gpio.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_gpio.c index 1d09efbfb30d..711d31ee9db8 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_gpio.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_gpio.c @@ -2,10 +2,8 @@ ****************************************************************************** * @file stm32f1xx_hal_gpio.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief GPIO HAL module driver. - * This file provides firmware functions to manage the following + * This file provides firmware functions to manage the following * functionalities of the General Purpose Input/Output (GPIO) peripheral: * + Initialization and de-initialization functions * + IO operation functions @@ -14,80 +12,80 @@ ============================================================================== ##### GPIO Peripheral features ##### ============================================================================== - [..] + [..] Subject to the specific hardware characteristics of each I/O port listed in the datasheet, each port bit of the General Purpose IO (GPIO) Ports, can be individually configured by software in several modes: - (+) Input mode + (+) Input mode (+) Analog mode (+) Output mode (+) Alternate function mode (+) External interrupt/event lines - [..] - During and just after reset, the alternate functions and external interrupt + [..] + During and just after reset, the alternate functions and external interrupt lines are not active and the I/O ports are configured in input floating mode. - - [..] - All GPIO pins have weak internal pull-up and pull-down resistors, which can be + + [..] + All GPIO pins have weak internal pull-up and pull-down resistors, which can be activated or not. [..] In Output or Alternate mode, each IO can be configured on open-drain or push-pull type and the IO speed can be selected depending on the VDD value. - [..] - All ports have external interrupt/event capability. To use external interrupt - lines, the port must be configured in input mode. All available GPIO pins are + [..] + All ports have external interrupt/event capability. To use external interrupt + lines, the port must be configured in input mode. All available GPIO pins are connected to the 16 external interrupt/event lines from EXTI0 to EXTI15. - - [..] + + [..] The external interrupt/event controller consists of up to 20 edge detectors in connectivity line devices, or 19 edge detectors in other devices for generating event/interrupt requests. Each input line can be independently configured to select the type (event or interrupt) and the corresponding trigger event (rising or falling or both). Each line can also masked independently. A pending register maintains the status line of the interrupt requests - + ##### How to use this driver ##### - ============================================================================== + ============================================================================== [..] - (#) Enable the GPIO APB2 clock using the following function : __HAL_RCC_GPIOx_CLK_ENABLE(). - + (#) Enable the GPIO APB2 clock using the following function : __HAL_RCC_GPIOx_CLK_ENABLE(). + (#) Configure the GPIO pin(s) using HAL_GPIO_Init(). (++) Configure the IO mode using "Mode" member from GPIO_InitTypeDef structure - (++) Activate Pull-up, Pull-down resistor using "Pull" member from GPIO_InitTypeDef + (++) Activate Pull-up, Pull-down resistor using "Pull" member from GPIO_InitTypeDef structure. - (++) In case of Output or alternate function mode selection: the speed is + (++) In case of Output or alternate function mode selection: the speed is configured through "Speed" member from GPIO_InitTypeDef structure - (++) Analog mode is required when a pin is to be used as ADC channel + (++) Analog mode is required when a pin is to be used as ADC channel or DAC output. - (++) In case of external interrupt/event selection the "Mode" member from - GPIO_InitTypeDef structure select the type (interrupt or event) and + (++) In case of external interrupt/event selection the "Mode" member from + GPIO_InitTypeDef structure select the type (interrupt or event) and the corresponding trigger event (rising or falling or both). - - (#) In case of external interrupt/event mode selection, configure NVIC IRQ priority + + (#) In case of external interrupt/event mode selection, configure NVIC IRQ priority mapped to the EXTI line using HAL_NVIC_SetPriority() and enable it using HAL_NVIC_EnableIRQ(). - + (#) To get the level of a pin configured in input mode use HAL_GPIO_ReadPin(). - - (#) To set/reset the level of a pin configured in output mode use + + (#) To set/reset the level of a pin configured in output mode use HAL_GPIO_WritePin()/HAL_GPIO_TogglePin(). - + (#) To lock pin configuration until next reset use HAL_GPIO_LockPin(). - - (#) During and just after reset, the alternate functions are not + + (#) During and just after reset, the alternate functions are not active and the GPIO pins are configured in input floating mode (except JTAG pins). - - (#) The LSE oscillator pins OSC32_IN and OSC32_OUT can be used as general purpose - (PC14 and PC15, respectively) when the LSE oscillator is off. The LSE has + + (#) The LSE oscillator pins OSC32_IN and OSC32_OUT can be used as general purpose + (PC14 and PC15, respectively) when the LSE oscillator is off. The LSE has priority over the GPIO function. - - (#) The HSE oscillator pins OSC_IN/OSC_OUT can be used as - general purpose PD0 and PD1, respectively, when the HSE oscillator is off. + + (#) The HSE oscillator pins OSC_IN/OSC_OUT can be used as + general purpose PD0 and PD1, respectively, when the HSE oscillator is off. The HSE has priority over the GPIO function. - + @endverbatim ****************************************************************************** * @attention @@ -116,8 +114,8 @@ * 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. * - ****************************************************************************** - */ + ****************************************************************************** + */ /* Includes ------------------------------------------------------------------*/ #include "stm32f1xx_hal.h" @@ -157,7 +155,7 @@ #define GPIO_CR_CNF_GP_OUTPUT_OD 0x00000004U /*!< 01: General purpose output Open-drain */ #define GPIO_CR_CNF_AF_OUTPUT_PP 0x00000008U /*!< 10: Alternate function output Push-pull */ #define GPIO_CR_CNF_AF_OUTPUT_OD 0x0000000CU /*!< 11: Alternate function output Open-drain */ - + /** * @} */ @@ -173,14 +171,14 @@ /** @defgroup GPIO_Exported_Functions_Group1 Initialization and de-initialization functions * @brief Initialization and Configuration functions * -@verbatim +@verbatim =============================================================================== ##### Initialization and de-initialization functions ##### =============================================================================== [..] This section provides functions allowing to initialize and de-initialize the GPIOs to be ready for use. - + @endverbatim * @{ */ @@ -202,7 +200,7 @@ void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init) uint32_t config = 0x00U; __IO uint32_t *configregister; /* Store the address of CRL or CRH register based on pin number */ uint32_t registeroffset = 0U; /* offset used during computation of CNF and MODE bits placement inside CRL or CRH register */ - + /* Check the parameters */ assert_param(IS_GPIO_ALL_INSTANCE(GPIOx)); assert_param(IS_GPIO_PIN(GPIO_Init->Pin)); @@ -213,7 +211,7 @@ void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init) { /* Get the IO position */ ioposition = (0x01U << position); - + /* Get the current IO position */ iocurrent = (uint32_t)(GPIO_Init->Pin) & ioposition; @@ -231,28 +229,28 @@ void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init) assert_param(IS_GPIO_SPEED(GPIO_Init->Speed)); config = GPIO_Init->Speed + GPIO_CR_CNF_GP_OUTPUT_PP; break; - + /* If we are configuring the pin in OUTPUT open-drain mode */ case GPIO_MODE_OUTPUT_OD: /* Check the GPIO speed parameter */ assert_param(IS_GPIO_SPEED(GPIO_Init->Speed)); config = GPIO_Init->Speed + GPIO_CR_CNF_GP_OUTPUT_OD; break; - + /* If we are configuring the pin in ALTERNATE FUNCTION push-pull mode */ case GPIO_MODE_AF_PP: /* Check the GPIO speed parameter */ assert_param(IS_GPIO_SPEED(GPIO_Init->Speed)); config = GPIO_Init->Speed + GPIO_CR_CNF_AF_OUTPUT_PP; break; - + /* If we are configuring the pin in ALTERNATE FUNCTION open-drain mode */ case GPIO_MODE_AF_OD: /* Check the GPIO speed parameter */ assert_param(IS_GPIO_SPEED(GPIO_Init->Speed)); config = GPIO_Init->Speed + GPIO_CR_CNF_AF_OUTPUT_OD; break; - + /* If we are configuring the pin in INPUT (also applicable to EVENT and IT mode) */ case GPIO_MODE_INPUT: case GPIO_MODE_IT_RISING: @@ -263,47 +261,47 @@ void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init) case GPIO_MODE_EVT_RISING_FALLING: /* Check the GPIO pull parameter */ assert_param(IS_GPIO_PULL(GPIO_Init->Pull)); - if(GPIO_Init->Pull == GPIO_NOPULL) - { + if (GPIO_Init->Pull == GPIO_NOPULL) + { config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_INPUT_FLOATING; } - else if(GPIO_Init->Pull == GPIO_PULLUP) + else if (GPIO_Init->Pull == GPIO_PULLUP) { config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_INPUT_PU_PD; - + /* Set the corresponding ODR bit */ GPIOx->BSRR = ioposition; } else /* GPIO_PULLDOWN */ { config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_INPUT_PU_PD; - + /* Reset the corresponding ODR bit */ GPIOx->BRR = ioposition; } - break; - + break; + /* If we are configuring the pin in INPUT analog mode */ case GPIO_MODE_ANALOG: - config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_ANALOG; + config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_ANALOG; break; - + /* Parameters are checked with assert_param */ default: break; } - + /* Check if the current bit belongs to first half or last half of the pin count number in order to address CRH or CRL register*/ configregister = (iocurrent < GPIO_PIN_8) ? &GPIOx->CRL : &GPIOx->CRH; registeroffset = (iocurrent < GPIO_PIN_8) ? (position << 2U) : ((position - 8U) << 2U); - + /* Apply the new configuration of the pin to the register */ - MODIFY_REG((*configregister), ((GPIO_CRL_MODE0 | GPIO_CRL_CNF0) << registeroffset ), (config << registeroffset)); - + MODIFY_REG((*configregister), ((GPIO_CRL_MODE0 | GPIO_CRL_CNF0) << registeroffset), (config << registeroffset)); + /*--------------------- EXTI Mode Configuration ------------------------*/ /* Configure the External Interrupt or event for the current IO */ - if((GPIO_Init->Mode & EXTI_MODE) == EXTI_MODE) + if ((GPIO_Init->Mode & EXTI_MODE) == EXTI_MODE) { /* Enable AFIO Clock */ __HAL_RCC_AFIO_CLK_ENABLE(); @@ -311,46 +309,46 @@ void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init) CLEAR_BIT(temp, (0x0FU) << (4U * (position & 0x03U))); SET_BIT(temp, (GPIO_GET_INDEX(GPIOx)) << (4U * (position & 0x03U))); AFIO->EXTICR[position >> 2U] = temp; - + /* Configure the interrupt mask */ - if((GPIO_Init->Mode & GPIO_MODE_IT) == GPIO_MODE_IT) + if ((GPIO_Init->Mode & GPIO_MODE_IT) == GPIO_MODE_IT) { - SET_BIT(EXTI->IMR, iocurrent); - } + SET_BIT(EXTI->IMR, iocurrent); + } else { - CLEAR_BIT(EXTI->IMR, iocurrent); - } - + CLEAR_BIT(EXTI->IMR, iocurrent); + } + /* Configure the event mask */ - if((GPIO_Init->Mode & GPIO_MODE_EVT) == GPIO_MODE_EVT) + if ((GPIO_Init->Mode & GPIO_MODE_EVT) == GPIO_MODE_EVT) { - SET_BIT(EXTI->EMR, iocurrent); - } + SET_BIT(EXTI->EMR, iocurrent); + } else { - CLEAR_BIT(EXTI->EMR, iocurrent); + CLEAR_BIT(EXTI->EMR, iocurrent); } - + /* Enable or disable the rising trigger */ - if((GPIO_Init->Mode & RISING_EDGE) == RISING_EDGE) + if ((GPIO_Init->Mode & RISING_EDGE) == RISING_EDGE) { - SET_BIT(EXTI->RTSR, iocurrent); - } + SET_BIT(EXTI->RTSR, iocurrent); + } else { - CLEAR_BIT(EXTI->RTSR, iocurrent); + CLEAR_BIT(EXTI->RTSR, iocurrent); } - + /* Enable or disable the falling trigger */ - if((GPIO_Init->Mode & FALLING_EDGE) == FALLING_EDGE) + if ((GPIO_Init->Mode & FALLING_EDGE) == FALLING_EDGE) { - SET_BIT(EXTI->FTSR, iocurrent); - } + SET_BIT(EXTI->FTSR, iocurrent); + } else { - CLEAR_BIT(EXTI->FTSR, iocurrent); + CLEAR_BIT(EXTI->FTSR, iocurrent); } } } @@ -365,13 +363,13 @@ void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init) * @retval None */ void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin) -{ +{ uint32_t position = 0x00U; uint32_t iocurrent = 0x00U; uint32_t tmp = 0x00U; __IO uint32_t *configregister; /* Store the address of CRL or CRH register based on pin number */ uint32_t registeroffset = 0U; - + /* Check the parameters */ assert_param(IS_GPIO_ALL_INSTANCE(GPIOx)); assert_param(IS_GPIO_PIN(GPIO_Pin)); @@ -389,33 +387,33 @@ void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin) in order to address CRH or CRL register */ configregister = (iocurrent < GPIO_PIN_8) ? &GPIOx->CRL : &GPIOx->CRH; registeroffset = (iocurrent < GPIO_PIN_8) ? (position << 2U) : ((position - 8U) << 2U); - + /* CRL/CRH default value is floating input(0x04) shifted to correct position */ - MODIFY_REG(*configregister, ((GPIO_CRL_MODE0 | GPIO_CRL_CNF0) << registeroffset ), GPIO_CRL_CNF0_0 << registeroffset); - + MODIFY_REG(*configregister, ((GPIO_CRL_MODE0 | GPIO_CRL_CNF0) << registeroffset), GPIO_CRL_CNF0_0 << registeroffset); + /* ODR default value is 0 */ CLEAR_BIT(GPIOx->ODR, iocurrent); - + /*------------------------- EXTI Mode Configuration --------------------*/ /* Clear the External Interrupt or Event for the current IO */ - + tmp = AFIO->EXTICR[position >> 2U]; tmp &= 0x0FU << (4U * (position & 0x03U)); - if(tmp == (GPIO_GET_INDEX(GPIOx) << (4U * (position & 0x03U)))) + if (tmp == (GPIO_GET_INDEX(GPIOx) << (4U * (position & 0x03U)))) { tmp = 0x0FU << (4U * (position & 0x03U)); CLEAR_BIT(AFIO->EXTICR[position >> 2U], tmp); - + /* Clear EXTI line configuration */ CLEAR_BIT(EXTI->IMR, (uint32_t)iocurrent); CLEAR_BIT(EXTI->EMR, (uint32_t)iocurrent); - + /* Clear Rising Falling edge configuration */ CLEAR_BIT(EXTI->RTSR, (uint32_t)iocurrent); CLEAR_BIT(EXTI->FTSR, (uint32_t)iocurrent); } } - + position++; } } @@ -424,7 +422,7 @@ void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin) * @} */ -/** @defgroup GPIO_Exported_Functions_Group2 IO operation functions +/** @defgroup GPIO_Exported_Functions_Group2 IO operation functions * @brief GPIO Read and Write * @verbatim @@ -445,7 +443,7 @@ void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin) * This parameter can be GPIO_PIN_x where x can be (0..15). * @retval The input port pin value. */ -GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin) { GPIO_PinState bitstatus; @@ -465,27 +463,27 @@ GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) /** * @brief Sets or clears the selected data port bit. - * - * @note This function uses GPIOx_BSRR register to allow atomic read/modify + * + * @note This function uses GPIOx_BSRR register to allow atomic read/modify * accesses. In this way, there is no risk of an IRQ occurring between * the read and the modify access. - * + * * @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral * @param GPIO_Pin: specifies the port bit to be written. * This parameter can be one of GPIO_PIN_x where x can be (0..15). * @param PinState: specifies the value to be written to the selected bit. * This parameter can be one of the GPIO_PinState enum values: - * @arg GPIO_BIT_RESET: to clear the port pin - * @arg GPIO_BIT_SET: to set the port pin + * @arg GPIO_PIN_RESET: to clear the port pin + * @arg GPIO_PIN_SET: to set the port pin * @retval None */ -void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState) +void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState) { /* Check the parameters */ assert_param(IS_GPIO_PIN(GPIO_Pin)); assert_param(IS_GPIO_PIN_ACTION(PinState)); - if(PinState != GPIO_PIN_RESET) + if (PinState != GPIO_PIN_RESET) { GPIOx->BSRR = GPIO_Pin; } @@ -497,11 +495,11 @@ void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState Pin /** * @brief Toggles the specified GPIO pin - * @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral + * @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral * @param GPIO_Pin: Specifies the pins to be toggled. * @retval None */ -void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin) { /* Check the parameters */ assert_param(IS_GPIO_PIN(GPIO_Pin)); @@ -519,7 +517,7 @@ void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) * This parameter can be any combination of GPIO_Pin_x where x can be (0..15). * @retval None */ -HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin) { __IO uint32_t tmp = GPIO_LCKR_LCKK; @@ -538,7 +536,7 @@ HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) /* Read LCKK bit*/ tmp = GPIOx->LCKR; - if((uint32_t)(GPIOx->LCKR & GPIO_LCKR_LCKK)) + if ((uint32_t)(GPIOx->LCKR & GPIO_LCKR_LCKK)) { return HAL_OK; } @@ -556,7 +554,7 @@ HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin) { /* EXTI line interrupt detected */ - if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET) + if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET) { __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin); HAL_GPIO_EXTI_Callback(GPIO_Pin); diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_gpio.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_gpio.h index ca9251d08646..7a213fee9ebd 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_gpio.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_gpio.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_gpio.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of GPIO HAL module. ****************************************************************************** * @attention @@ -33,14 +31,14 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** - */ + */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM32F1xx_HAL_GPIO_H #define __STM32F1xx_HAL_GPIO_H #ifdef __cplusplus - extern "C" { +extern "C" { #endif /* Includes ------------------------------------------------------------------*/ @@ -52,16 +50,16 @@ /** @addtogroup GPIO * @{ - */ + */ /* Exported types ------------------------------------------------------------*/ /** @defgroup GPIO_Exported_Types GPIO Exported Types * @{ */ -/** - * @brief GPIO Init structure definition - */ +/** + * @brief GPIO Init structure definition + */ typedef struct { uint32_t Pin; /*!< Specifies the GPIO pins to be configured. @@ -75,16 +73,16 @@ typedef struct uint32_t Speed; /*!< Specifies the speed for the selected pins. This parameter can be a value of @ref GPIO_speed_define */ -}GPIO_InitTypeDef; +} GPIO_InitTypeDef; -/** - * @brief GPIO Bit SET and Bit RESET enumeration +/** + * @brief GPIO Bit SET and Bit RESET enumeration */ typedef enum { GPIO_PIN_RESET = 0U, GPIO_PIN_SET -}GPIO_PinState; +} GPIO_PinState; /** * @} */ @@ -93,7 +91,7 @@ typedef enum /** @defgroup GPIO_Exported_Constants GPIO Exported Constants * @{ - */ + */ /** @defgroup GPIO_pins_define GPIO pins define * @{ @@ -122,15 +120,15 @@ typedef enum */ /** @defgroup GPIO_mode_define GPIO mode define - * @brief GPIO Configuration Mode + * @brief GPIO Configuration Mode * Elements values convention: 0xX0yz00YZ * - X : GPIO mode or EXTI Mode - * - y : External IT or Event trigger detection + * - y : External IT or Event trigger detection * - z : IO configuration on External IT or Event * - Y : Output type (Push Pull or Open Drain) * - Z : IO Direction mode (Input, Output, Alternate or Analog) * @{ - */ + */ #define GPIO_MODE_INPUT 0x00000000U /*!< Input Floating Mode */ #define GPIO_MODE_OUTPUT_PP 0x00000001U /*!< Output Push Pull Mode */ #define GPIO_MODE_OUTPUT_OD 0x00000011U /*!< Output Open Drain Mode */ @@ -139,11 +137,11 @@ typedef enum #define GPIO_MODE_AF_INPUT GPIO_MODE_INPUT /*!< Alternate Function Input Mode */ #define GPIO_MODE_ANALOG 0x00000003U /*!< Analog Mode */ - + #define GPIO_MODE_IT_RISING 0x10110000U /*!< External Interrupt Mode with Rising edge trigger detection */ #define GPIO_MODE_IT_FALLING 0x10210000U /*!< External Interrupt Mode with Falling edge trigger detection */ #define GPIO_MODE_IT_RISING_FALLING 0x10310000U /*!< External Interrupt Mode with Rising/Falling edge trigger detection */ - + #define GPIO_MODE_EVT_RISING 0x10120000U /*!< External Event Mode with Rising edge trigger detection */ #define GPIO_MODE_EVT_FALLING 0x10220000U /*!< External Event Mode with Falling edge trigger detection */ #define GPIO_MODE_EVT_RISING_FALLING 0x10320000U /*!< External Event Mode with Rising/Falling edge trigger detection */ @@ -164,17 +162,17 @@ typedef enum * @} */ - /** @defgroup GPIO_pull_define GPIO pull define - * @brief GPIO Pull-Up or Pull-Down Activation - * @{ - */ +/** @defgroup GPIO_pull_define GPIO pull define + * @brief GPIO Pull-Up or Pull-Down Activation + * @{ + */ #define GPIO_NOPULL 0x00000000U /*!< No Pull-up or Pull-down activation */ #define GPIO_PULLUP 0x00000001U /*!< Pull-up activation */ #define GPIO_PULLDOWN 0x00000002U /*!< Pull-down activation */ /** * @} */ - + /** * @} */ @@ -249,20 +247,20 @@ void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin); * @{ */ /* IO operation functions *****************************************************/ -GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); -void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState); -void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); -HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); +GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin); +void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState); +void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin); +HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin); void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin); void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin); /** * @} - */ + */ /** * @} - */ + */ /* Private types -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Private constants ---------------------------------------------------------*/ @@ -311,7 +309,7 @@ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin); /** * @} - */ + */ /** * @} diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_gpio_ex.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_gpio_ex.c index cc269d2d6589..2d7d8ca8ba46 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_gpio_ex.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_gpio_ex.c @@ -2,27 +2,25 @@ ****************************************************************************** * @file stm32f1xx_hal_gpio_ex.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief GPIO Extension HAL module driver. - * This file provides firmware functions to manage the following + * This file provides firmware functions to manage the following * functionalities of the General Purpose Input/Output (GPIO) extension peripheral. * + Extended features functions - * + * @verbatim ============================================================================== ##### GPIO Peripheral extension features ##### - ============================================================================== + ============================================================================== [..] GPIO module on STM32F1 family, manage also the AFIO register: (+) Possibility to use the EVENTOUT Cortex feature - + ##### How to use this driver ##### ============================================================================== [..] This driver provides functions to use EVENTOUT Cortex feature (#) Configure EVENTOUT Cortex feature using the function HAL_GPIOEx_ConfigEventout() (#) Activate EVENTOUT Cortex feature using the HAL_GPIOEx_EnableEventout() (#) Deactivate EVENTOUT Cortex feature using the HAL_GPIOEx_DisableEventout() - + @endverbatim ****************************************************************************** * @attention @@ -51,8 +49,8 @@ * 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. * - ****************************************************************************** - */ + ****************************************************************************** + */ /* Includes ------------------------------------------------------------------*/ #include "stm32f1xx_hal.h" @@ -73,21 +71,21 @@ */ /** @defgroup GPIOEx_Exported_Functions_Group1 Extended features functions - * @brief Extended features functions + * @brief Extended features functions * -@verbatim +@verbatim ============================================================================== ##### Extended features functions ##### - ============================================================================== + ============================================================================== [..] This section provides functions allowing to: (+) Configure EVENTOUT Cortex feature using the function HAL_GPIOEx_ConfigEventout() (+) Activate EVENTOUT Cortex feature using the HAL_GPIOEx_EnableEventout() (+) Deactivate EVENTOUT Cortex feature using the HAL_GPIOEx_DisableEventout() - + @endverbatim * @{ */ - + /** * @brief Configures the port and pin on which the EVENTOUT Cortex signal will be connected. * @param GPIO_PortSource Select the port used to output the Cortex EVENTOUT signal. @@ -95,15 +93,15 @@ * @param GPIO_PinSource Select the pin used to output the Cortex EVENTOUT signal. * This parameter can be a value of @ref GPIOEx_EVENTOUT_PIN. * @retval None - */ + */ void HAL_GPIOEx_ConfigEventout(uint32_t GPIO_PortSource, uint32_t GPIO_PinSource) { /* Verify the parameters */ assert_param(IS_AFIO_EVENTOUT_PORT(GPIO_PortSource)); assert_param(IS_AFIO_EVENTOUT_PIN(GPIO_PinSource)); - + /* Apply the new configuration */ - MODIFY_REG(AFIO->EVCR, (AFIO_EVCR_PORT)|(AFIO_EVCR_PIN), (GPIO_PortSource)|(GPIO_PinSource)); + MODIFY_REG(AFIO->EVCR, (AFIO_EVCR_PORT) | (AFIO_EVCR_PIN), (GPIO_PortSource) | (GPIO_PinSource)); } /** @@ -127,11 +125,11 @@ void HAL_GPIOEx_DisableEventout(void) /** * @} */ - + /** * @} */ - + #endif /* HAL_GPIO_MODULE_ENABLED */ /** diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_gpio_ex.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_gpio_ex.h index 67b3a8cef833..f34cdf7d903c 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_gpio_ex.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_gpio_ex.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_gpio_ex.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of GPIO HAL Extension module. ****************************************************************************** * @attention @@ -33,14 +31,14 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** - */ + */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM32F1xx_HAL_GPIO_EX_H #define __STM32F1xx_HAL_GPIO_EX_H #ifdef __cplusplus - extern "C" { +extern "C" { #endif /* Includes ------------------------------------------------------------------*/ @@ -52,25 +50,23 @@ /** @defgroup GPIOEx GPIOEx * @{ - */ - + */ /* Exported types ------------------------------------------------------------*/ - /* Exported constants --------------------------------------------------------*/ /** @defgroup GPIOEx_Exported_Constants GPIOEx Exported Constants * @{ - */ - + */ + /** @defgroup GPIOEx_EVENTOUT EVENTOUT Cortex Configuration * @brief This section propose definition to use the Cortex EVENTOUT signal. * @{ */ - -/** @defgroup GPIOEx_EVENTOUT_PIN EVENTOUT Pin + +/** @defgroup GPIOEx_EVENTOUT_PIN EVENTOUT Pin * @{ */ - + #define AFIO_EVENTOUT_PIN_0 AFIO_EVCR_PIN_PX0 /*!< EVENTOUT on pin 0 */ #define AFIO_EVENTOUT_PIN_1 AFIO_EVCR_PIN_PX1 /*!< EVENTOUT on pin 1 */ #define AFIO_EVENTOUT_PIN_2 AFIO_EVCR_PIN_PX2 /*!< EVENTOUT on pin 2 */ @@ -106,12 +102,12 @@ ((__PIN__) == AFIO_EVENTOUT_PIN_15)) /** * @} - */ - + */ + /** @defgroup GPIOEx_EVENTOUT_PORT EVENTOUT Port * @{ */ - + #define AFIO_EVENTOUT_PORT_A AFIO_EVCR_PORT_PA /*!< EVENTOUT on port A */ #define AFIO_EVENTOUT_PORT_B AFIO_EVCR_PORT_PB /*!< EVENTOUT on port B */ #define AFIO_EVENTOUT_PORT_C AFIO_EVCR_PORT_PC /*!< EVENTOUT on port C */ @@ -126,7 +122,7 @@ /** * @} */ - + /** * @} */ @@ -135,151 +131,132 @@ * @brief This section propose definition to remap the alternate function to some other port/pins. * @{ */ - + /** * @brief Enable the remapping of SPI1 alternate function NSS, SCK, MISO and MOSI. * @note ENABLE: Remap (NSS/PA15, SCK/PB3, MISO/PB4, MOSI/PB5) * @retval None */ -#define __HAL_AFIO_REMAP_SPI1_ENABLE() SET_BIT(AFIO->MAPR, AFIO_MAPR_SPI1_REMAP) +#define __HAL_AFIO_REMAP_SPI1_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_SPI1_REMAP) /** * @brief Disable the remapping of SPI1 alternate function NSS, SCK, MISO and MOSI. * @note DISABLE: No remap (NSS/PA4, SCK/PA5, MISO/PA6, MOSI/PA7) * @retval None */ -#define __HAL_AFIO_REMAP_SPI1_DISABLE() CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_SPI1_REMAP) +#define __HAL_AFIO_REMAP_SPI1_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_SPI1_REMAP) /** * @brief Enable the remapping of I2C1 alternate function SCL and SDA. * @note ENABLE: Remap (SCL/PB8, SDA/PB9) * @retval None */ -#define __HAL_AFIO_REMAP_I2C1_ENABLE() SET_BIT(AFIO->MAPR, AFIO_MAPR_I2C1_REMAP) +#define __HAL_AFIO_REMAP_I2C1_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_I2C1_REMAP) /** * @brief Disable the remapping of I2C1 alternate function SCL and SDA. * @note DISABLE: No remap (SCL/PB6, SDA/PB7) * @retval None */ -#define __HAL_AFIO_REMAP_I2C1_DISABLE() CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_I2C1_REMAP) +#define __HAL_AFIO_REMAP_I2C1_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_I2C1_REMAP) /** * @brief Enable the remapping of USART1 alternate function TX and RX. * @note ENABLE: Remap (TX/PB6, RX/PB7) * @retval None */ -#define __HAL_AFIO_REMAP_USART1_ENABLE() SET_BIT(AFIO->MAPR, AFIO_MAPR_USART1_REMAP) +#define __HAL_AFIO_REMAP_USART1_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_USART1_REMAP) /** * @brief Disable the remapping of USART1 alternate function TX and RX. * @note DISABLE: No remap (TX/PA9, RX/PA10) * @retval None */ -#define __HAL_AFIO_REMAP_USART1_DISABLE() CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_USART1_REMAP) +#define __HAL_AFIO_REMAP_USART1_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_USART1_REMAP) /** * @brief Enable the remapping of USART2 alternate function CTS, RTS, CK, TX and RX. * @note ENABLE: Remap (CTS/PD3, RTS/PD4, TX/PD5, RX/PD6, CK/PD7) * @retval None */ -#define __HAL_AFIO_REMAP_USART2_ENABLE() SET_BIT(AFIO->MAPR, AFIO_MAPR_USART2_REMAP) +#define __HAL_AFIO_REMAP_USART2_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_USART2_REMAP) /** * @brief Disable the remapping of USART2 alternate function CTS, RTS, CK, TX and RX. * @note DISABLE: No remap (CTS/PA0, RTS/PA1, TX/PA2, RX/PA3, CK/PA4) * @retval None */ -#define __HAL_AFIO_REMAP_USART2_DISABLE() CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_USART2_REMAP) +#define __HAL_AFIO_REMAP_USART2_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_USART2_REMAP) /** * @brief Enable the remapping of USART3 alternate function CTS, RTS, CK, TX and RX. * @note ENABLE: Full remap (TX/PD8, RX/PD9, CK/PD10, CTS/PD11, RTS/PD12) * @retval None */ -#define __HAL_AFIO_REMAP_USART3_ENABLE() do{ CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_USART3_REMAP); \ - SET_BIT(AFIO->MAPR, AFIO_MAPR_USART3_REMAP_FULLREMAP); \ - }while(0U) +#define __HAL_AFIO_REMAP_USART3_ENABLE() AFIO_REMAP_PARTIAL(AFIO_MAPR_USART3_REMAP_FULLREMAP, AFIO_MAPR_USART3_REMAP_FULLREMAP) + /** * @brief Enable the remapping of USART3 alternate function CTS, RTS, CK, TX and RX. * @note PARTIAL: Partial remap (TX/PC10, RX/PC11, CK/PC12, CTS/PB13, RTS/PB14) * @retval None */ -#define __HAL_AFIO_REMAP_USART3_PARTIAL() do{ CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_USART3_REMAP); \ - SET_BIT(AFIO->MAPR, AFIO_MAPR_USART3_REMAP_PARTIALREMAP); \ - }while(0U) +#define __HAL_AFIO_REMAP_USART3_PARTIAL() AFIO_REMAP_PARTIAL(AFIO_MAPR_USART3_REMAP_PARTIALREMAP, AFIO_MAPR_USART3_REMAP_FULLREMAP) /** * @brief Disable the remapping of USART3 alternate function CTS, RTS, CK, TX and RX. * @note DISABLE: No remap (TX/PB10, RX/PB11, CK/PB12, CTS/PB13, RTS/PB14) * @retval None */ -#define __HAL_AFIO_REMAP_USART3_DISABLE() do{ CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_USART3_REMAP); \ - SET_BIT(AFIO->MAPR, AFIO_MAPR_USART3_REMAP_NOREMAP); \ - }while(0U) +#define __HAL_AFIO_REMAP_USART3_DISABLE() AFIO_REMAP_PARTIAL(AFIO_MAPR_USART3_REMAP_NOREMAP, AFIO_MAPR_USART3_REMAP_FULLREMAP) /** * @brief Enable the remapping of TIM1 alternate function channels 1 to 4, 1N to 3N, external trigger (ETR) and Break input (BKIN) * @note ENABLE: Full remap (ETR/PE7, CH1/PE9, CH2/PE11, CH3/PE13, CH4/PE14, BKIN/PE15, CH1N/PE8, CH2N/PE10, CH3N/PE12) * @retval None */ -#define __HAL_AFIO_REMAP_TIM1_ENABLE() do{ CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_TIM1_REMAP); \ - SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM1_REMAP_FULLREMAP); \ - }while(0U) +#define __HAL_AFIO_REMAP_TIM1_ENABLE() AFIO_REMAP_PARTIAL(AFIO_MAPR_TIM1_REMAP_FULLREMAP, AFIO_MAPR_TIM1_REMAP_FULLREMAP) /** * @brief Enable the remapping of TIM1 alternate function channels 1 to 4, 1N to 3N, external trigger (ETR) and Break input (BKIN) * @note PARTIAL: Partial remap (ETR/PA12, CH1/PA8, CH2/PA9, CH3/PA10, CH4/PA11, BKIN/PA6, CH1N/PA7, CH2N/PB0, CH3N/PB1) * @retval None */ -#define __HAL_AFIO_REMAP_TIM1_PARTIAL() do{ CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_TIM1_REMAP); \ - SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM1_REMAP_PARTIALREMAP); \ - }while(0U) +#define __HAL_AFIO_REMAP_TIM1_PARTIAL() AFIO_REMAP_PARTIAL(AFIO_MAPR_TIM1_REMAP_PARTIALREMAP, AFIO_MAPR_TIM1_REMAP_FULLREMAP) /** * @brief Disable the remapping of TIM1 alternate function channels 1 to 4, 1N to 3N, external trigger (ETR) and Break input (BKIN) * @note DISABLE: No remap (ETR/PA12, CH1/PA8, CH2/PA9, CH3/PA10, CH4/PA11, BKIN/PB12, CH1N/PB13, CH2N/PB14, CH3N/PB15) * @retval None */ -#define __HAL_AFIO_REMAP_TIM1_DISABLE() do{ CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_TIM1_REMAP); \ - SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM1_REMAP_NOREMAP); \ - }while(0U) +#define __HAL_AFIO_REMAP_TIM1_DISABLE() AFIO_REMAP_PARTIAL(AFIO_MAPR_TIM1_REMAP_NOREMAP, AFIO_MAPR_TIM1_REMAP_FULLREMAP) /** * @brief Enable the remapping of TIM2 alternate function channels 1 to 4 and external trigger (ETR) * @note ENABLE: Full remap (CH1/ETR/PA15, CH2/PB3, CH3/PB10, CH4/PB11) * @retval None */ -#define __HAL_AFIO_REMAP_TIM2_ENABLE() do{ CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_TIM2_REMAP); \ - SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM2_REMAP_FULLREMAP); \ - }while(0U) +#define __HAL_AFIO_REMAP_TIM2_ENABLE() AFIO_REMAP_PARTIAL(AFIO_MAPR_TIM2_REMAP_FULLREMAP, AFIO_MAPR_TIM2_REMAP_FULLREMAP) /** * @brief Enable the remapping of TIM2 alternate function channels 1 to 4 and external trigger (ETR) * @note PARTIAL_2: Partial remap (CH1/ETR/PA0, CH2/PA1, CH3/PB10, CH4/PB11) * @retval None */ -#define __HAL_AFIO_REMAP_TIM2_PARTIAL_2() do{ CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_TIM2_REMAP); \ - SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM2_REMAP_PARTIALREMAP2); \ - }while(0U) +#define __HAL_AFIO_REMAP_TIM2_PARTIAL_2() AFIO_REMAP_PARTIAL(AFIO_MAPR_TIM2_REMAP_PARTIALREMAP2, AFIO_MAPR_TIM2_REMAP_FULLREMAP) /** * @brief Enable the remapping of TIM2 alternate function channels 1 to 4 and external trigger (ETR) * @note PARTIAL_1: Partial remap (CH1/ETR/PA15, CH2/PB3, CH3/PA2, CH4/PA3) * @retval None */ -#define __HAL_AFIO_REMAP_TIM2_PARTIAL_1() do{ CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_TIM2_REMAP); \ - SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM2_REMAP_PARTIALREMAP1); \ - }while(0U) +#define __HAL_AFIO_REMAP_TIM2_PARTIAL_1() AFIO_REMAP_PARTIAL(AFIO_MAPR_TIM2_REMAP_PARTIALREMAP1, AFIO_MAPR_TIM2_REMAP_FULLREMAP) /** * @brief Disable the remapping of TIM2 alternate function channels 1 to 4 and external trigger (ETR) * @note DISABLE: No remap (CH1/ETR/PA0, CH2/PA1, CH3/PA2, CH4/PA3) * @retval None */ -#define __HAL_AFIO_REMAP_TIM2_DISABLE() do{ CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_TIM2_REMAP); \ - SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM2_REMAP_NOREMAP); \ - }while(0U) +#define __HAL_AFIO_REMAP_TIM2_DISABLE() AFIO_REMAP_PARTIAL(AFIO_MAPR_TIM2_REMAP_NOREMAP, AFIO_MAPR_TIM2_REMAP_FULLREMAP) /** * @brief Enable the remapping of TIM3 alternate function channels 1 to 4 @@ -287,9 +264,7 @@ * @note TIM3_ETR on PE0 is not re-mapped. * @retval None */ -#define __HAL_AFIO_REMAP_TIM3_ENABLE() do{ CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_TIM3_REMAP); \ - SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM3_REMAP_FULLREMAP); \ - }while(0U) +#define __HAL_AFIO_REMAP_TIM3_ENABLE() AFIO_REMAP_PARTIAL(AFIO_MAPR_TIM3_REMAP_FULLREMAP, AFIO_MAPR_TIM3_REMAP_FULLREMAP) /** * @brief Enable the remapping of TIM3 alternate function channels 1 to 4 @@ -297,9 +272,7 @@ * @note TIM3_ETR on PE0 is not re-mapped. * @retval None */ -#define __HAL_AFIO_REMAP_TIM3_PARTIAL() do{ CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_TIM3_REMAP); \ - SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM3_REMAP_PARTIALREMAP); \ - }while(0U) +#define __HAL_AFIO_REMAP_TIM3_PARTIAL() AFIO_REMAP_PARTIAL(AFIO_MAPR_TIM3_REMAP_PARTIALREMAP, AFIO_MAPR_TIM3_REMAP_FULLREMAP) /** * @brief Disable the remapping of TIM3 alternate function channels 1 to 4 @@ -307,9 +280,7 @@ * @note TIM3_ETR on PE0 is not re-mapped. * @retval None */ -#define __HAL_AFIO_REMAP_TIM3_DISABLE() do{ CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_TIM3_REMAP); \ - SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM3_REMAP_NOREMAP); \ - }while(0U) +#define __HAL_AFIO_REMAP_TIM3_DISABLE() AFIO_REMAP_PARTIAL(AFIO_MAPR_TIM3_REMAP_NOREMAP, AFIO_MAPR_TIM3_REMAP_FULLREMAP) /** * @brief Enable the remapping of TIM4 alternate function channels 1 to 4. @@ -317,7 +288,7 @@ * @note TIM4_ETR on PE0 is not re-mapped. * @retval None */ -#define __HAL_AFIO_REMAP_TIM4_ENABLE() SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM4_REMAP) +#define __HAL_AFIO_REMAP_TIM4_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_TIM4_REMAP) /** * @brief Disable the remapping of TIM4 alternate function channels 1 to 4. @@ -325,7 +296,7 @@ * @note TIM4_ETR on PE0 is not re-mapped. * @retval None */ -#define __HAL_AFIO_REMAP_TIM4_DISABLE() CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_TIM4_REMAP) +#define __HAL_AFIO_REMAP_TIM4_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_TIM4_REMAP) #if defined(AFIO_MAPR_CAN_REMAP_REMAP1) @@ -334,48 +305,43 @@ * @note CASE 1: CAN_RX mapped to PA11, CAN_TX mapped to PA12 * @retval None */ -#define __HAL_AFIO_REMAP_CAN1_1() do{ CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_CAN_REMAP); \ - SET_BIT(AFIO->MAPR, AFIO_MAPR_CAN_REMAP_REMAP1); \ - }while(0U) +#define __HAL_AFIO_REMAP_CAN1_1() AFIO_REMAP_PARTIAL(AFIO_MAPR_CAN_REMAP_REMAP1, AFIO_MAPR_CAN_REMAP) /** * @brief Enable or disable the remapping of CAN alternate function CAN_RX and CAN_TX in devices with a single CAN interface. * @note CASE 2: CAN_RX mapped to PB8, CAN_TX mapped to PB9 (not available on 36-pin package) * @retval None */ -#define __HAL_AFIO_REMAP_CAN1_2() do{ CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_CAN_REMAP); \ - SET_BIT(AFIO->MAPR, AFIO_MAPR_CAN_REMAP_REMAP2); \ - }while(0U) +#define __HAL_AFIO_REMAP_CAN1_2() AFIO_REMAP_PARTIAL(AFIO_MAPR_CAN_REMAP_REMAP2, AFIO_MAPR_CAN_REMAP) /** * @brief Enable or disable the remapping of CAN alternate function CAN_RX and CAN_TX in devices with a single CAN interface. * @note CASE 3: CAN_RX mapped to PD0, CAN_TX mapped to PD1 * @retval None */ -#define __HAL_AFIO_REMAP_CAN1_3() do{ CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_CAN_REMAP); \ - SET_BIT(AFIO->MAPR, AFIO_MAPR_CAN_REMAP_REMAP3); \ - }while(0U) +#define __HAL_AFIO_REMAP_CAN1_3() AFIO_REMAP_PARTIAL(AFIO_MAPR_CAN_REMAP_REMAP3, AFIO_MAPR_CAN_REMAP) + #endif /** - * @brief Enable the remapping of PD0 and PD1. When the HSE oscillator is not used - * (application running on internal 8 MHz RC) PD0 and PD1 can be mapped on OSC_IN and - * OSC_OUT. This is available only on 36, 48 and 64 pins packages (PD0 and PD1 are available + * @brief Enable the remapping of PD0 and PD1. When the HSE oscillator is not used + * (application running on internal 8 MHz RC) PD0 and PD1 can be mapped on OSC_IN and + * OSC_OUT. This is available only on 36, 48 and 64 pins packages (PD0 and PD1 are available * on 100-pin and 144-pin packages, no need for remapping). * @note ENABLE: PD0 remapped on OSC_IN, PD1 remapped on OSC_OUT. * @retval None */ -#define __HAL_AFIO_REMAP_PD01_ENABLE() SET_BIT(AFIO->MAPR, AFIO_MAPR_PD01_REMAP) +#define __HAL_AFIO_REMAP_PD01_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_PD01_REMAP) /** - * @brief Disable the remapping of PD0 and PD1. When the HSE oscillator is not used - * (application running on internal 8 MHz RC) PD0 and PD1 can be mapped on OSC_IN and - * OSC_OUT. This is available only on 36, 48 and 64 pins packages (PD0 and PD1 are available + * @brief Disable the remapping of PD0 and PD1. When the HSE oscillator is not used + * (application running on internal 8 MHz RC) PD0 and PD1 can be mapped on OSC_IN and + * OSC_OUT. This is available only on 36, 48 and 64 pins packages (PD0 and PD1 are available * on 100-pin and 144-pin packages, no need for remapping). * @note DISABLE: No remapping of PD0 and PD1 * @retval None */ -#define __HAL_AFIO_REMAP_PD01_DISABLE() CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_PD01_REMAP) +#define __HAL_AFIO_REMAP_PD01_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_PD01_REMAP) #if defined(AFIO_MAPR_TIM5CH4_IREMAP) /** @@ -384,7 +350,7 @@ * @note This function is available only in high density value line devices. * @retval None */ -#define __HAL_AFIO_REMAP_TIM5CH4_ENABLE() SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM5CH4_IREMAP) +#define __HAL_AFIO_REMAP_TIM5CH4_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_TIM5CH4_IREMAP) /** * @brief Disable the remapping of TIM5CH4. @@ -392,7 +358,7 @@ * @note This function is available only in high density value line devices. * @retval None */ -#define __HAL_AFIO_REMAP_TIM5CH4_DISABLE() CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_TIM5CH4_IREMAP) +#define __HAL_AFIO_REMAP_TIM5CH4_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_TIM5CH4_IREMAP) #endif #if defined(AFIO_MAPR_ETH_REMAP) @@ -402,7 +368,7 @@ * @note This bit is available only in connectivity line devices and is reserved otherwise. * @retval None */ -#define __HAL_AFIO_REMAP_ETH_ENABLE() SET_BIT(AFIO->MAPR, AFIO_MAPR_ETH_REMAP) +#define __HAL_AFIO_REMAP_ETH_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_ETH_REMAP) /** * @brief Disable the remapping of Ethernet MAC connections with the PHY. @@ -410,7 +376,7 @@ * @note This bit is available only in connectivity line devices and is reserved otherwise. * @retval None */ -#define __HAL_AFIO_REMAP_ETH_DISABLE() CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_ETH_REMAP) +#define __HAL_AFIO_REMAP_ETH_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_ETH_REMAP) #endif #if defined(AFIO_MAPR_CAN2_REMAP) @@ -421,7 +387,7 @@ * @note This bit is available only in connectivity line devices and is reserved otherwise. * @retval None */ -#define __HAL_AFIO_REMAP_CAN2_ENABLE() SET_BIT(AFIO->MAPR, AFIO_MAPR_CAN2_REMAP) +#define __HAL_AFIO_REMAP_CAN2_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_CAN2_REMAP) /** * @brief Disable the remapping of CAN2 alternate function CAN2_RX and CAN2_TX. @@ -429,7 +395,7 @@ * @note This bit is available only in connectivity line devices and is reserved otherwise. * @retval None */ -#define __HAL_AFIO_REMAP_CAN2_DISABLE() CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_CAN2_REMAP) +#define __HAL_AFIO_REMAP_CAN2_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_CAN2_REMAP) #endif #if defined(AFIO_MAPR_MII_RMII_SEL) @@ -439,7 +405,7 @@ * @note This bit is available only in connectivity line devices and is reserved otherwise. * @retval None */ -#define __HAL_AFIO_ETH_RMII() SET_BIT(AFIO->MAPR, AFIO_MAPR_MII_RMII_SEL) +#define __HAL_AFIO_ETH_RMII() AFIO_REMAP_ENABLE(AFIO_MAPR_MII_RMII_SEL) /** * @brief Configures the Ethernet MAC internally for use with an external MII or RMII PHY. @@ -447,7 +413,7 @@ * @note This bit is available only in connectivity line devices and is reserved otherwise. * @retval None */ -#define __HAL_AFIO_ETH_MII() CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_MII_RMII_SEL) +#define __HAL_AFIO_ETH_MII() AFIO_REMAP_DISABLE(AFIO_MAPR_MII_RMII_SEL) #endif /** @@ -455,28 +421,28 @@ * @note ENABLE: ADC1 External Event injected conversion is connected to TIM8 Channel4. * @retval None */ -#define __HAL_AFIO_REMAP_ADC1_ETRGINJ_ENABLE() SET_BIT(AFIO->MAPR, AFIO_MAPR_ADC1_ETRGINJ_REMAP) +#define __HAL_AFIO_REMAP_ADC1_ETRGINJ_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_ADC1_ETRGINJ_REMAP) /** * @brief Disable the remapping of ADC1_ETRGINJ (ADC 1 External trigger injected conversion). * @note DISABLE: ADC1 External trigger injected conversion is connected to EXTI15 * @retval None */ -#define __HAL_AFIO_REMAP_ADC1_ETRGINJ_DISABLE() CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_ADC1_ETRGINJ_REMAP) +#define __HAL_AFIO_REMAP_ADC1_ETRGINJ_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_ADC1_ETRGINJ_REMAP) /** * @brief Enable the remapping of ADC1_ETRGREG (ADC 1 External trigger regular conversion). * @note ENABLE: ADC1 External Event regular conversion is connected to TIM8 TRG0. * @retval None */ -#define __HAL_AFIO_REMAP_ADC1_ETRGREG_ENABLE() SET_BIT(AFIO->MAPR, AFIO_MAPR_ADC1_ETRGREG_REMAP) +#define __HAL_AFIO_REMAP_ADC1_ETRGREG_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_ADC1_ETRGREG_REMAP) /** * @brief Disable the remapping of ADC1_ETRGREG (ADC 1 External trigger regular conversion). * @note DISABLE: ADC1 External trigger regular conversion is connected to EXTI11 * @retval None */ -#define __HAL_AFIO_REMAP_ADC1_ETRGREG_DISABLE() CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_ADC1_ETRGREG_REMAP) +#define __HAL_AFIO_REMAP_ADC1_ETRGREG_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_ADC1_ETRGREG_REMAP) #if defined(AFIO_MAPR_ADC2_ETRGINJ_REMAP) @@ -485,14 +451,14 @@ * @note ENABLE: ADC2 External Event injected conversion is connected to TIM8 Channel4. * @retval None */ -#define __HAL_AFIO_REMAP_ADC2_ETRGINJ_ENABLE() SET_BIT(AFIO->MAPR, AFIO_MAPR_ADC2_ETRGINJ_REMAP) +#define __HAL_AFIO_REMAP_ADC2_ETRGINJ_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_ADC2_ETRGINJ_REMAP) /** * @brief Disable the remapping of ADC2_ETRGREG (ADC 2 External trigger injected conversion). * @note DISABLE: ADC2 External trigger injected conversion is connected to EXTI15 * @retval None */ -#define __HAL_AFIO_REMAP_ADC2_ETRGINJ_DISABLE() CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_ADC2_ETRGINJ_REMAP) +#define __HAL_AFIO_REMAP_ADC2_ETRGINJ_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_ADC2_ETRGINJ_REMAP) #endif #if defined (AFIO_MAPR_ADC2_ETRGREG_REMAP) @@ -502,14 +468,14 @@ * @note ENABLE: ADC2 External Event regular conversion is connected to TIM8 TRG0. * @retval None */ -#define __HAL_AFIO_REMAP_ADC2_ETRGREG_ENABLE() SET_BIT(AFIO->MAPR, AFIO_MAPR_ADC2_ETRGREG_REMAP) +#define __HAL_AFIO_REMAP_ADC2_ETRGREG_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_ADC2_ETRGREG_REMAP) /** * @brief Disable the remapping of ADC2_ETRGREG (ADC 2 External trigger regular conversion). * @note DISABLE: ADC2 External trigger regular conversion is connected to EXTI11 * @retval None */ -#define __HAL_AFIO_REMAP_ADC2_ETRGREG_DISABLE() CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_ADC2_ETRGREG_REMAP) +#define __HAL_AFIO_REMAP_ADC2_ETRGREG_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_ADC2_ETRGREG_REMAP) #endif /** @@ -517,36 +483,29 @@ * @note ENABLE: Full SWJ (JTAG-DP + SW-DP): Reset State * @retval None */ -#define __HAL_AFIO_REMAP_SWJ_ENABLE() do{ CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_SWJ_CFG); \ - SET_BIT(AFIO->MAPR, AFIO_MAPR_SWJ_CFG_RESET); \ - }while(0U) +#define __HAL_AFIO_REMAP_SWJ_ENABLE() AFIO_DBGAFR_CONFIG(AFIO_MAPR_SWJ_CFG_RESET) /** * @brief Enable the Serial wire JTAG configuration * @note NONJTRST: Full SWJ (JTAG-DP + SW-DP) but without NJTRST * @retval None */ -#define __HAL_AFIO_REMAP_SWJ_NONJTRST() do{ CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_SWJ_CFG); \ - SET_BIT(AFIO->MAPR, AFIO_MAPR_SWJ_CFG_NOJNTRST); \ - }while(0U) +#define __HAL_AFIO_REMAP_SWJ_NONJTRST() AFIO_DBGAFR_CONFIG(AFIO_MAPR_SWJ_CFG_NOJNTRST) /** * @brief Enable the Serial wire JTAG configuration * @note NOJTAG: JTAG-DP Disabled and SW-DP Enabled * @retval None */ -#define __HAL_AFIO_REMAP_SWJ_NOJTAG() do{ CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_SWJ_CFG); \ - SET_BIT(AFIO->MAPR, AFIO_MAPR_SWJ_CFG_JTAGDISABLE); \ - }while(0U) + +#define __HAL_AFIO_REMAP_SWJ_NOJTAG() AFIO_DBGAFR_CONFIG(AFIO_MAPR_SWJ_CFG_JTAGDISABLE) /** * @brief Disable the Serial wire JTAG configuration * @note DISABLE: JTAG-DP Disabled and SW-DP Disabled * @retval None */ -#define __HAL_AFIO_REMAP_SWJ_DISABLE() do{ CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_SWJ_CFG); \ - SET_BIT(AFIO->MAPR, AFIO_MAPR_SWJ_CFG_DISABLE); \ - }while(0U) +#define __HAL_AFIO_REMAP_SWJ_DISABLE() AFIO_DBGAFR_CONFIG(AFIO_MAPR_SWJ_CFG_DISABLE) #if defined(AFIO_MAPR_SPI3_REMAP) @@ -556,7 +515,7 @@ * @note This bit is available only in connectivity line devices and is reserved otherwise. * @retval None */ -#define __HAL_AFIO_REMAP_SPI3_ENABLE() SET_BIT(AFIO->MAPR, AFIO_MAPR_SPI3_REMAP) +#define __HAL_AFIO_REMAP_SPI3_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_SPI3_REMAP) /** * @brief Disable the remapping of SPI3 alternate functions SPI3_NSS/I2S3_WS, SPI3_SCK/I2S3_CK, SPI3_MISO, SPI3_MOSI/I2S3_SD. @@ -564,7 +523,7 @@ * @note This bit is available only in connectivity line devices and is reserved otherwise. * @retval None */ -#define __HAL_AFIO_REMAP_SPI3_DISABLE() CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_SPI3_REMAP) +#define __HAL_AFIO_REMAP_SPI3_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_SPI3_REMAP) #endif #if defined(AFIO_MAPR_TIM2ITR1_IREMAP) @@ -575,7 +534,7 @@ * @note This bit is available only in connectivity line devices and is reserved otherwise. * @retval None */ -#define __HAL_AFIO_TIM2ITR1_TO_USB() SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM2ITR1_IREMAP) +#define __HAL_AFIO_TIM2ITR1_TO_USB() AFIO_REMAP_ENABLE(AFIO_MAPR_TIM2ITR1_IREMAP) /** * @brief Control of TIM2_ITR1 internal mapping. @@ -583,7 +542,7 @@ * @note This bit is available only in connectivity line devices and is reserved otherwise. * @retval None */ -#define __HAL_AFIO_TIM2ITR1_TO_ETH() CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_TIM2ITR1_IREMAP) +#define __HAL_AFIO_TIM2ITR1_TO_ETH() AFIO_REMAP_DISABLE(AFIO_MAPR_TIM2ITR1_IREMAP) #endif #if defined(AFIO_MAPR_PTP_PPS_REMAP) @@ -594,7 +553,7 @@ * @note This bit is available only in connectivity line devices and is reserved otherwise. * @retval None */ -#define __HAL_AFIO_ETH_PTP_PPS_ENABLE() SET_BIT(AFIO->MAPR, AFIO_MAPR_PTP_PPS_REMAP) +#define __HAL_AFIO_ETH_PTP_PPS_ENABLE() AFIO_REMAP_ENABLE(AFIO_MAPR_PTP_PPS_REMAP) /** * @brief Disable the remapping of ADC2_ETRGREG (ADC 2 External trigger regular conversion). @@ -602,7 +561,7 @@ * @note This bit is available only in connectivity line devices and is reserved otherwise. * @retval None */ -#define __HAL_AFIO_ETH_PTP_PPS_DISABLE() CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_PTP_PPS_REMAP) +#define __HAL_AFIO_ETH_PTP_PPS_DISABLE() AFIO_REMAP_DISABLE(AFIO_MAPR_PTP_PPS_REMAP) #endif #if defined(AFIO_MAPR2_TIM9_REMAP) @@ -856,12 +815,12 @@ /** * @} - */ - + */ + /** * @} */ - + /** @defgroup GPIOEx_Private_Macros GPIOEx Private Macros * @{ */ @@ -883,6 +842,31 @@ ((__GPIOx__) == (GPIOF))? 5U :6U) #endif +#define AFIO_REMAP_ENABLE(REMAP_PIN) do{ uint32_t tmpreg = AFIO->MAPR; \ + tmpreg |= AFIO_MAPR_SWJ_CFG; \ + tmpreg |= REMAP_PIN; \ + AFIO->MAPR = tmpreg; \ + }while(0U) + +#define AFIO_REMAP_DISABLE(REMAP_PIN) do{ uint32_t tmpreg = AFIO->MAPR; \ + tmpreg |= AFIO_MAPR_SWJ_CFG; \ + tmpreg &= ~REMAP_PIN; \ + AFIO->MAPR = tmpreg; \ + }while(0U) + +#define AFIO_REMAP_PARTIAL(REMAP_PIN, REMAP_PIN_MASK) do{ uint32_t tmpreg = AFIO->MAPR; \ + tmpreg &= ~REMAP_PIN_MASK; \ + tmpreg |= AFIO_MAPR_SWJ_CFG; \ + tmpreg |= REMAP_PIN; \ + AFIO->MAPR = tmpreg; \ + }while(0U) + +#define AFIO_DBGAFR_CONFIG(DBGAFR_SWJCFG) do{ uint32_t tmpreg = AFIO->MAPR; \ + tmpreg &= ~AFIO_MAPR_SWJ_CFG_Msk; \ + tmpreg |= DBGAFR_SWJCFG; \ + AFIO->MAPR = tmpreg; \ + }while(0U) + /** * @} */ @@ -903,20 +887,20 @@ void HAL_GPIOEx_DisableEventout(void); /** * @} - */ + */ /** * @} - */ + */ /** * @} - */ + */ /** * @} - */ - + */ + #ifdef __cplusplus } #endif diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_hcd.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_hcd.c index 7328bd214ab9..ac1465eff0c3 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_hcd.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_hcd.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_hcd.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief HCD HAL module driver. * This file provides firmware functions to manage the following * functionalities of the USB Peripheral Controller: diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_hcd.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_hcd.h index abc302f0694b..9572b44a3ceb 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_hcd.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_hcd.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_hcd.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of HCD HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_i2c.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_i2c.c index f9cf9e37718e..f5d99f337937 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_i2c.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_i2c.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_i2c.c * @author MCD Application Team - * @version V1.1.1 - * @date 12-May-2017 * @brief I2C HAL module driver. * This file provides firmware functions to manage the following * functionalities of the Inter Integrated Circuit (I2C) peripheral: @@ -406,6 +404,12 @@ HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c) /* Get PCLK1 frequency */ pclk1 = HAL_RCC_GetPCLK1Freq(); + /* Check the minimum allowed PCLK1 frequency */ + if (I2C_MIN_PCLK_FREQ(pclk1, hi2c->Init.ClockSpeed) == 1U) + { + return HAL_ERROR; + } + /* Calculate frequency range */ freqrange = I2C_FREQRANGE(pclk1); @@ -583,7 +587,7 @@ HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hi2c) * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains * the configuration information for the specified I2C. * @param DevAddress Target device address: The device 7 bits address value - * in datasheet must be shift at right before call interface + * in datasheet must be shifted to the left before calling the interface * @param pData Pointer to data buffer * @param Size Amount of data to be sent * @param Timeout Timeout duration @@ -715,7 +719,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevA * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains * the configuration information for the specified I2C. * @param DevAddress Target device address: The device 7 bits address value - * in datasheet must be shift at right before call interface + * in datasheet must be shifted to the left before calling the interface * @param pData Pointer to data buffer * @param Size Amount of data to be sent * @param Timeout Timeout duration @@ -1181,7 +1185,7 @@ HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, hi2c->XferSize--; hi2c->XferCount--; - if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (Size != 0U)) + if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (hi2c->XferSize != 0U)) { /* Read data from DR */ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; @@ -1231,7 +1235,7 @@ HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains * the configuration information for the specified I2C. * @param DevAddress Target device address: The device 7 bits address value - * in datasheet must be shift at right before call interface + * in datasheet must be shifted to the left before calling the interface * @param pData Pointer to data buffer * @param Size Amount of data to be sent * @retval HAL status @@ -1308,7 +1312,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t D * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains * the configuration information for the specified I2C. * @param DevAddress Target device address: The device 7 bits address value - * in datasheet must be shift at right before call interface + * in datasheet must be shifted to the left before calling the interface * @param pData Pointer to data buffer * @param Size Amount of data to be sent * @retval HAL status @@ -1390,7 +1394,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t De * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains * the configuration information for the specified I2C. * @param DevAddress Target device address: The device 7 bits address value - * in datasheet must be shift at right before call interface + * in datasheet must be shifted to the left before calling the interface * @param pData Pointer to data buffer * @param Size Amount of data to be sent * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition @@ -1462,7 +1466,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, /* Generate Start */ hi2c->Instance->CR1 |= I2C_CR1_START; } - else if(Prev_State == I2C_STATE_MASTER_BUSY_RX) // MBED + else if(Prev_State == I2C_STATE_MASTER_BUSY_RX) // MBED patch { /* Generate ReStart */ hi2c->Instance->CR1 |= I2C_CR1_START; @@ -1493,7 +1497,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains * the configuration information for the specified I2C. * @param DevAddress Target device address: The device 7 bits address value - * in datasheet must be shift at right before call interface + * in datasheet must be shifted to the left before calling the interface * @param pData Pointer to data buffer * @param Size Amount of data to be sent * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition @@ -1564,7 +1568,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, /* Generate Start */ hi2c->Instance->CR1 |= I2C_CR1_START; } - else if(hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) // MBED + else if(hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) // MBED patch { /* Enable Acknowledge */ hi2c->Instance->CR1 |= I2C_CR1_ACK; @@ -1955,7 +1959,7 @@ HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c) * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains * the configuration information for the specified I2C. * @param DevAddress Target device address: The device 7 bits address value - * in datasheet must be shift at right before call interface + * in datasheet must be shifted to the left before calling the interface * @param pData Pointer to data buffer * @param Size Amount of data to be sent * @retval HAL status @@ -2073,7 +2077,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains * the configuration information for the specified I2C. * @param DevAddress Target device address: The device 7 bits address value - * in datasheet must be shift at right before call interface + * in datasheet must be shifted to the left before calling the interface * @param pData Pointer to data buffer * @param Size Amount of data to be sent * @retval HAL status @@ -2192,7 +2196,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t D * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains * the configuration information for the specified I2C. * @param DevAddress Target device address: The device 7 bits address value - * in datasheet must be shift at right before call interface + * in datasheet must be shifted to the left before calling the interface * @retval HAL status */ HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress) @@ -2429,7 +2433,8 @@ HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pD * @brief Write an amount of data in blocking mode to a specific memory address * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains * the configuration information for the specified I2C. - * @param DevAddress Target device address + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface * @param MemAddress Internal memory address * @param MemAddSize Size of internal memory address * @param pData Pointer to data buffer @@ -2562,7 +2567,8 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress * @brief Read an amount of data in blocking mode from a specific memory address * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains * the configuration information for the specified I2C. - * @param DevAddress Target device address + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface * @param MemAddress Internal memory address * @param MemAddSize Size of internal memory address * @param pData Pointer to data buffer @@ -2827,7 +2833,8 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, * @brief Write an amount of data in non-blocking mode with Interrupt to a specific memory address * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains * the configuration information for the specified I2C. - * @param DevAddress Target device address + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface * @param MemAddress Internal memory address * @param MemAddSize Size of internal memory address * @param pData Pointer to data buffer @@ -2912,7 +2919,8 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddr * @brief Read an amount of data in non-blocking mode with Interrupt from a specific memory address * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains * the configuration information for the specified I2C. - * @param DevAddress Target device address + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface * @param MemAddress Internal memory address * @param MemAddSize Size of internal memory address * @param pData Pointer to data buffer @@ -3002,7 +3010,8 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddre * @brief Write an amount of data in non-blocking mode with DMA to a specific memory address * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains * the configuration information for the specified I2C. - * @param DevAddress Target device address + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface * @param MemAddress Internal memory address * @param MemAddSize Size of internal memory address * @param pData Pointer to data buffer @@ -3122,7 +3131,8 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAdd * @brief Reads an amount of data in non-blocking mode with DMA from a specific memory address. * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains * the configuration information for the specified I2C. - * @param DevAddress Target device address + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface * @param MemAddress Internal memory address * @param MemAddSize Size of internal memory address * @param pData Pointer to data buffer @@ -3283,7 +3293,8 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddr * @note This function is used with Memory devices * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains * the configuration information for the specified I2C. - * @param DevAddress Target device address + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface * @param Trials Number of trials * @param Timeout Timeout duration * @retval HAL status @@ -4003,22 +4014,35 @@ static HAL_StatusTypeDef I2C_MasterReceive_RXNE(I2C_HandleTypeDef *hi2c) } else if((tmp == 2U) || (tmp == 3U)) { + // MBED patch if(hi2c->XferOptions != I2C_NEXT_FRAME) + // MBED patch { /* Disable Acknowledge */ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; /* Enable Pos */ hi2c->Instance->CR1 |= I2C_CR1_POS; + // MBED patch } + // MBED patch else + // MBED patch { + // MBED patch /* Enable Acknowledge */ + // MBED patch hi2c->Instance->CR1 |= I2C_CR1_ACK; + // MBED patch } /* Disable BUF interrupt */ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF); } else { + // MBED patch if(hi2c->XferOptions != I2C_NEXT_FRAME) + // MBED patch { /* Disable Acknowledge */ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - - if(hi2c->XferOptions == I2C_NEXT_FRAME) + // MBED patch } + // MBED patch else + if(hi2c->XferOptions == I2C_NEXT_FRAME) // MBED patch { + // MBED patch /* Enable Acknowledge */ + // MBED patch hi2c->Instance->CR1 |= I2C_CR1_ACK; /* Enable Pos */ hi2c->Instance->CR1 |= I2C_CR1_POS; } @@ -4076,17 +4100,28 @@ static HAL_StatusTypeDef I2C_MasterReceive_BTF(I2C_HandleTypeDef *hi2c) /* Prepare next transfer or stop current transfer */ if((CurrentXferOptions != I2C_FIRST_AND_LAST_FRAME) && (CurrentXferOptions != I2C_LAST_FRAME) && (CurrentXferOptions != I2C_NO_OPTION_FRAME)) { + // MBED patch if(CurrentXferOptions != I2C_NEXT_FRAME) + // MBED patch { /* Disable Acknowledge */ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - - if((CurrentXferOptions == I2C_NEXT_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME)) + // MBED patch } + // MBED patch else + if((CurrentXferOptions == I2C_NEXT_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME)) // MBED patch { - /* Generate ReStart */ - hi2c->Instance->CR1 |= I2C_CR1_START; + // MBED patch /* Enable Acknowledge */ + // MBED patch hi2c->Instance->CR1 |= I2C_CR1_ACK; + /* Generate ReStart */ // MBED patch + hi2c->Instance->CR1 |= I2C_CR1_START; // MBED patch } + + /* Disable EVT and ERR interrupt */ + // MBED patch __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); } else { + /* Disable EVT and ERR interrupt */ + // MBED patch __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); + /* Generate Stop */ hi2c->Instance->CR1 |= I2C_CR1_STOP; } @@ -4099,8 +4134,8 @@ static HAL_StatusTypeDef I2C_MasterReceive_BTF(I2C_HandleTypeDef *hi2c) (*hi2c->pBuffPtr++) = hi2c->Instance->DR; hi2c->XferCount--; - /* Disable EVT and ERR interrupt */ - __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); + /* Disable EVT and ERR interrupt */ // MBED patch + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); // MBED patch hi2c->State = HAL_I2C_STATE_READY; hi2c->PreviousState = I2C_STATE_NONE; @@ -4751,7 +4786,7 @@ static void I2C_ITError(I2C_HandleTypeDef *hi2c) * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains * the configuration information for I2C module * @param DevAddress Target device address: The device 7 bits address value - * in datasheet must be shift at right before call interface + * in datasheet must be shifted to the left before calling the interface * @param Timeout Timeout duration * @param Tickstart Tick start value * @retval HAL status @@ -4827,7 +4862,7 @@ static HAL_StatusTypeDef I2C_MasterRequestWrite(I2C_HandleTypeDef *hi2c, uint16_ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains * the configuration information for I2C module * @param DevAddress Target device address: The device 7 bits address value - * in datasheet must be shift at right before call interface + * in datasheet must be shifted to the left before calling the interface * @param Timeout Timeout duration * @param Tickstart Tick start value * @retval HAL status @@ -4933,7 +4968,8 @@ static HAL_StatusTypeDef I2C_MasterRequestRead(I2C_HandleTypeDef *hi2c, uint16_t * @brief Master sends target device address followed by internal memory address for write request. * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains * the configuration information for I2C module - * @param DevAddress Target device address + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface * @param MemAddress Internal memory address * @param MemAddSize Size of internal memory address * @param Timeout Timeout duration @@ -5023,7 +5059,8 @@ static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_ * @brief Master sends target device address followed by internal memory address for read request. * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains * the configuration information for I2C module - * @param DevAddress Target device address + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface * @param MemAddress Internal memory address * @param MemAddSize Size of internal memory address * @param Timeout Timeout duration @@ -5558,4 +5595,3 @@ static HAL_StatusTypeDef I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c) */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_i2c.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_i2c.h index 36842f5acb62..aa47bf329cc7 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_i2c.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_i2c.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_i2c.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of I2C HAL module. ****************************************************************************** * @attention @@ -563,7 +561,9 @@ uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c); /** @defgroup I2C_Private_Constants I2C Private Constants * @{ */ -#define I2C_FLAG_MASK 0x0000FFFFU +#define I2C_FLAG_MASK 0x0000FFFFU +#define I2C_MIN_PCLK_FREQ_STANDARD 2000000U /*!< 2 MHz */ +#define I2C_MIN_PCLK_FREQ_FAST 4000000U /*!< 4 MHz */ /** * @} */ @@ -572,11 +572,13 @@ uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c); /** @defgroup I2C_Private_Macros I2C Private Macros * @{ */ - + +#define I2C_MIN_PCLK_FREQ(__PCLK__, __SPEED__) (((__SPEED__) <= 100000U) ? ((__PCLK__) < I2C_MIN_PCLK_FREQ_STANDARD) : ((__PCLK__) < I2C_MIN_PCLK_FREQ_FAST)) +#define I2C_CCR_CALCULATION(__PCLK__, __SPEED__, __COEFF__) (((((__PCLK__) - 1U)/((__SPEED__) * (__COEFF__))) + 1U) & I2C_CCR_CCR) #define I2C_FREQRANGE(__PCLK__) ((__PCLK__)/1000000U) #define I2C_RISE_TIME(__FREQRANGE__, __SPEED__) (((__SPEED__) <= 100000U) ? ((__FREQRANGE__) + 1U) : ((((__FREQRANGE__) * 300U) / 1000U) + 1U)) -#define I2C_SPEED_STANDARD(__PCLK__, __SPEED__) (((((__PCLK__)/((__SPEED__) << 1U)) & I2C_CCR_CCR) < 4U)? 4U:((__PCLK__) / ((__SPEED__) << 1U))) -#define I2C_SPEED_FAST(__PCLK__, __SPEED__, __DUTYCYCLE__) (((__DUTYCYCLE__) == I2C_DUTYCYCLE_2)? ((__PCLK__) / ((__SPEED__) * 3U)) : (((__PCLK__) / ((__SPEED__) * 25U)) | I2C_DUTYCYCLE_16_9)) +#define I2C_SPEED_STANDARD(__PCLK__, __SPEED__) ((I2C_CCR_CALCULATION((__PCLK__), (__SPEED__), 2U) < 4U)? 4U:I2C_CCR_CALCULATION((__PCLK__), (__SPEED__), 2U)) +#define I2C_SPEED_FAST(__PCLK__, __SPEED__, __DUTYCYCLE__) (((__DUTYCYCLE__) == I2C_DUTYCYCLE_2)? I2C_CCR_CALCULATION((__PCLK__), (__SPEED__), 3U) : (I2C_CCR_CALCULATION((__PCLK__), (__SPEED__), 25U) | I2C_DUTYCYCLE_16_9)) #define I2C_SPEED(__PCLK__, __SPEED__, __DUTYCYCLE__) (((__SPEED__) <= 100000U)? (I2C_SPEED_STANDARD((__PCLK__), (__SPEED__))) : \ ((I2C_SPEED_FAST((__PCLK__), (__SPEED__), (__DUTYCYCLE__)) & I2C_CCR_CCR) == 0U)? 1U : \ ((I2C_SPEED_FAST((__PCLK__), (__SPEED__), (__DUTYCYCLE__))) | I2C_CCR_FS)) diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_i2s.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_i2s.c index 332717572f60..d3389d8e1f7c 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_i2s.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_i2s.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_i2s.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief I2S HAL module driver. * This file provides firmware functions to manage the following * functionalities of the Integrated Interchip Sound (I2S) peripheral: diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_i2s.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_i2s.h index 2bf8d58b50cd..334f918e7c59 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_i2s.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_i2s.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_i2s.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of I2S HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_irda.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_irda.c index 14511eb4a24b..cc750e27b3dd 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_irda.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_irda.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_irda.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief IRDA HAL module driver. * This file provides firmware functions to manage the following * functionalities of the IrDA SIR ENDEC block (IrDA): diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_irda.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_irda.h index 983bc22e820d..763eb5d21ffd 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_irda.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_irda.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_irda.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of IRDA HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_iwdg.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_iwdg.c index debd2aed9b87..d654662cc5d9 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_iwdg.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_iwdg.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_iwdg.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief IWDG HAL module driver. * This file provides firmware functions to manage the following * functionalities of the Independent Watchdog (IWDG) peripheral: @@ -21,9 +19,9 @@ (+) The IWDG is clocked by Low-Speed clock (LSI) and thus stays active even if the main clock fails. - (+) Once the IWDG is started, the LSI is forced ON and both can not be + (+) Once the IWDG is started, the LSI is forced ON and both can not be disabled. The counter starts counting down from the reset value (0xFFF). - When it reaches the end of count value (0x000) a reset signal is + When it reaches the end of count value (0x000) a reset signal is generated (IWDG reset). (+) Whenever the key value 0x0000 AAAA is written in the IWDG_KR register, @@ -119,7 +117,7 @@ /** @defgroup IWDG_Private_Defines IWDG Private Defines * @{ */ -/* Status register need 5 RC LSI divided by prescaler clock to be updated. With +/* Status register need 5 RC LSI divided by prescaler clock to be updated. With higher prescaler (256), and according to HSI variation, we need to wait at least 6 cycles so 48 ms. */ #define HAL_IWDG_DEFAULT_TIMEOUT 48U @@ -166,7 +164,7 @@ HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg) uint32_t tickstart; /* Check the IWDG handle allocation */ - if(hiwdg == NULL) + if (hiwdg == NULL) { return HAL_ERROR; } @@ -190,9 +188,9 @@ HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg) tickstart = HAL_GetTick(); /* Wait for register to be updated */ - while(hiwdg->Instance->SR != RESET) + while (hiwdg->Instance->SR != RESET) { - if((HAL_GetTick() - tickstart ) > HAL_IWDG_DEFAULT_TIMEOUT) + if ((HAL_GetTick() - tickstart) > HAL_IWDG_DEFAULT_TIMEOUT) { return HAL_TIMEOUT; } diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_iwdg.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_iwdg.h index af20632cc2d5..18f9d524a360 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_iwdg.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_iwdg.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_iwdg.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of IWDG HAL module. ****************************************************************************** * @attention @@ -40,7 +38,7 @@ #define __STM32F1xx_HAL_IWDG_H #ifdef __cplusplus - extern "C" { +extern "C" { #endif /* Includes ------------------------------------------------------------------*/ @@ -59,7 +57,7 @@ * @{ */ -/** +/** * @brief IWDG Init structure definition */ typedef struct @@ -81,7 +79,7 @@ typedef struct IWDG_InitTypeDef Init; /*!< IWDG required parameters */ -}IWDG_HandleTypeDef; +} IWDG_HandleTypeDef; /** * @} diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_mmc.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_mmc.c index 61001b49195c..e3540a28baa9 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_mmc.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_mmc.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_mmc.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief MMC card HAL module driver. * This file provides firmware functions to manage the following * functionalities of the Secure Digital (MMC) peripheral: @@ -1312,7 +1310,7 @@ HAL_StatusTypeDef HAL_MMC_Erase(MMC_HandleTypeDef *hmmc, uint32_t BlockStartAdd, hmmc->State = HAL_MMC_STATE_BUSY; /* Check if the card command class supports erase command */ - if((hmmc->MmcCard.Class) & SDIO_CCCC_ERASE == 0U) + if(((hmmc->MmcCard.Class) & SDIO_CCCC_ERASE) == 0U) { /* Clear all the static flags */ __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_mmc.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_mmc.h index 7fa628e88efc..c4d35d8bc63b 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_mmc.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_mmc.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_mmc.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of MMC HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_nand.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_nand.c index 0509cb6cf120..91331d1cba5e 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_nand.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_nand.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_nand.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief NAND HAL module driver. * This file provides a generic firmware to drive NAND memories mounted * as external device. diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_nand.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_nand.h index 88eb5485e4d6..1298da64213a 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_nand.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_nand.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_nand.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of NAND HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_nor.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_nor.c index 9aa2df5633ed..23ece8a7c8cd 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_nor.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_nor.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_nor.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief NOR HAL module driver. * This file provides a generic firmware to drive NOR memories mounted * as external device. diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_nor.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_nor.h index a577715d22ad..be1cf6768e50 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_nor.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_nor.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_nor.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of NOR HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_pccard.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_pccard.c index 198e8041f73c..c361344b4623 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_pccard.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_pccard.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_pccard.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief PCCARD HAL module driver. * This file provides a generic firmware to drive PCCARD memories mounted * as external device. diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_pccard.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_pccard.h index e76a882f370c..3be9483b93ee 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_pccard.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_pccard.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_pccard.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of PCCARD HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_pcd.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_pcd.c index 11c636a8b9ae..254c480274eb 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_pcd.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_pcd.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_pcd.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief PCD HAL module driver. * This file provides firmware functions to manage the following * functionalities of the USB Peripheral Controller: @@ -1152,7 +1150,7 @@ static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t { USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; USB_OTG_EPTypeDef *ep = NULL; - uint32_t len; + uint32_t len; // MBED patch uint32_t len32b = 0U; uint32_t fifoemptymsk = 0U; @@ -1185,7 +1183,7 @@ static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t ep->xfer_count += len; } - if (ep->xfer_count >= ep->xfer_len) + if (ep->xfer_count >= ep->xfer_len) // MBED patch { fifoemptymsk = 0x01U << epnum; USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk; diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_pcd.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_pcd.h index d92c82fdcd6e..abd86275aff4 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_pcd.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_pcd.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_pcd.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of PCD HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_pcd_ex.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_pcd_ex.c index edadc8fb5294..e8dbcb45bc0f 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_pcd_ex.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_pcd_ex.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_pcd_ex.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Extended PCD HAL module driver. * This file provides firmware functions to manage the following * functionalities of the USB Peripheral Controller: diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_pcd_ex.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_pcd_ex.h index 09aae9018f98..fbb4048b8685 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_pcd_ex.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_pcd_ex.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_pcd_ex.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of Extended PCD HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_pwr.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_pwr.c index 84b2d130d3c6..ae3851ef905a 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_pwr.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_pwr.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_pwr.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief PWR HAL module driver. * * This file provides firmware functions to manage the following diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_pwr.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_pwr.h index af065b89d571..b50541b65580 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_pwr.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_pwr.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_pwr.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of PWR HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_rcc.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_rcc.c index 5d6e69f1bd74..f3e2232272e3 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_rcc.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_rcc.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_rcc.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief RCC HAL module driver. * This file provides firmware functions to manage the following * functionalities of the Reset and Clock Control (RCC) peripheral: @@ -207,42 +205,144 @@ static void RCC_Delay(uint32_t mdelay); * @brief Resets the RCC clock configuration to the default reset state. * @note The default reset state of the clock configuration is given below: * - HSI ON and used as system clock source - * - HSE and PLL OFF + * - HSE, PLL, PLL2 and PLL3 are OFF * - AHB, APB1 and APB2 prescaler set to 1. * - CSS and MCO1 OFF * - All interrupts disabled + * - All flags are cleared * @note This function does not modify the configuration of the * - Peripheral clocks * - LSI, LSE and RTC clocks - * @retval None + * @retval HAL_StatusTypeDef */ -void HAL_RCC_DeInit(void) +HAL_StatusTypeDef HAL_RCC_DeInit(void) { - /* Switch SYSCLK to HSI */ - CLEAR_BIT(RCC->CFGR, RCC_CFGR_SW); + uint32_t tickstart; + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Set HSION bit */ + SET_BIT(RCC->CR, RCC_CR_HSION); + + /* Wait till HSI is ready */ + while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == RESET) + { + if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } - /* Reset HSEON, CSSON, & PLLON bits */ - CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_CSSON | RCC_CR_PLLON); - - /* Reset HSEBYP bit */ - CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP); - - /* Reset CFGR register */ - CLEAR_REG(RCC->CFGR); - /* Set HSITRIM bits to the reset value */ MODIFY_REG(RCC->CR, RCC_CR_HSITRIM, (0x10U << RCC_CR_HSITRIM_Pos)); - -#if defined(RCC_CFGR2_SUPPORT) + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Reset CFGR register */ + CLEAR_REG(RCC->CFGR); + + /* Wait till clock switch is ready */ + while (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != RESET) + { + if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Update the SystemCoreClock global variable */ + SystemCoreClock = HSI_VALUE; + + /* Adapt Systick interrupt period */ + if(HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK) + { + return HAL_ERROR; + } + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Second step is to clear PLLON bit */ + CLEAR_BIT(RCC->CR, RCC_CR_PLLON); + + /* Wait till PLL is disabled */ + while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != RESET) + { + if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Ensure to reset PLLSRC and PLLMUL bits */ + CLEAR_REG(RCC->CFGR); + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Reset HSEON & CSSON bits */ + CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_CSSON); + + /* Wait till HSE is disabled */ + while (READ_BIT(RCC->CR, RCC_CR_HSERDY) != RESET) + { + if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Reset HSEBYP bit */ + CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP); + +#if defined(RCC_PLL2_SUPPORT) + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Clear PLL2ON bit */ + CLEAR_BIT(RCC->CR, RCC_CR_PLL2ON); + + /* Wait till PLL2 is disabled */ + while (READ_BIT(RCC->CR, RCC_CR_PLL2RDY) != RESET) + { + if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } +#endif /* RCC_PLL2_SUPPORT */ + +#if defined(RCC_PLLI2S_SUPPORT) + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Clear PLL3ON bit */ + CLEAR_BIT(RCC->CR, RCC_CR_PLL3ON); + + /* Wait till PLL3 is disabled */ + while (READ_BIT(RCC->CR, RCC_CR_PLL3RDY) != RESET) + { + if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } +#endif /* RCC_PLLI2S_SUPPORT */ + +#if defined(RCC_CFGR2_PREDIV1) /* Reset CFGR2 register */ CLEAR_REG(RCC->CFGR2); +#endif /* RCC_CFGR2_PREDIV1 */ + + /* Reset all CSR flags */ + SET_BIT(RCC->CSR, RCC_CSR_RMVF); -#endif /* RCC_CFGR2_SUPPORT */ /* Disable all interrupts */ CLEAR_REG(RCC->CIR); - /* Update the SystemCoreClock global variable */ - SystemCoreClock = HSI_VALUE; + return HAL_OK; } /** @@ -998,9 +1098,9 @@ uint32_t HAL_RCC_GetSysClockFreq(void) #if defined(RCC_CFGR2_PREDIV1SRC) uint32_t prediv2 = 0U, pll2mul = 0U; #endif /*RCC_CFGR2_PREDIV1SRC*/ - + tmpreg = RCC->CFGR; - + /* Get SYSCLK source -------------------------------------------------------*/ switch (tmpreg & RCC_CFGR_SWS) { @@ -1027,14 +1127,14 @@ uint32_t HAL_RCC_GetSysClockFreq(void) /* PLLCLK = PLL2CLK / PREDIV1 * PLLMUL with PLL2CLK = HSE/PREDIV2 * PLL2MUL */ prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> RCC_CFGR2_PREDIV2_Pos) + 1; pll2mul = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> RCC_CFGR2_PLL2MUL_Pos) + 2; - pllclk = (uint32_t)((((HSE_VALUE / prediv2) * pll2mul) / prediv) * pllmul); + pllclk = (uint32_t)(((uint64_t)HSE_VALUE * (uint64_t)pll2mul * (uint64_t)pllmul) / ((uint64_t)prediv2 * (uint64_t)prediv)); } else { /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */ - pllclk = (uint32_t)((HSE_VALUE / prediv) * pllmul); + pllclk = (uint32_t)((HSE_VALUE * pllmul) / prediv); } - + /* If PLLMUL was set to 13 means that it was to cover the case PLLMUL 6.5 (avoid using float) */ /* In this case need to divide pllclk by 2 */ if (pllmul == aPLLMULFactorTable[(uint32_t)(RCC_CFGR_PLLMULL6_5) >> RCC_CFGR_PLLMULL_Pos]) @@ -1043,7 +1143,7 @@ uint32_t HAL_RCC_GetSysClockFreq(void) } #else /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */ - pllclk = (uint32_t)((HSE_VALUE / prediv) * pllmul); + pllclk = (uint32_t)((HSE_VALUE * pllmul) / prediv); #endif /*RCC_CFGR2_PREDIV1SRC*/ } else diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_rcc.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_rcc.h index ebfc2805e64d..e4190722870e 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_rcc.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_rcc.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_rcc.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of RCC HAL module. ****************************************************************************** * @attention @@ -1170,7 +1168,7 @@ typedef struct */ /* Initialization and de-initialization functions ******************************/ -void HAL_RCC_DeInit(void); +HAL_StatusTypeDef HAL_RCC_DeInit(void); HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct); HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency); diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_rcc_ex.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_rcc_ex.c index 65114651c585..29ba34efef0d 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_rcc_ex.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_rcc_ex.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_rcc_ex.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Extended RCC HAL module driver. * This file provides firmware functions to manage the following * functionalities RCC extension peripheral: diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_rcc_ex.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_rcc_ex.h index 098ecd762e41..b3c198ade4ae 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_rcc_ex.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_rcc_ex.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_rcc_ex.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of RCC HAL Extension module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_rtc.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_rtc.c index 2f609f4d855a..d0da8f52353b 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_rtc.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_rtc.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_rtc.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief RTC HAL module driver. * This file provides firmware functions to manage the following * functionalities of the Real Time Clock (RTC) peripheral: diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_rtc.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_rtc.h index 1889c0ca20cf..792a9338db10 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_rtc.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_rtc.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_rtc.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of RTC HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_rtc_ex.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_rtc_ex.c index 1a8d9dca54be..3440898a4729 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_rtc_ex.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_rtc_ex.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_rtc_ex.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Extended RTC HAL module driver. * This file provides firmware functions to manage the following * functionalities of the Real Time Clock (RTC) Extension peripheral: diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_rtc_ex.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_rtc_ex.h index d6b8d437bc41..825b83d946f9 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_rtc_ex.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_rtc_ex.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_rtc_ex.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of RTC HAL Extension module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_sd.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_sd.c index 4a26b229d488..f1678807315b 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_sd.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_sd.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_sd.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief SD card HAL module driver. * This file provides firmware functions to manage the following * functionalities of the Secure Digital (SD) peripheral: diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_sd.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_sd.h index 1084d683c418..e240e2c70b74 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_sd.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_sd.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_sd.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of SD HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_smartcard.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_smartcard.c index 106f15e691b8..233f21a58325 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_smartcard.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_smartcard.c @@ -2,10 +2,8 @@ ****************************************************************************** * @file stm32f1xx_hal_smartcard.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief SMARTCARD HAL module driver. - * This file provides firmware functions to manage the following + * This file provides firmware functions to manage the following * functionalities of the SMARTCARD peripheral: * + Initialization and de-initialization functions * + IO operation functions @@ -39,14 +37,14 @@ (+++) Configure the USARTx interrupt priority and enable the NVIC USART IRQ handle (used for last byte sending completion detection in DMA non circular mode) - (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware + (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware flow control and Mode(Receiver/Transmitter) in the SMARTCARD Init structure. (#) Initialize the SMARTCARD registers by calling the HAL_SMARTCARD_Init() API: (++) These APIs configure also the low level Hardware GPIO, CLOCK, CORTEX...etc) by calling the customized HAL_SMARTCARD_MspInit() API. - [..] - (@)The specific SMARTCARD interrupts (Transmission complete interrupt, + [..] + (@)The specific SMARTCARD interrupts (Transmission complete interrupt, RXNE interrupt and Error Interrupts) will be managed using the macros __HAL_SMARTCARD_ENABLE_IT() and __HAL_SMARTCARD_DISABLE_IT() inside the transmit and receive process. @@ -67,12 +65,12 @@ (+) Receive an amount of data in non blocking mode using HAL_SMARTCARD_Receive_IT() (+) At reception end of transfer HAL_SMARTCARD_RxCpltCallback is executed and user can add his own code by customization of function pointer HAL_SMARTCARD_RxCpltCallback - (+) In case of transfer Error, HAL_SMARTCARD_ErrorCallback() function is executed and user can + (+) In case of transfer Error, HAL_SMARTCARD_ErrorCallback() function is executed and user can add his own code by customization of function pointer HAL_SMARTCARD_ErrorCallback - *** DMA mode IO operation *** + *** DMA mode IO operation *** ============================== - [..] + [..] (+) Send an amount of data in non blocking mode (DMA) using HAL_SMARTCARD_Transmit_DMA() (+) At transmission end of transfer HAL_SMARTCARD_TxCpltCallback is executed and user can add his own code by customization of function pointer HAL_SMARTCARD_TxCpltCallback @@ -93,10 +91,10 @@ (+) __HAL_SMARTCARD_CLEAR_FLAG : Clear the specified SMARTCARD pending flag (+) __HAL_SMARTCARD_ENABLE_IT: Enable the specified SMARTCARD interrupt (+) __HAL_SMARTCARD_DISABLE_IT: Disable the specified SMARTCARD interrupt - - [..] + + [..] (@) You can refer to the SMARTCARD HAL driver header file for more useful macros - + @endverbatim [..] (@) Additionnal remark: If the parity is enabled, then the MSB bit of the data written @@ -166,7 +164,7 @@ */ static void SMARTCARD_EndTxTransfer(SMARTCARD_HandleTypeDef *hsc); static void SMARTCARD_EndRxTransfer(SMARTCARD_HandleTypeDef *hsc); -static void SMARTCARD_SetConfig (SMARTCARD_HandleTypeDef *hsc); +static void SMARTCARD_SetConfig(SMARTCARD_HandleTypeDef *hsc); static HAL_StatusTypeDef SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc); static HAL_StatusTypeDef SMARTCARD_EndTransmit_IT(SMARTCARD_HandleTypeDef *hsmartcard); static HAL_StatusTypeDef SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc); @@ -187,22 +185,22 @@ static HAL_StatusTypeDef SMARTCARD_WaitOnFlagUntilTimeout(SMARTCARD_HandleTypeDe * @{ */ -/** @defgroup SMARTCARD_Exported_Functions_Group1 SmartCard Initialization and de-initialization functions - * @brief Initialization and Configuration functions +/** @defgroup SMARTCARD_Exported_Functions_Group1 SmartCard Initialization and de-initialization functions + * @brief Initialization and Configuration functions * @verbatim ============================================================================== ##### Initialization and Configuration functions ##### ============================================================================== [..] - This subsection provides a set of functions allowing to initialize the USART + This subsection provides a set of functions allowing to initialize the USART in Smartcard mode. [..] The Smartcard interface is designed to support asynchronous protocol Smartcards as defined in the ISO 7816-3 standard. [..] The USART can provide a clock to the smartcard through the SCLK output. - In smartcard mode, SCLK is not associated to the communication but is simply derived + In smartcard mode, SCLK is not associated to the communication but is simply derived from the internal peripheral input clock through a 5-bit prescaler. [..] (+) For the Smartcard mode only these parameters can be configured: @@ -228,11 +226,11 @@ static HAL_StatusTypeDef SMARTCARD_WaitOnFlagUntilTimeout(SMARTCARD_HandleTypeDe Please refer to the ISO 7816-3 specification for more details. [..] - (@) It is also possible to choose 0.5 stop bit for receiving but it is recommended - to use 1.5 stop bits for both transmitting and receiving to avoid switching + (@) It is also possible to choose 0.5 stop bit for receiving but it is recommended + to use 1.5 stop bits for both transmitting and receiving to avoid switching between the two configurations. [..] - The HAL_SMARTCARD_Init() function follows the USART SmartCard configuration + The HAL_SMARTCARD_Init() function follows the USART SmartCard configuration procedure (details for the procedure are available in reference manual (RM0329)). @endverbatim @@ -249,7 +247,7 @@ static HAL_StatusTypeDef SMARTCARD_WaitOnFlagUntilTimeout(SMARTCARD_HandleTypeDe HAL_StatusTypeDef HAL_SMARTCARD_Init(SMARTCARD_HandleTypeDef *hsc) { /* Check the SMARTCARD handle allocation */ - if(hsc == NULL) + if (hsc == NULL) { return HAL_ERROR; } @@ -258,8 +256,8 @@ HAL_StatusTypeDef HAL_SMARTCARD_Init(SMARTCARD_HandleTypeDef *hsc) assert_param(IS_SMARTCARD_INSTANCE(hsc->Instance)); - if(hsc->gState == HAL_SMARTCARD_STATE_RESET) - { + if (hsc->gState == HAL_SMARTCARD_STATE_RESET) + { /* Allocate lock resource and initialize it */ hsc->Lock = HAL_UNLOCKED; @@ -273,12 +271,12 @@ HAL_StatusTypeDef HAL_SMARTCARD_Init(SMARTCARD_HandleTypeDef *hsc) MODIFY_REG(hsc->Instance->GTPR, USART_GTPR_PSC, hsc->Init.Prescaler); /* Set the Guard Time */ - MODIFY_REG(hsc->Instance->GTPR, USART_GTPR_GT, ((hsc->Init.GuardTime)<<8U)); + MODIFY_REG(hsc->Instance->GTPR, USART_GTPR_GT, ((hsc->Init.GuardTime) << 8U)); /* Set the Smartcard Communication parameters */ SMARTCARD_SetConfig(hsc); - /* In SmartCard mode, the following bits must be kept cleared: + /* In SmartCard mode, the following bits must be kept cleared: - LINEN bit in the USART_CR2 register - HDSEL and IREN bits in the USART_CR3 register.*/ CLEAR_BIT(hsc->Instance->CR2, USART_CR2_LINEN); @@ -301,8 +299,8 @@ HAL_StatusTypeDef HAL_SMARTCARD_Init(SMARTCARD_HandleTypeDef *hsc) /* Initialize the SMARTCARD state*/ hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE; - hsc->gState= HAL_SMARTCARD_STATE_READY; - hsc->RxState= HAL_SMARTCARD_STATE_READY; + hsc->gState = HAL_SMARTCARD_STATE_READY; + hsc->RxState = HAL_SMARTCARD_STATE_READY; return HAL_OK; } @@ -316,7 +314,7 @@ HAL_StatusTypeDef HAL_SMARTCARD_Init(SMARTCARD_HandleTypeDef *hsc) HAL_StatusTypeDef HAL_SMARTCARD_DeInit(SMARTCARD_HandleTypeDef *hsc) { /* Check the SMARTCARD handle allocation */ - if(hsc == NULL) + if (hsc == NULL) { return HAL_ERROR; } @@ -373,8 +371,8 @@ __weak void HAL_SMARTCARD_MspDeInit(SMARTCARD_HandleTypeDef *hsc) * @} */ -/** @defgroup SMARTCARD_Exported_Functions_Group2 IO operation functions - * @brief SMARTCARD Transmit and Receive functions +/** @defgroup SMARTCARD_Exported_Functions_Group2 IO operation functions + * @brief SMARTCARD Transmit and Receive functions * @verbatim =============================================================================== @@ -384,23 +382,23 @@ __weak void HAL_SMARTCARD_MspDeInit(SMARTCARD_HandleTypeDef *hsc) This subsection provides a set of functions allowing to manage the SMARTCARD data transfers. [..] - (#) Smartcard is a single wire half duplex communication protocol. + (#) Smartcard is a single wire half duplex communication protocol. The Smartcard interface is designed to support asynchronous protocol Smartcards as - defined in the ISO 7816-3 standard. + defined in the ISO 7816-3 standard. (#) The USART should be configured as: (++) 8 bits plus parity: where M=1 and PCE=1 in the USART_CR1 register (++) 1.5 stop bits when transmitting and receiving: where STOP=11 in the USART_CR2 register. (#) There are two modes of transfer: - (++) Blocking mode: The communication is performed in polling mode. - The HAL status of all data processing is returned by the same function - after finishing transfer. - (++) Non Blocking mode: The communication is performed using Interrupts + (++) Blocking mode: The communication is performed in polling mode. + The HAL status of all data processing is returned by the same function + after finishing transfer. + (++) Non Blocking mode: The communication is performed using Interrupts or DMA, These APIs return the HAL status. - The end of the data processing will be indicated through the - dedicated SMARTCARD IRQ when using Interrupt mode or the DMA IRQ when + The end of the data processing will be indicated through the + dedicated SMARTCARD IRQ when using Interrupt mode or the DMA IRQ when using DMA mode. - The HAL_SMARTCARD_TxCpltCallback(), HAL_SMARTCARD_RxCpltCallback() user callbacks + The HAL_SMARTCARD_TxCpltCallback(), HAL_SMARTCARD_RxCpltCallback() user callbacks will be executed respectively at the end of the Transmit or Receive process The HAL_SMARTCARD_ErrorCallback() user callback will be executed when a communication error is detected @@ -437,12 +435,11 @@ __weak void HAL_SMARTCARD_MspDeInit(SMARTCARD_HandleTypeDef *hsc) */ HAL_StatusTypeDef HAL_SMARTCARD_Transmit(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size, uint32_t Timeout) { - uint16_t* tmp; uint32_t tickstart = 0U; - - if(hsc->gState == HAL_SMARTCARD_STATE_READY) + + if (hsc->gState == HAL_SMARTCARD_STATE_READY) { - if((pData == NULL) || (Size == 0U)) + if ((pData == NULL) || (Size == 0U)) { return HAL_ERROR; } @@ -458,26 +455,25 @@ HAL_StatusTypeDef HAL_SMARTCARD_Transmit(SMARTCARD_HandleTypeDef *hsc, uint8_t * hsc->TxXferSize = Size; hsc->TxXferCount = Size; - while(hsc->TxXferCount > 0U) + while (hsc->TxXferCount > 0U) { hsc->TxXferCount--; - if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK) + if (SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK) { return HAL_TIMEOUT; } - tmp = (uint16_t*) pData; - hsc->Instance->DR = (*tmp & (uint16_t)0x01FF); - pData +=1U; + hsc->Instance->DR = *(uint8_t *) pData; + pData += 1U; } - - if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK) + + if (SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK) { return HAL_TIMEOUT; } - /* At end of Tx process, restore hsc->gState to Ready */ + /* At end of Tx process, restore hsc->gState to Ready */ hsc->gState = HAL_SMARTCARD_STATE_READY; - + /* Process Unlocked */ __HAL_UNLOCK(hsc); @@ -490,7 +486,7 @@ HAL_StatusTypeDef HAL_SMARTCARD_Transmit(SMARTCARD_HandleTypeDef *hsc, uint8_t * } /** - * @brief Receive an amount of data in blocking mode + * @brief Receive an amount of data in blocking mode * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains * the configuration information for SMARTCARD module. * @param pData: pointer to data buffer @@ -501,17 +497,17 @@ HAL_StatusTypeDef HAL_SMARTCARD_Transmit(SMARTCARD_HandleTypeDef *hsc, uint8_t * HAL_StatusTypeDef HAL_SMARTCARD_Receive(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size, uint32_t Timeout) { uint32_t tickstart = 0U; - - if(hsc->RxState == HAL_SMARTCARD_STATE_READY) + + if (hsc->RxState == HAL_SMARTCARD_STATE_READY) { - if((pData == NULL) || (Size == 0U)) + if ((pData == NULL) || (Size == 0U)) { return HAL_ERROR; } /* Process Locked */ __HAL_LOCK(hsc); - + hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE; hsc->RxState = HAL_SMARTCARD_STATE_BUSY_RX; @@ -522,20 +518,20 @@ HAL_StatusTypeDef HAL_SMARTCARD_Receive(SMARTCARD_HandleTypeDef *hsc, uint8_t *p hsc->RxXferCount = Size; /* Check the remain data to be received */ - while(hsc->RxXferCount > 0U) + while (hsc->RxXferCount > 0U) { hsc->RxXferCount--; - if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK) + if (SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK) { return HAL_TIMEOUT; } - *pData = (uint8_t)(hsc->Instance->DR & (uint8_t)0xFF); - pData +=1U; + *(uint8_t *) pData = (uint8_t)hsc->Instance->DR; + pData += 1U; } /* At end of Rx process, restore hsc->RxState to Ready */ hsc->RxState = HAL_SMARTCARD_STATE_READY; - + /* Process Unlocked */ __HAL_UNLOCK(hsc); @@ -558,9 +554,9 @@ HAL_StatusTypeDef HAL_SMARTCARD_Receive(SMARTCARD_HandleTypeDef *hsc, uint8_t *p HAL_StatusTypeDef HAL_SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size) { /* Check that a Tx process is not already ongoing */ - if(hsc->gState == HAL_SMARTCARD_STATE_READY) + if (hsc->gState == HAL_SMARTCARD_STATE_READY) { - if((pData == NULL) || (Size == 0U)) + if ((pData == NULL) || (Size == 0U)) { return HAL_ERROR; } @@ -576,7 +572,7 @@ HAL_StatusTypeDef HAL_SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc, uint8_ /* Process Unlocked */ __HAL_UNLOCK(hsc); - + /* Enable the SMARTCARD Parity Error Interrupt */ SET_BIT(hsc->Instance->CR1, USART_CR1_PEIE); @@ -595,7 +591,7 @@ HAL_StatusTypeDef HAL_SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc, uint8_ } /** - * @brief Receive an amount of data in non blocking mode + * @brief Receive an amount of data in non blocking mode * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains * the configuration information for SMARTCARD module. * @param pData: pointer to data buffer @@ -605,9 +601,9 @@ HAL_StatusTypeDef HAL_SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc, uint8_ HAL_StatusTypeDef HAL_SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size) { /* Check that a Rx process is not already ongoing */ - if(hsc->RxState == HAL_SMARTCARD_STATE_READY) + if (hsc->RxState == HAL_SMARTCARD_STATE_READY) { - if((pData == NULL) || (Size == 0U)) + if ((pData == NULL) || (Size == 0U)) { return HAL_ERROR; } @@ -621,12 +617,12 @@ HAL_StatusTypeDef HAL_SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE; hsc->RxState = HAL_SMARTCARD_STATE_BUSY_RX; - + /* Process Unlocked */ __HAL_UNLOCK(hsc); /* Enable the SMARTCARD Parity Error and Data Register not empty Interrupts */ - SET_BIT(hsc->Instance->CR1, USART_CR1_PEIE| USART_CR1_RXNEIE); + SET_BIT(hsc->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE); /* Enable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */ SET_BIT(hsc->Instance->CR3, USART_CR3_EIE); @@ -640,7 +636,7 @@ HAL_StatusTypeDef HAL_SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t } /** - * @brief Send an amount of data in non blocking mode + * @brief Send an amount of data in non blocking mode * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains * the configuration information for SMARTCARD module. * @param pData: pointer to data buffer @@ -650,11 +646,11 @@ HAL_StatusTypeDef HAL_SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t HAL_StatusTypeDef HAL_SMARTCARD_Transmit_DMA(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size) { uint32_t *tmp; - + /* Check that a Tx process is not already ongoing */ - if(hsc->gState == HAL_SMARTCARD_STATE_READY) + if (hsc->gState == HAL_SMARTCARD_STATE_READY) { - if((pData == NULL) || (Size == 0U)) + if ((pData == NULL) || (Size == 0U)) { return HAL_ERROR; } @@ -679,8 +675,8 @@ HAL_StatusTypeDef HAL_SMARTCARD_Transmit_DMA(SMARTCARD_HandleTypeDef *hsc, uint8 hsc->hdmatx->XferAbortCallback = NULL; /* Enable the SMARTCARD transmit DMA Channel */ - tmp = (uint32_t*)&pData; - HAL_DMA_Start_IT(hsc->hdmatx, *(uint32_t*)tmp, (uint32_t)&hsc->Instance->DR, Size); + tmp = (uint32_t *)&pData; + HAL_DMA_Start_IT(hsc->hdmatx, *(uint32_t *)tmp, (uint32_t)&hsc->Instance->DR, Size); /* Clear the TC flag in the SR register by writing 0 to it */ __HAL_SMARTCARD_CLEAR_FLAG(hsc, SMARTCARD_FLAG_TC); @@ -701,7 +697,7 @@ HAL_StatusTypeDef HAL_SMARTCARD_Transmit_DMA(SMARTCARD_HandleTypeDef *hsc, uint8 } /** - * @brief Receive an amount of data in non blocking mode + * @brief Receive an amount of data in non blocking mode * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains * the configuration information for SMARTCARD module. * @param pData: pointer to data buffer @@ -712,11 +708,11 @@ HAL_StatusTypeDef HAL_SMARTCARD_Transmit_DMA(SMARTCARD_HandleTypeDef *hsc, uint8 HAL_StatusTypeDef HAL_SMARTCARD_Receive_DMA(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size) { uint32_t *tmp; - + /* Check that a Rx process is not already ongoing */ - if(hsc->RxState == HAL_SMARTCARD_STATE_READY) + if (hsc->RxState == HAL_SMARTCARD_STATE_READY) { - if((pData == NULL) || (Size == 0U)) + if ((pData == NULL) || (Size == 0U)) { return HAL_ERROR; } @@ -740,8 +736,8 @@ HAL_StatusTypeDef HAL_SMARTCARD_Receive_DMA(SMARTCARD_HandleTypeDef *hsc, uint8_ hsc->hdmatx->XferAbortCallback = NULL; /* Enable the DMA Channel */ - tmp = (uint32_t*)&pData; - HAL_DMA_Start_IT(hsc->hdmarx, (uint32_t)&hsc->Instance->DR, *(uint32_t*)tmp, Size); + tmp = (uint32_t *)&pData; + HAL_DMA_Start_IT(hsc->hdmarx, (uint32_t)&hsc->Instance->DR, *(uint32_t *)tmp, Size); /* Clear the Overrun flag just before enabling the DMA Rx request: can be mandatory for the second transfer */ __HAL_SMARTCARD_CLEAR_OREFLAG(hsc); @@ -755,7 +751,7 @@ HAL_StatusTypeDef HAL_SMARTCARD_Receive_DMA(SMARTCARD_HandleTypeDef *hsc, uint8_ /* Enable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */ SET_BIT(hsc->Instance->CR3, USART_CR3_EIE); - /* Enable the DMA transfer for the receiver request by setting the DMAR bit + /* Enable the DMA transfer for the receiver request by setting the DMAR bit in the SMARTCARD CR3 register */ SET_BIT(hsc->Instance->CR3, USART_CR3_DMAR); @@ -770,7 +766,7 @@ HAL_StatusTypeDef HAL_SMARTCARD_Receive_DMA(SMARTCARD_HandleTypeDef *hsc, uint8_ /** * @brief Abort ongoing transfers (blocking mode). * @param hsc SMARTCARD handle. - * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. + * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. * This procedure performs following operations : * - Disable PPP Interrupts * - Disable the DMA transfer in the peripheral register (if enabled) @@ -784,16 +780,16 @@ HAL_StatusTypeDef HAL_SMARTCARD_Abort(SMARTCARD_HandleTypeDef *hsc) /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE)); CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE); - + /* Disable the SMARTCARD DMA Tx request if enabled */ - if(HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAT)) + if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAT)) { CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAT); /* Abort the SMARTCARD DMA Tx channel: use blocking DMA Abort API (no callback) */ - if(hsc->hdmatx != NULL) + if (hsc->hdmatx != NULL) { - /* Set the SMARTCARD DMA Abort callback to Null. + /* Set the SMARTCARD DMA Abort callback to Null. No call back execution at end of DMA abort procedure */ hsc->hdmatx->XferAbortCallback = NULL; @@ -802,14 +798,14 @@ HAL_StatusTypeDef HAL_SMARTCARD_Abort(SMARTCARD_HandleTypeDef *hsc) } /* Disable the SMARTCARD DMA Rx request if enabled */ - if(HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR)) + if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR)) { CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAR); /* Abort the SMARTCARD DMA Rx channel: use blocking DMA Abort API (no callback) */ - if(hsc->hdmarx != NULL) + if (hsc->hdmarx != NULL) { - /* Set the SMARTCARD DMA Abort callback to Null. + /* Set the SMARTCARD DMA Abort callback to Null. No call back execution at end of DMA abort procedure */ hsc->hdmarx->XferAbortCallback = NULL; @@ -834,7 +830,7 @@ HAL_StatusTypeDef HAL_SMARTCARD_Abort(SMARTCARD_HandleTypeDef *hsc) /** * @brief Abort ongoing Transmit transfer (blocking mode). * @param hsc SMARTCARD handle. - * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. + * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. * This procedure performs following operations : * - Disable PPP Interrupts * - Disable the DMA transfer in the peripheral register (if enabled) @@ -849,14 +845,14 @@ HAL_StatusTypeDef HAL_SMARTCARD_AbortTransmit(SMARTCARD_HandleTypeDef *hsc) CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE)); /* Disable the SMARTCARD DMA Tx request if enabled */ - if(HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAT)) + if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAT)) { CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAT); /* Abort the SMARTCARD DMA Tx channel: use blocking DMA Abort API (no callback) */ - if(hsc->hdmatx != NULL) + if (hsc->hdmatx != NULL) { - /* Set the SMARTCARD DMA Abort callback to Null. + /* Set the SMARTCARD DMA Abort callback to Null. No call back execution at end of DMA abort procedure */ hsc->hdmatx->XferAbortCallback = NULL; @@ -876,7 +872,7 @@ HAL_StatusTypeDef HAL_SMARTCARD_AbortTransmit(SMARTCARD_HandleTypeDef *hsc) /** * @brief Abort ongoing Receive transfer (blocking mode). * @param hsc SMARTCARD handle. - * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. + * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. * This procedure performs following operations : * - Disable PPP Interrupts * - Disable the DMA transfer in the peripheral register (if enabled) @@ -892,14 +888,14 @@ HAL_StatusTypeDef HAL_SMARTCARD_AbortReceive(SMARTCARD_HandleTypeDef *hsc) CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE); /* Disable the SMARTCARD DMA Rx request if enabled */ - if(HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR)) + if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR)) { CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAR); /* Abort the SMARTCARD DMA Rx channel: use blocking DMA Abort API (no callback) */ - if(hsc->hdmarx != NULL) + if (hsc->hdmarx != NULL) { - /* Set the SMARTCARD DMA Abort callback to Null. + /* Set the SMARTCARD DMA Abort callback to Null. No call back execution at end of DMA abort procedure */ hsc->hdmarx->XferAbortCallback = NULL; @@ -919,7 +915,7 @@ HAL_StatusTypeDef HAL_SMARTCARD_AbortReceive(SMARTCARD_HandleTypeDef *hsc) /** * @brief Abort ongoing transfers (Interrupt mode). * @param hsc SMARTCARD handle. - * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. + * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. * This procedure performs following operations : * - Disable PPP Interrupts * - Disable the DMA transfer in the peripheral register (if enabled) @@ -941,11 +937,11 @@ HAL_StatusTypeDef HAL_SMARTCARD_Abort_IT(SMARTCARD_HandleTypeDef *hsc) /* If DMA Tx and/or DMA Rx Handles are associated to SMARTCARD Handle, DMA Abort complete callbacks should be initialised before any call to DMA Abort functions */ /* DMA Tx Handle is valid */ - if(hsc->hdmatx != NULL) + if (hsc->hdmatx != NULL) { /* Set DMA Abort Complete callback if SMARTCARD DMA Tx request if enabled. Otherwise, set it to NULL */ - if(HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAT)) + if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAT)) { hsc->hdmatx->XferAbortCallback = SMARTCARD_DMATxAbortCallback; } @@ -955,11 +951,11 @@ HAL_StatusTypeDef HAL_SMARTCARD_Abort_IT(SMARTCARD_HandleTypeDef *hsc) } } /* DMA Rx Handle is valid */ - if(hsc->hdmarx != NULL) + if (hsc->hdmarx != NULL) { /* Set DMA Abort Complete callback if SMARTCARD DMA Rx request if enabled. Otherwise, set it to NULL */ - if(HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR)) + if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR)) { hsc->hdmarx->XferAbortCallback = SMARTCARD_DMARxAbortCallback; } @@ -970,19 +966,19 @@ HAL_StatusTypeDef HAL_SMARTCARD_Abort_IT(SMARTCARD_HandleTypeDef *hsc) } /* Disable the SMARTCARD DMA Tx request if enabled */ - if(HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAT)) + if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAT)) { /* Disable DMA Tx at SMARTCARD level */ CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAT); /* Abort the SMARTCARD DMA Tx channel : use non blocking DMA Abort API (callback) */ - if(hsc->hdmatx != NULL) + if (hsc->hdmatx != NULL) { - /* SMARTCARD Tx DMA Abort callback has already been initialised : + /* SMARTCARD Tx DMA Abort callback has already been initialised : will lead to call HAL_SMARTCARD_AbortCpltCallback() at end of DMA abort procedure */ /* Abort DMA TX */ - if(HAL_DMA_Abort_IT(hsc->hdmatx) != HAL_OK) + if (HAL_DMA_Abort_IT(hsc->hdmatx) != HAL_OK) { hsc->hdmatx->XferAbortCallback = NULL; } @@ -994,18 +990,18 @@ HAL_StatusTypeDef HAL_SMARTCARD_Abort_IT(SMARTCARD_HandleTypeDef *hsc) } /* Disable the SMARTCARD DMA Rx request if enabled */ - if(HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR)) + if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR)) { CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAR); /* Abort the SMARTCARD DMA Rx channel : use non blocking DMA Abort API (callback) */ - if(hsc->hdmarx != NULL) + if (hsc->hdmarx != NULL) { - /* SMARTCARD Rx DMA Abort callback has already been initialised : + /* SMARTCARD Rx DMA Abort callback has already been initialised : will lead to call HAL_SMARTCARD_AbortCpltCallback() at end of DMA abort procedure */ /* Abort DMA RX */ - if(HAL_DMA_Abort_IT(hsc->hdmarx) != HAL_OK) + if (HAL_DMA_Abort_IT(hsc->hdmarx) != HAL_OK) { hsc->hdmarx->XferAbortCallback = NULL; AbortCplt = 0x01U; @@ -1018,10 +1014,10 @@ HAL_StatusTypeDef HAL_SMARTCARD_Abort_IT(SMARTCARD_HandleTypeDef *hsc) } /* if no DMA abort complete callback execution is required => call user Abort Complete callback */ - if(AbortCplt == 0x01U) + if (AbortCplt == 0x01U) { /* Reset Tx and Rx transfer counters */ - hsc->TxXferCount = 0x00U; + hsc->TxXferCount = 0x00U; hsc->RxXferCount = 0x00U; /* Reset ErrorCode */ @@ -1040,7 +1036,7 @@ HAL_StatusTypeDef HAL_SMARTCARD_Abort_IT(SMARTCARD_HandleTypeDef *hsc) /** * @brief Abort ongoing Transmit transfer (Interrupt mode). * @param hsc SMARTCARD handle. - * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. + * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. * This procedure performs following operations : * - Disable PPP Interrupts * - Disable the DMA transfer in the peripheral register (if enabled) @@ -1057,19 +1053,19 @@ HAL_StatusTypeDef HAL_SMARTCARD_AbortTransmit_IT(SMARTCARD_HandleTypeDef *hsc) CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE)); /* Disable the SMARTCARD DMA Tx request if enabled */ - if(HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAT)) + if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAT)) { CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAT); /* Abort the SMARTCARD DMA Tx channel : use blocking DMA Abort API (no callback) */ - if(hsc->hdmatx != NULL) + if (hsc->hdmatx != NULL) { - /* Set the SMARTCARD DMA Abort callback : + /* Set the SMARTCARD DMA Abort callback : will lead to call HAL_SMARTCARD_AbortCpltCallback() at end of DMA abort procedure */ hsc->hdmatx->XferAbortCallback = SMARTCARD_DMATxOnlyAbortCallback; /* Abort DMA TX */ - if(HAL_DMA_Abort_IT(hsc->hdmatx) != HAL_OK) + if (HAL_DMA_Abort_IT(hsc->hdmatx) != HAL_OK) { /* Call Directly hsc->hdmatx->XferAbortCallback function in case of error */ hsc->hdmatx->XferAbortCallback(hsc->hdmatx); @@ -1105,7 +1101,7 @@ HAL_StatusTypeDef HAL_SMARTCARD_AbortTransmit_IT(SMARTCARD_HandleTypeDef *hsc) /** * @brief Abort ongoing Receive transfer (Interrupt mode). * @param hsc SMARTCARD handle. - * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. + * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. * This procedure performs following operations : * - Disable PPP Interrupts * - Disable the DMA transfer in the peripheral register (if enabled) @@ -1123,19 +1119,19 @@ HAL_StatusTypeDef HAL_SMARTCARD_AbortReceive_IT(SMARTCARD_HandleTypeDef *hsc) CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE); /* Disable the SMARTCARD DMA Rx request if enabled */ - if(HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR)) + if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR)) { CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAR); /* Abort the SMARTCARD DMA Rx channel : use blocking DMA Abort API (no callback) */ - if(hsc->hdmarx != NULL) + if (hsc->hdmarx != NULL) { - /* Set the SMARTCARD DMA Abort callback : + /* Set the SMARTCARD DMA Abort callback : will lead to call HAL_SMARTCARD_AbortCpltCallback() at end of DMA abort procedure */ hsc->hdmarx->XferAbortCallback = SMARTCARD_DMARxOnlyAbortCallback; /* Abort DMA RX */ - if(HAL_DMA_Abort_IT(hsc->hdmarx) != HAL_OK) + if (HAL_DMA_Abort_IT(hsc->hdmarx) != HAL_OK) { /* Call Directly hsc->hdmarx->XferAbortCallback function in case of error */ hsc->hdmarx->XferAbortCallback(hsc->hdmarx); @@ -1184,10 +1180,10 @@ void HAL_SMARTCARD_IRQHandler(SMARTCARD_HandleTypeDef *hsc) /* If no error occurs */ errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE)); - if(errorflags == RESET) + if (errorflags == RESET) { /* SMARTCARD in mode Receiver -------------------------------------------------*/ - if(((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)) + if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)) { SMARTCARD_Receive_IT(hsc); return; @@ -1195,37 +1191,37 @@ void HAL_SMARTCARD_IRQHandler(SMARTCARD_HandleTypeDef *hsc) } /* If some errors occur */ - if((errorflags != RESET) && (((cr3its & USART_CR3_EIE) != RESET) || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET))) + if ((errorflags != RESET) && (((cr3its & USART_CR3_EIE) != RESET) || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET))) { /* SMARTCARD parity error interrupt occurred ---------------------------*/ - if(((isrflags & SMARTCARD_FLAG_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET)) + if (((isrflags & SMARTCARD_FLAG_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET)) { hsc->ErrorCode |= HAL_SMARTCARD_ERROR_PE; } /* SMARTCARD noise error interrupt occurred ----------------------------*/ - if(((isrflags & SMARTCARD_FLAG_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)) + if (((isrflags & SMARTCARD_FLAG_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)) { hsc->ErrorCode |= HAL_SMARTCARD_ERROR_NE; } /* SMARTCARD frame error interrupt occurred ----------------------------*/ - if(((isrflags & SMARTCARD_FLAG_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)) + if (((isrflags & SMARTCARD_FLAG_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)) { hsc->ErrorCode |= HAL_SMARTCARD_ERROR_FE; } /* SMARTCARD Over-Run interrupt occurred -------------------------------*/ - if(((isrflags & SMARTCARD_FLAG_ORE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)) - { + if (((isrflags & SMARTCARD_FLAG_ORE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)) + { hsc->ErrorCode |= HAL_SMARTCARD_ERROR_ORE; } /* Call SMARTCARD Error Call back function if need be ------------------*/ - if(hsc->ErrorCode != HAL_SMARTCARD_ERROR_NONE) + if (hsc->ErrorCode != HAL_SMARTCARD_ERROR_NONE) { /* SMARTCARD in mode Receiver ----------------------------------------*/ - if(((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)) + if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)) { SMARTCARD_Receive_IT(hsc); } @@ -1233,7 +1229,7 @@ void HAL_SMARTCARD_IRQHandler(SMARTCARD_HandleTypeDef *hsc) /* If Overrun error occurs, or if any error occurs in DMA mode reception, consider error as blocking */ dmarequest = HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR); - if(((hsc->ErrorCode & HAL_SMARTCARD_ERROR_ORE) != RESET) || dmarequest) + if (((hsc->ErrorCode & HAL_SMARTCARD_ERROR_ORE) != RESET) || dmarequest) { /* Blocking error : transfer is aborted Set the SMARTCARD state ready to be able to start again the process, @@ -1241,17 +1237,17 @@ void HAL_SMARTCARD_IRQHandler(SMARTCARD_HandleTypeDef *hsc) SMARTCARD_EndRxTransfer(hsc); /* Disable the SMARTCARD DMA Rx request if enabled */ - if(HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR)) + if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR)) { CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAR); /* Abort the SMARTCARD DMA Rx channel */ - if(hsc->hdmarx != NULL) + if (hsc->hdmarx != NULL) { - /* Set the SMARTCARD DMA Abort callback : + /* Set the SMARTCARD DMA Abort callback : will lead to call HAL_SMARTCARD_ErrorCallback() at end of DMA abort procedure */ hsc->hdmarx->XferAbortCallback = SMARTCARD_DMAAbortOnError; - if(HAL_DMA_Abort_IT(hsc->hdmarx) != HAL_OK) + if (HAL_DMA_Abort_IT(hsc->hdmarx) != HAL_OK) { /* Call Directly XferAbortCallback function in case of error */ hsc->hdmarx->XferAbortCallback(hsc->hdmarx); @@ -1271,7 +1267,7 @@ void HAL_SMARTCARD_IRQHandler(SMARTCARD_HandleTypeDef *hsc) } else { - /* Non Blocking error : transfer could go on. + /* Non Blocking error : transfer could go on. Error is notified to user through user error callback */ HAL_SMARTCARD_ErrorCallback(hsc); hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE; @@ -1279,16 +1275,16 @@ void HAL_SMARTCARD_IRQHandler(SMARTCARD_HandleTypeDef *hsc) } return; } /* End if some error occurs */ - + /* SMARTCARD in mode Transmitter -------------------------------------------*/ - if(((isrflags & SMARTCARD_FLAG_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET)) + if (((isrflags & SMARTCARD_FLAG_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET)) { SMARTCARD_Transmit_IT(hsc); return; } - + /* SMARTCARD in mode Transmitter (transmission end) ------------------------*/ - if(((isrflags & SMARTCARD_FLAG_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET)) + if (((isrflags & SMARTCARD_FLAG_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET)) { SMARTCARD_EndTransmit_IT(hsc); return; @@ -1307,7 +1303,7 @@ __weak void HAL_SMARTCARD_TxCpltCallback(SMARTCARD_HandleTypeDef *hsc) UNUSED(hsc); /* NOTE : This function Should not be modified, when the callback is needed, the HAL_SMARTCARD_TxCpltCallback could be implemented in the user file - */ + */ } /** @@ -1345,7 +1341,7 @@ __weak void HAL_SMARTCARD_ErrorCallback(SMARTCARD_HandleTypeDef *hsc) * @param hsc SMARTCARD handle. * @retval None */ -__weak void HAL_SMARTCARD_AbortCpltCallback (SMARTCARD_HandleTypeDef *hsc) +__weak void HAL_SMARTCARD_AbortCpltCallback(SMARTCARD_HandleTypeDef *hsc) { /* Prevent unused argument(s) compilation warning */ UNUSED(hsc); @@ -1360,14 +1356,14 @@ __weak void HAL_SMARTCARD_AbortCpltCallback (SMARTCARD_HandleTypeDef *hsc) * @param hsc SMARTCARD handle. * @retval None */ -__weak void HAL_SMARTCARD_AbortTransmitCpltCallback (SMARTCARD_HandleTypeDef *hsc) +__weak void HAL_SMARTCARD_AbortTransmitCpltCallback(SMARTCARD_HandleTypeDef *hsc) { - /* Prevent unused argument(s) compilation warning */ - UNUSED(hsc); + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsc); - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_SMARTCARD_AbortTransmitCpltCallback can be implemented in the user file. - */ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMARTCARD_AbortTransmitCpltCallback can be implemented in the user file. + */ } /** @@ -1375,31 +1371,31 @@ __weak void HAL_SMARTCARD_AbortTransmitCpltCallback (SMARTCARD_HandleTypeDef *hs * @param hsc SMARTCARD handle. * @retval None */ -__weak void HAL_SMARTCARD_AbortReceiveCpltCallback (SMARTCARD_HandleTypeDef *hsc) +__weak void HAL_SMARTCARD_AbortReceiveCpltCallback(SMARTCARD_HandleTypeDef *hsc) { - /* Prevent unused argument(s) compilation warning */ - UNUSED(hsc); + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsc); - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_SMARTCARD_AbortReceiveCpltCallback can be implemented in the user file. - */ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMARTCARD_AbortReceiveCpltCallback can be implemented in the user file. + */ } /** * @} */ -/** @defgroup SMARTCARD_Exported_Functions_Group3 Peripheral State and Errors functions - * @brief SMARTCARD State and Errors functions +/** @defgroup SMARTCARD_Exported_Functions_Group3 Peripheral State and Errors functions + * @brief SMARTCARD State and Errors functions * -@verbatim +@verbatim =============================================================================== ##### Peripheral State and Errors functions ##### - =============================================================================== + =============================================================================== [..] This subsection provides a set of functions allowing to control the SmartCard. (+) HAL_SMARTCARD_GetState() API can be helpful to check in run-time the state of the SmartCard peripheral. - (+) HAL_SMARTCARD_GetError() check in run-time errors that could be occurred during communication. + (+) HAL_SMARTCARD_GetError() check in run-time errors that could be occurred during communication. @endverbatim * @{ */ @@ -1412,10 +1408,10 @@ __weak void HAL_SMARTCARD_AbortReceiveCpltCallback (SMARTCARD_HandleTypeDef *hsc */ HAL_SMARTCARD_StateTypeDef HAL_SMARTCARD_GetState(SMARTCARD_HandleTypeDef *hsc) { - uint32_t temp1= 0x00U, temp2 = 0x00U; + uint32_t temp1 = 0x00U, temp2 = 0x00U; temp1 = hsc->gState; temp2 = hsc->RxState; - + return (HAL_SMARTCARD_StateTypeDef)(temp1 | temp2); } @@ -1435,17 +1431,17 @@ uint32_t HAL_SMARTCARD_GetError(SMARTCARD_HandleTypeDef *hsc) */ /** - * @brief DMA SMARTCARD transmit process complete callback + * @brief DMA SMARTCARD transmit process complete callback * @param hdma: pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA module. * @retval None */ static void SMARTCARD_DMATransmitCplt(DMA_HandleTypeDef *hdma) { - SMARTCARD_HandleTypeDef* hsc = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; - + SMARTCARD_HandleTypeDef *hsc = (SMARTCARD_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + hsc->TxXferCount = 0U; - + /* Disable the DMA transfer for transmit request by setting the DMAT bit in the USART CR3 register */ CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAT); @@ -1455,55 +1451,55 @@ static void SMARTCARD_DMATransmitCplt(DMA_HandleTypeDef *hdma) } /** - * @brief DMA SMARTCARD receive process complete callback + * @brief DMA SMARTCARD receive process complete callback * @param hdma: pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA module. * @retval None */ -static void SMARTCARD_DMAReceiveCplt(DMA_HandleTypeDef *hdma) +static void SMARTCARD_DMAReceiveCplt(DMA_HandleTypeDef *hdma) { - SMARTCARD_HandleTypeDef* hsc = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + SMARTCARD_HandleTypeDef *hsc = (SMARTCARD_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; hsc->RxXferCount = 0U; - + /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE); - - /* Disable the DMA transfer for the receiver request by setting the DMAR bit + + /* Disable the DMA transfer for the receiver request by setting the DMAR bit in the USART CR3 register */ CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAR); /* At end of Rx process, restore hsc->RxState to Ready */ hsc->RxState = HAL_SMARTCARD_STATE_READY; - + HAL_SMARTCARD_RxCpltCallback(hsc); } /** - * @brief DMA SMARTCARD communication error callback + * @brief DMA SMARTCARD communication error callback * @param hdma: pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA module. * @retval None */ -static void SMARTCARD_DMAError(DMA_HandleTypeDef *hdma) +static void SMARTCARD_DMAError(DMA_HandleTypeDef *hdma) { uint32_t dmarequest = 0x00U; - SMARTCARD_HandleTypeDef* hsc = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + SMARTCARD_HandleTypeDef *hsc = (SMARTCARD_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; hsc->RxXferCount = 0U; hsc->TxXferCount = 0U; hsc->ErrorCode = HAL_SMARTCARD_ERROR_DMA; - + /* Stop SMARTCARD DMA Tx request if ongoing */ dmarequest = HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAT); - if((hsc->gState == HAL_SMARTCARD_STATE_BUSY_TX) && dmarequest) + if ((hsc->gState == HAL_SMARTCARD_STATE_BUSY_TX) && dmarequest) { SMARTCARD_EndTxTransfer(hsc); } /* Stop SMARTCARD DMA Rx request if ongoing */ dmarequest = HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR); - if((hsc->RxState == HAL_SMARTCARD_STATE_BUSY_RX) && dmarequest) + if ((hsc->RxState == HAL_SMARTCARD_STATE_BUSY_RX) && dmarequest) { SMARTCARD_EndRxTransfer(hsc); } @@ -1523,23 +1519,23 @@ static void SMARTCARD_DMAError(DMA_HandleTypeDef *hdma) static HAL_StatusTypeDef SMARTCARD_WaitOnFlagUntilTimeout(SMARTCARD_HandleTypeDef *hsc, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout) { /* Wait until flag is set */ - while((__HAL_SMARTCARD_GET_FLAG(hsc, Flag) ? SET : RESET) == Status) + while ((__HAL_SMARTCARD_GET_FLAG(hsc, Flag) ? SET : RESET) == Status) { /* Check for the Timeout */ - if(Timeout != HAL_MAX_DELAY) + if (Timeout != HAL_MAX_DELAY) { - if((Timeout == 0U)||((HAL_GetTick() - Tickstart ) > Timeout)) + if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout)) { /* Disable TXE and RXNE interrupts for the interrupt process */ CLEAR_BIT(hsc->Instance->CR1, USART_CR1_TXEIE); CLEAR_BIT(hsc->Instance->CR1, USART_CR1_RXNEIE); - - hsc->gState= HAL_SMARTCARD_STATE_READY; - hsc->RxState= HAL_SMARTCARD_STATE_READY; - + + hsc->gState = HAL_SMARTCARD_STATE_READY; + hsc->RxState = HAL_SMARTCARD_STATE_READY; + /* Process Unlocked */ __HAL_UNLOCK(hsc); - + return HAL_TIMEOUT; } } @@ -1587,7 +1583,7 @@ static void SMARTCARD_EndRxTransfer(SMARTCARD_HandleTypeDef *hsc) */ static void SMARTCARD_DMAAbortOnError(DMA_HandleTypeDef *hdma) { - SMARTCARD_HandleTypeDef* hsc = (SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + SMARTCARD_HandleTypeDef *hsc = (SMARTCARD_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; hsc->RxXferCount = 0x00U; hsc->TxXferCount = 0x00U; @@ -1604,19 +1600,19 @@ static void SMARTCARD_DMAAbortOnError(DMA_HandleTypeDef *hdma) */ static void SMARTCARD_DMATxAbortCallback(DMA_HandleTypeDef *hdma) { - SMARTCARD_HandleTypeDef* hsc = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; - + SMARTCARD_HandleTypeDef *hsc = (SMARTCARD_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + hsc->hdmatx->XferAbortCallback = NULL; /* Check if an Abort process is still ongoing */ - if(hsc->hdmarx != NULL) + if (hsc->hdmarx != NULL) { - if(hsc->hdmarx->XferAbortCallback != NULL) + if (hsc->hdmarx->XferAbortCallback != NULL) { return; } } - + /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */ hsc->TxXferCount = 0x00U; hsc->RxXferCount = 0x00U; @@ -1642,19 +1638,19 @@ static void SMARTCARD_DMATxAbortCallback(DMA_HandleTypeDef *hdma) */ static void SMARTCARD_DMARxAbortCallback(DMA_HandleTypeDef *hdma) { - SMARTCARD_HandleTypeDef* hsc = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; - + SMARTCARD_HandleTypeDef *hsc = (SMARTCARD_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + hsc->hdmarx->XferAbortCallback = NULL; /* Check if an Abort process is still ongoing */ - if(hsc->hdmatx != NULL) + if (hsc->hdmatx != NULL) { - if(hsc->hdmatx->XferAbortCallback != NULL) + if (hsc->hdmatx->XferAbortCallback != NULL) { return; } } - + /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */ hsc->TxXferCount = 0x00U; hsc->RxXferCount = 0x00U; @@ -1680,7 +1676,7 @@ static void SMARTCARD_DMARxAbortCallback(DMA_HandleTypeDef *hdma) */ static void SMARTCARD_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma) { - SMARTCARD_HandleTypeDef* hsc = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + SMARTCARD_HandleTypeDef *hsc = (SMARTCARD_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; hsc->TxXferCount = 0x00U; @@ -1701,7 +1697,7 @@ static void SMARTCARD_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma) */ static void SMARTCARD_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma) { - SMARTCARD_HandleTypeDef* hsc = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + SMARTCARD_HandleTypeDef *hsc = (SMARTCARD_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; hsc->RxXferCount = 0x00U; @@ -1713,23 +1709,20 @@ static void SMARTCARD_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma) } /** - * @brief Send an amount of data in non blocking mode + * @brief Send an amount of data in non blocking mode * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains * the configuration information for SMARTCARD module. * @retval HAL status */ static HAL_StatusTypeDef SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc) { - uint16_t* tmp; - /* Check that a Tx process is ongoing */ - if(hsc->gState == HAL_SMARTCARD_STATE_BUSY_TX) + if (hsc->gState == HAL_SMARTCARD_STATE_BUSY_TX) { - tmp = (uint16_t*) hsc->pTxBuffPtr; - hsc->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF); + hsc->Instance->DR = *(uint8_t *) hsc->pTxBuffPtr; hsc->pTxBuffPtr += 1U; - - if(--hsc->TxXferCount == 0U) + + if (--hsc->TxXferCount == 0U) { /* Disable the SMARTCARD Transmit data register empty Interrupt */ CLEAR_BIT(hsc->Instance->CR1, USART_CR1_TXEIE); @@ -1754,9 +1747,9 @@ static HAL_StatusTypeDef SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc) */ static HAL_StatusTypeDef SMARTCARD_EndTransmit_IT(SMARTCARD_HandleTypeDef *hsmartcard) { - /* Disable the SMARTCARD Transmit Complete Interrupt */ + /* Disable the SMARTCARD Transmit Complete Interrupt */ CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_TCIE); - + /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */ CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE); @@ -1764,38 +1757,35 @@ static HAL_StatusTypeDef SMARTCARD_EndTransmit_IT(SMARTCARD_HandleTypeDef *hsmar hsmartcard->gState = HAL_SMARTCARD_STATE_READY; HAL_SMARTCARD_TxCpltCallback(hsmartcard); - + return HAL_OK; } /** - * @brief Receive an amount of data in non blocking mode + * @brief Receive an amount of data in non blocking mode * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains * the configuration information for SMARTCARD module. * @retval HAL status */ static HAL_StatusTypeDef SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc) { - uint16_t* tmp; - /* Check that a Rx process is ongoing */ - if(hsc->RxState == HAL_SMARTCARD_STATE_BUSY_RX) + if (hsc->RxState == HAL_SMARTCARD_STATE_BUSY_RX) { - tmp = (uint16_t*) hsc->pRxBuffPtr; - *tmp = (uint8_t)(hsc->Instance->DR & (uint8_t)0x00FF); + *(uint8_t *) hsc->pRxBuffPtr = (uint8_t)hsc->Instance->DR; hsc->pRxBuffPtr += 1U; - - if(--hsc->RxXferCount == 0U) + + if (--hsc->RxXferCount == 0U) { CLEAR_BIT(hsc->Instance->CR1, USART_CR1_RXNEIE); - + /* Disable the SMARTCARD Parity Error Interrupt */ CLEAR_BIT(hsc->Instance->CR1, USART_CR1_PEIE); - + /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */ CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE); - /* Rx process is completed, restore hsc->RxState to Ready */ + /* Rx process is completed, restore hsc->RxState to Ready */ hsc->RxState = HAL_SMARTCARD_STATE_READY; HAL_SMARTCARD_RxCpltCallback(hsc); @@ -1811,7 +1801,7 @@ static HAL_StatusTypeDef SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc) } /** - * @brief Configure the SMARTCARD peripheral + * @brief Configure the SMARTCARD peripheral * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains * the configuration information for SMARTCARD module. * @retval None @@ -1825,7 +1815,7 @@ static void SMARTCARD_SetConfig(SMARTCARD_HandleTypeDef *hsc) assert_param(IS_SMARTCARD_POLARITY(hsc->Init.CLKPolarity)); assert_param(IS_SMARTCARD_PHASE(hsc->Init.CLKPhase)); assert_param(IS_SMARTCARD_LASTBIT(hsc->Init.CLKLastBit)); - assert_param(IS_SMARTCARD_BAUDRATE(hsc->Init.BaudRate)); + assert_param(IS_SMARTCARD_BAUDRATE(hsc->Init.BaudRate)); assert_param(IS_SMARTCARD_WORD_LENGTH(hsc->Init.WordLength)); assert_param(IS_SMARTCARD_STOPBITS(hsc->Init.StopBits)); assert_param(IS_SMARTCARD_PARITY(hsc->Init.Parity)); @@ -1836,7 +1826,7 @@ static void SMARTCARD_SetConfig(SMARTCARD_HandleTypeDef *hsc) /* The LBCL, CPOL and CPHA bits have to be selected when both the transmitter and the receiver are disabled (TE=RE=0) to ensure that the clock pulses function correctly. */ CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_TE | USART_CR1_RE)); - + /*---------------------------- USART CR2 Configuration ---------------------*/ tmpreg = hsc->Instance->CR2; /* Clear CLKEN, CPOL, CPHA and LBCL bits */ @@ -1846,11 +1836,11 @@ static void SMARTCARD_SetConfig(SMARTCARD_HandleTypeDef *hsc) /* Set CPHA bit according to hsc->Init.CLKPhase value */ /* Set LBCL bit according to hsc->Init.CLKLastBit value */ /* Set Stop Bits: Set STOP[13:12] bits according to hsc->Init.StopBits value */ - tmpreg |= (uint32_t)(USART_CR2_CLKEN | hsc->Init.CLKPolarity | - hsc->Init.CLKPhase| hsc->Init.CLKLastBit | hsc->Init.StopBits); + tmpreg |= (uint32_t)(USART_CR2_CLKEN | hsc->Init.CLKPolarity | + hsc->Init.CLKPhase | hsc->Init.CLKLastBit | hsc->Init.StopBits); /* Write to USART CR2 */ WRITE_REG(hsc->Instance->CR2, (uint32_t)tmpreg); - + tmpreg = hsc->Instance->CR2; /* Clear STOP[13:12] bits */ @@ -1858,7 +1848,7 @@ static void SMARTCARD_SetConfig(SMARTCARD_HandleTypeDef *hsc) /* Set Stop Bits: Set STOP[13:12] bits according to hsc->Init.StopBits value */ tmpreg |= (uint32_t)(hsc->Init.StopBits); - + /* Write to USART CR2 */ WRITE_REG(hsc->Instance->CR2, (uint32_t)tmpreg); @@ -1869,22 +1859,22 @@ static void SMARTCARD_SetConfig(SMARTCARD_HandleTypeDef *hsc) tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | \ USART_CR1_RE)); - /* Configure the SMARTCARD Word Length, Parity and mode: - Set the M bits according to hsc->Init.WordLength value + /* Configure the SMARTCARD Word Length, Parity and mode: + Set the M bits according to hsc->Init.WordLength value Set PCE and PS bits according to hsc->Init.Parity value Set TE and RE bits according to hsc->Init.Mode value */ tmpreg |= (uint32_t)hsc->Init.WordLength | hsc->Init.Parity | hsc->Init.Mode; /* Write to USART CR1 */ - WRITE_REG(hsc->Instance->CR1, (uint32_t)tmpreg); + WRITE_REG(hsc->Instance->CR1, (uint32_t)tmpreg); - /*-------------------------- USART CR3 Configuration -----------------------*/ + /*-------------------------- USART CR3 Configuration -----------------------*/ /* Clear CTSE and RTSE bits */ CLEAR_BIT(hsc->Instance->CR3, (USART_CR3_RTSE | USART_CR3_CTSE)); /*-------------------------- USART BRR Configuration -----------------------*/ - if(hsc->Instance == USART1) + if (hsc->Instance == USART1) { hsc->Instance->BRR = SMARTCARD_BRR(HAL_RCC_GetPCLK2Freq(), hsc->Init.BaudRate); } diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_smartcard.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_smartcard.h index 0e6a1dde19d8..e19a2d2bf071 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_smartcard.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_smartcard.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_smartcard.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of SMARTCARD HAL module. ****************************************************************************** * @attention @@ -40,7 +38,7 @@ #define __STM32F1xx_HAL_SMARTCARD_H #ifdef __cplusplus - extern "C" { +extern "C" { #endif /* Includes ------------------------------------------------------------------*/ @@ -54,7 +52,7 @@ * @{ */ -/* Exported types ------------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ /** @defgroup SMARTCARD_Exported_Types SMARTCARD Exported Types * @{ */ @@ -95,7 +93,7 @@ typedef struct data bit (MSB) has to be output on the SCLK pin in synchronous mode. This parameter can be a value of @ref SMARTCARD_Last_Bit */ - uint32_t Prescaler; /*!< Specifies the SmartCard Prescaler value used for dividing the system clock + uint32_t Prescaler; /*!< Specifies the SmartCard Prescaler value used for dividing the system clock to provide the smartcard clock. The value given in the register (5 significant bits) is multiplied by 2 to give the division factor of the source clock frequency. This parameter can be a value of @ref SMARTCARD_Prescaler */ @@ -104,15 +102,15 @@ typedef struct uint32_t NACKState; /*!< Specifies the SmartCard NACK Transmission state This parameter can be a value of @ref SMARTCARD_NACK_State */ -}SMARTCARD_InitTypeDef; +} SMARTCARD_InitTypeDef; -/** +/** * @brief HAL SMARTCARD State structures definition * @note HAL SMARTCARD State value is a combination of 2 different substates: gState and RxState. - * - gState contains SMARTCARD state information related to global Handle management + * - gState contains SMARTCARD state information related to global Handle management * and also information related to Tx operations. * gState value coding follow below described bitmap : - * b7-b6 Error information + * b7-b6 Error information * 00 : No Error * 01 : (Not Used) * 10 : Timeout @@ -157,16 +155,16 @@ typedef enum Value is allowed for gState only */ HAL_SMARTCARD_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing Value is allowed for RxState only */ - HAL_SMARTCARD_STATE_BUSY_TX_RX = 0x23U, /*!< Data Transmission and Reception process is ongoing + HAL_SMARTCARD_STATE_BUSY_TX_RX = 0x23U, /*!< Data Transmission and Reception process is ongoing Not to be used for neither gState nor RxState. Value is result of combination (Or) between gState and RxState values */ HAL_SMARTCARD_STATE_TIMEOUT = 0xA0U, /*!< Timeout state Value is allowed for gState only */ HAL_SMARTCARD_STATE_ERROR = 0xE0U /*!< Error Value is allowed for gState only */ -}HAL_SMARTCARD_StateTypeDef; +} HAL_SMARTCARD_StateTypeDef; -/** +/** * @brief SMARTCARD handle Structure definition */ typedef struct @@ -193,15 +191,15 @@ typedef struct HAL_LockTypeDef Lock; /*!< Locking object */ - __IO HAL_SMARTCARD_StateTypeDef gState; /*!< SmartCard state information related to global Handle management + __IO HAL_SMARTCARD_StateTypeDef gState; /*!< SmartCard state information related to global Handle management and also related to Tx operations. This parameter can be a value of @ref HAL_SMARTCARD_StateTypeDef */ - + __IO HAL_SMARTCARD_StateTypeDef RxState; /*!< SmartCard state information related to Rx operations. This parameter can be a value of @ref HAL_SMARTCARD_StateTypeDef */ __IO uint32_t ErrorCode; /*!< SmartCard Error code */ -}SMARTCARD_HandleTypeDef; +} SMARTCARD_HandleTypeDef; /** * @} @@ -246,7 +244,7 @@ typedef struct * @{ */ #define SMARTCARD_PARITY_EVEN ((uint32_t)USART_CR1_PCE) -#define SMARTCARD_PARITY_ODD ((uint32_t)(USART_CR1_PCE | USART_CR1_PS)) +#define SMARTCARD_PARITY_ODD ((uint32_t)(USART_CR1_PCE | USART_CR1_PS)) /** * @} */ @@ -268,7 +266,7 @@ typedef struct #define SMARTCARD_POLARITY_HIGH ((uint32_t)USART_CR2_CPOL) /** * @} - */ + */ /** @defgroup SMARTCARD_Clock_Phase SMARTCARD Clock Phase * @{ @@ -397,7 +395,7 @@ typedef struct (__HANDLE__)->RxState = HAL_SMARTCARD_STATE_RESET; \ } while(0U) -/** @brief Flush the Smartcard DR register +/** @brief Flush the Smartcard DR register * @param __HANDLE__: specifies the SMARTCARD Handle. * SMARTCARD Handle selects the USARTx peripheral (USART availability and x value depending on device). */ @@ -427,12 +425,12 @@ typedef struct * This parameter can be any combination of the following values: * @arg SMARTCARD_FLAG_TC: Transmission Complete flag. * @arg SMARTCARD_FLAG_RXNE: Receive data register not empty flag. - * - * @note PE (Parity error), FE (Framing error), NE (Noise error) and ORE (OverRun - * error) flags are cleared by software sequence: a read operation to + * + * @note PE (Parity error), FE (Framing error), NE (Noise error) and ORE (OverRun + * error) flags are cleared by software sequence: a read operation to * USART_SR register followed by a read operation to USART_DR register. * @note RXNE flag can be also cleared by a read to the USART_DR register. - * @note TC flag can be also cleared by software sequence: a read operation to + * @note TC flag can be also cleared by software sequence: a read operation to * USART_SR register followed by a write operation to USART_DR register. * @note TXE flag is cleared only by a write to the USART_DR register. */ @@ -619,7 +617,7 @@ uint32_t HAL_SMARTCARD_GetError(SMARTCARD_HandleTypeDef *hsc); */ /** @brief SMARTCARD interruptions flag mask - * + * */ #define SMARTCARD_IT_MASK 0x0000FFFFU @@ -670,7 +668,7 @@ uint32_t HAL_SMARTCARD_GetError(SMARTCARD_HandleTypeDef *hsc); /** * @} - */ + */ /** * @} diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_spi.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_spi.c index 798545eee1c3..0dafcd66a472 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_spi.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_spi.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_spi.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief SPI HAL module driver. * This file provides firmware functions to manage the following * functionalities of the Serial Peripheral Interface (SPI) peripheral: diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_spi.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_spi.h index d152d74affd4..80de9efcfeac 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_spi.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_spi.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_spi.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of SPI HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_spi_ex.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_spi_ex.c index 8ae2f75b434f..31d100f5ad0d 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_spi_ex.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_spi_ex.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_spi_ex.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Extended SPI HAL module driver. * * This file provides firmware functions to manage the following diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_sram.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_sram.c index 156faaf03a93..27a9ae7afca8 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_sram.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_sram.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_sram.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief SRAM HAL module driver. * This file provides a generic firmware to drive SRAM memories * mounted as external device. diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_sram.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_sram.h index c096f1b9df2f..76f54342b5b0 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_sram.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_sram.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_sram.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of SRAM HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_tim.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_tim.c index 3e6bd1bbe744..db203f8f95a7 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_tim.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_tim.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_tim.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief TIM HAL module driver * This file provides firmware functions to manage the following * functionalities of the Timer (TIM) peripheral: diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_tim.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_tim.h index ad4d88533215..ea8aa92611d7 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_tim.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_tim.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_tim.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of TIM HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_tim_ex.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_tim_ex.c index 9fae96da0d3f..f67ee6d8594b 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_tim_ex.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_tim_ex.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_tim_ex.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief TIM HAL module driver. * This file provides firmware functions to manage the following * functionalities of the Timer Extended peripheral: @@ -494,7 +492,6 @@ HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_DMA(TIM_HandleTypeDef *htim) * @arg TIM_CHANNEL_1: TIM Channel 1 selected * @arg TIM_CHANNEL_2: TIM Channel 2 selected * @arg TIM_CHANNEL_3: TIM Channel 3 selected - * @arg TIM_CHANNEL_4: TIM Channel 4 selected * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_OCN_Start(TIM_HandleTypeDef *htim, uint32_t Channel) @@ -524,7 +521,6 @@ HAL_StatusTypeDef HAL_TIMEx_OCN_Start(TIM_HandleTypeDef *htim, uint32_t Channel) * @arg TIM_CHANNEL_1: TIM Channel 1 selected * @arg TIM_CHANNEL_2: TIM Channel 2 selected * @arg TIM_CHANNEL_3: TIM Channel 3 selected - * @arg TIM_CHANNEL_4: TIM Channel 4 selected * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_OCN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel) @@ -554,7 +550,6 @@ HAL_StatusTypeDef HAL_TIMEx_OCN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel) * @arg TIM_CHANNEL_1: TIM Channel 1 selected * @arg TIM_CHANNEL_2: TIM Channel 2 selected * @arg TIM_CHANNEL_3: TIM Channel 3 selected - * @arg TIM_CHANNEL_4: TIM Channel 4 selected * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_OCN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel) @@ -585,13 +580,6 @@ HAL_StatusTypeDef HAL_TIMEx_OCN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Chann } break; - case TIM_CHANNEL_4: - { - /* Enable the TIM Output Compare interrupt */ - __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC4); - } - break; - default: break; } @@ -621,7 +609,6 @@ HAL_StatusTypeDef HAL_TIMEx_OCN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Chann * @arg TIM_CHANNEL_1: TIM Channel 1 selected * @arg TIM_CHANNEL_2: TIM Channel 2 selected * @arg TIM_CHANNEL_3: TIM Channel 3 selected - * @arg TIM_CHANNEL_4: TIM Channel 4 selected * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel) @@ -654,13 +641,6 @@ HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channe } break; - case TIM_CHANNEL_4: - { - /* Disable the TIM Output Compare interrupt */ - __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC4); - } - break; - default: break; } @@ -694,7 +674,6 @@ HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channe * @arg TIM_CHANNEL_1: TIM Channel 1 selected * @arg TIM_CHANNEL_2: TIM Channel 2 selected * @arg TIM_CHANNEL_3: TIM Channel 3 selected - * @arg TIM_CHANNEL_4: TIM Channel 4 selected * @param pData : The source Buffer address. * @param Length : The length of data to be transferred from memory to TIM peripheral * @retval HAL status @@ -754,7 +733,7 @@ HAL_StatusTypeDef HAL_TIMEx_OCN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Chan break; case TIM_CHANNEL_3: -{ + { /* Set the DMA Period elapsed callback */ htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseCplt; @@ -769,22 +748,6 @@ HAL_StatusTypeDef HAL_TIMEx_OCN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Chan } break; - case TIM_CHANNEL_4: - { - /* Set the DMA Period elapsed callback */ - htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMADelayPulseCplt; - - /* Set the DMA error callback */ - htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ; - - /* Enable the DMA channel */ - HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)pData, (uint32_t)&htim->Instance->CCR4, Length); - - /* Enable the TIM Output Compare DMA request */ - __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC4); - } - break; - default: break; } @@ -811,7 +774,6 @@ HAL_StatusTypeDef HAL_TIMEx_OCN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Chan * @arg TIM_CHANNEL_1: TIM Channel 1 selected * @arg TIM_CHANNEL_2: TIM Channel 2 selected * @arg TIM_CHANNEL_3: TIM Channel 3 selected - * @arg TIM_CHANNEL_4: TIM Channel 4 selected * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel) @@ -842,13 +804,6 @@ HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Chann } break; - case TIM_CHANNEL_4: - { - /* Disable the TIM Output Compare interrupt */ - __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC4); - } - break; - default: break; } @@ -911,7 +866,6 @@ HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Chann * @arg TIM_CHANNEL_1: TIM Channel 1 selected * @arg TIM_CHANNEL_2: TIM Channel 2 selected * @arg TIM_CHANNEL_3: TIM Channel 3 selected - * @arg TIM_CHANNEL_4: TIM Channel 4 selected * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_PWMN_Start(TIM_HandleTypeDef *htim, uint32_t Channel) @@ -940,7 +894,6 @@ HAL_StatusTypeDef HAL_TIMEx_PWMN_Start(TIM_HandleTypeDef *htim, uint32_t Channel * @arg TIM_CHANNEL_1: TIM Channel 1 selected * @arg TIM_CHANNEL_2: TIM Channel 2 selected * @arg TIM_CHANNEL_3: TIM Channel 3 selected - * @arg TIM_CHANNEL_4: TIM Channel 4 selected * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel) @@ -970,7 +923,6 @@ HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel) * @arg TIM_CHANNEL_1: TIM Channel 1 selected * @arg TIM_CHANNEL_2: TIM Channel 2 selected * @arg TIM_CHANNEL_3: TIM Channel 3 selected - * @arg TIM_CHANNEL_4: TIM Channel 4 selected * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel) @@ -1001,13 +953,6 @@ HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Chan } break; - case TIM_CHANNEL_4: - { - /* Enable the TIM Capture/Compare 4 interrupt */ - __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC4); - } - break; - default: break; } @@ -1037,10 +982,9 @@ HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Chan * @arg TIM_CHANNEL_1: TIM Channel 1 selected * @arg TIM_CHANNEL_2: TIM Channel 2 selected * @arg TIM_CHANNEL_3: TIM Channel 3 selected - * @arg TIM_CHANNEL_4: TIM Channel 4 selected * @retval HAL status */ -HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_IT (TIM_HandleTypeDef *htim, uint32_t Channel) +HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel) { uint32_t tmpccer = 0U; @@ -1070,13 +1014,6 @@ HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_IT (TIM_HandleTypeDef *htim, uint32_t Chan } break; - case TIM_CHANNEL_4: - { - /* Disable the TIM Capture/Compare 3 interrupt */ - __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC4); - } - break; - default: break; } @@ -1110,7 +1047,6 @@ HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_IT (TIM_HandleTypeDef *htim, uint32_t Chan * @arg TIM_CHANNEL_1: TIM Channel 1 selected * @arg TIM_CHANNEL_2: TIM Channel 2 selected * @arg TIM_CHANNEL_3: TIM Channel 3 selected - * @arg TIM_CHANNEL_4: TIM Channel 4 selected * @param pData : The source Buffer address. * @param Length : The length of data to be transferred from memory to TIM peripheral * @retval HAL status @@ -1185,31 +1121,15 @@ HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Cha } break; - case TIM_CHANNEL_4: - { - /* Set the DMA Period elapsed callback */ - htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMADelayPulseCplt; - - /* Set the DMA error callback */ - htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ; - - /* Enable the DMA channel */ - HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)pData, (uint32_t)&htim->Instance->CCR4, Length); - - /* Enable the TIM Capture/Compare 4 DMA request */ - __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC4); - } - break; - default: break; } /* Enable the complementary PWM output */ - TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE); + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE); /* Enable the Main Ouput */ - __HAL_TIM_MOE_ENABLE(htim); + __HAL_TIM_MOE_ENABLE(htim); /* Enable the Peripheral */ __HAL_TIM_ENABLE(htim); @@ -1227,7 +1147,6 @@ HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Cha * @arg TIM_CHANNEL_1: TIM Channel 1 selected * @arg TIM_CHANNEL_2: TIM Channel 2 selected * @arg TIM_CHANNEL_3: TIM Channel 3 selected - * @arg TIM_CHANNEL_4: TIM Channel 4 selected * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel) @@ -1258,22 +1177,15 @@ HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Chan } break; - case TIM_CHANNEL_4: - { - /* Disable the TIM Capture/Compare 4 DMA request */ - __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC4); - } - break; - default: break; } /* Disable the complementary PWM output */ - TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE); + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE); /* Disable the Main Ouput */ - __HAL_TIM_MOE_DISABLE(htim); + __HAL_TIM_MOE_DISABLE(htim); /* Disable the Peripheral */ __HAL_TIM_DISABLE(htim); @@ -1318,7 +1230,7 @@ HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Chan * @retval HAL status */ HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel) - { +{ /* Check the parameters */ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel)); @@ -1390,7 +1302,7 @@ HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start_IT(TIM_HandleTypeDef *htim, uint32_t /* Return function status */ return HAL_OK; - } +} /** * @brief Stops the TIM One Pulse signal generation in interrupt mode on the @@ -1420,7 +1332,7 @@ HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t __HAL_TIM_MOE_DISABLE(htim); /* Disable the Peripheral */ - __HAL_TIM_DISABLE(htim); + __HAL_TIM_DISABLE(htim); /* Return function status */ return HAL_OK; @@ -1435,7 +1347,7 @@ HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t /* defined(STM32F105xC) || defined(STM32F107xC) */ /** @defgroup TIMEx_Exported_Functions_Group5 Peripheral Control functions - * @brief Peripheral Control functions + * @brief Peripheral Control functions * @verbatim ============================================================================== @@ -1643,7 +1555,7 @@ HAL_StatusTypeDef HAL_TIMEx_ConfigBreakDeadTime(TIM_HandleTypeDef *htim, /* Set the Lock level, the Break enable Bit and the Polarity, the OSSR State, the OSSI State, the dead time value and the Automatic Output Enable Bit */ - + /* Set the BDTR bits */ MODIFY_REG(tmpbdtr, TIM_BDTR_DTG, sBreakDeadTimeConfig->DeadTime); MODIFY_REG(tmpbdtr, TIM_BDTR_LOCK, sBreakDeadTimeConfig->LockLevel); @@ -1653,10 +1565,10 @@ HAL_StatusTypeDef HAL_TIMEx_ConfigBreakDeadTime(TIM_HandleTypeDef *htim, MODIFY_REG(tmpbdtr, TIM_BDTR_BKP, sBreakDeadTimeConfig->BreakPolarity); MODIFY_REG(tmpbdtr, TIM_BDTR_AOE, sBreakDeadTimeConfig->AutomaticOutput); MODIFY_REG(tmpbdtr, TIM_BDTR_MOE, sBreakDeadTimeConfig->AutomaticOutput); - + /* Set TIMx_BDTR */ htim->Instance->BDTR = tmpbdtr; - + __HAL_UNLOCK(htim); return HAL_OK; diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_tim_ex.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_tim_ex.h index 1e2d4a546343..f94ab664c1a2 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_tim_ex.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_tim_ex.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_tim_ex.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of TIM HAL Extension module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_uart.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_uart.c index 0e3e8603e721..56fa648b7790 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_uart.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_uart.c @@ -2,10 +2,8 @@ ****************************************************************************** * @file stm32f1xx_hal_uart.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief UART HAL module driver. - * This file provides firmware functions to manage the following + * This file provides firmware functions to manage the following * functionalities of the Universal Asynchronous Receiver Transmitter (UART) peripheral: * + Initialization and de-initialization functions * + IO operation functions diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_uart.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_uart.h index a8639814cbcd..73a0b7329c30 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_uart.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_uart.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_uart.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of UART HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_usart.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_usart.c index a6d19e9f99e9..f7ff93a2a55d 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_usart.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_usart.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_usart.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief USART HAL module driver. * This file provides firmware functions to manage the following * functionalities of the Universal Synchronous Asynchronous Receiver Transmitter (USART) peripheral: diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_usart.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_usart.h index f88eb86fd543..788c60ebdad8 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_usart.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_usart.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_usart.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of USART HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_wwdg.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_wwdg.c index aa435f318f05..6a05cff4f64f 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_wwdg.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_wwdg.c @@ -2,10 +2,8 @@ ****************************************************************************** * @file stm32f1xx_hal_wwdg.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief WWDG HAL module driver. - * This file provides firmware functions to manage the following + * This file provides firmware functions to manage the following * functionalities of the Window Watchdog (WWDG) peripheral: * + Initialization and de-initialization functions * + IO operation functions @@ -14,44 +12,44 @@ ============================================================================== ##### WWDG specific features ##### ============================================================================== - [..] + [..] Once enabled the WWDG generates a system reset on expiry of a programmed - time period, unless the program refreshes the counter (downcounter) + time period, unless the program refreshes the counter (downcounter) before reaching 0x3F value (i.e. a reset is generated when the counter - value rolls over from 0x40 to 0x3F). - + value rolls over from 0x40 to 0x3F). + (+) An MCU reset is also generated if the counter value is refreshed - before the counter has reached the refresh window value. This + before the counter has reached the refresh window value. This implies that the counter must be refreshed in a limited window. (+) Once enabled the WWDG cannot be disabled except by a system reset. (+) WWDGRST flag in RCC_CSR register can be used to inform when a WWDG - reset occurs. - (+) The WWDG counter input clock is derived from the APB clock divided + reset occurs. + (+) The WWDG counter input clock is derived from the APB clock divided by a programmable prescaler. (+) WWDG clock (Hz) = PCLK1 / (4096 * Prescaler) (+) WWDG timeout (mS) = 1000 * Counter / WWDG clock (+) WWDG Counter refresh is allowed between the following limits : (++) min time (mS) = 1000 * (Counter _ Window) / WWDG clock (++) max time (mS) = 1000 * (Counter _ 0x40) / WWDG clock - - (+) Min-max timeout value at 36 MHz(PCLK1): 910 us / 58.25 ms - (+) The Early Wakeup Interrupt (EWI) can be used if specific safety + (+) Min-max timeout value at 36 MHz(PCLK1): 910 us / 58.25 ms + + (+) The Early Wakeup Interrupt (EWI) can be used if specific safety operations or data logging must be performed before the actual reset is generated. When the downcounter reaches the value 0x40, an EWI interrupt - is generated and the corresponding interrupt service routine (ISR) can - be used to trigger specific actions (such as communications or data + is generated and the corresponding interrupt service routine (ISR) can + be used to trigger specific actions (such as communications or data logging), before resetting the device. In some applications, the EWI interrupt can be used to manage a software - system check and/or system recovery/graceful degradation, without - generating a WWDG reset. In this case, the corresponding interrupt - service routine (ISR) should reload the WWDG counter to avoid the WWDG + system check and/or system recovery/graceful degradation, without + generating a WWDG reset. In this case, the corresponding interrupt + service routine (ISR) should reload the WWDG counter to avoid the WWDG reset, then trigger the required actions. - Note:When the EWI interrupt cannot be served, e.g. due to a system lock + Note:When the EWI interrupt cannot be served, e.g. due to a system lock in a higher priority task, the WWDG reset will eventually be generated. (+) Debug mode : When the microcontroller enters debug mode (core halted), - the WWDG counter either continues to work normally or stops, depending + the WWDG counter either continues to work normally or stops, depending on DBG_WWDG_STOP configuration bit in DBG module, accessible through __HAL_DBGMCU_FREEZE_WWDG() and __HAL_DBGMCU_UNFREEZE_WWDG() macros @@ -60,12 +58,12 @@ [..] (+) Enable WWDG APB1 clock using __HAL_RCC_WWDG_CLK_ENABLE(). - (+) Set the WWDG prescaler, refresh window, counter value and Early Wakeup + (+) Set the WWDG prescaler, refresh window, counter value and Early Wakeup Interrupt mode using using HAL_WWDG_Init() function. - This enables WWDG peripheral and the downcounter starts downcounting + This enables WWDG peripheral and the downcounter starts downcounting from given counter value. - Init function can be called again to modify all watchdog parameters, - however if EWI mode has been set once, it can't be clear until next + Init function can be called again to modify all watchdog parameters, + however if EWI mode has been set once, it can't be clear until next reset. (+) The application program must refresh the WWDG counter at regular @@ -73,8 +71,8 @@ HAL_WWDG_Refresh() function. This operation must occur only when the counter is lower than the window value already programmed. - (+) if Early Wakeup Interrupt mode is enable an interrupt is generated when - the counter reaches 0x40. User can add his own code in weak function + (+) if Early Wakeup Interrupt mode is enable an interrupt is generated when + the counter reaches 0x40. User can add his own code in weak function HAL_WWDG_EarlyWakeupCallback(). *** WWDG HAL driver macros list *** @@ -148,7 +146,7 @@ ============================================================================== ##### Initialization and Configuration functions ##### ============================================================================== - [..] + [..] This section provides functions allowing to: (+) Initialize and start the WWDG according to the specified parameters in the WWDG_InitTypeDef of associated handle. @@ -168,7 +166,7 @@ HAL_StatusTypeDef HAL_WWDG_Init(WWDG_HandleTypeDef *hwwdg) { /* Check the WWDG handle allocation */ - if(hwwdg == NULL) + if (hwwdg == NULL) { return HAL_ERROR; } @@ -217,12 +215,12 @@ __weak void HAL_WWDG_MspInit(WWDG_HandleTypeDef *hwwdg) */ /** @defgroup WWDG_Exported_Functions_Group2 IO operation functions - * @brief IO operation functions + * @brief IO operation functions * @verbatim ============================================================================== ##### IO operation functions ##### - ============================================================================== + ============================================================================== [..] This section provides functions allowing to: (+) Refresh the WWDG. @@ -251,7 +249,7 @@ HAL_StatusTypeDef HAL_WWDG_Refresh(WWDG_HandleTypeDef *hwwdg) * @brief Handle WWDG interrupt request. * @note The Early Wakeup Interrupt (EWI) can be used if specific safety operations * or data logging must be performed before the actual reset is generated. - * The EWI interrupt is enabled by calling HAL_WWDG_Init function with + * The EWI interrupt is enabled by calling HAL_WWDG_Init function with * EWIMode set to WWDG_EWI_ENABLE. * When the downcounter reaches the value 0x40, and EWI interrupt is * generated and the corresponding Interrupt Service Routine (ISR) can @@ -264,15 +262,15 @@ HAL_StatusTypeDef HAL_WWDG_Refresh(WWDG_HandleTypeDef *hwwdg) void HAL_WWDG_IRQHandler(WWDG_HandleTypeDef *hwwdg) { /* Check if Early Wakeup Interrupt is enable */ - if(__HAL_WWDG_GET_IT_SOURCE(hwwdg, WWDG_IT_EWI) != RESET) + if (__HAL_WWDG_GET_IT_SOURCE(hwwdg, WWDG_IT_EWI) != RESET) { /* Check if WWDG Early Wakeup Interrupt occurred */ - if(__HAL_WWDG_GET_FLAG(hwwdg, WWDG_FLAG_EWIF) != RESET) + if (__HAL_WWDG_GET_FLAG(hwwdg, WWDG_FLAG_EWIF) != RESET) { /* Clear the WWDG Early Wakeup flag */ __HAL_WWDG_CLEAR_FLAG(hwwdg, WWDG_FLAG_EWIF); - /* Early Wakeup callback */ + /* Early Wakeup callback */ HAL_WWDG_EarlyWakeupCallback(hwwdg); } } @@ -284,7 +282,7 @@ void HAL_WWDG_IRQHandler(WWDG_HandleTypeDef *hwwdg) * the configuration information for the specified WWDG module. * @retval None */ -__weak void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef* hwwdg) +__weak void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg) { /* Prevent unused argument(s) compilation warning */ UNUSED(hwwdg); diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_wwdg.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_wwdg.h index 4f6510af0f25..9e01f036a60a 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_wwdg.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_hal_wwdg.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_hal_wwdg.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of WWDG HAL module. ****************************************************************************** * @attention @@ -33,14 +31,14 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** - */ + */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM32F1xx_HAL_WWDG_H #define __STM32F1xx_HAL_WWDG_H #ifdef __cplusplus - extern "C" { +extern "C" { #endif /* Includes ------------------------------------------------------------------*/ @@ -52,14 +50,14 @@ /** @addtogroup WWDG * @{ - */ + */ /* Exported types ------------------------------------------------------------*/ /** @defgroup WWDG_Exported_Types WWDG Exported Types * @{ */ -/** +/** * @brief WWDG Init structure definition */ typedef struct @@ -76,7 +74,7 @@ typedef struct uint32_t EWIMode ; /*!< Specifies if WWDG Early Wakeup Interupt is enable or not. This parameter can be a value of @ref WWDG_EWI_Mode */ -}WWDG_InitTypeDef; +} WWDG_InitTypeDef; /** * @brief WWDG handle Structure definition @@ -87,7 +85,7 @@ typedef struct WWDG_InitTypeDef Init; /*!< WWDG required parameters */ -}WWDG_HandleTypeDef; +} WWDG_HandleTypeDef; /** * @} */ @@ -117,7 +115,7 @@ typedef struct /** @defgroup WWDG_Prescaler WWDG Prescaler * @{ - */ + */ #define WWDG_PRESCALER_1 0x00000000U /*!< WWDG counter clock = (PCLK1/4096)/1 */ #define WWDG_PRESCALER_2 WWDG_CFR_WDGTB0 /*!< WWDG counter clock = (PCLK1/4096)/2 */ #define WWDG_PRESCALER_4 WWDG_CFR_WDGTB1 /*!< WWDG counter clock = (PCLK1/4096)/4 */ @@ -257,7 +255,7 @@ void HAL_WWDG_MspInit(WWDG_HandleTypeDef *hwwdg); /* I/O operation functions ******************************************************/ HAL_StatusTypeDef HAL_WWDG_Refresh(WWDG_HandleTypeDef *hwwdg); void HAL_WWDG_IRQHandler(WWDG_HandleTypeDef *hwwdg); -void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef* hwwdg); +void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg); /** * @} */ diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_adc.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_adc.c index 24ff8f3713ef..cd41409dc29c 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_adc.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_adc.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_adc.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief ADC LL module driver ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_adc.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_adc.h index b0c7a490dcf2..77779d9de4b4 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_adc.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_adc.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_adc.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of ADC LL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_bus.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_bus.h index c28b643b2877..f7414df89d4b 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_bus.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_bus.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_bus.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of BUS LL module. @verbatim diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_cortex.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_cortex.h index 74a320367302..862eda18b2c7 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_cortex.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_cortex.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_cortex.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of CORTEX LL module. @verbatim ============================================================================== diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_crc.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_crc.c index 7d07f8fe745f..5785b8967686 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_crc.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_crc.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_crc.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief CRC LL module driver. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_crc.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_crc.h index e6bc9b33d646..c5d2c36f701c 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_crc.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_crc.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_crc.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of CRC LL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_dac.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_dac.c index 60b8730367fd..b85598932d9f 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_dac.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_dac.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_dac.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief DAC LL module driver ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_dac.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_dac.h index d3a3b7d0fe49..af554910e16b 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_dac.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_dac.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_dac.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of DAC LL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_dma.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_dma.c index d90bfa04f012..cb73461f552d 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_dma.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_dma.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_dma.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief DMA LL module driver. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_dma.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_dma.h index fda0a074889d..5eb69aefe3d3 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_dma.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_dma.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_dma.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of DMA LL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_exti.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_exti.c index c3d094ad66da..5485adf95f8a 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_exti.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_exti.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_exti.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief EXTI LL module driver. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_exti.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_exti.h index 38e337815db1..dc4c3cef5911 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_exti.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_exti.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_exti.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of EXTI LL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_fsmc.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_fsmc.c index ecff5920e37a..6a9a9dca8a75 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_fsmc.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_fsmc.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_fsmc.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief FSMC Low Layer HAL module driver. * * This file provides firmware functions to manage the following diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_fsmc.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_fsmc.h index b04c4a7d4dc4..d087306a46d1 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_fsmc.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_fsmc.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_fsmc.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of FSMC HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_gpio.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_gpio.c index 43360fa9d682..18fc3bd1517c 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_gpio.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_gpio.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_gpio.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief GPIO LL module driver. ****************************************************************************** * @attention @@ -62,24 +60,26 @@ /** @addtogroup GPIO_LL_Private_Macros * @{ */ -#define IS_LL_GPIO_PIN(__VALUE__) ((((uint32_t)0x00000000U) < (__VALUE__)) && ((__VALUE__) <= (LL_GPIO_PIN_ALL))) + +#define IS_LL_GPIO_PIN(__VALUE__) ((((__VALUE__) & LL_GPIO_PIN_ALL)!= 0U) &&\ + (((__VALUE__) & (~LL_GPIO_PIN_ALL))== 0U)) #define IS_LL_GPIO_MODE(__VALUE__) (((__VALUE__) == LL_GPIO_MODE_ANALOG) ||\ ((__VALUE__) == LL_GPIO_MODE_FLOATING) ||\ ((__VALUE__) == LL_GPIO_MODE_INPUT) ||\ ((__VALUE__) == LL_GPIO_MODE_OUTPUT) ||\ - ((__VALUE__) == LL_GPIO_MODE_ALTERNATE)) + ((__VALUE__) == LL_GPIO_MODE_ALTERNATE)) #define IS_LL_GPIO_SPEED(__VALUE__) (((__VALUE__) == LL_GPIO_SPEED_FREQ_LOW) ||\ ((__VALUE__) == LL_GPIO_SPEED_FREQ_MEDIUM) ||\ ((__VALUE__) == LL_GPIO_SPEED_FREQ_HIGH)) - + #define IS_LL_GPIO_OUTPUT_TYPE(__VALUE__) (((__VALUE__) == LL_GPIO_OUTPUT_PUSHPULL) ||\ ((__VALUE__) == LL_GPIO_OUTPUT_OPENDRAIN)) - + #define IS_LL_GPIO_PULL(__VALUE__) (((__VALUE__) == LL_GPIO_PULL_DOWN) ||\ ((__VALUE__) == LL_GPIO_PULL_UP)) - + /** * @} */ @@ -144,7 +144,7 @@ ErrorStatus LL_GPIO_DeInit(GPIO_TypeDef *GPIOx) LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_GPIOF); } #endif -#if defined(GPIOG) +#if defined(GPIOG) else if (GPIOx == GPIOG) { LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_GPIOG); @@ -170,57 +170,61 @@ ErrorStatus LL_GPIO_DeInit(GPIO_TypeDef *GPIOx) */ ErrorStatus LL_GPIO_Init(GPIO_TypeDef *GPIOx, LL_GPIO_InitTypeDef *GPIO_InitStruct) { - uint32_t pinpos = 0x00000000U; - uint32_t currentpin = 0x00000000U; + uint32_t pinmask; + uint32_t pinpos; + uint32_t currentpin; /* Check the parameters */ assert_param(IS_GPIO_ALL_INSTANCE(GPIOx)); assert_param(IS_LL_GPIO_PIN(GPIO_InitStruct->Pin)); - assert_param(IS_LL_GPIO_MODE(GPIO_InitStruct->Mode)); - assert_param(IS_LL_GPIO_PULL(GPIO_InitStruct->Pull)); - + /* ------------------------- Configure the port pins ---------------- */ /* Initialize pinpos on first pin set */ - pinpos = POSITION_VAL(GPIO_InitStruct->Pin); + + pinmask = ((GPIO_InitStruct->Pin) << GPIO_PIN_MASK_POS) >> GPIO_PIN_NB; + pinpos = POSITION_VAL(pinmask); /* Configure the port pins */ - while ((((GPIO_InitStruct->Pin) & 0x0000FFFFU) >> pinpos) != 0x00000000U) + while ((pinmask >> pinpos) != 0U) { - /* Get current io position */ - if(pinpos <8 ) + /* skip if bit is not set */ + if ((pinmask & (1U << pinpos)) != 0U) { - currentpin = (GPIO_InitStruct->Pin) & (0x00000101U << pinpos); - } - else - { - currentpin = (GPIO_InitStruct->Pin) & ((0x00010001U << (pinpos-8)) | 0x04000000U); - } + /* Get current io position */ + if (pinpos < GPIO_PIN_MASK_POS) + { + currentpin = (0x00000101U << pinpos); + } + else + { + currentpin = ((0x00010001U << (pinpos - GPIO_PIN_MASK_POS)) | 0x04000000U); + } + + /* Check Pin Mode and Pin Pull parameters */ + assert_param(IS_LL_GPIO_MODE(GPIO_InitStruct->Mode)); + assert_param(IS_LL_GPIO_PULL(GPIO_InitStruct->Pull)); - if (currentpin) - { /* Pin Mode configuration */ LL_GPIO_SetPinMode(GPIOx, currentpin, GPIO_InitStruct->Mode); - - /* Pull-up Pull down resistor configuration*/ + + /* Pull-up Pull-down resistor configuration*/ LL_GPIO_SetPinPull(GPIOx, currentpin, GPIO_InitStruct->Pull); - - if ((GPIO_InitStruct->Mode == LL_GPIO_MODE_OUTPUT) || (GPIO_InitStruct->Mode == LL_GPIO_MODE_FLOATING)) + + if ((GPIO_InitStruct->Mode == LL_GPIO_MODE_OUTPUT) || (GPIO_InitStruct->Mode == LL_GPIO_MODE_ALTERNATE)) { + /* Check speed and Output mode parameters */ + assert_param(IS_LL_GPIO_SPEED(GPIO_InitStruct->Speed)); + assert_param(IS_LL_GPIO_OUTPUT_TYPE(GPIO_InitStruct->OutputType)); + /* Speed mode configuration */ LL_GPIO_SetPinSpeed(GPIOx, currentpin, GPIO_InitStruct->Speed); + + /* Output mode configuration*/ + LL_GPIO_SetPinOutputType(GPIOx, currentpin, GPIO_InitStruct->OutputType); } } pinpos++; } - - if ((GPIO_InitStruct->Mode == LL_GPIO_MODE_OUTPUT) || (GPIO_InitStruct->Mode == LL_GPIO_MODE_FLOATING)) - { - /* Check Output mode parameters */ - assert_param(IS_LL_GPIO_OUTPUT_TYPE(GPIO_InitStruct->OutputType)); - - /* Output mode configuration*/ - LL_GPIO_SetPinOutputType(GPIOx, GPIO_InitStruct->Pin, GPIO_InitStruct->OutputType); - } return (SUCCESS); } @@ -236,7 +240,7 @@ void LL_GPIO_StructInit(LL_GPIO_InitTypeDef *GPIO_InitStruct) /* Reset GPIO init structure parameters values */ GPIO_InitStruct->Pin = LL_GPIO_PIN_ALL; GPIO_InitStruct->Mode = LL_GPIO_MODE_FLOATING; - GPIO_InitStruct->Speed = 0x00000000U; + GPIO_InitStruct->Speed = LL_GPIO_SPEED_FREQ_LOW; GPIO_InitStruct->OutputType = LL_GPIO_OUTPUT_OPENDRAIN; GPIO_InitStruct->Pull = LL_GPIO_PULL_DOWN; } @@ -262,4 +266,3 @@ void LL_GPIO_StructInit(LL_GPIO_InitTypeDef *GPIO_InitStruct) #endif /* USE_FULL_LL_DRIVER */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_gpio.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_gpio.h index 6035560fe4b7..69e5025d401c 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_gpio.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_gpio.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_gpio.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of GPIO LL module. ****************************************************************************** * @attention @@ -58,16 +56,18 @@ extern "C" { /* Private types -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ - /* Private constants ---------------------------------------------------------*/ + /** @defgroup GPIO_LL_Private_Constants GPIO Private Constants * @{ */ +/* Defines used for Pin Mask Initialization */ +#define GPIO_PIN_MASK_POS 8U +#define GPIO_PIN_NB 16U /** * @} */ - /* Private macros ------------------------------------------------------------*/ #if defined(USE_FULL_LL_DRIVER) /** @defgroup GPIO_LL_Private_Macros GPIO Private Macros @@ -112,7 +112,7 @@ typedef struct This parameter can be a value of @ref GPIO_LL_EC_PULL. GPIO HW configuration can be modified afterwards using unitary function @ref LL_GPIO_SetPinPull().*/ -}LL_GPIO_InitTypeDef; +} LL_GPIO_InitTypeDef; /** * @} @@ -127,28 +127,28 @@ typedef struct /** @defgroup GPIO_LL_EC_PIN PIN * @{ */ -#define LL_GPIO_PIN_0 (GPIO_BSRR_BS0 << 8) | 0x00000001U /*!< Select pin 0 */ -#define LL_GPIO_PIN_1 (GPIO_BSRR_BS1 << 8) | 0x00000002U /*!< Select pin 1 */ -#define LL_GPIO_PIN_2 (GPIO_BSRR_BS2 << 8) | 0x00000004U /*!< Select pin 2 */ -#define LL_GPIO_PIN_3 (GPIO_BSRR_BS3 << 8) | 0x00000008U /*!< Select pin 3 */ -#define LL_GPIO_PIN_4 (GPIO_BSRR_BS4 << 8) | 0x00000010U /*!< Select pin 4 */ -#define LL_GPIO_PIN_5 (GPIO_BSRR_BS5 << 8) | 0x00000020U /*!< Select pin 5 */ -#define LL_GPIO_PIN_6 (GPIO_BSRR_BS6 << 8) | 0x00000040U /*!< Select pin 6 */ -#define LL_GPIO_PIN_7 (GPIO_BSRR_BS7 << 8) | 0x00000080U /*!< Select pin 7 */ -#define LL_GPIO_PIN_8 (GPIO_BSRR_BS8 << 8) | 0x04000001U /*!< Select pin 8 */ -#define LL_GPIO_PIN_9 (GPIO_BSRR_BS9 << 8) | 0x04000002U /*!< Select pin 9 */ -#define LL_GPIO_PIN_10 (GPIO_BSRR_BS10 << 8) | 0x04000004U /*!< Select pin 10 */ -#define LL_GPIO_PIN_11 (GPIO_BSRR_BS11 << 8) | 0x04000008U /*!< Select pin 11 */ -#define LL_GPIO_PIN_12 (GPIO_BSRR_BS12 << 8) | 0x04000010U /*!< Select pin 12 */ -#define LL_GPIO_PIN_13 (GPIO_BSRR_BS13 << 8) | 0x04000020U /*!< Select pin 13 */ -#define LL_GPIO_PIN_14 (GPIO_BSRR_BS14 << 8) | 0x04000040U /*!< Select pin 14 */ -#define LL_GPIO_PIN_15 (GPIO_BSRR_BS15 << 8) | 0x04000080U /*!< Select pin 15 */ +#define LL_GPIO_PIN_0 ((GPIO_BSRR_BS0 << GPIO_PIN_MASK_POS) | 0x00000001U) /*!< Select pin 0 */ +#define LL_GPIO_PIN_1 ((GPIO_BSRR_BS1 << GPIO_PIN_MASK_POS) | 0x00000002U) /*!< Select pin 1 */ +#define LL_GPIO_PIN_2 ((GPIO_BSRR_BS2 << GPIO_PIN_MASK_POS) | 0x00000004U) /*!< Select pin 2 */ +#define LL_GPIO_PIN_3 ((GPIO_BSRR_BS3 << GPIO_PIN_MASK_POS) | 0x00000008U) /*!< Select pin 3 */ +#define LL_GPIO_PIN_4 ((GPIO_BSRR_BS4 << GPIO_PIN_MASK_POS) | 0x00000010U) /*!< Select pin 4 */ +#define LL_GPIO_PIN_5 ((GPIO_BSRR_BS5 << GPIO_PIN_MASK_POS) | 0x00000020U) /*!< Select pin 5 */ +#define LL_GPIO_PIN_6 ((GPIO_BSRR_BS6 << GPIO_PIN_MASK_POS) | 0x00000040U) /*!< Select pin 6 */ +#define LL_GPIO_PIN_7 ((GPIO_BSRR_BS7 << GPIO_PIN_MASK_POS) | 0x00000080U) /*!< Select pin 7 */ +#define LL_GPIO_PIN_8 ((GPIO_BSRR_BS8 << GPIO_PIN_MASK_POS) | 0x04000001U) /*!< Select pin 8 */ +#define LL_GPIO_PIN_9 ((GPIO_BSRR_BS9 << GPIO_PIN_MASK_POS) | 0x04000002U) /*!< Select pin 9 */ +#define LL_GPIO_PIN_10 ((GPIO_BSRR_BS10 << GPIO_PIN_MASK_POS) | 0x04000004U) /*!< Select pin 10 */ +#define LL_GPIO_PIN_11 ((GPIO_BSRR_BS11 << GPIO_PIN_MASK_POS) | 0x04000008U) /*!< Select pin 11 */ +#define LL_GPIO_PIN_12 ((GPIO_BSRR_BS12 << GPIO_PIN_MASK_POS) | 0x04000010U) /*!< Select pin 12 */ +#define LL_GPIO_PIN_13 ((GPIO_BSRR_BS13 << GPIO_PIN_MASK_POS) | 0x04000020U) /*!< Select pin 13 */ +#define LL_GPIO_PIN_14 ((GPIO_BSRR_BS14 << GPIO_PIN_MASK_POS) | 0x04000040U) /*!< Select pin 14 */ +#define LL_GPIO_PIN_15 ((GPIO_BSRR_BS15 << GPIO_PIN_MASK_POS) | 0x04000080U) /*!< Select pin 15 */ #define LL_GPIO_PIN_ALL (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) /*!< Select all pins */ + LL_GPIO_PIN_15) /*!< Select all pins */ /** * @} */ @@ -156,11 +156,11 @@ typedef struct /** @defgroup GPIO_LL_EC_MODE Mode * @{ */ -#define LL_GPIO_MODE_ANALOG 0x00000000U /*!< Select analog mode */ -#define LL_GPIO_MODE_FLOATING GPIO_CRL_CNF0_0 /*!< Select floating mode */ -#define LL_GPIO_MODE_INPUT GPIO_CRL_CNF0_1 /*!< Select input mode */ -#define LL_GPIO_MODE_OUTPUT GPIO_CRL_MODE0_0 /*!< Select general purpose output mode */ -#define LL_GPIO_MODE_ALTERNATE (GPIO_CRL_CNF0_1 | GPIO_CRL_MODE0_0) /*!< Select alternate function mode */ +#define LL_GPIO_MODE_ANALOG 0x00000000U /*!< Select analog mode */ +#define LL_GPIO_MODE_FLOATING GPIO_CRL_CNF0_0 /*!< Select floating mode */ +#define LL_GPIO_MODE_INPUT GPIO_CRL_CNF0_1 /*!< Select input mode */ +#define LL_GPIO_MODE_OUTPUT GPIO_CRL_MODE0_0 /*!< Select general purpose output mode */ +#define LL_GPIO_MODE_ALTERNATE (GPIO_CRL_CNF0_1 | GPIO_CRL_MODE0_0) /*!< Select alternate function mode */ /** * @} */ @@ -168,8 +168,8 @@ typedef struct /** @defgroup GPIO_LL_EC_OUTPUT Output Type * @{ */ -#define LL_GPIO_OUTPUT_PUSHPULL 0x00000000U /*!< Select push-pull as output type */ -#define LL_GPIO_OUTPUT_OPENDRAIN GPIO_CRL_CNF0_0 /*!< Select open-drain as output type */ +#define LL_GPIO_OUTPUT_PUSHPULL 0x00000000U /*!< Select push-pull as output type */ +#define LL_GPIO_OUTPUT_OPENDRAIN GPIO_CRL_CNF0_0 /*!< Select open-drain as output type */ /** * @} */ @@ -177,13 +177,13 @@ typedef struct /** @defgroup GPIO_LL_EC_SPEED Output Speed * @{ */ -#define LL_GPIO_MODE_OUTPUT_10MHz GPIO_CRL_MODE0_0 /*!< Select Output mode, max speed 10 MHz */ -#define LL_GPIO_MODE_OUTPUT_2MHz GPIO_CRL_MODE0_1 /*!< Select Output mode, max speed 20 MHz */ -#define LL_GPIO_MODE_OUTPUT_50MHz GPIO_CRL_MODE0 /*!< Select Output mode, max speed 50 MHz */ +#define LL_GPIO_MODE_OUTPUT_10MHz GPIO_CRL_MODE0_0 /*!< Select Output mode, max speed 10 MHz */ +#define LL_GPIO_MODE_OUTPUT_2MHz GPIO_CRL_MODE0_1 /*!< Select Output mode, max speed 20 MHz */ +#define LL_GPIO_MODE_OUTPUT_50MHz GPIO_CRL_MODE0 /*!< Select Output mode, max speed 50 MHz */ /** * @} */ - + #define LL_GPIO_SPEED_FREQ_LOW LL_GPIO_MODE_OUTPUT_2MHz /*!< Select I/O low output speed */ #define LL_GPIO_SPEED_FREQ_MEDIUM LL_GPIO_MODE_OUTPUT_10MHz /*!< Select I/O medium output speed */ #define LL_GPIO_SPEED_FREQ_HIGH LL_GPIO_MODE_OUTPUT_50MHz /*!< Select I/O high output speed */ @@ -191,13 +191,13 @@ typedef struct /** @defgroup GPIO_LL_EC_PULL Pull Up Pull Down * @{ */ -#define LL_GPIO_PULL_DOWN 0x00000000U /*!< Select I/O pull down */ -#define LL_GPIO_PULL_UP GPIO_ODR_ODR0 /*!< Select I/O pull up */ +#define LL_GPIO_PULL_DOWN 0x00000000U /*!< Select I/O pull down */ +#define LL_GPIO_PULL_UP GPIO_ODR_ODR0 /*!< Select I/O pull up */ /** * @} */ - + /** @defgroup GPIO_LL_EVENTOUT_PIN EVENTOUT Pin * @{ */ @@ -240,13 +240,13 @@ typedef struct /** @defgroup GPIO_LL_EC_EXTI_PORT GPIO EXTI PORT * @{ */ -#define LL_GPIO_AF_EXTI_PORTA (uint32_t)0 /*!< EXTI PORT A */ -#define LL_GPIO_AF_EXTI_PORTB (uint32_t)1 /*!< EXTI PORT B */ -#define LL_GPIO_AF_EXTI_PORTC (uint32_t)2 /*!< EXTI PORT C */ -#define LL_GPIO_AF_EXTI_PORTD (uint32_t)3 /*!< EXTI PORT D */ -#define LL_GPIO_AF_EXTI_PORTE (uint32_t)4 /*!< EXTI PORT E */ -#define LL_GPIO_AF_EXTI_PORTF (uint32_t)5 /*!< EXTI PORT F */ -#define LL_GPIO_AF_EXTI_PORTG (uint32_t)6 /*!< EXTI PORT G */ +#define LL_GPIO_AF_EXTI_PORTA 0U /*!< EXTI PORT A */ +#define LL_GPIO_AF_EXTI_PORTB 1U /*!< EXTI PORT B */ +#define LL_GPIO_AF_EXTI_PORTC 2U /*!< EXTI PORT C */ +#define LL_GPIO_AF_EXTI_PORTD 3U /*!< EXTI PORT D */ +#define LL_GPIO_AF_EXTI_PORTE 4U /*!< EXTI PORT E */ +#define LL_GPIO_AF_EXTI_PORTF 5U /*!< EXTI PORT F */ +#define LL_GPIO_AF_EXTI_PORTG 6U /*!< EXTI PORT G */ /** * @} */ @@ -254,22 +254,22 @@ typedef struct /** @defgroup GPIO_LL_EC_EXTI_LINE GPIO EXTI LINE * @{ */ -#define LL_GPIO_AF_EXTI_LINE0 (uint32_t)(0x000FU << 16 | 0) /*!< EXTI_POSITION_0 | EXTICR[0] */ -#define LL_GPIO_AF_EXTI_LINE1 (uint32_t)(0x00F0U << 16 | 0) /*!< EXTI_POSITION_4 | EXTICR[0] */ -#define LL_GPIO_AF_EXTI_LINE2 (uint32_t)(0x0F00U << 16 | 0) /*!< EXTI_POSITION_8 | EXTICR[0] */ -#define LL_GPIO_AF_EXTI_LINE3 (uint32_t)(0xF000U << 16 | 0) /*!< EXTI_POSITION_12 | EXTICR[0] */ -#define LL_GPIO_AF_EXTI_LINE4 (uint32_t)(0x000FU << 16 | 1) /*!< EXTI_POSITION_0 | EXTICR[1] */ -#define LL_GPIO_AF_EXTI_LINE5 (uint32_t)(0x00F0U << 16 | 1) /*!< EXTI_POSITION_4 | EXTICR[1] */ -#define LL_GPIO_AF_EXTI_LINE6 (uint32_t)(0x0F00U << 16 | 1) /*!< EXTI_POSITION_8 | EXTICR[1] */ -#define LL_GPIO_AF_EXTI_LINE7 (uint32_t)(0xF000U << 16 | 1) /*!< EXTI_POSITION_12 | EXTICR[1] */ -#define LL_GPIO_AF_EXTI_LINE8 (uint32_t)(0x000FU << 16 | 2) /*!< EXTI_POSITION_0 | EXTICR[2] */ -#define LL_GPIO_AF_EXTI_LINE9 (uint32_t)(0x00F0U << 16 | 2) /*!< EXTI_POSITION_4 | EXTICR[2] */ -#define LL_GPIO_AF_EXTI_LINE10 (uint32_t)(0x0F00U << 16 | 2) /*!< EXTI_POSITION_8 | EXTICR[2] */ -#define LL_GPIO_AF_EXTI_LINE11 (uint32_t)(0xF000U << 16 | 2) /*!< EXTI_POSITION_12 | EXTICR[2] */ -#define LL_GPIO_AF_EXTI_LINE12 (uint32_t)(0x000FU << 16 | 3) /*!< EXTI_POSITION_0 | EXTICR[3] */ -#define LL_GPIO_AF_EXTI_LINE13 (uint32_t)(0x00F0U << 16 | 3) /*!< EXTI_POSITION_4 | EXTICR[3] */ -#define LL_GPIO_AF_EXTI_LINE14 (uint32_t)(0x0F00U << 16 | 3) /*!< EXTI_POSITION_8 | EXTICR[3] */ -#define LL_GPIO_AF_EXTI_LINE15 (uint32_t)(0xF000U << 16 | 3) /*!< EXTI_POSITION_12 | EXTICR[3] */ +#define LL_GPIO_AF_EXTI_LINE0 (0x000FU << 16U | 0U) /*!< EXTI_POSITION_0 | EXTICR[0] */ +#define LL_GPIO_AF_EXTI_LINE1 (0x00F0U << 16U | 0U) /*!< EXTI_POSITION_4 | EXTICR[0] */ +#define LL_GPIO_AF_EXTI_LINE2 (0x0F00U << 16U | 0U) /*!< EXTI_POSITION_8 | EXTICR[0] */ +#define LL_GPIO_AF_EXTI_LINE3 (0xF000U << 16U | 0U) /*!< EXTI_POSITION_12 | EXTICR[0] */ +#define LL_GPIO_AF_EXTI_LINE4 (0x000FU << 16U | 1U) /*!< EXTI_POSITION_0 | EXTICR[1] */ +#define LL_GPIO_AF_EXTI_LINE5 (0x00F0U << 16U | 1U) /*!< EXTI_POSITION_4 | EXTICR[1] */ +#define LL_GPIO_AF_EXTI_LINE6 (0x0F00U << 16U | 1U) /*!< EXTI_POSITION_8 | EXTICR[1] */ +#define LL_GPIO_AF_EXTI_LINE7 (0xF000U << 16U | 1U) /*!< EXTI_POSITION_12 | EXTICR[1] */ +#define LL_GPIO_AF_EXTI_LINE8 (0x000FU << 16U | 2U) /*!< EXTI_POSITION_0 | EXTICR[2] */ +#define LL_GPIO_AF_EXTI_LINE9 (0x00F0U << 16U | 2U) /*!< EXTI_POSITION_4 | EXTICR[2] */ +#define LL_GPIO_AF_EXTI_LINE10 (0x0F00U << 16U | 2U) /*!< EXTI_POSITION_8 | EXTICR[2] */ +#define LL_GPIO_AF_EXTI_LINE11 (0xF000U << 16U | 2U) /*!< EXTI_POSITION_12 | EXTICR[2] */ +#define LL_GPIO_AF_EXTI_LINE12 (0x000FU << 16U | 3U) /*!< EXTI_POSITION_0 | EXTICR[3] */ +#define LL_GPIO_AF_EXTI_LINE13 (0x00F0U << 16U | 3U) /*!< EXTI_POSITION_4 | EXTICR[3] */ +#define LL_GPIO_AF_EXTI_LINE14 (0x0F00U << 16U | 3U) /*!< EXTI_POSITION_8 | EXTICR[3] */ +#define LL_GPIO_AF_EXTI_LINE15 (0xF000U << 16U | 3U) /*!< EXTI_POSITION_12 | EXTICR[3] */ /** * @} */ @@ -357,8 +357,8 @@ typedef struct */ __STATIC_INLINE void LL_GPIO_SetPinMode(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Mode) { - register uint32_t *pReg = (uint32_t *)((uint32_t)((uint32_t)(&GPIOx->CRL) + (Pin>>24))); - MODIFY_REG(*pReg, ((GPIO_CRL_CNF0|GPIO_CRL_MODE0) << (POSITION_VAL(Pin) * 4U)), (Mode << (POSITION_VAL(Pin) * 4U))); + register uint32_t *pReg = (uint32_t *)((uint32_t)(&GPIOx->CRL) + (Pin >> 24)); + MODIFY_REG(*pReg, ((GPIO_CRL_CNF0 | GPIO_CRL_MODE0) << (POSITION_VAL(Pin) * 4U)), (Mode << (POSITION_VAL(Pin) * 4U))); } /** @@ -397,9 +397,8 @@ __STATIC_INLINE void LL_GPIO_SetPinMode(GPIO_TypeDef *GPIOx, uint32_t Pin, uint3 */ __STATIC_INLINE uint32_t LL_GPIO_GetPinMode(GPIO_TypeDef *GPIOx, uint32_t Pin) { - register uint32_t *pReg = (uint32_t *)((uint32_t)((uint32_t)(&GPIOx->CRL) + (Pin>>24))); - return (uint32_t)(READ_BIT(*pReg, - ((GPIO_CRL_CNF0|GPIO_CRL_MODE0) << (POSITION_VAL(Pin) * 4U))) >> (POSITION_VAL(Pin) * 4U)); + register uint32_t *pReg = (uint32_t *)((uint32_t)(&GPIOx->CRL) + (Pin >> 24)); + return (READ_BIT(*pReg, ((GPIO_CRL_CNF0 | GPIO_CRL_MODE0) << (POSITION_VAL(Pin) * 4U))) >> (POSITION_VAL(Pin) * 4U)); } /** @@ -436,7 +435,7 @@ __STATIC_INLINE uint32_t LL_GPIO_GetPinMode(GPIO_TypeDef *GPIOx, uint32_t Pin) */ __STATIC_INLINE void LL_GPIO_SetPinSpeed(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Speed) { - register uint32_t *pReg = (uint32_t *)((uint32_t)((uint32_t)(&GPIOx->CRL) + (Pin>>24))); + register uint32_t *pReg = (uint32_t *)((uint32_t)(&GPIOx->CRL) + (Pin >> 24)); MODIFY_REG(*pReg, (GPIO_CRL_MODE0 << (POSITION_VAL(Pin) * 4U)), (Speed << (POSITION_VAL(Pin) * 4U))); } @@ -474,9 +473,8 @@ __STATIC_INLINE void LL_GPIO_SetPinSpeed(GPIO_TypeDef *GPIOx, uint32_t Pin, uint */ __STATIC_INLINE uint32_t LL_GPIO_GetPinSpeed(GPIO_TypeDef *GPIOx, uint32_t Pin) { - register uint32_t *pReg = (uint32_t *)((uint32_t)((uint32_t)(&GPIOx->CRL) + (Pin>>24))); - return (uint32_t)(READ_BIT(*pReg, - (GPIO_CRL_MODE0 << (POSITION_VAL(Pin) * 4U))) >> (POSITION_VAL(Pin) * 4U)); + register uint32_t *pReg = (uint32_t *)((uint32_t)(&GPIOx->CRL) + (Pin >> 24)); + return (READ_BIT(*pReg, (GPIO_CRL_MODE0 << (POSITION_VAL(Pin) * 4U))) >> (POSITION_VAL(Pin) * 4U)); } /** @@ -511,7 +509,7 @@ __STATIC_INLINE uint32_t LL_GPIO_GetPinSpeed(GPIO_TypeDef *GPIOx, uint32_t Pin) */ __STATIC_INLINE void LL_GPIO_SetPinOutputType(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t OutputType) { - register uint32_t *pReg = (uint32_t *)((uint32_t)((uint32_t)(&GPIOx->CRL) + (Pin>>24))); + register uint32_t *pReg = (uint32_t *)((uint32_t)(&GPIOx->CRL) + (Pin >> 24)); MODIFY_REG(*pReg, (GPIO_CRL_CNF0_0 << (POSITION_VAL(Pin) * 4U)), (OutputType << (POSITION_VAL(Pin) * 4U))); } @@ -548,9 +546,8 @@ __STATIC_INLINE void LL_GPIO_SetPinOutputType(GPIO_TypeDef *GPIOx, uint32_t Pin, */ __STATIC_INLINE uint32_t LL_GPIO_GetPinOutputType(GPIO_TypeDef *GPIOx, uint32_t Pin) { - register uint32_t *pReg = (uint32_t *)((uint32_t)((uint32_t)(&GPIOx->CRL) + (Pin>>24))); - return (uint32_t)(READ_BIT(*pReg, - (GPIO_CRL_CNF0_0 << (POSITION_VAL(Pin) * 4U))) >> (POSITION_VAL(Pin) * 4U)); + register uint32_t *pReg = (uint32_t *)((uint32_t)(&GPIOx->CRL) + (Pin >> 24)); + return (READ_BIT(*pReg, (GPIO_CRL_CNF0_0 << (POSITION_VAL(Pin) * 4U))) >> (POSITION_VAL(Pin) * 4U)); } @@ -583,7 +580,7 @@ __STATIC_INLINE uint32_t LL_GPIO_GetPinOutputType(GPIO_TypeDef *GPIOx, uint32_t */ __STATIC_INLINE void LL_GPIO_SetPinPull(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Pull) { - MODIFY_REG(GPIOx->ODR, (Pin>>8) , Pull << (POSITION_VAL(Pin>>8))); + MODIFY_REG(GPIOx->ODR, (Pin >> GPIO_PIN_MASK_POS), Pull << (POSITION_VAL(Pin >> GPIO_PIN_MASK_POS))); } /** @@ -614,8 +611,7 @@ __STATIC_INLINE void LL_GPIO_SetPinPull(GPIO_TypeDef *GPIOx, uint32_t Pin, uint3 */ __STATIC_INLINE uint32_t LL_GPIO_GetPinPull(GPIO_TypeDef *GPIOx, uint32_t Pin) { - return (uint32_t)(READ_BIT(GPIOx->ODR, - (GPIO_ODR_ODR0 << (POSITION_VAL(Pin>>8)))) >> (POSITION_VAL(Pin>>8))); + return (READ_BIT(GPIOx->ODR, (GPIO_ODR_ODR0 << (POSITION_VAL(Pin >> GPIO_PIN_MASK_POS)))) >> (POSITION_VAL(Pin >> GPIO_PIN_MASK_POS))); } /** @@ -650,9 +646,9 @@ __STATIC_INLINE uint32_t LL_GPIO_GetPinPull(GPIO_TypeDef *GPIOx, uint32_t Pin) __STATIC_INLINE void LL_GPIO_LockPin(GPIO_TypeDef *GPIOx, uint32_t PinMask) { __IO uint32_t temp; - WRITE_REG(GPIOx->LCKR, GPIO_LCKR_LCKK | ((PinMask >> 8) & 0x0000FFFFU)); - WRITE_REG(GPIOx->LCKR, ((PinMask >>8 ) & 0x0000FFFFU)); - WRITE_REG(GPIOx->LCKR, GPIO_LCKR_LCKK | ((PinMask>>8) & 0x0000FFFFU)); + WRITE_REG(GPIOx->LCKR, GPIO_LCKR_LCKK | ((PinMask >> GPIO_PIN_MASK_POS) & 0x0000FFFFU)); + WRITE_REG(GPIOx->LCKR, ((PinMask >> GPIO_PIN_MASK_POS) & 0x0000FFFFU)); + WRITE_REG(GPIOx->LCKR, GPIO_LCKR_LCKK | ((PinMask >> GPIO_PIN_MASK_POS) & 0x0000FFFFU)); temp = READ_REG(GPIOx->LCKR); (void) temp; } @@ -683,7 +679,7 @@ __STATIC_INLINE void LL_GPIO_LockPin(GPIO_TypeDef *GPIOx, uint32_t PinMask) */ __STATIC_INLINE uint32_t LL_GPIO_IsPinLocked(GPIO_TypeDef *GPIOx, uint32_t PinMask) { - return (READ_BIT(GPIOx->LCKR, ((PinMask >> 8 ) & 0x0000FFFFU)) == ((PinMask >>8 ) & 0x0000FFFFU)); + return (READ_BIT(GPIOx->LCKR, ((PinMask >> GPIO_PIN_MASK_POS) & 0x0000FFFFU)) == ((PinMask >> GPIO_PIN_MASK_POS) & 0x0000FFFFU)); } /** @@ -713,7 +709,7 @@ __STATIC_INLINE uint32_t LL_GPIO_IsAnyPinLocked(GPIO_TypeDef *GPIOx) */ __STATIC_INLINE uint32_t LL_GPIO_ReadInputPort(GPIO_TypeDef *GPIOx) { - return (uint32_t)(READ_REG(GPIOx->IDR)); + return (READ_REG(GPIOx->IDR)); } /** @@ -742,7 +738,7 @@ __STATIC_INLINE uint32_t LL_GPIO_ReadInputPort(GPIO_TypeDef *GPIOx) */ __STATIC_INLINE uint32_t LL_GPIO_IsInputPinSet(GPIO_TypeDef *GPIOx, uint32_t PinMask) { - return (READ_BIT(GPIOx->IDR, (PinMask >> 8 ) & 0x0000FFFFU) == ((PinMask >> 8 ) & 0x0000FFFFU)); + return (READ_BIT(GPIOx->IDR, (PinMask >> GPIO_PIN_MASK_POS) & 0x0000FFFFU) == ((PinMask >> GPIO_PIN_MASK_POS) & 0x0000FFFFU)); } /** @@ -794,7 +790,7 @@ __STATIC_INLINE uint32_t LL_GPIO_ReadOutputPort(GPIO_TypeDef *GPIOx) */ __STATIC_INLINE uint32_t LL_GPIO_IsOutputPinSet(GPIO_TypeDef *GPIOx, uint32_t PinMask) { - return (READ_BIT(GPIOx->ODR, (PinMask >> 8 ) & 0x0000FFFFU) == ((PinMask >> 8 ) & 0x0000FFFFU)); + return (READ_BIT(GPIOx->ODR, (PinMask >> GPIO_PIN_MASK_POS) & 0x0000FFFFU) == ((PinMask >> GPIO_PIN_MASK_POS) & 0x0000FFFFU)); } /** @@ -823,7 +819,7 @@ __STATIC_INLINE uint32_t LL_GPIO_IsOutputPinSet(GPIO_TypeDef *GPIOx, uint32_t Pi */ __STATIC_INLINE void LL_GPIO_SetOutputPin(GPIO_TypeDef *GPIOx, uint32_t PinMask) { - WRITE_REG(GPIOx->BSRR, (PinMask >> 8) & 0x0000FFFFU); + WRITE_REG(GPIOx->BSRR, (PinMask >> GPIO_PIN_MASK_POS) & 0x0000FFFFU); } /** @@ -852,7 +848,7 @@ __STATIC_INLINE void LL_GPIO_SetOutputPin(GPIO_TypeDef *GPIOx, uint32_t PinMask) */ __STATIC_INLINE void LL_GPIO_ResetOutputPin(GPIO_TypeDef *GPIOx, uint32_t PinMask) { - WRITE_REG(GPIOx->BRR, (PinMask >> 8 ) & 0x0000FFFFU); + WRITE_REG(GPIOx->BRR, (PinMask >> GPIO_PIN_MASK_POS) & 0x0000FFFFU); } /** @@ -881,7 +877,7 @@ __STATIC_INLINE void LL_GPIO_ResetOutputPin(GPIO_TypeDef *GPIOx, uint32_t PinMas */ __STATIC_INLINE void LL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint32_t PinMask) { - WRITE_REG(GPIOx->ODR, READ_REG(GPIOx->ODR) ^ ((PinMask >> 8 ) & 0x0000FFFFU)); + WRITE_REG(GPIOx->ODR, READ_REG(GPIOx->ODR) ^ ((PinMask >> GPIO_PIN_MASK_POS) & 0x0000FFFFU)); } /** @@ -1031,7 +1027,7 @@ __STATIC_INLINE uint32_t LL_GPIO_AF_IsEnabledRemap_USART2(void) __STATIC_INLINE void LL_GPIO_AF_EnableRemap_USART3(void) { CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_USART3_REMAP); - SET_BIT(AFIO->MAPR, AFIO_MAPR_USART3_REMAP_FULLREMAP); + SET_BIT(AFIO->MAPR, AFIO_MAPR_USART3_REMAP_FULLREMAP); } /** @@ -1043,7 +1039,7 @@ __STATIC_INLINE void LL_GPIO_AF_EnableRemap_USART3(void) __STATIC_INLINE void LL_GPIO_AF_RemapPartial_USART3(void) { CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_USART3_REMAP); - SET_BIT(AFIO->MAPR, AFIO_MAPR_USART3_REMAP_PARTIALREMAP); + SET_BIT(AFIO->MAPR, AFIO_MAPR_USART3_REMAP_PARTIALREMAP); } /** @@ -1055,7 +1051,7 @@ __STATIC_INLINE void LL_GPIO_AF_RemapPartial_USART3(void) __STATIC_INLINE void LL_GPIO_AF_DisableRemap_USART3(void) { CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_USART3_REMAP); - SET_BIT(AFIO->MAPR, AFIO_MAPR_USART3_REMAP_NOREMAP); + SET_BIT(AFIO->MAPR, AFIO_MAPR_USART3_REMAP_NOREMAP); } #endif @@ -1068,7 +1064,7 @@ __STATIC_INLINE void LL_GPIO_AF_DisableRemap_USART3(void) __STATIC_INLINE void LL_GPIO_AF_EnableRemap_TIM1(void) { CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_TIM1_REMAP); - SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM1_REMAP_FULLREMAP); + SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM1_REMAP_FULLREMAP); } /** @@ -1080,7 +1076,7 @@ __STATIC_INLINE void LL_GPIO_AF_EnableRemap_TIM1(void) __STATIC_INLINE void LL_GPIO_AF_RemapPartial_TIM1(void) { CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_TIM1_REMAP); - SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM1_REMAP_PARTIALREMAP); + SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM1_REMAP_PARTIALREMAP); } /** @@ -1092,7 +1088,7 @@ __STATIC_INLINE void LL_GPIO_AF_RemapPartial_TIM1(void) __STATIC_INLINE void LL_GPIO_AF_DisableRemap_TIM1(void) { CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_TIM1_REMAP); - SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM1_REMAP_NOREMAP); + SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM1_REMAP_NOREMAP); } /** @@ -1104,7 +1100,7 @@ __STATIC_INLINE void LL_GPIO_AF_DisableRemap_TIM1(void) __STATIC_INLINE void LL_GPIO_AF_EnableRemap_TIM2(void) { CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_TIM2_REMAP); - SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM2_REMAP_FULLREMAP); + SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM2_REMAP_FULLREMAP); } /** @@ -1116,7 +1112,7 @@ __STATIC_INLINE void LL_GPIO_AF_EnableRemap_TIM2(void) __STATIC_INLINE void LL_GPIO_AF_RemapPartial2_TIM2(void) { CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_TIM2_REMAP); - SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM2_REMAP_PARTIALREMAP2); + SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM2_REMAP_PARTIALREMAP2); } /** @@ -1128,7 +1124,7 @@ __STATIC_INLINE void LL_GPIO_AF_RemapPartial2_TIM2(void) __STATIC_INLINE void LL_GPIO_AF_RemapPartial1_TIM2(void) { CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_TIM2_REMAP); - SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM2_REMAP_PARTIALREMAP1); + SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM2_REMAP_PARTIALREMAP1); } /** @@ -1140,7 +1136,7 @@ __STATIC_INLINE void LL_GPIO_AF_RemapPartial1_TIM2(void) __STATIC_INLINE void LL_GPIO_AF_DisableRemap_TIM2(void) { CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_TIM2_REMAP); - SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM2_REMAP_NOREMAP); + SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM2_REMAP_NOREMAP); } /** @@ -1153,7 +1149,7 @@ __STATIC_INLINE void LL_GPIO_AF_DisableRemap_TIM2(void) __STATIC_INLINE void LL_GPIO_AF_EnableRemap_TIM3(void) { CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_TIM3_REMAP); - SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM3_REMAP_FULLREMAP); + SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM3_REMAP_FULLREMAP); } /** @@ -1166,7 +1162,7 @@ __STATIC_INLINE void LL_GPIO_AF_EnableRemap_TIM3(void) __STATIC_INLINE void LL_GPIO_AF_RemapPartial_TIM3(void) { CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_TIM3_REMAP); - SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM3_REMAP_PARTIALREMAP); + SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM3_REMAP_PARTIALREMAP); } /** @@ -1179,7 +1175,7 @@ __STATIC_INLINE void LL_GPIO_AF_RemapPartial_TIM3(void) __STATIC_INLINE void LL_GPIO_AF_DisableRemap_TIM3(void) { CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_TIM3_REMAP); - SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM3_REMAP_NOREMAP); + SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM3_REMAP_NOREMAP); } #if defined(AFIO_MAPR_TIM4_REMAP) @@ -1228,7 +1224,7 @@ __STATIC_INLINE uint32_t LL_GPIO_AF_IsEnabledRemap_TIM4(void) __STATIC_INLINE void LL_GPIO_AF_RemapPartial1_CAN1(void) { CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_CAN_REMAP); - SET_BIT(AFIO->MAPR, AFIO_MAPR_CAN_REMAP_REMAP1); + SET_BIT(AFIO->MAPR, AFIO_MAPR_CAN_REMAP_REMAP1); } /** @@ -1240,7 +1236,7 @@ __STATIC_INLINE void LL_GPIO_AF_RemapPartial1_CAN1(void) __STATIC_INLINE void LL_GPIO_AF_RemapPartial2_CAN1(void) { CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_CAN_REMAP); - SET_BIT(AFIO->MAPR, AFIO_MAPR_CAN_REMAP_REMAP2); + SET_BIT(AFIO->MAPR, AFIO_MAPR_CAN_REMAP_REMAP2); } /** @@ -1252,7 +1248,7 @@ __STATIC_INLINE void LL_GPIO_AF_RemapPartial2_CAN1(void) __STATIC_INLINE void LL_GPIO_AF_RemapPartial3_CAN1(void) { CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_CAN_REMAP); - SET_BIT(AFIO->MAPR, AFIO_MAPR_CAN_REMAP_REMAP3); + SET_BIT(AFIO->MAPR, AFIO_MAPR_CAN_REMAP_REMAP3); } #endif @@ -1575,7 +1571,7 @@ __STATIC_INLINE uint32_t LL_GPIO_AF_IsEnabledRemap_ADC2_ETRGREG(void) __STATIC_INLINE void LL_GPIO_AF_EnableRemap_SWJ(void) { CLEAR_BIT(AFIO->MAPR,AFIO_MAPR_SWJ_CFG); - SET_BIT(AFIO->MAPR, AFIO_MAPR_SWJ_CFG_RESET); + SET_BIT(AFIO->MAPR, AFIO_MAPR_SWJ_CFG_RESET); } /** @@ -1611,7 +1607,7 @@ __STATIC_INLINE void LL_GPIO_AF_Remap_SWJ_NOJTAG(void) __STATIC_INLINE void LL_GPIO_AF_DisableRemap_SWJ(void) { CLEAR_BIT(AFIO->MAPR,AFIO_MAPR_SWJ_CFG); - SET_BIT(AFIO->MAPR, AFIO_MAPR_SWJ_CFG_DISABLE); + SET_BIT(AFIO->MAPR, AFIO_MAPR_SWJ_CFG_DISABLE); } #if defined(AFIO_MAPR_SPI3_REMAP) diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_i2c.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_i2c.c index 0a882f75435c..1cd84d436f46 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_i2c.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_i2c.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_i2c.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief I2C LL module driver. ****************************************************************************** * @attention @@ -69,9 +67,9 @@ ((__VALUE__) == LL_I2C_MODE_SMBUS_DEVICE) || \ ((__VALUE__) == LL_I2C_MODE_SMBUS_DEVICE_ARP)) -#define IS_I2C_CLOCK_SPEED(__VALUE__) (((__VALUE__) > 0U) && ((__VALUE__) <= LL_I2C_MAX_SPEED_FAST)) +#define IS_LL_I2C_CLOCK_SPEED(__VALUE__) (((__VALUE__) > 0U) && ((__VALUE__) <= LL_I2C_MAX_SPEED_FAST)) -#define IS_I2C_DUTY_CYCLE(__VALUE__) (((__VALUE__) == LL_I2C_DUTYCYCLE_2) || \ +#define IS_LL_I2C_DUTY_CYCLE(__VALUE__) (((__VALUE__) == LL_I2C_DUTYCYCLE_2) || \ ((__VALUE__) == LL_I2C_DUTYCYCLE_16_9)) #define IS_LL_I2C_OWN_ADDRESS1(__VALUE__) ((__VALUE__) <= 0x000003FFU) @@ -100,8 +98,8 @@ * @brief De-initialize the I2C registers to their default reset values. * @param I2Cx I2C Instance. * @retval An ErrorStatus enumeration value: - * - SUCCESS: I2C registers are de-initialized - * - ERROR: I2C registers are not de-initialized + * - SUCCESS I2C registers are de-initialized + * - ERROR I2C registers are not de-initialized */ uint32_t LL_I2C_DeInit(I2C_TypeDef *I2Cx) { @@ -142,8 +140,8 @@ uint32_t LL_I2C_DeInit(I2C_TypeDef *I2Cx) * @param I2Cx I2C Instance. * @param I2C_InitStruct pointer to a @ref LL_I2C_InitTypeDef structure. * @retval An ErrorStatus enumeration value: - * - SUCCESS: I2C registers are initialized - * - ERROR: Not applicable + * - SUCCESS I2C registers are initialized + * - ERROR Not applicable */ uint32_t LL_I2C_Init(I2C_TypeDef *I2Cx, LL_I2C_InitTypeDef *I2C_InitStruct) { @@ -154,8 +152,8 @@ uint32_t LL_I2C_Init(I2C_TypeDef *I2Cx, LL_I2C_InitTypeDef *I2C_InitStruct) /* Check the I2C parameters from I2C_InitStruct */ assert_param(IS_LL_I2C_PERIPHERAL_MODE(I2C_InitStruct->PeripheralMode)); - assert_param(IS_I2C_CLOCK_SPEED(I2C_InitStruct->ClockSpeed)); - assert_param(IS_I2C_DUTY_CYCLE(I2C_InitStruct->DutyCycle)); + assert_param(IS_LL_I2C_CLOCK_SPEED(I2C_InitStruct->ClockSpeed)); + assert_param(IS_LL_I2C_DUTY_CYCLE(I2C_InitStruct->DutyCycle)); assert_param(IS_LL_I2C_OWN_ADDRESS1(I2C_InitStruct->OwnAddress1)); assert_param(IS_LL_I2C_TYPE_ACKNOWLEDGE(I2C_InitStruct->TypeAcknowledge)); assert_param(IS_LL_I2C_OWN_ADDRSIZE(I2C_InitStruct->OwnAddrSize)); diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_i2c.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_i2c.h index 98081ddc45a9..0abf46fc5ca4 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_i2c.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_i2c.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_i2c.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of I2C LL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_iwdg.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_iwdg.h index 2605939096bd..c40082232be4 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_iwdg.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_iwdg.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_iwdg.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of IWDG LL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_pwr.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_pwr.c index 947d47ac4366..5304bd595766 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_pwr.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_pwr.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_pwr.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief PWR LL module driver. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_pwr.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_pwr.h index a1ad470b15a4..aba9146116e9 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_pwr.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_pwr.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_pwr.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of PWR LL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_rcc.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_rcc.c index d931ff9b6772..615adecb9be5 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_rcc.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_rcc.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_rcc.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief RCC LL module driver. ****************************************************************************** * @attention @@ -106,7 +104,7 @@ uint32_t RCC_PLL2_GetFreqClockFreq(void); * @brief Reset the RCC clock configuration to the default reset state. * @note The default reset state of the clock configuration is given below: * - HSI ON and used as system clock source - * - HSE PLL, PLL2, PLL3 OFF + * - HSE PLL, PLL2 & PLL3 are OFF * - AHB, APB1 and APB2 prescaler set to 1. * - CSS, MCO OFF * - All interrupts disabled @@ -114,78 +112,62 @@ uint32_t RCC_PLL2_GetFreqClockFreq(void); * - Peripheral clocks * - LSI, LSE and RTC clocks * @retval An ErrorStatus enumeration value: - * - SUCCESS: RCC registers are de-initialized - * - ERROR: not applicable + * - SUCCESS: RCC registers are de-initialized + * - ERROR: not applicable */ ErrorStatus LL_RCC_DeInit(void) { - uint32_t vl_mask = 0U; - /* Set HSION bit */ LL_RCC_HSI_Enable(); - /* Reset SW, HPRE, PPRE, MCOSEL, PLLXTPRE, PLLSRC and ADCPRE bits */ - vl_mask = 0xFFFFFFFFU; - CLEAR_BIT(vl_mask, (RCC_CFGR_SW | RCC_CFGR_HPRE | RCC_CFGR_PPRE1 | RCC_CFGR_PPRE2 | RCC_CFGR_MCOSEL |\ - RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_ADCPRE)); - -#if defined(USB) - /* Reset USBPRE bit */ - CLEAR_BIT(vl_mask, RCC_CFGR_USBPRE); -#elif defined(USB_OTG_FS) - /* Reset OTGFSPRE bit */ - CLEAR_BIT(vl_mask, RCC_CFGR_OTGFSPRE); -#endif /* USB */ + /* Wait for HSI READY bit */ + while(LL_RCC_HSI_IsReady() != 1U) + {} -#if defined(RCC_CFGR_PLLMULL2) - /* Set PLL multiplication factor to 2 */ - vl_mask |= RCC_CFGR_PLLMULL2; -#else - /* Set PLL multiplication factor to 4 */ - vl_mask |= RCC_CFGR_PLLMULL4; -#endif /* RCC_CFGR_PLLMULL2 */ + /* Configure HSI as system clock source */ + LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI); + + /* Wait till clock switch is ready */ + while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI) + {} - LL_RCC_WriteReg(CFGR, vl_mask); + /* Reset PLLON bit */ + CLEAR_BIT(RCC->CR, RCC_CR_PLLON); - /* Reset HSEON, HSEBYP, CSSON, PLLON bits */ - vl_mask = 0xFFFFFFFFU; - CLEAR_BIT(vl_mask, (RCC_CR_PLLON | RCC_CR_CSSON | RCC_CR_HSEON | RCC_CR_HSEBYP)); + /* Wait for PLL READY bit to be reset */ + while(LL_RCC_PLL_IsReady() != 0U) + {} + + /* Reset CFGR register */ + LL_RCC_WriteReg(CFGR, 0x00000000U); + + /* Reset HSEON, HSEBYP & CSSON bits */ + CLEAR_BIT(RCC->CR, (RCC_CR_CSSON | RCC_CR_HSEON | RCC_CR_HSEBYP)); #if defined(RCC_CR_PLL2ON) /* Reset PLL2ON bit */ - CLEAR_BIT(vl_mask, RCC_CR_PLL2ON); + CLEAR_BIT(RCC->CR, RCC_CR_PLL2ON); #endif /* RCC_CR_PLL2ON */ #if defined(RCC_CR_PLL3ON) /* Reset PLL3ON bit */ - CLEAR_BIT(vl_mask, RCC_CR_PLL3ON); + CLEAR_BIT(RCC->CR, RCC_CR_PLL3ON); #endif /* RCC_CR_PLL3ON */ - LL_RCC_WriteReg(CR, vl_mask); - /* Set HSITRIM bits to the reset value */ LL_RCC_HSI_SetCalibTrimming(0x10U); #if defined(RCC_CFGR2_PREDIV1) /* Reset CFGR2 register */ - vl_mask = 0x00000000U; - -#if defined(RCC_PLL2_SUPPORT) - /* Set PLL2 multiplication factor to 8 */ - vl_mask |= RCC_CFGR2_PLL2MUL8; -#endif /* RCC_PLL2_SUPPORT */ - -#if defined(RCC_PLLI2S_SUPPORT) - /* Set PLL3 multiplication factor to 8 */ - vl_mask |= RCC_CFGR2_PLL3MUL8; -#endif /* RCC_PLLI2S_SUPPORT */ - - LL_RCC_WriteReg(CFGR2, vl_mask); + LL_RCC_WriteReg(CFGR2, 0x00000000U); #endif /* RCC_CFGR2_PREDIV1 */ /* Disable all interrupts */ LL_RCC_WriteReg(CIR, 0x00000000U); + /* Clear reset flags */ + LL_RCC_ClearResetFlags(); + return SUCCESS; } diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_rcc.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_rcc.h index c87d5652063e..f03a74a1aa43 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_rcc.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_rcc.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_rcc.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of RCC LL module. ****************************************************************************** * @attention @@ -424,8 +422,8 @@ typedef struct #define LL_RCC_PLLSOURCE_PLL2 (RCC_CFGR_PLLSRC | RCC_CFGR2_PREDIV1SRC << 4U) /*!< PLL2/PREDIV1 clock selected as PLL entry clock source */ #endif /*RCC_CFGR2_PREDIV1SRC*/ -#define LL_RCC_PLLSOURCE_HSE_DIV_1 RCC_CFGR_PLLSRC /*!< HSE clock selected as PLL entry clock source */ #if defined(RCC_CFGR2_PREDIV1) +#define LL_RCC_PLLSOURCE_HSE_DIV_1 (RCC_CFGR_PLLSRC | RCC_CFGR2_PREDIV1_DIV1) /*!< HSE/1 clock selected as PLL entry clock source */ #define LL_RCC_PLLSOURCE_HSE_DIV_2 (RCC_CFGR_PLLSRC | RCC_CFGR2_PREDIV1_DIV2) /*!< HSE/2 clock selected as PLL entry clock source */ #define LL_RCC_PLLSOURCE_HSE_DIV_3 (RCC_CFGR_PLLSRC | RCC_CFGR2_PREDIV1_DIV3) /*!< HSE/3 clock selected as PLL entry clock source */ #define LL_RCC_PLLSOURCE_HSE_DIV_4 (RCC_CFGR_PLLSRC | RCC_CFGR2_PREDIV1_DIV4) /*!< HSE/4 clock selected as PLL entry clock source */ @@ -442,6 +440,7 @@ typedef struct #define LL_RCC_PLLSOURCE_HSE_DIV_15 (RCC_CFGR_PLLSRC | RCC_CFGR2_PREDIV1_DIV15) /*!< HSE/15 clock selected as PLL entry clock source */ #define LL_RCC_PLLSOURCE_HSE_DIV_16 (RCC_CFGR_PLLSRC | RCC_CFGR2_PREDIV1_DIV16) /*!< HSE/16 clock selected as PLL entry clock source */ #if defined(RCC_CFGR2_PREDIV1SRC) +#define LL_RCC_PLLSOURCE_PLL2_DIV_1 (RCC_CFGR_PLLSRC | RCC_CFGR2_PREDIV1_DIV1 | RCC_CFGR2_PREDIV1SRC << 4U) /*!< PLL2/1 clock selected as PLL entry clock source */ #define LL_RCC_PLLSOURCE_PLL2_DIV_2 (RCC_CFGR_PLLSRC | RCC_CFGR2_PREDIV1_DIV2 | RCC_CFGR2_PREDIV1SRC << 4U) /*!< PLL2/2 clock selected as PLL entry clock source */ #define LL_RCC_PLLSOURCE_PLL2_DIV_3 (RCC_CFGR_PLLSRC | RCC_CFGR2_PREDIV1_DIV3 | RCC_CFGR2_PREDIV1SRC << 4U) /*!< PLL2/3 clock selected as PLL entry clock source */ #define LL_RCC_PLLSOURCE_PLL2_DIV_4 (RCC_CFGR_PLLSRC | RCC_CFGR2_PREDIV1_DIV4 | RCC_CFGR2_PREDIV1SRC << 4U) /*!< PLL2/4 clock selected as PLL entry clock source */ @@ -459,6 +458,7 @@ typedef struct #define LL_RCC_PLLSOURCE_PLL2_DIV_16 (RCC_CFGR_PLLSRC | RCC_CFGR2_PREDIV1_DIV16 | RCC_CFGR2_PREDIV1SRC << 4U) /*!< PLL2/16 clock selected as PLL entry clock source */ #endif /*RCC_CFGR2_PREDIV1SRC*/ #else +#define LL_RCC_PLLSOURCE_HSE_DIV_1 (RCC_CFGR_PLLSRC | 0x00000000U) /*!< HSE/1 clock selected as PLL entry clock source */ #define LL_RCC_PLLSOURCE_HSE_DIV_2 (RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE) /*!< HSE/2 clock selected as PLL entry clock source */ #endif /*RCC_CFGR2_PREDIV1*/ /** @@ -1451,6 +1451,7 @@ __STATIC_INLINE uint32_t LL_RCC_PLL_IsReady(void) * @arg @ref LL_RCC_PLLSOURCE_HSE_DIV_14 (*) * @arg @ref LL_RCC_PLLSOURCE_HSE_DIV_15 (*) * @arg @ref LL_RCC_PLLSOURCE_HSE_DIV_16 (*) + * @arg @ref LL_RCC_PLLSOURCE_PLL2_DIV_1 (*) * @arg @ref LL_RCC_PLLSOURCE_PLL2_DIV_2 (*) * @arg @ref LL_RCC_PLLSOURCE_PLL2_DIV_3 (*) * @arg @ref LL_RCC_PLLSOURCE_PLL2_DIV_4 (*) @@ -1503,6 +1504,24 @@ __STATIC_INLINE void LL_RCC_PLL_ConfigDomain_SYS(uint32_t Source, uint32_t PLLMu #endif /*RCC_CFGR2_PREDIV1*/ } +/** + * @brief Configure PLL clock source + * @rmtoll CFGR PLLSRC LL_RCC_PLL_SetMainSource\n + * CFGR2 PREDIV1SRC LL_RCC_PLL_SetMainSource + * @param PLLSource This parameter can be one of the following values: + * @arg @ref LL_RCC_PLLSOURCE_HSI_DIV_2 + * @arg @ref LL_RCC_PLLSOURCE_HSE + * @arg @ref LL_RCC_PLLSOURCE_PLL2 (*) + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL_SetMainSource(uint32_t PLLSource) +{ +#if defined(RCC_CFGR2_PREDIV1SRC) + MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC, ((PLLSource & (RCC_CFGR2_PREDIV1SRC << 4U)) >> 4U)); +#endif /* RCC_CFGR2_PREDIV1SRC */ + MODIFY_REG(RCC->CFGR, RCC_CFGR_PLLSRC, PLLSource); +} + /** * @brief Get the oscillator used as PLL clock source. * @rmtoll CFGR PLLSRC LL_RCC_PLL_GetMainSource\n diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_rtc.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_rtc.c index 48510d246e31..d50e1ff1c73b 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_rtc.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_rtc.c @@ -1,9 +1,7 @@ /** ****************************************************************************** * @file stm32f1xx_ll_rtc.c - * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 + * @author MCD Application Team * @brief RTC LL module driver. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_rtc.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_rtc.h index 4d157120be22..944808db6931 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_rtc.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_rtc.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_rtc.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of RTC LL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_sdmmc.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_sdmmc.c index f8d04bc11716..a789b92700ea 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_sdmmc.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_sdmmc.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_sdmmc.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief SDIO Low Layer HAL module driver. * * This file provides firmware functions to manage the following diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_sdmmc.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_sdmmc.h index 7ff5f3784e87..d4cb12e3f99f 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_sdmmc.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_sdmmc.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_sdmmc.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of low layer SDMMC HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_spi.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_spi.c index 67262c96e922..151f6dd43451 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_spi.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_spi.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_spi.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief SPI LL module driver. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_spi.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_spi.h index c8c6061ee427..d274f04f94de 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_spi.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_spi.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_spi.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of SPI LL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_system.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_system.h index 7f204c23f4b5..f3592bc2b315 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_system.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_system.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_system.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of SYSTEM LL module. @verbatim ============================================================================== @@ -126,11 +124,12 @@ extern "C" { #if defined(DBGMCU_CR_DBG_TIM14_STOP) #define LL_DBGMCU_APB1_GRP1_TIM14_STOP DBGMCU_CR_DBG_TIM14_STOP /*!< TIM14 counter stopped when core is halted */ #endif /* DBGMCU_CR_DBG_TIM14_STOP */ -#define LL_DBGMCU_APB1_GRP1_RTC_STOP DBGMCU_CR_DBG_RTC_STOP /*!< RTC counter stopped when core is halted */ #define LL_DBGMCU_APB1_GRP1_WWDG_STOP DBGMCU_CR_DBG_WWDG_STOP /*!< Debug Window Watchdog stopped when Core is halted */ #define LL_DBGMCU_APB1_GRP1_IWDG_STOP DBGMCU_CR_DBG_IWDG_STOP /*!< Debug Independent Watchdog stopped when Core is halted */ -#define LL_DBGMCU_APB1_GRP1_I2C1_STOP DBGMCU_CR_DBG_I2C1_STOP /*!< I2C1 SMBUS timeout mode stopped when Core is halted */ -#define LL_DBGMCU_APB1_GRP1_I2C2_STOP DBGMCU_CR_DBG_I2C2_STOP /*!< I2C2 SMBUS timeout mode stopped when Core is halted */ +#define LL_DBGMCU_APB1_GRP1_I2C1_STOP DBGMCU_CR_DBG_I2C1_SMBUS_TIMEOUT /*!< I2C1 SMBUS timeout mode stopped when Core is halted */ +#if defined(DBGMCU_CR_DBG_I2C2_SMBUS_TIMEOUT) +#define LL_DBGMCU_APB1_GRP1_I2C2_STOP DBGMCU_CR_DBG_I2C2_SMBUS_TIMEOUT /*!< I2C2 SMBUS timeout mode stopped when Core is halted */ +#endif /* DBGMCU_CR_DBG_I2C2_SMBUS_TIMEOUT */ #if defined(DBGMCU_CR_DBG_CAN1_STOP) #define LL_DBGMCU_APB1_GRP1_CAN1_STOP DBGMCU_CR_DBG_CAN1_STOP /*!< CAN1 debug stopped when Core is halted */ #endif /* DBGMCU_CR_DBG_CAN1_STOP */ @@ -352,11 +351,10 @@ __STATIC_INLINE uint32_t LL_DBGMCU_GetTracePinAssignment(void) * @arg @ref LL_DBGMCU_APB1_GRP1_TIM12_STOP * @arg @ref LL_DBGMCU_APB1_GRP1_TIM13_STOP * @arg @ref LL_DBGMCU_APB1_GRP1_TIM14_STOP - * @arg @ref LL_DBGMCU_APB1_GRP1_RTC_STOP * @arg @ref LL_DBGMCU_APB1_GRP1_WWDG_STOP * @arg @ref LL_DBGMCU_APB1_GRP1_IWDG_STOP * @arg @ref LL_DBGMCU_APB1_GRP1_I2C1_STOP - * @arg @ref LL_DBGMCU_APB1_GRP1_I2C2_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_I2C2_STOP (*) * @arg @ref LL_DBGMCU_APB1_GRP1_CAN1_STOP (*) * @arg @ref LL_DBGMCU_APB1_GRP1_CAN2_STOP (*) * @@ -400,7 +398,7 @@ __STATIC_INLINE void LL_DBGMCU_APB1_GRP1_FreezePeriph(uint32_t Periphs) * @arg @ref LL_DBGMCU_APB1_GRP1_WWDG_STOP * @arg @ref LL_DBGMCU_APB1_GRP1_IWDG_STOP * @arg @ref LL_DBGMCU_APB1_GRP1_I2C1_STOP - * @arg @ref LL_DBGMCU_APB1_GRP1_I2C2_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_I2C2_STOP (*) * @arg @ref LL_DBGMCU_APB1_GRP1_CAN1_STOP (*) * @arg @ref LL_DBGMCU_APB1_GRP1_CAN2_STOP (*) * diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_tim.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_tim.c index ef5edc888858..942ce13466aa 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_tim.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_tim.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_tim.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief TIM LL module driver. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_tim.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_tim.h index 2f93fbd948ac..a2b7202d6023 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_tim.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_tim.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_tim.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of TIM LL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_usart.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_usart.c index 04b047a0b2bd..4a0873253201 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_usart.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_usart.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_usart.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief USART LL module driver. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_usart.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_usart.h index 00983287a163..6c4e3d05b88b 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_usart.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_usart.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_usart.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of USART LL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_usb.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_usb.c index 7cf32611ee7c..d119af1e7871 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_usb.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_usb.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_usb.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief USB Low Layer HAL module driver. * * This file provides firmware functions to manage the following diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_usb.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_usb.h index 4538acba4c0d..698f77f7b2b6 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_usb.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_usb.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_usb.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of USB Low Layer HAL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_utils.c b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_utils.c index 91e071a15b75..d2b47fd63381 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_utils.c +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_utils.c @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_utils.c * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief UTILS LL module driver. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_utils.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_utils.h index 1ac615c853d4..e224e691707d 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_utils.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_utils.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_utils.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of UTILS LL module. @verbatim ============================================================================== diff --git a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_wwdg.h b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_wwdg.h index 7330ac806af5..aca236eeed82 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_wwdg.h +++ b/targets/TARGET_STM/TARGET_STM32F1/device/stm32f1xx_ll_wwdg.h @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f1xx_ll_wwdg.h * @author MCD Application Team - * @version V1.1.0 - * @date 14-April-2017 * @brief Header file of WWDG LL module. ****************************************************************************** * @attention diff --git a/targets/TARGET_STM/TARGET_STM32F2/TARGET_NUCLEO_F207ZG/device/system_clock.c b/targets/TARGET_STM/TARGET_STM32F2/TARGET_NUCLEO_F207ZG/device/system_clock.c index 75e4ad856122..f201095cc3d4 100644 --- a/targets/TARGET_STM/TARGET_STM32F2/TARGET_NUCLEO_F207ZG/device/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F2/TARGET_NUCLEO_F207ZG/device/system_clock.c @@ -30,7 +30,7 @@ **/ #include "stm32f2xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -120,8 +120,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while(1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F2/device.h b/targets/TARGET_STM/TARGET_STM32F2/device.h index 8037b590d697..a60fa2abae0d 100644 --- a/targets/TARGET_STM/TARGET_STM32F2/device.h +++ b/targets/TARGET_STM/TARGET_STM32F2/device.h @@ -33,5 +33,7 @@ #define DEVICE_ID_LENGTH 24 #include "objects.h" +/* WORKAROUND waiting for mbed-os issue 4408 to be addressed */ +#include "stm32f2xx_ll_usart.h" #endif diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F302x8/TARGET_NUCLEO_F302R8/system_clock.c b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F302x8/TARGET_NUCLEO_F302R8/system_clock.c index 1dd610db0275..c584277b7e6c 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F302x8/TARGET_NUCLEO_F302R8/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F302x8/TARGET_NUCLEO_F302R8/system_clock.c @@ -36,7 +36,7 @@ #include "stm32f3xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -130,8 +130,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303x8/TARGET_NUCLEO_F303K8/system_clock.c b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303x8/TARGET_NUCLEO_F303K8/system_clock.c index bae835363345..ca6b13f82f4c 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303x8/TARGET_NUCLEO_F303K8/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303x8/TARGET_NUCLEO_F303K8/system_clock.c @@ -36,7 +36,7 @@ #include "stm32f3xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -130,8 +130,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xC/TARGET_DISCO_F303VC/system_clock.c b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xC/TARGET_DISCO_F303VC/system_clock.c index 0234b019ec04..30007bb9934e 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xC/TARGET_DISCO_F303VC/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xC/TARGET_DISCO_F303VC/system_clock.c @@ -35,7 +35,7 @@ **/ #include "stm32f3xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -129,8 +129,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/TARGET_NUCLEO_F303RE/system_clock.c b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/TARGET_NUCLEO_F303RE/system_clock.c index 901da5542163..5fcac16f67f1 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/TARGET_NUCLEO_F303RE/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/TARGET_NUCLEO_F303RE/system_clock.c @@ -31,13 +31,7 @@ #include "stm32f3xx.h" -#include "mbed_assert.h" - -/*!< Uncomment the following line if you need to relocate your vector Table in - Internal SRAM. */ -/* #define VECT_TAB_SRAM */ -#define VECT_TAB_OFFSET 0x0 /*!< Vector Table base offset field. - This value must be a multiple of 0x200. */ +#include "mbed_error.h" // clock source is selected with CLOCK_SOURCE in json config #define USE_PLL_HSE_EXTC 0x8 // Use external clock (ST Link MCO) @@ -89,13 +83,6 @@ void SystemInit(void) /* Disable all interrupts */ RCC->CIR = 0x00000000U; - -#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 */ -#endif - } @@ -125,8 +112,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/TARGET_NUCLEO_F303ZE/system_clock.c b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/TARGET_NUCLEO_F303ZE/system_clock.c index 901da5542163..2617e46319c0 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/TARGET_NUCLEO_F303ZE/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/TARGET_NUCLEO_F303ZE/system_clock.c @@ -31,7 +31,7 @@ #include "stm32f3xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -125,8 +125,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/device/TOOLCHAIN_ARM_STD/stm32f303xe.sct b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/device/TOOLCHAIN_ARM_STD/stm32f303xe.sct index e861c23b2cf1..b2f0812c8bee 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/device/TOOLCHAIN_ARM_STD/stm32f303xe.sct +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/device/TOOLCHAIN_ARM_STD/stm32f303xe.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. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +#if !defined(MBED_APP_START) + #define MBED_APP_START 0x08000000 +#endif + +#if !defined(MBED_APP_SIZE) + #define MBED_APP_SIZE 0x80000 +#endif + ; STM32F303RE: 512KB FLASH (0x80000) + 64KB SRAM (0x10000) -LR_IROM1 0x08000000 0x80000 { ; load region size_region +LR_IROM1 MBED_APP_START MBED_APP_SIZE { ; load region size_region - ER_IROM1 0x08000000 0x80000 { ; load address = execution address + ER_IROM1 MBED_APP_START MBED_APP_SIZE { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/device/TOOLCHAIN_GCC_ARM/STM32F303XE.ld b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/device/TOOLCHAIN_GCC_ARM/STM32F303XE.ld index a98a441f7d84..49c89254684d 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/device/TOOLCHAIN_GCC_ARM/STM32F303XE.ld +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/device/TOOLCHAIN_GCC_ARM/STM32F303XE.ld @@ -1,7 +1,15 @@ /* Linker script to configure memory regions. */ +#ifndef MBED_APP_START +#define MBED_APP_START 0x08000000 +#endif + +#ifndef MBED_APP_SIZE +#define MBED_APP_SIZE 512K +#endif + MEMORY { - FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K + FLASH (rx) : ORIGIN = MBED_APP_START, LENGTH = MBED_APP_SIZE CCM (rwx) : ORIGIN = 0x10000000, LENGTH = 16K RAM (rwx) : ORIGIN = 0x20000194, LENGTH = 64K - 0x194 } diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/device/TOOLCHAIN_IAR/stm32f303xe.icf b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/device/TOOLCHAIN_IAR/stm32f303xe.icf index 9b1f074c538f..5d04b1c52396 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/device/TOOLCHAIN_IAR/stm32f303xe.icf +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/device/TOOLCHAIN_IAR/stm32f303xe.icf @@ -1,7 +1,10 @@ +if (!isdefinedsymbol(MBED_APP_START)) { define symbol MBED_APP_START = 0x08000000; } +if (!isdefinedsymbol(MBED_APP_SIZE)) { define symbol MBED_APP_SIZE = 0x80000; } + /* [ROM = 512kb = 0x80000] */ -define symbol __intvec_start__ = 0x08000000; -define symbol __region_ROM_start__ = 0x08000000; -define symbol __region_ROM_end__ = 0x0807FFFF; +define symbol __intvec_start__ = MBED_APP_START; +define symbol __region_ROM_start__ = MBED_APP_START; +define symbol __region_ROM_end__ = MBED_APP_START + MBED_APP_SIZE - 1; define symbol __region_CCMRAM_start__ = 0x10000000; define symbol __region_CCMRAM_end__ = 0x10003FFF; @@ -21,7 +24,7 @@ define region CCMRAM_region = mem:[from __region_CCMRAM_start__ to __region_CCMR /* Stack and Heap */ /*Heap 1/4 of ram and stack 1/8*/ define symbol __size_cstack__ = 0x2000; -define symbol __size_heap__ = 0x4000; +define symbol __size_heap__ = 0x5000; define block CSTACK with alignment = 8, size = __size_cstack__ { }; define block HEAP with alignment = 8, size = __size_heap__ { }; define block STACKHEAP with fixed order { block HEAP, block CSTACK }; diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F334x8/TARGET_DISCO_F334C8/system_clock.c b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F334x8/TARGET_DISCO_F334C8/system_clock.c index bae835363345..ca6b13f82f4c 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F334x8/TARGET_DISCO_F334C8/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F334x8/TARGET_DISCO_F334C8/system_clock.c @@ -36,7 +36,7 @@ #include "stm32f3xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -130,8 +130,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F334x8/TARGET_NUCLEO_F334R8/system_clock.c b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F334x8/TARGET_NUCLEO_F334R8/system_clock.c index bae835363345..ca6b13f82f4c 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F334x8/TARGET_NUCLEO_F334R8/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F334x8/TARGET_NUCLEO_F334R8/system_clock.c @@ -36,7 +36,7 @@ #include "stm32f3xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -130,8 +130,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F3/device.h b/targets/TARGET_STM/TARGET_STM32F3/device.h index b6131682750f..df642ecaa543 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/device.h +++ b/targets/TARGET_STM/TARGET_STM32F3/device.h @@ -36,5 +36,7 @@ #define DEVICE_ID_LENGTH 24 #include "objects.h" +/* WORKAROUND waiting for mbed-os issue 4408 to be addressed */ +#include "stm32f3xx_ll_usart.h" #endif diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xE/TARGET_NUCLEO_F401RE/system_clock.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xE/TARGET_NUCLEO_F401RE/system_clock.c index 87344b0f2039..6c303390e67f 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xE/TARGET_NUCLEO_F401RE/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xE/TARGET_NUCLEO_F401RE/system_clock.c @@ -30,7 +30,7 @@ **/ #include "stm32f4xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -125,8 +125,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xE/TARGET_STEVAL_3DP001V1/system_clock.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xE/TARGET_STEVAL_3DP001V1/system_clock.c index dfb96ca3844d..e87e29a59bd0 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xE/TARGET_STEVAL_3DP001V1/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xE/TARGET_STEVAL_3DP001V1/system_clock.c @@ -30,7 +30,7 @@ **/ #include "stm32f4xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -125,8 +125,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F407xG/TARGET_DISCO_F407VG/system_clock.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F407xG/TARGET_DISCO_F407VG/system_clock.c index dcabc3b8437a..8ce597f5476c 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F407xG/TARGET_DISCO_F407VG/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F407xG/TARGET_DISCO_F407VG/system_clock.c @@ -30,7 +30,7 @@ **/ #include "stm32f4xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -124,8 +124,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F410xB/TARGET_NUCLEO_F410RB/system_clock.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F410xB/TARGET_NUCLEO_F410RB/system_clock.c index 9184ae478238..4cbf61f6792c 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F410xB/TARGET_NUCLEO_F410RB/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F410xB/TARGET_NUCLEO_F410RB/system_clock.c @@ -30,7 +30,7 @@ **/ #include "stm32f4xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -125,8 +125,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/TARGET_NUCLEO_F411RE/system_clock.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/TARGET_NUCLEO_F411RE/system_clock.c index 5a81b4a67382..a1980f0a2473 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/TARGET_NUCLEO_F411RE/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/TARGET_NUCLEO_F411RE/system_clock.c @@ -30,7 +30,7 @@ **/ #include "stm32f4xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" // clock source is selected with CLOCK_SOURCE in json config #define USE_PLL_HSE_EXTC 0x8 // Use external clock (ST Link MCO) @@ -110,8 +110,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/TARGET_SAKURAIO_EVB_01/system_clock.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/TARGET_SAKURAIO_EVB_01/system_clock.c index c15d024fce8f..d9bc626abe79 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/TARGET_SAKURAIO_EVB_01/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/TARGET_SAKURAIO_EVB_01/system_clock.c @@ -30,7 +30,7 @@ **/ #include "stm32f4xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -125,8 +125,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/TARGET_MTB_MXCHIP_EMW3166/PinNames.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/TARGET_MTB_MXCHIP_EMW3166/PinNames.h index 09351253a865..80e698307c3b 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/TARGET_MTB_MXCHIP_EMW3166/PinNames.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/TARGET_MTB_MXCHIP_EMW3166/PinNames.h @@ -201,6 +201,7 @@ typedef enum { // Generic signals namings LED1 = PB_2, LED2 = PB_10, + LED3 = NC, LED_RED = LED1, LED_BLUE = LED2, USER_BUTTON = PC_13, @@ -217,7 +218,7 @@ typedef enum { SPI_MOSI = P_4, SPI_MISO = P_7, SPI_SCK = P_6, - SPI_CS = P_16, + SPI_CS = P_5, // STDIO for console print #ifdef MBED_CONF_TARGET_STDIO_UART_TX diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/TARGET_MTB_MXCHIP_EMW3166/system_clock.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/TARGET_MTB_MXCHIP_EMW3166/system_clock.c index 362dba42c55e..6d56932c0495 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/TARGET_MTB_MXCHIP_EMW3166/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/TARGET_MTB_MXCHIP_EMW3166/system_clock.c @@ -31,7 +31,7 @@ #include "stm32f4xx.h" #include "nvic_addr.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -126,8 +126,8 @@ void SetSysClock(void) if (ret_HSIclk_status == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/TARGET_NUCLEO_F412ZG/system_clock.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/TARGET_NUCLEO_F412ZG/system_clock.c index 319fbc885bfa..419411be28a1 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/TARGET_NUCLEO_F412ZG/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/TARGET_NUCLEO_F412ZG/system_clock.c @@ -31,7 +31,7 @@ #include "stm32f4xx.h" #include "nvic_addr.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -125,8 +125,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/TARGET_USI_WM_BN_BM_22/PinNames.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/TARGET_USI_WM_BN_BM_22/PinNames.h index 140138831597..42969ea6bcec 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/TARGET_USI_WM_BN_BM_22/PinNames.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/TARGET_USI_WM_BN_BM_22/PinNames.h @@ -241,12 +241,24 @@ typedef enum { // Generic signals namings +#ifdef MBED_CONF_TARGET_LED1 + LED1 = MBED_CONF_TARGET_LED1, +#else LED1 = PA_7, +#endif +#ifdef MBED_CONF_TARGET_LED2 + LED2 = MBED_CONF_TARGET_LED2, +#else LED2 = PC_4, +#endif +#ifdef MBED_CONF_TARGET_LED3 + LED3 = MBED_CONF_TARGET_LED3, +#else LED3 = PC_11, +#endif LED_RED = LED1, LED_BLUE = LED2, - LED_GREEN = LED3, + LED_GREEN = LED3, USER_BUTTON = PB_14, // Standardized button names diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/TARGET_USI_WM_BN_BM_22/system_clock.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/TARGET_USI_WM_BN_BM_22/system_clock.c index 362dba42c55e..6d56932c0495 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/TARGET_USI_WM_BN_BM_22/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/TARGET_USI_WM_BN_BM_22/system_clock.c @@ -31,7 +31,7 @@ #include "stm32f4xx.h" #include "nvic_addr.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -126,8 +126,8 @@ void SetSysClock(void) if (ret_HSIclk_status == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/TARGET_DISCO_F413ZH/system_clock.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/TARGET_DISCO_F413ZH/system_clock.c index 63a9146a9d02..2016fd274deb 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/TARGET_DISCO_F413ZH/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/TARGET_DISCO_F413ZH/system_clock.c @@ -30,7 +30,7 @@ **/ #include "stm32f4xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in @@ -126,8 +126,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/TARGET_NUCLEO_F413ZH/system_clock.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/TARGET_NUCLEO_F413ZH/system_clock.c index a209b693ad4a..c7f64e5ff2ff 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/TARGET_NUCLEO_F413ZH/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/TARGET_NUCLEO_F413ZH/system_clock.c @@ -30,7 +30,7 @@ **/ #include "stm32f4xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in @@ -126,8 +126,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/TARGET_DISCO_F429ZI/system_clock.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/TARGET_DISCO_F429ZI/system_clock.c index a6f4d7180aa9..02edcc0e6002 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/TARGET_DISCO_F429ZI/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/TARGET_DISCO_F429ZI/system_clock.c @@ -31,7 +31,7 @@ #include "stm32f4xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" // clock source is selected with CLOCK_SOURCE in json config #define USE_PLL_HSE_EXTC 0x8 // Use external clock (ST Link MCO) @@ -107,8 +107,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/TARGET_NUCLEO_F429ZI/system_clock.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/TARGET_NUCLEO_F429ZI/system_clock.c index a6f4d7180aa9..02edcc0e6002 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/TARGET_NUCLEO_F429ZI/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/TARGET_NUCLEO_F429ZI/system_clock.c @@ -31,7 +31,7 @@ #include "stm32f4xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" // clock source is selected with CLOCK_SOURCE in json config #define USE_PLL_HSE_EXTC 0x8 // Use external clock (ST Link MCO) @@ -107,8 +107,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/TARGET_UBLOX_C030/onboard_modem_api.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/TARGET_UBLOX_C030/onboard_modem_api.c index 6689308b01a7..00281d2511ce 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/TARGET_UBLOX_C030/onboard_modem_api.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/TARGET_UBLOX_C030/onboard_modem_api.c @@ -70,13 +70,8 @@ void onboard_modem_power_up() void onboard_modem_power_down() { -#if defined(TARGET_UBLOX_C030_R410M) /* keep the power line low for 1.5 seconds */ press_power_button(1500000); -#else - /* keep the power line low for 1 seconds */ - press_power_button(1000000); -#endif } #endif //MODEM_ON_BOARD diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/TARGET_NUCLEO_F439ZI/system_clock.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/TARGET_NUCLEO_F439ZI/system_clock.c index 9a12df06e702..bbc9a292ed35 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/TARGET_NUCLEO_F439ZI/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/TARGET_NUCLEO_F439ZI/system_clock.c @@ -36,7 +36,7 @@ #include "stm32f4xx.h" #include "nvic_addr.h" -#include "mbed_assert.h" +#include "mbed_error.h" // clock source is selected with CLOCK_SOURCE in json config #define USE_PLL_HSE_EXTC 0x8 // Use external clock (ST Link MCO) @@ -122,8 +122,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/TARGET_WIO_3G/system_clock.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/TARGET_WIO_3G/system_clock.c index 6dc371b79452..2ee393505093 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/TARGET_WIO_3G/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/TARGET_WIO_3G/system_clock.c @@ -36,7 +36,7 @@ #include "stm32f4xx.h" #include "nvic_addr.h" -#include "mbed_assert.h" +#include "mbed_error.h" // clock source is selected with CLOCK_SOURCE in json config #define USE_PLL_HSE_EXTC 0x8 // Use external clock (ST Link MCO) @@ -122,8 +122,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/TOOLCHAIN_IAR/stm32f439xx_flash.icf b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/TOOLCHAIN_IAR/stm32f439xx_flash.icf index 3b428be87cff..cf2b2b01351c 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/TOOLCHAIN_IAR/stm32f439xx_flash.icf +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/TOOLCHAIN_IAR/stm32f439xx_flash.icf @@ -15,9 +15,9 @@ define symbol __ICFEDIT_region_RAM_end__ = 0x2002FFFF; define symbol __ICFEDIT_region_CCMRAM_start__ = 0x10000000; define symbol __ICFEDIT_region_CCMRAM_end__ = 0x1000FFFF; /*-Sizes-*/ -/*Heap 64kB and stack 24kB */ -define symbol __ICFEDIT_size_cstack__ = 0x6000; -define symbol __ICFEDIT_size_heap__ = 0x10000; +/*Heap 89kB and stack 1kB */ +define symbol __ICFEDIT_size_cstack__ = 0x400; +define symbol __ICFEDIT_size_heap__ = 0x15C00; /**** End of ICF editor section. ###ICF###*/ diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/TARGET_NUCLEO_F446RE/system_clock.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/TARGET_NUCLEO_F446RE/system_clock.c index e26ff60b4537..ffac28662250 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/TARGET_NUCLEO_F446RE/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/TARGET_NUCLEO_F446RE/system_clock.c @@ -35,7 +35,7 @@ **/ #include "stm32f4xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" // clock source is selected with CLOCK_SOURCE in json config #define USE_PLL_HSE_EXTC 0x8 // Use external clock (ST Link MCO) @@ -119,8 +119,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/TARGET_NUCLEO_F446ZE/system_clock.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/TARGET_NUCLEO_F446ZE/system_clock.c index c99a3932239a..fbd2f0e304b7 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/TARGET_NUCLEO_F446ZE/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/TARGET_NUCLEO_F446ZE/system_clock.c @@ -30,7 +30,7 @@ **/ #include "stm32f4xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in @@ -129,8 +129,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_DISCO_F469NI/system_clock.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_DISCO_F469NI/system_clock.c index ea9be4b2d29d..ddd89072426a 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_DISCO_F469NI/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_DISCO_F469NI/system_clock.c @@ -30,7 +30,7 @@ **/ #include "stm32f4xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in @@ -129,8 +129,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F4/device.h b/targets/TARGET_STM/TARGET_STM32F4/device.h index b6131682750f..d06e96fbbd26 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/device.h +++ b/targets/TARGET_STM/TARGET_STM32F4/device.h @@ -36,5 +36,7 @@ #define DEVICE_ID_LENGTH 24 #include "objects.h" +/* WORKAROUND waiting for mbed-os issue 4408 to be addressed */ +#include "stm32f4xx_ll_usart.h" #endif diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_DISCO_F746NG/system_clock.c b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_DISCO_F746NG/system_clock.c index 6a33c7fb08b2..0d52647f8483 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_DISCO_F746NG/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_DISCO_F746NG/system_clock.c @@ -30,7 +30,7 @@ **/ #include "stm32f7xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -123,8 +123,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_NUCLEO_F746ZG/system_clock.c b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_NUCLEO_F746ZG/system_clock.c index c37256a1e107..d0afc10a2439 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_NUCLEO_F746ZG/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_NUCLEO_F746ZG/system_clock.c @@ -31,7 +31,7 @@ #include "stm32f7xx.h" #include "nvic_addr.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -124,8 +124,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/device/us_ticker_data.h b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/device/us_ticker_data.h index 65e46d485d93..8e530666c2c1 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/device/us_ticker_data.h +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/device/us_ticker_data.h @@ -36,9 +36,6 @@ #define TIM_MST_PCLK 1 // Select the peripheral clock number (1 or 2) - -HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority); - #ifdef __cplusplus } #endif diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/TARGET_NUCLEO_F756ZG/system_clock.c b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/TARGET_NUCLEO_F756ZG/system_clock.c index fac353279c20..c9ccf489ddcd 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/TARGET_NUCLEO_F756ZG/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/TARGET_NUCLEO_F756ZG/system_clock.c @@ -30,7 +30,7 @@ **/ #include "stm32f7xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -123,8 +123,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/device/us_ticker_data.h b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/device/us_ticker_data.h index 65e46d485d93..8e530666c2c1 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/device/us_ticker_data.h +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/device/us_ticker_data.h @@ -36,9 +36,6 @@ #define TIM_MST_PCLK 1 // Select the peripheral clock number (1 or 2) - -HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority); - #ifdef __cplusplus } #endif diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/TARGET_NUCLEO_F767ZI/system_clock.c b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/TARGET_NUCLEO_F767ZI/system_clock.c index f18c625110fa..b7b2f9ed3b3d 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/TARGET_NUCLEO_F767ZI/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/TARGET_NUCLEO_F767ZI/system_clock.c @@ -31,7 +31,7 @@ #include "stm32f7xx.h" #include "nvic_addr.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -124,8 +124,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/device/us_ticker_data.h b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/device/us_ticker_data.h index 65e46d485d93..8e530666c2c1 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/device/us_ticker_data.h +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/device/us_ticker_data.h @@ -36,9 +36,6 @@ #define TIM_MST_PCLK 1 // Select the peripheral clock number (1 or 2) - -HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority); - #ifdef __cplusplus } #endif diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/TARGET_DISCO_F769NI/system_clock.c b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/TARGET_DISCO_F769NI/system_clock.c index c665b6867334..153d6b09a441 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/TARGET_DISCO_F769NI/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/TARGET_DISCO_F769NI/system_clock.c @@ -30,7 +30,7 @@ **/ #include "stm32f7xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -123,8 +123,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/device/us_ticker_data.h b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/device/us_ticker_data.h index 65e46d485d93..8e530666c2c1 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/device/us_ticker_data.h +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/device/us_ticker_data.h @@ -36,9 +36,6 @@ #define TIM_MST_PCLK 1 // Select the peripheral clock number (1 or 2) - -HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority); - #ifdef __cplusplus } #endif diff --git a/targets/TARGET_STM/TARGET_STM32F7/device.h b/targets/TARGET_STM/TARGET_STM32F7/device.h index b6131682750f..eec6746ca321 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/device.h +++ b/targets/TARGET_STM/TARGET_STM32F7/device.h @@ -36,5 +36,7 @@ #define DEVICE_ID_LENGTH 24 #include "objects.h" +/* WORKAROUND waiting for mbed-os issue 4408 to be addressed */ +#include "stm32f7xx_ll_usart.h" #endif diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/system_clock.c b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/system_clock.c index 1ea86c05f779..abc88daaac6d 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/system_clock.c @@ -29,7 +29,7 @@ */ #include "stm32l0xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -112,8 +112,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while(1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/system_clock.c b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/system_clock.c index 1ea86c05f779..abc88daaac6d 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/system_clock.c @@ -29,7 +29,7 @@ */ #include "stm32l0xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -112,8 +112,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while(1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/system_clock.c b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/system_clock.c index cbba5c5b9b21..7da07379b5d7 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/system_clock.c @@ -29,7 +29,7 @@ */ #include "stm32l0xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -112,8 +112,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while(1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/TARGET_DISCO_L053C8/system_clock.c b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/TARGET_DISCO_L053C8/system_clock.c index eb16b93d375f..4a9ee3935173 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/TARGET_DISCO_L053C8/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/TARGET_DISCO_L053C8/system_clock.c @@ -29,7 +29,7 @@ */ #include "stm32l0xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -112,8 +112,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/TARGET_NUCLEO_L053R8/system_clock.c b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/TARGET_NUCLEO_L053R8/system_clock.c index 1d39c676f34b..8e93a844d36f 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/TARGET_NUCLEO_L053R8/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L053x8/TARGET_NUCLEO_L053R8/system_clock.c @@ -29,7 +29,7 @@ */ #include "stm32l0xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -112,8 +112,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L072xZ/TARGET_DISCO_L072CZ_LRWAN1/system_clock.c b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L072xZ/TARGET_DISCO_L072CZ_LRWAN1/system_clock.c index 9c648f116e05..557402ee84b3 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L072xZ/TARGET_DISCO_L072CZ_LRWAN1/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L072xZ/TARGET_DISCO_L072CZ_LRWAN1/system_clock.c @@ -29,7 +29,7 @@ */ #include "stm32l0xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -115,8 +115,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L0x2xZ/TARGET_MTB_MURATA_ABZ/system_clock.c b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L0x2xZ/TARGET_MTB_MURATA_ABZ/system_clock.c index 741e3ea0aa66..ca7af4e7dadb 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L0x2xZ/TARGET_MTB_MURATA_ABZ/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_STM32L0x2xZ/TARGET_MTB_MURATA_ABZ/system_clock.c @@ -27,7 +27,7 @@ */ #include "stm32l0xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -85,8 +85,8 @@ void SystemInit(void) void SetSysClock(void) { if (SetSysClock_PLL_HSI() == 0) { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } diff --git a/targets/TARGET_STM/TARGET_STM32L0/device.h b/targets/TARGET_STM/TARGET_STM32L0/device.h index b6131682750f..57871faa2a10 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device.h +++ b/targets/TARGET_STM/TARGET_STM32L0/device.h @@ -36,5 +36,7 @@ #define DEVICE_ID_LENGTH 24 #include "objects.h" +/* WORKAROUND waiting for mbed-os issue 4408 to be addressed */ +#include "stm32l0xx_ll_usart.h" #endif diff --git a/targets/TARGET_STM/TARGET_STM32L1/TARGET_NUCLEO_L152RE/device/system_clock.c b/targets/TARGET_STM/TARGET_STM32L1/TARGET_NUCLEO_L152RE/device/system_clock.c index 2da2ab032989..fb85aaccac24 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/TARGET_NUCLEO_L152RE/device/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32L1/TARGET_NUCLEO_L152RE/device/system_clock.c @@ -29,7 +29,7 @@ */ #include "stm32l1xx.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -114,8 +114,8 @@ void SetSysClock(void) if (SetSysClock_PLL_HSI() == 0) #endif { - while(1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32L1/device.h b/targets/TARGET_STM/TARGET_STM32L1/device.h index b6131682750f..31b00715e277 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/device.h +++ b/targets/TARGET_STM/TARGET_STM32L1/device.h @@ -36,5 +36,7 @@ #define DEVICE_ID_LENGTH 24 #include "objects.h" +/* WORKAROUND waiting for mbed-os issue 4408 to be addressed */ +#include "stm32l1xx_ll_usart.h" #endif diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/TARGET_NUCLEO_L432KC/system_clock.c b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/TARGET_NUCLEO_L432KC/system_clock.c index e6b3380007c1..8f7409a57c01 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/TARGET_NUCLEO_L432KC/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/TARGET_NUCLEO_L432KC/system_clock.c @@ -45,7 +45,7 @@ #include "stm32l4xx.h" #include "nvic_addr.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -147,8 +147,8 @@ void SetSysClock(void) if (SetSysClock_PLL_MSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L433xC/TARGET_NUCLEO_L433RC_P/system_clock.c b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L433xC/TARGET_NUCLEO_L433RC_P/system_clock.c index e6b3380007c1..8f7409a57c01 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L433xC/TARGET_NUCLEO_L433RC_P/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L433xC/TARGET_NUCLEO_L433RC_P/system_clock.c @@ -45,7 +45,7 @@ #include "stm32l4xx.h" #include "nvic_addr.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -147,8 +147,8 @@ void SetSysClock(void) if (SetSysClock_PLL_MSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L443xC/TARGET_MTB_ADV_WISE_1510/system_clock.c b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L443xC/TARGET_MTB_ADV_WISE_1510/system_clock.c index e6b3380007c1..8f7409a57c01 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L443xC/TARGET_MTB_ADV_WISE_1510/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L443xC/TARGET_MTB_ADV_WISE_1510/system_clock.c @@ -45,7 +45,7 @@ #include "stm32l4xx.h" #include "nvic_addr.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -147,8 +147,8 @@ void SetSysClock(void) if (SetSysClock_PLL_MSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/TARGET_DISCO_L475VG_IOT01A/system_clock.c b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/TARGET_DISCO_L475VG_IOT01A/system_clock.c index 6e959a9da529..4c232a41c367 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/TARGET_DISCO_L475VG_IOT01A/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/TARGET_DISCO_L475VG_IOT01A/system_clock.c @@ -32,7 +32,7 @@ #include "stm32l4xx.h" #include "nvic_addr.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -134,8 +134,8 @@ void SetSysClock(void) if (SetSysClock_PLL_MSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_DISCO_L476VG/system_clock.c b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_DISCO_L476VG/system_clock.c index 6e959a9da529..4c232a41c367 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_DISCO_L476VG/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_DISCO_L476VG/system_clock.c @@ -32,7 +32,7 @@ #include "stm32l4xx.h" #include "nvic_addr.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -134,8 +134,8 @@ void SetSysClock(void) if (SetSysClock_PLL_MSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_NUCLEO_L476RG/system_clock.c b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_NUCLEO_L476RG/system_clock.c index 6e959a9da529..4c232a41c367 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_NUCLEO_L476RG/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_NUCLEO_L476RG/system_clock.c @@ -32,7 +32,7 @@ #include "stm32l4xx.h" #include "nvic_addr.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -134,8 +134,8 @@ void SetSysClock(void) if (SetSysClock_PLL_MSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_SILICA_SENSOR_NODE/system_clock.c b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_SILICA_SENSOR_NODE/system_clock.c index 6e959a9da529..4c232a41c367 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_SILICA_SENSOR_NODE/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_SILICA_SENSOR_NODE/system_clock.c @@ -32,7 +32,7 @@ #include "stm32l4xx.h" #include "nvic_addr.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -134,8 +134,8 @@ void SetSysClock(void) if (SetSysClock_PLL_MSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/TARGET_MTB_ADV_WISE_1570/system_clock.c b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/TARGET_MTB_ADV_WISE_1570/system_clock.c index 6d9e310be430..09fdb7c9e9f0 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/TARGET_MTB_ADV_WISE_1570/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/TARGET_MTB_ADV_WISE_1570/system_clock.c @@ -32,7 +32,7 @@ #include "stm32l4xx.h" #include "nvic_addr.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -134,8 +134,8 @@ void SetSysClock(void) if (SetSysClock_PLL_MSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/TARGET_NUCLEO_L486RG/system_clock.c b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/TARGET_NUCLEO_L486RG/system_clock.c index ba758b2bc770..8e2272547cfc 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/TARGET_NUCLEO_L486RG/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/TARGET_NUCLEO_L486RG/system_clock.c @@ -32,7 +32,7 @@ #include "stm32l4xx.h" #include "nvic_addr.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -134,8 +134,8 @@ void SetSysClock(void) if (SetSysClock_PLL_MSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L496xG/TARGET_DISCO_L496AG/system_clock.c b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L496xG/TARGET_DISCO_L496AG/system_clock.c index 2943dc51cc1f..cddb9c174a42 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L496xG/TARGET_DISCO_L496AG/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L496xG/TARGET_DISCO_L496AG/system_clock.c @@ -32,7 +32,7 @@ #include "stm32l4xx.h" #include "nvic_addr.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -134,8 +134,8 @@ void SetSysClock(void) if (SetSysClock_PLL_MSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L496xG/TARGET_NUCLEO_L496ZG/system_clock.c b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L496xG/TARGET_NUCLEO_L496ZG/system_clock.c index 2943dc51cc1f..cddb9c174a42 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L496xG/TARGET_NUCLEO_L496ZG/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L496xG/TARGET_NUCLEO_L496ZG/system_clock.c @@ -32,7 +32,7 @@ #include "stm32l4xx.h" #include "nvic_addr.h" -#include "mbed_assert.h" +#include "mbed_error.h" /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ @@ -134,8 +134,8 @@ void SetSysClock(void) if (SetSysClock_PLL_MSI() == 0) #endif { - while (1) { - MBED_ASSERT(1); + { + error("SetSysClock failed\n"); } } } diff --git a/targets/TARGET_STM/TARGET_STM32L4/device.h b/targets/TARGET_STM/TARGET_STM32L4/device.h index b6131682750f..bae9f605b823 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/device.h +++ b/targets/TARGET_STM/TARGET_STM32L4/device.h @@ -36,5 +36,7 @@ #define DEVICE_ID_LENGTH 24 #include "objects.h" +/* WORKAROUND waiting for mbed-os issue 4408 to be addressed */ +#include "stm32l4xx_ll_usart.h" #endif diff --git a/targets/TARGET_STM/lp_ticker.c b/targets/TARGET_STM/lp_ticker.c index 702ea878d6bf..f4df8b776fee 100644 --- a/targets/TARGET_STM/lp_ticker.c +++ b/targets/TARGET_STM/lp_ticker.c @@ -229,7 +229,10 @@ void lp_ticker_clear_interrupt(void) NVIC_ClearPendingIRQ(LPTIM1_IRQn); } - +void lp_ticker_free(void) +{ + lp_ticker_disable_interrupt(); +} /*****************************************************************/ /* lpticker_lptim config is 0 or not defined in json config file */ @@ -260,6 +263,7 @@ uint32_t lp_ticker_read(void) void lp_ticker_set_interrupt(timestamp_t timestamp) { + lp_ticker_disable_interrupt(); rtc_set_wake_up_timer(timestamp); } @@ -275,7 +279,12 @@ void lp_ticker_disable_interrupt(void) void lp_ticker_clear_interrupt(void) { - NVIC_DisableIRQ(RTC_WKUP_IRQn); + lp_ticker_disable_interrupt(); +} + +void lp_ticker_free(void) +{ + lp_ticker_disable_interrupt(); } #endif /* MBED_CONF_TARGET_LPTICKER_LPTIM */ diff --git a/targets/TARGET_STM/rtc_api.c b/targets/TARGET_STM/rtc_api.c index 7a0e99a1e304..e88e9cd28d3e 100644 --- a/targets/TARGET_STM/rtc_api.c +++ b/targets/TARGET_STM/rtc_api.c @@ -250,8 +250,8 @@ void rtc_write(time_t t) } // Fill RTC structures - if (timeinfo.tm_wday == 0) { - dateStruct.WeekDay = 7; + if (timeinfo.tm_wday == 0) { /* Sunday specific case */ + dateStruct.WeekDay = RTC_WEEKDAY_SUNDAY; } else { dateStruct.WeekDay = timeinfo.tm_wday; } @@ -270,7 +270,7 @@ void rtc_write(time_t t) #if DEVICE_LPTICKER && !MBED_CONF_TARGET_LPTICKER_LPTIM /* Need to update LP_continuous_time value before new RTC time */ - uint32_t current_lp_time = rtc_read_lp(); + rtc_read_lp(); /* LP_last_RTC_time value is updated with the new RTC time */ LP_last_RTC_time = timeStruct.Seconds + timeStruct.Minutes * 60 + timeStruct.Hours * 60 * 60; diff --git a/targets/TARGET_STM/serial_api.c b/targets/TARGET_STM/serial_api.c index d245a58cf655..9ad3d70ba82a 100644 --- a/targets/TARGET_STM/serial_api.c +++ b/targets/TARGET_STM/serial_api.c @@ -71,120 +71,90 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) // Reset and enable clock #if defined(USART1_BASE) if (obj_s->uart == UART_1) { - __HAL_RCC_USART1_FORCE_RESET(); - __HAL_RCC_USART1_RELEASE_RESET(); __HAL_RCC_USART1_CLK_ENABLE(); } #endif #if defined (USART2_BASE) if (obj_s->uart == UART_2) { - __HAL_RCC_USART2_FORCE_RESET(); - __HAL_RCC_USART2_RELEASE_RESET(); __HAL_RCC_USART2_CLK_ENABLE(); } #endif #if defined(USART3_BASE) if (obj_s->uart == UART_3) { - __HAL_RCC_USART3_FORCE_RESET(); - __HAL_RCC_USART3_RELEASE_RESET(); __HAL_RCC_USART3_CLK_ENABLE(); } #endif #if defined(UART4_BASE) if (obj_s->uart == UART_4) { - __HAL_RCC_UART4_FORCE_RESET(); - __HAL_RCC_UART4_RELEASE_RESET(); __HAL_RCC_UART4_CLK_ENABLE(); } #endif #if defined(USART4_BASE) if (obj_s->uart == UART_4) { - __HAL_RCC_USART4_FORCE_RESET(); - __HAL_RCC_USART4_RELEASE_RESET(); __HAL_RCC_USART4_CLK_ENABLE(); } #endif #if defined(UART5_BASE) if (obj_s->uart == UART_5) { - __HAL_RCC_UART5_FORCE_RESET(); - __HAL_RCC_UART5_RELEASE_RESET(); __HAL_RCC_UART5_CLK_ENABLE(); } #endif #if defined(USART5_BASE) if (obj_s->uart == UART_5) { - __HAL_RCC_USART5_FORCE_RESET(); - __HAL_RCC_USART5_RELEASE_RESET(); __HAL_RCC_USART5_CLK_ENABLE(); } #endif #if defined(USART6_BASE) if (obj_s->uart == UART_6) { - __HAL_RCC_USART6_FORCE_RESET(); - __HAL_RCC_USART6_RELEASE_RESET(); __HAL_RCC_USART6_CLK_ENABLE(); } #endif #if defined(UART7_BASE) if (obj_s->uart == UART_7) { - __HAL_RCC_UART7_FORCE_RESET(); - __HAL_RCC_UART7_RELEASE_RESET(); __HAL_RCC_UART7_CLK_ENABLE(); } #endif #if defined(USART7_BASE) if (obj_s->uart == UART_7) { - __HAL_RCC_USART7_FORCE_RESET(); - __HAL_RCC_USART7_RELEASE_RESET(); __HAL_RCC_USART7_CLK_ENABLE(); } #endif #if defined(UART8_BASE) if (obj_s->uart == UART_8) { - __HAL_RCC_UART8_FORCE_RESET(); - __HAL_RCC_UART8_RELEASE_RESET(); __HAL_RCC_UART8_CLK_ENABLE(); } #endif #if defined(USART8_BASE) if (obj_s->uart == UART_8) { - __HAL_RCC_USART8_FORCE_RESET(); - __HAL_RCC_USART8_RELEASE_RESET(); __HAL_RCC_USART8_CLK_ENABLE(); } #endif #if defined(UART9_BASE) if (obj_s->uart == UART_9) { - __HAL_RCC_UART9_FORCE_RESET(); - __HAL_RCC_UART9_RELEASE_RESET(); __HAL_RCC_UART9_CLK_ENABLE(); } #endif #if defined(UART10_BASE) if (obj_s->uart == UART_10) { - __HAL_RCC_UART10_FORCE_RESET(); - __HAL_RCC_UART10_RELEASE_RESET(); __HAL_RCC_UART10_CLK_ENABLE(); } #endif #if defined(LPUART1_BASE) if (obj_s->uart == LPUART_1) { - __HAL_RCC_LPUART1_FORCE_RESET(); - __HAL_RCC_LPUART1_RELEASE_RESET(); __HAL_RCC_LPUART1_CLK_ENABLE(); } #endif @@ -690,4 +660,105 @@ int8_t get_uart_index(UARTName uart_name) return -1; } +/* Function to protect deep sleep while a seral Tx is ongoing on not complete + * yet. Returns 1 if there is at least 1 serial instance with ongoing ransfer + * 0 otherwise. + */ +int serial_is_tx_ongoing(void) { + int TxOngoing = 0; + +#if defined(USART1_BASE) + if (LL_USART_IsEnabled(USART1) && !LL_USART_IsActiveFlag_TC(USART1)) { + TxOngoing |= 1; + } +#endif + +#if defined(USART2_BASE) + if (LL_USART_IsEnabled(USART2) && !LL_USART_IsActiveFlag_TC(USART2)) { + TxOngoing |= 1; + } +#endif + +#if defined(USART3_BASE) + if (LL_USART_IsEnabled(USART3) && !LL_USART_IsActiveFlag_TC(USART3)) { + TxOngoing |= 1; + } +#endif + +#if defined(UART4_BASE) + if (LL_USART_IsEnabled(UART4) && !LL_USART_IsActiveFlag_TC(UART4)) { + TxOngoing |= 1; + } +#endif + +#if defined(USART4_BASE) + if (LL_USART_IsEnabled(USART4) && !LL_USART_IsActiveFlag_TC(USART4)) { + TxOngoing |= 1; + } +#endif + +#if defined(UART5_BASE) + if (LL_USART_IsEnabled(UART5) && !LL_USART_IsActiveFlag_TC(UART5)) { + TxOngoing |= 1; + } +#endif + +#if defined(USART5_BASE) + if (LL_USART_IsEnabled(USART5) && !LL_USART_IsActiveFlag_TC(USART5)) { + TxOngoing |= 1; + } +#endif + +#if defined(USART6_BASE) + if (LL_USART_IsEnabled(USART6) && !LL_USART_IsActiveFlag_TC(USART6)) { + TxOngoing |= 1; + } +#endif + +#if defined(UART7_BASE) + if (LL_USART_IsEnabled(UART7) && !LL_USART_IsActiveFlag_TC(UART7)) { + TxOngoing |= 1; + } +#endif + +#if defined(USART7_BASE) + if (LL_USART_IsEnabled(USART7) && !LL_USART_IsActiveFlag_TC(USART7)) { + TxOngoing |= 1; + } +#endif + +#if defined(UART8_BASE) + if (LL_USART_IsEnabled(UART8) && !LL_USART_IsActiveFlag_TC(UART8)) { + TxOngoing |= 1; + } +#endif + +#if defined(USART8_BASE) + if (LL_USART_IsEnabled(USART8) && !LL_USART_IsActiveFlag_TC(USART8)) { + TxOngoing |= 1; + } +#endif + +#if defined(UART9_BASE) + if (LL_USART_IsEnabled(UART9) && !LL_USART_IsActiveFlag_TC(UART9)) { + TxOngoing |= 1; + } +#endif + +#if defined(UART10_BASE) + if (LL_USART_IsEnabled(UART10) && !LL_USART_IsActiveFlag_TC(UART10)) { + TxOngoing |= 1; + } +#endif + +#if defined(LPUART1_BASE) + if (LL_USART_IsEnabled(LPUART1) && !LL_USART_IsActiveFlag_TC(LPUART1)) { + TxOngoing |= 1; + } +#endif + + /* If Tx is ongoing, then transfer is */ + return TxOngoing; +} + #endif /* DEVICE_SERIAL */ diff --git a/targets/TARGET_STM/sleep.c b/targets/TARGET_STM/sleep.c index 866a46aff819..50759eb74b5d 100644 --- a/targets/TARGET_STM/sleep.c +++ b/targets/TARGET_STM/sleep.c @@ -157,8 +157,20 @@ void hal_sleep(void) core_util_critical_section_exit(); } +extern int serial_is_tx_ongoing(void); + void hal_deepsleep(void) { + /* WORKAROUND: + * MBED serial driver does not handle deepsleep lock + * to prevent entering deepsleep until HW serial FIFO is empty. + * This is tracked in mbed issue 4408. + * For now, we're checking all Serial HW FIFO. If any transfer is ongoing + * we're not entering deep sleep and returning immediately. */ + if(serial_is_tx_ongoing()) { + return; + } + // Disable IRQs core_util_critical_section_enter(); diff --git a/targets/TARGET_STM/us_ticker.c b/targets/TARGET_STM/us_ticker.c index a04f70527d6b..18e0be8487b3 100644 --- a/targets/TARGET_STM/us_ticker.c +++ b/targets/TARGET_STM/us_ticker.c @@ -206,6 +206,7 @@ void us_ticker_init(void) { // Timer is already initialized in HAL_InitTick() __HAL_TIM_DISABLE_IT(&TimMasterHandle, TIM_IT_CC1); + HAL_TIM_OC_Start(&TimMasterHandle, TIM_CHANNEL_1); } uint32_t us_ticker_read() @@ -256,3 +257,10 @@ void restore_timer_ctx(void) __HAL_TIM_SET_COMPARE(&TimMasterHandle, TIM_CHANNEL_1, timer_ccr1_reg); TIM_MST->DIER = timer_dier_reg; } + +void us_ticker_free(void) +{ + HAL_TIM_OC_Stop(&TimMasterHandle, TIM_CHANNEL_1); + us_ticker_disable_interrupt(); +} + diff --git a/targets/TARGET_TI/TARGET_CC32XX/TARGET_CC3220SF/PeripheralNames.h b/targets/TARGET_TI/TARGET_CC32XX/TARGET_CC3220SF/PeripheralNames.h index 0d8adda8a9c0..a1cc02c63944 100644 --- a/targets/TARGET_TI/TARGET_CC32XX/TARGET_CC3220SF/PeripheralNames.h +++ b/targets/TARGET_TI/TARGET_CC32XX/TARGET_CC3220SF/PeripheralNames.h @@ -35,17 +35,12 @@ typedef enum { } ADCName; typedef enum { - PWM_1 = 0, + PWM_1 = 1, PWM_2, PWM_3, PWM_4, PWM_5, - PWM_6, - PWM_7, - PWM_8, - PWM_9, - PWM_10, - PWM_11 + PWM_6 } PWMName; #define STDIO_UART_TX USBTX diff --git a/targets/TARGET_TI/TARGET_CC32XX/TARGET_CC3220SF/PeripheralPins.c b/targets/TARGET_TI/TARGET_CC32XX/TARGET_CC3220SF/PeripheralPins.c index 4905b9916afa..f2fa9cf76de7 100644 --- a/targets/TARGET_TI/TARGET_CC32XX/TARGET_CC3220SF/PeripheralPins.c +++ b/targets/TARGET_TI/TARGET_CC32XX/TARGET_CC3220SF/PeripheralPins.c @@ -16,6 +16,61 @@ #include "PeripheralPins.h" +/************GPIO***************/ +const PinMap PinMap_GPIO[] = { + {PIN_50, CC3220SF_GPIOA0_BASE, 0}, //GPIO_00 (PM/Dig Mux) + {PIN_55, CC3220SF_GPIOA0_BASE, 1}, //GPIO_01 + {PIN_57, CC3220SF_GPIOA0_BASE, 2}, //GPIO_02 (Dig/ADC Mux) + {PIN_58, CC3220SF_GPIOA0_BASE, 3}, //GPIO_03 (Dig/ADC Mux) + {PIN_59, CC3220SF_GPIOA0_BASE, 4}, //GPIO_04 (Dig/ADC Mux) + {PIN_60, CC3220SF_GPIOA0_BASE, 5}, //GPIO_05 (Dig/ADC Mux) + {PIN_61, CC3220SF_GPIOA0_BASE, 6}, //GPIO_06 + {PIN_62, CC3220SF_GPIOA0_BASE, 7}, //GPIO_07 + + {PIN_63, CC3220SF_GPIOA1_BASE, 8}, //GPIO_08 + {PIN_64, CC3220SF_GPIOA1_BASE, 9}, //GPIO_09 + {PIN_01, CC3220SF_GPIOA1_BASE, 10}, //GPIO_10 + {PIN_02, CC3220SF_GPIOA1_BASE, 11}, //GPIO_11 + {PIN_03, CC3220SF_GPIOA1_BASE, 12}, //GPIO_12 + {PIN_04, CC3220SF_GPIOA1_BASE, 13}, //GPIO_13 + {PIN_05, CC3220SF_GPIOA1_BASE, 14}, //GPIO_14 + {PIN_06, CC3220SF_GPIOA1_BASE, 15}, //GPIO_15 + + {PIN_07, CC3220SF_GPIOA2_BASE, 16}, //GPIO_16 + {PIN_08, CC3220SF_GPIOA2_BASE, 17}, //GPIO_17 + //this is only here for reference + {PIN_XX, CC3220SF_GPIOA2_BASE, 18}, //GPIO_18 (Reserved) No package pin associate with this GPIO + {PIN_XX, CC3220SF_GPIOA2_BASE, 19}, //GPIO_19 (Reserved) No package pin associate with this GPIO + {PIN_XX, CC3220SF_GPIOA2_BASE, 20}, //GPIO_20 (Reserved) No package pin associate with this GPIO + {PIN_XX, CC3220SF_GPIOA2_BASE, 21}, //GPIO_21 (Reserved) No package pin associate with this GPIO + {PIN_15, CC3220SF_GPIOA2_BASE, 22}, //GPIO_22 + {PIN_16, CC3220SF_GPIOA2_BASE, 23}, //GPIO_23 + + {PIN_17, CC3220SF_GPIOA3_BASE, 24}, //GPIO_24 + // pin 21 is one of three that must have a passive pullup or pulldown resistor + // on board to configure the chip hardware power-up mode. Because of this, + // if this pin is used for digital functions, it must be output only. + {PIN_21, CC3220SF_GPIOA3_BASE, 25}, //GPIO_25 + //this is only here for reference + {PIN_XX, CC3220SF_GPIOA3_BASE, 26}, //GPIO_26 (Restricted Use; Antenna Selection 1 Only) No package pin associate with this GPIO + {PIN_XX, CC3220SF_GPIOA3_BASE, 27}, //GPIO_27 (Restricted Use; Antenna Selection 1 Only) No package pin associate with this GPIO + {PIN_18, CC3220SF_GPIOA3_BASE, 28}, //GPIO_28 + {PIN_20, CC3220SF_GPIOA3_BASE, 29}, //GPIO_29 + {PIN_53, CC3220SF_GPIOA3_BASE, 30}, //GPIO_30 (PM/Dig Mux) + {PIN_45, CC3220SF_GPIOA3_BASE, 31}, //GPIO_31 (PM/Dig Mux) + {NC, NC, 0} +}; + +/************PWM***************/ +const PinMap PinMap_PWM[] = { + {PIN_01, PWM_1, 3}, + {PIN_02, PWM_2, 3}, + {PIN_17, PWM_3, 5}, + {PIN_19, PWM_4, 8}, + {PIN_21, PWM_5, 9}, + {PIN_64, PWM_6, 3}, +}; + /************UART***************/ const PinMap PinMap_UART_TX[] = { {PIN_01, UART_1, 7}, @@ -59,46 +114,3 @@ const PinMap PinMap_UART_CTS[] = { {PIN_61, UART_1, 3}, {NC, NC, 0} }; - -/************GPIO***************/ -const PinMap PinMap_GPIO[] = { - {PIN_50, CC3220SF_GPIOA0_BASE, 0}, //GPIO_00 (PM/Dig Mux) - {PIN_55, CC3220SF_GPIOA0_BASE, 1}, //GPIO_01 - {PIN_57, CC3220SF_GPIOA0_BASE, 2}, //GPIO_02 (Dig/ADC Mux) - {PIN_58, CC3220SF_GPIOA0_BASE, 3}, //GPIO_03 (Dig/ADC Mux) - {PIN_59, CC3220SF_GPIOA0_BASE, 4}, //GPIO_04 (Dig/ADC Mux) - {PIN_60, CC3220SF_GPIOA0_BASE, 5}, //GPIO_05 (Dig/ADC Mux) - {PIN_61, CC3220SF_GPIOA0_BASE, 6}, //GPIO_06 - {PIN_62, CC3220SF_GPIOA0_BASE, 7}, //GPIO_07 - - {PIN_63, CC3220SF_GPIOA1_BASE, 8}, //GPIO_08 - {PIN_64, CC3220SF_GPIOA1_BASE, 9}, //GPIO_09 - {PIN_01, CC3220SF_GPIOA1_BASE, 10}, //GPIO_10 - {PIN_02, CC3220SF_GPIOA1_BASE, 11}, //GPIO_11 - {PIN_03, CC3220SF_GPIOA1_BASE, 12}, //GPIO_12 - {PIN_04, CC3220SF_GPIOA1_BASE, 13}, //GPIO_13 - {PIN_05, CC3220SF_GPIOA1_BASE, 14}, //GPIO_14 - {PIN_06, CC3220SF_GPIOA1_BASE, 15}, //GPIO_15 - - {PIN_07, CC3220SF_GPIOA2_BASE, 16}, //GPIO_16 - {PIN_08, CC3220SF_GPIOA2_BASE, 17}, //GPIO_17 - //this is only here for reference - //{PIN_XX, CC3220SF_GPIOA2_BASE, 18}, //GPIO_18 (Reserved) No package pin associate with this GPIO - //{PIN_XX, CC3220SF_GPIOA2_BASE, 19}, //GPIO_19 (Reserved) No package pin associate with this GPIO - //{PIN_XX, CC3220SF_GPIOA2_BASE, 20}, //GPIO_20 (Reserved) No package pin associate with this GPIO - //{PIN_XX, CC3220SF_GPIOA2_BASE, 21}, //GPIO_21 (Reserved) No package pin associate with this GPIO - {PIN_15, CC3220SF_GPIOA2_BASE, 22}, //GPIO_22 - {PIN_16, CC3220SF_GPIOA2_BASE, 23}, //GPIO_23 - - {PIN_17, CC3220SF_GPIOA3_BASE, 24}, //GPIO_24 - //pin 21 is one of three that must have a passive pullup or pulldown resistor on board to configure the chip hardware power-up mode. Because of this, if this pin is used for digital functions,it must be output only. - {PIN_21, CC3220SF_GPIOA3_BASE, 25}, //GPIO_25 - //this is only here for reference - //{PIN_XX, CC3220SF_GPIOA3_BASE, 26}, //GPIO_26 (Restricted Use; Antenna Selection 1 Only) No package pin associate with this GPIO - //{PIN_XX, CC3220SF_GPIOA3_BASE, 27}, //GPIO_27 (Restricted Use; Antenna Selection 1 Only) No package pin associate with this GPIO - {PIN_18, CC3220SF_GPIOA3_BASE, 28}, //GPIO_28 - {PIN_20, CC3220SF_GPIOA3_BASE, 29}, //GPIO_29 - {PIN_53, CC3220SF_GPIOA3_BASE, 30}, //GPIO_30 (PM/Dig Mux) - {PIN_45, CC3220SF_GPIOA3_BASE, 31}, //GPIO_31 (PM/Dig Mux) - {NC, NC, 0} -}; diff --git a/targets/TARGET_TI/TARGET_CC32XX/TARGET_CC3220SF/PeripheralPins.h b/targets/TARGET_TI/TARGET_CC32XX/TARGET_CC3220SF/PeripheralPins.h index 0717245c2bd3..9d4d30b4ed9f 100644 --- a/targets/TARGET_TI/TARGET_CC32XX/TARGET_CC3220SF/PeripheralPins.h +++ b/targets/TARGET_TI/TARGET_CC32XX/TARGET_CC3220SF/PeripheralPins.h @@ -20,13 +20,16 @@ #include "pinmap.h" #include "PeripheralNames.h" +/************GPIO***************/ +extern const PinMap PinMap_GPIO[]; + +/************PWM****************/ +extern const PinMap PinMap_PWM[]; + /************UART***************/ extern const PinMap PinMap_UART_TX[]; extern const PinMap PinMap_UART_RX[]; extern const PinMap PinMap_UART_CTS[]; extern const PinMap PinMap_UART_RTS[]; -/************GPIO***************/ -extern const PinMap PinMap_GPIO[]; - #endif diff --git a/targets/TARGET_TI/TARGET_CC32XX/TARGET_CC3220SF/device/CC3220SF.h b/targets/TARGET_TI/TARGET_CC32XX/TARGET_CC3220SF/device/CC3220SF.h index 4000f746de3d..feb3e90c50b4 100644 --- a/targets/TARGET_TI/TARGET_CC32XX/TARGET_CC3220SF/device/CC3220SF.h +++ b/targets/TARGET_TI/TARGET_CC32XX/TARGET_CC3220SF/device/CC3220SF.h @@ -144,50 +144,10 @@ typedef enum IRQn /* ================ Device Specific Peripheral Section ================ */ /* =========================================================================================================================== */ -/* =========================================================================================================================== */ -/* ================ UART ================ */ -/* =========================================================================================================================== */ - - -/** - * @brief UART - */ -typedef struct -{ - __IO uint32_t DR; /*!< Data, Address offset : 0x00 */ - union { - __I uint32_t RSR; /*!< Receive Status, Address offset : 0x04 */ - __O uint32_t ECR; /*!< Error Clear, Address offset : 0x04 */ - }; - uint32_t RESERVED0[4]; - __IO uint32_t FR; /*!< Flags, Address offset : 0x18 */ - uint32_t RESERVED1[1]; - __IO uint32_t ILPR; /*!< IrDA Low-power Counter, Address offset : 0x20 */ - __IO uint32_t IBRD; /*!< Integer Baud Rate, Address offset : 0x24 */ - __IO uint32_t FBRD; /*!< Fractional Baud Rate, Address offset : 0x28 */ - __IO uint32_t LCRH; /*!< Line Control, Address offset : 0x2C */ - __IO uint32_t CTL; /*!< Control, Address offset : 0x30 */ - __IO uint32_t IFLS; /*!< Interrupt FIFO Level Select, Address offset : 0x34 */ - __IO uint32_t IM; /*!< Interrupt Mask Set / Clear, Address offset : 0x38 */ - __IO uint32_t RIS; /*!< Raw Interrupt Status , Address offset : 0x3C */ - __IO uint32_t MIS; /*!< Masked Interrupt Status , Address offset : 0x40 */ - __O uint32_t ICR; /*!< Interrupt Clear, Address offset : 0x44 */ - __IO uint32_t DMACTL; /*!< DMA Control, Address offset : 0x48 */ - __IO uint32_t LCTL; /*!< Address offset : 0x90 */ - __IO uint32_t LSS; /*!< Address offset : 0x94 */ - __IO uint32_t LTIM; /*!< Address offset : 0x98 */ - __IO uint32_t BITADDR; /*!< 9BITADDR Address offset : 0xA4 */ - __IO uint32_t BITMASK; /*!< 9BITMASK Address offset : 0xA8 */ - __IO uint32_t PP; /*!< Address offset : 0xFC0 */ - __IO uint32_t CC; /*!< Address offset : 0xFC8 */ -} CC3220SF_UART_TypeDef; - - /* =========================================================================================================================== */ /* ================ GPIO ================ */ /* =========================================================================================================================== */ - /** * @brief GPIO */ @@ -235,6 +195,43 @@ typedef struct __IO uint32_t PCELLID3; /*!< Address offset : 0x00000FFC */ } CC3220SF_GPIO_TypeDef; +/* =========================================================================================================================== */ +/* ================ UART ================ */ +/* =========================================================================================================================== */ + +/** + * @brief UART + */ +typedef struct +{ + __IO uint32_t DR; /*!< Data, Address offset : 0x00 */ + union { + __I uint32_t RSR; /*!< Receive Status, Address offset : 0x04 */ + __O uint32_t ECR; /*!< Error Clear, Address offset : 0x04 */ + }; + uint32_t RESERVED0[4]; + __IO uint32_t FR; /*!< Flags, Address offset : 0x18 */ + uint32_t RESERVED1[1]; + __IO uint32_t ILPR; /*!< IrDA Low-power Counter, Address offset : 0x20 */ + __IO uint32_t IBRD; /*!< Integer Baud Rate, Address offset : 0x24 */ + __IO uint32_t FBRD; /*!< Fractional Baud Rate, Address offset : 0x28 */ + __IO uint32_t LCRH; /*!< Line Control, Address offset : 0x2C */ + __IO uint32_t CTL; /*!< Control, Address offset : 0x30 */ + __IO uint32_t IFLS; /*!< Interrupt FIFO Level Select, Address offset : 0x34 */ + __IO uint32_t IM; /*!< Interrupt Mask Set / Clear, Address offset : 0x38 */ + __IO uint32_t RIS; /*!< Raw Interrupt Status , Address offset : 0x3C */ + __IO uint32_t MIS; /*!< Masked Interrupt Status , Address offset : 0x40 */ + __O uint32_t ICR; /*!< Interrupt Clear, Address offset : 0x44 */ + __IO uint32_t DMACTL; /*!< DMA Control, Address offset : 0x48 */ + __IO uint32_t LCTL; /*!< Address offset : 0x90 */ + __IO uint32_t LSS; /*!< Address offset : 0x94 */ + __IO uint32_t LTIM; /*!< Address offset : 0x98 */ + __IO uint32_t BITADDR; /*!< 9BITADDR Address offset : 0xA4 */ + __IO uint32_t BITMASK; /*!< 9BITMASK Address offset : 0xA8 */ + __IO uint32_t PP; /*!< Address offset : 0xFC0 */ + __IO uint32_t CC; /*!< Address offset : 0xFC8 */ +} CC3220SF_UART_TypeDef; + /* =========================================================================================================================== */ /* ================ Device Specific Peripheral Address Map ================ */ /* =========================================================================================================================== */ @@ -295,15 +292,6 @@ typedef struct * @{ */ -/******************************************************************************/ -/* */ -/* UART */ -/* */ -/******************************************************************************/ - -#define CC3220SF_UART0 ((CC3220SF_UART_TypeDef *) CC3220SF_UARTA0_BASE) -#define CC3220SF_UART1 ((CC3220SF_UART_TypeDef *) CC3220SF_UARTA1_BASE) - /******************************************************************************/ /* */ /* GPIO */ @@ -316,6 +304,15 @@ typedef struct #define CC3220SF_GPIO3 ((CC3220SF_GPIO_TypeDef *) CC3220SF_GPIOA3_BASE) #define CC3220SF_GPIO4 ((CC3220SF_GPIO_TypeDef *) CC3220SF_GPIOA4_BASE) +/******************************************************************************/ +/* */ +/* UART */ +/* */ +/******************************************************************************/ + +#define CC3220SF_UART0 ((CC3220SF_UART_TypeDef *) CC3220SF_UARTA0_BASE) +#define CC3220SF_UART1 ((CC3220SF_UART_TypeDef *) CC3220SF_UARTA1_BASE) + /** * @} diff --git a/targets/TARGET_TI/TARGET_CC32XX/TARGET_CC3220SF/objects.h b/targets/TARGET_TI/TARGET_CC32XX/TARGET_CC3220SF/objects.h index fd4308d47a70..f9c243c4a2bc 100644 --- a/targets/TARGET_TI/TARGET_CC32XX/TARGET_CC3220SF/objects.h +++ b/targets/TARGET_TI/TARGET_CC32XX/TARGET_CC3220SF/objects.h @@ -51,6 +51,11 @@ struct port_s { uint32_t mask; }; +struct pwmout_s { + uint32_t pwmPin; + PWMName pwm; +}; + struct serial_s { CC3220SF_UART_TypeDef *uart; int index; diff --git a/targets/TARGET_TI/TARGET_CC32XX/TARGET_CC3220SF/port_api.c b/targets/TARGET_TI/TARGET_CC32XX/TARGET_CC3220SF/port_api.c index 33a7ab51a1bd..630a5b95c1b3 100644 --- a/targets/TARGET_TI/TARGET_CC32XX/TARGET_CC3220SF/port_api.c +++ b/targets/TARGET_TI/TARGET_CC32XX/TARGET_CC3220SF/port_api.c @@ -76,7 +76,7 @@ void port_init(port_t *obj, PortName port, int mask, PinDirection dir) { for (int i = 0; i < 8; i++) { if (obj->mask & (1 << i)) { PinName pin = port_pin(obj->port, i); - PinModeSet(pin, PortPinTypes[PullNone]); + PinModeSet(pin, PIN_MODE_0); pin_mode(pin, PullNone); } } @@ -87,7 +87,6 @@ void port_init(port_t *obj, PortName port, int mask, PinDirection dir) { void port_mode(port_t *obj, PinMode mode) { for (int i = 0; i < 8; i++) { if (obj->mask & (1 << i)) { - PinModeSet(port_pin(obj->port, i), PortPinTypes[mode]); pin_mode(port_pin(obj->port, i), mode); } } diff --git a/targets/TARGET_TI/TARGET_CC32XX/TARGET_CC3220SF/pwmout_api.c b/targets/TARGET_TI/TARGET_CC32XX/TARGET_CC3220SF/pwmout_api.c new file mode 100644 index 000000000000..eaf4e16ead20 --- /dev/null +++ b/targets/TARGET_TI/TARGET_CC32XX/TARGET_CC3220SF/pwmout_api.c @@ -0,0 +1,180 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "pwmout_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "PeripheralPins.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const uint32_t timerBaseAddresses[4] = { + CC3220SF_TIMERA0_BASE, + CC3220SF_TIMERA1_BASE, + CC3220SF_TIMERA2_BASE, + CC3220SF_TIMERA3_BASE, +}; + +static const uint32_t timerHalves[2] = { + TIMER_A, + TIMER_B, +}; + +static const uint32_t gpioBaseAddresses[4] = { + CC3220SF_GPIOA0_BASE, + CC3220SF_GPIOA1_BASE, + CC3220SF_GPIOA2_BASE, + CC3220SF_GPIOA3_BASE, +}; + +static const uint32_t gpioPinIndexes[8] = { + GPIO_PIN_0, + GPIO_PIN_1, + GPIO_PIN_2, + GPIO_PIN_3, + GPIO_PIN_4, + GPIO_PIN_5, + GPIO_PIN_6, + GPIO_PIN_7, +}; + +#define PinConfigTimerPort(config) (((config) >> 28) & 0xF) +#define PinConfigTimerHalf(config) (((config) >> 24) & 0xF) +#define PinConfigGPIOPort(config) (((config) >> 20) & 0xF) +#define PinConfigGPIOPinIndex(config) (((config) >> 16) & 0xF) +#define PinConfigPinMode(config) (((config) >> 8) & 0xF) +#define PinConfigPin(config) (((config) >> 0) & 0x3F) + +#define PWMTimerCC32XX_T0A (0x00 << 24) +#define PWMTimerCC32XX_T0B (0x01 << 24) +#define PWMTimerCC32XX_T1A (0x10 << 24) +#define PWMTimerCC32XX_T1B (0x11 << 24) +#define PWMTimerCC32XX_T2A (0x20 << 24) +#define PWMTimerCC32XX_T2B (0x21 << 24) +#define PWMTimerCC32XX_T3A (0x30 << 24) +#define PWMTimerCC32XX_T3B (0x31 << 24) + +#define PWMTimerCC32XX_GPIO9 (0x11 << 16) +#define PWMTimerCC32XX_GPIO10 (0x12 << 16) +#define PWMTimerCC32XX_GPIO11 (0x13 << 16) +#define PWMTimerCC32XX_GPIO24 (0x30 << 16) +#define PWMTimerCC32XX_GPIO25 (0x31 << 16) + +#define PWMTimerCC32XX_GPIONONE (0xFF << 16) + +#define PWMTimerCC32XX_PIN_01 (PWMTimerCC32XX_T3A | PWMTimerCC32XX_GPIO10 | 0x0300) +#define PWMTimerCC32XX_PIN_02 (PWMTimerCC32XX_T3B | PWMTimerCC32XX_GPIO11 | 0x0301) +#define PWMTimerCC32XX_PIN_17 (PWMTimerCC32XX_T0A | PWMTimerCC32XX_GPIO24 | 0x0510) +#define PWMTimerCC32XX_PIN_19 (PWMTimerCC32XX_T1B | PWMTimerCC32XX_GPIONONE | 0x0812) +#define PWMTimerCC32XX_PIN_21 (PWMTimerCC32XX_T1A | PWMTimerCC32XX_GPIO25 | 0x0914) +#define PWMTimerCC32XX_PIN_64 (PWMTimerCC32XX_T2B | PWMTimerCC32XX_GPIO9 | 0x033F) + +static unsigned int pwm_clock_mhz; + +void pwmout_init(pwmout_t* obj, PinName pin) { + PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM); + MBED_ASSERT(pwm != (PWMName)NC); + obj->pwm = pwm; + + switch(pin) { + case PIN_01: obj->pwmPin = PWMTimerCC32XX_PIN_01; break; + case PIN_02: obj->pwmPin = PWMTimerCC32XX_PIN_02; break; + case PIN_17: obj->pwmPin = PWMTimerCC32XX_PIN_17; break; + case PIN_19: obj->pwmPin = PWMTimerCC32XX_PIN_19; break; + case PIN_21: obj->pwmPin = PWMTimerCC32XX_PIN_21; break; + case PIN_64: obj->pwmPin = PWMTimerCC32XX_PIN_64; break; + } + + uint32_t timerBaseAddr = timerBaseAddresses[PinConfigTimerPort(obj->pwmPin)]; + uint16_t halfTimer = timerHalves[PinConfigTimerHalf(obj->pwmPin)]; + + MAP_TimerDisable(timerBaseAddr, halfTimer); + + /* + * The CC32XX SDK TimerConfigure API halts both timers when it is + * used to configure a single half timer. The code below performs + * the register operations necessary to configure each half timer + * individually. + */ + /* Enable CCP to IO path */ + HWREG(APPS_CONFIG_BASE + APPS_CONFIG_O_GPT_TRIG_SEL) = 0xFF; + + /* Split the timer and configure it as a PWM */ + uint32_t timerConfigVal = ((halfTimer & (TIMER_CFG_A_PWM | TIMER_CFG_B_PWM)) | + TIMER_CFG_SPLIT_PAIR); + HWREG(timerBaseAddr + TIMER_O_CFG) |= (timerConfigVal >> 24); + if (halfTimer & TIMER_A) { + HWREG(timerBaseAddr + TIMER_O_TAMR) = timerConfigVal & 255; + } + else { + HWREG(timerBaseAddr + TIMER_O_TBMR) = (timerConfigVal >> 8) & 255; + } + + /* Set the peripheral output to active-high */ + MAP_TimerControlLevel(timerBaseAddr, halfTimer, true); + + uint16_t mode = PinConfigPinMode(obj->pwmPin); + + /* Start the timer & set pinmux to PWM mode */ + MAP_TimerEnable(timerBaseAddr, halfTimer); + MAP_PinTypeTimer((unsigned long)pin, (unsigned long)mode); +} + +void pwmout_free(pwmout_t* obj) { + // [TODO] +} + +void pwmout_write(pwmout_t* obj, float value) { + +} + +float pwmout_read(pwmout_t* obj) { + return 0; +} + +void pwmout_period(pwmout_t* obj, float seconds) { + pwmout_period_us(obj, seconds * 1000000.0f); +} + +void pwmout_period_ms(pwmout_t* obj, int ms) { + pwmout_period_us(obj, ms * 1000); +} + +// Set the PWM period, keeping the duty cycle the same. +void pwmout_period_us(pwmout_t* obj, int us) { + +} + +void pwmout_pulsewidth(pwmout_t* obj, float seconds) { + pwmout_pulsewidth_us(obj, seconds * 1000000.0f); +} + +void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) { + pwmout_pulsewidth_us(obj, ms * 1000); +} + +void pwmout_pulsewidth_us(pwmout_t* obj, int us) { + +} diff --git a/targets/TARGET_TOSHIBA/TARGET_TMPM066/us_ticker.c b/targets/TARGET_TOSHIBA/TARGET_TMPM066/us_ticker.c index 4fd8ed13b93d..e528be3be7e6 100644 --- a/targets/TARGET_TOSHIBA/TARGET_TMPM066/us_ticker.c +++ b/targets/TARGET_TOSHIBA/TARGET_TMPM066/us_ticker.c @@ -107,3 +107,8 @@ void us_ticker_clear_interrupt(void) { //no flags to clear } + +void us_ticker_free(void) +{ + +} diff --git a/targets/TARGET_TOSHIBA/TARGET_TMPM3H6/us_ticker.c b/targets/TARGET_TOSHIBA/TARGET_TMPM3H6/us_ticker.c index efdf17dc3daa..235319104f5b 100644 --- a/targets/TARGET_TOSHIBA/TARGET_TMPM3H6/us_ticker.c +++ b/targets/TARGET_TOSHIBA/TARGET_TMPM3H6/us_ticker.c @@ -83,3 +83,8 @@ void us_ticker_clear_interrupt(void) TSB_T32A0->STC = T32A_INT_MASK; NVIC_ClearPendingIRQ(INTT32A00C_IRQn); } + +void us_ticker_free(void) +{ + +} diff --git a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/device/TOOLCHAIN_IAR/tmpm46bf10fg.icf b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/device/TOOLCHAIN_IAR/tmpm46bf10fg.icf index 0254f84f41f1..dcc4f03fbdfe 100644 --- a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/device/TOOLCHAIN_IAR/tmpm46bf10fg.icf +++ b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/device/TOOLCHAIN_IAR/tmpm46bf10fg.icf @@ -25,11 +25,11 @@ define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFED define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; -define block FLASH_CODE_ROM {section FLASH_ROM_init object flash_api.o, section .text_init object tmpm46b_fc.o}; -define block FLASH_CODE_RAM {section FLASH_ROM object flash_api.o, section .text object tmpm46b_fc.o}; +define block FLASH_CODE_ROM {section FLASH_ROM_init object flash_api.o}; +define block FLASH_CODE_RAM {section FLASH_ROM object flash_api.o}; initialize by copy { readwrite }; -initialize manually { section FLASH_ROM object flash_api.o, section .text object tmpm46b_fc.o}; +initialize manually { section FLASH_ROM object flash_api.o }; do not initialize { section .noinit }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; diff --git a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/us_ticker.c b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/us_ticker.c index feca1b68621c..c1b4982f8b20 100644 --- a/targets/TARGET_TOSHIBA/TARGET_TMPM46B/us_ticker.c +++ b/targets/TARGET_TOSHIBA/TARGET_TMPM46B/us_ticker.c @@ -131,3 +131,8 @@ void us_ticker_clear_interrupt(void) { // No flag to clear } + +void us_ticker_free(void) +{ + +} diff --git a/targets/TARGET_WICED/README.md b/targets/TARGET_WICED/README.md index 4ef2c0b16b71..a2b4b1c64949 100644 --- a/targets/TARGET_WICED/README.md +++ b/targets/TARGET_WICED/README.md @@ -1 +1 @@ -This directory tree contains binaries build from Cypress WICED SDK modified for Mbed OS and released under Permissive Binary License. \ No newline at end of file +This directory tree contains binaries build from Cypress WICED SDK modified for Mbed OS and released under Permissive Binary License. diff --git a/targets/TARGET_WICED/wiced_interface/default_wifi_interface.cpp b/targets/TARGET_WICED/wiced_interface/default_wifi_interface.cpp new file mode 100644 index 000000000000..61ec37d2d60f --- /dev/null +++ b/targets/TARGET_WICED/wiced_interface/default_wifi_interface.cpp @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2018, Arm Limited and affiliates. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "WicedInterface.h" + +WiFiInterface *WiFiInterface::get_target_default_instance() +{ + static WicedInterface wifi; + return &wifi; +} diff --git a/targets/TARGET_WIZNET/TARGET_W7500x/us_ticker.c b/targets/TARGET_WIZNET/TARGET_W7500x/us_ticker.c index e027f602012b..14232d33c9b4 100644 --- a/targets/TARGET_WIZNET/TARGET_W7500x/us_ticker.c +++ b/targets/TARGET_WIZNET/TARGET_W7500x/us_ticker.c @@ -130,3 +130,8 @@ void us_ticker_clear_interrupt(void) { DUALTIMER_IntClear(TIMER_0); } + +void us_ticker_free(void) +{ + +} diff --git a/targets/TARGET_ublox/TARGET_HI2110/lp_ticker.c b/targets/TARGET_ublox/TARGET_HI2110/lp_ticker.c index 1aa98ab2203d..40efb16c8384 100644 --- a/targets/TARGET_ublox/TARGET_HI2110/lp_ticker.c +++ b/targets/TARGET_ublox/TARGET_HI2110/lp_ticker.c @@ -346,3 +346,8 @@ void lp_ticker_clear_interrupt(void) g_user_interrupt_pending = false; g_user_interrupt_set = false; } + +void lp_ticker_free(void) +{ + +} diff --git a/targets/TARGET_ublox/TARGET_HI2110/us_ticker.c b/targets/TARGET_ublox/TARGET_HI2110/us_ticker.c index 86decef26948..64c6cc48d512 100644 --- a/targets/TARGET_ublox/TARGET_HI2110/us_ticker.c +++ b/targets/TARGET_ublox/TARGET_HI2110/us_ticker.c @@ -251,3 +251,8 @@ void us_ticker_clear_interrupt(void) g_timer_extra_loops_required = 0; g_us_overflow_increment = 0; } + +void us_ticker_free(void) +{ + +} diff --git a/targets/targets.json b/targets/targets.json index 7977609bc8da..50e5130b2402 100755 --- a/targets/targets.json +++ b/targets/targets.json @@ -635,6 +635,12 @@ "network-default-interface-type": "ETHERNET" } }, + "SDT64B": { + "inherits": ["K64F"], + "extra_labels_add": ["K64F"], + "extra_labels_remove": ["FRDM"], + "detect_code": ["3105"] + }, "EV_COG_AD4050LZ": { "inherits": ["Target"], "core": "Cortex-M4F", @@ -724,7 +730,7 @@ "public": false, "extra_labels": ["STM"], "supported_toolchains": ["ARM", "uARM", "IAR", "GCC_ARM"], - "macros": ["TRANSACTION_QUEUE_SIZE_SPI=2", "LPTICKER_DELAY_TICKS=3"], + "macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"], "config": { "lse_available": { "help": "Define if a Low Speed External xtal (LSE) is available on the board (0 = No, 1 = Yes). If Yes, the LSE will be used to clock the RTC, LPUART, ... otherwise the Low Speed Internal clock (LSI) will be used", @@ -749,10 +755,10 @@ "supported_toolchains": ["ARM", "GCC_ARM", "IAR"], "extra_labels": ["NXP", "MCUXpresso_MCUS", "EVK", "MIMXRT1050", "IMX"], "is_disk_virtual": true, - "macros": ["CPU_MIMXRT1052DVL6B", "FSL_RTOS_MBED", "XIP_BOOT_HEADER_ENABLE=1", "XIP_EXTERNAL_FLASH=1", "XIP_BOOT_HEADER_DCD_ENABLE=1"], + "macros": ["CPU_MIMXRT1052DVL6B", "FSL_RTOS_MBED", "XIP_BOOT_HEADER_ENABLE=1", "XIP_EXTERNAL_FLASH=1", "XIP_BOOT_HEADER_DCD_ENABLE=1", "SKIP_SYSCLK_INIT"], "inherits": ["Target"], "detect_code": ["0227"], - "device_has": ["USTICKER", "LPTICKER", "ANALOGIN", "I2C", "I2CSLAVE", "ERROR_RED", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "SERIAL", "SPI", "SPISLAVE", "STDIO_MESSAGES"], + "device_has": ["SLEEP", "USTICKER", "LPTICKER", "ANALOGIN", "I2C", "I2CSLAVE", "ERROR_RED", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "SERIAL", "SPI", "SPISLAVE", "STDIO_MESSAGES"], "release_versions": ["2", "5"], "device_name": "MIMXRT1052" }, @@ -868,6 +874,11 @@ "help": "Mask value : USE_PLL_HSE_EXTC | USE_PLL_HSE_XTAL (need HW patch) | USE_PLL_HSI", "value": "USE_PLL_HSE_EXTC|USE_PLL_HSI", "macro_name": "CLOCK_SOURCE" + }, + "lpticker_delay_ticks": { + "help": "For targets with low frequency system clock, set lpticker_delay_ticks value to 1", + "value": 1, + "macro_name": "LPTICKER_DELAY_TICKS" } }, "detect_code": ["0755"], @@ -886,6 +897,11 @@ "help": "Mask value : USE_PLL_HSE_EXTC | USE_PLL_HSE_XTAL (need HW patch) | USE_PLL_HSI", "value": "USE_PLL_HSE_EXTC|USE_PLL_HSI", "macro_name": "CLOCK_SOURCE" + }, + "lpticker_delay_ticks": { + "help": "For targets with low frequency system clock, set lpticker_delay_ticks value to 1", + "value": 1, + "macro_name": "LPTICKER_DELAY_TICKS" } }, "detect_code": ["0730"], @@ -904,6 +920,11 @@ "help": "Mask value : USE_PLL_HSE_EXTC | USE_PLL_HSE_XTAL (need HW patch) | USE_PLL_HSI", "value": "USE_PLL_HSE_EXTC|USE_PLL_HSI", "macro_name": "CLOCK_SOURCE" + }, + "lpticker_delay_ticks": { + "help": "For targets with low frequency system clock, set lpticker_delay_ticks value to 1", + "value": 1, + "macro_name": "LPTICKER_DELAY_TICKS" } }, "detect_code": ["0750"], @@ -1014,6 +1035,7 @@ "detect_code": ["0745"], "device_has_add": ["ANALOGOUT", "CAN", "CRC", "SERIAL_ASYNCH", "SERIAL_FC", "FLASH"], "release_versions": ["2", "5"], + "bootloader_supported": true, "device_name": "STM32F303RE" }, "NUCLEO_F303ZE": { @@ -1100,6 +1122,11 @@ "lpticker_lptim": { "help": "This target supports LPTIM. Set value 1 to use LPTIM for LPTICKER, or 0 to use RTC wakeup timer", "value": 1 + }, + "lpticker_delay_ticks": { + "help": "In case of lpticker_lptim=1, set lpticker_delay_ticks=3", + "value": 3, + "macro_name": "LPTICKER_DELAY_TICKS" } }, "detect_code": ["0744"], @@ -1200,6 +1227,11 @@ }, "MTB_ADV_WISE_1530": { "inherits": ["USI_WM_BN_BM_22"], + "config": { + "led1": "PA_4", + "led2": "PC_12", + "led3": "NC" + }, "overrides": { "stdio_uart_tx": "PB_10", "stdio_uart_rx": "PC_11" @@ -1219,6 +1251,11 @@ "lpticker_lptim": { "help": "This target supports LPTIM. Set value 1 to use LPTIM for LPTICKER, or 0 to use RTC wakeup timer", "value": 1 + }, + "lpticker_delay_ticks": { + "help": "In case of lpticker_lptim=1, set lpticker_delay_ticks=3", + "value": 3, + "macro_name": "LPTICKER_DELAY_TICKS" } }, "detect_code": ["0743"], @@ -1241,6 +1278,11 @@ "lpticker_lptim": { "help": "This target supports LPTIM. Set value 1 to use LPTIM for LPTICKER, or 0 to use RTC wakeup timer", "value": 1 + }, + "lpticker_delay_ticks": { + "help": "In case of lpticker_lptim=1, set lpticker_delay_ticks=3", + "value": 3, + "macro_name": "LPTICKER_DELAY_TICKS" } }, "detect_code": ["0743"], @@ -1391,12 +1433,17 @@ "lpticker_lptim": { "help": "This target supports LPTIM. Set value 1 to use LPTIM for LPTICKER, or 0 to use RTC wakeup timer", "value": 1 + }, + "lpticker_delay_ticks": { + "help": "In case of lpticker_lptim=1, set lpticker_delay_ticks=3", + "value": 3, + "macro_name": "LPTICKER_DELAY_TICKS" } }, "macros_add": ["USBHOST_OTHER"], "supported_form_factors": ["ARDUINO"], "detect_code": ["0816"], - "device_has_add": ["LPTICKER", "ANALOGOUT", "CAN", "CRC", "EMAC", "SERIAL_ASYNCH", "TRNG", "FLASH"], + "device_has_add": ["ANALOGOUT", "CAN", "CRC", "EMAC", "SERIAL_ASYNCH", "TRNG", "FLASH"], "release_versions": ["2", "5"], "device_name": "STM32F746ZG", "bootloader_supported": true, @@ -1422,12 +1469,17 @@ "lpticker_lptim": { "help": "This target supports LPTIM. Set value 1 to use LPTIM for LPTICKER, or 0 to use RTC wakeup timer", "value": 1 + }, + "lpticker_delay_ticks": { + "help": "In case of lpticker_lptim=1, set lpticker_delay_ticks=3", + "value": 3, + "macro_name": "LPTICKER_DELAY_TICKS" } }, "macros_add": ["TRANSACTION_QUEUE_SIZE_SPI=2", "USBHOST_OTHER", "MBEDTLS_CONFIG_HW_SUPPORT"], "supported_form_factors": ["ARDUINO"], "detect_code": ["0819"], - "device_has_add": ["LPTICKER", "ANALOGOUT", "CAN", "CRC", "EMAC", "SERIAL_ASYNCH", "TRNG", "FLASH"], + "device_has_add": ["ANALOGOUT", "CAN", "CRC", "EMAC", "SERIAL_ASYNCH", "TRNG", "FLASH"], "release_versions": ["2", "5"], "device_name": "STM32F756ZG", "overrides": { @@ -1456,12 +1508,17 @@ "lpticker_lptim": { "help": "This target supports LPTIM. Set value 1 to use LPTIM for LPTICKER, or 0 to use RTC wakeup timer", "value": 1 + }, + "lpticker_delay_ticks": { + "help": "In case of lpticker_lptim=1, set lpticker_delay_ticks=3", + "value": 3, + "macro_name": "LPTICKER_DELAY_TICKS" } }, "supported_form_factors": ["ARDUINO"], "macros_add": ["USBHOST_OTHER"], "detect_code": ["0818"], - "device_has_add": ["LPTICKER", "ANALOGOUT", "CAN", "CRC", "EMAC", "SERIAL_ASYNCH", "TRNG", "FLASH"], + "device_has_add": ["ANALOGOUT", "CAN", "CRC", "EMAC", "SERIAL_ASYNCH", "TRNG", "FLASH"], "release_versions": ["2", "5"], "device_name": "STM32F767ZI", "bootloader_supported": true, @@ -1485,6 +1542,11 @@ "lpticker_lptim": { "help": "This target supports LPTIM. Set value 1 to use LPTIM for LPTICKER, or 0 to use RTC wakeup timer", "value": 1 + }, + "lpticker_delay_ticks": { + "help": "In case of lpticker_lptim=1, set lpticker_delay_ticks=3", + "value": 3, + "macro_name": "LPTICKER_DELAY_TICKS" } }, "detect_code": ["0780"], @@ -1508,6 +1570,11 @@ "lpticker_lptim": { "help": "This target supports LPTIM. Set value 1 to use LPTIM for LPTICKER, or 0 to use RTC wakeup timer", "value": 1 + }, + "lpticker_delay_ticks": { + "help": "In case of lpticker_lptim=1, set lpticker_delay_ticks=3", + "value": 3, + "macro_name": "LPTICKER_DELAY_TICKS" } }, "detect_code": ["0790"], @@ -1530,6 +1597,11 @@ "lpticker_lptim": { "help": "This target supports LPTIM. Set value 1 to use LPTIM for LPTICKER, or 0 to use RTC wakeup timer", "value": 1 + }, + "lpticker_delay_ticks": { + "help": "In case of lpticker_lptim=1, set lpticker_delay_ticks=3", + "value": 3, + "macro_name": "LPTICKER_DELAY_TICKS" } }, "detect_code": ["0715"], @@ -1552,6 +1624,11 @@ "lpticker_lptim": { "help": "This target supports LPTIM. Set value 1 to use LPTIM for LPTICKER, or 0 to use RTC wakeup timer", "value": 1 + }, + "lpticker_delay_ticks": { + "help": "In case of lpticker_lptim=1, set lpticker_delay_ticks=3", + "value": 3, + "macro_name": "LPTICKER_DELAY_TICKS" } }, "detect_code": ["0760"], @@ -1569,6 +1646,11 @@ "help": "Mask value : USE_PLL_HSE_EXTC | USE_PLL_HSE_XTAL (need HW patch) | USE_PLL_HSI", "value": "USE_PLL_HSE_EXTC|USE_PLL_HSI", "macro_name": "CLOCK_SOURCE" + }, + "lpticker_delay_ticks": { + "help": "For targets with low frequency system clock, set lpticker_delay_ticks value to 1", + "value": 1, + "macro_name": "LPTICKER_DELAY_TICKS" } }, "detect_code": ["0710"], @@ -1590,6 +1672,11 @@ "lpticker_lptim": { "help": "This target supports LPTIM. Set value 1 to use LPTIM for LPTICKER, or 0 to use RTC wakeup timer", "value": 1 + }, + "lpticker_delay_ticks": { + "help": "In case of lpticker_lptim=1, set lpticker_delay_ticks=3", + "value": 3, + "macro_name": "LPTICKER_DELAY_TICKS" } }, "detect_code": ["0770"], @@ -1612,6 +1699,11 @@ "lpticker_lptim": { "help": "This target supports LPTIM. Set value 1 to use LPTIM for LPTICKER, or 0 to use RTC wakeup timer", "value": 1 + }, + "lpticker_delay_ticks": { + "help": "In case of lpticker_lptim=1, set lpticker_delay_ticks=3", + "value": 3, + "macro_name": "LPTICKER_DELAY_TICKS" } }, "detect_code": ["0779"], @@ -1655,6 +1747,11 @@ "lpticker_lptim": { "help": "This target supports LPTIM. Set value 1 to use LPTIM for LPTICKER, or 0 to use RTC wakeup timer", "value": 1 + }, + "lpticker_delay_ticks": { + "help": "In case of lpticker_lptim=1, set lpticker_delay_ticks=3", + "value": 3, + "macro_name": "LPTICKER_DELAY_TICKS" } }, "detect_code": ["0765"], @@ -1696,6 +1793,11 @@ "lpticker_lptim": { "help": "This target supports LPTIM. Set value 1 to use LPTIM for LPTICKER, or 0 to use RTC wakeup timer", "value": 1 + }, + "lpticker_delay_ticks": { + "help": "In case of lpticker_lptim=1, set lpticker_delay_ticks=3", + "value": 3, + "macro_name": "LPTICKER_DELAY_TICKS" } }, "detect_code": ["0827"], @@ -1711,7 +1813,7 @@ "config": { "clock_source": { "help": "Mask value : USE_PLL_HSE_EXTC (need HW patch) | USE_PLL_HSE_XTAL (need HW patch) | USE_PLL_HSI | USE_PLL_MSI", - "value": "USE_PLL_HSI", + "value": "USE_PLL_HSE_XTAL", "macro_name": "CLOCK_SOURCE" } }, @@ -1903,6 +2005,11 @@ "help": "This target supports LPTIM. Set value 1 to use LPTIM for LPTICKER, or 0 to use RTC wakeup timer", "value": 1 + }, + "lpticker_delay_ticks": { + "help": "In case of lpticker_lptim=1, set lpticker_delay_ticks=3", + "value": 3, + "macro_name": "LPTICKER_DELAY_TICKS" } }, "overrides": {"lse_available": 0}, @@ -1925,6 +2032,11 @@ "lpticker_lptim": { "help": "This target supports LPTIM. Set value 1 to use LPTIM for LPTICKER, or 0 to use RTC wakeup timer", "value": 1 + }, + "lpticker_delay_ticks": { + "help": "In case of lpticker_lptim=1, set lpticker_delay_ticks=3", + "value": 3, + "macro_name": "LPTICKER_DELAY_TICKS" } }, "detect_code": ["0833"], @@ -1960,11 +2072,16 @@ "lpticker_lptim": { "help": "This target supports LPTIM. Set value 1 to use LPTIM for LPTICKER, or 0 to use RTC wakeup timer", "value": 1 + }, + "lpticker_delay_ticks": { + "help": "In case of lpticker_lptim=1, set lpticker_delay_ticks=3", + "value": 3, + "macro_name": "LPTICKER_DELAY_TICKS" } }, "detect_code": ["0815"], "macros_add": ["USB_STM_HAL", "USBHOST_OTHER"], - "device_has_add": ["LPTICKER", "ANALOGOUT", "CAN", "EMAC", "SERIAL_ASYNCH", "TRNG", "FLASH"], + "device_has_add": ["ANALOGOUT", "CAN", "EMAC", "SERIAL_ASYNCH", "TRNG", "FLASH"], "release_versions": ["2", "5"], "device_name": "STM32F746NG", "overrides": { @@ -1989,11 +2106,16 @@ "lpticker_lptim": { "help": "This target supports LPTIM. Set value 1 to use LPTIM for LPTICKER, or 0 to use RTC wakeup timer", "value": 1 + }, + "lpticker_delay_ticks": { + "help": "In case of lpticker_lptim=1, set lpticker_delay_ticks=3", + "value": 3, + "macro_name": "LPTICKER_DELAY_TICKS" } }, "detect_code": ["0817"], "macros_add": ["USB_STM_HAL", "USBHOST_OTHER"], - "device_has_add": ["LPTICKER", "ANALOGOUT", "CAN", "EMAC", "SERIAL_ASYNCH", "TRNG", "FLASH"], + "device_has_add": ["ANALOGOUT", "CAN", "EMAC", "SERIAL_ASYNCH", "TRNG", "FLASH"], "release_versions": ["2", "5"], "device_name": "STM32F769NI", "overrides": { @@ -2013,6 +2135,11 @@ "lpticker_lptim": { "help": "This target supports LPTIM. Set value 1 to use LPTIM for LPTICKER, or 0 to use RTC wakeup timer", "value": 1 + }, + "lpticker_delay_ticks": { + "help": "In case of lpticker_lptim=1, set lpticker_delay_ticks=3", + "value": 3, + "macro_name": "LPTICKER_DELAY_TICKS" } }, "supported_form_factors": ["ARDUINO"], @@ -2036,6 +2163,11 @@ "lpticker_lptim": { "help": "This target supports LPTIM. Set value 1 to use LPTIM for LPTICKER, or 0 to use RTC wakeup timer", "value": 1 + }, + "lpticker_delay_ticks": { + "help": "In case of lpticker_lptim=1, set lpticker_delay_ticks=3", + "value": 3, + "macro_name": "LPTICKER_DELAY_TICKS" } }, "detect_code": ["0820"], @@ -2841,7 +2973,7 @@ "inherits": ["RZ_A1XX"], "supported_form_factors": ["ARDUINO"], "extra_labels_add": ["RZA1H", "MBRZA1H", "RZ_A1_EMAC"], - "device_has_add": ["EMAC", "FLASH"], + "device_has_add": ["EMAC", "FLASH", "LPTICKER"], "release_versions": ["2", "5"], "device_name": "R7S72100", "bootloader_supported": true @@ -2856,7 +2988,7 @@ "inherits": ["RZ_A1XX"], "supported_form_factors": ["ARDUINO"], "extra_labels_add": ["RZA1UL", "MBRZA1LU"], - "device_has_add": ["TRNG", "FLASH"], + "device_has_add": ["TRNG", "FLASH", "LPTICKER"], "device_has_remove": ["ETHERNET"], "release_versions": ["2", "5"], "device_name": "R7S72103", @@ -2902,6 +3034,16 @@ "device_has": ["ANALOGIN", "I2C", "INTERRUPTIN", "LPTICKER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "STDIO_MESSAGES", "USTICKER"], "release_versions": ["2", "5"] }, + "SDT32620B": { + "inherits": ["Target"], + "core": "Cortex-M4F", + "macros": ["__SYSTEM_HFX=96000000","TARGET=MAX32620","TARGET_REV=0x4332","OPEN_DRAIN_LEDS"], + "detect_code": ["3101"], + "extra_labels": ["Maxim", "MAX32620C"], + "supported_toolchains": ["GCC_ARM", "IAR", "ARM"], + "device_has": ["ANALOGIN", "I2C", "INTERRUPTIN", "LPTICKER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "STDIO_MESSAGES", "USTICKER"], + "release_versions": ["2", "5"] + }, "MAX32625_BASE": { "inherits": ["Target"], "core": "Cortex-M4F", @@ -2909,33 +3051,26 @@ "extra_labels": ["Maxim", "MAX32625"], "supported_toolchains": ["GCC_ARM", "IAR", "ARM"], "device_has": ["ANALOGIN", "I2C", "INTERRUPTIN", "LPTICKER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "STDIO_MESSAGES", "USTICKER"], + "device_name": "MAX32625", "release_versions": ["2", "5"], "public": false }, - "MAX32625_BOOT": { + "MAX32625MBED": { "inherits": ["MAX32625_BASE"], - "extra_labels_add": ["MAX32625_BOOT"], - "public": false + "extra_labels_add": ["MAX32625_NO_BOOT"] }, - "MAX32625_NO_BOOT": { + "SDT32625B": { "inherits": ["MAX32625_BASE"], "extra_labels_add": ["MAX32625_NO_BOOT"], - "public": false - }, - "MAX32625MBED": { - "inherits": ["MAX32625_NO_BOOT"] + "detect_code": ["3102"] }, "MAX32625PICO": { - "inherits": ["MAX32625_BOOT"], - "extra_labels_add": ["MAX32625PICO_BASE"] - }, - "MAX32625PICO_NO_BOOT": { - "inherits": ["MAX32625_NO_BOOT"], - "extra_labels_add": ["MAX32625PICO_BASE"] + "inherits": ["MAX32625_BASE"], + "extra_labels_add": ["MAX32625_BOOT"], + "bootloader_supported": true }, "MAX32625NEXPAQ": { - "inherits": ["MAX32625_BASE"], - "extra_labels_add": ["MAX32625NEXPAQ"] + "inherits": ["MAX32625_BASE"] }, "MAX32630FTHR": { "inherits": ["Target"], @@ -3688,6 +3823,13 @@ "release_versions": ["2", "5"], "device_name": "nRF51822_xxAA" }, + "SDT51822B": { + "inherits": ["MCU_NRF51_32K_UNIFIED"], + "device_has": ["USTICKER", "LPTICKER", "ANALOGIN", "I2C", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPI_ASYNCH", "SPISLAVE"], + "detect_code": ["3103"], + "release_versions": ["2", "5"], + "device_name": "nRF51822_xxAA" + }, "NRF51_DONGLE": { "inherits": ["MCU_NRF51_32K_UNIFIED"], "progen": {"target": "nrf51-dongle"}, @@ -3770,6 +3912,12 @@ "release_versions": ["5"], "device_name": "nRF52832_xxAA" }, + "SDT52832B": { + "inherits": ["MCU_NRF52832"], + "release_versions": ["5"], + "detect_code": ["3104"], + "device_name": "nRF52832_xxAA" + }, "UBLOX_EVA_NINA": { "inherits": ["MCU_NRF52832"], "release_versions": ["5"], @@ -4051,7 +4199,7 @@ "extra_labels": ["Realtek", "AMEBA", "RTL8195A", "RTW_EMAC"], "macros": ["__RTL8195A__","CONFIG_PLATFORM_8195A","CONFIG_MBED_ENABLED","PLATFORM_CMSIS_RTOS","MBED_FAULT_HANDLER_DISABLED"], "supported_toolchains": ["GCC_ARM", "ARM", "IAR"], - "device_has": ["ANALOGIN", "ANALOGOUT", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "SERIAL", "SPI", "TRNG", "FLASH", "EMAC"], + "device_has": ["ANALOGIN", "ANALOGOUT", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "SERIAL", "SPI", "TRNG", "FLASH"], "post_binary_hook": { "function": "RTL8195ACode.binary_hook", "toolchains": ["ARM_STD", "GCC_ARM", "IAR"] @@ -4107,6 +4255,11 @@ "lpticker_lptim": { "help": "This target supports LPTIM. Set value 1 to use LPTIM for LPTICKER, or 0 to use RTC wakeup timer", "value": 1 + }, + "lpticker_delay_ticks": { + "help": "In case of lpticker_lptim=1, set lpticker_delay_ticks=3", + "value": 3, + "macro_name": "LPTICKER_DELAY_TICKS" } }, "detect_code": ["0822"], @@ -4128,6 +4281,11 @@ "lpticker_lptim": { "help": "This target supports LPTIM. Set value 1 to use LPTIM for LPTICKER, or 0 to use RTC wakeup timer", "value": 1 + }, + "lpticker_delay_ticks": { + "help": "In case of lpticker_lptim=1, set lpticker_delay_ticks=3", + "value": 3, + "macro_name": "LPTICKER_DELAY_TICKS" } }, "detect_code": ["0823"], @@ -4245,7 +4403,7 @@ "FVP_MPS2_M0": { "inherits": ["FVP_MPS2"], "core": "Cortex-M0", - "macros": ["CMSDK_CM0","CMSIS_VECTAB_VIRTUAL", "CMSIS_VECTAB_VIRTUAL_HEADER_FILE=\"cmsis_nvic.h\""] + "macros": ["CMSDK_CM0"] }, "FVP_MPS2_M0P": { "inherits": ["FVP_MPS2"], @@ -4329,7 +4487,7 @@ }, "CC3220SF": { "inherits": ["CC32XX"], - "device_has": ["USTICKER", "LPTICKER", "SERIAL", "SERIAL_FC", "PORTIN", "PORTINOUT", "PORTOUT", "INTERRUPTIN", "EMAC", "SPI", "ANALOGIN"], + "device_has": ["USTICKER", "LPTICKER", "SERIAL", "SERIAL_FC", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "INTERRUPTIN", "EMAC", "SPI", "ANALOGIN"], "core": "Cortex-M4" } } diff --git a/tools/build_api.py b/tools/build_api.py index 0b127700ac67..1d60c821b3b5 100644 --- a/tools/build_api.py +++ b/tools/build_api.py @@ -44,7 +44,7 @@ BUILD_DIR) from .resources import Resources, FileType, FileRef from .notifier.mock import MockNotifier -from .targets import TARGET_NAMES, TARGET_MAP +from .targets import TARGET_NAMES, TARGET_MAP, CORE_ARCH from .libraries import Library from .toolchains import TOOLCHAIN_CLASSES from .config import Config @@ -316,6 +316,8 @@ def prepare_toolchain(src_paths, build_dir, target, toolchain_name, raise NotSupportedException( "Target {} is not supported by toolchain {}".format( target.name, toolchain_name)) + if (toolchain_name == "ARM" and CORE_ARCH[target.core] == 8): + toolchain_name = "ARMC6" try: cur_tc = TOOLCHAIN_CLASSES[toolchain_name] @@ -446,6 +448,12 @@ def merge_region_list(region_list, destination, notify, padding=b'\xFF'): merged.tofile(destination, format=format.strip(".")) +UPDATE_WHITELIST = ( + "application", + "header", +) + + def build_project(src_paths, build_path, target, toolchain_name, libraries_paths=None, linker_script=None, clean=False, notify=None, name=None, macros=None, inc_dirs=None, jobs=1, @@ -532,15 +540,28 @@ def build_project(src_paths, build_path, target, toolchain_name, # Link Program if toolchain.config.has_regions: - res, _ = toolchain.link_program(resources, build_path, name + "_application") + binary, _ = toolchain.link_program(resources, build_path, name + "_application") region_list = list(toolchain.config.regions) - region_list = [r._replace(filename=res) if r.active else r + region_list = [r._replace(filename=binary) if r.active else r for r in region_list] res = "%s.%s" % (join(build_path, name), getattr(toolchain.target, "OUTPUT_EXT", "bin")) merge_region_list(region_list, res, notify) + update_regions = [ + r for r in region_list if r.name in UPDATE_WHITELIST + ] + if update_regions: + update_res = "%s_update.%s" % ( + join(build_path, name), + getattr(toolchain.target, "OUTPUT_EXT", "bin") + ) + merge_region_list(update_regions, update_res, notify) + res = (res, update_res) + else: + res = (res, None) else: res, _ = toolchain.link_program(resources, build_path, name) + res = (res, None) memap_instance = getattr(toolchain, 'memap_instance', None) memap_table = '' @@ -568,8 +589,8 @@ def build_project(src_paths, build_path, target, toolchain_name, cur_result["result"] = "OK" cur_result["memory_usage"] = (memap_instance.mem_report if memap_instance is not None else None) - cur_result["bin"] = res - cur_result["elf"] = splitext(res)[0] + ".elf" + cur_result["bin"] = res[0] + cur_result["elf"] = splitext(res[0])[0] + ".elf" cur_result.update(toolchain.report) add_result_to_report(report, cur_result) @@ -1196,9 +1217,13 @@ def mcu_toolchain_matrix(verbose_html=False, platform_filter=None, row.append(text) for unique_toolchain in unique_supported_toolchains: - if (unique_toolchain in TARGET_MAP[target].supported_toolchains or + tgt_obj = TARGET_MAP[target] + if (unique_toolchain in tgt_obj.supported_toolchains or (unique_toolchain == "ARMC6" and - "ARM" in TARGET_MAP[target].supported_toolchains)): + "ARM" in tgt_obj.supported_toolchains) or + (unique_toolchain == "ARM" and + "ARMC6" in tgt_obj.supported_toolchains and + CORE_ARCH[tgt_obj.core] == 8)): text = "Supported" perm_counter += 1 else: @@ -1331,4 +1356,4 @@ def merge_build_data(filename, toolchain_report, app_type): if 'type' not in build[0]: build[0]['type'] = app_type build_data['builds'].append(build[0]) - dump(build_data, open(filename, "wb"), indent=4, separators=(',', ': ')) + dump(build_data, open(filename, "w"), indent=4, separators=(',', ': ')) diff --git a/tools/config/__init__.py b/tools/config/__init__.py index e1ad2be77d9e..9dc7ddc3d95e 100644 --- a/tools/config/__init__.py +++ b/tools/config/__init__.py @@ -1124,10 +1124,14 @@ def config_to_header(config, fname=None): Config._check_required_parameters(params) params_with_values = [p for p in params.values() if p.value is not None] ctx = { - "cfg_params" : [(p.macro_name, str(p.value), p.set_by) - for p in params_with_values], - "macros": [(m.macro_name, str(m.macro_value or ""), m.defined_by) - for m in macros.values()], + "cfg_params": sorted([ + (p.macro_name, str(p.value), p.set_by) + for p in params_with_values + ]), + "macros": sorted([ + (m.macro_name, str(m.macro_value or ""), m.defined_by) + for m in macros.values() + ]), "name_len": max([len(m.macro_name) for m in macros.values()] + [len(m.macro_name) for m in params_with_values] + [0]), diff --git a/tools/export/cmake/CMakeLists.txt.tmpl b/tools/export/cmake/CMakeLists.txt.tmpl index b3b38ad3d5bf..f2894e9bffc2 100644 --- a/tools/export/cmake/CMakeLists.txt.tmpl +++ b/tools/export/cmake/CMakeLists.txt.tmpl @@ -71,6 +71,16 @@ add_custom_command(TARGET {{name}} POST_BUILD COMMAND ${CMAKE_COMMAND} -E echo "-- built: $.hex" ) +{% if hex_files %} +add_custom_command(TARGET {{name}} POST_BUILD + COMMAND ${SREC_CAT} + {% for f in hex_files %}${CMAKE_CURRENT_SOURCE_DIR}/{{f}} {% endfor %} + -intel $.hex + -intel -o $-combined.hex -intel --line-length=44 + COMMAND ${CMAKE_COMMAND} -E echo "-- built: $-combined.hex" + ) +{% endif %} + ########################################################################## # mbed-cli specific targets diff --git a/tools/export/iar/iar_definitions.json b/tools/export/iar/iar_definitions.json index e348a8dad605..1ac0ebc48b6a 100644 --- a/tools/export/iar/iar_definitions.json +++ b/tools/export/iar/iar_definitions.json @@ -57,8 +57,9 @@ "OGChipSelectEditMenu": "STM32F070RB\tST STM32F070RB" }, "MK22DN512xxx5": { - "OGChipSelectEditMenu": "MK22DN512xxx5\tNXP MK22DN512xxx5" + "OGChipSelectEditMenu": "MK22FN512xxx12\tFreescale MK22FN512xxx12" }, + "MK24FN1M0xxx12": { "OGChipSelectEditMenu": "MK24FN1M0xxx12\tNXP MK24FN1M0xxx12" }, @@ -154,9 +155,6 @@ "FPU2": 7, "NrRegs": 1 }, - "MKL43Z256xxx4": { - "OGChipSelectEditMenu": "MKL43Z256xxx4\tFreescale MKL43Z256xxx4" - }, "LPC812M101JDH20": { "OGChipSelectEditMenu": "LPC812M101\tNXP LPC812M101" }, @@ -185,9 +183,6 @@ "STM32F446ZE": { "OGChipSelectEditMenu": "STM32F446ZE\tST STM32F446ZE" }, - "MK22DN512xxx5": { - "OGChipSelectEditMenu": "MK22FN512xxx12\tFreescale MK22FN512xxx12" - }, "STM32F303K8": { "OGChipSelectEditMenu": "STM32F303x8\tST STM32F303x8" }, diff --git a/tools/export/makefile/Makefile.tmpl b/tools/export/makefile/Makefile.tmpl index 52a3d3d42bc8..83a7f2b039ed 100644 --- a/tools/export/makefile/Makefile.tmpl +++ b/tools/export/makefile/Makefile.tmpl @@ -75,11 +75,11 @@ SREC_CAT = srec_cat {%- endif %} {%- block additional_executables -%}{%- endblock %} -{% for flag in c_flags %}C_FLAGS += {{flag}} +{% for flag in c_flags %}C_FLAGS += {{shell_escape(flag)}} {% endfor %} -{% for flag in cxx_flags %}CXX_FLAGS += {{flag}} +{% for flag in cxx_flags %}CXX_FLAGS += {{shell_escape(flag)}} {% endfor %} -{% for flag in asm_flags %}ASM_FLAGS += {{flag}} +{% for flag in asm_flags %}ASM_FLAGS += {{shell_escape(flag)}} {% endfor %} LD_FLAGS :={%- block ld_flags -%} {{ld_flags|join(" ")}} {% endblock %} diff --git a/tools/export/makefile/__init__.py b/tools/export/makefile/__init__.py index 8c2c6208bee8..e812e2be495e 100644 --- a/tools/export/makefile/__init__.py +++ b/tools/export/makefile/__init__.py @@ -29,6 +29,15 @@ from tools.utils import NotSupportedException from tools.targets import TARGET_MAP +SHELL_ESCAPE_TABLE = { + "(": "\(", + ")": "\)", +} + + +def shell_escape(string): + return "".join(SHELL_ESCAPE_TABLE.get(char, char) for char in string) + class Makefile(Exporter): """Generic Makefile template that mimics the behavior of the python build @@ -88,18 +97,16 @@ def generate(self): if (basename(dirname(dirname(self.export_dir))) == "projectfiles") else [".."]), - 'cc_cmd': " ".join([basename(self.toolchain.cc[0])] + - self.toolchain.cc[1:]), - 'cppc_cmd': " ".join([basename(self.toolchain.cppc[0])] + - self.toolchain.cppc[1:]), - 'asm_cmd': " ".join([basename(self.toolchain.asm[0])] + - self.toolchain.asm[1:]), + 'cc_cmd': basename(self.toolchain.cc[0]), + 'cppc_cmd': basename(self.toolchain.cppc[0]), + 'asm_cmd': basename(self.toolchain.asm[0]), '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, 'user_library_flag': self.USER_LIBRARY_FLAG, 'needs_asm_preproc': self.PREPROCESS_ASM, + 'shell_escape': shell_escape, } if hasattr(self.toolchain, "preproc"): @@ -123,6 +130,9 @@ def generate(self): 'to_be_compiled']: ctx[key] = sorted(ctx[key]) ctx.update(self.format_flags()) + ctx['asm_flags'].extend(self.toolchain.asm[1:]) + ctx['c_flags'].extend(self.toolchain.cc[1:]) + ctx['cxx_flags'].extend(self.toolchain.cppc[1:]) # Add the virtual path the the include option in the ASM flags new_asm_flags = [] @@ -265,17 +275,6 @@ class Armc6(Arm): NAME = 'Make-ARMc6' TOOLCHAIN = "ARMC6" - @classmethod - def is_target_supported(cls, target_name): - target = TARGET_MAP[target_name] - if target.core in ( - "Cortex-M23", "Cortex-M23-NS", - "Cortex-M33", "Cortex-M33-NS" - ): - return False - return apply_supported_whitelist( - cls.TOOLCHAIN, cls.POST_BINARY_WHITELIST, target) - class IAR(Makefile): """IAR specific makefile target""" diff --git a/tools/make.py b/tools/make.py index 94f910d36018..d59c5badf8fe 100644 --- a/tools/make.py +++ b/tools/make.py @@ -273,23 +273,28 @@ build_dir = options.build_dir try: - bin_file = build_project(test.source_dir, build_dir, mcu, toolchain, - set(test.dependencies), - linker_script=options.linker_script, - clean=options.clean, - notify=notify, - report=build_data_blob, - macros=options.macros, - jobs=options.jobs, - name=options.artifact_name, - app_config=options.app_config, - inc_dirs=[dirname(MBED_LIBRARIES)], - build_profile=extract_profile(parser, - options, - toolchain), - stats_depth=options.stats_depth, - ignore=options.ignore) - print('Image: %s'% bin_file) + bin_file, update_file = build_project( + test.source_dir, + build_dir, + mcu, + toolchain, + set(test.dependencies), + linker_script=options.linker_script, + clean=options.clean, + notify=notify, + report=build_data_blob, + macros=options.macros, + jobs=options.jobs, + name=options.artifact_name, + app_config=options.app_config, + inc_dirs=[dirname(MBED_LIBRARIES)], + build_profile=extract_profile(parser, options, toolchain), + stats_depth=options.stats_depth, + ignore=options.ignore + ) + if update_file: + print('Update Image: %s' % update_file) + print('Image: %s' % bin_file) if options.disk: # Simple copy to the mbed disk diff --git a/tools/memap.py b/tools/memap.py index ca57415050c9..d2e812024a71 100644 --- a/tools/memap.py +++ b/tools/memap.py @@ -5,9 +5,9 @@ from abc import abstractmethod, ABCMeta from sys import stdout, exit, argv -from os import sep +from os import sep, rename, remove from os.path import (basename, dirname, join, relpath, abspath, commonprefix, - splitext) + splitext, exists) import re import csv import json @@ -20,6 +20,7 @@ from .utils import (argparse_filestring_type, argparse_lowercase_hyphen_type, argparse_uppercase_type) +from .settings import COMPARE_FIXED class _Parser(object): @@ -455,6 +456,7 @@ class MemapParser(object): """ print_sections = ('.text', '.data', '.bss') + delta_sections = ('.text-delta', '.data-delta', '.bss-delta') # sections to print info (generic for all toolchains) @@ -466,6 +468,7 @@ def __init__(self): # list of all modules and their sections # full list - doesn't change with depth self.modules = dict() + self.old_modules = None # short version with specific depth self.short_modules = dict() @@ -510,8 +513,17 @@ def reduce_depth(self, depth): new_name = join(*split_name[:depth]) self.short_modules.setdefault(new_name, defaultdict(int)) for section_idx, value in v.items(): - self.short_modules[new_name].setdefault(section_idx, 0) self.short_modules[new_name][section_idx] += self.modules[module_name][section_idx] + self.short_modules[new_name][section_idx + '-delta'] += self.modules[module_name][section_idx] + if self.old_modules: + for module_name, v in self.old_modules.items(): + split_name = module_name.split(sep) + if split_name[0] == '': + split_name = split_name[1:] + new_name = join(*split_name[:depth]) + self.short_modules.setdefault(new_name, defaultdict(int)) + for section_idx, value in v.items(): + self.short_modules[new_name][section_idx + '-delta'] -= self.old_modules[module_name][section_idx] export_formats = ["json", "csv-ci", "html", "table"] @@ -557,7 +569,7 @@ def _move_up_tree(tree, next_module): if child["name"] == next_module: return child else: - new_module = {"name": next_module, "value": 0} + new_module = {"name": next_module, "value": 0, "delta": 0} tree["children"].append(new_module) return new_module @@ -567,9 +579,9 @@ def generate_html(self, file_desc): Positional arguments: file_desc - the file to write out the final report to """ - tree_text = {"name": ".text", "value": 0} - tree_bss = {"name": ".bss", "value": 0} - tree_data = {"name": ".data", "value": 0} + tree_text = {"name": ".text", "value": 0, "delta": 0} + tree_bss = {"name": ".bss", "value": 0, "delta": 0} + tree_data = {"name": ".data", "value": 0, "delta": 0} for name, dct in self.modules.items(): cur_text = tree_text cur_bss = tree_bss @@ -578,14 +590,17 @@ def generate_html(self, file_desc): while True: try: cur_text["value"] += dct['.text'] + cur_text["delta"] += dct['.text'] except KeyError: pass try: cur_bss["value"] += dct['.bss'] + cur_bss["delta"] += dct['.bss'] except KeyError: pass try: cur_data["value"] += dct['.data'] + cur_data["delta"] += dct['.data'] except KeyError: pass if not modules: @@ -594,15 +609,44 @@ def generate_html(self, file_desc): cur_text = self._move_up_tree(cur_text, next_module) cur_data = self._move_up_tree(cur_data, next_module) cur_bss = self._move_up_tree(cur_bss, next_module) + if self.old_modules: + for name, dct in self.old_modules.items(): + cur_text = tree_text + cur_bss = tree_bss + cur_data = tree_data + modules = name.split(sep) + while True: + try: + cur_text["delta"] -= dct['.text'] + except KeyError: + pass + try: + cur_bss["delta"] -= dct['.bss'] + except KeyError: + pass + try: + cur_data["delta"] -= dct['.data'] + except KeyError: + pass + if not modules: + break + next_module = modules.pop(0) + if not any(cld['name'] == next_module for cld in cur_text['children']): + break + cur_text = self._move_up_tree(cur_text, next_module) + cur_data = self._move_up_tree(cur_data, next_module) + cur_bss = self._move_up_tree(cur_bss, next_module) tree_rom = { "name": "ROM", "value": tree_text["value"] + tree_data["value"], + "delta": tree_text["delta"] + tree_data["delta"], "children": [tree_text, tree_data] } tree_ram = { "name": "RAM", "value": tree_bss["value"] + tree_data["value"], + "delta": tree_bss["delta"] + tree_data["delta"], "children": [tree_bss, tree_data] } @@ -634,6 +678,14 @@ def generate_json(self, file_desc): file_desc.write('\n') return None + RAM_FORMAT_STR = ( + "Total Static RAM memory (data + bss): {}({:+}) bytes\n" + ) + + ROM_FORMAT_STR = ( + "Total Flash memory (text + data): {}({:+}) bytes\n" + ) + def generate_csv(self, file_desc): """Generate a CSV file from a memoy map @@ -646,7 +698,7 @@ def generate_csv(self, file_desc): module_section = [] sizes = [] for i in sorted(self.short_modules): - for k in self.print_sections: + for k in self.print_sections + self.delta_sections: module_section.append((i + k)) sizes += [self.short_modules[i][k]] @@ -681,23 +733,29 @@ def generate_table(self, file_desc): row = [i] for k in self.print_sections: - row.append(self.short_modules[i][k]) + row.append("{}({:+})".format(self.short_modules[i][k], + self.short_modules[i][k + "-delta"])) table.add_row(row) subtotal_row = ['Subtotals'] for k in self.print_sections: - subtotal_row.append(self.subtotal[k]) + subtotal_row.append("{}({:+})".format( + self.subtotal[k], self.subtotal[k + '-delta'])) table.add_row(subtotal_row) output = table.get_string() output += '\n' - output += "Total Static RAM memory (data + bss): %s bytes\n" % \ - str(self.mem_summary['static_ram']) - output += "Total Flash memory (text + data): %s bytes\n" % \ - str(self.mem_summary['total_flash']) + output += self.RAM_FORMAT_STR.format( + self.mem_summary['static_ram'], + self.mem_summary['static_ram_delta'] + ) + output += self.ROM_FORMAT_STR.format( + self.mem_summary['total_flash'], + self.mem_summary['total_flash_delta'] + ) return output @@ -706,16 +764,24 @@ def generate_table(self, file_desc): def compute_report(self): """ Generates summary of memory usage for main areas """ - for k in self.sections: - self.subtotal[k] = 0 + self.subtotal = defaultdict(int) for mod in self.modules.values(): for k in self.sections: self.subtotal[k] += mod[k] + self.subtotal[k + '-delta'] += mod[k] + if self.old_modules: + for mod in self.old_modules.values(): + for k in self.sections: + self.subtotal[k + '-delta'] -= mod[k] self.mem_summary = { - 'static_ram': (self.subtotal['.data'] + self.subtotal['.bss']), + 'static_ram': self.subtotal['.data'] + self.subtotal['.bss'], + 'static_ram_delta': + self.subtotal['.data-delta'] + self.subtotal['.bss-delta'], 'total_flash': (self.subtotal['.text'] + self.subtotal['.data']), + 'total_flash_delta': + self.subtotal['.text-delta'] + self.subtotal['.data-delta'], } self.mem_report = [] @@ -724,7 +790,8 @@ def compute_report(self): self.mem_report.append({ "module": name, "size":{ - k: sizes.get(k, 0) for k in self.print_sections + k: sizes.get(k, 0) for k in (self.print_sections + + self.delta_sections) } }) @@ -741,16 +808,26 @@ def parse(self, mapfile, toolchain): """ self.tc_name = toolchain.title() if toolchain in ("ARM", "ARM_STD", "ARM_MICRO", "ARMC6"): - parser = _ArmccParser() + parser = _ArmccParser elif toolchain == "GCC_ARM" or toolchain == "GCC_CR": - parser = _GccParser() + parser = _GccParser elif toolchain == "IAR": - parser = _IarParser() + parser = _IarParser else: return False try: with open(mapfile, 'r') as file_input: - self.modules = parser.parse_mapfile(file_input) + self.modules = parser().parse_mapfile(file_input) + try: + with open("%s.old" % mapfile, 'r') as old_input: + self.old_modules = parser().parse_mapfile(old_input) + except IOError: + self.old_modules = None + if not COMPARE_FIXED: + old_mapfile = "%s.old" % mapfile + if exists(old_mapfile): + remove(old_mapfile) + rename(mapfile, old_mapfile) return True except IOError as error: diff --git a/tools/memap_flamegraph.html b/tools/memap_flamegraph.html index 20fc2e30d773..bb7ea4744e3a 100644 --- a/tools/memap_flamegraph.html +++ b/tools/memap_flamegraph.html @@ -80,16 +80,35 @@

          {{name}} Memory Details

          .direction("s") .offset([8, 0]) .attr('class', 'd3-flame-graph-tip') - .html(function(d) { return "module: " + d.data.name + ", bytes: " + d.data.value; }); + .html(function(d) { return "module: " + d.data.name + ", bytes: " + d.data.value + ", delta: " + d.data.delta; }); + var colorizer = function (d) { + if (d.data.delta > 0) { + ratio = (d.data.value - d.data.delta) / d.data.value; + green = ("0" + (Number(ratio * 0xFF | 0).toString(16))).slice(-2).toUpperCase(); + blue = ("0" + (Number(ratio * 0xEE | 0).toString(16))).slice(-2).toUpperCase(); + console.log(d.data.name, green, blue); + return "#EE" + green + blue + } else if (d.data.delta < 0) { + ratio = (d.data.value + d.data.delta) / d.data.value; + green = ("0" + (Number(ratio * 0xFF | 0).toString(16))).slice(-2).toUpperCase(); + red = ("0" + (Number(ratio * 0xFF | 0).toString(16))).slice(-2).toUpperCase(); + console.log(d.data.name, red, green); + return "#" + red + green + "EE"; + } else { + return "#FFFFEE"; + } + } var flameGraph_rom = d3.flameGraph() .transitionDuration(250) .transitionEase(d3.easeCubic) .sort(true) + .color(colorizer) .tooltip(tip); var flameGraph_ram = d3.flameGraph() .transitionDuration(250) .transitionEase(d3.easeCubic) .sort(true) + .color(colorizer) .tooltip(tip); var rom_elem = d3.select("#chart-rom"); flameGraph_rom.width(rom_elem.node().getBoundingClientRect().width); diff --git a/tools/resources/__init__.py b/tools/resources/__init__.py index 953fb55c2793..79ec719ad94d 100644 --- a/tools/resources/__init__.py +++ b/tools/resources/__init__.py @@ -136,9 +136,10 @@ def __init__(self, notify, collect_ignores=False): # Incremental scan related self._label_paths = [] self._labels = {"TARGET": [], "TOOLCHAIN": [], "FEATURE": []} + self._prefixed_labels = set() - # Should we convert all paths to unix-style? - self._win_to_unix = False + # Path seperator style (defaults to OS-specific seperator) + self._sep = sep # Ignore patterns from .mbedignore files and add_ignore_patters self._ignore_patterns = [] @@ -181,11 +182,12 @@ def detect_duplicates(self): return count def win_to_unix(self): - self._win_to_unix = True - for file_type in self.ALL_FILE_TYPES: - v = [f._replace(name=f.name.replace('\\', '/')) for - f in self.get_file_refs(file_type)] - self._file_refs[file_type] = v + self._sep = "/" + if self._sep != sep: + for file_type in self.ALL_FILE_TYPES: + v = [f._replace(name=f.name.replace(sep, self._sep)) for + f in self.get_file_refs(file_type)] + self._file_refs[file_type] = v def __str__(self): s = [] @@ -216,12 +218,12 @@ def __str__(self): def _add_labels(self, prefix, labels): self._labels[prefix].extend(labels) - prefixed_labels = set("%s_%s" % (prefix, label) for label in labels) + self._prefixed_labels |= set("%s_%s" % (prefix, label) for label in labels) for path, base_path, into_path in self._label_paths: - if basename(path) in prefixed_labels: + if basename(path) in self._prefixed_labels: self.add_directory(path, base_path, into_path) self._label_paths = [(p, b, i) for p, b, i in self._label_paths - if basename(p) not in prefixed_labels] + if basename(p) not in self._prefixed_labels] def add_target_labels(self, target): self._add_labels("TARGET", target.labels) @@ -262,8 +264,8 @@ def _not_current_label(self, dirname, label_type): dirname[len(label_type) + 1:] not in self._labels[label_type]) def add_file_ref(self, file_type, file_name, file_path): - if self._win_to_unix: - ref = FileRef(file_name.replace("\\", "/"), file_path) + if sep != self._sep: + ref = FileRef(file_name.replace(sep, self._sep), file_path) else: ref = FileRef(file_name, file_path) self._file_refs[file_type].add(ref) @@ -272,12 +274,16 @@ def get_file_refs(self, file_type): """Return a list of FileRef for every file of the given type""" return list(self._file_refs[file_type]) - @staticmethod - def _all_parents(files): + def _all_parents(self, files): for name in files: - components = name.split(sep) - for n in range(1, len(components)): - parent = join(*components[:n]) + components = name.split(self._sep) + start_at = 2 if components[0] in set(['', '.']) else 1 + for index, directory in reversed(list(enumerate(components))[start_at:]): + if directory in self._prefixed_labels: + start_at = index + 1 + break + for n in range(start_at, len(components)): + parent = self._sep.join(components[:n]) yield parent def _get_from_refs(self, file_type, key): @@ -346,7 +352,7 @@ def lib_refs(self): def linker_script(self): options = self.get_file_names(FileType.LD_SCRIPT) if options: - return options[-1] + return options[0] else: return None diff --git a/tools/settings.py b/tools/settings.py index 3b7fa32b1b48..267bc00e45de 100644 --- a/tools/settings.py +++ b/tools/settings.py @@ -58,6 +58,9 @@ # Print compiler warnings and errors as link format PRINT_COMPILER_OUTPUT_AS_LINK = False +# Compare against a fixed build of the project for space consumption +COMPARE_FIXED = False + # Print warnings/errors in color COLOR = False @@ -91,7 +94,7 @@ print("WARNING: MBED_%s set as environment variable but doesn't" " exist" % _n) -_ENV_VARS = ['PRINT_COMPILER_OUTPUT_AS_LINK', 'COLOR'] +_ENV_VARS = ['PRINT_COMPILER_OUTPUT_AS_LINK', 'COLOR', 'COMPARE_FIXED'] for _n in _ENV_VARS: value = getenv('MBED_%s' % _n) if value: diff --git a/tools/targets/__init__.py b/tools/targets/__init__.py index bf1864554de7..594381cc0751 100644 --- a/tools/targets/__init__.py +++ b/tools/targets/__init__.py @@ -30,7 +30,7 @@ from tools.utils import json_file_to_dict __all__ = ["target", "TARGETS", "TARGET_MAP", "TARGET_NAMES", "CORE_LABELS", - "HookError", "generate_py_target", "Target", + "CORE_ARCH", "HookError", "generate_py_target", "Target", "CUMULATIVE_ATTRIBUTES", "get_resolution_order"] CORE_LABELS = { @@ -50,6 +50,23 @@ "Cortex-M33-NS": ["M33", "M33_NS", "CORTEX_M", "LIKE_CORTEX_M33", "CORTEX"] } +CORE_ARCH = { + "Cortex-M0": 6, + "Cortex-M0+": 6, + "Cortex-M1": 6, + "Cortex-M3": 7, + "Cortex-M4": 7, + "Cortex-M4F": 7, + "Cortex-M7": 7, + "Cortex-M7F": 7, + "Cortex-M7FD": 7, + "Cortex-A9": 7, + "Cortex-M23": 8, + "Cortex-M23-NS": 8, + "Cortex-M33": 8, + "Cortex-M33-NS": 8, +} + ################################################################################ # Generic Target class that reads and interprets the data in targets.json diff --git a/tools/test.py b/tools/test.py index df9b8378445d..179c7fb30b28 100644 --- a/tools/test.py +++ b/tools/test.py @@ -220,6 +220,9 @@ # NotSupportedException is handled by the build log pass except Exception as e: + if options.verbose: + import traceback + traceback.print_exc() # Some other exception occurred, print the error message print(e) diff --git a/tools/test/toolchains/api_test.py b/tools/test/toolchains/api_test.py index fada557661b3..b1a19c3300e8 100644 --- a/tools/test/toolchains/api_test.py +++ b/tools/test/toolchains/api_test.py @@ -184,7 +184,7 @@ def test_toolchain_profile_asm(profile, source_file): with patch('os.mkdir') as _mkdir: for _, tc_class in TOOLCHAIN_CLASSES.items(): toolchain = tc_class(TARGET_MAP["K64F"], build_profile=profile, - notify=MockNotifier) + notify=MockNotifier()) toolchain.inc_md5 = "" toolchain.build_dir = "" toolchain.config = MagicMock() diff --git a/tools/test_api.py b/tools/test_api.py index c23fa26a2327..ccde1158d742 100644 --- a/tools/test_api.py +++ b/tools/test_api.py @@ -2174,7 +2174,7 @@ def build_test_worker(*args, **kwargs): del kwargs['toolchain_paths'] try: - bin_file = build_project(*args, **kwargs) + bin_file, _ = build_project(*args, **kwargs) ret['result'] = True ret['bin_file'] = bin_file ret['kwargs'] = kwargs @@ -2208,7 +2208,7 @@ def build_tests(tests, base_source_paths, build_path, target, toolchain_name, base_path = norm_relative_path(build_path, execution_directory) if isinstance(target, Target): - target_name + target_name = target.name else: target_name = target target = TARGET_MAP[target_name] diff --git a/tools/toolchains/__init__.py b/tools/toolchains/__init__.py index 3ff1f60e1224..bdde695aeff7 100644 --- a/tools/toolchains/__init__.py +++ b/tools/toolchains/__init__.py @@ -312,12 +312,17 @@ def make_option_file(self, options, naming=".options_{}.txt"): """ Generate a via file for a pile of defines ARM, GCC, IAR cross compatible """ - option_md5 = md5(' '.join(options).encode('utf-8')).hexdigest() - via_file = join(self.build_dir, naming.format(option_md5)) - if not exists(via_file): - with open(via_file, "w") as fd: - string = " ".join(options) - fd.write(string) + to_write = " ".join(options).encode('utf-8') + new_md5 = md5(to_write).hexdigest() + via_file = join(self.build_dir, naming.format(new_md5)) + try: + with open(via_file, "r") as fd: + old_md5 = md5(fd.read().encode('utf-8')).hexdigest() + except IOError: + old_md5 = None + if old_md5 != new_md5: + with open(via_file, "wb") as fd: + fd.write(to_write) return via_file def get_inc_file(self, includes): diff --git a/tools/toolchains/arm.py b/tools/toolchains/arm.py index 1935bf005975..bd6ff7f56aae 100644 --- a/tools/toolchains/arm.py +++ b/tools/toolchains/arm.py @@ -25,6 +25,7 @@ from shutil import rmtree from distutils.version import LooseVersion +from tools.targets import CORE_ARCH from tools.toolchains import mbedToolchain, TOOLCHAIN_PATHS from tools.hooks import hook_tool from tools.utils import mkdir, NotSupportedException, run_cmd @@ -62,8 +63,12 @@ def __init__(self, target, notify=None, macros=None, if getattr(target, "default_lib", "std") == "small": if "-DMBED_RTOS_SINGLE_THREAD" not in self.flags['common']: self.flags['common'].append("-DMBED_RTOS_SINGLE_THREAD") + if "-D__MICROLIB" not in self.flags['common']: + self.flags['common'].append("-D__MICROLIB") if "--library_type=microlib" not in self.flags['ld']: self.flags['ld'].append("--library_type=microlib") + if "--library_type=microlib" not in self.flags['common']: + self.flags['common'].append("--library_type=microlib") if target.core == "Cortex-M0+": cpu = "Cortex-M0" @@ -368,6 +373,14 @@ def __init__(self, target, *args, **kwargs): if target.core not in self.SUPPORTED_CORES: raise NotSupportedException( "this compiler does not support the core %s" % target.core) + if CORE_ARCH[target.core] < 8: + self.notify.cc_info({ + 'severity': "Error", 'file': "", 'line': "", 'col': "", + 'message': "ARMC6 does not support ARM architecture v{}" + " targets".format(CORE_ARCH[target.core]), + 'text': '', 'target_name': self.target.name, + 'toolchain_name': self.name + }) if not set(("ARM", "ARMC6")).intersection(set(target.supported_toolchains)): raise NotSupportedException("ARM/ARMC6 compiler support is required for ARMC6 build") diff --git a/tools/toolchains/gcc.py b/tools/toolchains/gcc.py index 3d89c3cd376a..d7d53a7e109d 100644 --- a/tools/toolchains/gcc.py +++ b/tools/toolchains/gcc.py @@ -16,6 +16,7 @@ """ import re from os.path import join, basename, splitext, dirname, exists +from os import getenv from distutils.spawn import find_executable from distutils.version import LooseVersion @@ -116,6 +117,9 @@ def __init__(self, target, notify=None, macros=None, build_profile=None, self.ar = join(tool_path, "arm-none-eabi-ar") self.elf2bin = join(tool_path, "arm-none-eabi-objcopy") + self.use_distcc = (bool(getenv("DISTCC_POTENTIAL_HOSTS", False)) + and not getenv("MBED_DISABLE_DISTCC", False)) + def version_check(self): stdout, _, retcode = run_cmd([self.cc[0], "--version"], redirect=True) msg = None @@ -207,6 +211,8 @@ def compile(self, cc, source, object, includes): # Call cmdline hook cmd = self.hook.get_cmdline_compiler(cmd) + if self.use_distcc: + cmd = ["distcc"] + cmd return [cmd]