diff --git a/.github/issue_template.md b/.github/issue_template.md index 7d4f1e8407..c5ed65cbbf 100644 --- a/.github/issue_template.md +++ b/.github/issue_template.md @@ -19,7 +19,7 @@ diff --git a/.travis.yml b/.travis.yml index 2b37e5503b..7ecfcd570c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -85,7 +85,6 @@ matrix: - doxygen doxyfile_options 2>&1 # Once Mbed OS has been fixed, enable the full test by replacing the top line with this: # - ( ! doxygen doxyfile_options 2>&1 | grep . ) - # Assert that all binary libraries are named correctly # The strange command below asserts that there are exactly 0 libraries # that do not start with lib @@ -106,12 +105,20 @@ matrix: install: # Install dependencies - sudo apt-get install gcc-arm-embedded - - pip install -r requirements.txt - - pip install pytest pylint hypothesis==3.88.3 mock coverage coveralls - # Print versions we use - - arm-none-eabi-gcc --version + # Add additional dependencies specific for testing - python --version + - |- + tr -d ' ' >> requirements.txt <<< " + mock==2.0.0 + pytest==3.3.0 + pylint>=1.9,<2 + hypothesis>=3,<4 + coverage>=4.5,<5 + coveralls>=1.5,<2 + " + # ... and install. + - pip install -r requirements.txt - pip list --verbose script: # Run local testing on tools @@ -122,7 +129,27 @@ matrix: after_success: # Coverage for tools - coveralls - # Report success since we have overridden default behaviour + # Report success since we have overridden default behavior + - bash -c "$STATUS" success "Local $NAME testing has passed" + + - env: + - NAME=doxy-spellcheck + + install: + - sudo apt-get install aspell + + script: + # Run local testing on header file doxy + - ./tools/test/travis-ci/doxy-spellchecker/spell.sh drivers + - ./tools/test/travis-ci/doxy-spellchecker/spell.sh platform + - ./tools/test/travis-ci/doxy-spellchecker/spell.sh events + - ./tools/test/travis-ci/doxy-spellchecker/spell.sh rtos + - ./tools/test/travis-ci/doxy-spellchecker/spell.sh features/netsocket + + after_success: + # Coverage for tools + - coveralls + # Report success since we have overridden default behavior - bash -c "$STATUS" success "Local $NAME testing has passed" # - <<: *tools-pytest @@ -275,9 +302,18 @@ matrix: - env: - NAME=licence_check script: - - echo 'Checking that there is no GPL licence text in code' - - ! git grep -q --ignore-case "gnu general public"; - - ! git grep -q --ignore-case "gnu library general public"; + - >- + ! grep --recursive --max-count=100 --ignore-case --exclude .travis.yml \ + "gnu general\|gnu lesser\|lesser general\|public license" + + - env: + - NAME=include_check + script: + - echo 'Checking that there are no '#include "mbed.h"' in code where it should not be' + - | + ! git grep '^#include\s["'"']mbed.h['"'"]$' -- '*.c' '*.h' '*.cpp' '*.hpp' \ + ':!*platform_mbed.h' ':!*TESTS/*' ':!TEST_APPS/' ':!UNITTESTS/' \ + ':!*tests/*' ':!*targets/*' ':!*TARGET_*' ':!*unsupported/*' - env: - NAME=psa-autogen diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 701af04107..f433ee4128 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,4 +2,4 @@ Mbed OS is an open-source, device software platform for the Internet of Things. Contributions are an important part of the platform, and our goal is to make it as simple as possible to become a contributor. -To encourage productive collaboration, as well as robust, consistent and maintainable code, we have a set of guidelines for [contributing to Mbed OS](https://os.mbed.com/docs/latest/reference/contributing.html). +To encourage productive collaboration, as well as robust, consistent and maintainable code, we have a set of guidelines for [contributing to Mbed OS](https://os.mbed.com/docs/mbed-os/latest/contributing/index.html). diff --git a/TESTS/host_tests/crash_reporting.py b/TESTS/host_tests/crash_reporting.py index bc4a717078..a505597389 100644 --- a/TESTS/host_tests/crash_reporting.py +++ b/TESTS/host_tests/crash_reporting.py @@ -60,7 +60,7 @@ class CrashReportingTest(BaseHostTest): wait_after_reset = wait_after_reset if wait_after_reset is not None else DEFAULT_CYCLE_PERIOD #Wait 2 seconds for system to init - time.sleep(2.0) + time.sleep(7.0) #self.send_kv(MSG_KEY_SYNC, MSG_VALUE_DUMMY) self.send_kv(MSG_KEY_DEVICE_ERROR, MSG_VALUE_DUMMY) time.sleep(5.0) diff --git a/TESTS/mbed_drivers/flashiap/main.cpp b/TESTS/mbed_drivers/flashiap/main.cpp index 263376c919..9cd3cd861b 100644 --- a/TESTS/mbed_drivers/flashiap/main.cpp +++ b/TESTS/mbed_drivers/flashiap/main.cpp @@ -128,6 +128,7 @@ void flashiap_cross_sector_program_test() agg_size += sector_size; address -= sector_size; } + utest_printf("ROM ends at 0x%lx, test starts at 0x%lx\n", FLASHIAP_APP_ROM_END_ADDR, address); TEST_SKIP_UNLESS_MESSAGE(address >= FLASHIAP_APP_ROM_END_ADDR, "Test skipped. Test region overlaps code."); ret = flash_device.erase(address, agg_size); TEST_ASSERT_EQUAL_INT32(0, ret); @@ -184,6 +185,7 @@ void flashiap_program_error_test() TEST_ASSERT_TRUE(address != 0UL); // unaligned address + utest_printf("ROM ends at 0x%lx, test starts at 0x%lx\n", FLASHIAP_APP_ROM_END_ADDR, address); TEST_SKIP_UNLESS_MESSAGE(address >= FLASHIAP_APP_ROM_END_ADDR, "Test skipped. Test region overlaps code."); ret = flash_device.erase(address + 1, sector_size); TEST_ASSERT_EQUAL_INT32(-1, ret); @@ -220,6 +222,9 @@ void flashiap_timing_test() 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; + utest_printf("ROM ends at 0x%lx, test starts at 0x%lx\n", FLASHIAP_APP_ROM_END_ADDR, base_address); + TEST_SKIP_UNLESS_MESSAGE(base_address >= FLASHIAP_APP_ROM_END_ADDR, "Test skipped. Test region overlaps code."); + timer.start(); for (num_write_sizes = 0; num_write_sizes < max_write_sizes; num_write_sizes++) { if (write_size > sector_size) { diff --git a/TESTS/mbed_hal/flash/functional_tests/main.cpp b/TESTS/mbed_hal/flash/functional_tests/main.cpp index 06c876dfdd..e79a16a53d 100644 --- a/TESTS/mbed_hal/flash/functional_tests/main.cpp +++ b/TESTS/mbed_hal/flash/functional_tests/main.cpp @@ -175,6 +175,10 @@ void flash_erase_sector_test() uint32_t last_sector_size = flash_get_sector_size(&test_flash, addr_after_last - 1); uint32_t last_sector = addr_after_last - last_sector_size; TEST_ASSERT_EQUAL_INT32(0, last_sector % last_sector_size); + + utest_printf("ROM ends at 0x%lx, test starts at 0x%lx\n", FLASHIAP_APP_ROM_END_ADDR, last_sector); + TEST_SKIP_UNLESS_MESSAGE(last_sector >= FLASHIAP_APP_ROM_END_ADDR, "Test skipped. Test region overlaps code."); + ret = flash_erase_sector(&test_flash, last_sector); TEST_ASSERT_EQUAL_INT32(0, ret); @@ -201,6 +205,9 @@ void flash_program_page_test() // sector size might not be same as page size uint32_t erase_sector_boundary = ALIGN_DOWN(address, flash_get_sector_size(&test_flash, address)); + utest_printf("ROM ends at 0x%lx, test starts at 0x%lx\n", FLASHIAP_APP_ROM_END_ADDR, erase_sector_boundary); + TEST_SKIP_UNLESS_MESSAGE(erase_sector_boundary >= FLASHIAP_APP_ROM_END_ADDR, "Test skipped. Test region overlaps code."); + ret = flash_erase_sector(&test_flash, erase_sector_boundary); TEST_ASSERT_EQUAL_INT32(0, ret); diff --git a/TESTS/mbed_platform/crash_reporting/main.cpp b/TESTS/mbed_platform/crash_reporting/main.cpp index dab00237de..d971099c85 100644 --- a/TESTS/mbed_platform/crash_reporting/main.cpp +++ b/TESTS/mbed_platform/crash_reporting/main.cpp @@ -53,12 +53,17 @@ void test_crash_reporting() // Report readiness greentea_send_kv(MSG_KEY_DEVICE_READY, MSG_VALUE_DUMMY); + printf("\nMessage sent: %s\n", MSG_KEY_DEVICE_READY); static char _key[MSG_KEY_LEN + 1] = { }; static char _value[MSG_VALUE_LEN + 1] = { }; + printf("\nWaiting for crash inject error message: %s\n", MSG_KEY_DEVICE_ERROR); greentea_parse_kv(_key, _value, MSG_KEY_LEN, MSG_VALUE_LEN); + printf("\nCrash inject error message received\n"); + if (strcmp(_key, MSG_KEY_DEVICE_ERROR) == 0) { + printf("\nForcing error\n"); MBED_ERROR1(MBED_ERROR_OUT_OF_MEMORY, "Executing crash reporting test.", 0xDEADBAD); TEST_ASSERT_MESSAGE(0, "crash_reporting() error call failed."); } @@ -67,7 +72,7 @@ void test_crash_reporting() int main(void) { - GREENTEA_SETUP(30, "crash_reporting"); + GREENTEA_SETUP(40, "crash_reporting"); test_crash_reporting(); GREENTEA_TESTSUITE_RESULT(0); diff --git a/TESTS/mbedmicro-rtos-mbed/systimer/main.cpp b/TESTS/mbedmicro-rtos-mbed/systimer/main.cpp index 8a25ad2871..d1dba04709 100644 --- a/TESTS/mbedmicro-rtos-mbed/systimer/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/systimer/main.cpp @@ -245,7 +245,10 @@ void test_handler_called_once(void) int32_t sem_slots = st.sem_wait(0); TEST_ASSERT_EQUAL_INT32(0, sem_slots); - sem_slots = st.sem_wait(osWaitForever); + // Wait in a busy loop to prevent entering sleep or deepsleep modes. + while (sem_slots != 1) { + sem_slots = st.sem_wait(0); + } us_timestamp_t t2 = st.get_time(); TEST_ASSERT_EQUAL_INT32(1, sem_slots); TEST_ASSERT_EQUAL_UINT32(1, st.get_tick()); diff --git a/TESTS/netsocket/README.md b/TESTS/netsocket/README.md index ae321e4afd..0874f18b9a 100644 --- a/TESTS/netsocket/README.md +++ b/TESTS/netsocket/README.md @@ -243,6 +243,10 @@ content at minimum: "help" : "Port of echo server", "value" : "7" } + "echo-server-discard-port" : { + "help" : "Discard port of echo server", + "value" : "9" + } } } ``` diff --git a/TESTS/netsocket/dns/main.cpp b/TESTS/netsocket/dns/main.cpp index 9c2fedf92d..324e3b8c56 100644 --- a/TESTS/netsocket/dns/main.cpp +++ b/TESTS/netsocket/dns/main.cpp @@ -160,7 +160,7 @@ static void net_bringup() // Test setup utest::v1::status_t test_setup(const size_t number_of_cases) { - GREENTEA_SETUP(120, "default_auto"); + GREENTEA_SETUP(200, "default_auto"); net_bringup(); return verbose_test_setup_handler(number_of_cases); } diff --git a/TESTS/netsocket/tcp/main.cpp b/TESTS/netsocket/tcp/main.cpp index 0f0810c51a..36f453532a 100644 --- a/TESTS/netsocket/tcp/main.cpp +++ b/TESTS/netsocket/tcp/main.cpp @@ -34,7 +34,6 @@ using namespace utest::v1; namespace { -NetworkInterface *net; Timer tc_bucket; // Timer to limit a test cases run time } @@ -45,11 +44,6 @@ mbed_stats_socket_t tcp_stats[MBED_CONF_NSAPI_SOCKET_STATS_MAX_COUNT]; char tcp_global::rx_buffer[RX_BUFF_SIZE]; char tcp_global::tx_buffer[TX_BUFF_SIZE]; -NetworkInterface *get_interface() -{ - return net; -} - void drop_bad_packets(TCPSocket &sock, int orig_timeout) { nsapi_error_t err; @@ -65,7 +59,7 @@ void drop_bad_packets(TCPSocket &sock, int orig_timeout) static void _ifup() { - net = NetworkInterface::get_default_instance(); + NetworkInterface *net = NetworkInterface::get_default_instance(); nsapi_error_t err = net->connect(); TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, err); printf("MBED: TCPClient IP address is '%s'\n", net->get_ip_address()); @@ -73,38 +67,42 @@ static void _ifup() static void _ifdown() { - net->disconnect(); + NetworkInterface::get_default_instance()->disconnect(); printf("MBED: ifdown\n"); } +nsapi_error_t tcpsocket_connect_to_srv(TCPSocket &sock, uint16_t port) +{ + SocketAddress tcp_addr; + + NetworkInterface::get_default_instance()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &tcp_addr); + tcp_addr.set_port(port); + + printf("MBED: Server '%s', port %d\n", tcp_addr.get_ip_address(), tcp_addr.get_port()); + + nsapi_error_t err = sock.open(NetworkInterface::get_default_instance()); + if (err != NSAPI_ERROR_OK) { + printf("Error from sock.open: %d\n", err); + return err; + } + + err = sock.connect(tcp_addr); + if (err != NSAPI_ERROR_OK) { + printf("Error from sock.connect: %d\n", err); + return err; + } + + return NSAPI_ERROR_OK; +} + 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); - - nsapi_error_t err = sock.open(get_interface()); - if (err != NSAPI_ERROR_OK) { - return err; - } - - return sock.connect(tcp_addr); + return tcpsocket_connect_to_srv(sock, MBED_CONF_APP_ECHO_SERVER_PORT); } 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); - - nsapi_error_t err = sock.open(get_interface()); - if (err != NSAPI_ERROR_OK) { - return err; - } - - return sock.connect(tcp_addr); + return tcpsocket_connect_to_srv(sock, MBED_CONF_APP_ECHO_SERVER_DISCARD_PORT); } void fill_tx_buffer_ascii(char *buff, size_t len) diff --git a/TESTS/netsocket/tcp/tcpsocket_bind_address.cpp b/TESTS/netsocket/tcp/tcpsocket_bind_address.cpp index a606c54c61..93aa82ce06 100644 --- a/TESTS/netsocket/tcp/tcpsocket_bind_address.cpp +++ b/TESTS/netsocket/tcp/tcpsocket_bind_address.cpp @@ -36,9 +36,10 @@ void TCPSOCKET_BIND_ADDRESS() TCPSocket *sock = new TCPSocket; if (!sock) { TEST_FAIL(); + return; } - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(get_interface())); - SocketAddress sockAddr = SocketAddress(get_interface()->get_ip_address(), 80); + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(NetworkInterface::get_default_instance())); + SocketAddress sockAddr = SocketAddress(NetworkInterface::get_default_instance()->get_ip_address(), 80); nsapi_error_t bind_result = sock->bind(sockAddr); if (bind_result == NSAPI_ERROR_UNSUPPORTED) { TEST_IGNORE_MESSAGE("bind() not supported"); diff --git a/TESTS/netsocket/tcp/tcpsocket_bind_address_invalid.cpp b/TESTS/netsocket/tcp/tcpsocket_bind_address_invalid.cpp index 77c5ca73f2..4e0c568ce7 100644 --- a/TESTS/netsocket/tcp/tcpsocket_bind_address_invalid.cpp +++ b/TESTS/netsocket/tcp/tcpsocket_bind_address_invalid.cpp @@ -36,8 +36,9 @@ void TCPSOCKET_BIND_ADDRESS_INVALID() TCPSocket *sock = new TCPSocket; if (!sock) { TEST_FAIL(); + return; } - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(get_interface())); + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(NetworkInterface::get_default_instance())); nsapi_error_t bind_result = sock->bind("190.2.3.4", 1024); if (bind_result == NSAPI_ERROR_UNSUPPORTED) { TEST_IGNORE_MESSAGE("bind() not supported"); diff --git a/TESTS/netsocket/tcp/tcpsocket_bind_address_null.cpp b/TESTS/netsocket/tcp/tcpsocket_bind_address_null.cpp index e838e2792d..d5a43cb3c5 100644 --- a/TESTS/netsocket/tcp/tcpsocket_bind_address_null.cpp +++ b/TESTS/netsocket/tcp/tcpsocket_bind_address_null.cpp @@ -36,8 +36,9 @@ void TCPSOCKET_BIND_ADDRESS_NULL() TCPSocket *sock = new TCPSocket; if (!sock) { TEST_FAIL(); + return; } - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(get_interface())); + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(NetworkInterface::get_default_instance())); nsapi_error_t bind_result = sock->bind(NULL, 1024); if (bind_result == NSAPI_ERROR_UNSUPPORTED) { TEST_IGNORE_MESSAGE("bind() not supported"); diff --git a/TESTS/netsocket/tcp/tcpsocket_bind_address_port.cpp b/TESTS/netsocket/tcp/tcpsocket_bind_address_port.cpp index ee60fc0caf..29fdaa3372 100644 --- a/TESTS/netsocket/tcp/tcpsocket_bind_address_port.cpp +++ b/TESTS/netsocket/tcp/tcpsocket_bind_address_port.cpp @@ -36,9 +36,10 @@ void TCPSOCKET_BIND_ADDRESS_PORT() TCPSocket *sock = new TCPSocket; if (!sock) { TEST_FAIL(); + return; } - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(get_interface())); - nsapi_error_t bind_result = sock->bind(get_interface()->get_ip_address(), 80); + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(NetworkInterface::get_default_instance())); + nsapi_error_t bind_result = sock->bind(NetworkInterface::get_default_instance()->get_ip_address(), 80); if (bind_result == NSAPI_ERROR_UNSUPPORTED) { TEST_IGNORE_MESSAGE("bind() not supported"); } else { diff --git a/TESTS/netsocket/tcp/tcpsocket_bind_port.cpp b/TESTS/netsocket/tcp/tcpsocket_bind_port.cpp index 4fd75370de..f7601be695 100644 --- a/TESTS/netsocket/tcp/tcpsocket_bind_port.cpp +++ b/TESTS/netsocket/tcp/tcpsocket_bind_port.cpp @@ -36,8 +36,9 @@ void TCPSOCKET_BIND_PORT() TCPSocket *sock = new TCPSocket; if (!sock) { TEST_FAIL(); + return; } - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(get_interface())); + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(NetworkInterface::get_default_instance())); nsapi_error_t bind_result = sock->bind(1024); if (bind_result == NSAPI_ERROR_UNSUPPORTED) { TEST_IGNORE_MESSAGE("bind() not supported"); diff --git a/TESTS/netsocket/tcp/tcpsocket_bind_port_fail.cpp b/TESTS/netsocket/tcp/tcpsocket_bind_port_fail.cpp index 2fd8beb312..dd4326cccd 100644 --- a/TESTS/netsocket/tcp/tcpsocket_bind_port_fail.cpp +++ b/TESTS/netsocket/tcp/tcpsocket_bind_port_fail.cpp @@ -36,8 +36,9 @@ void TCPSOCKET_BIND_PORT_FAIL() TCPSocket *sock = new TCPSocket; if (!sock) { TEST_FAIL(); + return; } - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(get_interface())); + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(NetworkInterface::get_default_instance())); nsapi_error_t bind_result = sock->bind(1024); if (bind_result == NSAPI_ERROR_UNSUPPORTED) { TEST_IGNORE_MESSAGE("bind() not supported"); @@ -51,7 +52,7 @@ void TCPSOCKET_BIND_PORT_FAIL() if (!sock2) { TEST_FAIL(); } - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock2->open(get_interface())); + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock2->open(NetworkInterface::get_default_instance())); TEST_ASSERT_EQUAL(NSAPI_ERROR_PARAMETER, sock2->bind(1024)); delete sock; diff --git a/TESTS/netsocket/tcp/tcpsocket_bind_unopened.cpp b/TESTS/netsocket/tcp/tcpsocket_bind_unopened.cpp index daa66adff5..6b992dd4b3 100644 --- a/TESTS/netsocket/tcp/tcpsocket_bind_unopened.cpp +++ b/TESTS/netsocket/tcp/tcpsocket_bind_unopened.cpp @@ -36,6 +36,7 @@ void TCPSOCKET_BIND_UNOPENED() TCPSocket *sock = new TCPSocket; if (!sock) { TEST_FAIL(); + return; } nsapi_error_t bind_result = sock->bind(1024); if (bind_result == NSAPI_ERROR_UNSUPPORTED) { diff --git a/TESTS/netsocket/tcp/tcpsocket_bind_wrong_type.cpp b/TESTS/netsocket/tcp/tcpsocket_bind_wrong_type.cpp index 11b172255d..be223b0f2c 100644 --- a/TESTS/netsocket/tcp/tcpsocket_bind_wrong_type.cpp +++ b/TESTS/netsocket/tcp/tcpsocket_bind_wrong_type.cpp @@ -36,8 +36,9 @@ void TCPSOCKET_BIND_WRONG_TYPE() TCPSocket *sock = new TCPSocket; if (!sock) { TEST_FAIL(); + return; } - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(get_interface())); + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(NetworkInterface::get_default_instance())); char addr_bytes[16] = {0xfe, 0x80, 0xff, 0x1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; SocketAddress sockAddr = SocketAddress(addr_bytes, NSAPI_IPv4, 80); nsapi_error_t bind_result = sock->bind(sockAddr); diff --git a/TESTS/netsocket/tcp/tcpsocket_connect_invalid.cpp b/TESTS/netsocket/tcp/tcpsocket_connect_invalid.cpp index aa77cbc4a8..a7cf0a5156 100644 --- a/TESTS/netsocket/tcp/tcpsocket_connect_invalid.cpp +++ b/TESTS/netsocket/tcp/tcpsocket_connect_invalid.cpp @@ -27,7 +27,7 @@ using namespace utest::v1; void TCPSOCKET_CONNECT_INVALID() { TCPSocket sock; - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(get_interface())); + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(NetworkInterface::get_default_instance())); TEST_ASSERT(sock.connect(NULL, 9) < 0); TEST_ASSERT(sock.connect("", 9) < 0); diff --git a/TESTS/netsocket/tcp/tcpsocket_echotest.cpp b/TESTS/netsocket/tcp/tcpsocket_echotest.cpp index 782619f1bd..bb5d5e714d 100644 --- a/TESTS/netsocket/tcp/tcpsocket_echotest.cpp +++ b/TESTS/netsocket/tcp/tcpsocket_echotest.cpp @@ -36,14 +36,25 @@ static const int pkt_sizes[PKTS] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, \ }; TCPSocket sock; Semaphore tx_sem(0, 1); +events::EventQueue *event_queue; +int bytes2recv; +int bytes2recv_total; Timer tc_exec_time; int time_allotted; +bool receive_error; } +void tcpsocket_echotest_nonblock_receive(); + static void _sigio_handler(osThreadId id) { osSignalSet(id, SIGNAL_SIGIO); + if (event_queue != NULL) { + event_queue->call(tcpsocket_echotest_nonblock_receive); + } else { + TEST_FAIL_MESSAGE("_sigio_handler running when event_queue is NULL"); + } } void TCPSOCKET_ECHOTEST() @@ -83,33 +94,31 @@ void TCPSOCKET_ECHOTEST() TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close()); } -void tcpsocket_echotest_nonblock_receiver(void *receive_bytes) +void tcpsocket_echotest_nonblock_receive() { - int bytes2recv = *(int *)receive_bytes; - int recvd; - while (bytes2recv) { - recvd = sock.recv(&(tcp_global::rx_buffer[*(int *)receive_bytes - bytes2recv]), bytes2recv); - if (recvd == NSAPI_ERROR_WOULD_BLOCK) { - if (tc_exec_time.read() >= time_allotted) { - TEST_FAIL(); - break; - } - wait(1); - continue; - } else if (recvd < 0) { - TEST_FAIL(); - break; + int recvd = sock.recv(&(tcp_global::rx_buffer[bytes2recv_total - bytes2recv]), bytes2recv); + if (recvd == NSAPI_ERROR_WOULD_BLOCK) { + if (tc_exec_time.read() >= time_allotted) { + receive_error = true; } + return; + } else if (recvd < 0) { + receive_error = true; + } else { bytes2recv -= recvd; } - 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); - - tx_sem.release(); + if (bytes2recv == 0) { + TEST_ASSERT_EQUAL(0, memcmp(tcp_global::tx_buffer, tcp_global::rx_buffer, bytes2recv_total)); + static int round = 0; + printf("[Recevr#%02d] bytes received: %d\n", round++, bytes2recv_total); + tx_sem.release(); + } else if (receive_error || bytes2recv < 0) { + TEST_FAIL(); + tx_sem.release(); + } + // else - no error, not all bytes were received yet. } void TCPSOCKET_ECHOTEST_NONBLOCK() @@ -124,6 +133,9 @@ void TCPSOCKET_ECHOTEST_NONBLOCK() tc_exec_time.start(); time_allotted = split2half_rmng_tcp_test_time(); // [s] + EventQueue queue(2 * EVENTS_EVENT_SIZE); + event_queue = &queue; + tcpsocket_connect_to_echo_srv(sock); sock.set_blocking(false); sock.sigio(callback(_sigio_handler, ThisThread::get_id())); @@ -131,17 +143,20 @@ void TCPSOCKET_ECHOTEST_NONBLOCK() int bytes2send; int sent; int s_idx = 0; - Thread *thread; + receive_error = false; unsigned char *stack_mem = (unsigned char *)malloc(tcp_global::TCP_OS_STACK_SIZE); TEST_ASSERT_NOT_NULL(stack_mem); + Thread *receiver_thread = new Thread(osPriorityNormal, + tcp_global::TCP_OS_STACK_SIZE, + stack_mem, + "receiver"); + + TEST_ASSERT_EQUAL(osOK, receiver_thread->start(callback(&queue, &EventQueue::dispatch_forever))); for (int pkt_s = pkt_sizes[s_idx]; s_idx < PKTS; ++s_idx) { pkt_s = pkt_sizes[s_idx]; - thread = new Thread(osPriorityNormal, - tcp_global::TCP_OS_STACK_SIZE, - stack_mem, - "receiver"); - TEST_ASSERT_EQUAL(osOK, thread->start(callback(tcpsocket_echotest_nonblock_receiver, &pkt_s))); + bytes2recv = pkt_s; + bytes2recv_total = pkt_s; fill_tx_buffer_ascii(tcp_global::tx_buffer, pkt_s); @@ -151,16 +166,12 @@ void TCPSOCKET_ECHOTEST_NONBLOCK() if (sent == NSAPI_ERROR_WOULD_BLOCK) { 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; } @@ -176,12 +187,17 @@ void TCPSOCKET_ECHOTEST_NONBLOCK() } TEST_ASSERT_EQUAL(bytes2send, tcp_stats[j].sent_bytes); #endif - tx_sem.wait(split2half_rmng_tcp_test_time()); - thread->join(); - delete thread; + tx_sem.wait(split2half_rmng_tcp_test_time() * 1000); // *1000 to convert s->ms + if (receive_error) { + break; + } } END: + sock.sigio(NULL); + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close()); + receiver_thread->terminate(); + delete receiver_thread; + receiver_thread = NULL; 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 fa86fa63a3..08910cd94c 100644 --- a/TESTS/netsocket/tcp/tcpsocket_echotest_burst.cpp +++ b/TESTS/netsocket/tcp/tcpsocket_echotest_burst.cpp @@ -78,8 +78,7 @@ void TCPSOCKET_ECHOTEST_BURST() } if (bt_left != 0) { - drop_bad_packets(sock, 0); - TEST_FAIL(); + TEST_FAIL_MESSAGE("bt_left != 0"); goto END; } @@ -142,7 +141,6 @@ void TCPSOCKET_ECHOTEST_BURST_NONBLOCK() if (bt_left != 0) { printf("network error %d, missing %d bytes from a burst\n", recvd, bt_left); - drop_bad_packets(sock, -1); TEST_FAIL(); goto END; } diff --git a/TESTS/netsocket/tcp/tcpsocket_endpoint_close.cpp b/TESTS/netsocket/tcp/tcpsocket_endpoint_close.cpp index 88e40f699a..436c4bf281 100644 --- a/TESTS/netsocket/tcp/tcpsocket_endpoint_close.cpp +++ b/TESTS/netsocket/tcp/tcpsocket_endpoint_close.cpp @@ -38,10 +38,10 @@ 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); + NetworkInterface::get_default_instance()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &tcp_addr); tcp_addr.set_port(13); - nsapi_error_t err = sock.open(get_interface()); + nsapi_error_t err = sock.open(NetworkInterface::get_default_instance()); if (err != NSAPI_ERROR_OK) { return err; } diff --git a/TESTS/netsocket/tcp/tcpsocket_open_close_repeat.cpp b/TESTS/netsocket/tcp/tcpsocket_open_close_repeat.cpp index 2e3c382958..4bb303dc34 100644 --- a/TESTS/netsocket/tcp/tcpsocket_open_close_repeat.cpp +++ b/TESTS/netsocket/tcp/tcpsocket_open_close_repeat.cpp @@ -38,7 +38,7 @@ void TCPSOCKET_OPEN_CLOSE_REPEAT() } for (int i = 0; i < 2; i++) { - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(get_interface())); + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(NetworkInterface::get_default_instance())); TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->close()); } delete sock; diff --git a/TESTS/netsocket/tcp/tcpsocket_open_destruct.cpp b/TESTS/netsocket/tcp/tcpsocket_open_destruct.cpp index d82c4ac9cc..7733003377 100644 --- a/TESTS/netsocket/tcp/tcpsocket_open_destruct.cpp +++ b/TESTS/netsocket/tcp/tcpsocket_open_destruct.cpp @@ -38,7 +38,7 @@ void TCPSOCKET_OPEN_DESTRUCT() if (!sock) { TEST_FAIL(); } - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(get_interface())); + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(NetworkInterface::get_default_instance())); delete sock; } #if MBED_CONF_NSAPI_SOCKET_STATS_ENABLE diff --git a/TESTS/netsocket/tcp/tcpsocket_open_limit.cpp b/TESTS/netsocket/tcp/tcpsocket_open_limit.cpp index 0da94bec2c..4ebe4bdf8f 100644 --- a/TESTS/netsocket/tcp/tcpsocket_open_limit.cpp +++ b/TESTS/netsocket/tcp/tcpsocket_open_limit.cpp @@ -46,7 +46,7 @@ void TCPSOCKET_OPEN_LIMIT() if (!sock) { break; } - ret = sock->open(get_interface()); + ret = sock->open(NetworkInterface::get_default_instance()); if (ret == NSAPI_ERROR_NO_MEMORY || ret == NSAPI_ERROR_NO_SOCKET) { printf("[round#%02d] unable to open new socket, error: %d\n", i, ret); delete sock; diff --git a/TESTS/netsocket/tcp/tcpsocket_open_twice.cpp b/TESTS/netsocket/tcp/tcpsocket_open_twice.cpp index 4edb4f3209..278a290e28 100644 --- a/TESTS/netsocket/tcp/tcpsocket_open_twice.cpp +++ b/TESTS/netsocket/tcp/tcpsocket_open_twice.cpp @@ -37,8 +37,8 @@ void TCPSOCKET_OPEN_TWICE() TEST_FAIL(); } - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(get_interface())); - TEST_ASSERT_EQUAL(NSAPI_ERROR_PARAMETER, sock->open(get_interface())); + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(NetworkInterface::get_default_instance())); + TEST_ASSERT_EQUAL(NSAPI_ERROR_PARAMETER, sock->open(NetworkInterface::get_default_instance())); delete sock; #if MBED_CONF_NSAPI_SOCKET_STATS_ENABLE diff --git a/TESTS/netsocket/tcp/tcpsocket_recv_100k.cpp b/TESTS/netsocket/tcp/tcpsocket_recv_100k.cpp index a7b723cb36..d8fb3ed3ad 100644 --- a/TESTS/netsocket/tcp/tcpsocket_recv_100k.cpp +++ b/TESTS/netsocket/tcp/tcpsocket_recv_100k.cpp @@ -33,10 +33,10 @@ 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); + NetworkInterface::get_default_instance()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &tcp_addr); tcp_addr.set_port(19); - nsapi_error_t err = sock.open(get_interface()); + nsapi_error_t err = sock.open(NetworkInterface::get_default_instance()); if (err != NSAPI_ERROR_OK) { return err; } diff --git a/TESTS/netsocket/tcp/tcpsocket_setsockopt_keepalive_valid.cpp b/TESTS/netsocket/tcp/tcpsocket_setsockopt_keepalive_valid.cpp index 62ceaa315d..3d018530a5 100644 --- a/TESTS/netsocket/tcp/tcpsocket_setsockopt_keepalive_valid.cpp +++ b/TESTS/netsocket/tcp/tcpsocket_setsockopt_keepalive_valid.cpp @@ -27,9 +27,18 @@ using namespace utest::v1; void TCPSOCKET_SETSOCKOPT_KEEPALIVE_VALID() { TCPSocket sock; - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(get_interface())); + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(NetworkInterface::get_default_instance())); int32_t seconds = 7200; - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.setsockopt(NSAPI_SOCKET, NSAPI_KEEPALIVE, &seconds, sizeof(int))); + + int ret = sock.setsockopt(NSAPI_SOCKET, NSAPI_KEEPALIVE, &seconds, sizeof(int)); + + if (ret == NSAPI_ERROR_UNSUPPORTED) { + TEST_IGNORE_MESSAGE("NSAPI_KEEPALIVE option not supported"); + sock.close(); + return; + } + + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, ret); TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.connect(MBED_CONF_APP_ECHO_SERVER_ADDR, 9)); // LWIP stack does not support getsockopt so the part below is commented out // int32_t optval; diff --git a/TESTS/netsocket/udp/main.cpp b/TESTS/netsocket/udp/main.cpp index 18471f7ef9..14fac54a56 100644 --- a/TESTS/netsocket/udp/main.cpp +++ b/TESTS/netsocket/udp/main.cpp @@ -33,22 +33,13 @@ using namespace utest::v1; -namespace { -NetworkInterface *net; -} - #if MBED_CONF_NSAPI_SOCKET_STATS_ENABLE mbed_stats_socket_t udp_stats[MBED_CONF_NSAPI_SOCKET_STATS_MAX_COUNT]; #endif -NetworkInterface *get_interface() -{ - return net; -} - static void _ifup() { - net = NetworkInterface::get_default_instance(); + NetworkInterface *net = NetworkInterface::get_default_instance(); nsapi_error_t err = net->connect(); TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, err); printf("MBED: UDPClient IP address is '%s'\n", net->get_ip_address()); @@ -56,7 +47,7 @@ static void _ifup() static void _ifdown() { - net->disconnect(); + NetworkInterface::get_default_instance()->disconnect(); printf("MBED: ifdown\n"); } diff --git a/TESTS/netsocket/udp/udpsocket_bind_address.cpp b/TESTS/netsocket/udp/udpsocket_bind_address.cpp index 2405e8c918..2f8ce54243 100644 --- a/TESTS/netsocket/udp/udpsocket_bind_address.cpp +++ b/TESTS/netsocket/udp/udpsocket_bind_address.cpp @@ -37,8 +37,8 @@ void UDPSOCKET_BIND_ADDRESS() if (!sock) { TEST_FAIL(); } - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(get_interface())); - SocketAddress sockAddr = SocketAddress(get_interface()->get_ip_address(), 80); + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(NetworkInterface::get_default_instance())); + SocketAddress sockAddr = SocketAddress(NetworkInterface::get_default_instance()->get_ip_address(), 80); nsapi_error_t bind_result = sock->bind(sockAddr); if (bind_result == NSAPI_ERROR_UNSUPPORTED) { TEST_IGNORE_MESSAGE("bind() not supported"); diff --git a/TESTS/netsocket/udp/udpsocket_bind_address_invalid.cpp b/TESTS/netsocket/udp/udpsocket_bind_address_invalid.cpp index 49ad3eb32d..e0cee8a360 100644 --- a/TESTS/netsocket/udp/udpsocket_bind_address_invalid.cpp +++ b/TESTS/netsocket/udp/udpsocket_bind_address_invalid.cpp @@ -37,7 +37,7 @@ void UDPSOCKET_BIND_ADDRESS_INVALID() if (!sock) { TEST_FAIL(); } - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(get_interface())); + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(NetworkInterface::get_default_instance())); nsapi_error_t bind_result = sock->bind("190.2.3.4", 1024); if (bind_result == NSAPI_ERROR_UNSUPPORTED) { TEST_IGNORE_MESSAGE("bind() not supported"); diff --git a/TESTS/netsocket/udp/udpsocket_bind_address_null.cpp b/TESTS/netsocket/udp/udpsocket_bind_address_null.cpp index ee8616bce4..44bf9333e2 100644 --- a/TESTS/netsocket/udp/udpsocket_bind_address_null.cpp +++ b/TESTS/netsocket/udp/udpsocket_bind_address_null.cpp @@ -37,7 +37,7 @@ void UDPSOCKET_BIND_ADDRESS_NULL() if (!sock) { TEST_FAIL(); } - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(get_interface())); + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(NetworkInterface::get_default_instance())); nsapi_error_t bind_result = sock->bind(NULL, 1024); if (bind_result == NSAPI_ERROR_UNSUPPORTED) { TEST_IGNORE_MESSAGE("bind() not supported"); diff --git a/TESTS/netsocket/udp/udpsocket_bind_address_port.cpp b/TESTS/netsocket/udp/udpsocket_bind_address_port.cpp index 503be63de5..13bd3bdee6 100644 --- a/TESTS/netsocket/udp/udpsocket_bind_address_port.cpp +++ b/TESTS/netsocket/udp/udpsocket_bind_address_port.cpp @@ -37,8 +37,8 @@ void UDPSOCKET_BIND_ADDRESS_PORT() if (!sock) { TEST_FAIL(); } - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(get_interface())); - nsapi_error_t bind_result = sock->bind(get_interface()->get_ip_address(), 80); + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(NetworkInterface::get_default_instance())); + nsapi_error_t bind_result = sock->bind(NetworkInterface::get_default_instance()->get_ip_address(), 80); if (bind_result == NSAPI_ERROR_UNSUPPORTED) { TEST_IGNORE_MESSAGE("bind() not supported"); } else { diff --git a/TESTS/netsocket/udp/udpsocket_bind_port.cpp b/TESTS/netsocket/udp/udpsocket_bind_port.cpp index 54290ec0dc..f825b42e03 100644 --- a/TESTS/netsocket/udp/udpsocket_bind_port.cpp +++ b/TESTS/netsocket/udp/udpsocket_bind_port.cpp @@ -37,7 +37,7 @@ void UDPSOCKET_BIND_PORT() if (!sock) { TEST_FAIL(); } - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(get_interface())); + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(NetworkInterface::get_default_instance())); nsapi_error_t bind_result = sock->bind(1024); if (bind_result == NSAPI_ERROR_UNSUPPORTED) { TEST_IGNORE_MESSAGE("bind() not supported"); diff --git a/TESTS/netsocket/udp/udpsocket_bind_port_fail.cpp b/TESTS/netsocket/udp/udpsocket_bind_port_fail.cpp index e39d3b26b2..95a17bf346 100644 --- a/TESTS/netsocket/udp/udpsocket_bind_port_fail.cpp +++ b/TESTS/netsocket/udp/udpsocket_bind_port_fail.cpp @@ -37,7 +37,7 @@ void UDPSOCKET_BIND_PORT_FAIL() if (!sock) { TEST_FAIL(); } - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(get_interface())); + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(NetworkInterface::get_default_instance())); nsapi_error_t bind_result = sock->bind(1024); if (bind_result == NSAPI_ERROR_UNSUPPORTED) { TEST_IGNORE_MESSAGE("bind() not supported"); @@ -51,7 +51,7 @@ void UDPSOCKET_BIND_PORT_FAIL() if (!sock2) { TEST_FAIL(); } - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock2->open(get_interface())); + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock2->open(NetworkInterface::get_default_instance())); TEST_ASSERT_EQUAL(NSAPI_ERROR_PARAMETER, sock2->bind(1024)); delete sock; diff --git a/TESTS/netsocket/udp/udpsocket_bind_wrong_type.cpp b/TESTS/netsocket/udp/udpsocket_bind_wrong_type.cpp index 9a27c1f410..5925af6254 100644 --- a/TESTS/netsocket/udp/udpsocket_bind_wrong_type.cpp +++ b/TESTS/netsocket/udp/udpsocket_bind_wrong_type.cpp @@ -37,7 +37,7 @@ void UDPSOCKET_BIND_WRONG_TYPE() if (!sock) { TEST_FAIL(); } - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(get_interface())); + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(NetworkInterface::get_default_instance())); char addr_bytes[16] = {0xfe, 0x80, 0xff, 0x1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; SocketAddress sockAddr = SocketAddress(addr_bytes, NSAPI_IPv4, 80); nsapi_error_t bind_result = sock->bind(sockAddr); diff --git a/TESTS/netsocket/udp/udpsocket_echotest.cpp b/TESTS/netsocket/udp/udpsocket_echotest.cpp index 09b27254e6..ffd3dc75e7 100644 --- a/TESTS/netsocket/udp/udpsocket_echotest.cpp +++ b/TESTS/netsocket/udp/udpsocket_echotest.cpp @@ -55,11 +55,11 @@ static void _sigio_handler(osThreadId id) void UDPSOCKET_ECHOTEST() { SocketAddress udp_addr; - get_interface()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &udp_addr); + NetworkInterface::get_default_instance()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &udp_addr); udp_addr.set_port(MBED_CONF_APP_ECHO_SERVER_PORT); UDPSocket sock; - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(get_interface())); + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(NetworkInterface::get_default_instance())); int recvd; int sent; @@ -109,6 +109,10 @@ void udpsocket_echotest_nonblock_receiver(void *receive_bytes) wait_ms(WAIT2RECV_TIMEOUT); --retry_cnt; continue; + } else if (recvd < 0) { + printf("sock.recvfrom returned %d\n", recvd); + TEST_FAIL(); + break; } else if (recvd == expt2recv) { break; } @@ -130,10 +134,10 @@ void UDPSOCKET_ECHOTEST_NONBLOCK() #endif SocketAddress udp_addr; - get_interface()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &udp_addr); + NetworkInterface::get_default_instance()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &udp_addr); udp_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.open(NetworkInterface::get_default_instance())); sock.set_blocking(false); sock.sigio(callback(_sigio_handler, ThisThread::get_id())); diff --git a/TESTS/netsocket/udp/udpsocket_echotest_burst.cpp b/TESTS/netsocket/udp/udpsocket_echotest_burst.cpp index d2e6a1ce23..209f9597b3 100644 --- a/TESTS/netsocket/udp/udpsocket_echotest_burst.cpp +++ b/TESTS/netsocket/udp/udpsocket_echotest_burst.cpp @@ -71,12 +71,12 @@ static void _sigio_handler(osThreadId id) void UDPSOCKET_ECHOTEST_BURST() { SocketAddress udp_addr; - get_interface()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &udp_addr); + NetworkInterface::get_default_instance()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &udp_addr); udp_addr.set_port(MBED_CONF_APP_ECHO_SERVER_PORT); UDPSocket sock; const int TIMEOUT = 5000; // [ms] - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(get_interface())); + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(NetworkInterface::get_default_instance())); sock.set_timeout(TIMEOUT); sock.sigio(callback(_sigio_handler, ThisThread::get_id())); @@ -150,11 +150,11 @@ void UDPSOCKET_ECHOTEST_BURST() void UDPSOCKET_ECHOTEST_BURST_NONBLOCK() { SocketAddress udp_addr; - get_interface()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &udp_addr); + NetworkInterface::get_default_instance()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &udp_addr); udp_addr.set_port(MBED_CONF_APP_ECHO_SERVER_PORT); UDPSocket sock; - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(get_interface())); + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(NetworkInterface::get_default_instance())); sock.set_blocking(false); sock.sigio(callback(_sigio_handler, ThisThread::get_id())); diff --git a/TESTS/netsocket/udp/udpsocket_open_close_repeat.cpp b/TESTS/netsocket/udp/udpsocket_open_close_repeat.cpp index 510eb200da..e118990cf4 100644 --- a/TESTS/netsocket/udp/udpsocket_open_close_repeat.cpp +++ b/TESTS/netsocket/udp/udpsocket_open_close_repeat.cpp @@ -38,7 +38,7 @@ void UDPSOCKET_OPEN_CLOSE_REPEAT() } for (int i = 0; i < 2; i++) { - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(get_interface())); + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(NetworkInterface::get_default_instance())); TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->close()); } delete sock; diff --git a/TESTS/netsocket/udp/udpsocket_open_destruct.cpp b/TESTS/netsocket/udp/udpsocket_open_destruct.cpp index 7c79951d0d..3042a189e4 100644 --- a/TESTS/netsocket/udp/udpsocket_open_destruct.cpp +++ b/TESTS/netsocket/udp/udpsocket_open_destruct.cpp @@ -38,7 +38,7 @@ void UDPSOCKET_OPEN_DESTRUCT() if (!sock) { TEST_FAIL(); } - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(get_interface())); + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(NetworkInterface::get_default_instance())); delete sock; } #if MBED_CONF_NSAPI_SOCKET_STATS_ENABLE diff --git a/TESTS/netsocket/udp/udpsocket_open_limit.cpp b/TESTS/netsocket/udp/udpsocket_open_limit.cpp index 8a2b6becad..dfe35de305 100644 --- a/TESTS/netsocket/udp/udpsocket_open_limit.cpp +++ b/TESTS/netsocket/udp/udpsocket_open_limit.cpp @@ -47,7 +47,7 @@ void UDPSOCKET_OPEN_LIMIT() if (!sock) { break; } - ret = sock->open(get_interface()); + ret = sock->open(NetworkInterface::get_default_instance()); if (ret == NSAPI_ERROR_NO_MEMORY || ret == NSAPI_ERROR_NO_SOCKET) { printf("[round#%02d] unable to open new socket, error: %d\n", i, ret); delete sock; diff --git a/TESTS/netsocket/udp/udpsocket_open_twice.cpp b/TESTS/netsocket/udp/udpsocket_open_twice.cpp index fe8f6df95e..893450ca9d 100644 --- a/TESTS/netsocket/udp/udpsocket_open_twice.cpp +++ b/TESTS/netsocket/udp/udpsocket_open_twice.cpp @@ -37,8 +37,8 @@ void UDPSOCKET_OPEN_TWICE() TEST_FAIL(); } - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(get_interface())); - TEST_ASSERT_EQUAL(NSAPI_ERROR_PARAMETER, sock->open(get_interface())); + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->open(NetworkInterface::get_default_instance())); + TEST_ASSERT_EQUAL(NSAPI_ERROR_PARAMETER, sock->open(NetworkInterface::get_default_instance())); delete sock; #if MBED_CONF_NSAPI_SOCKET_STATS_ENABLE diff --git a/TESTS/netsocket/udp/udpsocket_recv_timeout.cpp b/TESTS/netsocket/udp/udpsocket_recv_timeout.cpp index 2d0d558742..3592d307ce 100644 --- a/TESTS/netsocket/udp/udpsocket_recv_timeout.cpp +++ b/TESTS/netsocket/udp/udpsocket_recv_timeout.cpp @@ -37,14 +37,14 @@ static void _sigio_handler(osThreadId id) void UDPSOCKET_RECV_TIMEOUT() { SocketAddress udp_addr; - get_interface()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &udp_addr); + NetworkInterface::get_default_instance()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &udp_addr); udp_addr.set_port(MBED_CONF_APP_ECHO_SERVER_PORT); static const int DATA_LEN = 100; char buff[DATA_LEN] = {0}; UDPSocket sock; - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(get_interface())); + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(NetworkInterface::get_default_instance())); sock.set_timeout(100); sock.sigio(callback(_sigio_handler, ThisThread::get_id())); diff --git a/TESTS/netsocket/udp/udpsocket_sendto_invalid.cpp b/TESTS/netsocket/udp/udpsocket_sendto_invalid.cpp index 26ae88bda8..6b16c28a15 100644 --- a/TESTS/netsocket/udp/udpsocket_sendto_invalid.cpp +++ b/TESTS/netsocket/udp/udpsocket_sendto_invalid.cpp @@ -27,7 +27,7 @@ using namespace utest::v1; void UDPSOCKET_SENDTO_INVALID() { UDPSocket sock; - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(get_interface())); + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(NetworkInterface::get_default_instance())); TEST_ASSERT(sock.sendto(NULL, 9, NULL, 0) < 0); TEST_ASSERT(sock.sendto("", 9, NULL, 0) < 0); diff --git a/TESTS/netsocket/udp/udpsocket_sendto_repeat.cpp b/TESTS/netsocket/udp/udpsocket_sendto_repeat.cpp index fdef245292..249d9661b2 100644 --- a/TESTS/netsocket/udp/udpsocket_sendto_repeat.cpp +++ b/TESTS/netsocket/udp/udpsocket_sendto_repeat.cpp @@ -27,10 +27,10 @@ using namespace utest::v1; void UDPSOCKET_SENDTO_REPEAT() { UDPSocket sock; - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(get_interface())); + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(NetworkInterface::get_default_instance())); SocketAddress udp_addr; - get_interface()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &udp_addr); + NetworkInterface::get_default_instance()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &udp_addr); udp_addr.set_port(9); int sent; diff --git a/TESTS/netsocket/udp/udpsocket_sendto_timeout.cpp b/TESTS/netsocket/udp/udpsocket_sendto_timeout.cpp index 5fdcb39af7..d229cf7837 100644 --- a/TESTS/netsocket/udp/udpsocket_sendto_timeout.cpp +++ b/TESTS/netsocket/udp/udpsocket_sendto_timeout.cpp @@ -30,10 +30,10 @@ void UDPSOCKET_SENDTO_TIMEOUT() fill_tx_buffer_ascii(tx_buffer, sizeof(tx_buffer)); UDPSocket sock; - TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(get_interface())); + TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(NetworkInterface::get_default_instance())); SocketAddress udp_addr; - get_interface()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &udp_addr); + NetworkInterface::get_default_instance()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &udp_addr); udp_addr.set_port(9); Timer timer; @@ -43,12 +43,14 @@ void UDPSOCKET_SENDTO_TIMEOUT() TEST_ASSERT_EQUAL(sizeof(tx_buffer), sent); TEST_ASSERT(timer.read_ms() <= 100); + sock.set_timeout(1000); + timer.reset(); timer.start(); sent = sock.sendto(udp_addr, tx_buffer, sizeof(tx_buffer)); timer.stop(); TEST_ASSERT_EQUAL(sizeof(tx_buffer), sent); - TEST_ASSERT(timer.read_ms() <= 100); + TEST_ASSERT(timer.read_ms() <= 1000); printf("MBED: Time taken: %fs\n", timer.read()); TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close()); diff --git a/TEST_APPS/testcases/nanostack_mac_tester/ED_scan.py b/TEST_APPS/testcases/nanostack_mac_tester/ED_scan.py index 7ef6e435e1..11d034edfd 100644 --- a/TEST_APPS/testcases/nanostack_mac_tester/ED_scan.py +++ b/TEST_APPS/testcases/nanostack_mac_tester/ED_scan.py @@ -42,7 +42,7 @@ class Testcase(Bench): '*': { "count":3, "type": "hardware", - "allowed_platforms": ["K64F", "K66F", "NUCLEO_F429ZI", "KW24D", "UBLOX_EVK_ODIN_W2"], + "allowed_platforms": ["K64F", "K66F", "NUCLEO_F429ZI", "KW24D", "UBLOX_EVK_ODIN_W2", "KW41Z"], "application": { "name": "TEST_APPS-device-nanostack_mac_tester" } diff --git a/TEST_APPS/testcases/nanostack_mac_tester/address_read_and_write.py b/TEST_APPS/testcases/nanostack_mac_tester/address_read_and_write.py index ffda6107ab..d65100d228 100644 --- a/TEST_APPS/testcases/nanostack_mac_tester/address_read_and_write.py +++ b/TEST_APPS/testcases/nanostack_mac_tester/address_read_and_write.py @@ -41,7 +41,7 @@ class Testcase(Bench): '*': { "count":1, "type": "hardware", - "allowed_platforms": ["K64F", "K66F", "NUCLEO_F429ZI", "KW24D", "UBLOX_EVK_ODIN_W2"], + "allowed_platforms": ["K64F", "K66F", "NUCLEO_F429ZI", "KW24D", "UBLOX_EVK_ODIN_W2", "KW41Z"], "application": { "name": "TEST_APPS-device-nanostack_mac_tester" } diff --git a/TEST_APPS/testcases/nanostack_mac_tester/create_and_join_PAN.py b/TEST_APPS/testcases/nanostack_mac_tester/create_and_join_PAN.py index eb52328fbe..91a7f8b50d 100644 --- a/TEST_APPS/testcases/nanostack_mac_tester/create_and_join_PAN.py +++ b/TEST_APPS/testcases/nanostack_mac_tester/create_and_join_PAN.py @@ -41,7 +41,7 @@ class Testcase(Bench): '*': { "count":3, "type": "hardware", - "allowed_platforms": ["K64F", "K66F", "NUCLEO_F429ZI", "KW24D", "UBLOX_EVK_ODIN_W2"], + "allowed_platforms": ["K64F", "K66F", "NUCLEO_F429ZI", "KW24D", "UBLOX_EVK_ODIN_W2", "KW41Z"], "application": { "name": "TEST_APPS-device-nanostack_mac_tester" } diff --git a/TEST_APPS/testcases/nanostack_mac_tester/send_data.py b/TEST_APPS/testcases/nanostack_mac_tester/send_data.py index a2da5d0840..40db26069d 100644 --- a/TEST_APPS/testcases/nanostack_mac_tester/send_data.py +++ b/TEST_APPS/testcases/nanostack_mac_tester/send_data.py @@ -41,7 +41,7 @@ class Testcase(Bench): '*': { "count":2, "type": "hardware", - "allowed_platforms": ["K64F", "K66F", "NUCLEO_F429ZI", "KW24D", "UBLOX_EVK_ODIN_W2"], + "allowed_platforms": ["K64F", "K66F", "NUCLEO_F429ZI", "KW24D", "UBLOX_EVK_ODIN_W2", "KW41Z"], "application": { "name": "TEST_APPS-device-nanostack_mac_tester" } diff --git a/TEST_APPS/testcases/nanostack_mac_tester/send_data_indirect.py b/TEST_APPS/testcases/nanostack_mac_tester/send_data_indirect.py index 540c1365cf..709321da6d 100644 --- a/TEST_APPS/testcases/nanostack_mac_tester/send_data_indirect.py +++ b/TEST_APPS/testcases/nanostack_mac_tester/send_data_indirect.py @@ -41,7 +41,7 @@ class Testcase(Bench): '*': { "count":3, "type": "hardware", - "allowed_platforms": ["K64F", "K66F", "NUCLEO_F429ZI", "KW24D", "UBLOX_EVK_ODIN_W2"], + "allowed_platforms": ["K64F", "K66F", "NUCLEO_F429ZI", "KW24D", "UBLOX_EVK_ODIN_W2", "KW41Z"], "application": { "name": "TEST_APPS-device-nanostack_mac_tester" } diff --git a/TEST_APPS/testcases/nanostack_mac_tester/send_large_payloads.py b/TEST_APPS/testcases/nanostack_mac_tester/send_large_payloads.py index ee12489d38..f0fb4b87bf 100644 --- a/TEST_APPS/testcases/nanostack_mac_tester/send_large_payloads.py +++ b/TEST_APPS/testcases/nanostack_mac_tester/send_large_payloads.py @@ -41,7 +41,7 @@ class Testcase(Bench): '*': { "count":2, "type": "hardware", - "allowed_platforms": ["K64F", "K66F", "NUCLEO_F429ZI", "KW24D", "UBLOX_EVK_ODIN_W2"], + "allowed_platforms": ["K64F", "K66F", "NUCLEO_F429ZI", "KW24D", "UBLOX_EVK_ODIN_W2", "KW41Z"], "application": { "name": "TEST_APPS-device-nanostack_mac_tester" } diff --git a/UNITTESTS/README.md b/UNITTESTS/README.md index 69288cd74c..e250a1b8da 100644 --- a/UNITTESTS/README.md +++ b/UNITTESTS/README.md @@ -32,7 +32,7 @@ In a terminal window: sudo easy_install pip ``` -1. Install Gcovr and [Mbed CLI](https://os.mbed.com/docs/latest/tools/developing-arm-mbed-cli.html) with `pip install "gcovr>=4.1" mbed-cli`. +1. Install Gcovr and [Mbed CLI](https://os.mbed.com/docs/mbed-os/latest/tools/developing-mbed-cli.html) with `pip install "gcovr>=4.1" mbed-cli`. #### Installing dependencies on macOS @@ -48,7 +48,7 @@ In a terminal window: sudo easy_install pip ``` -1. Install Gcovr and [Mbed CLI](https://os.mbed.com/docs/latest/tools/developing-arm-mbed-cli.html) with `pip install "gcovr>=4.1" mbed-cli`. +1. Install Gcovr and [Mbed CLI](https://os.mbed.com/docs/mbed-os/latest/tools/developing-mbed-cli.html) with `pip install "gcovr>=4.1" mbed-cli`. 1. (Optional) Install GCC with `brew install gcc`. #### Installing dependencies on Windows @@ -59,7 +59,7 @@ In a terminal window: 1. Download CMake binaries from https://cmake.org/download/, and run the installer. 1. Download Python 2.7 or Python 3 from https://www.python.org/getit/, and run the installer. 1. Add MinGW, CMake and Python into system PATH. -1. Install Gcovr and [Mbed CLI](https://os.mbed.com/docs/latest/tools/developing-arm-mbed-cli.html) with `pip install "gcovr>=4.1" mbed-cli`. +1. Install Gcovr and [Mbed CLI](https://os.mbed.com/docs/mbed-os/latest/tools/developing-mbed-cli.html) with `pip install "gcovr>=4.1" mbed-cli`. ### Test code structure @@ -79,7 +79,7 @@ The build system automatically generates names of test suites. The name is const ### Unit testing with Mbed CLI -Mbed CLI supports unit tests through the `mbed test --unittests` command. For information on using Mbed CLI, please see the [CLI documentation](https://os.mbed.com/docs/latest/tools/developing-arm-mbed-cli.html). +Mbed CLI supports unit tests through the `mbed test --unittests` command. For information on using Mbed CLI, please see the [CLI documentation](https://os.mbed.com/docs/mbed-os/latest/tools/developing-mbed-cli.html). ### Writing unit tests diff --git a/components/storage/blockdevice/COMPONENT_QSPIF/QSPIFBlockDevice.cpp b/components/storage/blockdevice/COMPONENT_QSPIF/QSPIFBlockDevice.cpp index 30e80ee119..ae0ca070ed 100644 --- a/components/storage/blockdevice/COMPONENT_QSPIF/QSPIFBlockDevice.cpp +++ b/components/storage/blockdevice/COMPONENT_QSPIF/QSPIFBlockDevice.cpp @@ -29,8 +29,6 @@ using namespace mbed; /* Default QSPIF Parameters */ /****************************/ -#define QSPIF_DEFAULT_READ_SIZE 1 -#define QSPIF_DEFAULT_PROG_SIZE 1 #define QSPIF_DEFAULT_PAGE_SIZE 256 #define QSPIF_DEFAULT_SE_SIZE 4096 #define QSPI_MAX_STATUS_REGISTER_SIZE 3 @@ -95,6 +93,7 @@ enum qspif_default_instructions { QSPIF_RSTEN = 0x66, // Reset Enable QSPIF_RST = 0x99, // Reset QSPIF_RDID = 0x9f, // Read Manufacturer and JDEC Device ID + QSPIF_ULBPR = 0x98, // Clears all write-protection bits in the Block-Protection register }; // Local Function @@ -204,9 +203,9 @@ int QSPIFBlockDevice::init() switch (vendor_device_ids[0]) { case 0xbf: // SST devices come preset with block protection - // enabled for some regions, issue write disable instruction to clear + // enabled for some regions, issue global protection unlock to clear _set_write_enable(); - _qspi_send_general_command(QSPIF_WRDI, QSPI_NO_ADDRESS_COMMAND, NULL, 0, NULL, 0); + _qspi_send_general_command(QSPIF_ULBPR, QSPI_NO_ADDRESS_COMMAND, NULL, 0, NULL, 0); break; } @@ -461,14 +460,14 @@ exit_point: bd_size_t QSPIFBlockDevice::get_read_size() const { - // Assuming all devices support 1byte read granularity - return QSPIF_DEFAULT_READ_SIZE; + // Return minimum read size in bytes for the device + return MBED_CONF_QSPIF_QSPI_MIN_READ_SIZE; } bd_size_t QSPIFBlockDevice::get_program_size() const { - // Assuming all devices support 1byte program granularity - return QSPIF_DEFAULT_PROG_SIZE; + // Return minimum program/write size in bytes for the device + return MBED_CONF_QSPIF_QSPI_MIN_PROG_SIZE; } bd_size_t QSPIFBlockDevice::get_erase_size() const diff --git a/components/storage/blockdevice/COMPONENT_QSPIF/mbed_lib.json b/components/storage/blockdevice/COMPONENT_QSPIF/mbed_lib.json index dc49d3f462..683b216cc9 100644 --- a/components/storage/blockdevice/COMPONENT_QSPIF/mbed_lib.json +++ b/components/storage/blockdevice/COMPONENT_QSPIF/mbed_lib.json @@ -8,7 +8,9 @@ "QSPI_SCK": "QSPI_FLASH1_SCK", "QSPI_CSN": "QSPI_FLASH1_CSN", "QSPI_POLARITY_MODE": 0, - "QSPI_FREQ": "40000000" + "QSPI_FREQ": "40000000", + "QSPI_MIN_READ_SIZE": "1", + "QSPI_MIN_PROG_SIZE": "1" }, "target_overrides": { "DISCO_F413ZH": { @@ -32,8 +34,10 @@ "DISCO_F769NI": { "QSPI_FREQ": "8000000" }, - "NRF52840_DK": { - "QSPI_FREQ": "32000000" + "MCU_NRF52840": { + "QSPI_FREQ": "32000000", + "QSPI_MIN_READ_SIZE": "4", + "QSPI_MIN_PROG_SIZE": "4" } } } diff --git a/components/storage/blockdevice/COMPONENT_RSPIF/SPIFReducedBlockDevice.cpp b/components/storage/blockdevice/COMPONENT_RSPIF/SPIFReducedBlockDevice.cpp index fceb8af4fc..2092f58e1e 100644 --- a/components/storage/blockdevice/COMPONENT_RSPIF/SPIFReducedBlockDevice.cpp +++ b/components/storage/blockdevice/COMPONENT_RSPIF/SPIFReducedBlockDevice.cpp @@ -40,6 +40,7 @@ enum ops { SPIF_WRDI = 0x04, // Write Disable SPIF_RDSR = 0x05, // Read Status Register SPIF_RDID = 0x9f, // Read Manufacturer and JDEC Device ID + SPIF_ULBPR = 0x98, // Clears all write-protection bits in the Block-Protection register }; // Status register from RDSR @@ -66,9 +67,9 @@ int SPIFReducedBlockDevice::init() switch (id[0]) { case 0xbf: // SST devices come preset with block protection - // enabled for some regions, issue gbpu instruction to clear + // enabled for some regions, issue global protection unlock to clear _wren(); - _cmdwrite(0x98, 0, 0, 0x0, NULL); + _cmdwrite(SPIF_ULBPR, 0, 0, 0x0, NULL); break; } diff --git a/components/storage/blockdevice/COMPONENT_SD/TESTS/filesystem/fopen/fopen.cpp b/components/storage/blockdevice/COMPONENT_SD/TESTS/filesystem/fopen/fopen.cpp index 3916616ad6..bc8093d164 100644 --- a/components/storage/blockdevice/COMPONENT_SD/TESTS/filesystem/fopen/fopen.cpp +++ b/components/storage/blockdevice/COMPONENT_SD/TESTS/filesystem/fopen/fopen.cpp @@ -80,6 +80,7 @@ static const char *sd_testfile_path = "/sd/test.txt"; SDBlockDevice sd(MBED_CONF_SD_SPI_MOSI, MBED_CONF_SD_SPI_MISO, MBED_CONF_SD_SPI_CLK, MBED_CONF_SD_SPI_CS); FATFileSystem fs("sd", &sd); +#define FSFAT_FOPEN_TEST_00 fsfat_fopen_test_00 #define FSFAT_FOPEN_TEST_01 fsfat_fopen_test_01 #define FSFAT_FOPEN_TEST_02 fsfat_fopen_test_02 #define FSFAT_FOPEN_TEST_03 fsfat_fopen_test_03 @@ -276,6 +277,26 @@ static int32_t fsfat_filepath_make_dirs(char *filepath, bool do_asserts) return ret; } +/** @brief + * First and last test must format the SD card to FAT FS format: + * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. + */ +control_t fsfat_fopen_test_00(const size_t call_count) +{ + FSFAT_FENTRYLOG("%s:entered\n", __func__); + (void) call_count; + int32_t ret = -1; + + fs.unmount(); + ret = fs.format(&sd); + FSFAT_TEST_UTEST_MESSAGE(fsfat_fopen_utest_msg_g, FSFAT_UTEST_MSG_BUF_SIZE, + "%s:Error: failed to format sdcard (ret=%d)\n", __func__, (int) ret); + TEST_ASSERT_MESSAGE(ret == 0, fsfat_fopen_utest_msg_g); + fs.mount(&sd); + + return CaseNext; +} + /* FIX ME: errno not set correctly when error occurs. This indicates a problem with the implementation. */ @@ -1535,7 +1556,7 @@ control_t fsfat_fopen_test_16(const size_t call_count) #else - +#define FSFAT_FOPEN_TEST_00 fsfat_fopen_test_dummy #define FSFAT_FOPEN_TEST_01 fsfat_fopen_test_dummy #define FSFAT_FOPEN_TEST_02 fsfat_fopen_test_dummy #define FSFAT_FOPEN_TEST_03 fsfat_fopen_test_dummy @@ -1590,6 +1611,7 @@ utest::v1::status_t greentea_setup(const size_t number_of_cases) Case cases[] = { /* 1 2 3 4 5 6 7 */ /* 1234567890123456789012345678901234567890123456789012345678901234567890 */ + Case("FSFAT_FOPEN_TEST_00: format sd card to FAT FS.", FSFAT_FOPEN_TEST_00), Case("FSFAT_FOPEN_TEST_01: fopen()/fwrite()/fclose() directories/file in multi-dir filepath.", FSFAT_FOPEN_TEST_01), Case("FSFAT_FOPEN_TEST_02: fopen(r) pre-existing file try to write it.", FSFAT_FOPEN_TEST_02), Case("FSFAT_FOPEN_TEST_03: fopen(w+) pre-existing file try to write it.", FSFAT_FOPEN_TEST_03), diff --git a/components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.cpp b/components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.cpp index 5716f9d179..b55f71707b 100644 --- a/components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.cpp +++ b/components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.cpp @@ -88,6 +88,7 @@ enum spif_default_instructions { SPIF_RSTEN = 0x66, // Reset Enable SPIF_RST = 0x99, // Reset SPIF_RDID = 0x9f, // Read Manufacturer and JDEC Device ID + SPIF_ULBPR = 0x98, // Clears all write-protection bits in the Block-Protection register }; // Mutex is used for some SPI Driver commands that must be done sequentially with no other commands in between @@ -167,9 +168,9 @@ int SPIFBlockDevice::init() switch (vendor_device_ids[0]) { case 0xbf: // SST devices come preset with block protection - // enabled for some regions, issue write disable instruction to clear + // enabled for some regions, issue global protection unlock to clear _set_write_enable(); - _spi_send_general_command(SPIF_WRDI, SPI_NO_ADDRESS_COMMAND, NULL, 0, NULL, 0); + _spi_send_general_command(SPIF_ULBPR, SPI_NO_ADDRESS_COMMAND, NULL, 0, NULL, 0); break; } diff --git a/components/wifi/esp8266-driver/ESP8266/ESP8266.cpp b/components/wifi/esp8266-driver/ESP8266/ESP8266.cpp index 0533c1984f..50f898c4f2 100644 --- a/components/wifi/esp8266-driver/ESP8266/ESP8266.cpp +++ b/components/wifi/esp8266-driver/ESP8266/ESP8266.cpp @@ -715,6 +715,10 @@ int32_t ESP8266::_recv_tcp_passive(int id, void *data, uint32_t amount, uint32_t // update internal variable tcp_data_avbl to reflect the remaining data if (_sock_i[id].tcp_data_rcvd > 0) { + if (_sock_i[id].tcp_data_rcvd > (int32_t)amount) { + MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_DRIVER, MBED_ERROR_CODE_EBADMSG), \ + "ESP8266::_recv_tcp_passive() too much data from modem\n"); + } if (_sock_i[id].tcp_data_avbl > _sock_i[id].tcp_data_rcvd) { _sock_i[id].tcp_data_avbl -= _sock_i[id].tcp_data_rcvd; } else { diff --git a/components/wifi/esp8266-driver/ESP8266Interface.cpp b/components/wifi/esp8266-driver/ESP8266Interface.cpp index 9ef3c73bfb..08c9100587 100644 --- a/components/wifi/esp8266-driver/ESP8266Interface.cpp +++ b/components/wifi/esp8266-driver/ESP8266Interface.cpp @@ -55,11 +55,14 @@ ESP8266Interface::ESP8266Interface() : _esp(MBED_CONF_ESP8266_TX, MBED_CONF_ESP8266_RX, MBED_CONF_ESP8266_DEBUG, MBED_CONF_ESP8266_RTS, MBED_CONF_ESP8266_CTS), _rst_pin(MBED_CONF_ESP8266_RST), // Notice that Pin7 CH_EN cannot be left floating if used as reset _ap_sec(NSAPI_SECURITY_UNKNOWN), + _if_blocking(true), + _if_connected(_cmutex), _initialized(false), _conn_stat(NSAPI_STATUS_DISCONNECTED), _conn_stat_cb(NULL), _global_event_queue(NULL), - _oob_event_id(0) + _oob_event_id(0), + _connect_event_id(0) { memset(_cbs, 0, sizeof(_cbs)); memset(ap_ssid, 0, sizeof(ap_ssid)); @@ -83,11 +86,14 @@ ESP8266Interface::ESP8266Interface(PinName tx, PinName rx, bool debug, PinName r : _esp(tx, rx, debug, rts, cts), _rst_pin(rst), _ap_sec(NSAPI_SECURITY_UNKNOWN), + _if_blocking(true), + _if_connected(_cmutex), _initialized(false), _conn_stat(NSAPI_STATUS_DISCONNECTED), _conn_stat_cb(NULL), _global_event_queue(NULL), - _oob_event_id(0) + _oob_event_id(0), + _connect_event_id(0) { memset(_cbs, 0, sizeof(_cbs)); memset(ap_ssid, 0, sizeof(ap_ssid)); @@ -111,6 +117,12 @@ ESP8266Interface::~ESP8266Interface() _global_event_queue->cancel(_oob_event_id); } + _cmutex.lock(); + if (_connect_event_id) { + _global_event_queue->cancel(_connect_event_id); + } + _cmutex.unlock(); + // Power down the modem _rst_pin.rst_assert(); } @@ -167,9 +179,36 @@ void ESP8266Interface::_oob2global_event_queue() } } +void ESP8266Interface::_connect_async() +{ + _cmutex.lock(); + if (!_connect_event_id) { + tr_debug("_connect_async(): cancelled"); + _cmutex.unlock(); + return; + } + + if (_esp.connect(ap_ssid, ap_pass) != NSAPI_ERROR_OK) { + // Postpone to give other stuff time to run + _connect_event_id = _global_event_queue->call_in(ESP8266_CONNECT_TIMEOUT, callback(this, &ESP8266Interface::_connect_async)); + + if (!_connect_event_id) { + MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_DRIVER, MBED_ERROR_CODE_ENOMEM), \ + "_connect_async(): unable to add event to queue"); + } + } else { + _connect_event_id = 0; + _if_connected.notify_all(); + } + _cmutex.unlock(); +} + int ESP8266Interface::connect() { - nsapi_error_t status; + nsapi_error_t status = _conn_status_to_error(); + if (status != NSAPI_ERROR_NO_CONNECTION) { + return status; + } if (strlen(ap_ssid) == 0) { return NSAPI_ERROR_NO_SSID; @@ -194,11 +233,32 @@ int ESP8266Interface::connect() return NSAPI_ERROR_DHCP_FAILURE; } - return _esp.connect(ap_ssid, ap_pass); + _cmutex.lock(); + + MBED_ASSERT(!_connect_event_id); + _connect_event_id = _global_event_queue->call(callback(this, &ESP8266Interface::_connect_async)); + + if (!_connect_event_id) { + MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_DRIVER, MBED_ERROR_CODE_ENOMEM), \ + "connect(): unable to add event to queue"); + } + + while (_if_blocking && (_conn_status_to_error() != NSAPI_ERROR_IS_CONNECTED)) { + _if_connected.wait(); + } + + _cmutex.unlock(); + + return NSAPI_ERROR_OK; } int ESP8266Interface::set_credentials(const char *ssid, const char *pass, nsapi_security_t security) { + nsapi_error_t status = _conn_status_to_error(); + if (status != NSAPI_ERROR_NO_CONNECTION) { + return status; + } + _ap_sec = security; if (!ssid) { @@ -244,10 +304,16 @@ int ESP8266Interface::set_channel(uint8_t channel) int ESP8266Interface::disconnect() { + _cmutex.lock(); + if (_connect_event_id) { + _global_event_queue->cancel(_connect_event_id); + _connect_event_id = 0; // cancel asynchronous connection attempt if one is ongoing + } + _cmutex.unlock(); _initialized = false; - if (_conn_stat == NSAPI_STATUS_DISCONNECTED) - { + nsapi_error_t status = _conn_status_to_error(); + if (status == NSAPI_ERROR_NO_CONNECTION || !get_ip_address()) { return NSAPI_ERROR_NO_CONNECTION; } @@ -508,9 +574,11 @@ int ESP8266Interface::socket_send(void *handle, const void *data, unsigned size) } while ((sendStartTime - rtos::Kernel::get_ms_count() < 50) && (status != NSAPI_ERROR_OK)); - if (status == NSAPI_ERROR_WOULD_BLOCK) { - debug("Enqueuing the event call"); + if (status == NSAPI_ERROR_WOULD_BLOCK && socket->proto == NSAPI_TCP) { + tr_debug("ESP8266Interface::socket_send(): enqueuing the event call"); _global_event_queue->call_in(100, callback(this, &ESP8266Interface::event)); + } else if (status == NSAPI_ERROR_WOULD_BLOCK && socket->proto == NSAPI_UDP) { + status = NSAPI_ERROR_DEVICE_ERROR; } return status != NSAPI_ERROR_OK ? status : size; @@ -714,4 +782,35 @@ void ESP8266Interface::proc_oob_evnt() _esp.bg_process_oob(ESP8266_RECV_TIMEOUT, true); } +nsapi_error_t ESP8266Interface::_conn_status_to_error() +{ + nsapi_error_t ret; + + _esp.bg_process_oob(ESP8266_RECV_TIMEOUT, true); + + switch (_conn_stat) { + case NSAPI_STATUS_DISCONNECTED: + ret = NSAPI_ERROR_NO_CONNECTION; + break; + case NSAPI_STATUS_CONNECTING: + ret = NSAPI_ERROR_ALREADY; + break; + case NSAPI_STATUS_GLOBAL_UP: + ret = NSAPI_ERROR_IS_CONNECTED; + break; + default: + ret = NSAPI_ERROR_DEVICE_ERROR; + } + + return ret; +} + +nsapi_error_t ESP8266Interface::set_blocking(bool blocking) +{ + _if_blocking = blocking; + + return NSAPI_ERROR_OK; +} + + #endif diff --git a/components/wifi/esp8266-driver/ESP8266Interface.h b/components/wifi/esp8266-driver/ESP8266Interface.h index 415e291d7d..f123cf27cd 100644 --- a/components/wifi/esp8266-driver/ESP8266Interface.h +++ b/components/wifi/esp8266-driver/ESP8266Interface.h @@ -29,6 +29,8 @@ #include "features/netsocket/WiFiAccessPoint.h" #include "features/netsocket/WiFiInterface.h" #include "platform/Callback.h" +#include "rtos/ConditionVariable.h" +#include "rtos/Mutex.h" #define ESP8266_SOCKET_COUNT 5 @@ -316,6 +318,13 @@ protected: return this; } + /** Set blocking status of connect() which by default should be blocking. + * + * @param blocking Use true to make connect() blocking. + * @return NSAPI_ERROR_OK on success, negative error code on failure. + */ + virtual nsapi_error_t set_blocking(bool blocking); + private: // AT layer ESP8266 _esp; @@ -341,6 +350,12 @@ private: char ap_pass[ESP8266_PASSPHRASE_MAX_LENGTH + 1]; /* The longest possible passphrase; +1 for the \0 */ nsapi_security_t _ap_sec; + bool _if_blocking; // NetworkInterface, blocking or not + rtos::ConditionVariable _if_connected; + + // connect status reporting + nsapi_error_t _conn_status_to_error(); + // Drivers's socket info struct _sock_info { bool open; @@ -369,8 +384,12 @@ private: // Use global EventQueue events::EventQueue *_global_event_queue; int _oob_event_id; + int _connect_event_id; void proc_oob_evnt(); void _oob2global_event_queue(); + void _connect_async(); + rtos::Mutex _cmutex; // Protect asynchronous connection logic + }; #endif #endif diff --git a/docs/design-documents/features/storage/Configuration/CONFIGURATION.md b/docs/design-documents/features/storage/Configuration/CONFIGURATION.md index c9d14e4c36..27e06a252d 100644 --- a/docs/design-documents/features/storage/Configuration/CONFIGURATION.md +++ b/docs/design-documents/features/storage/Configuration/CONFIGURATION.md @@ -63,7 +63,7 @@ The following is a list of all storage parameters available and their descriptio * `FILESYSTEM`. * `FILESYSTEM_NO_RBP`. * `default` - If default is set, the system will choose the type of storage base on the block device component set in target.json. For QSPIF, SPIF and DATAFLASH block devices TDB_EXTERNAL will be used. If SD is set a FILESYSTEM storage is set and if only FLASHIAP exists as the only block device component, a TDB_INTERNAL will be used. + If the `default` configuration is set, the system will choose the type of storage based on the block device component set in `target.json`. If QSPIF, SPIF or DATAFLASH is the block device component in `target.json`, the system chooses `TDB_EXTERNAL` as its storage option. If SD is the block device in `target.json`, the system chooses FILESYSTEM. If FLASHIAP is the only block device component, the system chooses `TDB_INTERNAL`. * `default_kv` - This is a string representing the path for the default KVStore instantiation. Applications can pass an empty path (only the key name) or pass the generated name for this parameter (`MBED_CONF_STORAGE_DEFAULT_KV`) as the path to use this configuration. * `internal_size` - The size in bytes for the internal FlashIAP block device. This, together with the `internal_base_address`, adjusts exactly the size and location where the block device resides on memory. If not defined, the block device will try to get the maximum size available. * `internal_base_address` - The address where the internal FlashIAP blockDevice starts. This helps to prevent collisions with other needs, such as firmware updates. If not defined, the start address will be set to the first sector after the application code ends in `TDB_internal`. In any external configurations with rollback protection support, it will be set to end of flash - `rbp_internal_size`. diff --git a/drivers/FlashIAP.cpp b/drivers/FlashIAP.cpp index 3f67093900..ff01509259 100644 --- a/drivers/FlashIAP.cpp +++ b/drivers/FlashIAP.cpp @@ -33,6 +33,8 @@ namespace mbed { +const unsigned int num_write_retries = 16; + SingletonPtr FlashIAP::_mutex; static inline bool is_aligned(uint32_t number, uint32_t alignment) @@ -119,7 +121,7 @@ int FlashIAP::program(const void *buffer, uint32_t addr, uint32_t size) int ret = 0; _mutex->lock(); - while (size) { + while (size && !ret) { uint32_t current_sector_size = flash_get_sector_size(&_flash, addr); bool unaligned_src = (((size_t) buf / sizeof(uint32_t) * sizeof(uint32_t)) != (size_t) buf); chunk = std::min(current_sector_size - (addr % current_sector_size), size); @@ -141,11 +143,17 @@ int FlashIAP::program(const void *buffer, uint32_t addr, uint32_t size) prog_size = chunk; } { - ScopedRamExecutionLock make_ram_executable; - ScopedRomWriteLock make_rom_writable; - if (flash_program_page(&_flash, addr, prog_buf, prog_size)) { - ret = -1; - break; + // Few boards may fail the write actions due to HW limitations (like critical drivers that + // disable flash operations). Just retry a few times until success. + for (unsigned int retry = 0; retry < num_write_retries; retry++) { + ScopedRamExecutionLock make_ram_executable; + ScopedRomWriteLock make_rom_writable; + ret = flash_program_page(&_flash, addr, prog_buf, prog_size); + if (ret) { + ret = -1; + } else { + break; + } } } size -= chunk; @@ -187,15 +195,18 @@ int FlashIAP::erase(uint32_t addr, uint32_t size) int32_t ret = 0; _mutex->lock(); - while (size) { - { + while (size && !ret) { + // Few boards may fail the erase actions due to HW limitations (like critical drivers that + // disable flash operations). Just retry a few times until success. + for (unsigned int retry = 0; retry < num_write_retries; retry++) { ScopedRamExecutionLock make_ram_executable; ScopedRomWriteLock make_rom_writable; ret = flash_erase_sector(&_flash, addr); - } - if (ret != 0) { - ret = -1; - break; + if (ret) { + ret = -1; + } else { + break; + } } current_sector_size = flash_get_sector_size(&_flash, addr); size -= current_sector_size; diff --git a/drivers/MbedCRC.h b/drivers/MbedCRC.h index 9e99e9049f..60227e0826 100644 --- a/drivers/MbedCRC.h +++ b/drivers/MbedCRC.h @@ -497,7 +497,7 @@ private: } /** Constructor init called from all specialized cases of constructor. - * Note: All construtor common code should be in this function. + * Note: All constructor common code should be in this function. */ void mbed_crc_ctor(void) { diff --git a/features/FEATURE_BLE/ble/services/iBeacon.h b/features/FEATURE_BLE/ble/services/iBeacon.h index bed6d13eae..e3003e27d3 100644 --- a/features/FEATURE_BLE/ble/services/iBeacon.h +++ b/features/FEATURE_BLE/ble/services/iBeacon.h @@ -1,18 +1,18 @@ /* mbed Microcontroller Library - * Copyright (c) 2006-2015 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) 2006-2015 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_BLE_IBEACON_H__ #define MBED_BLE_IBEACON_H__ @@ -28,8 +28,8 @@ * number generally used to determine the location of devices or physical objects * near a mobile phone user. * - * iOS scans for iBeacon devices in a background task and notifies Apps - * subscribed to a specific region when the area is entered or left. Apps may + * iOS scans for iBeacon devices in a background task and notifies apps + * that subscribe to a specific region when a device enters or leaves an area. Apps may * use this information to display context-aware content to users. * * As an example, a museum can deploy an app that informs the user when one of @@ -48,7 +48,7 @@ * of iBeacons in relevant touristic locations it operates. The UUID may * identify a place managed by the city. The major ID would identify the place; * it can be a museum, a historic monument, a metro station and so on. The minor ID - * would locate a specific spot within a specific city place. It can be a + * would identify a specific spot within a specific city place. It can be a * piece of art, a ticket dispenser or a relevant point of interest. * * Each iBeacon device is physically attached to the spot it locates and @@ -78,7 +78,7 @@ * * @attention If you are interested in manufacturing iBeacons, you must obtain a * license from Apple. More information at https://developer.apple.com/ibeacon/. - * The licence also grant access to the iBeacons technical specification. + * The license also grant access to the iBeacons technical specification. * * @note More information at https://developer.apple.com/ibeacon/Getting-Started-with-iBeacon.pdf * @@ -88,9 +88,9 @@ MBED_DEPRECATED_SINCE( "mbed-os-5.11", "This service is deprecated, and no replacement is currently available." ) -class iBeacon -{ +class iBeacon { public: +#if !(DOXYGEN_ONLY) /** * Data buffer of a location UUID. */ @@ -116,12 +116,12 @@ public: uint16_t companyID; /** - * Packet ID; Equal to 2 for an iBeacon. + * Packet ID; equal to 2 for an iBeacon. */ uint8_t ID; /** - * Length of the remaining data presents in the payload. + * Length of the remaining data present in the payload. */ uint8_t len; @@ -131,7 +131,7 @@ public: uint8_t proximityUUID[16]; /** - * Beacon Major group ID. + * Beacon major group ID. */ uint16_t majorNumber; @@ -150,11 +150,11 @@ public: * Assemble an iBeacon payload. * * @param[in] uuid Beacon network ID. iBeacon operators use this value - * to group their iBeacons into a single network, a single region and + * to group their iBeacons into a single network, a single region, and * identify their organization among others. * * @param[in] majNum Beacon major group ID. iBeacon exploitants may use - * this field to divide the region into subregions, their network into + * this field to divide the region into subregions, and their network into * subnetworks. * * @param[in] minNum Identifier of the Beacon in its subregion. @@ -181,7 +181,7 @@ public: memcpy(proximityUUID, uuid, sizeof(LocationUUID_t)); } }; - +#endif //#if !(DOXYGEN_ONLY) public: /** * Construct an iBeacon::Payload and register it into Gap. @@ -189,17 +189,17 @@ public: * @param[in] _ble The BLE interface to configure with the iBeacon payload. * * @param[in] uuid Beacon network ID. iBeacon operators use this value - * to group their iBeacons into a single network, a single region and + * to group their iBeacons into a single network, a single region, and * identify their organization among others. * - * @param[in] majNum Beacon major group ID. iBeacon exploitants may use - * this field to divide the region into subregions, their network into + * @param[in] majNum Beacon major group ID. iBeacon fleet operators may use + * this field to divide the region into subregions, and their network into * subnetworks. * * @param[in] minNum Identifier of the Beacon in its subregion. * - * @param[in] txP Measured transmit power of the beacon at 1 - * meter. Scanners use this parameter to approximate the distance + * @param[in] txP Measured transmit power of the beacon at distance of + * one meter. Scanners use this parameter to approximate the distance * to the beacon. * * @param[in] compID ID of the beacon manufacturer. diff --git a/features/FEATURE_BLE/source/generic/GenericGap.cpp b/features/FEATURE_BLE/source/generic/GenericGap.cpp index 2fbd56f4c2..a6be0dc6ff 100644 --- a/features/FEATURE_BLE/source/generic/GenericGap.cpp +++ b/features/FEATURE_BLE/source/generic/GenericGap.cpp @@ -64,6 +64,10 @@ static const GapScanningParams default_scan_params; static const mbed_error_status_t mixed_scan_api_error = MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_USE_INCOMPATIBLE_API); +static const mbed_error_status_t illegal_state_error = + MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_ILLEGAL_STATE); + + /* * Return true if value is included in the range [lower_bound : higher_bound] */ @@ -1782,7 +1786,8 @@ void GenericGap::on_disconnection_complete(const pal::GapDisconnectionCompleteEv void GenericGap::on_connection_parameter_request(const pal::GapRemoteConnectionParameterRequestEvent &e) { if (_user_manage_connection_parameter_requests) { - _eventHandler->onUpdateConnectionParametersRequest( + if (_eventHandler) { + _eventHandler->onUpdateConnectionParametersRequest( UpdateConnectionParametersRequestEvent( e.connection_handle, conn_interval_t(e.min_connection_interval), @@ -1791,6 +1796,9 @@ void GenericGap::on_connection_parameter_request(const pal::GapRemoteConnectionP supervision_timeout_t(e.supervision_timeout) ) ); + } else { + MBED_ERROR(illegal_state_error, "Event handler required if connection params are user handled"); + } } else { _pal_gap.accept_connection_parameter_request( e.connection_handle, @@ -1806,6 +1814,10 @@ void GenericGap::on_connection_parameter_request(const pal::GapRemoteConnectionP void GenericGap::on_connection_update(const pal::GapConnectionUpdateEvent &e) { + if (!_eventHandler) { + return; + } + _eventHandler->onConnectionParametersUpdateComplete( ConnectionParametersUpdateCompleteEvent( e.status == pal::hci_error_code_t::SUCCESS ? BLE_ERROR_NONE : BLE_ERROR_UNSPECIFIED, diff --git a/features/FEATURE_BLE/source/generic/GenericSecurityManager.cpp b/features/FEATURE_BLE/source/generic/GenericSecurityManager.cpp index 0c5e047dc4..621f758680 100644 --- a/features/FEATURE_BLE/source/generic/GenericSecurityManager.cpp +++ b/features/FEATURE_BLE/source/generic/GenericSecurityManager.cpp @@ -653,14 +653,20 @@ ble_error_t GenericSecurityManager::generateOOB( /* Secure connections. Avoid generating if we're already waiting for it. * If a local random is set to 0 it means we're already calculating. */ if (!is_all_zeros(_oob_local_random)) { - status = _pal.generate_secure_connections_oob(); + /* save the current values in case the call to + * generate_secure_connections_oob fails */ + address_t orig_local_address = _oob_local_address; + oob_lesc_value_t orig_local_random = _oob_local_random; - if (status == BLE_ERROR_NONE) { - _oob_local_address = *address; - /* this will be updated when calculation completes, - * a value of all zeros is an invalid random value */ - set_all_zeros(_oob_local_random); - } else if (status != BLE_ERROR_NOT_IMPLEMENTED) { + _oob_local_address = *address; + /* this will be updated when calculation completes, + * a value of all zeros is an invalid random value */ + set_all_zeros(_oob_local_random); + + status = _pal.generate_secure_connections_oob(); + if (status != BLE_ERROR_NONE && status != BLE_ERROR_NOT_IMPLEMENTED) { + _oob_local_address = orig_local_address; + _oob_local_random = orig_local_random; return status; } } else { diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/source/CordioBLE.cpp b/features/FEATURE_BLE/targets/TARGET_CORDIO/source/CordioBLE.cpp index 7596decc96..ba57e6bb96 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/source/CordioBLE.cpp +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/source/CordioBLE.cpp @@ -423,10 +423,10 @@ void BLE::callDispatcher() wsfOsDispatcher(); + static Timeout nextTimeout; CriticalSectionLock critical_section; if (wsfOsReadyToSleep()) { - static Timeout nextTimeout; // setup an mbed timer for the next Cordio timeout bool_t pTimerRunning; timestamp_t nextTimestamp = (timestamp_t) (WsfTimerNextExpiration(&pTimerRunning) * WSF_MS_PER_TICK) * 1000; diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_SOFTDEVICE/TARGET_NRF52/source/btle/btle.cpp b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_SOFTDEVICE/TARGET_NRF52/source/btle/btle.cpp index cf7836a8ee..a0ce8bbeb9 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_SOFTDEVICE/TARGET_NRF52/source/btle/btle.cpp +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_SOFTDEVICE/TARGET_NRF52/source/btle/btle.cpp @@ -355,9 +355,10 @@ void btle_handler(const ble_evt_t *p_ble_evt) uint8_t const data_length_peer = p_gap_evt->params.data_length_update_request.peer_params.max_tx_octets; - const uint8_t max_data_length = NRF_SDH_BLE_GATT_MAX_MTU_SIZE + 4 /* L2CAP header size */; - - uint8_t const data_length = MIN(max_data_length, data_length_peer); + uint8_t const data_length = MIN( + NRF_SDH_BLE_GATT_MAX_MTU_SIZE + 4 /* L2CAP header size */, + data_length_peer + ); ble_gap_data_length_params_t const dlp = { diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_SOFTDEVICE/TARGET_NRF52/source/nRF5xPalSecurityManager.cpp b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_SOFTDEVICE/TARGET_NRF52/source/nRF5xPalSecurityManager.cpp index a1d6b1e7e9..01126720b4 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_SOFTDEVICE/TARGET_NRF52/source/nRF5xPalSecurityManager.cpp +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_SOFTDEVICE/TARGET_NRF52/source/nRF5xPalSecurityManager.cpp @@ -15,6 +15,7 @@ */ #include +#include "platform/mbed_assert.h" #include "nRF5xPalSecurityManager.h" #include "nRF5xn.h" #include "ble/Gap.h" @@ -80,11 +81,6 @@ struct nRF5xSecurityManager::pairing_control_block_t { ble_gap_id_key_t peer_id_key; ble_gap_sign_info_t peer_sign_key; ble_gap_lesc_p256_pk_t peer_pk; - - // flag required to help DHKey computation/process; should be removed with - // later versions of the softdevice - uint8_t own_oob:1; - uint8_t peer_oob:1; }; nRF5xSecurityManager::nRF5xSecurityManager() @@ -662,26 +658,37 @@ ble_error_t nRF5xSecurityManager::secure_connections_oob_request_reply( const oob_lesc_value_t &peer_random, const oob_confirm_t &peer_confirm ) { + bool have_oob_own; + bool have_oob_peer; + const oob_lesc_value_t zerokey; + ble_gap_lesc_oob_data_t oob_own; + ble_gap_lesc_oob_data_t oob_peer; + pairing_control_block_t* pairing_cb = get_pairing_cb(connection); if (!pairing_cb) { return BLE_ERROR_INVALID_STATE; } - ble_gap_lesc_oob_data_t oob_own; - ble_gap_lesc_oob_data_t oob_peer; + have_oob_own = false; + if (local_random != zerokey) { + have_oob_own = true; + // is own address important ? + memcpy(oob_own.r, local_random.data(), local_random.size()); + // FIXME: What to do with local confirm ??? + } - // is own address important ? - memcpy(oob_own.r, local_random.data(), local_random.size()); - // FIXME: What to do with local confirm ??? - - // is peer address important ? - memcpy(oob_peer.r, peer_random.data(), peer_random.size()); - memcpy(oob_peer.c, peer_confirm.data(), peer_confirm.size()); + have_oob_peer = false; + if (peer_random != zerokey && peer_confirm != zerokey) { + have_oob_peer = true; + // is peer address important ? + memcpy(oob_peer.r, peer_random.data(), peer_random.size()); + memcpy(oob_peer.c, peer_confirm.data(), peer_confirm.size()); + } uint32_t err = sd_ble_gap_lesc_oob_data_set( connection, - pairing_cb->own_oob ? &oob_own : NULL, - pairing_cb->peer_oob ? &oob_peer : NULL + have_oob_own ? &oob_own : NULL, + have_oob_peer ? &oob_peer : NULL ); return convert_sd_error(err); @@ -734,7 +741,9 @@ ble_error_t nRF5xSecurityManager::generate_secure_connections_oob() ble_gap_lesc_p256_pk_t own_secret; ble_gap_lesc_oob_data_t oob_data; - memcpy(own_secret.pk, secret.data(), secret.size()); + MBED_ASSERT(sizeof(own_secret.pk) >= X.size() + Y.size()); + memcpy(own_secret.pk, X.data(), X.size()); + memcpy(own_secret.pk + X.size(), Y.data(), Y.size()); uint32_t err = sd_ble_gap_lesc_oob_data_get( BLE_CONN_HANDLE_INVALID, diff --git a/features/cellular/framework/common/CellularTargets.h b/features/cellular/framework/common/CellularTargets.h index feb330efa8..2ffb377c4f 100644 --- a/features/cellular/framework/common/CellularTargets.h +++ b/features/cellular/framework/common/CellularTargets.h @@ -32,7 +32,7 @@ namespace mbed { #elif TARGET_MTB_MTS_DRAGONFLY #define CELLULAR_DEVICE TELIT_HE910 #elif TARGET_UBLOX_C030 -#if defined(TARGET_UBLOX_C030_N211) || defined(TARGET_UBLOX_C030_R410M) +#if defined(TARGET_UBLOX_C030_N211) || defined(TARGET_UBLOX_C030_R41XM) #define CELLULAR_DEVICE UBLOX_AT #else #define CELLULAR_DEVICE UBLOX_PPP diff --git a/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26.cpp b/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26.cpp new file mode 100644 index 0000000000..a5efe042d9 --- /dev/null +++ b/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26.cpp @@ -0,0 +1,67 @@ +/* + * 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 "QUECTEL_M26_CellularNetwork.h" +#include "QUECTEL_M26_CellularPower.h" +#include "QUECTEL_M26_CellularSIM.h" +#include "QUECTEL_M26_CellularContext.h" +#include "QUECTEL_M26.h" + +using namespace events; +using namespace mbed; + +#define CONNECT_DELIM "\r\n" +#define CONNECT_BUFFER_SIZE (1280 + 80 + 80) // AT response + sscanf format +#define CONNECT_TIMEOUT 8000 + +#define MAX_STARTUP_TRIALS 5 +#define MAX_RESET_TRIALS 5 + +static const AT_CellularBase::SupportedFeature unsupported_features[] = { + AT_CellularBase::AT_CGSN_WITH_TYPE, + AT_CellularBase::AT_CGAUTH, + AT_CellularBase::SUPPORTED_FEATURE_END_MARK +}; + +QUECTEL_M26::QUECTEL_M26(FileHandle *fh) : AT_CellularDevice(fh) +{ + AT_CellularBase::set_unsupported_features(unsupported_features); +} + +QUECTEL_M26::~QUECTEL_M26() +{ +} + +AT_CellularNetwork *QUECTEL_M26::open_network_impl(ATHandler &at) +{ + return new QUECTEL_M26_CellularNetwork(at); +} + +AT_CellularPower *QUECTEL_M26::open_power_impl(ATHandler &at) +{ + return new QUECTEL_M26_CellularPower(at); +} + +AT_CellularSIM *QUECTEL_M26::open_sim_impl(ATHandler &at) +{ + return new QUECTEL_M26_CellularSIM(at); +} + +AT_CellularContext *QUECTEL_M26::create_context_impl(ATHandler &at, const char *apn) +{ + return new QUECTEL_M26_CellularContext(at, this, apn); +} diff --git a/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26.h b/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26.h new file mode 100644 index 0000000000..05053e0308 --- /dev/null +++ b/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26.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 QUECTEL_M26_H_ +#define QUECTEL_M26_H_ + +#include "AT_CellularDevice.h" + +namespace mbed { + +class QUECTEL_M26 : public AT_CellularDevice { +public: + QUECTEL_M26(FileHandle *fh); + virtual ~QUECTEL_M26(); + +protected: // AT_CellularDevice + virtual AT_CellularNetwork *open_network_impl(ATHandler &at); + virtual AT_CellularPower *open_power_impl(ATHandler &at); + virtual AT_CellularSIM *open_sim_impl(ATHandler &at); + virtual AT_CellularContext *create_context_impl(ATHandler &at, const char *apn); + +public: // NetworkInterface + void handle_urc(FileHandle *fh); +}; +} // namespace mbed + +#endif // QUECTEL_M26_H_ diff --git a/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26_CellularContext.cpp b/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26_CellularContext.cpp new file mode 100644 index 0000000000..04d0cb21ee --- /dev/null +++ b/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26_CellularContext.cpp @@ -0,0 +1,66 @@ +/* + * 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 "QUECTEL_M26_CellularContext.h" +#include "QUECTEL_M26_CellularStack.h" + +namespace mbed { + +QUECTEL_M26_CellularContext::QUECTEL_M26_CellularContext(ATHandler &at, CellularDevice *device, const char *apn) : + AT_CellularContext(at, device, apn) +{ +} + +QUECTEL_M26_CellularContext::~QUECTEL_M26_CellularContext() +{ +} + +bool QUECTEL_M26_CellularContext::stack_type_supported(nsapi_ip_stack_t stack_type) +{ + return stack_type == IPV4_STACK ? true : false; +} + +#if !NSAPI_PPP_AVAILABLE +NetworkStack *QUECTEL_M26_CellularContext::get_stack() +{ + if (!_stack) { + _stack = new QUECTEL_M26_CellularStack(_at, _cid, _ip_stack_type); + } + return _stack; +} +#endif // #if !NSAPI_PPP_AVAILABLE + +nsapi_error_t QUECTEL_M26_CellularContext::do_user_authentication() +{ + + _at.cmd_start("AT+QICSGP="); + _at.write_int(1); /*GPRS MODE = 1, CSD MODE = 0*/ + _at.write_string(_apn); + if (_pwd && _uname) { + _at.write_string(_uname); + _at.write_string(_pwd); + } + _at.cmd_stop(); + _at.resp_start(); + _at.resp_stop(); + if (_at.get_last_error() != NSAPI_ERROR_OK) { + return NSAPI_ERROR_AUTH_FAILURE; + } + + return NSAPI_ERROR_OK; +} + +} /* namespace mbed */ diff --git a/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26_CellularContext.h b/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26_CellularContext.h new file mode 100644 index 0000000000..ae66b9fd31 --- /dev/null +++ b/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26_CellularContext.h @@ -0,0 +1,39 @@ +/* + * 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 QUECTEL_M26_CELLULARCONTEXT_H_ +#define QUECTEL_M26_CELLULARCONTEXT_H_ + +#include "AT_CellularContext.h" + +namespace mbed { + +class QUECTEL_M26_CellularContext: public AT_CellularContext { +public: + QUECTEL_M26_CellularContext(ATHandler &at, CellularDevice *device, const char *apn); + virtual ~QUECTEL_M26_CellularContext(); + +protected: + virtual bool stack_type_supported(nsapi_ip_stack_t stack_type); +#if !NSAPI_PPP_AVAILABLE + virtual NetworkStack *get_stack(); +#endif // #if !NSAPI_PPP_AVAILABLE + virtual nsapi_error_t do_user_authentication(); +}; + +} /* namespace mbed */ + +#endif // QUECTEL_M26_CELLULARCONTEXT_H_ diff --git a/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26_CellularNetwork.cpp b/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26_CellularNetwork.cpp new file mode 100644 index 0000000000..0ee5464fd8 --- /dev/null +++ b/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26_CellularNetwork.cpp @@ -0,0 +1,45 @@ +/* + * 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 "QUECTEL_M26_CellularNetwork.h" + +using namespace mbed; + +QUECTEL_M26_CellularNetwork::QUECTEL_M26_CellularNetwork(ATHandler &atHandler) : AT_CellularNetwork(atHandler) +{ + _op_act = RAT_EGPRS; +} + +QUECTEL_M26_CellularNetwork::~QUECTEL_M26_CellularNetwork() +{ +} + +AT_CellularNetwork::RegistrationMode QUECTEL_M26_CellularNetwork::has_registration(RegistrationType reg_type) +{ + return (reg_type == C_GREG) ? RegistrationModeLAC : RegistrationModeDisable; +} + +nsapi_error_t QUECTEL_M26_CellularNetwork::set_access_technology_impl(RadioAccessTechnology opRat) +{ + if (opRat != RAT_EGPRS) { + // only GPRS support in the driver. + _op_act = RAT_EGPRS; + return NSAPI_ERROR_UNSUPPORTED; + } + + return NSAPI_ERROR_OK; +} diff --git a/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26_CellularNetwork.h b/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26_CellularNetwork.h new file mode 100644 index 0000000000..0aff1e3e36 --- /dev/null +++ b/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26_CellularNetwork.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 QUECTEL_M26_CELLULAR_NETWORK_H_ +#define QUECTEL_M26_CELLULAR_NETWORK_H_ + +#include "AT_CellularNetwork.h" + +namespace mbed { + +class QUECTEL_M26_CellularNetwork : public AT_CellularNetwork { +public: + QUECTEL_M26_CellularNetwork(ATHandler &atHandler); + virtual ~QUECTEL_M26_CellularNetwork(); + +protected: + virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology opRat); + virtual RegistrationMode has_registration(RegistrationType reg_type); +}; +} // namespace mbed +#endif // QUECTEL_M26_CELLULAR_NETWORK_H_ diff --git a/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26_CellularPower.cpp b/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26_CellularPower.cpp new file mode 100644 index 0000000000..2ab2b9a1dd --- /dev/null +++ b/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26_CellularPower.cpp @@ -0,0 +1,60 @@ +/* + * 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 "QUECTEL_M26_CellularPower.h" + +using namespace mbed; + +QUECTEL_M26_CellularPower::QUECTEL_M26_CellularPower(ATHandler &atHandler) : AT_CellularPower(atHandler) +{ + +} + +QUECTEL_M26_CellularPower::~QUECTEL_M26_CellularPower() +{ + +} + +nsapi_error_t QUECTEL_M26_CellularPower::set_at_mode() +{ + _at.lock(); + _at.cmd_start("AT"); + _at.cmd_stop_read_resp(); + + _at.cmd_start("AT+CMEE="); // verbose responses + _at.write_int(1); + _at.cmd_stop_read_resp(); + + return _at.unlock_return_error(); +} + +nsapi_error_t QUECTEL_M26_CellularPower::on() +{ + + return NSAPI_ERROR_OK; +} + +nsapi_error_t QUECTEL_M26_CellularPower::off() +{ + _at.lock(); + _at.cmd_start("AT+QPOWD=0"); + _at.cmd_stop(); + _at.resp_start(); + _at.resp_stop(); + + return _at.unlock_return_error();; +} diff --git a/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26_CellularPower.h b/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26_CellularPower.h new file mode 100644 index 0000000000..c62a7f5be8 --- /dev/null +++ b/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26_CellularPower.h @@ -0,0 +1,40 @@ +/* + * 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 QUECTEL_M26_CELLULAR_POWER_H_ +#define QUECTEL_M26_CELLULAR_POWER_H_ + +#include "AT_CellularPower.h" + +namespace mbed { + +class QUECTEL_M26_CellularPower : public AT_CellularPower { +public: + QUECTEL_M26_CellularPower(ATHandler &atHandler); + virtual ~QUECTEL_M26_CellularPower(); + +public: //from CellularPower + virtual nsapi_error_t set_at_mode(); + + virtual nsapi_error_t on(); + + virtual nsapi_error_t off(); +}; + +} // namespace mbed + +#endif // QUECTEL_M26_CELLULAR_POWER_H_ diff --git a/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26_CellularSIM.cpp b/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26_CellularSIM.cpp new file mode 100644 index 0000000000..0b4fa84659 --- /dev/null +++ b/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26_CellularSIM.cpp @@ -0,0 +1,88 @@ +/* + * 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 "QUECTEL_M26_CellularSIM.h" +#include "CellularLog.h" + +using namespace mbed; + +QUECTEL_M26_CellularSIM::QUECTEL_M26_CellularSIM(ATHandler &atHandler) : AT_CellularSIM(atHandler) +{ + +} + +QUECTEL_M26_CellularSIM::~QUECTEL_M26_CellularSIM() +{ + +} + +nsapi_error_t QUECTEL_M26_CellularSIM::get_sim_state(SimState &state) +{ + char buf[13]; + + _at.lock(); + _at.cmd_start("AT+CPIN?"); + _at.cmd_stop(); + _at.resp_start("+CPIN:"); + if (_at.info_resp()) { + _at.read_string(buf, 13); + tr_debug("CPIN: %s", buf); + + if (memcmp(buf, "READY", 5) == 0) { + state = SimStateReady; + } else if (memcmp(buf, "SIM PIN", 7) == 0) { + state = SimStatePinNeeded; + } else if (memcmp(buf, "SIM PUK", 7) == 0) { + state = SimStatePukNeeded; + } else if (memcmp(buf, "PH_SIM PIN", 10) == 0) { + state = SimStatePinNeeded; + } else if (memcmp(buf, "PH_SIM PUK", 10) == 0) { + state = SimStatePukNeeded; + } else if (memcmp(buf, "SIM PIN2", 8) == 0) { + state = SimStatePinNeeded; + } else if (memcmp(buf, "SIM PUK2", 8) == 0) { + state = SimStatePukNeeded; + } else { + state = SimStateUnknown; // SIM may not be ready yet + } + + } + _at.resp_stop(); + return _at.unlock_return_error(); +} + +// According to M26_AT_Commands_Manual_V1.9 +nsapi_error_t QUECTEL_M26_CellularSIM::get_iccid(char *buf, size_t buf_size) +{ + _at.lock(); + _at.cmd_start("AT+CCID"); + _at.cmd_stop(); + _at.resp_start("+CCID:"); + _at.read_string(buf, buf_size); + _at.resp_stop(); + return _at.unlock_return_error(); +} + +nsapi_error_t QUECTEL_M26_CellularSIM::change_pin(const char *sim_pin, const char *new_pin) +{ + return NSAPI_ERROR_UNSUPPORTED; +} + +nsapi_error_t QUECTEL_M26_CellularSIM::set_pin_query(const char *sim_pin, bool query_pin) +{ + return NSAPI_ERROR_UNSUPPORTED; +} diff --git a/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26_CellularSIM.h b/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26_CellularSIM.h new file mode 100644 index 0000000000..8cf227a70c --- /dev/null +++ b/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26_CellularSIM.h @@ -0,0 +1,39 @@ +/* + * 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 QUECTEL_M26_CELLULAR_SIM_H_ +#define QUECTEL_M26_CELLULAR_SIM_H_ + +#include "AT_CellularSIM.h" + +namespace mbed { + +class QUECTEL_M26_CellularSIM : public AT_CellularSIM { +public: + QUECTEL_M26_CellularSIM(ATHandler &atHandler); + virtual ~QUECTEL_M26_CellularSIM(); + +public: //from CellularSIM + virtual nsapi_error_t get_sim_state(SimState &state); + virtual nsapi_error_t get_iccid(char *buf, size_t buf_size); + virtual nsapi_error_t change_pin(const char *sim_pin, const char *new_pin); + virtual nsapi_error_t set_pin_query(const char *sim_pin, bool query_pin); +}; + +} // namespace mbed + +#endif // QUECTEL_M26_CELLULAR_SIM_H_ diff --git a/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26_CellularStack.cpp b/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26_CellularStack.cpp new file mode 100644 index 0000000000..20515438a2 --- /dev/null +++ b/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26_CellularStack.cpp @@ -0,0 +1,498 @@ +/* + * 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 "QUECTEL/M26/QUECTEL_M26_CellularStack.h" +#include "CellularLog.h" + +using namespace mbed; + +QUECTEL_M26_CellularStack::QUECTEL_M26_CellularStack(ATHandler &atHandler, int cid, nsapi_ip_stack_t stack_type) : AT_CellularStack(atHandler, cid, stack_type) +{ + _at.set_urc_handler("+QIRDI:", mbed::Callback(this, &QUECTEL_M26_CellularStack::urc_qiurc)); +} + +QUECTEL_M26_CellularStack::~QUECTEL_M26_CellularStack() +{ +} + +nsapi_error_t QUECTEL_M26_CellularStack::socket_listen(nsapi_socket_t handle, int backlog) +{ + return NSAPI_ERROR_UNSUPPORTED; +} + +nsapi_error_t QUECTEL_M26_CellularStack::socket_accept(void *server, void **socket, SocketAddress *addr) +{ + return NSAPI_ERROR_UNSUPPORTED; +} + +nsapi_error_t QUECTEL_M26_CellularStack::socket_bind(nsapi_socket_t handle, const SocketAddress &addr) +{ + return NSAPI_ERROR_UNSUPPORTED; +} + +void QUECTEL_M26_CellularStack::urc_qiurc() +{ + int sock_id = 0; + + _at.lock(); + (void) _at.skip_param(); /* AT+QIFGCNT*/ + (void) _at.skip_param(); /* 1 Client, 2 Server*/ + sock_id = _at.read_int(); + (void) _at.skip_param(); /**/ + (void) _at.skip_param(); /**/ + (void) _at.skip_param(); /**/ + _at.unlock(); + + for (int i = 0; i < get_max_socket_count(); i++) { + CellularSocket *sock = _socket[i]; + if (sock && sock->id == sock_id) { + if (sock->_cb) { + sock->_cb(sock->_data); + } + break; + } + } +} + +nsapi_error_t QUECTEL_M26_CellularStack::socket_stack_init() +{ + int tcpip_mode = 1; + int mux_mode = 0; + int cache_mode = 0; + nsapi_error_t ret_val; + + tr_debug("QUECTEL_M26_CellularStack:%s:%u: START ", __FUNCTION__, __LINE__); + _at.lock(); + + /*AT+QIFGCNT=0*/ + _at.cmd_start("AT+QIFGCNT="); + _at.write_int(0); /* Set the Context 0 as the foreground context.*/ + _at.cmd_stop(); + _at.resp_start(); + _at.resp_stop(); + + ret_val = _at.get_last_error(); + if (ret_val != NSAPI_ERROR_OK) { + _at.unlock(); + return NSAPI_ERROR_DEVICE_ERROR; + } +#if 0 + /*AT+QICSGP=1*/ + _at.cmd_start("AT+QICSGP="); + _at.write_int(1); /* mode: 0-CSD, 1-GPRS */ + _at.write_string(_apn); + if (_pwd && _uname) { + _at.write_string(_uname); + _at.write_string(_pwd); + } + _at.cmd_stop(); + _at.resp_start(); + _at.resp_stop(); +#endif + ret_val = _at.get_last_error(); + if (ret_val != NSAPI_ERROR_OK) { + _at.unlock(); + return NSAPI_ERROR_DEVICE_ERROR; + } + + /*AT+QIMODE=0 Set transparent mode*/ + _at.cmd_start("AT+QIMODE?"); + _at.cmd_stop(); + _at.resp_start("+QIMODE:"); + if (_at.info_resp()) { + tcpip_mode = _at.read_int(); + } + _at.resp_stop(); + if (tcpip_mode) { + _at.cmd_start("AT+QIMOD="); + _at.write_int(0); /* 0-Disable, 1-Enable */ + _at.cmd_stop(); + _at.resp_start(); + _at.resp_stop(); + } + ret_val = _at.get_last_error(); + if (ret_val != NSAPI_ERROR_OK) { + _at.unlock(); + return NSAPI_ERROR_DEVICE_ERROR; + } + + /*AT+QIMUX=1*/ + _at.cmd_start("AT+QIMUX?"); + _at.cmd_stop(); + _at.resp_start("+QIMUX:"); + if (_at.info_resp()) { + mux_mode = _at.read_int(); + } + _at.resp_stop(); + if (!mux_mode) { + _at.cmd_start("AT+QIMUX="); + _at.write_int(1); /* 0-Disable, 1-Enable */ + _at.cmd_stop(); + _at.resp_start(); + _at.resp_stop(); + } + ret_val = _at.get_last_error(); + if (ret_val != NSAPI_ERROR_OK) { + _at.unlock(); + return NSAPI_ERROR_DEVICE_ERROR; + } + + /*AT+QINDI=2*/ + _at.cmd_start("AT+QINDI?"); + _at.cmd_stop(); + _at.resp_start(); + if (_at.info_resp()) { + cache_mode = _at.read_int(); + } + _at.resp_stop(); + if (cache_mode != 2) { + _at.cmd_start("AT+QINDI="); + _at.write_int(2); /* 0-Disable, 1-Single Cache, 2-Multi Cache */ + _at.cmd_stop(); + _at.resp_start(); + _at.resp_stop(); + } + + ret_val = _at.get_last_error(); + if (ret_val != NSAPI_ERROR_OK) { + _at.unlock(); + return NSAPI_ERROR_DEVICE_ERROR; + } + + _at.unlock(); + + tr_debug("QUECTEL_M26_CellularStack:%s:%u: SUCCESS ", __FUNCTION__, __LINE__); + return NSAPI_ERROR_OK; +} + +int QUECTEL_M26_CellularStack::get_max_socket_count() +{ + return M26_SOCKET_MAX; +} + +bool QUECTEL_M26_CellularStack::is_protocol_supported(nsapi_protocol_t protocol) +{ + return (protocol == NSAPI_UDP || protocol == NSAPI_TCP); +} + +nsapi_error_t QUECTEL_M26_CellularStack::socket_close_impl(int sock_id) +{ + tr_debug("QUECTEL_M26_CellularStack:%s:%u:", __FUNCTION__, __LINE__); + + _at.cmd_start("AT+QICLOSE="); + _at.write_int(sock_id); + _at.cmd_stop(); + _at.resp_start(); + _at.resp_stop(); + + return _at.get_last_error(); +} + +void QUECTEL_M26_CellularStack::handle_open_socket_response(int &modem_connect_id, int &err) +{ + char status[15]; + tr_debug("QUECTEL_M26_CellularStack:%s:%u: START", __FUNCTION__, __LINE__); + + _at.resp_start("ALREADY CONNECT"); + if (_at.info_resp()) { + /* ALREADY CONNECT: The request socket already connected */ + err = 0; + return; + } + _at.resp_stop(); + if (_at.get_last_error() != NSAPI_ERROR_OK) { + /* ERROR: The command format error */ + err = 1; + return; + } + + tr_debug("QUECTEL_M26_CellularStack:%s:%u: OK", __FUNCTION__, __LINE__); + + _at.set_at_timeout(M26_CREATE_SOCKET_TIMEOUT); + _at.resp_start(); + _at.set_stop_tag("\r\n"); + modem_connect_id = _at.read_int(); + _at.read_string(status, sizeof(status), true); + _at.resp_stop(); + _at.restore_at_timeout(); + + if ((!strcmp(status, "CONNECT FAIL")) || (_at.get_last_error() != NSAPI_ERROR_OK)) { + err = 1; + return; + } + + err = 0; + tr_debug("QUECTEL_M26_CellularStack:%s:%u: END [%s, %d]", __FUNCTION__, __LINE__, status, err); +} + + +nsapi_error_t QUECTEL_M26_CellularStack::socket_connect(nsapi_socket_t handle, const SocketAddress &address) +{ + CellularSocket *socket = (CellularSocket *)handle; + + int modem_connect_id = -1; + int request_connect_id = socket->id; + int err = -1; + + _at.lock(); + if (socket->proto == NSAPI_TCP) { + _at.cmd_start("AT+QIOPEN="); + _at.write_int(request_connect_id); + _at.write_string("TCP"); + _at.write_string(address.get_ip_address()); + _at.write_int(address.get_port()); + _at.cmd_stop(); + + handle_open_socket_response(modem_connect_id, err); + + if ((_at.get_last_error() == NSAPI_ERROR_OK) && err) { + _at.cmd_start("AT+QICLOSE="); + _at.write_int(modem_connect_id); + _at.cmd_stop(); + _at.resp_start(); + _at.resp_stop(); + + _at.cmd_start("AT+QIOPEN="); + _at.write_int(request_connect_id); + _at.write_string("TCP"); + _at.write_string(address.get_ip_address()); + _at.write_int(address.get_port()); + _at.cmd_stop(); + + handle_open_socket_response(modem_connect_id, err); + } + } + + // If opened successfully BUT not requested one, close it + if (!err && (modem_connect_id != request_connect_id)) { + _at.cmd_start("AT+QICLOSE="); + _at.write_int(modem_connect_id); + _at.cmd_stop(); + _at.resp_start(); + _at.resp_stop(); + } + + nsapi_error_t ret_val = _at.get_last_error(); + _at.unlock(); + + if ((ret_val == NSAPI_ERROR_OK) && (modem_connect_id == request_connect_id)) { + socket->created = true; + socket->remoteAddress = address; + socket->connected = true; + return NSAPI_ERROR_OK; + } + + return NSAPI_ERROR_NO_CONNECTION; +} + +nsapi_error_t QUECTEL_M26_CellularStack::create_socket_impl(CellularSocket *socket) +{ + int request_connect_id = socket->id; + int modem_connect_id = request_connect_id; + int err = -1; + nsapi_error_t ret_val; + tr_debug("QUECTEL_M26_CellularStack:%s:%u:[%d,%d]", __FUNCTION__, __LINE__, socket->proto, socket->connected); + + if (socket->connected) { + _at.cmd_start("AT+QIOPEN="); + _at.write_int(request_connect_id); + _at.write_string((socket->proto == NSAPI_TCP) ? "TCP" : "UDP"); + _at.write_string(socket->remoteAddress.get_ip_address()); + _at.write_int(socket->remoteAddress.get_port()); + _at.cmd_stop(); + + handle_open_socket_response(modem_connect_id, err); + + /* Close and retry if socket create fail */ + if ((_at.get_last_error() != NSAPI_ERROR_OK) || err) { + _at.cmd_start("AT+QICLOSE="); + _at.write_int(modem_connect_id); + _at.cmd_stop(); + _at.resp_start(); + _at.resp_stop(); + + _at.cmd_start("AT+QIOPEN="); + _at.write_int(request_connect_id); + _at.write_string((socket->proto == NSAPI_TCP) ? "TCP" : "UDP"); + _at.write_string(socket->remoteAddress.get_ip_address()); + _at.write_int(socket->remoteAddress.get_port()); + _at.cmd_stop(); + + handle_open_socket_response(modem_connect_id, err); + } + + /* If opened successfully BUT not requested one, close it */ + if (!err && (modem_connect_id != request_connect_id)) { + _at.cmd_start("AT+QICLOSE="); + _at.write_int(modem_connect_id); + _at.cmd_stop(); + _at.resp_start(); + _at.resp_stop(); + } + + ret_val = _at.get_last_error(); + socket->created = ((ret_val == NSAPI_ERROR_OK) && (modem_connect_id == request_connect_id)); + return ret_val; + } else { + tr_warn("QUECTEL_M26_CellularStack:%s:%u: Do not support TCP Listner/UDP Service Mode [%d,%d]", __FUNCTION__, __LINE__, socket->created, ret_val); + ret_val = NSAPI_ERROR_OK; + } + + tr_debug("QUECTEL_M26_CellularStack:%s:%u: END [%d,%d]", __FUNCTION__, __LINE__, socket->created, ret_val); + return ret_val; +} + + +nsapi_size_or_error_t QUECTEL_M26_CellularStack::socket_sendto_impl(CellularSocket *socket, const SocketAddress &address, + const void *data, nsapi_size_t size) +{ + int sent_len = (size > M26_SENT_BYTE_MAX) ? M26_SENT_BYTE_MAX : size; + int sent_acked = 0; + int sent_nacked = 0; + int sent_len_before = 0; + int sent_len_after = 0; + nsapi_error_t error; + + tr_debug("QUECTEL_M26_CellularStack:%s:%u:[%d-%d]", __FUNCTION__, __LINE__, sent_len, size); + + if (sent_len == 0) { + tr_error("QUECTEL_M26_CellularStack:%s:%u:[NSAPI_ERROR_PARAMETER]", __FUNCTION__, __LINE__); + return NSAPI_ERROR_PARAMETER; + } + + if (!socket->created) { + socket->remoteAddress = address; + socket->connected = true; + nsapi_error_t ret_val = create_socket_impl(socket); + if ((ret_val != NSAPI_ERROR_OK) || (!socket->created)) { + tr_error("QUECTEL_M26_CellularStack:%s:%u:[NSAPI_ERROR_NO_SOCKET]", __FUNCTION__, __LINE__); + return NSAPI_ERROR_NO_SOCKET; + } + } + + if (socket->proto == NSAPI_TCP) { + _at.cmd_start("AT+QISACK="); + _at.write_int(socket->id); + _at.cmd_stop(); + _at.resp_start("+QISACK:"); + sent_len_before = _at.read_int(); + sent_acked = _at.read_int(); + sent_nacked = _at.read_int(); + _at.resp_stop(); + + if (_at.get_last_error() != NSAPI_ERROR_OK) { + tr_error("QUECTEL_M26_CellularStack:%s:%u:[NSAPI_ERROR_DEVICE_ERROR]", __FUNCTION__, __LINE__); + return NSAPI_ERROR_DEVICE_ERROR; + } + + if (sent_nacked != 0) { + tr_debug("QUECTEL_M26_CellularStack:%s:%u:[NSAPI_ERROR_WOULD_BLOCK]", __FUNCTION__, __LINE__); + return NSAPI_ERROR_WOULD_BLOCK; + } + } + + _at.cmd_start("AT+QISEND="); + _at.write_int(socket->id); + _at.write_int(sent_len); + _at.cmd_stop(); + + _at.resp_start(">"); + _at.write_bytes((uint8_t *)data, sent_len); + _at.resp_start(); + _at.resp_stop(); + + if (_at.get_last_error() != NSAPI_ERROR_OK) { + tr_error("QUECTEL_M26_CellularStack:%s:%u:[NSAPI_ERROR_DEVICE_ERROR]", __FUNCTION__, __LINE__); + return NSAPI_ERROR_DEVICE_ERROR; + } + + if (socket->proto == NSAPI_TCP) { + _at.cmd_start("AT+QISACK="); + _at.write_int(socket->id); + _at.cmd_stop(); + + _at.resp_start("+QISACK:"); + sent_len_after = _at.read_int(); + sent_acked = _at.read_int(); + sent_nacked = _at.read_int(); + _at.resp_stop(); + + error = _at.get_last_error(); + if (error == NSAPI_ERROR_OK) { + sent_len = sent_len_after - sent_len_before; + tr_debug("QUECTEL_M26_CellularStack:%s:%u:[TCP: BA %d-%d, ACK %d-%d,LEN %d-%d]", __FUNCTION__, __LINE__, sent_len_before, sent_len_after, sent_acked, sent_nacked, sent_len, size); + return sent_len; + } + + tr_error("QUECTEL_M26_CellularStack:%s:%u:[TCP: %d]", __FUNCTION__, __LINE__, error); + return error; + } + + error = _at.get_last_error(); + if (error == NSAPI_ERROR_OK) { + tr_debug("QUECTEL_M26_CellularStack:%s:%u:[UDP: %d]", __FUNCTION__, __LINE__, sent_len); + return sent_len; + } + + tr_debug("QUECTEL_M26_CellularStack:%s:%u:[ERROR: %d]", __FUNCTION__, __LINE__, error); + return error; +} + +nsapi_size_or_error_t QUECTEL_M26_CellularStack::socket_recvfrom_impl(CellularSocket *socket, SocketAddress *address, + void *buffer, nsapi_size_t size) +{ + nsapi_size_or_error_t recv_len = (size > M26_RECV_BYTE_MAX) ? M26_RECV_BYTE_MAX : size; + int recv_len_after = 0; + int port; + char type[8]; + char ip_address[NSAPI_IP_SIZE + 1]; + + tr_debug("QUECTEL_M26_CellularStack:%s:%u:[%d]", __FUNCTION__, __LINE__, size); + _at.cmd_start("AT+QIRD="); + _at.write_int(0); /* at+qifgcnt 0-1 */ + _at.write_int(1); /* 1-Client, 2-Server */ + _at.write_int(socket->id); + _at.write_int(recv_len); + _at.cmd_stop(); + + _at.resp_start("+QIRD:"); + if (_at.info_resp()) { + _at.set_delimiter(':'); + _at.read_string(ip_address, sizeof(ip_address)); + _at.set_default_delimiter(); + port = _at.read_int(); + _at.read_string(type, sizeof(type)); + recv_len_after = _at.read_int(); + if (recv_len_after > 0) { + _at.read_bytes((uint8_t *)buffer, recv_len_after); + } + } + _at.resp_stop(); + + if (!recv_len_after || (_at.get_last_error() != NSAPI_ERROR_OK)) { + tr_debug("QUECTEL_M26_CellularStack:%s:%u:[ERROR NSAPI_ERROR_WOULD_BLOCK]", __FUNCTION__, __LINE__); + return NSAPI_ERROR_WOULD_BLOCK; + } + + if (address) { + address->set_ip_address(ip_address); + address->set_port(port); + } + + tr_debug("QUECTEL_M26_CellularStack:%s:%u:[%d]", __FUNCTION__, __LINE__, recv_len_after); + return recv_len_after; +} diff --git a/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26_CellularStack.h b/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26_CellularStack.h new file mode 100644 index 0000000000..822c4967c3 --- /dev/null +++ b/features/cellular/framework/targets/QUECTEL/M26/QUECTEL_M26_CellularStack.h @@ -0,0 +1,72 @@ +/* + * 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 QUECTEL_M26_CELLULARSTACK_H_ +#define QUECTEL_M26_CELLULARSTACK_H_ + +#include "AT_CellularStack.h" + +namespace mbed { + +#define M26_SOCKET_MAX 6 +#define M26_CREATE_SOCKET_TIMEOUT 75000 //75 seconds +#define M26_SENT_BYTE_MAX 1460 +#define M26_RECV_BYTE_MAX 1000 + +class QUECTEL_M26_CellularStack : public AT_CellularStack { +public: + QUECTEL_M26_CellularStack(ATHandler &atHandler, int cid, nsapi_ip_stack_t stack_type); + virtual ~QUECTEL_M26_CellularStack(); + +protected: // NetworkStack + + 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); + + virtual nsapi_error_t socket_bind(nsapi_socket_t handle, const SocketAddress &address); + + virtual nsapi_error_t socket_connect(nsapi_socket_t handle, const SocketAddress &address); + +protected: // AT_CellularStack + + virtual nsapi_error_t socket_stack_init(); + + virtual int get_max_socket_count(); + + virtual bool is_protocol_supported(nsapi_protocol_t protocol); + + virtual nsapi_error_t socket_close_impl(int sock_id); + + 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); + + virtual nsapi_size_or_error_t socket_recvfrom_impl(CellularSocket *socket, SocketAddress *address, + void *buffer, nsapi_size_t size); + +private: + // URC handlers + // URC handlers + void urc_qiurc(); + + void handle_open_socket_response(int &modem_connect_id, int &err); +}; +} // namespace mbed +#endif /* QUECTEL_M26_CELLULARSTACK_H_ */ diff --git a/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT.cpp b/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT.cpp index 86e4b72be3..5532b45b93 100644 --- a/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT.cpp +++ b/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT.cpp @@ -23,7 +23,7 @@ using namespace mbed; using namespace events; -#ifdef TARGET_UBLOX_C030_R410M +#ifdef TARGET_UBLOX_C030_R41XM static const AT_CellularBase::SupportedFeature unsupported_features[] = { AT_CellularBase::AT_CGSN_WITH_TYPE, AT_CellularBase::SUPPORTED_FEATURE_END_MARK @@ -32,7 +32,7 @@ static const AT_CellularBase::SupportedFeature unsupported_features[] = { UBLOX_AT::UBLOX_AT(FileHandle *fh) : AT_CellularDevice(fh) { -#ifdef TARGET_UBLOX_C030_R410M +#ifdef TARGET_UBLOX_C030_R41XM AT_CellularBase::set_unsupported_features(unsupported_features); #endif } diff --git a/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT_CellularContext.cpp b/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT_CellularContext.cpp index 240710239e..c06cf6d119 100644 --- a/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT_CellularContext.cpp +++ b/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT_CellularContext.cpp @@ -50,7 +50,7 @@ void UBLOX_AT_CellularContext::do_connect() _cb_data.error = NSAPI_ERROR_NO_CONNECTION; // Attempt to establish a connection -#ifdef TARGET_UBLOX_C030_R410M +#ifdef TARGET_UBLOX_C030_R41XM _cb_data.error = NSAPI_ERROR_OK; #else _cb_data.error = open_data_channel(); diff --git a/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT_CellularNetwork.cpp b/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT_CellularNetwork.cpp index 85b06a4c7e..1491deee60 100644 --- a/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT_CellularNetwork.cpp +++ b/features/cellular/framework/targets/UBLOX/AT/UBLOX_AT_CellularNetwork.cpp @@ -54,10 +54,10 @@ nsapi_error_t UBLOX_AT_CellularNetwork::set_access_technology_impl(RadioAccessTe break; case RAT_HSDPA_HSUPA: break; -#elif defined(TARGET_UBLOX_C030_R410M) +#elif defined(TARGET_UBLOX_C030_R41XM) case RAT_CATM1: break; -#elif defined(TARGET_UBLOX_C030_R410M) || defined(TARGET_UBLOX_C030_N211) +#elif defined(TARGET_UBLOX_C030_R41XM) || defined(TARGET_UBLOX_C030_N211) case RAT_NB1: break; #endif diff --git a/features/cryptocell/FEATURE_CRYPTOCELL310/Readme.md b/features/cryptocell/FEATURE_CRYPTOCELL310/Readme.md index 4ab2853ac0..6d584899c2 100644 --- a/features/cryptocell/FEATURE_CRYPTOCELL310/Readme.md +++ b/features/cryptocell/FEATURE_CRYPTOCELL310/Readme.md @@ -24,5 +24,5 @@ To port your CC 310 driver to Mbed OS on your specific target, do the following: 1. In `features/cryptocell/FEATURE_CRYPTOCELL310/TARGET_`, add your platform-specific libraries for all toolchains in `TOOLCHAIN_ARM`, `TOOLCHAIN_GCC_ARM` and `TOOLCHAIN_IAR` respectively. 1. Add your CC setup code: * Implement `crypto_platform_setup()` and `crypto_platform_terminate()` to enable CC on your platform, in case you have board-specific setup functionality, required for CC setup. You MUST call 'SaSi_LibInit()` and 'SaSi_LibFini()' respectively in these functions. - * Define `crypto_platform_ctx` in `crypto_platform.h` in a way that suits your implementation. + * Define `crypto_platform_ctx` in `crypto_device_platform.h` in a way that suits your implementation. diff --git a/features/cryptocell/FEATURE_CRYPTOCELL310/TARGET_MCU_NRF52840/crypto_platform.c b/features/cryptocell/FEATURE_CRYPTOCELL310/TARGET_MCU_NRF52840/crypto_device_platform.c similarity index 100% rename from features/cryptocell/FEATURE_CRYPTOCELL310/TARGET_MCU_NRF52840/crypto_platform.c rename to features/cryptocell/FEATURE_CRYPTOCELL310/TARGET_MCU_NRF52840/crypto_device_platform.c diff --git a/features/cryptocell/FEATURE_CRYPTOCELL310/TARGET_MCU_NRF52840/crypto_platform.h b/features/cryptocell/FEATURE_CRYPTOCELL310/TARGET_MCU_NRF52840/crypto_device_platform.h similarity index 100% rename from features/cryptocell/FEATURE_CRYPTOCELL310/TARGET_MCU_NRF52840/crypto_platform.h rename to features/cryptocell/FEATURE_CRYPTOCELL310/TARGET_MCU_NRF52840/crypto_device_platform.h diff --git a/features/cryptocell/FEATURE_CRYPTOCELL310/trng.c b/features/cryptocell/FEATURE_CRYPTOCELL310/trng.c index 4f1c3991ee..fb2f893d30 100644 --- a/features/cryptocell/FEATURE_CRYPTOCELL310/trng.c +++ b/features/cryptocell/FEATURE_CRYPTOCELL310/trng.c @@ -24,7 +24,7 @@ #include "trng_api.h" #include "mbedtls/platform.h" -extern mbedtls_platform_context ctx; +extern mbedtls_platform_context plat_ctx; static CRYS_RND_WorkBuff_t rndWorkBuff = { { 0 } }; /* Implementation that should never be optimized out by the compiler */ @@ -49,7 +49,7 @@ CRYSError_t LLF_RND_GetTrngSource( void trng_init(trng_t *obj) { - RNG_PLAT_SetUserRngParameters(&ctx.platform_impl_ctx.rndState, obj); + RNG_PLAT_SetUserRngParameters(&plat_ctx.platform_impl_ctx.rndState, obj); } void trng_free(trng_t *obj) @@ -67,7 +67,7 @@ int trng_get_bytes(trng_t *obj, uint8_t *output, size_t length, size_t *outputLe uint32_t actualLength; ret = LLF_RND_GetTrngSource( - &ctx.platform_impl_ctx.rndState , /*in/out*/ + &plat_ctx.platform_impl_ctx.rndState , /*in/out*/ obj, /*in/out*/ 0, /*in*/ &entropySizeBits, /*in/out*/ diff --git a/features/device_key/source/DeviceKey.cpp b/features/device_key/source/DeviceKey.cpp index 016b28c135..3d9b8dac07 100644 --- a/features/device_key/source/DeviceKey.cpp +++ b/features/device_key/source/DeviceKey.cpp @@ -30,6 +30,7 @@ #include "entropy.h" #include "platform_mbed.h" #include "mbed_trace.h" +#include "ssl_internal.h" #define TRACE_GROUP "DEVKEY" @@ -260,12 +261,14 @@ int DeviceKey::generate_key_by_random(uint32_t *output, size_t size) } #if DEVICE_TRNG + uint32_t test_buff[DEVICE_KEY_32BYTE / sizeof(int)]; mbedtls_entropy_context *entropy = new mbedtls_entropy_context; mbedtls_entropy_init(entropy); memset(output, 0, size); + memset(test_buff, 0, size); ret = mbedtls_entropy_func(entropy, (unsigned char *)output, size); - if (ret != MBED_SUCCESS) { + if (ret != MBED_SUCCESS || mbedtls_ssl_safer_memcmp(test_buff, (unsigned char *)output, size) == 0) { ret = DEVICEKEY_GENERATE_RANDOM_ERROR; } else { ret = DEVICEKEY_SUCCESS; diff --git a/features/mbedtls/platform/inc/platform_alt.h b/features/mbedtls/platform/inc/platform_alt.h index 687be6d642..92e9c33364 100644 --- a/features/mbedtls/platform/inc/platform_alt.h +++ b/features/mbedtls/platform/inc/platform_alt.h @@ -22,7 +22,7 @@ #define __PLATFORM_ALT__ #include "platform_mbed.h" #if defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT) -#include "crypto_platform.h" +#include "crypto_device_platform.h" /** * \brief The platform context structure. * diff --git a/features/mbedtls/platform/src/platform_alt.c b/features/mbedtls/platform/src/platform_alt.c index d3250d1105..c0254de9dc 100644 --- a/features/mbedtls/platform/src/platform_alt.c +++ b/features/mbedtls/platform/src/platform_alt.c @@ -22,30 +22,30 @@ #if defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT) #include "mbed_critical.h" -mbedtls_platform_context ctx = { { 0 } }; +mbedtls_platform_context plat_ctx = { { 0 } }; int mbedtls_platform_setup( mbedtls_platform_context *unused_ctx ) { int ret = 0; - core_util_atomic_incr_u32( ( volatile uint32_t * )&ctx.reference_count, 1 ); + core_util_atomic_incr_u32( ( volatile uint32_t * )&plat_ctx.reference_count, 1 ); - if( ctx.reference_count == 1 ) + if( plat_ctx.reference_count == 1 ) { /* call platform specific code to setup crypto driver */ - ret = crypto_platform_setup( &ctx.platform_impl_ctx ); + ret = crypto_platform_setup( &plat_ctx.platform_impl_ctx ); } return ( ret ); } void mbedtls_platform_teardown( mbedtls_platform_context *unused_ctx ) { - core_util_atomic_decr_u32( ( volatile uint32_t * )&ctx.reference_count, 1 ); - if( ctx.reference_count < 1 ) + core_util_atomic_decr_u32( ( volatile uint32_t * )&plat_ctx.reference_count, 1 ); + if( plat_ctx.reference_count < 1 ) { /* call platform specific code to terminate crypto driver */ - crypto_platform_terminate( &ctx.platform_impl_ctx ); - ctx.reference_count = 0; + crypto_platform_terminate( &plat_ctx.platform_impl_ctx ); + plat_ctx.reference_count = 0; } } diff --git a/features/nanostack/mbed-mesh-api/mbed_lib.json b/features/nanostack/mbed-mesh-api/mbed_lib.json index b24664c78a..fee1171b58 100644 --- a/features/nanostack/mbed-mesh-api/mbed_lib.json +++ b/features/nanostack/mbed-mesh-api/mbed_lib.json @@ -161,6 +161,9 @@ }, "NCS36510": { "mbed-mesh-api.heap-size": 14000 + }, + "KW41Z": { + "mbed-mesh-api.heap-size": 14000 } } } diff --git a/features/nanostack/sal-stack-nanostack/mbed_lib.json b/features/nanostack/sal-stack-nanostack/mbed_lib.json index b69dd1c4f1..2881711667 100644 --- a/features/nanostack/sal-stack-nanostack/mbed_lib.json +++ b/features/nanostack/sal-stack-nanostack/mbed_lib.json @@ -16,6 +16,9 @@ }, "TB_SENSE_12": { "nanostack.configuration": "lowpan_router" + }, + "KW41Z": { + "nanostack.configuration": "lowpan_router" } } } 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 a6530d4ba1..48883d2aea 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 @@ -759,7 +759,7 @@ static void thread_host_child_update_request_process(protocol_interface_info_ent uint64_t pending_timestamp = 0;// means no pending timestamp mac_neighbor_table_entry_t *entry_temp; bool data_request_needed = false; - mle_tlv_info_t tlv_info = {0}; + mle_tlv_info_t tlv_info = {MLE_TYPE_SRC_ADDRESS, 0, 0}; tr_debug("Child update request"); entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL); @@ -831,7 +831,7 @@ static void thread_parse_child_update_response(protocol_interface_info_entry_t * thread_leader_data_t leaderData = {0}; uint8_t status; bool leader_data_received; - mle_tlv_info_t tlv_info = {0}; + mle_tlv_info_t tlv_info = {MLE_TYPE_SRC_ADDRESS, 0, 0}; if (cur->thread_info->thread_endnode_parent == NULL) { return; diff --git a/features/nanostack/targets/TARGET_NXP/TARGET_KW41Z/NanostackRfPhyKw41z.cpp b/features/nanostack/targets/TARGET_NXP/TARGET_KW41Z/NanostackRfPhyKw41z.cpp new file mode 100644 index 0000000000..9ac086d771 --- /dev/null +++ b/features/nanostack/targets/TARGET_NXP/TARGET_KW41Z/NanostackRfPhyKw41z.cpp @@ -0,0 +1,1093 @@ +/* +* Copyright (c) 2016-2018 ARM Limited. All rights reserved. +* SPDX-License-Identifier: Apache-2.0 +* Licensed under the Apache License, Version 2.0 (the License); you may +* not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an AS IS BASIS, WITHOUT +* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#include "common_functions.h" +#include "platform/arm_hal_interrupt.h" +#include "platform/arm_hal_phy.h" +#include "NanostackRfPhyKw41z.h" + +#include "fsl_xcvr.h" + +#define RF_THREAD_STACK_SIZE 1024 + +static void rf_thread_loop(); +Thread rf_thread(osPriorityRealtime, RF_THREAD_STACK_SIZE); + +#define PHY_MTU_SIZE 127 +#define CRC_LENGTH 0 +#define PHY_HEADER_LENGTH 0 + +#define BM_ZLL_IRQSTS_TMRxMSK (ZLL_IRQSTS_TMR1MSK_MASK | \ + ZLL_IRQSTS_TMR2MSK_MASK | \ + ZLL_IRQSTS_TMR3MSK_MASK | \ + ZLL_IRQSTS_TMR4MSK_MASK) + +#define RF_CCA_THRESHOLD 75 /* -75 dBm */ + +#define gPhyDefaultTxPowerLevel_d (22) +#define gPhyMaxTxPowerLevel_d (32) +#define gCcaED_c (0) +#define gCcaCCA_MODE1_c (1) + +#define gPhyTimeMask_c (0x00FFFFFF) + +#define KW41Z_SHR_PHY_TIME 12 +#define KW41Z_PER_BYTE_TIME 2 +#define KW41Z_ACK_WAIT_TIME 54 + +static int8_t rf_radio_driver_id = -1; +static uint8_t need_ack = 0; + +/* PHY states */ +typedef enum xcvrState_tag { + gIdle_c, + gRX_c, + gTX_c, + gCCA_c, + gTR_c, + gCCCA_c, +} xcvrState_t; + +static int8_t rf_interface_state_control(phy_interface_state_e new_state, uint8_t rf_channel); +static int8_t rf_start_cca(uint8_t *data_ptr, uint16_t data_length, uint8_t tx_handle, data_protocol_e data_protocol); +static int8_t rf_address_write(phy_address_type_e address_type, uint8_t *address_ptr); +static int8_t rf_extension(phy_extension_type_e extension_type, uint8_t *data_ptr); +static void rf_mac_hw_init(void); +static void rf_mac_ed_state_enable(void); +static void rf_mac_set_pending(uint8_t status); +static void rf_mac_set_shortAddress(uint8_t* valueAddress); +static void rf_mac_set_panId(uint8_t* valueAddress); +static void rf_mac_set_mac64(const uint8_t* valueAddress); +static uint8_t rf_convert_energy_level(uint8_t energyLevel); +static void rf_abort(void); +static void rf_ack_wait_timer_start(uint16_t time); +static void rf_get_timestamp(uint32_t *pRetClk); +static uint32_t rf_get_timeout(void); +static void rf_set_timeout(uint32_t timeout); +static void rf_promiscuous(uint8_t state); +static void handle_IRQ_events(void); +static uint8_t PhyPlmeSetCurrentChannelRequest(uint8_t channel, uint8_t pan); +static void rf_receive(void); +static void rf_handle_rx_end(void); + +static uint8_t MAC64_addr_default[8] = {1, 2, 3, 4, 5, 6, 7, 8}; +static uint8_t MAC64_addr[8]; + +static xcvrState_t mPhySeqState; +static uint8_t rf_mac_handle; +volatile uint8_t rf_ed_value = 0; +static bool rf_ack_pending_state = false; + +static NanostackRfPhyKw41z *rf = NULL; + +#define MAC_PACKET_SIZE 127 //MAX MAC payload is 127 bytes +static uint8_t PHYPAYLOAD[MAC_PACKET_SIZE]; + +const phy_rf_channel_configuration_s phy_2_4ghz = {2405000000U, 5000000U, 250000U, 16U, M_OQPSK}; + +const phy_device_channel_page_s phy_channel_pages[] = { + {CHANNEL_PAGE_0, &phy_2_4ghz}, + {CHANNEL_PAGE_0, NULL} +}; + +static phy_device_driver_s device_driver = { + PHY_LINK_15_4_2_4GHZ_TYPE, + PHY_LAYER_PAYLOAD_DATA_FLOW, + MAC64_addr, + PHY_MTU_SIZE, + (char*)"NXP kw41z", + CRC_LENGTH, + PHY_HEADER_LENGTH, + &rf_interface_state_control, + &rf_start_cca, + &rf_address_write, + &rf_extension, + phy_channel_pages, + NULL, + NULL, + NULL, + NULL +}; + +static void rf_thread_loop() +{ + for (;;) { + ThisThread::flags_wait_all(1); + + platform_enter_critical(); + + handle_IRQ_events(); + + platform_exit_critical(); + NVIC_ClearPendingIRQ(Radio_1_IRQn); + NVIC_EnableIRQ(Radio_1_IRQn); + } +} + +static int8_t rf_device_register(void) +{ + if (rf_radio_driver_id < 0) { + rf_mac_hw_init(); + /** + * Read factory stored Mac address to RAM + */ + common_write_32_bit(ZLL->MACLONGADDRS0_MSB, MAC64_addr); + common_write_32_bit(ZLL->MACLONGADDRS0_LSB, MAC64_addr + 4); + + rf_radio_driver_id = arm_net_phy_register(&device_driver); + } + + return rf_radio_driver_id; +} + +static void rf_device_unregister(void) +{ + arm_net_phy_unregister(rf_radio_driver_id); +} + +/* + * \brief Function enables/disables Rx promiscuous mode. + * + * \param state of XCVR promiscuous mode + * + * \return none + */ +static void rf_promiscuous(uint8_t state) +{ + if (state) { + ZLL->PHY_CTRL |= ZLL_PHY_CTRL_PROMISCUOUS_MASK; + /* FRM_VER[11:8] = b1111. Any FrameVersion accepted */ + ZLL->RX_FRAME_FILTER |= (ZLL_RX_FRAME_FILTER_FRM_VER_FILTER_MASK | + ZLL_RX_FRAME_FILTER_ACK_FT_MASK | + ZLL_RX_FRAME_FILTER_NS_FT_MASK); + } else { + ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_PROMISCUOUS_MASK; + /* FRM_VER[11:8] = b0011. Accept FrameVersion 0 and 1 packets, reject all others */ + /* Beacon, Data and MAC command frame types accepted */ + ZLL->RX_FRAME_FILTER &= ~(ZLL_RX_FRAME_FILTER_FRM_VER_FILTER_MASK | + ZLL_RX_FRAME_FILTER_ACK_FT_MASK | + ZLL_RX_FRAME_FILTER_NS_FT_MASK | + ZLL_RX_FRAME_FILTER_ACTIVE_PROMISCUOUS_MASK); + ZLL->RX_FRAME_FILTER |= ZLL_RX_FRAME_FILTER_FRM_VER_FILTER(3); + } +} + +static void rf_mac_set_pending(uint8_t status) +{ + uint32_t reg = ZLL->SAM_TABLE; + + /* Disable the Source Address Matching feature and set FP manually */ + reg |= ZLL_SAM_TABLE_ACK_FRM_PND_CTRL_MASK; + if (status) { + reg |= ZLL_SAM_TABLE_ACK_FRM_PND_MASK; + rf_ack_pending_state = true; + } else { + reg &= ~ZLL_SAM_TABLE_ACK_FRM_PND_MASK; + rf_ack_pending_state = false; + } + ZLL->SAM_TABLE = reg; +} + +static int8_t rf_interface_state_control(phy_interface_state_e new_state, uint8_t rf_channel) +{ + platform_enter_critical(); + + switch (new_state) + { + /*Reset PHY driver and set to idle*/ + case PHY_INTERFACE_RESET: + rf_abort(); + break; + /*Disable PHY Interface driver*/ + case PHY_INTERFACE_DOWN: + rf_abort(); + break; + /*Enable PHY Interface driver*/ + case PHY_INTERFACE_UP: + if (PhyPlmeSetCurrentChannelRequest(rf_channel, 0)) { + return 1; + } + rf_receive(); + break; + /*Enable wireless interface ED scan mode*/ + case PHY_INTERFACE_RX_ENERGY_STATE: + if (PhyPlmeSetCurrentChannelRequest(rf_channel, 0)) { + return 1; + } + rf_abort(); + rf_mac_ed_state_enable(); + break; + case PHY_INTERFACE_SNIFFER_STATE: /**< Enable Sniffer state */ + rf_promiscuous(1); + if (PhyPlmeSetCurrentChannelRequest(rf_channel, 0)) { + return 1; + } + rf_receive(); + break; + } + + platform_exit_critical(); + + return 0; +} + +/* + * \brief Function forces the XCVR to Idle state. + * + * \param none + * + * \return none + */ +static void rf_abort(void) +{ + /* Mask XCVR irq */ + NVIC_DisableIRQ(Radio_1_IRQn); + + mPhySeqState = gIdle_c; + + /* Mask SEQ interrupt */ + ZLL->PHY_CTRL |= ZLL_PHY_CTRL_SEQMSK_MASK; + + /* Disable timer trigger (for scheduled XCVSEQ) */ + if (ZLL->PHY_CTRL & ZLL_PHY_CTRL_TMRTRIGEN_MASK) { + ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_TMRTRIGEN_MASK; + /* give the FSM enough time to start if it was triggered */ + while( (XCVR_MISC->XCVR_CTRL & XCVR_CTRL_XCVR_STATUS_TSM_COUNT_MASK) == 0) {} + } + + /* If XCVR is not idle, abort current SEQ */ + if (ZLL->PHY_CTRL & ZLL_PHY_CTRL_XCVSEQ_MASK) { + /* Abort current SEQ */ + ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_XCVSEQ_MASK; + + /* Wait for Sequence Idle (if not already) */ + while (ZLL->SEQ_STATE & ZLL_SEQ_STATE_SEQ_STATE_MASK) {} + } + + /* Stop timers */ + ZLL->PHY_CTRL &= ~(ZLL_PHY_CTRL_TMR1CMP_EN_MASK | + ZLL_PHY_CTRL_TMR2CMP_EN_MASK | + ZLL_PHY_CTRL_TMR3CMP_EN_MASK | + ZLL_PHY_CTRL_TC3TMOUT_MASK); + + /* clear all IRQ bits to avoid unexpected interrupts */ + ZLL->IRQSTS = ZLL->IRQSTS; + + /* Unmask XCVR irq */ + NVIC_EnableIRQ(Radio_1_IRQn); +} + +static int8_t rf_start_cca(uint8_t *data_ptr, uint16_t data_length, uint8_t tx_handle, data_protocol_e data_protocol) +{ + uint32_t reg, tx_len; + uint32_t irqSts; + volatile uint8_t *pPB; + uint8_t i; + uint32_t tx_warmup_time; + + platform_enter_critical(); + + if (mPhySeqState == gRX_c) { + rf_abort(); + } + + /* Check if transmitter is busy*/ + if (mPhySeqState != gIdle_c) { + platform_exit_critical(); + /*Return busy*/ + return -1; + } + + /*Store TX handle*/ + rf_mac_handle = tx_handle; + + /* Check if transmitted data needs to be acked */ + need_ack = (*data_ptr & 0x20) == 0x20; + + /* Load data into Packet Buffer */ + pPB = (uint8_t*)ZLL->PKT_BUFFER_TX; + + tx_len = data_length + 2; + *pPB++ = tx_len; /* including 2 bytes of FCS */ + + for (i = 0; i < data_length; i++) { + *pPB++ = *data_ptr++; + } + + reg = ZLL->PHY_CTRL; + + /* Perform CCA before TX */ + reg |= ZLL_PHY_CTRL_CCABFRTX_MASK; + + /* Set CCA mode 1 */ + reg &= ~(ZLL_PHY_CTRL_CCATYPE_MASK); + reg |= ZLL_PHY_CTRL_CCATYPE(gCcaCCA_MODE1_c); + ZLL->PHY_CTRL = reg; + + /* Perform TxRxAck sequence if required by phyTxMode */ + if (need_ack) { + ZLL->PHY_CTRL |= ZLL_PHY_CTRL_RXACKRQD_MASK; + mPhySeqState = gTR_c; + } else { + ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_RXACKRQD_MASK; + mPhySeqState = gTX_c; + } + + /* Ensure that no spurious interrupts are raised */ + irqSts = ZLL->IRQSTS; + irqSts &= ~(ZLL_IRQSTS_TMR1IRQ_MASK | ZLL_IRQSTS_TMR4IRQ_MASK); + irqSts |= ZLL_IRQSTS_TMR3MSK_MASK; + ZLL->IRQSTS = irqSts; + + tx_warmup_time = (XCVR_TSM->END_OF_SEQ & XCVR_TSM_END_OF_SEQ_END_OF_TX_WU_MASK) >> + XCVR_TSM_END_OF_SEQ_END_OF_TX_WU_SHIFT; + + /* Compute warmup times (scaled to 16us) */ + if (tx_warmup_time & 0x0F) { + tx_warmup_time = 1 + (tx_warmup_time >> 4); + } else { + tx_warmup_time = tx_warmup_time >> 4; + } + + if (need_ack) { + rf_ack_wait_timer_start(tx_warmup_time + KW41Z_SHR_PHY_TIME + + tx_len * KW41Z_PER_BYTE_TIME + 10 + KW41Z_ACK_WAIT_TIME); + } + + /* Unmask SEQ interrupt */ + ZLL->PHY_CTRL &= ~(ZLL_PHY_CTRL_SEQMSK_MASK); + + /* Start the TX / TRX */ + reg = ZLL->PHY_CTRL; + reg &= ~(ZLL_PHY_CTRL_XCVSEQ_MASK); + reg |= mPhySeqState; + ZLL->PHY_CTRL = reg; + + platform_exit_critical(); + + /*Return success*/ + return 0; +} + +static int8_t rf_address_write(phy_address_type_e address_type, uint8_t *address_ptr) +{ + int8_t ret_val = 0; + + platform_enter_critical(); + + switch (address_type) { + case PHY_MAC_64BIT: + rf_mac_set_mac64(address_ptr); + break; + /*Set 16-bit address*/ + case PHY_MAC_16BIT: + rf_mac_set_shortAddress(address_ptr); + break; + /*Set PAN Id*/ + case PHY_MAC_PANID: + rf_mac_set_panId(address_ptr); + break; + default: + ret_val = -1; + } + + platform_exit_critical(); + + return ret_val; +} + +static int8_t rf_extension(phy_extension_type_e extension_type, uint8_t *data_ptr) +{ + int ret_value = 0; + + platform_enter_critical(); + + switch (extension_type) { + case PHY_EXTENSION_CTRL_PENDING_BIT: /**< Control MAC pending bit for indirect data. */ + rf_mac_set_pending(*data_ptr); + break; + /* Return frame Auto Ack frame pending status */ + case PHY_EXTENSION_READ_LAST_ACK_PENDING_STATUS: { + *data_ptr = rf_ack_pending_state; + break; + } + case PHY_EXTENSION_SET_CHANNEL: /**< Net library channel set. */ + break; + case PHY_EXTENSION_READ_CHANNEL_ENERGY: /**< RF interface ED scan energy read. */ + *data_ptr = rf_ed_value; + break; + case PHY_EXTENSION_READ_LINK_STATUS: /**< Net library could read link status. */ + case PHY_EXTENSION_CONVERT_SIGNAL_INFO: /**< Convert signal info. */ + default: + ret_value = -1; + } + + platform_exit_critical(); + + return ret_value; +} + +/* + * \brief Function converts the energy level from dBm to a 0-255 value. + * + * \param energyLevel in dBm + * + * \return energy level (0-255) + */ +static uint8_t rf_convert_energy_level(uint8_t energyLevel) +{ + int32_t temp = (int8_t)energyLevel; + + if (temp <= -82) { + temp = 0x00; + } else if (temp >= -3) { + temp = 0xFF; + } else { + /* Convert energy level from dbm into a 0x00-0xFF value */ + temp = (255 * temp + 20910) / 79; + } + + return (uint8_t)temp; +} + +/** + * SET MAC 16 address to Register + */ +static void rf_mac_set_shortAddress(uint8_t* valueAddress) { + ZLL->MACSHORTADDRS0 &= ~ZLL_MACSHORTADDRS0_MACSHORTADDRS0_MASK; + ZLL->MACSHORTADDRS0 |= ZLL_MACSHORTADDRS0_MACSHORTADDRS0(common_read_16_bit(valueAddress)); +} + +/** + * SET PAN-ID to Register + */ +static void rf_mac_set_panId(uint8_t* valueAddress) { + ZLL->MACSHORTADDRS0 &= ~ZLL_MACSHORTADDRS0_MACPANID0_MASK; + ZLL->MACSHORTADDRS0 |= ZLL_MACSHORTADDRS0_MACPANID0(common_read_16_bit(valueAddress)); +} + +/** + * SET MAC64 address to register + */ +static void rf_mac_set_mac64(const uint8_t* valueAddress) { + ZLL->MACLONGADDRS0_MSB = common_read_32_bit(valueAddress); + valueAddress += 4; + ZLL->MACLONGADDRS0_LSB = common_read_32_bit(valueAddress); +} + +static void PhyPlmeSetPwrLevelRequest(uint8_t pwrStep) +{ + /* Do not exceed the Tx power limit for the current channel */ + if (pwrStep > gPhyMaxTxPowerLevel_d) { + pwrStep = gPhyMaxTxPowerLevel_d; + } + + if (pwrStep > 2) { + pwrStep = (pwrStep << 1) - 2; + } + + ZLL->PA_PWR = pwrStep; +} + +static uint8_t PhyPlmeGetPwrLevelRequest(void) +{ + uint8_t pwrStep = (uint8_t)ZLL->PA_PWR; + + if (pwrStep > 2) { + pwrStep = (pwrStep + 2) >> 1; + } + + return pwrStep; +} + +static uint8_t PhyPlmeSetCurrentChannelRequest(uint8_t channel, uint8_t pan) +{ + if((channel < 11) || (channel > 26)) { + return 1; + } + + if (!pan) { + ZLL->CHANNEL_NUM0 = channel; + } else { + ZLL->CHANNEL_NUM1 = channel; + } + + /* Make sure the current Tx power doesn't exceed the Tx power limit for the new channel */ + if (PhyPlmeGetPwrLevelRequest() > gPhyMaxTxPowerLevel_d) { + PhyPlmeSetPwrLevelRequest(gPhyMaxTxPowerLevel_d); + } + + return 0; +} + +/* + * Function is a RF interrupt vector. + */ +static void PHY_InterruptHandler(void) +{ + /* Disable and clear transceiver(IRQ_B) interrupt */ + NVIC_DisableIRQ(Radio_1_IRQn); + rf_thread.flags_set(1); +} + +static void PhyIsrSeqCleanup(void) +{ + uint32_t irqStatus; + + /* Set the PHY sequencer back to IDLE */ + ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_XCVSEQ_MASK; + /* Mask SEQ, RX, TX and CCA interrupts */ + ZLL->PHY_CTRL |= ZLL_PHY_CTRL_CCAMSK_MASK | + ZLL_PHY_CTRL_RXMSK_MASK | + ZLL_PHY_CTRL_TXMSK_MASK | + ZLL_PHY_CTRL_SEQMSK_MASK; + + while (ZLL->SEQ_STATE & ZLL_SEQ_STATE_SEQ_STATE_MASK) {} + + irqStatus = ZLL->IRQSTS; + /* Mask TMR3 interrupt */ + irqStatus |= ZLL_IRQSTS_TMR3MSK_MASK; + /* Clear transceiver interrupts except TMRxIRQ */ + irqStatus &= ~(ZLL_IRQSTS_TMR1IRQ_MASK | + ZLL_IRQSTS_TMR2IRQ_MASK | + ZLL_IRQSTS_TMR3IRQ_MASK | + ZLL_IRQSTS_TMR4IRQ_MASK); + ZLL->IRQSTS = irqStatus; +} + +static void PhyIsrTimeoutCleanup(void) +{ + uint32_t irqStatus; + + /* Set the PHY sequencer back to IDLE and disable TMR3 comparator and timeout */ + ZLL->PHY_CTRL &= ~(ZLL_PHY_CTRL_TMR3CMP_EN_MASK | + ZLL_PHY_CTRL_TC3TMOUT_MASK | + ZLL_PHY_CTRL_XCVSEQ_MASK); + /* Mask SEQ, RX, TX and CCA interrupts */ + ZLL->PHY_CTRL |= ZLL_PHY_CTRL_CCAMSK_MASK | + ZLL_PHY_CTRL_RXMSK_MASK | + ZLL_PHY_CTRL_TXMSK_MASK | + ZLL_PHY_CTRL_SEQMSK_MASK; + + while (ZLL->SEQ_STATE & ZLL_SEQ_STATE_SEQ_STATE_MASK) {} + + irqStatus = ZLL->IRQSTS; + /* Mask TMR3 interrupt */ + irqStatus |= ZLL_IRQSTS_TMR3MSK_MASK; + /* Clear transceiver interrupts except TMR1IRQ and TMR4IRQ. */ + irqStatus &= ~( ZLL_IRQSTS_TMR1IRQ_MASK | + ZLL_IRQSTS_TMR4IRQ_MASK ); + ZLL->IRQSTS = irqStatus; + + /* The packet was transmitted successfully, but no ACK was received */ + if (device_driver.phy_tx_done_cb) { + device_driver.phy_tx_done_cb(rf_radio_driver_id, rf_mac_handle, PHY_LINK_TX_SUCCESS, 1, 1); + } +} + +/* + * \brief Function get the time-out for the current sequence. + * + * \return sequence time-out value + */ +static uint32_t rf_get_timeout(void) +{ + return ZLL->T3CMP; +} + +/* + * \brief Function set a time-out to an XCVR sequence. + * + * \param pEndTime sequence time-out value [symbols] + * + * \return none + */ +static void rf_set_timeout(uint32_t pEndTime) +{ + uint32_t irqsts; + + platform_enter_critical(); + + /* disable TMR3 compare */ + ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_TMR3CMP_EN_MASK; + ZLL->T3CMP = pEndTime & ZLL_T3CMP_T3CMP_MASK; + + /* acknowledge TMR3 IRQ */ + irqsts = ZLL->IRQSTS & BM_ZLL_IRQSTS_TMRxMSK; + irqsts |= ZLL_IRQSTS_TMR3IRQ_MASK; + ZLL->IRQSTS = irqsts; + /* enable TMR3 compare */ + ZLL->PHY_CTRL |= ZLL_PHY_CTRL_TMR3CMP_EN_MASK; + /* enable autosequence stop by TC3 match */ + ZLL->PHY_CTRL |= ZLL_PHY_CTRL_TC3TMOUT_MASK; + + platform_exit_critical(); + +} + +/** + * Call this only One time + */ +static void rf_mac_hw_init(void) +{ + xcvrStatus_t xcvrStatus; + uint32_t phyReg; + + /* The data rate argument only matters when GFSK/MSK protocol is selected */ + xcvrStatus = XCVR_Init(ZIGBEE_MODE, DR_500KBPS); + if (xcvrStatus != gXcvrSuccess_c) { + return; + } + + mPhySeqState = gIdle_c; + + /* Enable 16 bit mode for TC2 - TC2 prime EN, disable all timers, + enable AUTOACK, mask all interrupts */ + ZLL->PHY_CTRL = (gCcaCCA_MODE1_c << ZLL_PHY_CTRL_CCATYPE_SHIFT) | + ZLL_PHY_CTRL_TC2PRIME_EN_MASK | + ZLL_PHY_CTRL_TSM_MSK_MASK | + ZLL_PHY_CTRL_WAKE_MSK_MASK | + ZLL_PHY_CTRL_CRC_MSK_MASK | + ZLL_PHY_CTRL_PLL_UNLOCK_MSK_MASK | + ZLL_PHY_CTRL_FILTERFAIL_MSK_MASK | + ZLL_PHY_CTRL_RX_WMRK_MSK_MASK | + ZLL_PHY_CTRL_CCAMSK_MASK | + ZLL_PHY_CTRL_RXMSK_MASK | + ZLL_PHY_CTRL_TXMSK_MASK | + ZLL_PHY_CTRL_SEQMSK_MASK | + ZLL_PHY_CTRL_AUTOACK_MASK | + ZLL_PHY_CTRL_TRCV_MSK_MASK; + + /* Clear all PP IRQ bits to avoid unexpected interrupts immediately after init + disable all timer interrupts */ + ZLL->IRQSTS = ZLL->IRQSTS; + + /* Clear HW indirect queue */ + ZLL->SAM_TABLE |= ZLL_SAM_TABLE_INVALIDATE_ALL_MASK; + + /* Frame Filtering + FRM_VER[7:6] = b11. Accept FrameVersion 0 and 1 packets, reject all others */ + ZLL->RX_FRAME_FILTER &= ~ZLL_RX_FRAME_FILTER_FRM_VER_FILTER_MASK; + ZLL->RX_FRAME_FILTER = ZLL_RX_FRAME_FILTER_FRM_VER_FILTER(3) | + ZLL_RX_FRAME_FILTER_CMD_FT_MASK | + ZLL_RX_FRAME_FILTER_DATA_FT_MASK | + ZLL_RX_FRAME_FILTER_BEACON_FT_MASK; + + /* Set prescaller to obtain 1 symbol (16us) timebase */ + ZLL->TMR_PRESCALE = 0x05; + + /* Set CCA threshold to -75 dBm */ + ZLL->CCA_LQI_CTRL &= ~ZLL_CCA_LQI_CTRL_CCA1_THRESH_MASK; + ZLL->CCA_LQI_CTRL |= ZLL_CCA_LQI_CTRL_CCA1_THRESH(RF_CCA_THRESHOLD); + + /* Set the default power level */ + PhyPlmeSetPwrLevelRequest(gPhyDefaultTxPowerLevel_d); + + /* Adjust ACK delay to fulfill the 802.15.4 turnaround requirements */ + ZLL->ACKDELAY &= ~ZLL_ACKDELAY_ACKDELAY_MASK; + ZLL->ACKDELAY |= ZLL_ACKDELAY_ACKDELAY(-8); + + /* Adjust LQI compensation */ + ZLL->CCA_LQI_CTRL &= ~ZLL_CCA_LQI_CTRL_LQI_OFFSET_COMP_MASK; + ZLL->CCA_LQI_CTRL |= ZLL_CCA_LQI_CTRL_LQI_OFFSET_COMP(96); + + /* Enable the RxWatermark IRQ */ + ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_RX_WMRK_MSK_MASK; + /* Set Rx watermark level */ + ZLL->RX_WTR_MARK = 0; + + /* Set default channels */ + PhyPlmeSetCurrentChannelRequest(0x0B, 0); /* 2405 MHz */ + PhyPlmeSetCurrentChannelRequest(0x0B, 1); /* 2405 MHz */ + + /* DSM settings */ + phyReg = (RSIM->RF_OSC_CTRL & RSIM_RF_OSC_CTRL_BB_XTAL_READY_COUNT_SEL_MASK) >> + RSIM_RF_OSC_CTRL_BB_XTAL_READY_COUNT_SEL_SHIFT; + phyReg = (1024U << phyReg) / (SystemCoreClock / 32768) + 1; + RSIM->DSM_OSC_OFFSET = phyReg; + + osStatus status = rf_thread.start(mbed::callback(rf_thread_loop)); + MBED_ASSERT(status == osOK); + + /** Clear and enable MAC IRQ at task level, when scheduler is on. */ + InstallIRQHandler((IRQn_Type)Radio_1_IRQn, (uint32_t)PHY_InterruptHandler); + + /* Unmask Transceiver Global Interrupts */ + ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_TRCV_MSK_MASK; + + NVIC_ClearPendingIRQ(Radio_1_IRQn); + NVIC_EnableIRQ(Radio_1_IRQn); +} + +/* + * \brief Function reads a time-stamp value from XCVR [symbols] + * + * \param pEndTime pointer to location where time-stamp will be stored + * + * \return none + */ +static void rf_get_timestamp(uint32_t *pRetClk) +{ + if (NULL == pRetClk) { + return; + } + + platform_enter_critical(); + + *pRetClk = 0; + *pRetClk = ZLL->EVENT_TMR >> ZLL_EVENT_TMR_EVENT_TMR_SHIFT; + + platform_exit_critical(); +} + +/* + * \brief Function starts the ACK wait time-out. + * + * \param slots The ACK wait time-out in [symbols] + * + * \return none + */ +static void rf_ack_wait_timer_start(uint16_t time) +{ + uint32_t timestamp, t; + + rf_get_timestamp(×tamp); + + t = (rf_get_timeout() - timestamp) & gPhyTimeMask_c; + + if (t > 1) { + timestamp += time; + rf_set_timeout(timestamp); + } +} + +/* + * \brief Function sets the RF in RX state. + * + * \param none + * + * \return none + */ +static void rf_receive(void) +{ + uint32_t irqSts; + + /* RX can start only from Idle state */ + if (mPhySeqState != gIdle_c) { + rf_abort(); + } + + mPhySeqState = gRX_c; + + /* Ensure that no spurious interrupts are raised, but do not change TMR1 and TMR4 IRQ status */ + irqSts = ZLL->IRQSTS; + irqSts &= ~(ZLL_IRQSTS_TMR1IRQ_MASK | ZLL_IRQSTS_TMR4IRQ_MASK); + irqSts |= ZLL_IRQSTS_TMR3MSK_MASK; + ZLL->IRQSTS = irqSts; + + /* unmask SEQ interrupt */ + ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_SEQMSK_MASK; + + /* Start the RX sequence */ + ZLL->PHY_CTRL |= gRX_c; +} + +static void rf_mac_ed_state_enable(void) +{ + uint32_t ccaMode, irqSts; + + mPhySeqState = gCCA_c; + + /* Switch to ED mode */ + ccaMode = (ZLL->PHY_CTRL & ZLL_PHY_CTRL_CCATYPE_MASK) >> ZLL_PHY_CTRL_CCATYPE_SHIFT; + if (ccaMode != gCcaED_c) { + ZLL->PHY_CTRL &= ~(ZLL_PHY_CTRL_CCATYPE_MASK); + } + + /* Ensure that no spurious interrupts are raised(do not change TMR1 and TMR4 IRQ status) */ + irqSts = ZLL->IRQSTS; + irqSts &= ~(ZLL_IRQSTS_TMR1IRQ_MASK | ZLL_IRQSTS_TMR4IRQ_MASK); + irqSts |= ZLL_IRQSTS_TMR3MSK_MASK; + ZLL->IRQSTS = irqSts; + + /* Unmask SEQ interrupt */ + ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_SEQMSK_MASK; + + /* start ED sequence */ + ZLL->PHY_CTRL |= gCCA_c; +} + +/* + * \brief Function is a call back for TX end interrupt. + * + * \param none + * + * \return none + */ +static void rf_handle_tx_end(bool framePending) +{ + /*Start receiver*/ + rf_receive(); + + if (!device_driver.phy_tx_done_cb) { + return; + } + + /*Call PHY TX Done API*/ + if (need_ack) { + if (framePending) { + device_driver.phy_tx_done_cb(rf_radio_driver_id, rf_mac_handle, PHY_LINK_TX_DONE_PENDING, 1, 1); + } else { + device_driver.phy_tx_done_cb(rf_radio_driver_id, rf_mac_handle, PHY_LINK_TX_DONE, 1, 1); + } + } else { + device_driver.phy_tx_done_cb(rf_radio_driver_id, rf_mac_handle, PHY_LINK_TX_SUCCESS, 1, 1); + } +} + +/* + * \brief Function converts LQI into RSSI. + * + * \param LQI + * + * \return RSSI + */ +static int8_t rf_convert_LQI_to_RSSI(uint8_t lqi) +{ + int32_t rssi = (36 * lqi - 9836) / 109; + + return (int8_t)rssi; +} + +/* + * \brief Function scale the LQI value reported by RF into a 0-255 value. + * + * \param hwLqi - the LQI value reported by RF + * + * \return scaled LQI + */ +static uint8_t rf_convert_LQI(uint8_t hwLqi) +{ + if (hwLqi >= 220) { + return 255; + } else { + return (51 * hwLqi) / 44; + } +} + +/* + * \brief Function is a call back for RX end interrupt. + * + * \param none + * + * \return none + */ +static void rf_handle_rx_end(void) +{ + uint8_t rf_lqi = (ZLL->LQI_AND_RSSI & ZLL_LQI_AND_RSSI_LQI_VALUE_MASK) >> + ZLL_LQI_AND_RSSI_LQI_VALUE_SHIFT; + int8_t rf_rssi = 0; + uint8_t len; + uint8_t i; + volatile uint8_t *pPB; + + len = (ZLL->IRQSTS & ZLL_IRQSTS_RX_FRAME_LENGTH_MASK) >> ZLL_IRQSTS_RX_FRAME_LENGTH_SHIFT; /* Including FCS (2 bytes) */ + + /* Excluding FCS (2 bytes) */ + len -= 2; + + /*Check the length is valid*/ + if (len > 1 && len < MAC_PACKET_SIZE) { + rf_lqi = rf_convert_LQI(rf_lqi); + rf_rssi = rf_convert_LQI_to_RSSI(rf_lqi); + + /* Load data from Packet Buffer */ + pPB = (uint8_t*)ZLL->PKT_BUFFER_RX; + + for (i = 0; i < len; i++) { + PHYPAYLOAD[i] = *pPB++; + } + + /* Start receiver */ + rf_receive(); + + if (device_driver.phy_rx_cb) { + device_driver.phy_rx_cb(PHYPAYLOAD, len, rf_lqi, rf_rssi, rf_radio_driver_id); + } + } else { + /* Start receiver */ + rf_receive(); + } +} + +static void handle_IRQ_events(void) +{ + uint8_t xcvseqCopy; + uint32_t irqStatus; + + /* Read current XCVRSEQ and interrupt status */ + xcvseqCopy = ZLL->PHY_CTRL & ZLL_PHY_CTRL_XCVSEQ_MASK; + irqStatus = ZLL->IRQSTS; + /* Clear all xcvr interrupts */ + ZLL->IRQSTS = irqStatus; + + /* Filter Fail IRQ */ + if (irqStatus & ZLL_IRQSTS_FILTERFAIL_IRQ_MASK) { + + } else { + /* Rx Watermark IRQ */ + if((!(ZLL->PHY_CTRL & ZLL_PHY_CTRL_RX_WMRK_MSK_MASK)) && + (irqStatus & ZLL_IRQSTS_RXWTRMRKIRQ_MASK)) { + uint32_t rx_len = (irqStatus & ZLL_IRQSTS_RX_FRAME_LENGTH_MASK) >> ZLL_IRQSTS_RX_FRAME_LENGTH_SHIFT; + + /* Convert to symbols and add IFS and ACK duration */ + rx_len = rx_len * 2 + 12 + 22 + 2; + rf_ack_wait_timer_start(rx_len); + } + } + + /* Sequencer interrupt, the autosequence has completed */ + if (irqStatus & ZLL_IRQSTS_SEQIRQ_MASK) { + + /* XCVR will be set to Idle */ + mPhySeqState = gIdle_c; + + /* PLL unlock, the autosequence has been aborted due to PLL unlock */ + if (irqStatus & ZLL_IRQSTS_PLL_UNLOCK_IRQ_MASK) { + PhyIsrSeqCleanup(); + /* Start receiver */ + rf_receive(); + } + /* TMR3 timeout, the autosequence has been aborted due to TMR3 timeout */ + else if ((irqStatus & ZLL_IRQSTS_TMR3IRQ_MASK) && + (!(irqStatus & ZLL_IRQSTS_RXIRQ_MASK)) && + (xcvseqCopy != gTX_c)) { + PhyIsrTimeoutCleanup(); + /* Start receiver */ + rf_receive(); + } else { + PhyIsrSeqCleanup(); + switch(xcvseqCopy) + { + case gTX_c: + if ((ZLL->PHY_CTRL & ZLL_PHY_CTRL_CCABFRTX_MASK) && + (irqStatus & ZLL_IRQSTS_CCA_MASK)) { + device_driver.phy_tx_done_cb(rf_radio_driver_id, rf_mac_handle, + PHY_LINK_CCA_FAIL, 1, 1); + } else { + rf_handle_tx_end(false); + } + break; + + case gTR_c: + if ((ZLL->PHY_CTRL & ZLL_PHY_CTRL_CCABFRTX_MASK) && + (irqStatus & ZLL_IRQSTS_CCA_MASK)) { + device_driver.phy_tx_done_cb(rf_radio_driver_id, rf_mac_handle, + PHY_LINK_CCA_FAIL, 1, 1); + } else { + rf_handle_tx_end((irqStatus & ZLL_IRQSTS_RX_FRM_PEND_MASK) > 0); + } + break; + + case gRX_c: + rf_handle_rx_end(); + break; + + case gCCA_c: + rf_ed_value = rf_convert_energy_level((ZLL->LQI_AND_RSSI & + ZLL_LQI_AND_RSSI_CCA1_ED_FNL_MASK) >> + ZLL_LQI_AND_RSSI_CCA1_ED_FNL_SHIFT); + break; + + default: + break; + } + } + } +} + +NanostackRfPhyKw41z::NanostackRfPhyKw41z() +{ + memcpy(MAC64_addr, MAC64_addr_default, sizeof(MAC64_addr)); +} + +NanostackRfPhyKw41z::~NanostackRfPhyKw41z() +{ + // Do nothing +} + +int8_t NanostackRfPhyKw41z::rf_register() +{ + platform_enter_critical(); + + if (rf != NULL) { + platform_exit_critical(); + error("Multiple registrations of NanostackRfPhyKw41z not supported"); + return -1; + } + + rf = this; + int8_t radio_id = rf_device_register(); + if (radio_id < 0) { + rf = NULL; + } + + platform_exit_critical(); + return radio_id; +} + +void NanostackRfPhyKw41z::rf_unregister() +{ + platform_enter_critical(); + + if (rf != this) { + platform_exit_critical(); + return; + } + + rf_device_unregister(); + rf = NULL; + + platform_exit_critical(); +} + +void NanostackRfPhyKw41z::get_mac_address(uint8_t *mac) +{ + platform_enter_critical(); + + memcpy((void*)mac, (void*)MAC64_addr, sizeof(MAC64_addr)); + + platform_exit_critical(); +} + +void NanostackRfPhyKw41z::set_mac_address(uint8_t *mac) +{ + platform_enter_critical(); + + if (NULL != rf) { + error("NanostackRfPhyKw41z cannot change mac address when running"); + platform_exit_critical(); + return; + } + memcpy((void*)MAC64_addr, (void*)mac, sizeof(MAC64_addr)); + + platform_exit_critical(); +} + +NanostackRfPhy &NanostackRfPhy::get_default_instance() +{ + static NanostackRfPhyKw41z rf_phy; + return rf_phy; +} diff --git a/features/nanostack/targets/TARGET_NXP/TARGET_KW41Z/NanostackRfPhyKw41z.h b/features/nanostack/targets/TARGET_NXP/TARGET_KW41Z/NanostackRfPhyKw41z.h new file mode 100644 index 0000000000..c85f6bdca3 --- /dev/null +++ b/features/nanostack/targets/TARGET_NXP/TARGET_KW41Z/NanostackRfPhyKw41z.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2018 ARM Limited. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NANOSTACK_PHY_KW41Z_H_ +#define NANOSTACK_PHY_KW41Z_H_ + +#if MBED_CONF_RTOS_PRESENT +#include "rtos/rtos.h" +#endif +#include "NanostackRfPhy.h" +#include "fsl_common.h" + +class NanostackRfPhyKw41z : public NanostackRfPhy { +public: + NanostackRfPhyKw41z(); + ~NanostackRfPhyKw41z(); + int8_t rf_register(); + void rf_unregister(); + void get_mac_address(uint8_t *mac); + void set_mac_address(uint8_t *mac); +}; + +#endif /* NANOSTACK_PHY_KW41Z_H_ */ diff --git a/features/netsocket/TLSSocketWrapper.h b/features/netsocket/TLSSocketWrapper.h index bffdd97d2b..78451a28f4 100644 --- a/features/netsocket/TLSSocketWrapper.h +++ b/features/netsocket/TLSSocketWrapper.h @@ -168,7 +168,7 @@ public: */ void set_ssl_config(mbedtls_ssl_config *conf); - /** Get internal Mbed TLS contect structure. + /** Get internal Mbed TLS context structure. * @return SSL context */ mbedtls_ssl_context *get_ssl_context(); @@ -198,7 +198,7 @@ protected: private: - /** Continue already initialised handshake */ + /** Continue already initialized handshake */ nsapi_error_t continue_handshake(); /** * Helper for pretty-printing mbed TLS error codes diff --git a/features/netsocket/cellular/generic_modem_driver/PPPCellularInterface.h b/features/netsocket/cellular/generic_modem_driver/PPPCellularInterface.h index 4f98293f3c..b0658c77dd 100644 --- a/features/netsocket/cellular/generic_modem_driver/PPPCellularInterface.h +++ b/features/netsocket/cellular/generic_modem_driver/PPPCellularInterface.h @@ -214,7 +214,7 @@ public: * connection. It doesn't do anything immediately other than setting up flags. * * @param set can be set to true if the SIM pin check is supposed to be enabled - * and vice versa. + * and false if not. */ MBED_DEPRECATED_SINCE("mbed-os-5.9", "This API will be deprecated, use mbed-os/features/cellular/easy_cellular/EasyCellularConnection.h instead.") void set_sim_pin_check(bool set); diff --git a/features/storage/TESTS/blockdevice/general_block_device/main.cpp b/features/storage/TESTS/blockdevice/general_block_device/main.cpp index 6d28ac34e3..df680f75ea 100644 --- a/features/storage/TESTS/blockdevice/general_block_device/main.cpp +++ b/features/storage/TESTS/blockdevice/general_block_device/main.cpp @@ -212,7 +212,7 @@ void test_multi_threads() TEST_ASSERT_EQUAL(0, err); } -void test_get_erase_value() +void test_erase_functionality() { utest_printf("\nTest BlockDevice::get_erase_value()..\n"); @@ -251,36 +251,60 @@ void test_get_erase_value() start_address -= start_address % erase_size; // align with erase_block utest_printf("start_address=0x%016" PRIx64 "\n", start_address); - // Allocate buffer for read test data + // Allocate buffer for write test data uint8_t *data_buf = (uint8_t *)malloc(data_buf_size); TEST_SKIP_UNLESS_MESSAGE(data_buf, "Not enough memory for test.\n"); + // Allocate buffer for read test data + uint8_t *out_data_buf = (uint8_t *)malloc(data_buf_size); + TEST_SKIP_UNLESS_MESSAGE(out_data_buf, "Not enough memory for test.\n"); + + // First must Erase given memory region + utest_printf("erasing given memory region\n"); + err = block_device->erase(start_address, data_buf_size); + TEST_ASSERT_EQUAL(0, err); + // Write random data to selected region to make sure data is not accidentally set to "erased" value. // With this pre-write, the test case will fail even if block_device->erase() is broken. for (bd_size_t i = 0; i < data_buf_size; i++) { data_buf[i] = (uint8_t) rand(); } + utest_printf("writing given memory region\n"); err = block_device->program((const void *)data_buf, start_address, data_buf_size); TEST_ASSERT_EQUAL(0, err); + // Read written memory region to verify it contains information + memset(out_data_buf, 0, data_buf_size); + utest_printf("reading written memory region\n"); + err = block_device->read((void *)out_data_buf, start_address, data_buf_size); + TEST_ASSERT_EQUAL(0, err); + + // Verify erased memory region + utest_printf("verifying written memory region\n"); + for (bd_size_t i = 0; i < data_buf_size; i++) { + TEST_ASSERT_EQUAL(out_data_buf[i], data_buf[i]); + } + // Erase given memory region - utest_printf("erasing given memory region\n"); + utest_printf("erasing written memory region\n"); err = block_device->erase(start_address, data_buf_size); TEST_ASSERT_EQUAL(0, err); // Read erased memory region utest_printf("reading erased memory region\n"); - err = block_device->read((void *)data_buf, start_address, data_buf_size); + memset(out_data_buf, 0, data_buf_size); + err = block_device->read((void *)out_data_buf, start_address, data_buf_size); TEST_ASSERT_EQUAL(0, err); // Verify erased memory region utest_printf("verifying erased memory region\n"); for (bd_size_t i = 0; i < data_buf_size; i++) { - TEST_ASSERT_EQUAL(erase_value, data_buf[i]); + TEST_ASSERT_EQUAL(erase_value, out_data_buf[i]); } free(data_buf); + free(out_data_buf); // BlockDevice deinitialization err = block_device->deinit(); @@ -359,6 +383,11 @@ void test_contiguous_erase_write_read() } utest_printf("write_read_buf_size=%" PRIu64 "\n", (uint64_t)write_read_buf_size); + // Must Erase the whole region first + utest_printf("erasing memory, from 0x%" PRIx64 " of size 0x%" PRIx64 "\n", start_address, contiguous_erase_size); + err = block_device->erase(start_address, contiguous_erase_size); + TEST_ASSERT_EQUAL(0, err); + // Pre-fill the to-be-erased region. By pre-filling the region, // we can be sure the test will not pass if the erase doesn't work. for (bd_size_t offset = 0; start_address + offset < stop_address; offset += write_read_buf_size) { @@ -371,7 +400,7 @@ void test_contiguous_erase_write_read() TEST_ASSERT_EQUAL(0, err); } - // Erase the whole region first + // Erase the whole region again utest_printf("erasing memory, from 0x%" PRIx64 " of size 0x%" PRIx64 "\n", start_address, contiguous_erase_size); err = block_device->erase(start_address, contiguous_erase_size); TEST_ASSERT_EQUAL(0, err); @@ -517,10 +546,10 @@ utest::v1::status_t test_setup(const size_t number_of_cases) } Case cases[] = { + Case("Testing BlockDevice erase functionality", test_erase_functionality, greentea_failure_handler), Case("Testing read write random blocks", test_random_program_read_erase, greentea_failure_handler), Case("Testing multi threads erase program read", test_multi_threads, greentea_failure_handler), Case("Testing contiguous erase, write and read", test_contiguous_erase_write_read, greentea_failure_handler), - Case("Testing BlockDevice::get_erase_value()", test_get_erase_value, greentea_failure_handler), Case("Testing program read small data sizes", test_program_read_small_data_sizes, greentea_failure_handler), Case("Testing get type functionality", test_get_type_functionality, greentea_failure_handler) }; diff --git a/features/storage/TESTS/kvstore/direct_access_devicekey_test/main.cpp b/features/storage/TESTS/kvstore/direct_access_devicekey_test/main.cpp index 781a08fc3f..25704b8b2a 100644 --- a/features/storage/TESTS/kvstore/direct_access_devicekey_test/main.cpp +++ b/features/storage/TESTS/kvstore/direct_access_devicekey_test/main.cpp @@ -245,7 +245,7 @@ void test_direct_access_to_device_inject_root() uint32_t key[DEVICE_KEY_16BYTE / sizeof(uint32_t)]; KVMap &kv_map = KVMap::get_instance(); KVStore *inner_store = kv_map.get_internal_kv_instance(NULL); - TEST_ASSERT_NOT_EQUAL(NULL, inner_store); + TEST_SKIP_UNLESS_MESSAGE(inner_store != NULL, "Test skipped. No KVStore Internal"); BlockDevice *flash_bd = kv_map.get_internal_blockdevice_instance(""); TEST_ASSERT_NOT_EQUAL(NULL, flash_bd); @@ -271,6 +271,20 @@ void test_direct_access_to_device_inject_root() internal_start_address = MBED_CONF_STORAGE_TDB_INTERNAL_INTERNAL_BASE_ADDRESS; internal_rbp_size = MBED_CONF_STORAGE_TDB_INTERNAL_INTERNAL_SIZE; is_conf_tdb_internal = true; + } else if (strcmp(STR(MBED_CONF_STORAGE_STORAGE_TYPE), "default") == 0) { +#if COMPONENT_QSPIF || COMPONENT_SPIF || COMPONENT_DATAFLASH + internal_start_address = MBED_CONF_STORAGE_TDB_EXTERNAL_INTERNAL_BASE_ADDRESS; + internal_rbp_size = MBED_CONF_STORAGE_TDB_EXTERNAL_RBP_INTERNAL_SIZE; +#elif COMPONENT_SD + internal_start_address = MBED_CONF_STORAGE_FILESYSTEM_INTERNAL_BASE_ADDRESS; + internal_rbp_size = MBED_CONF_STORAGE_FILESYSTEM_RBP_INTERNAL_SIZE; +#elif COMPONENT_FLASHIAP + internal_start_address = MBED_CONF_STORAGE_TDB_INTERNAL_INTERNAL_BASE_ADDRESS; + internal_rbp_size = MBED_CONF_STORAGE_TDB_INTERNAL_INTERNAL_SIZE; + is_conf_tdb_internal = true; +#else + TEST_SKIP_UNLESS_MESSAGE(false, "Test skipped. No KVStore Internal"); +#endif } else { TEST_SKIP_UNLESS_MESSAGE(false, "Test skipped. No KVStore Internal"); } diff --git a/features/storage/TESTS/kvstore/static_tests/main.cpp b/features/storage/TESTS/kvstore/static_tests/main.cpp index db6379c8b3..a063d5c4d6 100644 --- a/features/storage/TESTS/kvstore/static_tests/main.cpp +++ b/features/storage/TESTS/kvstore/static_tests/main.cpp @@ -910,6 +910,7 @@ static void iterator_close_right_after_iterator_open() utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) { greentea_case_failure_abort_handler(source, reason); + UnityConcludeTest(); return STATUS_CONTINUE; } diff --git a/features/storage/blockdevice/BufferedBlockDevice.h b/features/storage/blockdevice/BufferedBlockDevice.h index 8b2aad0c4c..f29f7e1281 100644 --- a/features/storage/blockdevice/BufferedBlockDevice.h +++ b/features/storage/blockdevice/BufferedBlockDevice.h @@ -35,35 +35,36 @@ namespace mbed { */ class BufferedBlockDevice : public BlockDevice { public: - /** Lifetime of the memory block device + /** Lifetime of a memory-buffered block device wrapping an underlying block device * * @param bd Block device to back the BufferedBlockDevice */ BufferedBlockDevice(BlockDevice *bd); - /** Lifetime of a block device + /** Lifetime of the memory-buffered block device */ virtual ~BufferedBlockDevice(); - /** Initialize a block device + /** Initialize a buffered-memory block device and its underlying block device * * @return 0 on success or a negative error code on failure */ virtual int init(); - /** Deinitialize a block device + /** Deinitialize the buffered-memory block device and its underlying block device * * @return 0 on success or a negative error code on failure */ virtual int deinit(); - /** Ensure data on storage is in sync with the driver + /** Ensure that data on the underlying storage block device is in sync with the + * memory-buffered block device * * @return 0 on success or a negative error code on failure */ virtual int sync(); - /** Read blocks from a block device + /** Read blocks from the memory-buffered block device * * @param buffer Buffer to read blocks into * @param addr Address of block to begin reading from @@ -72,9 +73,9 @@ public: */ virtual int read(void *buffer, bd_addr_t addr, bd_size_t size); - /** Program blocks to a block device + /** Program data to the memory-buffered block device * - * The blocks must have been erased prior to being programmed + * The write address blocks must be erased prior to being programmed. * * @param buffer Buffer of data to write to blocks * @param addr Address of block to begin writing to @@ -83,10 +84,10 @@ public: */ virtual int program(const void *buffer, bd_addr_t addr, bd_size_t size); - /** Erase blocks on a block device + /** Erase blocks from the memory-buffered block device * * The state of an erased block is undefined until it has been programmed, - * unless get_erase_value returns a non-negative byte value + * unless get_erase_value returns a non-negative byte value. * * @param addr Address of block to begin erasing * @param size Size to erase in bytes, must be a multiple of erase block size @@ -127,7 +128,7 @@ public: */ virtual bd_size_t get_erase_size() const; - /** Get the size of an erasable block given address + /** Get the size of an erasable block of a given address * * @param addr Address within the erasable block * @return Size of an erasable block in bytes @@ -135,7 +136,7 @@ public: */ virtual bd_size_t get_erase_size(bd_addr_t addr) const; - /** Get the value of storage when erased + /** Get the value of storage data after being erased * * If get_erase_value returns a non-negative byte value, the underlying * storage is set to that value when erased, and storage containing @@ -152,9 +153,9 @@ public: */ virtual bd_size_t size() const; - /** Get the BlockDevice class type. + /** Get the underlying BlockDevice class type * - * @return A string represent the BlockDevice class type. + * @return A string representing the underlying BlockDevice class type */ virtual const char *get_type() const; @@ -170,6 +171,7 @@ protected: uint32_t _init_ref_count; bool _is_initialized; +#if !(DOXYGEN_ONLY) /** Flush data in cache * * @return 0 on success or a negative error code on failure @@ -181,7 +183,7 @@ protected: * @return none */ void invalidate_write_cache(); - +#endif //#if !(DOXYGEN_ONLY) }; } // namespace mbed diff --git a/features/storage/filesystem/littlefs/littlefs/emubd/.mbedignore b/features/storage/filesystem/littlefs/littlefs/emubd/.mbedignore new file mode 100644 index 0000000000..904f0ed67c --- /dev/null +++ b/features/storage/filesystem/littlefs/littlefs/emubd/.mbedignore @@ -0,0 +1 @@ +lfs_emubd.* diff --git a/features/storage/filesystem/littlefs/littlefs/lfs.c b/features/storage/filesystem/littlefs/littlefs/lfs.c index c6b5870395..40d2b86ddc 100644 --- a/features/storage/filesystem/littlefs/littlefs/lfs.c +++ b/features/storage/filesystem/littlefs/littlefs/lfs.c @@ -2206,6 +2206,10 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) { lfs->root[0] = superblock.d.root[0]; lfs->root[1] = superblock.d.root[1]; + if (lfs_paircmp(lfs->root, dir.d.tail) != 0) { + err = LFS_ERR_CORRUPT; + goto cleanup; + } } if (err || memcmp(superblock.d.magic, "littlefs", 8) != 0) { @@ -2223,10 +2227,18 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) { goto cleanup; } + // verify that no metadata pairs are corrupt + while (!lfs_pairisnull(dir.d.tail)) { + err = lfs_dir_fetch(lfs, &dir, dir.d.tail); + if (err) { + goto cleanup; + } + } + + // succuessfully mounted return 0; cleanup: - lfs_deinit(lfs); return err; } diff --git a/features/storage/kvstore/conf/kv_config.cpp b/features/storage/kvstore/conf/kv_config.cpp index 3ff9762d5a..852e153f22 100644 --- a/features/storage/kvstore/conf/kv_config.cpp +++ b/features/storage/kvstore/conf/kv_config.cpp @@ -134,6 +134,8 @@ int _storage_config_FILESYSTEM_NO_RBP(); int _storage_config_tdb_external_common(); int _storage_config_filesystem_common(); +static const char *filesystemstore_folder_path = NULL; + using namespace mbed; @@ -881,6 +883,9 @@ int _storage_config_FILESYSTEM() #if !SECURESTORE_ENABLED return MBED_ERROR_UNSUPPORTED; #endif + + filesystemstore_folder_path = STR(MBED_CONF_STORAGE_FILESYSTEM_FOLDER_PATH); + bd_size_t internal_rbp_size = MBED_CONF_STORAGE_FILESYSTEM_RBP_INTERNAL_SIZE; bd_addr_t internal_start_address = MBED_CONF_STORAGE_FILESYSTEM_INTERNAL_BASE_ADDRESS; @@ -962,6 +967,12 @@ int _storage_config_FILESYSTEM() int _storage_config_FILESYSTEM_NO_RBP() { +#if !SECURESTORE_ENABLED + return MBED_ERROR_UNSUPPORTED; +#endif + + filesystemstore_folder_path = STR(MBED_CONF_STORAGE_FILESYSTEM_NO_RBP_FOLDER_PATH); + bd_size_t size = MBED_CONF_STORAGE_FILESYSTEM_NO_RBP_EXTERNAL_SIZE; bd_addr_t address = MBED_CONF_STORAGE_FILESYSTEM_NO_RBP_EXTERNAL_BASE_ADDRESS; const char *mount_point = STR(MBED_CONF_STORAGE_FILESYSTEM_NO_RBP_MOUNT_POINT); @@ -1062,6 +1073,11 @@ int _storage_config_default() #endif } +const char *get_filesystemstore_folder_path() +{ + return filesystemstore_folder_path; +} + MBED_WEAK int kv_init_storage_config() { diff --git a/features/storage/kvstore/conf/kv_config.h b/features/storage/kvstore/conf/kv_config.h index 6a78cf3390..660a6bdd88 100644 --- a/features/storage/kvstore/conf/kv_config.h +++ b/features/storage/kvstore/conf/kv_config.h @@ -20,12 +20,6 @@ extern "C" { #endif -#if MBED_CONF_STORAGE_STORAGE_TYPE == FILESYSTEM -#define FSST_FOLDER_PATH MBED_CONF_STORAGE_FILESYSTEM_FOLDER_PATH -#elif MBED_CONF_STORAGE_STORAGE_TYPE == FILESYSTEM_NO_RBP -#define FSST_FOLDER_PATH MBED_CONF_STORAGE_FILESYSTEM_NO_RBP_FOLDER_PATH -#endif - #ifndef MBED_CONF_STORAGE_STORAGE #define MBED_CONF_STORAGE_STORAGE USER_DEFINED #endif @@ -41,6 +35,13 @@ extern "C" { */ int kv_init_storage_config(); +/** + * @brief A getter for filesystemstore folder path configuration + * + * @returns string with the file folder path or NULL if not set + */ +const char *get_filesystemstore_folder_path(); + #ifdef __cplusplus } // closing brace for extern "C" #endif diff --git a/features/storage/kvstore/tdbstore/DirectAccessDevicekey.cpp b/features/storage/kvstore/direct_access_devicekey/DirectAccessDevicekey.cpp similarity index 95% rename from features/storage/kvstore/tdbstore/DirectAccessDevicekey.cpp rename to features/storage/kvstore/direct_access_devicekey/DirectAccessDevicekey.cpp index 12741873a6..68085164a1 100644 --- a/features/storage/kvstore/tdbstore/DirectAccessDevicekey.cpp +++ b/features/storage/kvstore/direct_access_devicekey/DirectAccessDevicekey.cpp @@ -123,6 +123,15 @@ int get_expected_internal_TDBStore_position(uint32_t *out_tdb_start_offset, uin } else if (strcmp(STR(MBED_CONF_STORAGE_STORAGE_TYPE), "TDB_EXTERNAL") == 0) { *out_tdb_start_offset = MBED_CONF_STORAGE_TDB_EXTERNAL_INTERNAL_BASE_ADDRESS; tdb_size = MBED_CONF_STORAGE_TDB_EXTERNAL_RBP_INTERNAL_SIZE; + } else if (strcmp(STR(MBED_CONF_STORAGE_STORAGE_TYPE), "default") == 0) { +#if COMPONENT_QSPIF || COMPONENT_SPIF || COMPONENT_DATAFLASH + *out_tdb_start_offset = MBED_CONF_STORAGE_TDB_EXTERNAL_INTERNAL_BASE_ADDRESS; + tdb_size = MBED_CONF_STORAGE_TDB_EXTERNAL_RBP_INTERNAL_SIZE; +#elif COMPONENT_SD + tdb_size = MBED_CONF_STORAGE_FILESYSTEM_RBP_INTERNAL_SIZE; +#else + return MBED_ERROR_UNSUPPORTED; +#endif } else { return MBED_ERROR_UNSUPPORTED; } diff --git a/features/storage/kvstore/tdbstore/DirectAccessDevicekey.h b/features/storage/kvstore/direct_access_devicekey/DirectAccessDevicekey.h similarity index 100% rename from features/storage/kvstore/tdbstore/DirectAccessDevicekey.h rename to features/storage/kvstore/direct_access_devicekey/DirectAccessDevicekey.h diff --git a/features/storage/kvstore/filesystemstore/FileSystemStore.cpp b/features/storage/kvstore/filesystemstore/FileSystemStore.cpp index 3e4fc2381b..ac1aea3cd7 100644 --- a/features/storage/kvstore/filesystemstore/FileSystemStore.cpp +++ b/features/storage/kvstore/filesystemstore/FileSystemStore.cpp @@ -17,6 +17,7 @@ */ #include "FileSystemStore.h" +#include "kv_config.h" #include "Dir.h" #include "File.h" #include "BlockDevice.h" @@ -31,9 +32,7 @@ #define FSST_REVISION 1 #define FSST_MAGIC 0x46535354 // "FSST" hex 'magic' signature -#ifndef FSST_FOLDER_PATH -#define FSST_FOLDER_PATH "kvstore" //default FileSystemStore folder path on fs -#endif +#define FSST_DEFAULT_FOLDER_PATH "kvstore" //default FileSystemStore folder path on fs static const uint32_t supported_flags = mbed::KVStore::WRITE_ONCE_FLAG; @@ -73,9 +72,15 @@ int FileSystemStore::init() int status = MBED_SUCCESS; _mutex.lock(); + const char *temp_path = get_filesystemstore_folder_path(); + if (temp_path == NULL) { + _cfg_fs_path_size = strlen(FSST_DEFAULT_FOLDER_PATH); + _cfg_fs_path = string_ndup(FSST_DEFAULT_FOLDER_PATH, _cfg_fs_path_size); + } else { + _cfg_fs_path_size = strlen(temp_path); + _cfg_fs_path = string_ndup(temp_path, _cfg_fs_path_size); + } - _cfg_fs_path_size = strlen(FSST_FOLDER_PATH); - _cfg_fs_path = string_ndup(FSST_FOLDER_PATH, _cfg_fs_path_size); _full_path_key = new char[_cfg_fs_path_size + KVStore::MAX_KEY_SIZE + 1]; memset(_full_path_key, 0, (_cfg_fs_path_size + KVStore::MAX_KEY_SIZE + 1)); strncpy(_full_path_key, _cfg_fs_path, _cfg_fs_path_size); @@ -207,7 +212,7 @@ int FileSystemStore::get(const char *key, void *buffer, size_t buffer_size, size key_metadata_t key_metadata; if ((status = _verify_key_file(key, &key_metadata, &kv_file)) != MBED_SUCCESS) { - tr_error("File Verification failed, status: %d", status); + tr_debug("File Verification failed, status: %d", status); goto exit_point; } @@ -259,7 +264,7 @@ int FileSystemStore::get_info(const char *key, info_t *info) key_metadata_t key_metadata; if ((status = _verify_key_file(key, &key_metadata, &kv_file)) != MBED_SUCCESS) { - tr_error("File Verification failed, status: %d", status); + tr_debug("File Verification failed, status: %d", status); goto exit_point; } @@ -295,9 +300,9 @@ int FileSystemStore::remove(const char *key) /* If File Exists and is Valid, then check its Write Once Flag to verify its disabled before removing */ /* If File exists and is not valid, or is Valid and not Write-Onced then remove it */ if ((status = _verify_key_file(key, &key_metadata, &kv_file)) == MBED_SUCCESS) { - tr_error("File: %s, Exists Verifying Write Once Disabled before setting new value", _full_path_key); if (key_metadata.user_flags & KVStore::WRITE_ONCE_FLAG) { kv_file.close(); + tr_error("File: %s, Exists but write protected", _full_path_key); status = MBED_ERROR_WRITE_PROTECTED; goto exit_point; } @@ -516,7 +521,7 @@ int FileSystemStore::iterator_next(iterator_t it, char *key, size_t key_size) Dir *kv_dir; struct dirent kv_dir_ent; int status = MBED_ERROR_ITEM_NOT_FOUND; - key_iterator_handle_t *key_it = NULL; + key_iterator_handle_t *key_it; size_t key_name_size = KVStore::MAX_KEY_SIZE; if (key_size < key_name_size) { key_name_size = key_size; diff --git a/features/storage/kvstore/KVStore.h b/features/storage/kvstore/include/KVStore.h similarity index 100% rename from features/storage/kvstore/KVStore.h rename to features/storage/kvstore/include/KVStore.h diff --git a/features/storage/kvstore/tdbstore/TDBStore.cpp b/features/storage/kvstore/tdbstore/TDBStore.cpp index 60d107407e..0ab8dcecb3 100644 --- a/features/storage/kvstore/tdbstore/TDBStore.cpp +++ b/features/storage/kvstore/tdbstore/TDBStore.cpp @@ -24,7 +24,10 @@ #include "mbed_error.h" #include "mbed_wait_api.h" #include "MbedCRC.h" +//Bypass the check of NVStore co existance if compiled for TARGET_TFM +#if !(BYPASS_NVSTORE_CHECK) #include "SystemStorage.h" +#endif using namespace mbed; @@ -990,6 +993,9 @@ int TDBStore::init() goto end; } +//Bypass the check of NVStore co existance if compiled for TARGET_TFM +#if !(BYPASS_NVSTORE_CHECK) + //Check if we are on internal memory && try to set the internal memory for TDBStore use. if (strcmp(_bd->get_type(), "FLASHIAP") == 0 && avoid_conflict_nvstore_tdbstore(TDBSTORE) == MBED_ERROR_ALREADY_INITIALIZED) { @@ -997,6 +1003,8 @@ int TDBStore::init() MBED_ERROR(MBED_ERROR_ALREADY_INITIALIZED, "TDBStore in internal memory can not be initialize when NVStore is in use"); } +#endif + _max_keys = initial_max_keys; ram_table = new ram_table_entry_t[_max_keys]; diff --git a/features/storage/nvstore/source/nvstore.cpp b/features/storage/nvstore/source/nvstore.cpp index b071e03f20..fc98faf173 100644 --- a/features/storage/nvstore/source/nvstore.cpp +++ b/features/storage/nvstore/source/nvstore.cpp @@ -72,8 +72,6 @@ typedef struct { static const uint32_t min_area_size = 4096; static const uint32_t max_data_size = 4096; -static const int num_write_retries = 16; - static const uint8_t blank_flash_val = 0xFF; typedef enum { @@ -234,31 +232,13 @@ int NVStore::flash_read_area(uint8_t area, uint32_t offset, uint32_t size, void int NVStore::flash_write_area(uint8_t area, uint32_t offset, uint32_t size, const void *buf) { - int ret; - // On some boards, write action can fail due to HW limitations (like critical drivers - // that disable all other actions). Just retry a few times until success. - for (int i = 0; i < num_write_retries; i++) { - ret = _flash->program(buf, _flash_area_params[area].address + offset, size); - if (!ret) { - return ret; - } - wait_ms(1); - } + int ret = _flash->program(buf, _flash_area_params[area].address + offset, size); return ret; } int NVStore::flash_erase_area(uint8_t area) { - int ret; - // On some boards, write action can fail due to HW limitations (like critical drivers - // that disable all other actions). Just retry a few times until success. - for (int i = 0; i < num_write_retries; i++) { - ret = _flash->erase(_flash_area_params[area].address, _flash_area_params[area].size); - if (!ret) { - return ret; - } - wait_ms(1); - } + int ret = _flash->erase(_flash_area_params[area].address, _flash_area_params[area].size); return ret; } diff --git a/platform/ATCmdParser.h b/platform/ATCmdParser.h index 927b24d992..ee60813834 100644 --- a/platform/ATCmdParser.h +++ b/platform/ATCmdParser.h @@ -171,7 +171,7 @@ public: /** * Allows traces from modem to be turned on or off * - * @param on Set as 1 to turn on traces and vice versa. + * @param on Set as 1 to turn on traces and 0 to disable traces. */ void debug_on(uint8_t on) { @@ -184,7 +184,7 @@ public: * * Allows traces from modem to be turned on or off * - * @param on Set as 1 to turn on traces and vice versa. + * @param on Set as 1 to turn on traces and 0 to disable traces. */ MBED_DEPRECATED_SINCE("mbed-os-5.5.0", "Replaced with debug_on for consistency") void debugOn(uint8_t on) diff --git a/platform/mbed_board.c b/platform/mbed_board.c index d882f6ec1c..4b3844e2a4 100644 --- a/platform/mbed_board.c +++ b/platform/mbed_board.c @@ -33,16 +33,16 @@ WEAK MBED_NORETURN void mbed_die(void) while (1) { for (int i = 0; i < 4; ++i) { gpio_write(&led_err, 1); - wait_ms(150); + wait_us(150000); gpio_write(&led_err, 0); - wait_ms(150); + wait_us(150000); } for (int i = 0; i < 4; ++i) { gpio_write(&led_err, 1); - wait_ms(400); + wait_us(400000); gpio_write(&led_err, 0); - wait_ms(400); + wait_us(400000); } } } diff --git a/platform/mbed_critical.h b/platform/mbed_critical.h index c4a510ca8e..28a6396b6d 100644 --- a/platform/mbed_critical.h +++ b/platform/mbed_critical.h @@ -93,14 +93,14 @@ bool core_util_in_critical_section(void); * A lock-free, primitive atomic flag. * * Emulate C11's atomic_flag. The flag is initially in an indeterminate state - * unless explicitly initialised with CORE_UTIL_ATOMIC_FLAG_INIT. + * unless explicitly initialized with CORE_UTIL_ATOMIC_FLAG_INIT. */ typedef struct core_util_atomic_flag { uint8_t _flag; } core_util_atomic_flag; /** - * Initialiser for a core_util_atomic_flag. + * Initializer for a core_util_atomic_flag. * * Example: * ~~~ diff --git a/platform/mbed_error.c b/platform/mbed_error.c index 9c38322773..c1ee19d6fd 100644 --- a/platform/mbed_error.c +++ b/platform/mbed_error.c @@ -210,30 +210,23 @@ mbed_error_status_t mbed_error_initialize(void) //Read report_error_ctx and check if CRC is correct, and with valid status code if ((report_error_ctx->crc_error_ctx == crc_val) && (report_error_ctx->is_error_processed == 0)) { is_reboot_error_valid = true; - //Report the error info -#ifndef NDEBUG - printf("\n== The system has been rebooted due to a fatal error. ==\n"); -#endif //Call the mbed_error_reboot_callback, this enables applications to do some handling before we do the handling mbed_error_reboot_callback(report_error_ctx); //We let the callback reset the error info, so check if its still valid and do the rest only if its still valid. - if (report_error_ctx->error_reboot_count < 0) { + if (report_error_ctx->error_reboot_count > 0) { + + report_error_ctx->is_error_processed = 1;//Set the flag that we already processed this error + crc_val = compute_crc32(report_error_ctx, offsetof(mbed_error_ctx, crc_error_ctx)); + report_error_ctx->crc_error_ctx = crc_val; //Enforce max-reboot only if auto reboot is enabled #if MBED_CONF_PLATFORM_FATAL_ERROR_AUTO_REBOOT_ENABLED if (report_error_ctx->error_reboot_count >= MBED_CONF_PLATFORM_ERROR_REBOOT_MAX) { - //We have rebooted more than enough, hold the system here. -#ifndef NDEBUG - printf("\n== Reboot count(=%ld) exceeded maximum, system halting ==\n", report_error_ctx->error_reboot_count); -#endif mbed_halt_system(); } #endif - report_error_ctx->is_error_processed = 1;//Set the flag that we already processed this error - crc_val = compute_crc32(report_error_ctx, offsetof(mbed_error_ctx, crc_error_ctx)); - report_error_ctx->crc_error_ctx = crc_val; } } } @@ -299,6 +292,13 @@ WEAK MBED_NORETURN mbed_error_status_t mbed_error(mbed_error_status_t error_stat core_util_critical_section_exit(); //We need not call delete_mbed_crc(crc_obj) here as we are going to reset the system anyway, and calling delete while handling a fatal error may cause nested exception #if MBED_CONF_PLATFORM_FATAL_ERROR_AUTO_REBOOT_ENABLED && (MBED_CONF_PLATFORM_ERROR_REBOOT_MAX > 0) +#ifndef NDEBUG + mbed_error_printf("\n= System will be rebooted due to a fatal error =\n"); + if (report_error_ctx->error_reboot_count >= MBED_CONF_PLATFORM_ERROR_REBOOT_MAX) { + //We have rebooted more than enough, hold the system here. + mbed_error_printf("= Reboot count(=%ld) reached maximum, system will halt after rebooting =\n", report_error_ctx->error_reboot_count); + } +#endif system_reset();//do a system reset to get the system rebooted #endif #endif diff --git a/platform/mbed_error.h b/platform/mbed_error.h index d91c967f6c..4301f2ff67 100644 --- a/platform/mbed_error.h +++ b/platform/mbed_error.h @@ -792,6 +792,7 @@ typedef enum _mbed_error_code { MBED_DEFINE_SYSTEM_ERROR(AUTHENTICATION_FAILED, 69), /* 325 Authentication Failed */ MBED_DEFINE_SYSTEM_ERROR(RBP_AUTHENTICATION_FAILED, 70), /* 326 Rollback Protection Authentication Failed */ MBED_DEFINE_SYSTEM_ERROR(BLE_USE_INCOMPATIBLE_API, 71), /* 327 Concurrent use of incompatible versions of a BLE API */ + MBED_DEFINE_SYSTEM_ERROR(BLE_ILLEGAL_STATE, 72), /* 328 BLE stack entered illegal state */ //Everytime you add a new system error code, you must update //Error documentation under Handbook to capture the info on @@ -948,7 +949,7 @@ typedef void (*mbed_error_hook_t)(const mbed_error_ctx *error_ctx); * it will auto-reboot the system(if MBED_CONF_PLATFORM_FATAL_ERROR_AUTO_REBOOT_ENABLED is enabled) after capturing the * error info in special crash data RAM region. Once rebooted, MbedOS initialization routines will call this function with a pointer to * the captured mbed_error_ctx structure. If application implementation needs to receive this callback, mbed_error_reboot_callback - * function should be overriden with custom implementation. By default it's defined as a WEAK function in mbed_error.c. + * function should be overridden with custom implementation. By default it's defined as a WEAK function in mbed_error.c. * Note that this callback will be invoked before the system starts executing main() function. So the implementation of * the callback should be aware any resource limitations/availability of resources which are yet to be initialized by application main(). * diff --git a/hal/mbed_sleep_manager.c b/platform/mbed_sleep_manager.c similarity index 95% rename from hal/mbed_sleep_manager.c rename to platform/mbed_sleep_manager.c index 492a4ab018..c1d4c9b510 100644 --- a/hal/mbed_sleep_manager.c +++ b/platform/mbed_sleep_manager.c @@ -15,18 +15,18 @@ * limitations under the License. */ -#include "platform/mbed_assert.h" -#include "platform/mbed_power_mgmt.h" -#include "platform/mbed_critical.h" -#include "sleep_api.h" -#include "platform/mbed_error.h" -#include "platform/mbed_stats.h" -#include "us_ticker_api.h" -#include "lp_ticker_api.h" +#include "mbed_power_mgmt.h" +#include "mbed_interface.h" +#include "mbed_critical.h" +#include "mbed_assert.h" +#include "mbed_error.h" +#include "mbed_stats.h" + +#include "hal/us_ticker_api.h" +#include "hal/lp_ticker_api.h" + #include #include -#include "platform/mbed_stats.h" -#include "platform/mbed_interface.h" #if DEVICE_SLEEP diff --git a/platform/mbed_version.h b/platform/mbed_version.h index 88f4a942ab..d78faf9993 100644 --- a/platform/mbed_version.h +++ b/platform/mbed_version.h @@ -44,7 +44,7 @@ * * @note 99 is default value for development version (master branch) */ -#define MBED_PATCH_VERSION 2 +#define MBED_PATCH_VERSION 3 #define MBED_ENCODE_VERSION(major, minor, patch) ((major)*10000 + (minor)*100 + (patch)) diff --git a/requirements.txt b/requirements.txt index e7f6071e59..c997a5f012 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,23 +1,24 @@ colorama==0.3.9 -pyserial>=3,<=3.4 +urllib3[secure]==1.23 prettytable==0.7.2 -Jinja2>=2.7.3,<=2.10 -intelhex>=1.3,<=2.2.1 junit-xml==1.8 pyyaml==4.2b1 -urllib3[secure]==1.23 +jsonschema==2.6.0 +future==0.16.0 +six==1.11.0 +mbed-cloud-sdk==2.0.1 requests>=2.20,<2.21 +idna>=2,<2.8 +pyserial>=3,<=3.4 +Jinja2>=2.7.3,<=2.10 +intelhex>=1.3,<=2.2.1 intervaltree>=2,<3 mbed-ls>=1.5.1,<1.7 -mbed-host-tests>=1.1.2,<=1.5 +mbed-host-tests>=1.4.4,<=1.5 mbed-greentea>=0.2.24,<=1.5 beautifulsoup4>=4,<=4.6.3 fuzzywuzzy>=0.11,<=0.17 pyelftools>=0.24,<=0.25 -jsonschema==2.6.0 -future==0.16.0 -six==1.11.0 git+https://github.com/armmbed/manifest-tool.git@v1.4.6 -mbed-cloud-sdk==2.0.1 pyocd>=0.14,<0.15 icetea>=1.0.2,<1.1 diff --git a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/device/drivers/smsc9220_eth_drv.h b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/device/drivers/smsc9220_eth_drv.h index aa60b4f95f..cd1ac6e342 100644 --- a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/device/drivers/smsc9220_eth_drv.h +++ b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/device/drivers/smsc9220_eth_drv.h @@ -125,19 +125,19 @@ enum smsc9220_mac_reg_offsets_t{ * */ enum phy_reg_offsets_t{ - SMSC9220_PHY_REG_OFFSET_BCTRL = 0x0U, - SMSC9220_PHY_REG_OFFSET_BSTATUS = 0x1U, - SMSC9220_PHY_REG_OFFSET_ID1 = 0x2U, - SMSC9220_PHY_REG_OFFSET_ID2 = 0x3U, - SMSC9220_PHY_REG_OFFSET_ANEG_ADV = 0x4U, - SMSC9220_PHY_REG_OFFSET_ANEG_LPA = 0x5U, - SMSC9220_PHY_REG_OFFSET_ANEG_EXP = 0x6U, - SMSC9220_PHY_REG_OFFSET_MCONTROL = 0x17U, - SMSC9220_PHY_REG_OFFSET_MSTATUS = 0x18U, - SMSC9220_PHY_REG_OFFSET_CSINDICATE = 0x27U, - SMSC9220_PHY_REG_OFFSET_INTSRC = 0x29U, - SMSC9220_PHY_REG_OFFSET_INTMASK = 0x30U, - SMSC9220_PHY_REG_OFFSET_CS = 0x31U + SMSC9220_PHY_REG_OFFSET_BCTRL = 0U, + SMSC9220_PHY_REG_OFFSET_BSTATUS = 1U, + SMSC9220_PHY_REG_OFFSET_ID1 = 2U, + SMSC9220_PHY_REG_OFFSET_ID2 = 3U, + SMSC9220_PHY_REG_OFFSET_ANEG_ADV = 4U, + SMSC9220_PHY_REG_OFFSET_ANEG_LPA = 5U, + SMSC9220_PHY_REG_OFFSET_ANEG_EXP = 6U, + SMSC9220_PHY_REG_OFFSET_MCONTROL = 17U, + SMSC9220_PHY_REG_OFFSET_MSTATUS = 18U, + SMSC9220_PHY_REG_OFFSET_CSINDICATE = 27U, + SMSC9220_PHY_REG_OFFSET_INTSRC = 29U, + SMSC9220_PHY_REG_OFFSET_INTMASK = 30U, + SMSC9220_PHY_REG_OFFSET_CS = 31U }; /* Bit definitions for PHY Basic Status Register */ diff --git a/targets/TARGET_Cypress/TARGET_PSOC6/TARGET_FUTURE_SEQUANA_PSA/prebuilt/README.md b/targets/TARGET_Cypress/TARGET_PSOC6/TARGET_FUTURE_SEQUANA_PSA/prebuilt/README.md index e22425b32f..b90d675937 100644 --- a/targets/TARGET_Cypress/TARGET_PSOC6/TARGET_FUTURE_SEQUANA_PSA/prebuilt/README.md +++ b/targets/TARGET_Cypress/TARGET_PSOC6/TARGET_FUTURE_SEQUANA_PSA/prebuilt/README.md @@ -6,7 +6,8 @@ Build by mbed-cli using GNU Arm Embedded - version 6.3.1 These images were compiled by the following command: ``` -mbed compile -m TARGET_FUTURE_SEQUANA_M0_PSA -t GCC_ARM --profile debug/release +mbed compile -m FUTURE_SEQUANA_M0_PSA -t GCC_ARM --profile release -N psa_release_1.0 +mbed compile -m FUTURE_SEQUANA_M0_PSA -t GCC_ARM --profile debug -N psa_debug_1.0 ``` There are also prebuilt images for PSA tests. @@ -16,5 +17,7 @@ Those images can be found in the test folder under a `TARGET_FUTURE_SEQUANA_PSA` These images were compiled by the following command: ``` -mbed test --compile -m TARGET_FUTURE_SEQUANA_M0_PSA -t GCC_ARM --profile debug -n *spm* +mbed test --compile -m FUTURE_SEQUANA_M0_PSA -t GCC_ARM --profile debug -n *psa-* ``` + +To update the prebuilt binaries run the previous commands and then run ```python export_binaries.py``` diff --git a/targets/TARGET_Cypress/TARGET_PSOC6/TARGET_FUTURE_SEQUANA_PSA/prebuilt/export_binaries.py b/targets/TARGET_Cypress/TARGET_PSOC6/TARGET_FUTURE_SEQUANA_PSA/prebuilt/export_binaries.py new file mode 100644 index 0000000000..054df24bc9 --- /dev/null +++ b/targets/TARGET_Cypress/TARGET_PSOC6/TARGET_FUTURE_SEQUANA_PSA/prebuilt/export_binaries.py @@ -0,0 +1,36 @@ +# Copyright (c) 2017-2018 ARM Limited +# +# 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. + +import fnmatch +import shutil +import os + +SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) +ROOT_DIR = os.path.realpath(os.path.join(SCRIPT_DIR, '..', '..', '..', '..', '..')) +DELIVERY_DIR = os.path.join(ROOT_DIR, 'DELIVERY', 'TARGET_FUTURE_SEQUANA_PSA') + +for f in fnmatch.filter(os.listdir(DELIVERY_DIR), '*.hex'): + test_suite_name = os.path.splitext(f)[0] + test_directory = os.path.join(ROOT_DIR, 'TESTS', 'psa', test_suite_name) + + if os.path.exists(test_directory): + target_dir = os.path.join(test_directory, 'TARGET_FUTURE_SEQUANA_PSA', f) + if not os.path.exists(os.path.join(test_directory, 'TARGET_FUTURE_SEQUANA_PSA')): + continue + else: + target_dir = os.path.join(SCRIPT_DIR, f) + + shutil.copyfile(os.path.join(DELIVERY_DIR, f), target_dir) diff --git a/targets/TARGET_Cypress/TARGET_PSOC6/serial_api.c b/targets/TARGET_Cypress/TARGET_PSOC6/serial_api.c index a3122d12d9..a2b8149684 100644 --- a/targets/TARGET_Cypress/TARGET_PSOC6/serial_api.c +++ b/targets/TARGET_Cypress/TARGET_PSOC6/serial_api.c @@ -650,6 +650,7 @@ int serial_tx_asynch(serial_t *obj_in, const void *tx, size_t tx_length, uint8_t return 0; } + obj->tx_events = event; obj->async_handler = (cy_israddress)handler; if (serial_irq_setup_channel(obj) < 0) { return 0; @@ -662,17 +663,16 @@ int serial_tx_asynch(serial_t *obj_in, const void *tx, size_t tx_length, uint8_t } if (tx_length > 0) { - obj->tx_events = event; obj_in->tx_buff.buffer = (void *)p_buf; obj_in->tx_buff.length = tx_length; obj_in->tx_buff.pos = 0; obj->tx_pending = true; // Enable interrupts to complete transmission. - Cy_SCB_SetRxInterruptMask(obj->base, CY_SCB_TX_INTR_LEVEL | CY_SCB_UART_TX_DONE); + Cy_SCB_SetTxInterruptMask(obj->base, CY_SCB_TX_INTR_LEVEL | CY_SCB_UART_TX_DONE); } else { // Enable interrupt to signal completing of the transmission. - Cy_SCB_SetRxInterruptMask(obj->base, CY_SCB_UART_TX_DONE); + Cy_SCB_SetTxInterruptMask(obj->base, CY_SCB_UART_TX_DONE); } return tx_length; } @@ -739,7 +739,7 @@ int serial_irq_handler_asynch(serial_t *obj_in) // No more bytes to follow; check to see if we need to signal completion. if (obj->tx_events & SERIAL_EVENT_TX_COMPLETE) { // Disable FIFO interrupt as there are no more bytes to follow. - Cy_SCB_SetRxInterruptMask(obj->base, CY_SCB_UART_TX_DONE); + Cy_SCB_SetTxInterruptMask(obj->base, CY_SCB_UART_TX_DONE); } else { // Nothing more to do, mark end of transmission. serial_finish_tx_asynch(obj); @@ -770,13 +770,12 @@ int serial_irq_handler_asynch(serial_t *obj_in) if (rx_status & CY_SCB_RX_INTR_LEVEL) { uint8_t *ptr = obj_in->rx_buff.buffer; ptr += obj_in->rx_buff.pos; - while (obj_in->rx_buff.pos < obj_in->rx_buff.length) { + uint32_t fifo_cnt = Cy_SCB_UART_GetNumInRxFifo(obj->base); + while ((obj_in->rx_buff.pos < obj_in->rx_buff.length) && fifo_cnt) { uint32_t c = Cy_SCB_UART_Get(obj->base); - if (c == CY_SCB_UART_RX_NO_DATA) { - break; - } *ptr++ = (uint8_t)c; ++(obj_in->rx_buff.pos); + --fifo_cnt; // Check for character match condition. if (obj_in->char_match != SERIAL_RESERVED_CHAR_MATCH) { if (c == obj_in->char_match) { @@ -788,9 +787,13 @@ int serial_irq_handler_asynch(serial_t *obj_in) } } } + if (obj_in->rx_buff.pos == obj_in->rx_buff.length) { + cur_events |= SERIAL_EVENT_RX_COMPLETE & obj->rx_events; + } } - if (obj_in->rx_buff.pos == obj_in->rx_buff.length) { + // Any event should end operation. + if (cur_events & SERIAL_EVENT_RX_ALL) { serial_finish_rx_asynch(obj); } diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/Common/EmbeddedTypes.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/Common/EmbeddedTypes.h new file mode 100644 index 0000000000..6953b4d707 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/Common/EmbeddedTypes.h @@ -0,0 +1,215 @@ +/*! +* Copyright (c) 2015, Freescale Semiconductor, Inc. +* Copyright 2016-2017 NXP +* +* \file +* +* This file holds type definitions that maps the standard c-types into types +* with guaranteed sizes. The types are target/platform specific and must be edited +* for each new target/platform. +* The header file also provides definitions for TRUE, FALSE and NULL. +* +* 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 _EMBEDDEDTYPES_H_ +#define _EMBEDDEDTYPES_H_ + + +/************************************************************************************ +* +* INCLUDES +* +************************************************************************************/ + +#include + + +/************************************************************************************ +* +* TYPE DEFINITIONS +* +************************************************************************************/ + +/* boolean types */ +typedef uint8_t bool_t; + +typedef uint8_t index_t; + +/* TRUE/FALSE definition*/ +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +/* null pointer definition*/ +#ifndef NULL +#define NULL (( void * )( 0x0UL )) +#endif + +#if defined(__GNUC__) +#define PACKED_STRUCT struct __attribute__ ((__packed__)) +#define PACKED_UNION union __attribute__ ((__packed__)) +#elif defined(__IAR_SYSTEMS_ICC__) +#define PACKED_STRUCT __packed struct +#define PACKED_UNION __packed union +#else +#define PACKED_STRUCT struct +#define PACKED_UNION union +#endif + +typedef unsigned char uintn8_t; +typedef unsigned long uintn32_t; + +typedef unsigned char uchar_t; + +#if !defined(MIN) +#define MIN(a,b) (((a) < (b))?(a):(b)) +#endif + +#if !defined(MAX) +#define MAX(a,b) (((a) > (b))?(a):(b)) +#endif + +/* Compute the number of elements of an array */ +#define NumberOfElements(x) (sizeof(x)/sizeof((x)[0])) + +/* Compute the size of a string initialized with quotation marks */ +#define SizeOfString(string) (sizeof(string) - 1) + +#define GetRelAddr(strct, member) ((uint32_t)&(((strct*)(void *)0)->member)) +#define GetSizeOfMember(strct, member) sizeof(((strct*)(void *)0)->member) + +/* Type definitions for link configuration of instantiable layers */ +#define gInvalidInstanceId_c (instanceId_t)(-1) +typedef uint32_t instanceId_t; + +/* Bit shift definitions */ +#define BIT0 0x01 +#define BIT1 0x02 +#define BIT2 0x04 +#define BIT3 0x08 +#define BIT4 0x10 +#define BIT5 0x20 +#define BIT6 0x40 +#define BIT7 0x80 +#define BIT8 0x100 +#define BIT9 0x200 +#define BIT10 0x400 +#define BIT11 0x800 +#define BIT12 0x1000 +#define BIT13 0x2000 +#define BIT14 0x4000 +#define BIT15 0x8000 +#define BIT16 0x10000 +#define BIT17 0x20000 +#define BIT18 0x40000 +#define BIT19 0x80000 +#define BIT20 0x100000 +#define BIT21 0x200000 +#define BIT22 0x400000 +#define BIT23 0x800000 +#define BIT24 0x1000000 +#define BIT25 0x2000000 +#define BIT26 0x4000000 +#define BIT27 0x8000000 +#define BIT28 0x10000000 +#define BIT29 0x20000000 +#define BIT30 0x40000000 +#define BIT31 0x80000000 + +/* Shift definitions */ +#define SHIFT0 (0) +#define SHIFT1 (1) +#define SHIFT2 (2) +#define SHIFT3 (3) +#define SHIFT4 (4) +#define SHIFT5 (5) +#define SHIFT6 (6) +#define SHIFT7 (7) +#define SHIFT8 (8) +#define SHIFT9 (9) +#define SHIFT10 (10) +#define SHIFT11 (11) +#define SHIFT12 (12) +#define SHIFT13 (13) +#define SHIFT14 (14) +#define SHIFT15 (15) +#define SHIFT16 (16) +#define SHIFT17 (17) +#define SHIFT18 (18) +#define SHIFT19 (19) +#define SHIFT20 (20) +#define SHIFT21 (21) +#define SHIFT22 (22) +#define SHIFT23 (23) +#define SHIFT24 (24) +#define SHIFT25 (25) +#define SHIFT26 (26) +#define SHIFT27 (27) +#define SHIFT28 (28) +#define SHIFT29 (29) +#define SHIFT30 (30) +#define SHIFT31 (31) + +#define SHIFT32 (32) +#define SHIFT33 (33) +#define SHIFT34 (34) +#define SHIFT35 (35) +#define SHIFT36 (36) +#define SHIFT37 (37) +#define SHIFT38 (38) +#define SHIFT39 (39) +#define SHIFT40 (40) +#define SHIFT41 (41) +#define SHIFT42 (42) +#define SHIFT43 (43) +#define SHIFT44 (44) +#define SHIFT45 (45) +#define SHIFT46 (46) +#define SHIFT47 (47) +#define SHIFT48 (48) +#define SHIFT49 (49) +#define SHIFT50 (50) +#define SHIFT51 (51) +#define SHIFT52 (52) +#define SHIFT53 (53) +#define SHIFT54 (54) +#define SHIFT55 (55) +#define SHIFT56 (56) +#define SHIFT57 (57) +#define SHIFT58 (58) +#define SHIFT59 (59) +#define SHIFT60 (60) +#define SHIFT61 (61) +#define SHIFT62 (62) +#define SHIFT63 (63) + + +#endif /* _EMBEDDEDTYPES_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/OSAbstraction/Interface/fsl_os_abstraction.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/OSAbstraction/Interface/fsl_os_abstraction.h new file mode 100644 index 0000000000..8f97457116 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/OSAbstraction/Interface/fsl_os_abstraction.h @@ -0,0 +1,608 @@ +/*! +* Copyright (c) 2015, Freescale Semiconductor, Inc. +* Copyright 2016-2017 NXP +* +* \file +* +* 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_OS_ABSTRACTION_H_ +#define _FSL_OS_ABSTRACTION_H_ + +#include "EmbeddedTypes.h" +#include "fsl_os_abstraction_config.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/*! ********************************************************************************* +************************************************************************************* +* Public type definitions +************************************************************************************* +********************************************************************************** */ +/*! @brief Type for the Task Priority*/ + typedef uint16_t osaTaskPriority_t; +/*! @brief Type for the timer definition*/ + typedef enum { + osaTimer_Once = 0, /*!< one-shot timer*/ + osaTimer_Periodic = 1 /*!< repeating timer*/ + } osaTimer_t; + /*! @brief Type for a task handler, returned by the OSA_TaskCreate function. */ + typedef void* osaTaskId_t; +/*! @brief Type for the parameter to be passed to the task at its creation */ + typedef void* osaTaskParam_t; + /*! @brief Type for task pointer. Task prototype declaration */ + typedef void (*osaTaskPtr_t) (osaTaskParam_t task_param); +/*! @brief Type for the semaphore handler, returned by the OSA_SemaphoreCreate function. */ + typedef void* osaSemaphoreId_t; +/*! @brief Type for the mutex handler, returned by the OSA_MutexCreate function. */ + typedef void* osaMutexId_t; +/*! @brief Type for the event handler, returned by the OSA_EventCreate function. */ + typedef void* osaEventId_t; +/*! @brief Type for an event flags group, bit 32 is reserved. */ + typedef uint32_t osaEventFlags_t; +/*! @brief Message definition. */ + typedef void* osaMsg_t; +/*! @brief Type for the message queue handler, returned by the OSA_MsgQCreate function. */ + typedef void* osaMsgQId_t; + /*! @brief Type for the Timer handler, returned by the OSA_TimerCreate function. */ + typedef void *osaTimerId_t; +/*! @brief Type for the Timer callback function pointer. */ + typedef void (*osaTimerFctPtr_t) (void const *argument); +/*! @brief Thread Definition structure contains startup information of a thread.*/ +typedef struct osaThreadDef_tag { + osaTaskPtr_t pthread; /*!< start address of thread function*/ + uint32_t tpriority; /*!< initial thread priority*/ + uint32_t instances; /*!< maximum number of instances of that thread function*/ + uint32_t stacksize; /*!< stack size requirements in bytes; 0 is default stack size*/ + uint32_t *tstack; + void *tlink; + uint8_t *tname; + bool_t useFloat; +} osaThreadDef_t; +/*! @brief Thread Link Definition structure .*/ +typedef struct osaThreadLink_tag{ + uint8_t link[12]; + osaTaskId_t osThreadId; + osaThreadDef_t *osThreadDefHandle; + uint32_t *osThreadStackHandle; +}osaThreadLink_t, *osaThreadLinkHandle_t; + +/*! @Timer Definition structure contains timer parameters.*/ +typedef struct osaTimerDef_tag { + osaTimerFctPtr_t pfCallback; /* < start address of a timer function */ + void *argument; +} osaTimerDef_t; +/*! @brief Defines the return status of OSA's functions */ +typedef enum osaStatus_tag +{ + osaStatus_Success = 0U, /*!< Success */ + osaStatus_Error = 1U, /*!< Failed */ + osaStatus_Timeout = 2U, /*!< Timeout occurs while waiting */ + osaStatus_Idle = 3U /*!< Used for bare metal only, the wait object is not ready + and timeout still not occur */ +}osaStatus_t; + + +/*! ********************************************************************************* +************************************************************************************* +* Public macros +************************************************************************************* +********************************************************************************** */ +#if defined (FSL_RTOS_MQX) + #define USE_RTOS 1 +#elif defined (FSL_RTOS_FREE_RTOS) + #define USE_RTOS 1 +#elif defined (FSL_RTOS_UCOSII) + #define USE_RTOS 1 +#elif defined (FSL_RTOS_UCOSIII) + #define USE_RTOS 1 +#else + #define USE_RTOS 0 +#endif + +#define OSA_PRIORITY_IDLE (6) +#define OSA_PRIORITY_LOW (5) +#define OSA_PRIORITY_BELOW_NORMAL (4) +#define OSA_PRIORITY_NORMAL (3) +#define OSA_PRIORITY_ABOVE_NORMAL (2) +#define OSA_PRIORITY_HIGH (1) +#define OSA_PRIORITY_REAL_TIME (0) +#define OSA_TASK_PRIORITY_MAX (0) +#define OSA_TASK_PRIORITY_MIN (15) +#define SIZE_IN_UINT32_UNITS(size) (((size) + sizeof(uint32_t) - 1) / sizeof(uint32_t)) + +/*! @brief Constant to pass as timeout value in order to wait indefinitely. */ +#define osaWaitForever_c ((uint32_t)(-1)) +#define osaEventFlagsAll_c ((osaEventFlags_t)(0x00FFFFFF)) +#define osThreadStackArray(name) osThread_##name##_stack +#define osThreadStackDef(name, stacksize, instances) \ + uint32_t osThreadStackArray(name)[SIZE_IN_UINT32_UNITS(stacksize)*(instances)]; + +/* ==== Thread Management ==== */ + +/* Create a Thread Definition with function, priority, and stack requirements. + * \param name name of the thread function. + * \param priority initial priority of the thread function. + * \param instances number of possible thread instances. + * \param stackSz stack size (in bytes) requirements for the thread function. + * \param useFloat + */ +#if defined(FSL_RTOS_MQX) +#define OSA_TASK_DEFINE(name, priority, instances, stackSz, useFloat) \ +osaThreadLink_t osThreadLink_##name[instances] = {0}; \ +osThreadStackDef(name, stackSz, instances) \ +osaThreadDef_t os_thread_def_##name = { (name), \ + (priority), \ + (instances), \ + (stackSz), \ + osThreadStackArray(name), \ + osThreadLink_##name, \ + (uint8_t*) #name,\ + (useFloat)} +#elif defined (FSL_RTOS_UCOSII) + #if gTaskMultipleInstancesManagement_c +#define OSA_TASK_DEFINE(name, priority, instances, stackSz, useFloat) \ +osaThreadLink_t osThreadLink_##name[instances] = {0}; \ +osThreadStackDef(name, stackSz, instances) \ +osaThreadDef_t os_thread_def_##name = { (name), \ + (priority), \ + (instances), \ + (stackSz), \ + osThreadStackArray(name), \ + osThreadLink_##name, \ + (uint8_t*) #name,\ + (useFloat)} +#else +#define OSA_TASK_DEFINE(name, priority, instances, stackSz, useFloat) \ +osThreadStackDef(name, stackSz, instances) \ +osaThreadDef_t os_thread_def_##name = { (name), \ + (priority), \ + (instances), \ + (stackSz), \ + osThreadStackArray(name), \ + NULL, \ + (uint8_t*) #name,\ + (useFloat)} +#endif +#else +#define OSA_TASK_DEFINE(name, priority, instances, stackSz, useFloat) \ +osaThreadDef_t os_thread_def_##name = { (name), \ + (priority), \ + (instances), \ + (stackSz), \ + NULL, \ + NULL, \ + (uint8_t*) #name,\ + (useFloat)} +#endif +/* Access a Thread defintion. + * \param name name of the thread definition object. + */ +#define OSA_TASK(name) \ +&os_thread_def_##name + +#define OSA_TASK_PROTO(name) \ +extern osaThreadDef_t os_thread_def_##name +/* ==== Timer Management ==== + * Define a Timer object. + * \param name name of the timer object. + * \param function name of the timer call back function. + */ + +#define OSA_TIMER_DEF(name, function) \ +osaTimerDef_t os_timer_def_##name = \ +{ (function), NULL } + +/* Access a Timer definition. + * \param name name of the timer object. + */ +#define OSA_TIMER(name) \ +&os_timer_def_##name + + +/***************************************************************************** +****************************************************************************** +* Public memory declarations +****************************************************************************** +*****************************************************************************/ +extern const uint8_t gUseRtos_c; + + +/*! ********************************************************************************* +************************************************************************************* +* Public functions +************************************************************************************* +********************************************************************************** */ +/*! + * @name Task management + * @{ + */ + +/*! + * @brief Creates a task. + * + * This function is used to create task based on the resources defined + * by the macro OSA_TASK_DEFINE. + * + * @param thread_def pointer to the osaThreadDef_t structure which defines the task. + * @param task_param Pointer to be passed to the task when it is created. + * + * @retval taskId The task is successfully created. + * @retval NULL The task can not be created.. + * + * Example: + @code + osaTaskId_t taskId; + OSA_TASK_DEFINE( Job1, OSA_PRIORITY_HIGH, 1, 800, 0);; + taskId = OSA__TaskCreate(OSA__TASK(Job1), (osaTaskParam_t)NULL); + @endcode + */ +osaTaskId_t OSA_TaskCreate(osaThreadDef_t *thread_def, osaTaskParam_t task_param); + +/*! + * @brief Gets the handler of active task. + * + * @return Handler to current active task. + */ +osaTaskId_t OSA_TaskGetId(void); + +/*! + * @brief Puts the active task to the end of scheduler's queue. + * + * When a task calls this function, it gives up the CPU and puts itself to the + * end of a task ready list. + * + * @retval osaStatus_Success The function is called successfully. + * @retval osaStatus_Error Error occurs with this function. + */ +osaStatus_t OSA_TaskYield(void); + +/*! + * @brief Gets the priority of a task. + * + * @param taskId The handler of the task whose priority is received. + * + * @return Task's priority. + */ +osaTaskPriority_t OSA_TaskGetPriority(osaTaskId_t taskId); + +/*! + * @brief Sets the priority of a task. + * + * @param taskId The handler of the task whose priority is set. + * @param taskPriority The priority to set. + * + * @retval osaStatus_Success Task's priority is set successfully. + * @retval osaStatus_Error Task's priority can not be set. + */ +osaStatus_t OSA_TaskSetPriority(osaTaskId_t taskId, osaTaskPriority_t taskPriority); +/*! + * @brief Destroys a previously created task. + * + * @param taskId The handler of the task to destroy. Returned by the OSA_TaskCreate function. + * + * @retval osaStatus_Success The task was successfully destroyed. + * @retval osaStatus_Error Task destruction failed or invalid parameter. + */ +osaStatus_t OSA_TaskDestroy(osaTaskId_t taskId); + +/*! + * @brief Creates a semaphore with a given value. + * + * This function creates a semaphore and sets the value to the parameter + * initValue. + * + * @param initValue Initial value the semaphore will be set to. + * + * @retval handler to the new semaphore if the semaphore is created successfully. + * @retval NULL if the semaphore can not be created. + * + * + */ +osaSemaphoreId_t OSA_SemaphoreCreate(uint32_t initValue); + +/*! + * @brief Destroys a previously created semaphore. + * + * @param semId Pointer to the semaphore to destroy. + * + * @retval osaStatus_Success The semaphore is successfully destroyed. + * @retval osaStatus_Error The semaphore can not be destroyed. + */ +osaStatus_t OSA_SemaphoreDestroy(osaSemaphoreId_t semId); + +/*! + * @brief Pending a semaphore with timeout. + * + * This function checks the semaphore's counting value. If it is positive, + * decreases it and returns osaStatus_Success. Otherwise, a timeout is used + * to wait. + * + * @param semId Pointer to the semaphore. + * @param millisec The maximum number of milliseconds to wait if semaphore is not + * positive. Pass osaWaitForever_c to wait indefinitely, pass 0 + * will return osaStatus_Timeout immediately. + * + * @retval osaStatus_Success The semaphore is received. + * @retval osaStatus_Timeout The semaphore is not received within the specified 'timeout'. + * @retval osaStatus_Error An incorrect parameter was passed. + */ +osaStatus_t OSA_SemaphoreWait(osaSemaphoreId_t semId, uint32_t millisec); + +/*! + * @brief Signals for someone waiting on the semaphore to wake up. + * + * Wakes up one task that is waiting on the semaphore. If no task is waiting, increases + * the semaphore's counting value. + * + * @param semId Pointer to the semaphore to signal. + * + * @retval osaStatus_Success The semaphore is successfully signaled. + * @retval osaStatus_Error The object can not be signaled or invalid parameter. + * + */ +osaStatus_t OSA_SemaphorePost(osaSemaphoreId_t semId); + +/*! + * @brief Create an unlocked mutex. + * + * This function creates a non-recursive mutex and sets it to unlocked status. + * + * @param none. + * + * @retval handler to the new mutex if the mutex is created successfully. + * @retval NULL if the mutex can not be created. + */ +osaMutexId_t OSA_MutexCreate(void); + +/*! + * @brief Waits for a mutex and locks it. + * + * This function checks the mutex's status. If it is unlocked, locks it and returns the + * osaStatus_Success. Otherwise, waits for a timeout in milliseconds to lock. + * + * @param mutexId Pointer to the Mutex. + * @param millisec The maximum number of milliseconds to wait for the mutex. + * If the mutex is locked, Pass the value osaWaitForever_c will + * wait indefinitely, pass 0 will return osaStatus_Timeout + * immediately. + * + * @retval osaStatus_Success The mutex is locked successfully. + * @retval osaStatus_Timeout Timeout occurred. + * @retval osaStatus_Error Incorrect parameter was passed. + * + * @note This is non-recursive mutex, a task can not try to lock the mutex it has locked. + */ +osaStatus_t OSA_MutexLock(osaMutexId_t mutexId, uint32_t millisec); + +/*! + * @brief Unlocks a previously locked mutex. + * + * @param mutexId Pointer to the Mutex. + * + * @retval osaStatus_Success The mutex is successfully unlocked. + * @retval osaStatus_Error The mutex can not be unlocked or invalid parameter. + */ +osaStatus_t OSA_MutexUnlock(osaMutexId_t mutexId); + +/*! + * @brief Destroys a previously created mutex. + * + * @param mutexId Pointer to the Mutex. + * + * @retval osaStatus_Success The mutex is successfully destroyed. + * @retval osaStatus_Error The mutex can not be destroyed. + * + */ +osaStatus_t OSA_MutexDestroy(osaMutexId_t mutexId); + +/*! + * @brief Initializes an event object with all flags cleared. + * + * This function creates an event object and set its clear mode. If autoClear + * is TRUE, when a task gets the event flags, these flags will be + * cleared automatically. Otherwise these flags must + * be cleared manually. + * + * @param autoClear TRUE The event is auto-clear. + * FALSE The event manual-clear + * @retval handler to the new event if the event is created successfully. + * @retval NULL if the event can not be created. + */ +osaEventId_t OSA_EventCreate(bool_t autoClear); + +/*! + * @brief Sets one or more event flags. + * + * Sets specified flags of an event object. + * + * @param eventId Pointer to the event. + * @param flagsToSet Flags to be set. + * + * @retval osaStatus_Success The flags were successfully set. + * @retval osaStatus_Error An incorrect parameter was passed. + */ +osaStatus_t OSA_EventSet(osaEventId_t eventId, osaEventFlags_t flagsToSet); + +/*! + * @brief Clears one or more flags. + * + * Clears specified flags of an event object. + * + * @param eventId Pointer to the event. + * @param flagsToClear Flags to be clear. + * + * @retval osaStatus_Success The flags were successfully cleared. + * @retval osaStatus_Error An incorrect parameter was passed. + */ +osaStatus_t OSA_EventClear(osaEventId_t eventId, osaEventFlags_t flagsToClear); + +/*! + * @brief Waits for specified event flags to be set. + * + * This function waits for a combination of flags to be set in an event object. + * Applications can wait for any/all bits to be set. Also this function could + * obtain the flags who wakeup the waiting task. + * + * @param eventId Pointer to the event. + * @param flagsToWait Flags that to wait. + * @param waitAll Wait all flags or any flag to be set. + * @param millisec The maximum number of milliseconds to wait for the event. + * If the wait condition is not met, pass osaWaitForever_c will + * wait indefinitely, pass 0 will return osaStatus_Timeout + * immediately. + * @param setFlags Flags that wakeup the waiting task are obtained by this parameter. + * + * @retval osaStatus_Success The wait condition met and function returns successfully. + * @retval osaStatus_Timeout Has not met wait condition within timeout. + * @retval osaStatus_Error An incorrect parameter was passed. + + * + * @note Please pay attention to the flags bit width, FreeRTOS uses the most + * significant 8 bis as control bits, so do not wait these bits while using + * FreeRTOS. + * + */ +osaStatus_t OSA_EventWait(osaEventId_t eventId, osaEventFlags_t flagsToWait, bool_t waitAll, uint32_t millisec, osaEventFlags_t *pSetFlags); + +/*! + * @brief Destroys a previously created event object. + * + * @param eventId Pointer to the event. + * + * @retval osaStatus_Success The event is successfully destroyed. + * @retval osaStatus_Error Event destruction failed. + */ +osaStatus_t OSA_EventDestroy(osaEventId_t eventId); + +/*! + * @brief Initializes a message queue. + * + * This function allocates memory for and initializes a message queue. Message queue elements are hardcoded as void*. + * + * @param msgNo :number of messages the message queue should accommodate. + * This parameter should not exceed osNumberOfMessages defined in OSAbstractionConfig.h. + * +* @return: Handler to access the queue for put and get operations. If message queue + * creation failed, return NULL. + */ +osaMsgQId_t OSA_MsgQCreate(uint32_t msgNo); + +/*! + * @brief Puts a message at the end of the queue. + * + * This function puts a message to the end of the message queue. If the queue + * is full, this function returns the osaStatus_Error; + * + * @param msgQId pointer to queue returned by the OSA_MsgQCreate function. + * @param pMessage Pointer to the message to be put into the queue. + * + * @retval osaStatus_Success Message successfully put into the queue. + * @retval osaStatus_Error The queue was full or an invalid parameter was passed. + */ +osaStatus_t OSA_MsgQPut(osaMsgQId_t msgQId, osaMsg_t pMessage); + +/*! + * @brief Reads and remove a message at the head of the queue. + * + * This function gets a message from the head of the message queue. If the + * queue is empty, timeout is used to wait. + * + * @param msgQId Queue handler returned by the OSA_MsgQCreate function. + * @param pMessage Pointer to a memory to save the message. + * @param millisec The number of milliseconds to wait for a message. If the + * queue is empty, pass osaWaitForever_c will wait indefinitely, + * pass 0 will return osaStatus_Timeout immediately. + * + * @retval osaStatus_Success Message successfully obtained from the queue. + * @retval osaStatus_Timeout The queue remains empty after timeout. + * @retval osaStatus_Error Invalid parameter. + */ +osaStatus_t OSA_MsgQGet(osaMsgQId_t msgQId, osaMsg_t pMessage, uint32_t millisec); + +/*! + * @brief Destroys a previously created queue. + * + * @param msgQId queue handler returned by the OSA_MsgQCreate function. + * + * @retval osaStatus_Success The queue was successfully destroyed. + * @retval osaStatus_Error Message queue destruction failed. +*/ +osaStatus_t OSA_MsgQDestroy(osaMsgQId_t msgQId); + +/*! + * @brief Enable all interrupts. +*/ +void OSA_InterruptEnable(void); + +/*! + * @brief Disable all interrupts. +*/ +void OSA_InterruptDisable(void); + +/*! + * @brief Enable all interrupts using PRIMASK. +*/ +void OSA_EnableIRQGlobal(void); + +/*! + * @brief Disable all interrupts using PRIMASK. +*/ +void OSA_DisableIRQGlobal(void); + +/*! + * @brief Delays execution for a number of milliseconds. + * + * @param millisec The time in milliseconds to wait. + */ +void OSA_TimeDelay(uint32_t millisec); + +/*! + * @brief This function gets current time in milliseconds. + * + * @retval current time in milliseconds + */ +uint32_t OSA_TimeGetMsec(void); + +/*! + * @brief Installs the interrupt handler. + * + * @param IRQNumber IRQ number of the interrupt. + * @param handler The interrupt handler to install. + */ +void OSA_InstallIntHandler(uint32_t IRQNumber, void (*handler)(void)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/OSAbstraction/Interface/fsl_os_abstraction_config.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/OSAbstraction/Interface/fsl_os_abstraction_config.h new file mode 100644 index 0000000000..43d2927c67 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/OSAbstraction/Interface/fsl_os_abstraction_config.h @@ -0,0 +1,63 @@ +/*! +* Copyright (c) 2015, Freescale Semiconductor, Inc. +* Copyright 2016-2017 NXP +* +* \file +* +* 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_OS_ABSTRACTION_CONFIG_H_ +#define _FSL_OS_ABSTRACTION_CONFIG_H_ + +#ifndef osNumberOfSemaphores +#define osNumberOfSemaphores 5 +#endif +#ifndef osNumberOfMutexes +#define osNumberOfMutexes 5 +#endif +#ifndef osNumberOfMessageQs +#define osNumberOfMessageQs 0 +#endif +#ifndef osNumberOfMessages +#define osNumberOfMessages 10 +#endif +#ifndef osNumberOfEvents +#define osNumberOfEvents 5 +#endif + +#ifndef gMainThreadStackSize_c +#define gMainThreadStackSize_c 1024 +#endif +#ifndef gMainThreadPriority_c +#define gMainThreadPriority_c 7 +#endif + +#ifndef gTaskMultipleInstancesManagement_c +#define gTaskMultipleInstancesManagement_c 0 +#endif +#endif /* _FSL_OS_ABSTRACTION_CONFIG_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/OSAbstraction/Source/fsl_os_abstraction_mbed.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/OSAbstraction/Source/fsl_os_abstraction_mbed.c new file mode 100644 index 0000000000..3a950ac2f4 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/OSAbstraction/Source/fsl_os_abstraction_mbed.c @@ -0,0 +1,23 @@ +#include "fsl_os_abstraction.h" +#include "fsl_common.h" +/*FUNCTION********************************************************************** + * + * Function Name : OSA_InterruptEnable + * Description : self explanatory. + * + *END**************************************************************************/ +void OSA_InterruptEnable(void) +{ + __enable_irq(); +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_InterruptDisable + * Description : self explanatory. + * + *END**************************************************************************/ +void OSA_InterruptDisable(void) +{ + __disable_irq(); +} diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_ant_config.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_ant_config.c new file mode 100644 index 0000000000..319a104a0e --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_ant_config.c @@ -0,0 +1,207 @@ +/* + * 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 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_xcvr.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ +const xcvr_mode_config_t ant_mode_config = +{ + .radio_mode = ANT_MODE, + .scgc5_clock_ena_bits = SIM_SCGC5_PHYDIG_MASK +#if !RADIO_IS_GEN_2P1 + | SIM_SCGC5_ANT_MASK +#endif /* !RADIO_IS_GEN_2P1 */ + , + + /* XCVR_MISC configs */ + .xcvr_ctrl.mask = XCVR_CTRL_XCVR_CTRL_PROTOCOL_MASK | + XCVR_CTRL_XCVR_CTRL_TGT_PWR_SRC_MASK | + XCVR_CTRL_XCVR_CTRL_DEMOD_SEL_MASK, + .xcvr_ctrl.init = XCVR_CTRL_XCVR_CTRL_PROTOCOL(3) | + XCVR_CTRL_XCVR_CTRL_TGT_PWR_SRC(7) | + XCVR_CTRL_XCVR_CTRL_DEMOD_SEL(1), + + /* XCVR_PHY configs */ + .phy_pre_ref0_init = RW0PS(0, 0x1B) | + RW0PS(1, 0x1CU) | + RW0PS(2, 0x1CU) | + RW0PS(3, 0x1CU) | + RW0PS(4, 0x1DU) | + RW0PS(5, 0x1DU) | + RW0PS(6, 0x1EU & 0x3U), /* Phase info #6 overlaps two initialization words - only need two lowest bits*/ + .phy_pre_ref1_init = (0x1E) >> 2 | /* Phase info #6 overlaps two initialization words - manually compute the shift */ + RW1PS(7, 0x1EU) | + RW1PS(8, 0x1EU) | + RW1PS(9, 0x1EU) | + RW1PS(10, 0x1EU) | + RW1PS(11, 0x1DU) | + RW1PS(12, 0x1DU & 0xFU), /* Phase info #12 overlaps two initialization words */ + .phy_pre_ref2_init = (0x1D) >> 4 | /* Phase info #12 overlaps two initialization words - manually compute the shift */ + RW2PS(13, 0x1CU) | + RW2PS(14, 0x1CU) | + RW2PS(15, 0x1CU), + + .phy_cfg1_init = XCVR_PHY_CFG1_AA_PLAYBACK(1) | + XCVR_PHY_CFG1_AA_OUTPUT_SEL(1) | + XCVR_PHY_CFG1_FSK_BIT_INVERT(0) | + XCVR_PHY_CFG1_BSM_EN_BLE(0) | + XCVR_PHY_CFG1_DEMOD_CLK_MODE(0) | + XCVR_PHY_CFG1_CTS_THRESH(0xF8) | + XCVR_PHY_CFG1_FSK_FTS_TIMEOUT(2), + + .phy_el_cfg_init = XCVR_PHY_EL_CFG_EL_ENABLE(1) +#if !RADIO_IS_GEN_2P1 + | XCVR_PHY_EL_CFG_EL_ZB_ENABLE(0) +#endif /* !RADIO_IS_GEN_2P1 */ + , + + /* XCVR_RX_DIG configs */ + .rx_dig_ctrl_init_26mhz = XCVR_RX_DIG_RX_DIG_CTRL_RX_FSK_ZB_SEL(0) | /* Depends on protocol */ + XCVR_RX_DIG_RX_DIG_CTRL_RX_DC_RESID_EN(1) | /* Depends on protocol */ + XCVR_RX_DIG_RX_DIG_CTRL_RX_SRC_RATE(0), + + .rx_dig_ctrl_init_32mhz = XCVR_RX_DIG_RX_DIG_CTRL_RX_FSK_ZB_SEL(0) | /* Depends on protocol */ + XCVR_RX_DIG_RX_DIG_CTRL_RX_DC_RESID_EN(1), /* Depends on protocol */ + + .agc_ctrl_0_init = XCVR_RX_DIG_AGC_CTRL_0_AGC_DOWN_RSSI_THRESH(0xFF), + /* XCVR_TSM configs */ +#if (DATA_PADDING_EN) + .tsm_timing_35_init = B0(TX_DIG_EN_ASSERT+TX_DIG_EN_TX_HI_ADJ), +#else + .tsm_timing_35_init = B0(TX_DIG_EN_ASSERT), +#endif /* (DATA_PADDING_EN) */ + + /* XCVR_TX_DIG configs */ + .tx_gfsk_ctrl = XCVR_TX_DIG_GFSK_CTRL_GFSK_MULTIPLY_TABLE_MANUAL(0x4000) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_MI(0) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_MLD(0) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_FLD(0) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_MOD_INDEX_SCALING(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_OVRD_EN(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_0_OVRD(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_1_OVRD(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_2_OVRD(0), + .tx_gfsk_coeff1_26mhz = 0, + .tx_gfsk_coeff2_26mhz = 0, + .tx_gfsk_coeff1_32mhz = 0, + .tx_gfsk_coeff2_32mhz = 0, +}; + +/* MODE & DATA RATE combined configuration */ +const xcvr_mode_datarate_config_t xcvr_ANT_1mbps_config = +{ + .radio_mode = ANT_MODE, + .data_rate = DR_1MBPS, + + .ana_sy_ctrl2.mask = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM_MASK, + .ana_sy_ctrl2.init = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM(0), /* VCO KVM */ + .ana_rx_bba.mask = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL_MASK | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL_MASK, + .ana_rx_bba.init = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL(5) | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL(5), /* BBA_BW_SEL and BBA2_BW_SEL */ + .ana_rx_tza.mask = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL_MASK, + .ana_rx_tza.init = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL(5), /* TZA_BW_SEL */ + + .phy_cfg2_init = XCVR_PHY_CFG2_PHY_FIFO_PRECHG(8) | + XCVR_PHY_CFG2_X2_DEMOD_GAIN(0x6) , + + /* AGC configs */ + .agc_ctrl_2_init_26mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(12) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + .agc_ctrl_2_init_32mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(14) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + + /* All constant values are represented as 16 bits, register writes will remove unused bits */ + .rx_chf_coeffs_26mhz.rx_chf_coef_0 = 0xFFFB, + .rx_chf_coeffs_26mhz.rx_chf_coef_1 = 0xFFF5, + .rx_chf_coeffs_26mhz.rx_chf_coef_2 = 0xFFF0, + .rx_chf_coeffs_26mhz.rx_chf_coef_3 = 0xFFEC, + .rx_chf_coeffs_26mhz.rx_chf_coef_4 = 0xFFEC, + .rx_chf_coeffs_26mhz.rx_chf_coef_5 = 0xFFF3, + .rx_chf_coeffs_26mhz.rx_chf_coef_6 = 0x0001, + .rx_chf_coeffs_26mhz.rx_chf_coef_7 = 0x0016, + .rx_chf_coeffs_26mhz.rx_chf_coef_8 = 0x002F, + .rx_chf_coeffs_26mhz.rx_chf_coef_9 = 0x0049, + .rx_chf_coeffs_26mhz.rx_chf_coef_10 = 0x005D, + .rx_chf_coeffs_26mhz.rx_chf_coef_11 = 0x0069, + + /* ANT 32MHz Channel Filter */ + .rx_chf_coeffs_32mhz.rx_chf_coef_0 = 0xFFF9, + .rx_chf_coeffs_32mhz.rx_chf_coef_1 = 0xFFF4, + .rx_chf_coeffs_32mhz.rx_chf_coef_2 = 0xFFED, + .rx_chf_coeffs_32mhz.rx_chf_coef_3 = 0xFFE7, + .rx_chf_coeffs_32mhz.rx_chf_coef_4 = 0xFFE7, + .rx_chf_coeffs_32mhz.rx_chf_coef_5 = 0xFFEE, + .rx_chf_coeffs_32mhz.rx_chf_coef_6 = 0xFFFD, + .rx_chf_coeffs_32mhz.rx_chf_coef_7 = 0x0015, + .rx_chf_coeffs_32mhz.rx_chf_coef_8 = 0x0031, + .rx_chf_coeffs_32mhz.rx_chf_coef_9 = 0x004E, + .rx_chf_coeffs_32mhz.rx_chf_coef_10 = 0x0066, + .rx_chf_coeffs_32mhz.rx_chf_coef_11 = 0x0073, + + .rx_rccal_ctrl_0 = XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_SMP_DLY(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_COMP_INV(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_DIS(0) , + .rx_rccal_ctrl_1 = XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_DIS(0) , + + .tx_fsk_scale_26mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1627) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x09d9), + .tx_fsk_scale_32mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1800) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x0800), +}; + diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_ble_config.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_ble_config.c new file mode 100644 index 0000000000..054b0ccfea --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_ble_config.c @@ -0,0 +1,201 @@ +/* + * 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 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_xcvr.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ +const xcvr_mode_config_t ble_mode_config = +{ + .radio_mode = BLE_MODE, + .scgc5_clock_ena_bits = SIM_SCGC5_PHYDIG_MASK | SIM_SCGC5_BTLL_MASK, + + /* XCVR_MISC configs */ + .xcvr_ctrl.mask = XCVR_CTRL_XCVR_CTRL_PROTOCOL_MASK | + XCVR_CTRL_XCVR_CTRL_TGT_PWR_SRC_MASK | + XCVR_CTRL_XCVR_CTRL_DEMOD_SEL_MASK, + .xcvr_ctrl.init = XCVR_CTRL_XCVR_CTRL_PROTOCOL(0) | + XCVR_CTRL_XCVR_CTRL_TGT_PWR_SRC(7) | + XCVR_CTRL_XCVR_CTRL_DEMOD_SEL(1), + + /* XCVR_PHY configs */ + .phy_pre_ref0_init = RW0PS(0, 0x19) | + RW0PS(1, 0x19U) | + RW0PS(2, 0x1AU) | + RW0PS(3, 0x1BU) | + RW0PS(4, 0x1CU) | + RW0PS(5, 0x1CU) | + RW0PS(6, 0x1DU & 0x3U), /* Phase info #6 overlaps two initialization words */ + .phy_pre_ref1_init = (0x1D) >> 2 | /* Phase info #6 overlaps two initialization words - manually compute the shift*/ + RW1PS(7, 0x1EU) | + RW1PS(8, 0x1EU) | + RW1PS(9, 0x1EU) | + RW1PS(10, 0x1DU) | + RW1PS(11, 0x1CU) | + RW1PS(12, 0x1CU & 0xFU), /* Phase info #12 overlaps two initialization words */ + .phy_pre_ref2_init = (0x1C) >> 4 | /* Phase info #12 overlaps two initialization words - manually compute the shift*/ + RW2PS(13, 0x1BU) | + RW2PS(14, 0x1AU) | + RW2PS(15, 0x19U), + + .phy_cfg1_init = XCVR_PHY_CFG1_AA_PLAYBACK(0) | + XCVR_PHY_CFG1_AA_OUTPUT_SEL(1) | + XCVR_PHY_CFG1_FSK_BIT_INVERT(0) | + XCVR_PHY_CFG1_BSM_EN_BLE(0) | + XCVR_PHY_CFG1_DEMOD_CLK_MODE(0) | + XCVR_PHY_CFG1_CTS_THRESH(220) | + XCVR_PHY_CFG1_FSK_FTS_TIMEOUT(2), + + .phy_el_cfg_init = XCVR_PHY_EL_CFG_EL_ENABLE(1) /* Per SMB */ +#if !RADIO_IS_GEN_2P1 + | XCVR_PHY_EL_CFG_EL_ZB_ENABLE(0) +#endif /* !RADIO_IS_GEN_2P1 */ + , + + /* XCVR_RX_DIG configs */ + .rx_dig_ctrl_init_26mhz = XCVR_RX_DIG_RX_DIG_CTRL_RX_FSK_ZB_SEL(0) | /* Depends on protocol */ + XCVR_RX_DIG_RX_DIG_CTRL_RX_DC_RESID_EN(1) | /* Depends on protocol */ + XCVR_RX_DIG_RX_DIG_CTRL_RX_SRC_RATE(0), + + .rx_dig_ctrl_init_32mhz = XCVR_RX_DIG_RX_DIG_CTRL_RX_FSK_ZB_SEL(0) | /* Depends on protocol */ + XCVR_RX_DIG_RX_DIG_CTRL_RX_DC_RESID_EN(1), /* Depends on protocol */ + + .agc_ctrl_0_init = XCVR_RX_DIG_AGC_CTRL_0_AGC_DOWN_RSSI_THRESH(0xFF), + /* XCVR_TSM configs */ +#if (DATA_PADDING_EN) + .tsm_timing_35_init = B0(TX_DIG_EN_ASSERT+TX_DIG_EN_TX_HI_ADJ), +#else + .tsm_timing_35_init = B0(TX_DIG_EN_ASSERT), +#endif /* (DATA_PADDING_EN) */ + + /* XCVR_TX_DIG configs */ + .tx_gfsk_ctrl = XCVR_TX_DIG_GFSK_CTRL_GFSK_MULTIPLY_TABLE_MANUAL(0x4000) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_MI(1) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_MLD(0) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_FLD(0) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_MOD_INDEX_SCALING(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_OVRD_EN(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_0_OVRD(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_1_OVRD(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_2_OVRD(0), + .tx_gfsk_coeff1_26mhz = 0, + .tx_gfsk_coeff2_26mhz = 0, + .tx_gfsk_coeff1_32mhz = 0, + .tx_gfsk_coeff2_32mhz = 0, +}; + +/* MODE & DATA RATE combined configuration */ +const xcvr_mode_datarate_config_t xcvr_BLE_1mbps_config = +{ + .radio_mode = BLE_MODE, + .data_rate = DR_1MBPS, + + .ana_sy_ctrl2.mask = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM_MASK, + .ana_sy_ctrl2.init = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM(0), /* VCO KVM */ + .ana_rx_bba.mask = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL_MASK | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL_MASK, + .ana_rx_bba.init = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL(4) | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL(4), /* BBA_BW_SEL and BBA2_BW_SEL */ + .ana_rx_tza.mask = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL_MASK, + .ana_rx_tza.init = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL(4), /* TZA_BW_SEL */ + + .phy_cfg2_init = XCVR_PHY_CFG2_PHY_FIFO_PRECHG(8) | + XCVR_PHY_CFG2_X2_DEMOD_GAIN(0xA) , + + /* AGC configs */ + .agc_ctrl_2_init_26mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(10) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + .agc_ctrl_2_init_32mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(12) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + + /* BLE 26MHz Channel Filter */ + /* All constant values are represented as 16 bits, register writes will remove unused bits */ + .rx_chf_coeffs_26mhz.rx_chf_coef_0 = 0xFFFA, + .rx_chf_coeffs_26mhz.rx_chf_coef_1 = 0xFFF6, + .rx_chf_coeffs_26mhz.rx_chf_coef_2 = 0xFFF1, + .rx_chf_coeffs_26mhz.rx_chf_coef_3 = 0xFFEE, + .rx_chf_coeffs_26mhz.rx_chf_coef_4 = 0xFFEF, + .rx_chf_coeffs_26mhz.rx_chf_coef_5 = 0xFFF6, + .rx_chf_coeffs_26mhz.rx_chf_coef_6 = 0x0004, + .rx_chf_coeffs_26mhz.rx_chf_coef_7 = 0x0017, + .rx_chf_coeffs_26mhz.rx_chf_coef_8 = 0x002F, + .rx_chf_coeffs_26mhz.rx_chf_coef_9 = 0x0046, + .rx_chf_coeffs_26mhz.rx_chf_coef_10 = 0x0059, + .rx_chf_coeffs_26mhz.rx_chf_coef_11 = 0x0063, + + /* BLE 32MHz Channel Filter */ + .rx_chf_coeffs_32mhz.rx_chf_coef_0 = 0xFFFA, + .rx_chf_coeffs_32mhz.rx_chf_coef_1 = 0xFFF5, + .rx_chf_coeffs_32mhz.rx_chf_coef_2 = 0xFFEF, + .rx_chf_coeffs_32mhz.rx_chf_coef_3 = 0xFFEB, + .rx_chf_coeffs_32mhz.rx_chf_coef_4 = 0xFFEB, + .rx_chf_coeffs_32mhz.rx_chf_coef_5 = 0xFFF2, + .rx_chf_coeffs_32mhz.rx_chf_coef_6 = 0x0000, + .rx_chf_coeffs_32mhz.rx_chf_coef_7 = 0x0015, + .rx_chf_coeffs_32mhz.rx_chf_coef_8 = 0x0030, + .rx_chf_coeffs_32mhz.rx_chf_coef_9 = 0x004A, + .rx_chf_coeffs_32mhz.rx_chf_coef_10 = 0x005F, + .rx_chf_coeffs_32mhz.rx_chf_coef_11 = 0x006B, + + .rx_rccal_ctrl_0 = XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_SMP_DLY(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_COMP_INV(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_DIS(0) , + .rx_rccal_ctrl_1 = XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_DIS(0) , +}; + diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_common_config.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_common_config.c new file mode 100644 index 0000000000..4277d3a1f7 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_common_config.c @@ -0,0 +1,623 @@ +/* + * 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 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_xcvr.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ +const xcvr_common_config_t xcvr_common_config = +{ + /* XCVR_ANA configs */ + .ana_sy_ctrl1.mask = XCVR_ANALOG_SY_CTRL_1_SY_LPF_FILT_CTRL_MASK, + .ana_sy_ctrl1.init = XCVR_ANALOG_SY_CTRL_1_SY_LPF_FILT_CTRL(3), /* PLL Analog Loop Filter */ + +#define hpm_vcm_tx 0 +#define hpm_vcm_cal 1 +#define hpm_fdb_res_tx 0 +#define hpm_fdb_res_cal 1 +#define modulation_word_manual 0 +#define mod_disable 0 +#define hpm_mod_manual 0 +#define hpm_mod_disable 0 +#define hpm_sdm_out_manual 0 +#define hpm_sdm_out_disable 0 +#define channel_num 0 +#define boc 0 +#define bmr 1 +#define zoc 0 +#define ctune_ldf_lev 8 +#define ftf_rx_thrsh 33 +#define ftw_rx 0 +#define ftf_tx_thrsh 6 +#define ftw_tx 0 +#define freq_count_go 0 +#define freq_count_time 0 +#define hpm_sdm_in_manual 0 +#define hpm_sdm_out_invert 0 +#define hpm_sdm_in_disable 0 +#define hpm_lfsr_size 4 +#define hpm_dth_scl 0 +#define hpm_dth_en 1 +#define hpm_integer_scale 0 +#define hpm_integer_invert 0 +#define hpm_cal_invert 1 +#define hpm_mod_in_invert 1 +#define hpm_cal_not_bumped 0 +#define hpm_cal_count_scale 0 +#define hp_cal_disable 0 +#define hpm_cal_factor_manual 0 +#define hpm_cal_array_size 1 +#define hpm_cal_time 0 +#define hpm_sdm_denom 256 +#define hpm_count_adjust 0 +#define pll_ld_manual 0 +#define pll_ld_disable 0 +#define lpm_sdm_inv 0 +#define lpm_disable 0 +#define lpm_dth_scl 8 +#define lpm_d_ctrl 1 +#define lpm_d_ovrd 1 +#define lpm_scale 8 +#define lpm_sdm_use_neg 0 +#define hpm_array_bias 0 +#define lpm_intg 38 +#define sdm_map_disable 0 +#define lpm_sdm_delay 4 +#define hpm_sdm_delay 0 +#define hpm_integer_delay 0 +#define ctune_target_manual 0 +#define ctune_target_disable 0 +#define ctune_adjust 0 +#define ctune_manual 0 +#define ctune_disable 0 + +/*-------------------------------------------------------------------------------------------------*/ + + .pll_hpm_bump = XCVR_PLL_DIG_HPM_BUMP_HPM_FDB_RES_CAL(hpm_fdb_res_cal) | + XCVR_PLL_DIG_HPM_BUMP_HPM_FDB_RES_TX(hpm_fdb_res_tx) | + XCVR_PLL_DIG_HPM_BUMP_HPM_VCM_CAL(hpm_vcm_cal) | + XCVR_PLL_DIG_HPM_BUMP_HPM_VCM_TX(hpm_vcm_tx), + +/*-------------------------------------------------------------------------------------------------*/ + + .pll_mod_ctrl = XCVR_PLL_DIG_MOD_CTRL_HPM_MOD_DISABLE(hpm_mod_disable) | + XCVR_PLL_DIG_MOD_CTRL_HPM_MOD_MANUAL(hpm_mod_manual) | + XCVR_PLL_DIG_MOD_CTRL_HPM_SDM_OUT_DISABLE(hpm_sdm_out_disable) | + XCVR_PLL_DIG_MOD_CTRL_HPM_SDM_OUT_MANUAL(hpm_sdm_out_manual) | + XCVR_PLL_DIG_MOD_CTRL_MOD_DISABLE(mod_disable) | + XCVR_PLL_DIG_MOD_CTRL_MODULATION_WORD_MANUAL(modulation_word_manual), + +/*-------------------------------------------------------------------------------------------------*/ + + .pll_chan_map = XCVR_PLL_DIG_CHAN_MAP_BMR(bmr) | + XCVR_PLL_DIG_CHAN_MAP_BOC(boc) | + XCVR_PLL_DIG_CHAN_MAP_CHANNEL_NUM(channel_num) +#if !RADIO_IS_GEN_2P1 + | XCVR_PLL_DIG_CHAN_MAP_ZOC(zoc) +#endif /* !RADIO_IS_GEN_2P1 */ + , + +/*-------------------------------------------------------------------------------------------------*/ + + .pll_lock_detect = XCVR_PLL_DIG_LOCK_DETECT_CTUNE_LDF_LEV(ctune_ldf_lev) | + XCVR_PLL_DIG_LOCK_DETECT_FREQ_COUNT_GO(freq_count_go) | + XCVR_PLL_DIG_LOCK_DETECT_FREQ_COUNT_TIME(freq_count_time) | + XCVR_PLL_DIG_LOCK_DETECT_FTF_RX_THRSH(ftf_rx_thrsh) | + XCVR_PLL_DIG_LOCK_DETECT_FTF_TX_THRSH(ftf_tx_thrsh) | + XCVR_PLL_DIG_LOCK_DETECT_FTW_RX(ftw_rx) | + XCVR_PLL_DIG_LOCK_DETECT_FTW_TX(ftw_tx), + +/*-------------------------------------------------------------------------------------------------*/ + + .pll_hpm_ctrl = XCVR_PLL_DIG_HPM_CTRL_HPM_CAL_INVERT(hpm_cal_invert) | + XCVR_PLL_DIG_HPM_CTRL_HPM_DTH_EN(hpm_dth_en) | + XCVR_PLL_DIG_HPM_CTRL_HPM_DTH_SCL(hpm_dth_scl) | + XCVR_PLL_DIG_HPM_CTRL_HPM_INTEGER_INVERT(hpm_integer_invert) | + XCVR_PLL_DIG_HPM_CTRL_HPM_INTEGER_SCALE(hpm_integer_scale) | + XCVR_PLL_DIG_HPM_CTRL_HPM_LFSR_SIZE(hpm_lfsr_size) | + XCVR_PLL_DIG_HPM_CTRL_HPM_MOD_IN_INVERT(hpm_mod_in_invert) | + XCVR_PLL_DIG_HPM_CTRL_HPM_SDM_IN_DISABLE(hpm_sdm_in_disable) | + XCVR_PLL_DIG_HPM_CTRL_HPM_SDM_IN_MANUAL(hpm_sdm_in_manual) | + XCVR_PLL_DIG_HPM_CTRL_HPM_SDM_OUT_INVERT(hpm_sdm_out_invert), +/*-------------------------------------------------------------------------------------------------*/ +#if !RADIO_IS_GEN_2P1 + .pll_hpmcal_ctrl = XCVR_PLL_DIG_HPMCAL_CTRL_HP_CAL_DISABLE(hp_cal_disable) | + XCVR_PLL_DIG_HPMCAL_CTRL_HPM_CAL_ARRAY_SIZE(hpm_cal_array_size) | + XCVR_PLL_DIG_HPMCAL_CTRL_HPM_CAL_COUNT_SCALE(hpm_cal_count_scale) | + XCVR_PLL_DIG_HPMCAL_CTRL_HPM_CAL_FACTOR_MANUAL(hpm_cal_factor_manual) | + XCVR_PLL_DIG_HPMCAL_CTRL_HPM_CAL_NOT_BUMPED(hpm_cal_not_bumped) | + XCVR_PLL_DIG_HPMCAL_CTRL_HPM_CAL_TIME(hpm_cal_time), +#endif /* !RADIO_IS_GEN_2P1 */ +/*-------------------------------------------------------------------------------------------------*/ + .pll_hpm_sdm_res = XCVR_PLL_DIG_HPM_SDM_RES_HPM_COUNT_ADJUST(hpm_count_adjust) | + XCVR_PLL_DIG_HPM_SDM_RES_HPM_DENOM(hpm_sdm_denom), +/*-------------------------------------------------------------------------------------------------*/ + .pll_lpm_ctrl = XCVR_PLL_DIG_LPM_CTRL_LPM_D_CTRL(lpm_d_ctrl) | + XCVR_PLL_DIG_LPM_CTRL_LPM_D_OVRD(lpm_d_ovrd) | + XCVR_PLL_DIG_LPM_CTRL_LPM_DISABLE(lpm_disable) | + XCVR_PLL_DIG_LPM_CTRL_LPM_DTH_SCL(lpm_dth_scl) | + XCVR_PLL_DIG_LPM_CTRL_LPM_SCALE(lpm_scale) | + XCVR_PLL_DIG_LPM_CTRL_LPM_SDM_INV(lpm_sdm_inv) | + XCVR_PLL_DIG_LPM_CTRL_LPM_SDM_USE_NEG(lpm_sdm_use_neg) | + XCVR_PLL_DIG_LPM_CTRL_PLL_LD_DISABLE(pll_ld_disable) | + XCVR_PLL_DIG_LPM_CTRL_PLL_LD_MANUAL(pll_ld_manual), +/*-------------------------------------------------------------------------------------------------*/ + .pll_lpm_sdm_ctrl1 = XCVR_PLL_DIG_LPM_SDM_CTRL1_HPM_ARRAY_BIAS(hpm_array_bias) | + XCVR_PLL_DIG_LPM_SDM_CTRL1_LPM_INTG(lpm_intg) | + XCVR_PLL_DIG_LPM_SDM_CTRL1_SDM_MAP_DISABLE(sdm_map_disable), +/*-------------------------------------------------------------------------------------------------*/ + .pll_delay_match = XCVR_PLL_DIG_DELAY_MATCH_HPM_INTEGER_DELAY(hpm_integer_delay) | + XCVR_PLL_DIG_DELAY_MATCH_HPM_SDM_DELAY(hpm_sdm_delay) | + XCVR_PLL_DIG_DELAY_MATCH_LPM_SDM_DELAY(lpm_sdm_delay), +/*-------------------------------------------------------------------------------------------------*/ + .pll_ctune_ctrl = XCVR_PLL_DIG_CTUNE_CTRL_CTUNE_ADJUST(ctune_adjust) | + XCVR_PLL_DIG_CTUNE_CTRL_CTUNE_DISABLE(ctune_disable) | + XCVR_PLL_DIG_CTUNE_CTRL_CTUNE_MANUAL(ctune_manual) | + XCVR_PLL_DIG_CTUNE_CTRL_CTUNE_TARGET_DISABLE(ctune_target_disable) | + XCVR_PLL_DIG_CTUNE_CTRL_CTUNE_TARGET_MANUAL(ctune_target_manual), +/*-------------------------------------------------------------------------------------------------*/ + + /* XCVR_RX_DIG configs */ + /* NOTE: Clock specific settings are embedded in the mode dependent configs */ + .rx_dig_ctrl_init = XCVR_RX_DIG_RX_DIG_CTRL_RX_ADC_NEGEDGE(0) | + XCVR_RX_DIG_RX_DIG_CTRL_RX_CH_FILT_BYPASS(0) | +#if !RADIO_IS_GEN_2P1 + XCVR_RX_DIG_RX_DIG_CTRL_RX_ADC_RAW_EN(0) | +#endif /* !RADIO_IS_GEN_2P1 */ + XCVR_RX_DIG_RX_DIG_CTRL_RX_ADC_POL(0) | + XCVR_RX_DIG_RX_DIG_CTRL_RX_NORM_EN(1) | + XCVR_RX_DIG_RX_DIG_CTRL_RX_RSSI_EN(1) | + XCVR_RX_DIG_RX_DIG_CTRL_RX_AGC_EN(1) | + XCVR_RX_DIG_RX_DIG_CTRL_RX_DCOC_EN(1) | + XCVR_RX_DIG_RX_DIG_CTRL_RX_DCOC_CAL_EN(1) | + XCVR_RX_DIG_RX_DIG_CTRL_RX_IQ_SWAP(0) | + XCVR_RX_DIG_RX_DIG_CTRL_RX_DMA_DTEST_EN(0) | + XCVR_RX_DIG_RX_DIG_CTRL_RX_DEC_FILT_HZD_CORR_DIS(1), + + .agc_ctrl_0_init = XCVR_RX_DIG_AGC_CTRL_0_SLOW_AGC_EN(1) | + XCVR_RX_DIG_AGC_CTRL_0_SLOW_AGC_SRC(2) | + XCVR_RX_DIG_AGC_CTRL_0_AGC_FREEZE_EN(1) | + XCVR_RX_DIG_AGC_CTRL_0_AGC_FREEZE_PRE_OR_AA(0) | + XCVR_RX_DIG_AGC_CTRL_0_AGC_UP_EN(1) | + XCVR_RX_DIG_AGC_CTRL_0_AGC_UP_SRC(0) | + XCVR_RX_DIG_AGC_CTRL_0_AGC_DOWN_BBA_STEP_SZ(2) | + XCVR_RX_DIG_AGC_CTRL_0_AGC_DOWN_LNA_STEP_SZ(2) | + XCVR_RX_DIG_AGC_CTRL_0_AGC_UP_RSSI_THRESH(0xe7), + + .agc_ctrl_3_init = XCVR_RX_DIG_AGC_CTRL_3_AGC_UNFREEZE_TIME(21) | + XCVR_RX_DIG_AGC_CTRL_3_AGC_PDET_LO_DLY(2) | + XCVR_RX_DIG_AGC_CTRL_3_AGC_RSSI_DELT_H2S(20) | + XCVR_RX_DIG_AGC_CTRL_3_AGC_H2S_STEP_SZ(6) | + XCVR_RX_DIG_AGC_CTRL_3_AGC_UP_STEP_SZ(2), + + /* DCOC configs */ + .dcoc_ctrl_0_init_26mhz = XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CAL_DURATION(16) | /* Only the duration changes between 26MHz and 32MHz ref osc settings */ +#if (RADIO_IS_GEN_2P1) + XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CAL_CHECK_EN(0) | +#endif /* (RADIO_IS_GEN_2P1) */ + XCVR_RX_DIG_DCOC_CTRL_0_TRACK_FROM_ZERO(0) | + XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CORRECT_EN(1) | + XCVR_RX_DIG_DCOC_CTRL_0_TZA_CORR_POL(0) | + XCVR_RX_DIG_DCOC_CTRL_0_BBA_CORR_POL(0) | + XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CORRECT_SRC(1), + .dcoc_ctrl_0_init_32mhz = XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CAL_DURATION(20) | /* Only the duration changes between 26MHz and 32MHz ref osc settings */ +#if (RADIO_IS_GEN_2P1) + XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CAL_CHECK_EN(0) | +#endif /* (RADIO_IS_GEN_2P1) */ + XCVR_RX_DIG_DCOC_CTRL_0_TRACK_FROM_ZERO(0) | + XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CORRECT_EN(1) | + XCVR_RX_DIG_DCOC_CTRL_0_TZA_CORR_POL(0) | + XCVR_RX_DIG_DCOC_CTRL_0_BBA_CORR_POL(0) | + XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CORRECT_SRC(1), + + .dcoc_ctrl_1_init = XCVR_RX_DIG_DCOC_CTRL_1_DCOC_TRK_MIN_AGC_IDX(26), + + .dc_resid_ctrl_init = XCVR_RX_DIG_DC_RESID_CTRL_DC_RESID_ITER_FREEZE(4) | + XCVR_RX_DIG_DC_RESID_CTRL_DC_RESID_ALPHA(1) | + XCVR_RX_DIG_DC_RESID_CTRL_DC_RESID_EXT_DC_EN(1) | + XCVR_RX_DIG_DC_RESID_CTRL_DC_RESID_MIN_AGC_IDX(26), + + .dcoc_cal_gain_init = XCVR_RX_DIG_DCOC_CAL_GAIN_DCOC_BBA_CAL_GAIN1(1) | + XCVR_RX_DIG_DCOC_CAL_GAIN_DCOC_LNA_CAL_GAIN1(1) | + XCVR_RX_DIG_DCOC_CAL_GAIN_DCOC_BBA_CAL_GAIN2(1) | + XCVR_RX_DIG_DCOC_CAL_GAIN_DCOC_LNA_CAL_GAIN2(2) | + XCVR_RX_DIG_DCOC_CAL_GAIN_DCOC_BBA_CAL_GAIN3(3) | + XCVR_RX_DIG_DCOC_CAL_GAIN_DCOC_LNA_CAL_GAIN3(1) , + + .dcoc_cal_rcp_init = XCVR_RX_DIG_DCOC_CAL_RCP_ALPHA_CALC_RECIP(1) | + XCVR_RX_DIG_DCOC_CAL_RCP_DCOC_TMP_CALC_RECIP(711), + + .lna_gain_val_3_0 = XCVR_RX_DIG_LNA_GAIN_VAL_3_0_LNA_GAIN_VAL_0(0x1DU) | + XCVR_RX_DIG_LNA_GAIN_VAL_3_0_LNA_GAIN_VAL_1(0x32U) | + XCVR_RX_DIG_LNA_GAIN_VAL_3_0_LNA_GAIN_VAL_2(0x09U) | + XCVR_RX_DIG_LNA_GAIN_VAL_3_0_LNA_GAIN_VAL_3(0x38U), + + .lna_gain_val_7_4 = XCVR_RX_DIG_LNA_GAIN_VAL_7_4_LNA_GAIN_VAL_4(0x4FU) | + XCVR_RX_DIG_LNA_GAIN_VAL_7_4_LNA_GAIN_VAL_5(0x5BU) | + XCVR_RX_DIG_LNA_GAIN_VAL_7_4_LNA_GAIN_VAL_6(0x72U) | + XCVR_RX_DIG_LNA_GAIN_VAL_7_4_LNA_GAIN_VAL_7(0x8AU), + .lna_gain_val_8 = XCVR_RX_DIG_LNA_GAIN_VAL_8_LNA_GAIN_VAL_8(0xA0U) | + XCVR_RX_DIG_LNA_GAIN_VAL_8_LNA_GAIN_VAL_9(0xB6U), + + .bba_res_tune_val_7_0 = XCVR_RX_DIG_BBA_RES_TUNE_VAL_7_0_BBA_RES_TUNE_VAL_0(0x0) | + XCVR_RX_DIG_BBA_RES_TUNE_VAL_7_0_BBA_RES_TUNE_VAL_1(0x0) | + XCVR_RX_DIG_BBA_RES_TUNE_VAL_7_0_BBA_RES_TUNE_VAL_2(0x0) | + XCVR_RX_DIG_BBA_RES_TUNE_VAL_7_0_BBA_RES_TUNE_VAL_3(0x0) | + XCVR_RX_DIG_BBA_RES_TUNE_VAL_7_0_BBA_RES_TUNE_VAL_4(0x0) | + XCVR_RX_DIG_BBA_RES_TUNE_VAL_7_0_BBA_RES_TUNE_VAL_5(0x0) | + XCVR_RX_DIG_BBA_RES_TUNE_VAL_7_0_BBA_RES_TUNE_VAL_6(0x0) | + XCVR_RX_DIG_BBA_RES_TUNE_VAL_7_0_BBA_RES_TUNE_VAL_7(0xF), + .bba_res_tune_val_10_8 = XCVR_RX_DIG_BBA_RES_TUNE_VAL_10_8_BBA_RES_TUNE_VAL_8(0x0) | + XCVR_RX_DIG_BBA_RES_TUNE_VAL_10_8_BBA_RES_TUNE_VAL_9(0x1) | + XCVR_RX_DIG_BBA_RES_TUNE_VAL_10_8_BBA_RES_TUNE_VAL_10(0x2), + + .lna_gain_lin_val_2_0_init = XCVR_RX_DIG_LNA_GAIN_LIN_VAL_2_0_LNA_GAIN_LIN_VAL_0(0) | + XCVR_RX_DIG_LNA_GAIN_LIN_VAL_2_0_LNA_GAIN_LIN_VAL_1(0) | + XCVR_RX_DIG_LNA_GAIN_LIN_VAL_2_0_LNA_GAIN_LIN_VAL_2(1), + + .lna_gain_lin_val_5_3_init = XCVR_RX_DIG_LNA_GAIN_LIN_VAL_5_3_LNA_GAIN_LIN_VAL_3(3) | + XCVR_RX_DIG_LNA_GAIN_LIN_VAL_5_3_LNA_GAIN_LIN_VAL_4(5) | + XCVR_RX_DIG_LNA_GAIN_LIN_VAL_5_3_LNA_GAIN_LIN_VAL_5(7), + + .lna_gain_lin_val_8_6_init = XCVR_RX_DIG_LNA_GAIN_LIN_VAL_8_6_LNA_GAIN_LIN_VAL_6(14) | + XCVR_RX_DIG_LNA_GAIN_LIN_VAL_8_6_LNA_GAIN_LIN_VAL_7(27) | + XCVR_RX_DIG_LNA_GAIN_LIN_VAL_8_6_LNA_GAIN_LIN_VAL_8(50), + + .lna_gain_lin_val_9_init = XCVR_RX_DIG_LNA_GAIN_LIN_VAL_9_LNA_GAIN_LIN_VAL_9(91), + + .bba_res_tune_lin_val_3_0_init = XCVR_RX_DIG_BBA_RES_TUNE_LIN_VAL_3_0_BBA_RES_TUNE_LIN_VAL_0(8) | + XCVR_RX_DIG_BBA_RES_TUNE_LIN_VAL_3_0_BBA_RES_TUNE_LIN_VAL_1(11) | + XCVR_RX_DIG_BBA_RES_TUNE_LIN_VAL_3_0_BBA_RES_TUNE_LIN_VAL_2(16) | + XCVR_RX_DIG_BBA_RES_TUNE_LIN_VAL_3_0_BBA_RES_TUNE_LIN_VAL_3(22), + + .bba_res_tune_lin_val_7_4_init = XCVR_RX_DIG_BBA_RES_TUNE_LIN_VAL_7_4_BBA_RES_TUNE_LIN_VAL_4(31) | + XCVR_RX_DIG_BBA_RES_TUNE_LIN_VAL_7_4_BBA_RES_TUNE_LIN_VAL_5(44) | + XCVR_RX_DIG_BBA_RES_TUNE_LIN_VAL_7_4_BBA_RES_TUNE_LIN_VAL_6(62) | + XCVR_RX_DIG_BBA_RES_TUNE_LIN_VAL_7_4_BBA_RES_TUNE_LIN_VAL_7(42), /* Has 2 fractional bits unlike other BBA_RES_TUNE_LIN_VALs */ + + .bba_res_tune_lin_val_10_8_init = XCVR_RX_DIG_BBA_RES_TUNE_LIN_VAL_10_8_BBA_RES_TUNE_LIN_VAL_8(128) | + XCVR_RX_DIG_BBA_RES_TUNE_LIN_VAL_10_8_BBA_RES_TUNE_LIN_VAL_9(188) | + XCVR_RX_DIG_BBA_RES_TUNE_LIN_VAL_10_8_BBA_RES_TUNE_LIN_VAL_10(288), + + .dcoc_bba_step_init = XCVR_RX_DIG_DCOC_BBA_STEP_BBA_DCOC_STEP_RECIP(939) | + XCVR_RX_DIG_DCOC_BBA_STEP_BBA_DCOC_STEP(279), + + .dcoc_tza_step_00_init = XCVR_RX_DIG_DCOC_TZA_STEP_0_DCOC_TZA_STEP_GAIN_0(77) | + XCVR_RX_DIG_DCOC_TZA_STEP_0_DCOC_TZA_STEP_RCP_0(3404), + .dcoc_tza_step_01_init = XCVR_RX_DIG_DCOC_TZA_STEP_1_DCOC_TZA_STEP_GAIN_1(108) | + XCVR_RX_DIG_DCOC_TZA_STEP_1_DCOC_TZA_STEP_RCP_1(2439), + .dcoc_tza_step_02_init = XCVR_RX_DIG_DCOC_TZA_STEP_2_DCOC_TZA_STEP_GAIN_2(155) | + XCVR_RX_DIG_DCOC_TZA_STEP_2_DCOC_TZA_STEP_RCP_2(1691), + .dcoc_tza_step_03_init = XCVR_RX_DIG_DCOC_TZA_STEP_3_DCOC_TZA_STEP_GAIN_3(220) | + XCVR_RX_DIG_DCOC_TZA_STEP_3_DCOC_TZA_STEP_RCP_3(1192), + .dcoc_tza_step_04_init = XCVR_RX_DIG_DCOC_TZA_STEP_4_DCOC_TZA_STEP_GAIN_4(314) | + XCVR_RX_DIG_DCOC_TZA_STEP_4_DCOC_TZA_STEP_RCP_4(835), + .dcoc_tza_step_05_init = XCVR_RX_DIG_DCOC_TZA_STEP_5_DCOC_TZA_STEP_GAIN_5(436) | + XCVR_RX_DIG_DCOC_TZA_STEP_5_DCOC_TZA_STEP_RCP_5(601), + .dcoc_tza_step_06_init = XCVR_RX_DIG_DCOC_TZA_STEP_6_DCOC_TZA_STEP_GAIN_6(614) | + XCVR_RX_DIG_DCOC_TZA_STEP_6_DCOC_TZA_STEP_RCP_6(427), + .dcoc_tza_step_07_init = XCVR_RX_DIG_DCOC_TZA_STEP_7_DCOC_TZA_STEP_GAIN_7(845) | + XCVR_RX_DIG_DCOC_TZA_STEP_7_DCOC_TZA_STEP_RCP_7(310), + .dcoc_tza_step_08_init = XCVR_RX_DIG_DCOC_TZA_STEP_8_DCOC_TZA_STEP_GAIN_8(1256) | + XCVR_RX_DIG_DCOC_TZA_STEP_8_DCOC_TZA_STEP_RCP_8(209), + .dcoc_tza_step_09_init = XCVR_RX_DIG_DCOC_TZA_STEP_9_DCOC_TZA_STEP_GAIN_9(1805) | + XCVR_RX_DIG_DCOC_TZA_STEP_9_DCOC_TZA_STEP_RCP_9(145), + .dcoc_tza_step_10_init = XCVR_RX_DIG_DCOC_TZA_STEP_10_DCOC_TZA_STEP_GAIN_10(2653) | + XCVR_RX_DIG_DCOC_TZA_STEP_10_DCOC_TZA_STEP_RCP_10(99), +#if (RADIO_IS_GEN_2P1) + .dcoc_cal_fail_th_init = XCVR_RX_DIG_DCOC_CAL_FAIL_TH_DCOC_CAL_BETA_F_TH(20) | + XCVR_RX_DIG_DCOC_CAL_FAIL_TH_DCOC_CAL_ALPHA_F_TH(10), + .dcoc_cal_pass_th_init = XCVR_RX_DIG_DCOC_CAL_PASS_TH_DCOC_CAL_BETA_P_TH(16) | + XCVR_RX_DIG_DCOC_CAL_PASS_TH_DCOC_CAL_ALPHA_P_TH(2), +#endif /* (RADIO_IS_GEN_2P1) */ + /* AGC Configs */ + .agc_gain_tbl_03_00_init = XCVR_RX_DIG_AGC_GAIN_TBL_03_00_LNA_GAIN_00(0) | + XCVR_RX_DIG_AGC_GAIN_TBL_03_00_BBA_GAIN_00(0) | + XCVR_RX_DIG_AGC_GAIN_TBL_03_00_LNA_GAIN_01(1) | + XCVR_RX_DIG_AGC_GAIN_TBL_03_00_BBA_GAIN_01(1) | + XCVR_RX_DIG_AGC_GAIN_TBL_03_00_LNA_GAIN_02(2) | + XCVR_RX_DIG_AGC_GAIN_TBL_03_00_BBA_GAIN_02(1) | + XCVR_RX_DIG_AGC_GAIN_TBL_03_00_LNA_GAIN_03(2) | + XCVR_RX_DIG_AGC_GAIN_TBL_03_00_BBA_GAIN_03(2), + + .agc_gain_tbl_07_04_init = XCVR_RX_DIG_AGC_GAIN_TBL_07_04_LNA_GAIN_04(2) | + XCVR_RX_DIG_AGC_GAIN_TBL_07_04_BBA_GAIN_04(3) | + XCVR_RX_DIG_AGC_GAIN_TBL_07_04_LNA_GAIN_05(3) | + XCVR_RX_DIG_AGC_GAIN_TBL_07_04_BBA_GAIN_05(0) | + XCVR_RX_DIG_AGC_GAIN_TBL_07_04_LNA_GAIN_06(3) | + XCVR_RX_DIG_AGC_GAIN_TBL_07_04_BBA_GAIN_06(1) | + XCVR_RX_DIG_AGC_GAIN_TBL_07_04_LNA_GAIN_07(3) | + XCVR_RX_DIG_AGC_GAIN_TBL_07_04_BBA_GAIN_07(2), + + .agc_gain_tbl_11_08_init = XCVR_RX_DIG_AGC_GAIN_TBL_11_08_LNA_GAIN_08(3) | + XCVR_RX_DIG_AGC_GAIN_TBL_11_08_BBA_GAIN_08(3) | + XCVR_RX_DIG_AGC_GAIN_TBL_11_08_LNA_GAIN_09(4) | + XCVR_RX_DIG_AGC_GAIN_TBL_11_08_BBA_GAIN_09(2) | + XCVR_RX_DIG_AGC_GAIN_TBL_11_08_LNA_GAIN_10(4) | + XCVR_RX_DIG_AGC_GAIN_TBL_11_08_BBA_GAIN_10(3) | + XCVR_RX_DIG_AGC_GAIN_TBL_11_08_LNA_GAIN_11(4) | + XCVR_RX_DIG_AGC_GAIN_TBL_11_08_BBA_GAIN_11(4), + + .agc_gain_tbl_15_12_init = XCVR_RX_DIG_AGC_GAIN_TBL_15_12_LNA_GAIN_12(5) | + XCVR_RX_DIG_AGC_GAIN_TBL_15_12_BBA_GAIN_12(4) | + XCVR_RX_DIG_AGC_GAIN_TBL_15_12_LNA_GAIN_13(5) | + XCVR_RX_DIG_AGC_GAIN_TBL_15_12_BBA_GAIN_13(5) | + XCVR_RX_DIG_AGC_GAIN_TBL_15_12_LNA_GAIN_14(6) | + XCVR_RX_DIG_AGC_GAIN_TBL_15_12_BBA_GAIN_14(4) | + XCVR_RX_DIG_AGC_GAIN_TBL_15_12_LNA_GAIN_15(6) | + XCVR_RX_DIG_AGC_GAIN_TBL_15_12_BBA_GAIN_15(5), + + .agc_gain_tbl_19_16_init = XCVR_RX_DIG_AGC_GAIN_TBL_19_16_LNA_GAIN_16(6) | + XCVR_RX_DIG_AGC_GAIN_TBL_19_16_BBA_GAIN_16(6) | + XCVR_RX_DIG_AGC_GAIN_TBL_19_16_LNA_GAIN_17(6) | + XCVR_RX_DIG_AGC_GAIN_TBL_19_16_BBA_GAIN_17(7) | + XCVR_RX_DIG_AGC_GAIN_TBL_19_16_LNA_GAIN_18(7) | + XCVR_RX_DIG_AGC_GAIN_TBL_19_16_BBA_GAIN_18(6) | + XCVR_RX_DIG_AGC_GAIN_TBL_19_16_LNA_GAIN_19(7) | + XCVR_RX_DIG_AGC_GAIN_TBL_19_16_BBA_GAIN_19(7), + + .agc_gain_tbl_23_20_init = XCVR_RX_DIG_AGC_GAIN_TBL_23_20_LNA_GAIN_20(8) | + XCVR_RX_DIG_AGC_GAIN_TBL_23_20_BBA_GAIN_20(6) | + XCVR_RX_DIG_AGC_GAIN_TBL_23_20_LNA_GAIN_21(8) | + XCVR_RX_DIG_AGC_GAIN_TBL_23_20_BBA_GAIN_21(7) | + XCVR_RX_DIG_AGC_GAIN_TBL_23_20_LNA_GAIN_22(9) | + XCVR_RX_DIG_AGC_GAIN_TBL_23_20_BBA_GAIN_22(6) | + XCVR_RX_DIG_AGC_GAIN_TBL_23_20_LNA_GAIN_23(9) | + XCVR_RX_DIG_AGC_GAIN_TBL_23_20_BBA_GAIN_23(7), + + .agc_gain_tbl_26_24_init = XCVR_RX_DIG_AGC_GAIN_TBL_26_24_LNA_GAIN_24(9) | + XCVR_RX_DIG_AGC_GAIN_TBL_26_24_BBA_GAIN_24(8) | + XCVR_RX_DIG_AGC_GAIN_TBL_26_24_LNA_GAIN_25(9) | + XCVR_RX_DIG_AGC_GAIN_TBL_26_24_BBA_GAIN_25(9) | + XCVR_RX_DIG_AGC_GAIN_TBL_26_24_LNA_GAIN_26(9) | + XCVR_RX_DIG_AGC_GAIN_TBL_26_24_BBA_GAIN_26(10), + + .rssi_ctrl_0_init = XCVR_RX_DIG_RSSI_CTRL_0_RSSI_USE_VALS(1) | + XCVR_RX_DIG_RSSI_CTRL_0_RSSI_HOLD_SRC(0) | + XCVR_RX_DIG_RSSI_CTRL_0_RSSI_HOLD_EN(1) | + XCVR_RX_DIG_RSSI_CTRL_0_RSSI_IIR_CW_WEIGHT(0) | +#if !RADIO_IS_GEN_2P1 + XCVR_RX_DIG_RSSI_CTRL_0_RSSI_N_WINDOW_AVG(1) | +#else + XCVR_RX_DIG_RSSI_CTRL_0_RSSI_N_WINDOW_NB(1) | +#endif /* !RADIO_IS_GEN_2P1 */ + XCVR_RX_DIG_RSSI_CTRL_0_RSSI_HOLD_DELAY(4) | + XCVR_RX_DIG_RSSI_CTRL_0_RSSI_IIR_WEIGHT(3) | + XCVR_RX_DIG_RSSI_CTRL_0_RSSI_VLD_SETTLE(3) | + XCVR_RX_DIG_RSSI_CTRL_0_RSSI_ADJ(0xE8) , + + .cca_ed_lqi_ctrl_0_init = XCVR_RX_DIG_CCA_ED_LQI_CTRL_0_LQI_CORR_THRESH(0) | + XCVR_RX_DIG_CCA_ED_LQI_CTRL_0_CORR_CNTR_THRESH(0) | + XCVR_RX_DIG_CCA_ED_LQI_CTRL_0_LQI_CNTR(0x1A) | + XCVR_RX_DIG_CCA_ED_LQI_CTRL_0_SNR_ADJ(0), + + .cca_ed_lqi_ctrl_1_init = XCVR_RX_DIG_CCA_ED_LQI_CTRL_1_RSSI_NOISE_AVG_DELAY(0) | + XCVR_RX_DIG_CCA_ED_LQI_CTRL_1_RSSI_NOISE_AVG_FACTOR(0) | + XCVR_RX_DIG_CCA_ED_LQI_CTRL_1_LQI_RSSI_WEIGHT(0x4) | + XCVR_RX_DIG_CCA_ED_LQI_CTRL_1_LQI_RSSI_SENS(0x7) | + XCVR_RX_DIG_CCA_ED_LQI_CTRL_1_SNR_LQI_DIS(0) | +#if !RADIO_IS_GEN_2P1 + XCVR_RX_DIG_CCA_ED_LQI_CTRL_1_SEL_SNR_MODE(0) | +#endif /* !RADIO_IS_GEN_2P1 */ + XCVR_RX_DIG_CCA_ED_LQI_CTRL_1_MEAS_TRANS_TO_IDLE(0) | + XCVR_RX_DIG_CCA_ED_LQI_CTRL_1_CCA1_ED_EN_DIS(0) | + XCVR_RX_DIG_CCA_ED_LQI_CTRL_1_MAN_MEAS_COMPLETE(0) | + XCVR_RX_DIG_CCA_ED_LQI_CTRL_1_MAN_AA_MATCH(0) | + XCVR_RX_DIG_CCA_ED_LQI_CTRL_1_SNR_LQI_WEIGHT(0x5) | + XCVR_RX_DIG_CCA_ED_LQI_CTRL_1_LQI_BIAS(0x2), + + /* XCVR_TSM configs */ + .tsm_ctrl = XCVR_TSM_CTRL_PA_RAMP_SEL(PA_RAMP_SEL) | + XCVR_TSM_CTRL_DATA_PADDING_EN(DATA_PADDING_EN) | + XCVR_TSM_CTRL_TSM_IRQ0_EN(0) | + XCVR_TSM_CTRL_TSM_IRQ1_EN(0) | + XCVR_TSM_CTRL_RAMP_DN_DELAY(0x4) | + XCVR_TSM_CTRL_TX_ABORT_DIS(0) | + XCVR_TSM_CTRL_RX_ABORT_DIS(0) | + XCVR_TSM_CTRL_ABORT_ON_CTUNE(0) | + XCVR_TSM_CTRL_ABORT_ON_CYCLE_SLIP(0) | + XCVR_TSM_CTRL_ABORT_ON_FREQ_TARG(0) | + XCVR_TSM_CTRL_BKPT(0xFF) , + + .tsm_ovrd2_init = XCVR_TSM_OVRD2_FREQ_TARG_LD_EN_OVRD(0) | XCVR_TSM_OVRD2_FREQ_TARG_LD_EN_OVRD_EN_MASK, + .end_of_seq_init_26mhz = B3(END_OF_RX_WD_26MHZ) | B2(END_OF_RX_WU_26MHZ) | B1(END_OF_TX_WD) | B0(END_OF_TX_WU), + .end_of_seq_init_32mhz = B3(END_OF_RX_WD) | B2(END_OF_RX_WU) | B1(END_OF_TX_WD) | B0(END_OF_TX_WU), + +#if !RADIO_IS_GEN_2P1 + .lpps_ctrl_init = B3(102) | B2(40) | B1(0) | B0(0), +#endif /* !RADIO_IS_GEN_2P1 */ + + .tsm_fast_ctrl2_init_26mhz = B3(102 + ADD_FOR_26MHZ) | B2(40 + ADD_FOR_26MHZ) | B1(66) | B0(8), + .tsm_fast_ctrl2_init_32mhz = B3(102) | B2(40) | B1(66) | B0(8), + + .pa_ramp_tbl_0_init = XCVR_TSM_PA_RAMP_TBL0_PA_RAMP0(PA_RAMP_0) | XCVR_TSM_PA_RAMP_TBL0_PA_RAMP1(PA_RAMP_1) | + XCVR_TSM_PA_RAMP_TBL0_PA_RAMP2(PA_RAMP_2) | XCVR_TSM_PA_RAMP_TBL0_PA_RAMP3(PA_RAMP_3), + .pa_ramp_tbl_1_init = XCVR_TSM_PA_RAMP_TBL1_PA_RAMP4(PA_RAMP_4) | XCVR_TSM_PA_RAMP_TBL1_PA_RAMP5(PA_RAMP_5) | + XCVR_TSM_PA_RAMP_TBL1_PA_RAMP6(PA_RAMP_6) | XCVR_TSM_PA_RAMP_TBL1_PA_RAMP7(PA_RAMP_7), + + .recycle_count_init_26mhz = B3(0) | B2(0x1C + ADD_FOR_26MHZ) | B1(0x06) | B0(0x66 + ADD_FOR_26MHZ), + .recycle_count_init_26mhz = B3(0) | B2(0x1C) | B1(0x06) | B0(0x66), + + .tsm_timing_00_init = B3(END_OF_RX_WD) | B2(0x00) | B1(END_OF_TX_WD) | B0(0x00), /* bb_ldo_hf_en */ + .tsm_timing_01_init = B3(END_OF_RX_WD) | B2(0x00) | B1(END_OF_TX_WD) | B0(0x00), /* bb_ldo_adcdac_en */ + .tsm_timing_02_init = B3(END_OF_RX_WD) | B2(0x00) | B1(0xFF) | B0(0xFF), /* bb_ldo_bba_en */ + .tsm_timing_03_init = B3(END_OF_RX_WD) | B2(0x00) | B1(END_OF_TX_WD) | B0(0x00), /* bb_ldo_pd_en */ + .tsm_timing_04_init = B3(END_OF_RX_WD) | B2(0x00) | B1(END_OF_TX_WD) | B0(0x00), /* bb_ldo_fdbk_en */ + .tsm_timing_05_init = B3(END_OF_RX_WD) | B2(0x00) | B1(END_OF_TX_WD) | B0(0x00), /* bb_ldo_vcolo_en */ + .tsm_timing_06_init = B3(END_OF_RX_WD) | B2(0x00) | B1(END_OF_TX_WD) | B0(0x00), /* bb_ldo_vtref_en */ + .tsm_timing_07_init = B3(0x05) | B2(0x00) | B1(0x05) | B0(0x00), /* bb_ldo_fdbk_bleed_en */ + .tsm_timing_08_init = B3(0x03) | B2(0x00) | B1(0x03) | B0(0x00), /* bb_ldo_vcolo_bleed_en */ + .tsm_timing_09_init = B3(0x03) | B2(0x00) | B1(0x03) | B0(0x00), /* bb_ldo_vcolo_fastcharge_en */ + + .tsm_timing_10_init = B3(END_OF_RX_WD) | B2(0x03 + AUX_PLL_DELAY) | B1(END_OF_TX_WD) | B0(0x03), /* bb_xtal_pll_ref_clk_en */ + .tsm_timing_11_init = B3(0xFF) | B2(0xFF) | B1(END_OF_TX_WD) | B0(0x03), /* bb_xtal_dac_ref_clk_en */ + .tsm_timing_12_init = B3(END_OF_RX_WD) | B2(0x03 + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), /* rxtx_auxpll_vco_ref_clk_en */ + .tsm_timing_13_init = B3(0x18) | B2(0x00) | B1(0x4C) | B0(0x00), /* sy_vco_autotune_en */ + .tsm_timing_14_init_26mhz = B3(END_OF_RX_WD_26MHZ) | B2(0x31+ADD_FOR_26MHZ) | B1(END_OF_TX_WU + PD_CYCLE_SLIP_TX_LO_ADJ) | B0(0x63 + PD_CYCLE_SLIP_TX_HI_ADJ), /* sy_pd_cycle_slip_ld_ft_en */ + .tsm_timing_14_init_32mhz = B3(END_OF_RX_WD) | B2(0x31 + AUX_PLL_DELAY) | B1(END_OF_TX_WU + PD_CYCLE_SLIP_TX_LO_ADJ) | B0(0x63 + PD_CYCLE_SLIP_TX_HI_ADJ), + .tsm_timing_15_init = B3(END_OF_RX_WD) | B2(0x03 + AUX_PLL_DELAY) | B1(END_OF_TX_WD) | B0(0x03), /* sy_vco_en */ + .tsm_timing_16_init_26mhz = B3(END_OF_RX_WD_26MHZ) | B2(0x1C + ADD_FOR_26MHZ) | B1(0xFF) | B0(0xFF), /* sy_lo_rx_buf_en */ + .tsm_timing_16_init_32mhz = B3(END_OF_RX_WD) | B2(0x1C + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), + .tsm_timing_17_init = B3(0xFF) | B2(0xFF) | B1(END_OF_TX_WD) | B0(0x55), /* sy_lo_tx_buf_en */ + .tsm_timing_18_init = B3(END_OF_RX_WD) | B2(0x05 + AUX_PLL_DELAY) | B1(END_OF_TX_WD) | B0(0x05), /* sy_divn_en */ + .tsm_timing_19_init = B3(0x18+AUX_PLL_DELAY) | B2(0x03 + AUX_PLL_DELAY) | B1(0x4C) | B0(0x03), /* sy_pd_filter_charge_en */ + + .tsm_timing_20_init = B3(END_OF_RX_WD) | B2(0x03 + AUX_PLL_DELAY) | B1(END_OF_TX_WD) | B0(0x03), /* sy_pd_en */ + .tsm_timing_21_init = B3(END_OF_RX_WD) | B2(0x04 + AUX_PLL_DELAY) | B1(END_OF_TX_WD) | B0(0x04), /* sy_lo_divn_en */ + .tsm_timing_22_init = B3(END_OF_RX_WD) | B2(0x04 + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), /* sy_lo_rx_en */ + .tsm_timing_23_init = B3(0xFF) | B2(0xFF) | B1(END_OF_TX_WD) | B0(0x04), /*sy_lo_tx_en */ + .tsm_timing_24_init = B3(0x18) | B2(0x00) | B1(0x4C) | B0(0x00), /* sy_divn_cal_en */ + .tsm_timing_25_init_26mhz = B3(END_OF_RX_WD_26MHZ) | B2(0x1D + ADD_FOR_26MHZ + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), /* rx_lna_mixer_en */ + .tsm_timing_25_init_32mhz = B3(END_OF_RX_WD) | B2(0x1D + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), + .tsm_timing_26_init = B3(0xFF) | B2(0xFF) | B1(END_OF_TX_WD) | B0(0x58), /* tx_pa_en */ + .tsm_timing_27_init_26mhz = B3(END_OF_RX_WD_26MHZ) | B2(0x20 + ADD_FOR_26MHZ + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), /* rx_adc_i_q_en */ + .tsm_timing_27_init_32mhz = B3(END_OF_RX_WD) | B2(0x20 + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), + .tsm_timing_28_init_26mhz = B3(0x21 + ADD_FOR_26MHZ) | B2(0x20 + ADD_FOR_26MHZ + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), /* rx_adc_reset_en */ + .tsm_timing_28_init_32mhz = B3(0x21 + AUX_PLL_DELAY) | B2(0x20 + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), + .tsm_timing_29_init_26mhz = B3(END_OF_RX_WD_26MHZ) | B2(0x1E + ADD_FOR_26MHZ + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), /* rx_bba_i_q_en */ + .tsm_timing_29_init_32mhz = B3(END_OF_RX_WD) | B2(0x1E + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), + + .tsm_timing_30_init_26mhz = B3(END_OF_RX_WD_26MHZ) | B2(0x20 + ADD_FOR_26MHZ + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), /* rx_bba_pdet_en */ + .tsm_timing_30_init_32mhz = B3(END_OF_RX_WD) | B2(0x20 + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), + .tsm_timing_31_init_26mhz = B3(END_OF_RX_WD_26MHZ) | B2(0x1F + ADD_FOR_26MHZ + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), /* rx_bba_tza_dcoc_en */ + .tsm_timing_31_init_32mhz = B3(END_OF_RX_WD) | B2(0x1F + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), + .tsm_timing_32_init_26mhz = B3(END_OF_RX_WD_26MHZ) | B2(0x1D + ADD_FOR_26MHZ + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), /* rx_tza_i_q_en */ + .tsm_timing_32_init_32mhz = B3(END_OF_RX_WD) | B2(0x1D + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), + .tsm_timing_33_init_26mhz = B3(END_OF_RX_WD_26MHZ) | B2(0x20 + ADD_FOR_26MHZ + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), /* rx_tza_pdet_en */ + .tsm_timing_33_init_32mhz = B3(END_OF_RX_WD) | B2(0x20 + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), + .tsm_timing_34_init = B3(END_OF_RX_WD) | B2(0x07 + AUX_PLL_DELAY) | B1(END_OF_TX_WD) | B0(0x07), /* pll_dig_en */ + .tsm_timing_35_init = B3(0xFF) | B2(0xFF) | B1(END_OF_TX_WD), /* tx_dig_en - Byte 0 comes from mode specific settings */ + .tsm_timing_36_init_26mhz = B3(END_OF_RX_WD) | B2(0x66 + ADD_FOR_26MHZ + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), /* rx_dig_en */ + .tsm_timing_36_init_32mhz = B3(END_OF_RX_WD) | B2(0x66 + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), + .tsm_timing_37_init_26mhz = B3(0x67 + ADD_FOR_26MHZ + AUX_PLL_DELAY) | B2(0x66 + ADD_FOR_26MHZ + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), /* rx_init */ + .tsm_timing_37_init_32mhz = B3(0x67 + AUX_PLL_DELAY) | B2(0x66 + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), + .tsm_timing_38_init = B3(END_OF_RX_WD) | B2(0x0E + AUX_PLL_DELAY) | B1(END_OF_TX_WD) | B0(0x42), /* sigma_delta_en */ + .tsm_timing_39_init_26mhz = B3(END_OF_RX_WD_26MHZ) | B2(0x66 + ADD_FOR_26MHZ + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), /* rx_phy_en */ + .tsm_timing_39_init_32mhz = B3(END_OF_RX_WD) | B2(0x66 + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), + + .tsm_timing_40_init_26mhz = B3(END_OF_RX_WD_26MHZ) | B2(0x26 + ADD_FOR_26MHZ + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), /* dcoc_en */ + .tsm_timing_40_init_32mhz = B3(END_OF_RX_WD) | B2(0x26 + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), + .tsm_timing_41_init_26mhz = B3(0x27 + ADD_FOR_26MHZ + AUX_PLL_DELAY) | B2(0x26 + ADD_FOR_26MHZ + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), /* dcoc_init */ + .tsm_timing_41_init_32mhz = B3(0x27 + AUX_PLL_DELAY) | B2(0x26 + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), + .tsm_timing_51_init = B3(END_OF_RX_WD) | B2(0x03 + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), /* rxtx_auxpll_bias_en */ + .tsm_timing_52_init_26mhz = B3(0x17 + ADD_FOR_26MHZ + AUX_PLL_DELAY) | B2(0x06 + ADD_FOR_26MHZ + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), /* rxtx_auxpll_fcal_en */ + .tsm_timing_52_init_32mhz = B3(0x17 + AUX_PLL_DELAY) | B2(0x06 + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), + .tsm_timing_53_init = B3(END_OF_RX_WD) | B2(0x03 + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), /* rxtx_auxpll_lf_pd_en */ + .tsm_timing_54_init_26mhz = B3(0x17 + ADD_FOR_26MHZ + AUX_PLL_DELAY) | B2(0x03 + ADD_FOR_26MHZ + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), /* rxtx_auxpll_pd_lf_filter_charge_en */ + .tsm_timing_54_init_32mhz = B3(0x17 + AUX_PLL_DELAY) | B2(0x03 + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), + .tsm_timing_55_init_26mhz = B3(END_OF_RX_WD_26MHZ) | B2(0x20 + ADD_FOR_26MHZ + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), /* rxtx_auxpll_adc_buf_en */ + .tsm_timing_55_init_32mhz = B3(END_OF_RX_WD) | B2(0x20 + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), + .tsm_timing_56_init_26mhz = B3(END_OF_RX_WD_26MHZ) | B2(0x20 + ADD_FOR_26MHZ + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), /* rxtx_auxpll_dig_buf_en */ + .tsm_timing_56_init_32mhz = B3(END_OF_RX_WD) | B2(0x20 + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), + .tsm_timing_57_init = B3(0x1A + AUX_PLL_DELAY) | B2(0x03 + AUX_PLL_DELAY) | B1(0xFF) | B0(0xFF), /*rxtx_rccal_en */ + .tsm_timing_58_init = B3(0xFF) | B2(0xFF) | B1(END_OF_TX_WD) | B0(0x03), /* tx_hpm_dac_en */ + +/* XCVR_TX_DIG configs */ +#define radio_dft_mode 0 +#define lfsr_length 4 +#define lfsr_en 0 +#define dft_clk_sel 4 +#define tx_dft_en 0 +#define soc_test_sel 0 +#define tx_capture_pol 0 +#define freq_word_adj 0 +#define lrm 0 +#define data_padding_pat_1 0x55 +#define data_padding_pat_0 0xAA +#define gfsk_multiply_table_manual 0 +#define gfsk_mi 1 +#define gfsk_mld 0 +#define gfsk_fld 0 +#define gfsk_mod_index_scaling 0 +#define tx_image_filter_ovrd_en 0 +#define tx_image_filter_0_ovrd 0 +#define tx_image_filter_1_ovrd 0 +#define tx_image_filter_2_ovrd 0 +#define gfsk_filter_coeff_manual2 0xC0630401 +#define gfsk_filter_coeff_manual1 0xBB29960D +#define fsk_modulation_scale_0 0x1800 +#define fsk_modulation_scale_1 0x0800 +#define dft_mod_patternval 0 +#define ctune_bist_go 0 +#define ctune_bist_thrshld 0 +#define pa_am_mod_freq 0 +#define pa_am_mod_entries 0 +#define pa_am_mod_en 0 +#define syn_bist_go 0 +#define syn_bist_all_channels 0 +#define freq_count_threshold 0 +#define hpm_inl_bist_go 0 +#define hpm_dnl_bist_go 0 +#define dft_max_ram_size 0 + + .tx_ctrl = XCVR_TX_DIG_CTRL_RADIO_DFT_MODE(radio_dft_mode) | + XCVR_TX_DIG_CTRL_LFSR_LENGTH(lfsr_length) | + XCVR_TX_DIG_CTRL_LFSR_EN(lfsr_en) | + XCVR_TX_DIG_CTRL_DFT_CLK_SEL(dft_clk_sel) | + XCVR_TX_DIG_CTRL_TX_DFT_EN(tx_dft_en) | + XCVR_TX_DIG_CTRL_SOC_TEST_SEL(soc_test_sel) | + XCVR_TX_DIG_CTRL_TX_CAPTURE_POL(tx_capture_pol) | + XCVR_TX_DIG_CTRL_FREQ_WORD_ADJ(freq_word_adj), +/*-------------------------------------------------------------------------------------------------*/ + .tx_data_padding = XCVR_TX_DIG_DATA_PADDING_LRM(lrm) | + XCVR_TX_DIG_DATA_PADDING_DATA_PADDING_PAT_1(data_padding_pat_1) | + XCVR_TX_DIG_DATA_PADDING_DATA_PADDING_PAT_0(data_padding_pat_0), +/*-------------------------------------------------------------------------------------------------*/ + .tx_dft_pattern = XCVR_TX_DIG_DFT_PATTERN_DFT_MOD_PATTERN(dft_mod_patternval), +#if !RADIO_IS_GEN_2P1 +/*-------------------------------------------------------------------------------------------------*/ + .rf_dft_bist_1 = XCVR_TX_DIG_RF_DFT_BIST_1_CTUNE_BIST_GO(ctune_bist_go) | + XCVR_TX_DIG_RF_DFT_BIST_1_CTUNE_BIST_THRSHLD(ctune_bist_thrshld) | + XCVR_TX_DIG_RF_DFT_BIST_1_PA_AM_MOD_FREQ(pa_am_mod_freq) | + XCVR_TX_DIG_RF_DFT_BIST_1_PA_AM_MOD_ENTRIES(pa_am_mod_entries) | + XCVR_TX_DIG_RF_DFT_BIST_1_PA_AM_MOD_EN(pa_am_mod_en), +/*-------------------------------------------------------------------------------------------------*/ + .rf_dft_bist_2 = XCVR_TX_DIG_RF_DFT_BIST_2_SYN_BIST_GO(syn_bist_go) | + XCVR_TX_DIG_RF_DFT_BIST_2_SYN_BIST_ALL_CHANNELS(syn_bist_all_channels) | + XCVR_TX_DIG_RF_DFT_BIST_2_FREQ_COUNT_THRESHOLD(freq_count_threshold) | + XCVR_TX_DIG_RF_DFT_BIST_2_HPM_INL_BIST_GO(hpm_inl_bist_go) | + XCVR_TX_DIG_RF_DFT_BIST_2_HPM_DNL_BIST_GO(hpm_dnl_bist_go) | + XCVR_TX_DIG_RF_DFT_BIST_2_DFT_MAX_RAM_SIZE(dft_max_ram_size), +#endif /* !RADIO_IS_GEN_2P1 */ +}; + diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_gfsk_bt_0p3_h_0p5_config.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_gfsk_bt_0p3_h_0p5_config.c new file mode 100644 index 0000000000..8bb5e3637c --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_gfsk_bt_0p3_h_0p5_config.c @@ -0,0 +1,353 @@ +/* + * 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 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_xcvr.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ +/* MODE only configuration */ +const xcvr_mode_config_t gfsk_bt_0p3_h_0p5_mode_config = +{ + .radio_mode = GFSK_BT_0p3_h_0p5, + .scgc5_clock_ena_bits = SIM_SCGC5_PHYDIG_MASK | SIM_SCGC5_GEN_FSK_MASK, + + /* XCVR_MISC configs */ + .xcvr_ctrl.mask = XCVR_CTRL_XCVR_CTRL_PROTOCOL_MASK | + XCVR_CTRL_XCVR_CTRL_TGT_PWR_SRC_MASK | + XCVR_CTRL_XCVR_CTRL_DEMOD_SEL_MASK, + .xcvr_ctrl.init = XCVR_CTRL_XCVR_CTRL_PROTOCOL(8) | + XCVR_CTRL_XCVR_CTRL_TGT_PWR_SRC(7) | + XCVR_CTRL_XCVR_CTRL_DEMOD_SEL(1), + + /* XCVR_PHY configs */ + .phy_pre_ref0_init = 0x7BCDEB39, + .phy_pre_ref1_init = 0xCEF7DEF7, + .phy_pre_ref2_init = 0x0000CEB7, + + .phy_cfg1_init = XCVR_PHY_CFG1_AA_PLAYBACK(1) | + XCVR_PHY_CFG1_AA_OUTPUT_SEL(1) | + XCVR_PHY_CFG1_FSK_BIT_INVERT(0) | + XCVR_PHY_CFG1_BSM_EN_BLE(0) | + XCVR_PHY_CFG1_DEMOD_CLK_MODE(0) | + XCVR_PHY_CFG1_CTS_THRESH(0xda) | + XCVR_PHY_CFG1_FSK_FTS_TIMEOUT(2), + + .phy_el_cfg_init = XCVR_PHY_EL_CFG_EL_ENABLE(1) +#if !RADIO_IS_GEN_2P1 + | XCVR_PHY_EL_CFG_EL_ZB_ENABLE(0) +#endif /* !RADIO_IS_GEN_2P1 */ + , + + /* XCVR_RX_DIG configs */ + .rx_dig_ctrl_init_26mhz = XCVR_RX_DIG_RX_DIG_CTRL_RX_FSK_ZB_SEL(0) | /* Depends on protocol */ + XCVR_RX_DIG_RX_DIG_CTRL_RX_DC_RESID_EN(1) | /* Depends on protocol */ + XCVR_RX_DIG_RX_DIG_CTRL_RX_SRC_RATE(0), + + .rx_dig_ctrl_init_32mhz = XCVR_RX_DIG_RX_DIG_CTRL_RX_FSK_ZB_SEL(0) | /* Depends on protocol */ + XCVR_RX_DIG_RX_DIG_CTRL_RX_DC_RESID_EN(1), /* Depends on protocol */ + + .agc_ctrl_0_init = XCVR_RX_DIG_AGC_CTRL_0_AGC_DOWN_RSSI_THRESH(0xFF), + + /* XCVR_TSM configs */ +#if (DATA_PADDING_EN) + .tsm_timing_35_init = B0(TX_DIG_EN_ASSERT+TX_DIG_EN_TX_HI_ADJ), +#else + .tsm_timing_35_init = B0(TX_DIG_EN_ASSERT), +#endif /* (DATA_PADDING_EN) */ + + /* XCVR_TX_DIG configs */ + .tx_gfsk_ctrl = XCVR_TX_DIG_GFSK_CTRL_GFSK_MULTIPLY_TABLE_MANUAL(0x4000) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_MI(1) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_MLD(0) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_FLD(1) | /* Use GFSK Manual Filter Coeffs */ + XCVR_TX_DIG_GFSK_CTRL_GFSK_MOD_INDEX_SCALING(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_OVRD_EN(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_0_OVRD(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_1_OVRD(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_2_OVRD(0), + .tx_gfsk_coeff1_26mhz = (107U) << 0 | /* coeff 2/13 */ + (164U) << 7 | /* coeff 6/9 */ + (125U) << 16 | /* coef 3/12 */ + (169U) << 23, /* coeff 7/8 */ + .tx_gfsk_coeff2_26mhz = (72U) << 0 | /* coeff 0/15 */ + (90U) << 8 | /* coeff 1/14 */ + (141U) << 16 | /* coeff 4/11 */ + (155U) << 24, /* coeff 5/10 */ + .tx_gfsk_coeff1_32mhz = (70U) << 0 | /* coeff 2/13 */ + (216U) << 7 | /* coeff 6/9 */ + (105U) << 16 | /* coef 3/12 */ + (233U) << 23, /* coeff 7/8 */ + .tx_gfsk_coeff2_32mhz = (25U) << 0 | /* coeff 0/15 */ + (44U) << 8 | /* coeff 1/14 */ + (145U) << 16 | /* coeff 4/11 */ + (184U) << 24, /* coeff 5/10 */ +}; + +/* MODE & DATA RATE combined configuration */ +const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p3_h_0p5_1mbps_config = +{ + .radio_mode = GFSK_BT_0p3_h_0p5, + .data_rate = DR_1MBPS, + + .ana_sy_ctrl2.mask = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM_MASK, + .ana_sy_ctrl2.init = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM(0), /* VCO KVM */ + .ana_rx_bba.mask = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL_MASK | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL_MASK, + .ana_rx_bba.init = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL(4) | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL(4), /* BBA_BW_SEL and BBA2_BW_SEL */ + .ana_rx_tza.mask = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL_MASK, + .ana_rx_tza.init = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL(4), /*TZA_BW_SEL */ + + .phy_cfg2_init = XCVR_PHY_CFG2_PHY_FIFO_PRECHG(8) | + XCVR_PHY_CFG2_X2_DEMOD_GAIN(0xA) , + + /* AGC configs */ + .agc_ctrl_2_init_26mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(11) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + .agc_ctrl_2_init_32mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(12) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + + /* All constant values are represented as 16 bits, register writes will remove unused bits */ + .rx_chf_coeffs_26mhz.rx_chf_coef_0 = 0xFFFF, + .rx_chf_coeffs_26mhz.rx_chf_coef_1 = 0xFFFD, + .rx_chf_coeffs_26mhz.rx_chf_coef_2 = 0xFFF9, + .rx_chf_coeffs_26mhz.rx_chf_coef_3 = 0xFFF4, + .rx_chf_coeffs_26mhz.rx_chf_coef_4 = 0xFFF2, + .rx_chf_coeffs_26mhz.rx_chf_coef_5 = 0xFFF5, + .rx_chf_coeffs_26mhz.rx_chf_coef_6 = 0x0000, + .rx_chf_coeffs_26mhz.rx_chf_coef_7 = 0x0011, + .rx_chf_coeffs_26mhz.rx_chf_coef_8 = 0x0028, + .rx_chf_coeffs_26mhz.rx_chf_coef_9 = 0x0041, + .rx_chf_coeffs_26mhz.rx_chf_coef_10 = 0x0055, + .rx_chf_coeffs_26mhz.rx_chf_coef_11 = 0x0061, + + /* 32MHz Channel Filter */ + .rx_chf_coeffs_32mhz.rx_chf_coef_0 = 0x0001, + .rx_chf_coeffs_32mhz.rx_chf_coef_1 = 0xFFFF, + .rx_chf_coeffs_32mhz.rx_chf_coef_2 = 0xFFFA, + .rx_chf_coeffs_32mhz.rx_chf_coef_3 = 0xFFF4, + .rx_chf_coeffs_32mhz.rx_chf_coef_4 = 0xFFF0, + .rx_chf_coeffs_32mhz.rx_chf_coef_5 = 0xFFF0, + .rx_chf_coeffs_32mhz.rx_chf_coef_6 = 0xFFF9, + .rx_chf_coeffs_32mhz.rx_chf_coef_7 = 0x000B, + .rx_chf_coeffs_32mhz.rx_chf_coef_8 = 0x0025, + .rx_chf_coeffs_32mhz.rx_chf_coef_9 = 0x0043, + .rx_chf_coeffs_32mhz.rx_chf_coef_10 = 0x005C, + .rx_chf_coeffs_32mhz.rx_chf_coef_11 = 0x006A, + + .rx_rccal_ctrl_0 = XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_SMP_DLY(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_COMP_INV(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_DIS(0) , + .rx_rccal_ctrl_1 = XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_DIS(0) , + + .tx_fsk_scale_26mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1627) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x09d9), + .tx_fsk_scale_32mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1800) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x0800), +}; + +const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p3_h_0p5_500kbps_config = +{ + .radio_mode = GFSK_BT_0p3_h_0p5, + .data_rate = DR_500KBPS, + + .ana_sy_ctrl2.mask = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM_MASK, + .ana_sy_ctrl2.init = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM(0), /* VCO KVM */ + .ana_rx_bba.mask = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL_MASK | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL_MASK, + .ana_rx_bba.init = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL(5) | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL(5), /* BBA_BW_SEL and BBA2_BW_SEL */ + .ana_rx_tza.mask = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL_MASK, + .ana_rx_tza.init = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL(5), /* TZA_BW_SEL */ + + .phy_cfg2_init = XCVR_PHY_CFG2_PHY_FIFO_PRECHG(8) | + XCVR_PHY_CFG2_X2_DEMOD_GAIN(0x8) , + + /* AGC configs */ + .agc_ctrl_2_init_26mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(15) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + .agc_ctrl_2_init_32mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(18) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + + /* All constant values are represented as 16 bits, register writes will remove unused bits */ + .rx_chf_coeffs_26mhz.rx_chf_coef_0 = 0x0001, + .rx_chf_coeffs_26mhz.rx_chf_coef_1 = 0x0000, + .rx_chf_coeffs_26mhz.rx_chf_coef_2 = 0xFFFC, + .rx_chf_coeffs_26mhz.rx_chf_coef_3 = 0xFFF7, + .rx_chf_coeffs_26mhz.rx_chf_coef_4 = 0xFFF3, + .rx_chf_coeffs_26mhz.rx_chf_coef_5 = 0xFFF2, + .rx_chf_coeffs_26mhz.rx_chf_coef_6 = 0xFFF9, + .rx_chf_coeffs_26mhz.rx_chf_coef_7 = 0x000A, + .rx_chf_coeffs_26mhz.rx_chf_coef_8 = 0x0023, + .rx_chf_coeffs_26mhz.rx_chf_coef_9 = 0x0040, + .rx_chf_coeffs_26mhz.rx_chf_coef_10 = 0x0059, + .rx_chf_coeffs_26mhz.rx_chf_coef_11 = 0x0068, + + /* 32MHz Channel Filter */ + .rx_chf_coeffs_32mhz.rx_chf_coef_0 = 0x0001, + .rx_chf_coeffs_32mhz.rx_chf_coef_1 = 0x0001, + .rx_chf_coeffs_32mhz.rx_chf_coef_2 = 0xFFFF, + .rx_chf_coeffs_32mhz.rx_chf_coef_3 = 0xFFFA, + .rx_chf_coeffs_32mhz.rx_chf_coef_4 = 0xFFF3, + .rx_chf_coeffs_32mhz.rx_chf_coef_5 = 0xFFEF, + .rx_chf_coeffs_32mhz.rx_chf_coef_6 = 0xFFF3, + .rx_chf_coeffs_32mhz.rx_chf_coef_7 = 0x0001, + .rx_chf_coeffs_32mhz.rx_chf_coef_8 = 0x001D, + .rx_chf_coeffs_32mhz.rx_chf_coef_9 = 0x003F, + .rx_chf_coeffs_32mhz.rx_chf_coef_10 = 0x005F, + .rx_chf_coeffs_32mhz.rx_chf_coef_11 = 0x0072, + + .rx_rccal_ctrl_0 = XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_DIS(1) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_SMP_DLY(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_COMP_INV(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_DIS(1) , + .rx_rccal_ctrl_1 = XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_DIS(1) , + + .tx_fsk_scale_26mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1627) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x09d9), + .tx_fsk_scale_32mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1800) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x0800), +}; + +const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p3_h_0p5_250kbps_config = +{ + .radio_mode = GFSK_BT_0p3_h_0p5, + .data_rate = DR_250KBPS, + + .ana_sy_ctrl2.mask = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM_MASK, + .ana_sy_ctrl2.init = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM(0), /* VCO KVM */ + .ana_rx_bba.mask = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL_MASK | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL_MASK, + .ana_rx_bba.init = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL(5) | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL(5), /* BBA_BW_SEL and BBA2_BW_SEL */ + .ana_rx_tza.mask = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL_MASK, + .ana_rx_tza.init = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL(5), /* TZA_BW_SEL */ + + .phy_cfg2_init = XCVR_PHY_CFG2_PHY_FIFO_PRECHG(8) | + XCVR_PHY_CFG2_X2_DEMOD_GAIN(0x6) , + + /* AGC configs */ + .agc_ctrl_2_init_26mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(18) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(2) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + .agc_ctrl_2_init_32mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(22) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + + /* All constant values are represented as 16 bits, register writes will remove unused bits */ + .rx_chf_coeffs_26mhz.rx_chf_coef_0 = 0x0001, + .rx_chf_coeffs_26mhz.rx_chf_coef_1 = 0x0003, + .rx_chf_coeffs_26mhz.rx_chf_coef_2 = 0x0003, + .rx_chf_coeffs_26mhz.rx_chf_coef_3 = 0xFFFF, + .rx_chf_coeffs_26mhz.rx_chf_coef_4 = 0xFFF7, + .rx_chf_coeffs_26mhz.rx_chf_coef_5 = 0xFFEE, + .rx_chf_coeffs_26mhz.rx_chf_coef_6 = 0xFFEC, + .rx_chf_coeffs_26mhz.rx_chf_coef_7 = 0xFFF7, + .rx_chf_coeffs_26mhz.rx_chf_coef_8 = 0x0014, + .rx_chf_coeffs_26mhz.rx_chf_coef_9 = 0x003C, + .rx_chf_coeffs_26mhz.rx_chf_coef_10 = 0x0064, + .rx_chf_coeffs_26mhz.rx_chf_coef_11 = 0x007D, + + /* 32MHz Channel Filter */ + .rx_chf_coeffs_32mhz.rx_chf_coef_0 = 0x0001, + .rx_chf_coeffs_32mhz.rx_chf_coef_1 = 0x0003, + .rx_chf_coeffs_32mhz.rx_chf_coef_2 = 0x0005, + .rx_chf_coeffs_32mhz.rx_chf_coef_3 = 0x0003, + .rx_chf_coeffs_32mhz.rx_chf_coef_4 = 0xFFFC, + .rx_chf_coeffs_32mhz.rx_chf_coef_5 = 0xFFF0, + .rx_chf_coeffs_32mhz.rx_chf_coef_6 = 0xFFE8, + .rx_chf_coeffs_32mhz.rx_chf_coef_7 = 0xFFEF, + .rx_chf_coeffs_32mhz.rx_chf_coef_8 = 0x000B, + .rx_chf_coeffs_32mhz.rx_chf_coef_9 = 0x0038, + .rx_chf_coeffs_32mhz.rx_chf_coef_10 = 0x0068, + .rx_chf_coeffs_32mhz.rx_chf_coef_11 = 0x0086, + + .rx_rccal_ctrl_0 = XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_DIS(1) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_SMP_DLY(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_COMP_INV(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_DIS(1) , + .rx_rccal_ctrl_1 = XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_DIS(1), + + .tx_fsk_scale_26mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1627) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x09d9), + .tx_fsk_scale_32mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1800) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x0800), +}; + diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_gfsk_bt_0p5_h_0p32_config.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_gfsk_bt_0p5_h_0p32_config.c new file mode 100644 index 0000000000..55366cf749 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_gfsk_bt_0p5_h_0p32_config.c @@ -0,0 +1,341 @@ +/* + * 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 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_xcvr.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ +/* MODE only configuration */ +const xcvr_mode_config_t gfsk_bt_0p5_h_0p32_mode_config = +{ + .radio_mode = GFSK_BT_0p5_h_0p32, + .scgc5_clock_ena_bits = SIM_SCGC5_PHYDIG_MASK | SIM_SCGC5_GEN_FSK_MASK, + + /* XCVR_MISC configs */ + .xcvr_ctrl.mask = XCVR_CTRL_XCVR_CTRL_PROTOCOL_MASK | + XCVR_CTRL_XCVR_CTRL_TGT_PWR_SRC_MASK | + XCVR_CTRL_XCVR_CTRL_DEMOD_SEL_MASK, + .xcvr_ctrl.init = XCVR_CTRL_XCVR_CTRL_PROTOCOL(8) | + XCVR_CTRL_XCVR_CTRL_TGT_PWR_SRC(7) | + XCVR_CTRL_XCVR_CTRL_DEMOD_SEL(1), + + /* XCVR_PHY configs */ + .phy_pre_ref0_init = 0xBBDE739B, + .phy_pre_ref1_init = 0xDEFBDEF7, + .phy_pre_ref2_init = 0x0000E739, + + .phy_cfg1_init = XCVR_PHY_CFG1_AA_PLAYBACK(1) | + XCVR_PHY_CFG1_AA_OUTPUT_SEL(1) | + XCVR_PHY_CFG1_FSK_BIT_INVERT(0) | + XCVR_PHY_CFG1_BSM_EN_BLE(0) | + XCVR_PHY_CFG1_DEMOD_CLK_MODE(0) | + XCVR_PHY_CFG1_CTS_THRESH(0xF0) | + XCVR_PHY_CFG1_FSK_FTS_TIMEOUT(2), + + .phy_el_cfg_init = XCVR_PHY_EL_CFG_EL_ENABLE(1) +#if !RADIO_IS_GEN_2P1 + | XCVR_PHY_EL_CFG_EL_ZB_ENABLE(0) +#endif /* !RADIO_IS_GEN_2P1 */ + , + + /* XCVR_RX_DIG configs */ + .rx_dig_ctrl_init_26mhz = XCVR_RX_DIG_RX_DIG_CTRL_RX_FSK_ZB_SEL(0) | /* Depends on protocol */ + XCVR_RX_DIG_RX_DIG_CTRL_RX_DC_RESID_EN(1) | /* Depends on protocol */ + XCVR_RX_DIG_RX_DIG_CTRL_RX_SRC_RATE(0), + + .rx_dig_ctrl_init_32mhz = XCVR_RX_DIG_RX_DIG_CTRL_RX_FSK_ZB_SEL(0) | /* Depends on protocol */ + XCVR_RX_DIG_RX_DIG_CTRL_RX_DC_RESID_EN(1), /* Depends on protocol */ + + .agc_ctrl_0_init = XCVR_RX_DIG_AGC_CTRL_0_AGC_DOWN_RSSI_THRESH(0xFF), + + /* XCVR_TSM configs */ +#if (DATA_PADDING_EN) + .tsm_timing_35_init = B0(TX_DIG_EN_ASSERT+TX_DIG_EN_TX_HI_ADJ), +#else + .tsm_timing_35_init = B0(TX_DIG_EN_ASSERT), +#endif /* (DATA_PADDING_EN) */ + + /* XCVR_TX_DIG configs */ + .tx_gfsk_ctrl = XCVR_TX_DIG_GFSK_CTRL_GFSK_MULTIPLY_TABLE_MANUAL(0x4000) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_MI(0) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_MLD(0) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_FLD(0) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_MOD_INDEX_SCALING(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_OVRD_EN(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_0_OVRD(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_1_OVRD(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_2_OVRD(0), + .tx_gfsk_coeff1_26mhz = 0, + .tx_gfsk_coeff2_26mhz = 0, + .tx_gfsk_coeff1_32mhz = 0, + .tx_gfsk_coeff2_32mhz = 0, +}; + +/* MODE & DATA RATE combined configuration */ +const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p5_h_0p32_1mbps_config = +{ + .radio_mode = GFSK_BT_0p5_h_0p32, + .data_rate = DR_1MBPS, + + .ana_sy_ctrl2.mask = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM_MASK, + .ana_sy_ctrl2.init = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM(0), /* VCO KVM */ + .ana_rx_bba.mask = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL_MASK | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL_MASK, + .ana_rx_bba.init = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL(5) | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL(5), /* BBA_BW_SEL and BBA2_BW_SEL */ + .ana_rx_tza.mask = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL_MASK, + .ana_rx_tza.init = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL(5), /* TZA_BW_SEL */ + + .phy_cfg2_init = XCVR_PHY_CFG2_PHY_FIFO_PRECHG(8) | + XCVR_PHY_CFG2_X2_DEMOD_GAIN(0x4) , + + /* AGC configs */ + .agc_ctrl_2_init_26mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(12) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + .agc_ctrl_2_init_32mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(14) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + + /* All constant values are represented as 16 bits, register writes will remove unused bits */ + .rx_chf_coeffs_26mhz.rx_chf_coef_0 = 0xFFFB, + .rx_chf_coeffs_26mhz.rx_chf_coef_1 = 0xFFF5, + .rx_chf_coeffs_26mhz.rx_chf_coef_2 = 0xFFF0, + .rx_chf_coeffs_26mhz.rx_chf_coef_3 = 0xFFEC, + .rx_chf_coeffs_26mhz.rx_chf_coef_4 = 0xFFEC, + .rx_chf_coeffs_26mhz.rx_chf_coef_5 = 0xFFF3, + .rx_chf_coeffs_26mhz.rx_chf_coef_6 = 0x0001, + .rx_chf_coeffs_26mhz.rx_chf_coef_7 = 0x0016, + .rx_chf_coeffs_26mhz.rx_chf_coef_8 = 0x002F, + .rx_chf_coeffs_26mhz.rx_chf_coef_9 = 0x0049, + .rx_chf_coeffs_26mhz.rx_chf_coef_10 = 0x005D, + .rx_chf_coeffs_26mhz.rx_chf_coef_11 = 0x0069, + + /* 32MHz Channel Filter */ + .rx_chf_coeffs_32mhz.rx_chf_coef_0 = 0xFFF9, + .rx_chf_coeffs_32mhz.rx_chf_coef_1 = 0xFFF4, + .rx_chf_coeffs_32mhz.rx_chf_coef_2 = 0xFFED, + .rx_chf_coeffs_32mhz.rx_chf_coef_3 = 0xFFE7, + .rx_chf_coeffs_32mhz.rx_chf_coef_4 = 0xFFE7, + .rx_chf_coeffs_32mhz.rx_chf_coef_5 = 0xFFEE, + .rx_chf_coeffs_32mhz.rx_chf_coef_6 = 0xFFFD, + .rx_chf_coeffs_32mhz.rx_chf_coef_7 = 0x0015, + .rx_chf_coeffs_32mhz.rx_chf_coef_8 = 0x0031, + .rx_chf_coeffs_32mhz.rx_chf_coef_9 = 0x004E, + .rx_chf_coeffs_32mhz.rx_chf_coef_10 = 0x0066, + .rx_chf_coeffs_32mhz.rx_chf_coef_11 = 0x0073, + + .rx_rccal_ctrl_0 = XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_SMP_DLY(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_COMP_INV(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_DIS(0) , + .rx_rccal_ctrl_1 = XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_DIS(0) , + + .tx_fsk_scale_26mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1627) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x09d9), + .tx_fsk_scale_32mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1800) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x0800), +}; + +const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p5_h_0p32_500kbps_config = +{ + .radio_mode = GFSK_BT_0p5_h_0p32, + .data_rate = DR_500KBPS, + + .ana_sy_ctrl2.mask = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM_MASK, + .ana_sy_ctrl2.init = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM(0), /* VCO KVM */ + .ana_rx_bba.mask = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL_MASK | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL_MASK, + .ana_rx_bba.init = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL(5) | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL(5), /* BBA_BW_SEL and BBA2_BW_SEL */ + .ana_rx_tza.mask = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL_MASK, + .ana_rx_tza.init = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL(5), /* TZA_BW_SEL */ + + .phy_cfg2_init = XCVR_PHY_CFG2_PHY_FIFO_PRECHG(8) | + XCVR_PHY_CFG2_X2_DEMOD_GAIN(0x4) , + + /* AGC configs */ + .agc_ctrl_2_init_26mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(15) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + .agc_ctrl_2_init_32mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(18) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + + /* All constant values are represented as 16 bits, register writes will remove unused bits */ + .rx_chf_coeffs_26mhz.rx_chf_coef_0 = 0x0001, + .rx_chf_coeffs_26mhz.rx_chf_coef_1 = 0x0000, + .rx_chf_coeffs_26mhz.rx_chf_coef_2 = 0xFFFA, + .rx_chf_coeffs_26mhz.rx_chf_coef_3 = 0xFFF3, + .rx_chf_coeffs_26mhz.rx_chf_coef_4 = 0xFFEE, + .rx_chf_coeffs_26mhz.rx_chf_coef_5 = 0xFFEF, + .rx_chf_coeffs_26mhz.rx_chf_coef_6 = 0xFFF8, + .rx_chf_coeffs_26mhz.rx_chf_coef_7 = 0x000A, + .rx_chf_coeffs_26mhz.rx_chf_coef_8 = 0x0025, + .rx_chf_coeffs_26mhz.rx_chf_coef_9 = 0x0043, + .rx_chf_coeffs_26mhz.rx_chf_coef_10 = 0x005D, + .rx_chf_coeffs_26mhz.rx_chf_coef_11 = 0x006B, + + /* 32MHz Channel Filter */ + .rx_chf_coeffs_32mhz.rx_chf_coef_0 = 0x0004, + .rx_chf_coeffs_32mhz.rx_chf_coef_1 = 0x0003, + .rx_chf_coeffs_32mhz.rx_chf_coef_2 = 0xFFFE, + .rx_chf_coeffs_32mhz.rx_chf_coef_3 = 0xFFF6, + .rx_chf_coeffs_32mhz.rx_chf_coef_4 = 0xFFED, + .rx_chf_coeffs_32mhz.rx_chf_coef_5 = 0xFFE9, + .rx_chf_coeffs_32mhz.rx_chf_coef_6 = 0xFFEF, + .rx_chf_coeffs_32mhz.rx_chf_coef_7 = 0x0001, + .rx_chf_coeffs_32mhz.rx_chf_coef_8 = 0x0020, + .rx_chf_coeffs_32mhz.rx_chf_coef_9 = 0x0044, + .rx_chf_coeffs_32mhz.rx_chf_coef_10 = 0x0064, + .rx_chf_coeffs_32mhz.rx_chf_coef_11 = 0x0077, + + .rx_rccal_ctrl_0 = XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_DIS(1) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_SMP_DLY(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_COMP_INV(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_DIS(1) , + .rx_rccal_ctrl_1 = XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_DIS(1) , + + .tx_fsk_scale_26mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1627) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x09d9), + .tx_fsk_scale_32mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1800) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x0800), +}; + +const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p5_h_0p32_250kbps_config = +{ + .radio_mode = GFSK_BT_0p5_h_0p32, + .data_rate = DR_250KBPS, + + .ana_sy_ctrl2.mask = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM_MASK, + .ana_sy_ctrl2.init = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM(0), /* VCO KVM */ + .ana_rx_bba.mask = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL_MASK | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL_MASK, + .ana_rx_bba.init = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL(5) | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL(5), /* BBA_BW_SEL and BBA2_BW_SEL */ + .ana_rx_tza.mask = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL_MASK, + .ana_rx_tza.init = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL(5), /* TZA_BW_SEL */ + + .phy_cfg2_init = XCVR_PHY_CFG2_PHY_FIFO_PRECHG(8) | + XCVR_PHY_CFG2_X2_DEMOD_GAIN(0x4) , + + /* AGC configs */ + .agc_ctrl_2_init_26mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(18) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + .agc_ctrl_2_init_32mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(22) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(2) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + + /* All constant values are represented as 16 bits, register writes will remove unused bits */ + .rx_chf_coeffs_26mhz.rx_chf_coef_0 = 0x0002, + .rx_chf_coeffs_26mhz.rx_chf_coef_1 = 0xFFFD, + .rx_chf_coeffs_26mhz.rx_chf_coef_2 = 0xFFF8, + .rx_chf_coeffs_26mhz.rx_chf_coef_3 = 0xFFF1, + .rx_chf_coeffs_26mhz.rx_chf_coef_4 = 0xFFEC, + .rx_chf_coeffs_26mhz.rx_chf_coef_5 = 0xFFED, + .rx_chf_coeffs_26mhz.rx_chf_coef_6 = 0xFFF7, + .rx_chf_coeffs_26mhz.rx_chf_coef_7 = 0x000B, + .rx_chf_coeffs_26mhz.rx_chf_coef_8 = 0x0027, + .rx_chf_coeffs_26mhz.rx_chf_coef_9 = 0x0046, + .rx_chf_coeffs_26mhz.rx_chf_coef_10 = 0x0060, + .rx_chf_coeffs_26mhz.rx_chf_coef_11 = 0x0070, + + /* 32MHz Channel Filter */ + .rx_chf_coeffs_32mhz.rx_chf_coef_0 = 0x0001, + .rx_chf_coeffs_32mhz.rx_chf_coef_1 = 0x0003, + .rx_chf_coeffs_32mhz.rx_chf_coef_2 = 0x0005, + .rx_chf_coeffs_32mhz.rx_chf_coef_3 = 0x0003, + .rx_chf_coeffs_32mhz.rx_chf_coef_4 = 0xFFFC, + .rx_chf_coeffs_32mhz.rx_chf_coef_5 = 0xFFF0, + .rx_chf_coeffs_32mhz.rx_chf_coef_6 = 0xFFE8, + .rx_chf_coeffs_32mhz.rx_chf_coef_7 = 0xFFEF, + .rx_chf_coeffs_32mhz.rx_chf_coef_8 = 0x000B, + .rx_chf_coeffs_32mhz.rx_chf_coef_9 = 0x0038, + .rx_chf_coeffs_32mhz.rx_chf_coef_10 = 0x0068, + .rx_chf_coeffs_32mhz.rx_chf_coef_11 = 0x0086, + + .rx_rccal_ctrl_0 = XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_DIS(1) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_SMP_DLY(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_COMP_INV(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_DIS(1) , + .rx_rccal_ctrl_1 = XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_DIS(1) , + + .tx_fsk_scale_26mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1627) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x09d9), + .tx_fsk_scale_32mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1800) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x0800), +}; + diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_gfsk_bt_0p5_h_0p5_config.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_gfsk_bt_0p5_h_0p5_config.c new file mode 100644 index 0000000000..d57d0696eb --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_gfsk_bt_0p5_h_0p5_config.c @@ -0,0 +1,356 @@ +/* + * 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 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_xcvr.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ +/* MODE only configuration */ +const xcvr_mode_config_t gfsk_bt_0p5_h_0p5_mode_config = +{ + .radio_mode = GFSK_BT_0p5_h_0p5, + .scgc5_clock_ena_bits = SIM_SCGC5_PHYDIG_MASK | SIM_SCGC5_GEN_FSK_MASK, + + /* XCVR_MISC configs */ + .xcvr_ctrl.mask = XCVR_CTRL_XCVR_CTRL_PROTOCOL_MASK | + XCVR_CTRL_XCVR_CTRL_TGT_PWR_SRC_MASK | + XCVR_CTRL_XCVR_CTRL_DEMOD_SEL_MASK, + .xcvr_ctrl.init = XCVR_CTRL_XCVR_CTRL_PROTOCOL(8) | + XCVR_CTRL_XCVR_CTRL_TGT_PWR_SRC(7) | + XCVR_CTRL_XCVR_CTRL_DEMOD_SEL(1), + + .phy_pre_ref0_init = RW0PS(0, 0x19) | + RW0PS(1, 0x19U) | + RW0PS(2, 0x1AU) | + RW0PS(3, 0x1BU) | + RW0PS(4, 0x1CU) | + RW0PS(5, 0x1CU) | + RW0PS(6, 0x1DU & 0x3U), /* Phase info #6 overlaps two initialization words */ + .phy_pre_ref1_init = (0x1D) >> 2 | /* Phase info #6 overlaps two initialization words - manually compute the shift*/ + RW1PS(7, 0x1EU) | + RW1PS(8, 0x1EU) | + RW1PS(9, 0x1EU) | + RW1PS(10, 0x1DU) | + RW1PS(11, 0x1CU) | + RW1PS(12, 0x1CU & 0xFU), /* Phase info #12 overlaps two initialization words */ + .phy_pre_ref2_init = (0x1C) >> 4 | /* Phase info #12 overlaps two initialization words - manually compute the shift*/ + RW2PS(13, 0x1BU) | + RW2PS(14, 0x1AU) | + RW2PS(15, 0x19U), + + .phy_cfg1_init = XCVR_PHY_CFG1_AA_PLAYBACK(1) | + XCVR_PHY_CFG1_AA_OUTPUT_SEL(1) | + XCVR_PHY_CFG1_FSK_BIT_INVERT(0) | + XCVR_PHY_CFG1_BSM_EN_BLE(0) | + XCVR_PHY_CFG1_DEMOD_CLK_MODE(0) | + XCVR_PHY_CFG1_CTS_THRESH(205) | + XCVR_PHY_CFG1_FSK_FTS_TIMEOUT(2), + + .phy_el_cfg_init = XCVR_PHY_EL_CFG_EL_ENABLE(1) +#if !RADIO_IS_GEN_2P1 + | XCVR_PHY_EL_CFG_EL_ZB_ENABLE(0) +#endif /* !RADIO_IS_GEN_2P1 */ + , + /* XCVR_RX_DIG configs */ + .rx_dig_ctrl_init_26mhz = XCVR_RX_DIG_RX_DIG_CTRL_RX_FSK_ZB_SEL(0) | /* Depends on protocol */ + XCVR_RX_DIG_RX_DIG_CTRL_RX_DC_RESID_EN(1) | /* Depends on protocol */ + XCVR_RX_DIG_RX_DIG_CTRL_RX_SRC_RATE(0), + + .rx_dig_ctrl_init_32mhz = XCVR_RX_DIG_RX_DIG_CTRL_RX_FSK_ZB_SEL(0) | /* Depends on protocol */ + XCVR_RX_DIG_RX_DIG_CTRL_RX_DC_RESID_EN(1), /* Depends on protocol */ + + .agc_ctrl_0_init = XCVR_RX_DIG_AGC_CTRL_0_AGC_DOWN_RSSI_THRESH(0xFF), + + /* XCVR_TSM configs */ +#if (DATA_PADDING_EN) + .tsm_timing_35_init = B0(TX_DIG_EN_ASSERT+TX_DIG_EN_TX_HI_ADJ), +#else + .tsm_timing_35_init = B0(TX_DIG_EN_ASSERT), +#endif /* (DATA_PADDING_EN) */ + + /* XCVR_TX_DIG configs */ + .tx_gfsk_ctrl = XCVR_TX_DIG_GFSK_CTRL_GFSK_MULTIPLY_TABLE_MANUAL(0x4000) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_MI(1) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_MLD(0) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_FLD(0) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_MOD_INDEX_SCALING(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_OVRD_EN(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_0_OVRD(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_1_OVRD(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_2_OVRD(0), + .tx_gfsk_coeff1_26mhz = 0, + .tx_gfsk_coeff2_26mhz = 0, + .tx_gfsk_coeff1_32mhz = 0, + .tx_gfsk_coeff2_32mhz = 0, +}; + +/* MODE & DATA RATE combined configuration */ + +const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p5_h_0p5_1mbps_config = +{ + .radio_mode = GFSK_BT_0p5_h_0p5, + .data_rate = DR_1MBPS, + + .ana_sy_ctrl2.mask = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM_MASK, + .ana_sy_ctrl2.init = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM(0), /* VCO KVM */ + .ana_rx_bba.mask = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL_MASK | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL_MASK, + .ana_rx_bba.init = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL(4) | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL(4), /* BBA_BW_SEL and BBA2_BW_SEL */ + .ana_rx_tza.mask = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL_MASK, + .ana_rx_tza.init = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL(4), /*TZA_BW_SEL */ + + .phy_cfg2_init = XCVR_PHY_CFG2_PHY_FIFO_PRECHG(8) | + XCVR_PHY_CFG2_X2_DEMOD_GAIN(0xA) , + + /* AGC configs */ + .agc_ctrl_2_init_26mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(10) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + .agc_ctrl_2_init_32mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(12) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + + /* BLE 26MHz Channel Filter */ + /* All constant values are represented as 16 bits, register writes will remove unused bits */ + .rx_chf_coeffs_26mhz.rx_chf_coef_0 = 0xFFFA, + .rx_chf_coeffs_26mhz.rx_chf_coef_1 = 0xFFF6, + .rx_chf_coeffs_26mhz.rx_chf_coef_2 = 0xFFF1, + .rx_chf_coeffs_26mhz.rx_chf_coef_3 = 0xFFEE, + .rx_chf_coeffs_26mhz.rx_chf_coef_4 = 0xFFEF, + .rx_chf_coeffs_26mhz.rx_chf_coef_5 = 0xFFF6, + .rx_chf_coeffs_26mhz.rx_chf_coef_6 = 0x0004, + .rx_chf_coeffs_26mhz.rx_chf_coef_7 = 0x0017, + .rx_chf_coeffs_26mhz.rx_chf_coef_8 = 0x002F, + .rx_chf_coeffs_26mhz.rx_chf_coef_9 = 0x0046, + .rx_chf_coeffs_26mhz.rx_chf_coef_10 = 0x0059, + .rx_chf_coeffs_26mhz.rx_chf_coef_11 = 0x0063, + + /* BLE 32MHz Channel Filter */ + .rx_chf_coeffs_32mhz.rx_chf_coef_0 = 0xFFFA, + .rx_chf_coeffs_32mhz.rx_chf_coef_1 = 0xFFF5, + .rx_chf_coeffs_32mhz.rx_chf_coef_2 = 0xFFEF, + .rx_chf_coeffs_32mhz.rx_chf_coef_3 = 0xFFEB, + .rx_chf_coeffs_32mhz.rx_chf_coef_4 = 0xFFEB, + .rx_chf_coeffs_32mhz.rx_chf_coef_5 = 0xFFF2, + .rx_chf_coeffs_32mhz.rx_chf_coef_6 = 0x0000, + .rx_chf_coeffs_32mhz.rx_chf_coef_7 = 0x0015, + .rx_chf_coeffs_32mhz.rx_chf_coef_8 = 0x0030, + .rx_chf_coeffs_32mhz.rx_chf_coef_9 = 0x004A, + .rx_chf_coeffs_32mhz.rx_chf_coef_10 = 0x005F, + .rx_chf_coeffs_32mhz.rx_chf_coef_11 = 0x006B, + + .rx_rccal_ctrl_0 = XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_SMP_DLY(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_COMP_INV(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_DIS(0) , + .rx_rccal_ctrl_1 = XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_DIS(0) , + + .tx_fsk_scale_26mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1627) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x09d9), + .tx_fsk_scale_32mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1800) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x0800), +}; + +const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p5_h_0p5_500kbps_config = +{ + .radio_mode = GFSK_BT_0p5_h_0p5, + .data_rate = DR_500KBPS, + + .ana_sy_ctrl2.mask = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM_MASK, + .ana_sy_ctrl2.init = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM(0), /* VCO KVM */ + .ana_rx_bba.mask = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL_MASK | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL_MASK, + .ana_rx_bba.init = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL(5) | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL(5), /* BBA_BW_SEL and BBA2_BW_SEL */ + .ana_rx_tza.mask = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL_MASK, + .ana_rx_tza.init = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL(5), /* TZA_BW_SEL */ + + .phy_cfg2_init = XCVR_PHY_CFG2_PHY_FIFO_PRECHG(8) | + XCVR_PHY_CFG2_X2_DEMOD_GAIN(0x8) , + + /* AGC configs */ + .agc_ctrl_2_init_26mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(15) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + .agc_ctrl_2_init_32mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(18) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + + /* All constant values are represented as 16 bits, register writes will remove unused bits */ + .rx_chf_coeffs_26mhz.rx_chf_coef_0 = 0x0004, + .rx_chf_coeffs_26mhz.rx_chf_coef_1 = 0x0003, + .rx_chf_coeffs_26mhz.rx_chf_coef_2 = 0xFFFE, + .rx_chf_coeffs_26mhz.rx_chf_coef_3 = 0xFFF5, + .rx_chf_coeffs_26mhz.rx_chf_coef_4 = 0xFFEC, + .rx_chf_coeffs_26mhz.rx_chf_coef_5 = 0xFFE8, + .rx_chf_coeffs_26mhz.rx_chf_coef_6 = 0xFFEE, + .rx_chf_coeffs_26mhz.rx_chf_coef_7 = 0x0001, + .rx_chf_coeffs_26mhz.rx_chf_coef_8 = 0x0020, + .rx_chf_coeffs_26mhz.rx_chf_coef_9 = 0x0045, + .rx_chf_coeffs_26mhz.rx_chf_coef_10 = 0x0065, + .rx_chf_coeffs_26mhz.rx_chf_coef_11 = 0x0079, + + /* 32MHz */ + .rx_chf_coeffs_32mhz.rx_chf_coef_0 = 0x0005, + .rx_chf_coeffs_32mhz.rx_chf_coef_1 = 0x0006, + .rx_chf_coeffs_32mhz.rx_chf_coef_2 = 0x0003, + .rx_chf_coeffs_32mhz.rx_chf_coef_3 = 0xFFFA, + .rx_chf_coeffs_32mhz.rx_chf_coef_4 = 0xFFEF, + .rx_chf_coeffs_32mhz.rx_chf_coef_5 = 0xFFE6, + .rx_chf_coeffs_32mhz.rx_chf_coef_6 = 0xFFE7, + .rx_chf_coeffs_32mhz.rx_chf_coef_7 = 0xFFF8, + .rx_chf_coeffs_32mhz.rx_chf_coef_8 = 0x0019, + .rx_chf_coeffs_32mhz.rx_chf_coef_9 = 0x0042, + .rx_chf_coeffs_32mhz.rx_chf_coef_10 = 0x0069, + .rx_chf_coeffs_32mhz.rx_chf_coef_11 = 0x0080, + + .rx_rccal_ctrl_0 = XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_DIS(1) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_SMP_DLY(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_COMP_INV(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_DIS(1) , + .rx_rccal_ctrl_1 = XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_DIS(1) , + + .tx_fsk_scale_26mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1627) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x09d9), + .tx_fsk_scale_32mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1800) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x0800), +}; + +const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p5_h_0p5_250kbps_config = +{ + .radio_mode = GFSK_BT_0p5_h_0p5, + .data_rate = DR_250KBPS, + + .ana_sy_ctrl2.mask = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM_MASK, + .ana_sy_ctrl2.init = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM(0), /* VCO KVM */ + .ana_rx_bba.mask = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL_MASK | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL_MASK, + .ana_rx_bba.init = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL(5) | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL(5), /* BBA_BW_SEL and BBA2_BW_SEL */ + .ana_rx_tza.mask = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL_MASK, + .ana_rx_tza.init = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL(5), /* TZA_BW_SEL */ + + .phy_cfg2_init = XCVR_PHY_CFG2_PHY_FIFO_PRECHG(8) | + XCVR_PHY_CFG2_X2_DEMOD_GAIN(0x6) , + + /* AGC configs */ + .agc_ctrl_2_init_26mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(18) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + .agc_ctrl_2_init_32mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(22) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(2) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + + /* All constant values are represented as 16 bits, register writes will remove unused bits */ + .rx_chf_coeffs_26mhz.rx_chf_coef_0 = 0x0002, + .rx_chf_coeffs_26mhz.rx_chf_coef_1 = 0xFFFD, + .rx_chf_coeffs_26mhz.rx_chf_coef_2 = 0xFFF8, + .rx_chf_coeffs_26mhz.rx_chf_coef_3 = 0xFFF1, + .rx_chf_coeffs_26mhz.rx_chf_coef_4 = 0xFFEC, + .rx_chf_coeffs_26mhz.rx_chf_coef_5 = 0xFFED, + .rx_chf_coeffs_26mhz.rx_chf_coef_6 = 0xFFF7, + .rx_chf_coeffs_26mhz.rx_chf_coef_7 = 0x000B, + .rx_chf_coeffs_26mhz.rx_chf_coef_8 = 0x0027, + .rx_chf_coeffs_26mhz.rx_chf_coef_9 = 0x0046, + .rx_chf_coeffs_26mhz.rx_chf_coef_10 = 0x0060, + .rx_chf_coeffs_26mhz.rx_chf_coef_11 = 0x0070, + + /* 32MHz Channel Filter */ + .rx_chf_coeffs_32mhz.rx_chf_coef_0 = 0x0002, + .rx_chf_coeffs_32mhz.rx_chf_coef_1 = 0xFFFD, + .rx_chf_coeffs_32mhz.rx_chf_coef_2 = 0xFFF8, + .rx_chf_coeffs_32mhz.rx_chf_coef_3 = 0xFFF1, + .rx_chf_coeffs_32mhz.rx_chf_coef_4 = 0xFFEC, + .rx_chf_coeffs_32mhz.rx_chf_coef_5 = 0xFFED, + .rx_chf_coeffs_32mhz.rx_chf_coef_6 = 0xFFF6, + .rx_chf_coeffs_32mhz.rx_chf_coef_7 = 0x000A, + .rx_chf_coeffs_32mhz.rx_chf_coef_8 = 0x0027, + .rx_chf_coeffs_32mhz.rx_chf_coef_9 = 0x0046, + .rx_chf_coeffs_32mhz.rx_chf_coef_10 = 0x0061, + .rx_chf_coeffs_32mhz.rx_chf_coef_11 = 0x0071, + + .rx_rccal_ctrl_0 = XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_DIS(1) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_SMP_DLY(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_COMP_INV(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_DIS(1) , + .rx_rccal_ctrl_1 = XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_DIS(1) , + + .tx_fsk_scale_26mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1627) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x09d9), + .tx_fsk_scale_32mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1800) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x0800), +}; + diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_gfsk_bt_0p5_h_0p7_config.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_gfsk_bt_0p5_h_0p7_config.c new file mode 100644 index 0000000000..cc680b6101 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_gfsk_bt_0p5_h_0p7_config.c @@ -0,0 +1,341 @@ +/* + * 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 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_xcvr.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ +/* MODE only configuration */ +const xcvr_mode_config_t gfsk_bt_0p5_h_0p7_mode_config = +{ + .radio_mode = GFSK_BT_0p5_h_0p7, + .scgc5_clock_ena_bits = SIM_SCGC5_PHYDIG_MASK | SIM_SCGC5_GEN_FSK_MASK, + + /* XCVR_MISC configs */ + .xcvr_ctrl.mask = XCVR_CTRL_XCVR_CTRL_PROTOCOL_MASK | + XCVR_CTRL_XCVR_CTRL_TGT_PWR_SRC_MASK | + XCVR_CTRL_XCVR_CTRL_DEMOD_SEL_MASK, + .xcvr_ctrl.init = XCVR_CTRL_XCVR_CTRL_PROTOCOL(8) | + XCVR_CTRL_XCVR_CTRL_TGT_PWR_SRC(7) | + XCVR_CTRL_XCVR_CTRL_DEMOD_SEL(1), + + /* XCVR_PHY configs */ + .phy_pre_ref0_init = 0x37ACE2F7, + .phy_pre_ref1_init = 0xADF3BDEF, + .phy_pre_ref2_init = 0x0000BE33, + + .phy_cfg1_init = XCVR_PHY_CFG1_AA_PLAYBACK(1) | + XCVR_PHY_CFG1_AA_OUTPUT_SEL(1) | + XCVR_PHY_CFG1_FSK_BIT_INVERT(0) | + XCVR_PHY_CFG1_BSM_EN_BLE(0) | + XCVR_PHY_CFG1_DEMOD_CLK_MODE(0) | + XCVR_PHY_CFG1_CTS_THRESH(0xCD) | + XCVR_PHY_CFG1_FSK_FTS_TIMEOUT(2), + + .phy_el_cfg_init = XCVR_PHY_EL_CFG_EL_ENABLE(1) +#if !RADIO_IS_GEN_2P1 + | XCVR_PHY_EL_CFG_EL_ZB_ENABLE(0) +#endif /* !RADIO_IS_GEN_2P1 */ + , + + /* XCVR_RX_DIG configs */ + .rx_dig_ctrl_init_26mhz = XCVR_RX_DIG_RX_DIG_CTRL_RX_FSK_ZB_SEL(0) | /* Depends on protocol */ + XCVR_RX_DIG_RX_DIG_CTRL_RX_DC_RESID_EN(1) | /* Depends on protocol */ + XCVR_RX_DIG_RX_DIG_CTRL_RX_SRC_RATE(0), + + .rx_dig_ctrl_init_32mhz = XCVR_RX_DIG_RX_DIG_CTRL_RX_FSK_ZB_SEL(0) | /* Depends on protocol */ + XCVR_RX_DIG_RX_DIG_CTRL_RX_DC_RESID_EN(1), /* Depends on protocol */ + + .agc_ctrl_0_init = XCVR_RX_DIG_AGC_CTRL_0_AGC_DOWN_RSSI_THRESH(0xFF), + + /* XCVR_TSM configs */ +#if (DATA_PADDING_EN) + .tsm_timing_35_init = B0(TX_DIG_EN_ASSERT + TX_DIG_EN_TX_HI_ADJ), +#else + .tsm_timing_35_init = B0(TX_DIG_EN_ASSERT), +#endif /* (DATA_PADDING_EN) */ + + /* XCVR_TX_DIG configs */ + .tx_gfsk_ctrl = XCVR_TX_DIG_GFSK_CTRL_GFSK_MULTIPLY_TABLE_MANUAL(0x4000) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_MI(2) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_MLD(0) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_FLD(0) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_MOD_INDEX_SCALING(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_OVRD_EN(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_0_OVRD(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_1_OVRD(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_2_OVRD(0), + .tx_gfsk_coeff1_26mhz = 0, + .tx_gfsk_coeff2_26mhz = 0, + .tx_gfsk_coeff1_32mhz = 0, + .tx_gfsk_coeff2_32mhz = 0, +}; + +/* MODE & DATA RATE combined configuration */ +const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p5_h_0p7_1mbps_config = +{ + .radio_mode = GFSK_BT_0p5_h_0p7, + .data_rate = DR_1MBPS, + + .ana_sy_ctrl2.mask = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM_MASK, + .ana_sy_ctrl2.init = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM(1), /* VCO KVM */ + .ana_rx_bba.mask = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL_MASK | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL_MASK, + .ana_rx_bba.init = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL(3) | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL(3), /* BBA_BW_SEL and BBA2_BW_SEL */ + .ana_rx_tza.mask = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL_MASK, + .ana_rx_tza.init = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL(3), /* TZA_BW_SEL */ + + .phy_cfg2_init = XCVR_PHY_CFG2_PHY_FIFO_PRECHG(8) | + XCVR_PHY_CFG2_X2_DEMOD_GAIN(0xA) , + + /* AGC configs */ + .agc_ctrl_2_init_26mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(11) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + .agc_ctrl_2_init_32mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(12) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + + /* All constant values are represented as 16 bits, register writes will remove unused bits */ + .rx_chf_coeffs_26mhz.rx_chf_coef_0 = 0x0002, + .rx_chf_coeffs_26mhz.rx_chf_coef_1 = 0x0002, + .rx_chf_coeffs_26mhz.rx_chf_coef_2 = 0x0000, + .rx_chf_coeffs_26mhz.rx_chf_coef_3 = 0xFFF9, + .rx_chf_coeffs_26mhz.rx_chf_coef_4 = 0xFFF0, + .rx_chf_coeffs_26mhz.rx_chf_coef_5 = 0xFFEA, + .rx_chf_coeffs_26mhz.rx_chf_coef_6 = 0xFFEC, + .rx_chf_coeffs_26mhz.rx_chf_coef_7 = 0xFFFC, + .rx_chf_coeffs_26mhz.rx_chf_coef_8 = 0x001B, + .rx_chf_coeffs_26mhz.rx_chf_coef_9 = 0x0042, + .rx_chf_coeffs_26mhz.rx_chf_coef_10 = 0x0066, + .rx_chf_coeffs_26mhz.rx_chf_coef_11 = 0x007C, + + /* 32MHz Channel Filter */ + .rx_chf_coeffs_32mhz.rx_chf_coef_0 = 0x0002, + .rx_chf_coeffs_32mhz.rx_chf_coef_1 = 0x0003, + .rx_chf_coeffs_32mhz.rx_chf_coef_2 = 0x0002, + .rx_chf_coeffs_32mhz.rx_chf_coef_3 = 0xFFFC, + .rx_chf_coeffs_32mhz.rx_chf_coef_4 = 0xFFF2, + .rx_chf_coeffs_32mhz.rx_chf_coef_5 = 0xFFE9, + .rx_chf_coeffs_32mhz.rx_chf_coef_6 = 0xFFE9, + .rx_chf_coeffs_32mhz.rx_chf_coef_7 = 0xFFF7, + .rx_chf_coeffs_32mhz.rx_chf_coef_8 = 0x0016, + .rx_chf_coeffs_32mhz.rx_chf_coef_9 = 0x0040, + .rx_chf_coeffs_32mhz.rx_chf_coef_10 = 0x0069, + .rx_chf_coeffs_32mhz.rx_chf_coef_11 = 0x0082, + + .rx_rccal_ctrl_0 = XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_SMP_DLY(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_COMP_INV(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_DIS(0) , + .rx_rccal_ctrl_1 = XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_DIS(0) , + + .tx_fsk_scale_26mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1627) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x09d9), + .tx_fsk_scale_32mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1800) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x0800), +}; + +const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p5_h_0p7_500kbps_config = +{ + .radio_mode = GFSK_BT_0p5_h_0p7, + .data_rate = DR_500KBPS, + + .ana_sy_ctrl2.mask = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM_MASK, + .ana_sy_ctrl2.init = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM(0), /* VCO KVM */ + .ana_rx_bba.mask = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL_MASK | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL_MASK, + .ana_rx_bba.init = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL(5) | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL(5), /* BBA_BW_SEL and BBA2_BW_SEL */ + .ana_rx_tza.mask = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL_MASK, + .ana_rx_tza.init = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL(5), /* TZA_BW_SEL */ + + .phy_cfg2_init = XCVR_PHY_CFG2_PHY_FIFO_PRECHG(8) | + XCVR_PHY_CFG2_X2_DEMOD_GAIN(0x8) , + + /* AGC configs */ + .agc_ctrl_2_init_26mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(15) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + .agc_ctrl_2_init_32mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(18) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + + /* All constant values are represented as 16 bits, register writes will remove unused bits */ + .rx_chf_coeffs_26mhz.rx_chf_coef_0 = 0x0002, + .rx_chf_coeffs_26mhz.rx_chf_coef_1 = 0x0004, + .rx_chf_coeffs_26mhz.rx_chf_coef_2 = 0x0005, + .rx_chf_coeffs_26mhz.rx_chf_coef_3 = 0x0001, + .rx_chf_coeffs_26mhz.rx_chf_coef_4 = 0xFFF6, + .rx_chf_coeffs_26mhz.rx_chf_coef_5 = 0xFFE8, + .rx_chf_coeffs_26mhz.rx_chf_coef_6 = 0xFFE2, + .rx_chf_coeffs_26mhz.rx_chf_coef_7 = 0xFFEC, + .rx_chf_coeffs_26mhz.rx_chf_coef_8 = 0x000C, + .rx_chf_coeffs_26mhz.rx_chf_coef_9 = 0x003D, + .rx_chf_coeffs_26mhz.rx_chf_coef_10 = 0x006F, + .rx_chf_coeffs_26mhz.rx_chf_coef_11 = 0x008F, + + /* 32MHz Channel Filter */ + .rx_chf_coeffs_32mhz.rx_chf_coef_0 = 0x0001, + .rx_chf_coeffs_32mhz.rx_chf_coef_1 = 0x0004, + .rx_chf_coeffs_32mhz.rx_chf_coef_2 = 0x0007, + .rx_chf_coeffs_32mhz.rx_chf_coef_3 = 0x0006, + .rx_chf_coeffs_32mhz.rx_chf_coef_4 = 0xFFFC, + .rx_chf_coeffs_32mhz.rx_chf_coef_5 = 0xFFEC, + .rx_chf_coeffs_32mhz.rx_chf_coef_6 = 0xFFDF, + .rx_chf_coeffs_32mhz.rx_chf_coef_7 = 0xFFE3, + .rx_chf_coeffs_32mhz.rx_chf_coef_8 = 0x0002, + .rx_chf_coeffs_32mhz.rx_chf_coef_9 = 0x0038, + .rx_chf_coeffs_32mhz.rx_chf_coef_10 = 0x0072, + .rx_chf_coeffs_32mhz.rx_chf_coef_11 = 0x0098, + + .rx_rccal_ctrl_0 = XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_DIS(1) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_SMP_DLY(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_COMP_INV(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_DIS(1) , + .rx_rccal_ctrl_1 = XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_DIS(1) , + + .tx_fsk_scale_26mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1627) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x09d9), + .tx_fsk_scale_32mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1800) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x0800), +}; + +const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p5_h_0p7_250kbps_config = +{ + .radio_mode = GFSK_BT_0p5_h_0p7, + .data_rate = DR_250KBPS, + + .ana_sy_ctrl2.mask = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM_MASK, + .ana_sy_ctrl2.init = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM(0), /* VCO KVM */ + .ana_rx_bba.mask = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL_MASK | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL_MASK, + .ana_rx_bba.init = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL(5) | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL(5), /* BBA_BW_SEL and BBA2_BW_SEL */ + .ana_rx_tza.mask = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL_MASK, + .ana_rx_tza.init = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL(5), /* TZA_BW_SEL */ + + .phy_cfg2_init = XCVR_PHY_CFG2_PHY_FIFO_PRECHG(8) | + XCVR_PHY_CFG2_X2_DEMOD_GAIN(0x6) , + + /* AGC configs */ + .agc_ctrl_2_init_26mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(18) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + .agc_ctrl_2_init_32mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(22) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(2) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + + /* All constant values are represented as 16 bits, register writes will remove unused bits */ + .rx_chf_coeffs_26mhz.rx_chf_coef_0 = 0x0000, + .rx_chf_coeffs_26mhz.rx_chf_coef_1 = 0x0003, + .rx_chf_coeffs_26mhz.rx_chf_coef_2 = 0x0006, + .rx_chf_coeffs_26mhz.rx_chf_coef_3 = 0x0005, + .rx_chf_coeffs_26mhz.rx_chf_coef_4 = 0xFFFE, + .rx_chf_coeffs_26mhz.rx_chf_coef_5 = 0xFFF1, + .rx_chf_coeffs_26mhz.rx_chf_coef_6 = 0xFFE6, + .rx_chf_coeffs_26mhz.rx_chf_coef_7 = 0xFFEA, + .rx_chf_coeffs_26mhz.rx_chf_coef_8 = 0x0005, + .rx_chf_coeffs_26mhz.rx_chf_coef_9 = 0x0036, + .rx_chf_coeffs_26mhz.rx_chf_coef_10 = 0x006B, + .rx_chf_coeffs_26mhz.rx_chf_coef_11 = 0x008D, + + /* 32MHz Channel Filter */ + .rx_chf_coeffs_32mhz.rx_chf_coef_0 = 0xFFFF, + .rx_chf_coeffs_32mhz.rx_chf_coef_1 = 0x0000, + .rx_chf_coeffs_32mhz.rx_chf_coef_2 = 0x0004, + .rx_chf_coeffs_32mhz.rx_chf_coef_3 = 0x0008, + .rx_chf_coeffs_32mhz.rx_chf_coef_4 = 0x0004, + .rx_chf_coeffs_32mhz.rx_chf_coef_5 = 0xFFF8, + .rx_chf_coeffs_32mhz.rx_chf_coef_6 = 0xFFE6, + .rx_chf_coeffs_32mhz.rx_chf_coef_7 = 0xFFE2, + .rx_chf_coeffs_32mhz.rx_chf_coef_8 = 0xFFFA, + .rx_chf_coeffs_32mhz.rx_chf_coef_9 = 0x002E, + .rx_chf_coeffs_32mhz.rx_chf_coef_10 = 0x006D, + .rx_chf_coeffs_32mhz.rx_chf_coef_11 = 0x0098, + + .rx_rccal_ctrl_0 = XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_DIS(1) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_SMP_DLY(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_COMP_INV(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_DIS(1) , + .rx_rccal_ctrl_1 = XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_DIS(1) , + + .tx_fsk_scale_26mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1627) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x09d9), + .tx_fsk_scale_32mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1800) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x0800), +}; + diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_gfsk_bt_0p5_h_1p0_config.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_gfsk_bt_0p5_h_1p0_config.c new file mode 100644 index 0000000000..49c6dc75c2 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_gfsk_bt_0p5_h_1p0_config.c @@ -0,0 +1,340 @@ +/* + * 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 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_xcvr.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ +/* MODE only configuration */ +const xcvr_mode_config_t gfsk_bt_0p5_h_1p0_mode_config = +{ + .radio_mode = GFSK_BT_0p5_h_1p0, + .scgc5_clock_ena_bits = SIM_SCGC5_PHYDIG_MASK | SIM_SCGC5_GEN_FSK_MASK, + + /* XCVR_MISC configs */ + .xcvr_ctrl.mask = XCVR_CTRL_XCVR_CTRL_PROTOCOL_MASK | + XCVR_CTRL_XCVR_CTRL_TGT_PWR_SRC_MASK | + XCVR_CTRL_XCVR_CTRL_DEMOD_SEL_MASK, + .xcvr_ctrl.init = XCVR_CTRL_XCVR_CTRL_PROTOCOL(8) | + XCVR_CTRL_XCVR_CTRL_TGT_PWR_SRC(7) | + XCVR_CTRL_XCVR_CTRL_DEMOD_SEL(1), + + /* XCVR_PHY configs */ + .phy_pre_ref0_init = 0xF38B5273, + .phy_pre_ref1_init = 0x8CEF9CE6, + .phy_pre_ref2_init = 0x00009D2D, + + .phy_cfg1_init = XCVR_PHY_CFG1_AA_PLAYBACK(1) | + XCVR_PHY_CFG1_AA_OUTPUT_SEL(1) | + XCVR_PHY_CFG1_FSK_BIT_INVERT(0) | + XCVR_PHY_CFG1_BSM_EN_BLE(0) | + XCVR_PHY_CFG1_DEMOD_CLK_MODE(0) | + XCVR_PHY_CFG1_CTS_THRESH(0xb0) | + XCVR_PHY_CFG1_FSK_FTS_TIMEOUT(2), + + .phy_el_cfg_init = XCVR_PHY_EL_CFG_EL_ENABLE(1) +#if !RADIO_IS_GEN_2P1 + | XCVR_PHY_EL_CFG_EL_ZB_ENABLE(0) +#endif /* !RADIO_IS_GEN_2P1 */ + , + /* XCVR_RX_DIG configs */ + .rx_dig_ctrl_init_26mhz = XCVR_RX_DIG_RX_DIG_CTRL_RX_FSK_ZB_SEL(0) | /* Depends on protocol */ + XCVR_RX_DIG_RX_DIG_CTRL_RX_DC_RESID_EN(1) | /* Depends on protocol */ + XCVR_RX_DIG_RX_DIG_CTRL_RX_SRC_RATE(0), + + .rx_dig_ctrl_init_32mhz = XCVR_RX_DIG_RX_DIG_CTRL_RX_FSK_ZB_SEL(0) | /* Depends on protocol */ + XCVR_RX_DIG_RX_DIG_CTRL_RX_DC_RESID_EN(1), /* Depends on protocol */ + + .agc_ctrl_0_init = XCVR_RX_DIG_AGC_CTRL_0_AGC_DOWN_RSSI_THRESH(0xFF), + + /* XCVR_TSM configs */ +#if (DATA_PADDING_EN) + .tsm_timing_35_init = B0(TX_DIG_EN_ASSERT + TX_DIG_EN_TX_HI_ADJ), +#else + .tsm_timing_35_init = B0(TX_DIG_EN_ASSERT), +#endif /* (DATA_PADDING_EN) */ + + /* XCVR_TX_DIG configs */ + .tx_gfsk_ctrl = XCVR_TX_DIG_GFSK_CTRL_GFSK_MULTIPLY_TABLE_MANUAL(0x4000) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_MI(3) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_MLD(0) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_FLD(0) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_MOD_INDEX_SCALING(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_OVRD_EN(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_0_OVRD(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_1_OVRD(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_2_OVRD(0), + .tx_gfsk_coeff1_26mhz = 0, + .tx_gfsk_coeff2_26mhz = 0, + .tx_gfsk_coeff1_32mhz = 0, + .tx_gfsk_coeff2_32mhz = 0, +}; + +/* MODE & DATA RATE combined configuration */ +const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p5_h_1p0_1mbps_config = +{ + .radio_mode = GFSK_BT_0p5_h_1p0, + .data_rate = DR_1MBPS, + + .ana_sy_ctrl2.mask = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM_MASK, + .ana_sy_ctrl2.init = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM(1), /* VCO KVM */ + .ana_rx_bba.mask = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL_MASK | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL_MASK, + .ana_rx_bba.init = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL(3) | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL(3), /* BBA_BW_SEL and BBA2_BW_SEL */ + .ana_rx_tza.mask = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL_MASK, + .ana_rx_tza.init = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL(3), /* TZA_BW_SEL */ + + .phy_cfg2_init = XCVR_PHY_CFG2_PHY_FIFO_PRECHG(8) | + XCVR_PHY_CFG2_X2_DEMOD_GAIN(0xA) , + + /* AGC configs */ + .agc_ctrl_2_init_26mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(11) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + .agc_ctrl_2_init_32mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(12) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + + /* All constant values are represented as 16 bits, register writes will remove unused bits */ + .rx_chf_coeffs_26mhz.rx_chf_coef_0 = 0x0001, + .rx_chf_coeffs_26mhz.rx_chf_coef_1 = 0x0004, + .rx_chf_coeffs_26mhz.rx_chf_coef_2 = 0x0006, + .rx_chf_coeffs_26mhz.rx_chf_coef_3 = 0x0003, + .rx_chf_coeffs_26mhz.rx_chf_coef_4 = 0xFFF9, + .rx_chf_coeffs_26mhz.rx_chf_coef_5 = 0xFFEB, + .rx_chf_coeffs_26mhz.rx_chf_coef_6 = 0xFFE2, + .rx_chf_coeffs_26mhz.rx_chf_coef_7 = 0xFFE9, + .rx_chf_coeffs_26mhz.rx_chf_coef_8 = 0x0008, + .rx_chf_coeffs_26mhz.rx_chf_coef_9 = 0x003A, + .rx_chf_coeffs_26mhz.rx_chf_coef_10 = 0x006F, + .rx_chf_coeffs_26mhz.rx_chf_coef_11 = 0x0090, + + /* 32MHz Channel Filter */ + .rx_chf_coeffs_32mhz.rx_chf_coef_0 = 0x0000, + .rx_chf_coeffs_32mhz.rx_chf_coef_1 = 0x0003, + .rx_chf_coeffs_32mhz.rx_chf_coef_2 = 0x0007, + .rx_chf_coeffs_32mhz.rx_chf_coef_3 = 0x0008, + .rx_chf_coeffs_32mhz.rx_chf_coef_4 = 0x0000, + .rx_chf_coeffs_32mhz.rx_chf_coef_5 = 0xFFF0, + .rx_chf_coeffs_32mhz.rx_chf_coef_6 = 0xFFE0, + .rx_chf_coeffs_32mhz.rx_chf_coef_7 = 0xFFE1, + .rx_chf_coeffs_32mhz.rx_chf_coef_8 = 0xFFFD, + .rx_chf_coeffs_32mhz.rx_chf_coef_9 = 0x0034, + .rx_chf_coeffs_32mhz.rx_chf_coef_10 = 0x0072, + .rx_chf_coeffs_32mhz.rx_chf_coef_11 = 0x009A, + + .rx_rccal_ctrl_0 = XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_SMP_DLY(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_COMP_INV(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_DIS(0) , + .rx_rccal_ctrl_1 = XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_DIS(0) , + + .tx_fsk_scale_26mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1627) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x09d9), + .tx_fsk_scale_32mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1800) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x0800), +}; + +const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p5_h_1p0_500kbps_config = +{ + .radio_mode = GFSK_BT_0p5_h_1p0, + .data_rate = DR_500KBPS, + + .ana_sy_ctrl2.mask = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM_MASK, + .ana_sy_ctrl2.init = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM(0), /* VCO KVM */ + .ana_rx_bba.mask = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL_MASK | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL_MASK, + .ana_rx_bba.init = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL(5) | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL(5), /* BBA_BW_SEL and BBA2_BW_SEL */ + .ana_rx_tza.mask = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL_MASK, + .ana_rx_tza.init = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL(5), /* TZA_BW_SEL */ + + .phy_cfg2_init = XCVR_PHY_CFG2_PHY_FIFO_PRECHG(8) | + XCVR_PHY_CFG2_X2_DEMOD_GAIN(0x8) , + + /* AGC configs */ + .agc_ctrl_2_init_26mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(15) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + .agc_ctrl_2_init_32mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(18) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + + /* All constant values are represented as 16 bits, register writes will remove unused bits */ + .rx_chf_coeffs_26mhz.rx_chf_coef_0 = 0xFFFD, + .rx_chf_coeffs_26mhz.rx_chf_coef_1 = 0xFFEA, + .rx_chf_coeffs_26mhz.rx_chf_coef_2 = 0xFFF3, + .rx_chf_coeffs_26mhz.rx_chf_coef_3 = 0x0021, + .rx_chf_coeffs_26mhz.rx_chf_coef_4 = 0x0013, + .rx_chf_coeffs_26mhz.rx_chf_coef_5 = 0xFFC9, + .rx_chf_coeffs_26mhz.rx_chf_coef_6 = 0xFFEE, + .rx_chf_coeffs_26mhz.rx_chf_coef_7 = 0x005E, + .rx_chf_coeffs_26mhz.rx_chf_coef_8 = 0x0004, + .rx_chf_coeffs_26mhz.rx_chf_coef_9 = 0xFF4E, + .rx_chf_coeffs_26mhz.rx_chf_coef_10 = 0xFFFC, + .rx_chf_coeffs_26mhz.rx_chf_coef_11 = 0x018F, + + /* 32MHz Channel Filter */ + .rx_chf_coeffs_32mhz.rx_chf_coef_0 = 0x0012, + .rx_chf_coeffs_32mhz.rx_chf_coef_1 = 0x0011, + .rx_chf_coeffs_32mhz.rx_chf_coef_2 = 0xFFE1, + .rx_chf_coeffs_32mhz.rx_chf_coef_3 = 0xFFEE, + .rx_chf_coeffs_32mhz.rx_chf_coef_4 = 0x0034, + .rx_chf_coeffs_32mhz.rx_chf_coef_5 = 0xFFFD, + .rx_chf_coeffs_32mhz.rx_chf_coef_6 = 0xFFB7, + .rx_chf_coeffs_32mhz.rx_chf_coef_7 = 0x003B, + .rx_chf_coeffs_32mhz.rx_chf_coef_8 = 0x004F, + .rx_chf_coeffs_32mhz.rx_chf_coef_9 = 0xFF5B, + .rx_chf_coeffs_32mhz.rx_chf_coef_10 = 0xFFB5, + .rx_chf_coeffs_32mhz.rx_chf_coef_11 = 0x018B, + + .rx_rccal_ctrl_0 = XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_SMP_DLY(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_COMP_INV(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_DIS(0) , + .rx_rccal_ctrl_1 = XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_DIS(0) , + + .tx_fsk_scale_26mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1627) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x09d9), + .tx_fsk_scale_32mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1800) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x0800), +}; + +const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p5_h_1p0_250kbps_config = +{ + .radio_mode = GFSK_BT_0p5_h_1p0, + .data_rate = DR_250KBPS, + + .ana_sy_ctrl2.mask = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM_MASK, + .ana_sy_ctrl2.init = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM(0), /* VCO KVM */ + .ana_rx_bba.mask = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL_MASK | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL_MASK, + .ana_rx_bba.init = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL(5) | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL(5), /* BBA_BW_SEL and BBA2_BW_SEL */ + .ana_rx_tza.mask = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL_MASK, + .ana_rx_tza.init = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL(5), /* TZA_BW_SEL */ + + .phy_cfg2_init = XCVR_PHY_CFG2_PHY_FIFO_PRECHG(8) | + XCVR_PHY_CFG2_X2_DEMOD_GAIN(0x6) , + + /* AGC configs */ + .agc_ctrl_2_init_26mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(18) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(2) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + .agc_ctrl_2_init_32mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(22) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + + /* All constant values are represented as 16 bits, register writes will remove unused bits */ + .rx_chf_coeffs_26mhz.rx_chf_coef_0 = 0xFFFE, + .rx_chf_coeffs_26mhz.rx_chf_coef_1 = 0x0004, + .rx_chf_coeffs_26mhz.rx_chf_coef_2 = 0x000C, + .rx_chf_coeffs_26mhz.rx_chf_coef_3 = 0x0011, + .rx_chf_coeffs_26mhz.rx_chf_coef_4 = 0x000B, + .rx_chf_coeffs_26mhz.rx_chf_coef_5 = 0xFFF8, + .rx_chf_coeffs_26mhz.rx_chf_coef_6 = 0xFFE0, + .rx_chf_coeffs_26mhz.rx_chf_coef_7 = 0xFFD7, + .rx_chf_coeffs_26mhz.rx_chf_coef_8 = 0xFFF0, + .rx_chf_coeffs_26mhz.rx_chf_coef_9 = 0x002A, + .rx_chf_coeffs_26mhz.rx_chf_coef_10 = 0x006F, + .rx_chf_coeffs_26mhz.rx_chf_coef_11 = 0x009E, + + /* 32MHz Channel Filter */ + .rx_chf_coeffs_32mhz.rx_chf_coef_0 = 0xFFFA, + .rx_chf_coeffs_32mhz.rx_chf_coef_1 = 0xFFF9, + .rx_chf_coeffs_32mhz.rx_chf_coef_2 = 0x0000, + .rx_chf_coeffs_32mhz.rx_chf_coef_3 = 0x000F, + .rx_chf_coeffs_32mhz.rx_chf_coef_4 = 0x0019, + .rx_chf_coeffs_32mhz.rx_chf_coef_5 = 0x000C, + .rx_chf_coeffs_32mhz.rx_chf_coef_6 = 0xFFEB, + .rx_chf_coeffs_32mhz.rx_chf_coef_7 = 0xFFCD, + .rx_chf_coeffs_32mhz.rx_chf_coef_8 = 0xFFD7, + .rx_chf_coeffs_32mhz.rx_chf_coef_9 = 0x0017, + .rx_chf_coeffs_32mhz.rx_chf_coef_10 = 0x0075, + .rx_chf_coeffs_32mhz.rx_chf_coef_11 = 0x00BB, + + .rx_rccal_ctrl_0 = XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_DIS(1) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_SMP_DLY(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_COMP_INV(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_DIS(1) , + .rx_rccal_ctrl_1 = XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_DIS(1) , + + .tx_fsk_scale_26mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1627) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x09d9), + .tx_fsk_scale_32mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1800) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x0800), +}; + diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_gfsk_bt_0p7_h_0p5_config.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_gfsk_bt_0p7_h_0p5_config.c new file mode 100644 index 0000000000..46f6c85086 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_gfsk_bt_0p7_h_0p5_config.c @@ -0,0 +1,353 @@ +/* + * 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 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_xcvr.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ +/* MODE only configuration */ +const xcvr_mode_config_t gfsk_bt_0p7_h_0p5_mode_config = +{ + .radio_mode = GFSK_BT_0p7_h_0p5, + .scgc5_clock_ena_bits = SIM_SCGC5_PHYDIG_MASK | SIM_SCGC5_GEN_FSK_MASK, + + /* XCVR_MISC configs */ + .xcvr_ctrl.mask = XCVR_CTRL_XCVR_CTRL_PROTOCOL_MASK | + XCVR_CTRL_XCVR_CTRL_TGT_PWR_SRC_MASK | + XCVR_CTRL_XCVR_CTRL_DEMOD_SEL_MASK, + .xcvr_ctrl.init = XCVR_CTRL_XCVR_CTRL_PROTOCOL(8) | + XCVR_CTRL_XCVR_CTRL_TGT_PWR_SRC(7) | + XCVR_CTRL_XCVR_CTRL_DEMOD_SEL(1), + + /* XCVR_PHY configs */ + .phy_pre_ref0_init = 0x79CDEB39, + .phy_pre_ref1_init = 0xCE77DEF7, + .phy_pre_ref2_init = 0x0000CEB7, + + .phy_cfg1_init = XCVR_PHY_CFG1_AA_PLAYBACK(1) | + XCVR_PHY_CFG1_AA_OUTPUT_SEL(1) | + XCVR_PHY_CFG1_FSK_BIT_INVERT(0) | + XCVR_PHY_CFG1_BSM_EN_BLE(0) | + XCVR_PHY_CFG1_DEMOD_CLK_MODE(0) | + XCVR_PHY_CFG1_CTS_THRESH(0xb0) | + XCVR_PHY_CFG1_FSK_FTS_TIMEOUT(2), + + .phy_el_cfg_init = XCVR_PHY_EL_CFG_EL_ENABLE(1) +#if !RADIO_IS_GEN_2P1 + | XCVR_PHY_EL_CFG_EL_ZB_ENABLE(0) +#endif /* !RADIO_IS_GEN_2P1 */ + , + + /* XCVR_RX_DIG configs */ + .rx_dig_ctrl_init_26mhz = XCVR_RX_DIG_RX_DIG_CTRL_RX_FSK_ZB_SEL(0) | /* Depends on protocol */ + XCVR_RX_DIG_RX_DIG_CTRL_RX_DC_RESID_EN(1), /* Depends on protocol */ + XCVR_RX_DIG_RX_DIG_CTRL_RX_SRC_RATE(0), + + .rx_dig_ctrl_init_32mhz = XCVR_RX_DIG_RX_DIG_CTRL_RX_FSK_ZB_SEL(0) | /* Depends on protocol */ + XCVR_RX_DIG_RX_DIG_CTRL_RX_DC_RESID_EN(1), /* Depends on protocol */ + + .agc_ctrl_0_init = XCVR_RX_DIG_AGC_CTRL_0_AGC_DOWN_RSSI_THRESH(0xFF), + + /* XCVR_TSM configs */ +#if (DATA_PADDING_EN) + .tsm_timing_35_init = B0(TX_DIG_EN_ASSERT+TX_DIG_EN_TX_HI_ADJ), +#else + .tsm_timing_35_init = B0(TX_DIG_EN_ASSERT), +#endif /* (DATA_PADDING_EN) */ + + /* XCVR_TX_DIG configs */ + .tx_gfsk_ctrl = XCVR_TX_DIG_GFSK_CTRL_GFSK_MULTIPLY_TABLE_MANUAL(0x4000) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_MI(1) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_MLD(0) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_FLD(1) | /* Use GFSK Manual Filter Coeffs */ + XCVR_TX_DIG_GFSK_CTRL_GFSK_MOD_INDEX_SCALING(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_OVRD_EN(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_0_OVRD(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_1_OVRD(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_2_OVRD(0), + .tx_gfsk_coeff1_26mhz = (27U) << 0 | /* Coeff 2/13 */ + (276U) << 7 | /* Coeff 6/9 */ + (62U) << 16 | /* Coef 3/12 */ + (326U) << 23, /* Coeff 7/8 */ + .tx_gfsk_coeff2_26mhz = (3U) << 0 | /* Coeff 0/15 */ + (10U) << 8 | /* Coeff 1/14 */ + (121U) << 16 | /* Coeff 4/11 */ + (198U) << 24, /* Coeff 5/10 */ + .tx_gfsk_coeff1_32mhz = (1U) << 0 | /* Coeff 2/13 */ + (330U) << 7 | /* Coeff 6/9 */ + (7U) << 16 | /* Coef 3/12 */ + (510U) << 23, /* Coeff 7/8 */ + .tx_gfsk_coeff2_32mhz = (0U) << 0 | /* Coeff 0/15 */ + (0U) << 8 | /* Coeff 1/14 */ + (37U) << 16 | /* Coeff 4/11 */ + (138U) << 24, /* Coeff 5/10 */ +}; + +/* MODE & DATA RATE combined configuration */ +const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p7_h_0p5_1mbps_config = +{ + .radio_mode = GFSK_BT_0p7_h_0p5, + .data_rate = DR_1MBPS, + + .ana_sy_ctrl2.mask = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM_MASK, + .ana_sy_ctrl2.init = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM(0), /* VCO KVM */ + .ana_rx_bba.mask = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL_MASK | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL_MASK, + .ana_rx_bba.init = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL(3) | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL(3), /* BBA_BW_SEL and BBA2_BW_SEL */ + .ana_rx_tza.mask = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL_MASK, + .ana_rx_tza.init = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL(3), /*TZA_BW_SEL */ + + .phy_cfg2_init = XCVR_PHY_CFG2_PHY_FIFO_PRECHG(8) | + XCVR_PHY_CFG2_X2_DEMOD_GAIN(0xA) , + + /* AGC configs */ + .agc_ctrl_2_init_26mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(11) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + .agc_ctrl_2_init_32mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(12) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + + /* All constant values are represented as 16 bits, register writes will remove unused bits */ + .rx_chf_coeffs_26mhz.rx_chf_coef_0 = 0x0001, + .rx_chf_coeffs_26mhz.rx_chf_coef_1 = 0x0000, + .rx_chf_coeffs_26mhz.rx_chf_coef_2 = 0xFFFE, + .rx_chf_coeffs_26mhz.rx_chf_coef_3 = 0xFFF8, + .rx_chf_coeffs_26mhz.rx_chf_coef_4 = 0xFFF1, + .rx_chf_coeffs_26mhz.rx_chf_coef_5 = 0xFFEF, + .rx_chf_coeffs_26mhz.rx_chf_coef_6 = 0xFFF4, + .rx_chf_coeffs_26mhz.rx_chf_coef_7 = 0x0004, + .rx_chf_coeffs_26mhz.rx_chf_coef_8 = 0x0020, + .rx_chf_coeffs_26mhz.rx_chf_coef_9 = 0x0041, + .rx_chf_coeffs_26mhz.rx_chf_coef_10 = 0x005E, + .rx_chf_coeffs_26mhz.rx_chf_coef_11 = 0x0070, + + /* 32MHz Channel Filter */ + .rx_chf_coeffs_32mhz.rx_chf_coef_0 = 0x0002, + .rx_chf_coeffs_32mhz.rx_chf_coef_1 = 0x0002, + .rx_chf_coeffs_32mhz.rx_chf_coef_2 = 0x0000, + .rx_chf_coeffs_32mhz.rx_chf_coef_3 = 0xFFFA, + .rx_chf_coeffs_32mhz.rx_chf_coef_4 = 0xFFF2, + .rx_chf_coeffs_32mhz.rx_chf_coef_5 = 0xFFEB, + .rx_chf_coeffs_32mhz.rx_chf_coef_6 = 0xFFED, + .rx_chf_coeffs_32mhz.rx_chf_coef_7 = 0xFFFD, + .rx_chf_coeffs_32mhz.rx_chf_coef_8 = 0x001B, + .rx_chf_coeffs_32mhz.rx_chf_coef_9 = 0x0041, + .rx_chf_coeffs_32mhz.rx_chf_coef_10 = 0x0065, + .rx_chf_coeffs_32mhz.rx_chf_coef_11 = 0x007A, + + .rx_rccal_ctrl_0 = XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_SMP_DLY(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_COMP_INV(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_DIS(0) , + .rx_rccal_ctrl_1 = XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_DIS(0) , + + .tx_fsk_scale_26mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1627) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x09d9), + .tx_fsk_scale_32mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1800) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x0800), +}; + +const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p7_h_0p5_500kbps_config = +{ + .radio_mode = GFSK_BT_0p7_h_0p5, + .data_rate = DR_500KBPS, + + .ana_sy_ctrl2.mask = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM_MASK, + .ana_sy_ctrl2.init = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM(0), /* VCO KVM */ + .ana_rx_bba.mask = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL_MASK | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL_MASK, + .ana_rx_bba.init = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL(5) | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL(5), /* BBA_BW_SEL and BBA2_BW_SEL */ + .ana_rx_tza.mask = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL_MASK, + .ana_rx_tza.init = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL(5), /* TZA_BW_SEL */ + + .phy_cfg2_init = XCVR_PHY_CFG2_PHY_FIFO_PRECHG(8) | + XCVR_PHY_CFG2_X2_DEMOD_GAIN(0x8) , + + /* AGC configs */ + .agc_ctrl_2_init_26mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(15) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + .agc_ctrl_2_init_32mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(18) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + + /* All constant values are represented as 16 bits, register writes will remove unused bits */ + .rx_chf_coeffs_26mhz.rx_chf_coef_0 = 0x0002, + .rx_chf_coeffs_26mhz.rx_chf_coef_1 = 0xFFFF, + .rx_chf_coeffs_26mhz.rx_chf_coef_2 = 0xFFF8, + .rx_chf_coeffs_26mhz.rx_chf_coef_3 = 0xFFFA, + .rx_chf_coeffs_26mhz.rx_chf_coef_4 = 0x000A, + .rx_chf_coeffs_26mhz.rx_chf_coef_5 = 0x0019, + .rx_chf_coeffs_26mhz.rx_chf_coef_6 = 0x0009, + .rx_chf_coeffs_26mhz.rx_chf_coef_7 = 0xFFDB, + .rx_chf_coeffs_26mhz.rx_chf_coef_8 = 0xFFC1, + .rx_chf_coeffs_26mhz.rx_chf_coef_9 = 0xFFF6, + .rx_chf_coeffs_26mhz.rx_chf_coef_10 = 0x0072, + .rx_chf_coeffs_26mhz.rx_chf_coef_11 = 0x00DD, + + /* 32MHz Channel Filter */ + .rx_chf_coeffs_32mhz.rx_chf_coef_0 = 0x0002, + .rx_chf_coeffs_32mhz.rx_chf_coef_1 = 0x0003, + .rx_chf_coeffs_32mhz.rx_chf_coef_2 = 0xFFFC, + .rx_chf_coeffs_32mhz.rx_chf_coef_3 = 0xFFF4, + .rx_chf_coeffs_32mhz.rx_chf_coef_4 = 0xFFFD, + .rx_chf_coeffs_32mhz.rx_chf_coef_5 = 0x0016, + .rx_chf_coeffs_32mhz.rx_chf_coef_6 = 0x001A, + .rx_chf_coeffs_32mhz.rx_chf_coef_7 = 0xFFEC, + .rx_chf_coeffs_32mhz.rx_chf_coef_8 = 0xFFBC, + .rx_chf_coeffs_32mhz.rx_chf_coef_9 = 0xFFE0, + .rx_chf_coeffs_32mhz.rx_chf_coef_10 = 0x0069, + .rx_chf_coeffs_32mhz.rx_chf_coef_11 = 0x00ED, + + .rx_rccal_ctrl_0 = XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_DIS(1) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_SMP_DLY(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_COMP_INV(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_DIS(1) , + .rx_rccal_ctrl_1 = XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_DIS(1) , + + .tx_fsk_scale_26mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1627) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x09d9), + .tx_fsk_scale_32mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1800) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x0800), +}; + +const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p7_h_0p5_250kbps_config = +{ + .radio_mode = GFSK_BT_0p7_h_0p5, + .data_rate = DR_250KBPS, + + .ana_sy_ctrl2.mask = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM_MASK, + .ana_sy_ctrl2.init = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM(0), /* VCO KVM */ + .ana_rx_bba.mask = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL_MASK | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL_MASK, + .ana_rx_bba.init = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL(5) | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL(5), /* BBA_BW_SEL and BBA2_BW_SEL */ + .ana_rx_tza.mask = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL_MASK, + .ana_rx_tza.init = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL(5), /* TZA_BW_SEL */ + + .phy_cfg2_init = XCVR_PHY_CFG2_PHY_FIFO_PRECHG(8) | + XCVR_PHY_CFG2_X2_DEMOD_GAIN(0x6) , + + /* AGC configs */ + .agc_ctrl_2_init_26mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(18) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + .agc_ctrl_2_init_32mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(22) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(2) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + + /* All constant values are represented as 16 bits, register writes will remove unused bits */ + .rx_chf_coeffs_26mhz.rx_chf_coef_0 = 0x0000, + .rx_chf_coeffs_26mhz.rx_chf_coef_1 = 0x0003, + .rx_chf_coeffs_26mhz.rx_chf_coef_2 = 0x0006, + .rx_chf_coeffs_26mhz.rx_chf_coef_3 = 0x0005, + .rx_chf_coeffs_26mhz.rx_chf_coef_4 = 0xFFFE, + .rx_chf_coeffs_26mhz.rx_chf_coef_5 = 0xFFF1, + .rx_chf_coeffs_26mhz.rx_chf_coef_6 = 0xFFE6, + .rx_chf_coeffs_26mhz.rx_chf_coef_7 = 0xFFEA, + .rx_chf_coeffs_26mhz.rx_chf_coef_8 = 0x0005, + .rx_chf_coeffs_26mhz.rx_chf_coef_9 = 0x0036, + .rx_chf_coeffs_26mhz.rx_chf_coef_10 = 0x006B, + .rx_chf_coeffs_26mhz.rx_chf_coef_11 = 0x008D, + + /* 32MHz Channel Filter */ + .rx_chf_coeffs_32mhz.rx_chf_coef_0 = 0xFFFF, + .rx_chf_coeffs_32mhz.rx_chf_coef_1 = 0x0000, + .rx_chf_coeffs_32mhz.rx_chf_coef_2 = 0x0004, + .rx_chf_coeffs_32mhz.rx_chf_coef_3 = 0x0008, + .rx_chf_coeffs_32mhz.rx_chf_coef_4 = 0x0004, + .rx_chf_coeffs_32mhz.rx_chf_coef_5 = 0xFFF8, + .rx_chf_coeffs_32mhz.rx_chf_coef_6 = 0xFFE6, + .rx_chf_coeffs_32mhz.rx_chf_coef_7 = 0xFFE2, + .rx_chf_coeffs_32mhz.rx_chf_coef_8 = 0xFFFA, + .rx_chf_coeffs_32mhz.rx_chf_coef_9 = 0x002E, + .rx_chf_coeffs_32mhz.rx_chf_coef_10 = 0x006D, + .rx_chf_coeffs_32mhz.rx_chf_coef_11 = 0x0098, + + .rx_rccal_ctrl_0 = XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_DIS(1) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_SMP_DLY(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_COMP_INV(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_DIS(1) , + .rx_rccal_ctrl_1 = XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_DIS(1) , + + .tx_fsk_scale_26mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1627) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x09d9), + .tx_fsk_scale_32mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1800) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x0800), +}; + diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_mode_datarate_config.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_mode_datarate_config.c new file mode 100644 index 0000000000..dcfc957475 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_mode_datarate_config.c @@ -0,0 +1,212 @@ +/* + * 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 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_xcvr.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ +/* ========================= DATA RATE ONLY settings ===============*/ +/*! + * @brief XCVR 1Mbps DATA RATE specific configure structure + */ +const xcvr_datarate_config_t xcvr_1mbps_config = +{ + .data_rate = DR_1MBPS, + .phy_el_cfg_init = XCVR_PHY_EL_CFG_EL_WIN_SIZE(0xF) | +#if !RADIO_IS_GEN_2P1 + XCVR_PHY_EL_CFG_EL_ZB_WIN_SIZE(0) | +#endif /* !RADIO_IS_GEN_2P1 */ + XCVR_PHY_EL_CFG_EL_INTERVAL(0x20) , + .rx_dig_ctrl_init_26mhz = XCVR_RX_DIG_RX_DIG_CTRL_RX_DEC_FILT_OSR(0) | + XCVR_RX_DIG_RX_DIG_CTRL_RX_DEC_FILT_GAIN(16), + .rx_dig_ctrl_init_32mhz = XCVR_RX_DIG_RX_DIG_CTRL_RX_DEC_FILT_OSR(1) | + XCVR_RX_DIG_RX_DIG_CTRL_RX_DEC_FILT_GAIN(16), + + .agc_ctrl_1_init_26mhz = XCVR_RX_DIG_AGC_CTRL_1_LNA_GAIN_SETTLE_TIME(10) | + XCVR_RX_DIG_AGC_CTRL_1_PRESLOW_EN(PRESLOW_ENA), + .agc_ctrl_1_init_32mhz = XCVR_RX_DIG_AGC_CTRL_1_LNA_GAIN_SETTLE_TIME(12) | + XCVR_RX_DIG_AGC_CTRL_1_PRESLOW_EN(PRESLOW_ENA), + + .dcoc_ctrl_0_init_26mhz = XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CORR_DLY(10) | + XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CORR_HOLD_TIME(21), + .dcoc_ctrl_0_init_32mhz = XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CORR_DLY(12) | + XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CORR_HOLD_TIME(26), + + .dcoc_ctrl_1_init_26mhz = XCVR_RX_DIG_DCOC_CTRL_1_DCOC_SIGN_SCALE_IDX(1) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_ALPHAC_SCALE_IDX(3) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_ALPHA_RADIUS_IDX(3) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_TRK_EST_GS_CNT(0) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_SIGN_SCALE_GS_IDX(1) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_ALPHAC_SCALE_GS_IDX(3) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_ALPHA_RADIUS_GS_IDX(3), + + .dcoc_ctrl_1_init_32mhz = XCVR_RX_DIG_DCOC_CTRL_1_DCOC_SIGN_SCALE_IDX(1) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_ALPHAC_SCALE_IDX(3) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_ALPHA_RADIUS_IDX(3) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_TRK_EST_GS_CNT(0) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_SIGN_SCALE_GS_IDX(1) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_ALPHAC_SCALE_GS_IDX(3) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_ALPHA_RADIUS_GS_IDX(3), + + .dcoc_cal_iir_init_26mhz = XCVR_RX_DIG_DCOC_CAL_IIR_DCOC_CAL_IIR3A_IDX(2) | + XCVR_RX_DIG_DCOC_CAL_IIR_DCOC_CAL_IIR2A_IDX(2) | + XCVR_RX_DIG_DCOC_CAL_IIR_DCOC_CAL_IIR1A_IDX(2), + .dcoc_cal_iir_init_32mhz = XCVR_RX_DIG_DCOC_CAL_IIR_DCOC_CAL_IIR3A_IDX(2) | + XCVR_RX_DIG_DCOC_CAL_IIR_DCOC_CAL_IIR2A_IDX(3) | + XCVR_RX_DIG_DCOC_CAL_IIR_DCOC_CAL_IIR1A_IDX(2), + + .dc_resid_ctrl_26mhz = XCVR_RX_DIG_DC_RESID_CTRL_DC_RESID_NWIN(33) | + XCVR_RX_DIG_DC_RESID_CTRL_DC_RESID_DLY(6), + .dc_resid_ctrl_32mhz = XCVR_RX_DIG_DC_RESID_CTRL_DC_RESID_NWIN(40) | + XCVR_RX_DIG_DC_RESID_CTRL_DC_RESID_DLY(7), +}; + +/*! + * @brief XCVR 500K bps DATA RATE specific configure structure + */ +const xcvr_datarate_config_t xcvr_500kbps_config = +{ + .data_rate = DR_500KBPS, + .phy_el_cfg_init = XCVR_PHY_EL_CFG_EL_WIN_SIZE(0x8) | +#if !RADIO_IS_GEN_2P1 + XCVR_PHY_EL_CFG_EL_ZB_WIN_SIZE(0) | +#endif /* !RADIO_IS_GEN_2P1 */ + XCVR_PHY_EL_CFG_EL_INTERVAL(0x10), + .rx_dig_ctrl_init_26mhz = XCVR_RX_DIG_RX_DIG_CTRL_RX_DEC_FILT_OSR(1) | + XCVR_RX_DIG_RX_DIG_CTRL_RX_DEC_FILT_GAIN(16), + .rx_dig_ctrl_init_32mhz = XCVR_RX_DIG_RX_DIG_CTRL_RX_DEC_FILT_OSR(2) | + XCVR_RX_DIG_RX_DIG_CTRL_RX_DEC_FILT_GAIN(16), + + .agc_ctrl_1_init_26mhz = XCVR_RX_DIG_AGC_CTRL_1_LNA_GAIN_SETTLE_TIME(15) | + XCVR_RX_DIG_AGC_CTRL_1_PRESLOW_EN(PRESLOW_ENA), + .agc_ctrl_1_init_32mhz = XCVR_RX_DIG_AGC_CTRL_1_LNA_GAIN_SETTLE_TIME(18) | + XCVR_RX_DIG_AGC_CTRL_1_PRESLOW_EN(PRESLOW_ENA), + + .dcoc_ctrl_0_init_26mhz = XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CORR_DLY(13) | + XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CORR_HOLD_TIME(29), + .dcoc_ctrl_0_init_32mhz = XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CORR_DLY(16) | + XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CORR_HOLD_TIME(36), + + .dcoc_ctrl_1_init_26mhz = XCVR_RX_DIG_DCOC_CTRL_1_DCOC_SIGN_SCALE_IDX(1) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_ALPHAC_SCALE_IDX(3) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_ALPHA_RADIUS_IDX(2) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_TRK_EST_GS_CNT(0) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_SIGN_SCALE_GS_IDX(1) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_ALPHAC_SCALE_GS_IDX(3) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_ALPHA_RADIUS_GS_IDX(2), + + .dcoc_ctrl_1_init_32mhz = XCVR_RX_DIG_DCOC_CTRL_1_DCOC_SIGN_SCALE_IDX(1) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_ALPHAC_SCALE_IDX(3) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_ALPHA_RADIUS_IDX(2) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_TRK_EST_GS_CNT(0) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_SIGN_SCALE_GS_IDX(1) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_ALPHAC_SCALE_GS_IDX(3) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_ALPHA_RADIUS_GS_IDX(2), + + .dcoc_cal_iir_init_26mhz = XCVR_RX_DIG_DCOC_CAL_IIR_DCOC_CAL_IIR3A_IDX(2) | + XCVR_RX_DIG_DCOC_CAL_IIR_DCOC_CAL_IIR2A_IDX(2) | + XCVR_RX_DIG_DCOC_CAL_IIR_DCOC_CAL_IIR1A_IDX(2), + .dcoc_cal_iir_init_32mhz = XCVR_RX_DIG_DCOC_CAL_IIR_DCOC_CAL_IIR3A_IDX(2) | + XCVR_RX_DIG_DCOC_CAL_IIR_DCOC_CAL_IIR2A_IDX(2) | + XCVR_RX_DIG_DCOC_CAL_IIR_DCOC_CAL_IIR1A_IDX(2), + + .dc_resid_ctrl_26mhz = XCVR_RX_DIG_DC_RESID_CTRL_DC_RESID_NWIN(26) | + XCVR_RX_DIG_DC_RESID_CTRL_DC_RESID_DLY(4), + .dc_resid_ctrl_32mhz = XCVR_RX_DIG_DC_RESID_CTRL_DC_RESID_NWIN(32) | + XCVR_RX_DIG_DC_RESID_CTRL_DC_RESID_DLY(4), +}; + +/*! + * @brief XCVR 250K bps DATA RATE specific configure structure + */ +const xcvr_datarate_config_t xcvr_250kbps_config = +{ + .data_rate = DR_250KBPS, + .phy_el_cfg_init = XCVR_PHY_EL_CFG_EL_WIN_SIZE(0x4) | +#if !RADIO_IS_GEN_2P1 + XCVR_PHY_EL_CFG_EL_ZB_WIN_SIZE(0) | +#endif /* !RADIO_IS_GEN_2P1 */ + XCVR_PHY_EL_CFG_EL_INTERVAL(0x8) , + .rx_dig_ctrl_init_26mhz = XCVR_RX_DIG_RX_DIG_CTRL_RX_DEC_FILT_OSR(2) | + XCVR_RX_DIG_RX_DIG_CTRL_RX_DEC_FILT_GAIN(16), + .rx_dig_ctrl_init_32mhz = XCVR_RX_DIG_RX_DIG_CTRL_RX_DEC_FILT_OSR(4) | + XCVR_RX_DIG_RX_DIG_CTRL_RX_DEC_FILT_GAIN(16), + + .agc_ctrl_1_init_26mhz = XCVR_RX_DIG_AGC_CTRL_1_LNA_GAIN_SETTLE_TIME(18) | + XCVR_RX_DIG_AGC_CTRL_1_PRESLOW_EN(PRESLOW_ENA), + .agc_ctrl_1_init_32mhz = XCVR_RX_DIG_AGC_CTRL_1_LNA_GAIN_SETTLE_TIME(22) | + XCVR_RX_DIG_AGC_CTRL_1_PRESLOW_EN(PRESLOW_ENA), + + .dcoc_ctrl_0_init_26mhz = XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CORR_DLY(16) | + XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CORR_HOLD_TIME(34), + .dcoc_ctrl_0_init_32mhz = XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CORR_DLY(20) | + XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CORR_HOLD_TIME(42), + + .dcoc_ctrl_1_init_26mhz = XCVR_RX_DIG_DCOC_CTRL_1_DCOC_SIGN_SCALE_IDX(1) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_ALPHAC_SCALE_IDX(3) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_ALPHA_RADIUS_IDX(1) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_TRK_EST_GS_CNT(0) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_SIGN_SCALE_GS_IDX(1) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_ALPHAC_SCALE_GS_IDX(3) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_ALPHA_RADIUS_GS_IDX(2), + + .dcoc_ctrl_1_init_32mhz = XCVR_RX_DIG_DCOC_CTRL_1_DCOC_SIGN_SCALE_IDX(1) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_ALPHAC_SCALE_IDX(3) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_ALPHA_RADIUS_IDX(1) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_TRK_EST_GS_CNT(0) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_SIGN_SCALE_GS_IDX(1) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_ALPHAC_SCALE_GS_IDX(3) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_ALPHA_RADIUS_GS_IDX(2), + + .dcoc_cal_iir_init_26mhz = XCVR_RX_DIG_DCOC_CAL_IIR_DCOC_CAL_IIR3A_IDX(0) | + XCVR_RX_DIG_DCOC_CAL_IIR_DCOC_CAL_IIR2A_IDX(1) | + XCVR_RX_DIG_DCOC_CAL_IIR_DCOC_CAL_IIR1A_IDX(1), + .dcoc_cal_iir_init_32mhz = XCVR_RX_DIG_DCOC_CAL_IIR_DCOC_CAL_IIR3A_IDX(0) | + XCVR_RX_DIG_DCOC_CAL_IIR_DCOC_CAL_IIR2A_IDX(1) | + XCVR_RX_DIG_DCOC_CAL_IIR_DCOC_CAL_IIR1A_IDX(1), + + .dc_resid_ctrl_26mhz = XCVR_RX_DIG_DC_RESID_CTRL_DC_RESID_NWIN(13) | + XCVR_RX_DIG_DC_RESID_CTRL_DC_RESID_DLY(4), + .dc_resid_ctrl_32mhz = XCVR_RX_DIG_DC_RESID_CTRL_DC_RESID_NWIN(16) | + XCVR_RX_DIG_DC_RESID_CTRL_DC_RESID_DLY(4), +}; + diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_msk_config.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_msk_config.c new file mode 100644 index 0000000000..44eb38c1f2 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_msk_config.c @@ -0,0 +1,343 @@ +/* + * 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 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_xcvr.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ +/* MODE only configuration */ +const xcvr_mode_config_t msk_mode_config = +{ + .radio_mode = MSK, + .scgc5_clock_ena_bits = SIM_SCGC5_PHYDIG_MASK | SIM_SCGC5_GEN_FSK_MASK, + + /* XCVR_MISC configs */ + .xcvr_ctrl.mask = XCVR_CTRL_XCVR_CTRL_PROTOCOL_MASK | + XCVR_CTRL_XCVR_CTRL_TGT_PWR_SRC_MASK | + XCVR_CTRL_XCVR_CTRL_DEMOD_SEL_MASK, + .xcvr_ctrl.init = XCVR_CTRL_XCVR_CTRL_PROTOCOL(9) | + XCVR_CTRL_XCVR_CTRL_TGT_PWR_SRC(4) | + XCVR_CTRL_XCVR_CTRL_DEMOD_SEL(1), + + /* XCVR_PHY configs */ + .phy_pre_ref0_init = 0x79CDEB38, + .phy_pre_ref1_init = 0xCE77DFF7, + .phy_pre_ref2_init = 0x0000CEB7, + + .phy_cfg1_init = XCVR_PHY_CFG1_AA_PLAYBACK(0) | + XCVR_PHY_CFG1_AA_OUTPUT_SEL(1) | + XCVR_PHY_CFG1_FSK_BIT_INVERT(0) | + XCVR_PHY_CFG1_BSM_EN_BLE(0) | + XCVR_PHY_CFG1_DEMOD_CLK_MODE(0) | + XCVR_PHY_CFG1_CTS_THRESH(208U) | + XCVR_PHY_CFG1_FSK_FTS_TIMEOUT(2), + + .phy_el_cfg_init = XCVR_PHY_EL_CFG_EL_ENABLE(1) +#if !RADIO_IS_GEN_2P1 + | XCVR_PHY_EL_CFG_EL_ZB_ENABLE(0) +#endif /* !RADIO_IS_GEN_2P1 */ + , + + /* XCVR_RX_DIG configs */ + .rx_dig_ctrl_init_26mhz = XCVR_RX_DIG_RX_DIG_CTRL_RX_FSK_ZB_SEL(0) | /* Depends on protocol */ + XCVR_RX_DIG_RX_DIG_CTRL_RX_DC_RESID_EN(1) | /* Depends on protocol */ + XCVR_RX_DIG_RX_DIG_CTRL_RX_SRC_RATE(0), + + .rx_dig_ctrl_init_32mhz = XCVR_RX_DIG_RX_DIG_CTRL_RX_FSK_ZB_SEL(0) | /* Depends on protocol */ + XCVR_RX_DIG_RX_DIG_CTRL_RX_DC_RESID_EN(1), /* Depends on protocol */ + + .agc_ctrl_0_init = XCVR_RX_DIG_AGC_CTRL_0_AGC_DOWN_RSSI_THRESH(0xFF), + + /* XCVR_TSM configs */ +#if (DATA_PADDING_EN) + .tsm_timing_35_init = B0(TX_DIG_EN_ASSERT+TX_DIG_EN_TX_HI_ADJ), +#else + .tsm_timing_35_init = B0(TX_DIG_EN_ASSERT), +#endif /* (DATA_PADDING_EN) */ + + /* XCVR_TX_DIG configs */ + .tx_gfsk_ctrl = XCVR_TX_DIG_GFSK_CTRL_GFSK_MULTIPLY_TABLE_MANUAL(0x4000) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_MI(0) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_MLD(0) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_FLD(0) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_MOD_INDEX_SCALING(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_OVRD_EN(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_0_OVRD(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_1_OVRD(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_2_OVRD(0), + .tx_gfsk_coeff1_26mhz = 0, + .tx_gfsk_coeff2_26mhz = 0, + .tx_gfsk_coeff1_32mhz = 0, + .tx_gfsk_coeff2_32mhz = 0, +}; + +/* MODE & DATA RATE combined configuration */ +const xcvr_mode_datarate_config_t xcvr_MSK_1mbps_config = +{ + .radio_mode = MSK, + .data_rate = DR_1MBPS, + + .ana_sy_ctrl2.mask = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM_MASK, + .ana_sy_ctrl2.init = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM(0), /* VCO KVM */ + .ana_rx_bba.mask = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL_MASK | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL_MASK, + .ana_rx_bba.init = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL(3) | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL(3), /* BBA_BW_SEL and BBA2_BW_SEL */ + .ana_rx_tza.mask = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL_MASK, + .ana_rx_tza.init = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL(3), /*TZA_BW_SEL */ + + .phy_cfg2_init = XCVR_PHY_CFG2_PHY_FIFO_PRECHG(8) | + XCVR_PHY_CFG2_X2_DEMOD_GAIN(0xA) , + + /* AGC configs */ + .agc_ctrl_2_init_26mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(11) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + .agc_ctrl_2_init_32mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(12) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + + /* All constant values are represented as 16 bits, register writes will remove unused bits */ + /* MSK 1MBPS channel filter @ 26MHz RF OSC */ + .rx_chf_coeffs_26mhz.rx_chf_coef_0 = 0x0002, + .rx_chf_coeffs_26mhz.rx_chf_coef_1 = 0x0002, + .rx_chf_coeffs_26mhz.rx_chf_coef_2 = 0x0000, + .rx_chf_coeffs_26mhz.rx_chf_coef_3 = 0xFFF9, + .rx_chf_coeffs_26mhz.rx_chf_coef_4 = 0xFFF0, + .rx_chf_coeffs_26mhz.rx_chf_coef_5 = 0xFFEA, + .rx_chf_coeffs_26mhz.rx_chf_coef_6 = 0xFFEC, + .rx_chf_coeffs_26mhz.rx_chf_coef_7 = 0xFFFC, + .rx_chf_coeffs_26mhz.rx_chf_coef_8 = 0x001B, + .rx_chf_coeffs_26mhz.rx_chf_coef_9 = 0x0042, + .rx_chf_coeffs_26mhz.rx_chf_coef_10 = 0x0066, + .rx_chf_coeffs_26mhz.rx_chf_coef_11 = 0x007C, + + /* MSK 1MBPS channel filter @ 32MHz RF OSC */ + .rx_chf_coeffs_32mhz.rx_chf_coef_0 = 0x0002, + .rx_chf_coeffs_32mhz.rx_chf_coef_1 = 0x0003, + .rx_chf_coeffs_32mhz.rx_chf_coef_2 = 0x0002, + .rx_chf_coeffs_32mhz.rx_chf_coef_3 = 0xFFFC, + .rx_chf_coeffs_32mhz.rx_chf_coef_4 = 0xFFF2, + .rx_chf_coeffs_32mhz.rx_chf_coef_5 = 0xFFE9, + .rx_chf_coeffs_32mhz.rx_chf_coef_6 = 0xFFE9, + .rx_chf_coeffs_32mhz.rx_chf_coef_7 = 0xFFF7, + .rx_chf_coeffs_32mhz.rx_chf_coef_8 = 0x0016, + .rx_chf_coeffs_32mhz.rx_chf_coef_9 = 0x0040, + .rx_chf_coeffs_32mhz.rx_chf_coef_10 = 0x0069, + .rx_chf_coeffs_32mhz.rx_chf_coef_11 = 0x0082, + + .rx_rccal_ctrl_0 = XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_SMP_DLY(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_COMP_INV(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_DIS(0) , + .rx_rccal_ctrl_1 = XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_DIS(0) , + + .tx_fsk_scale_26mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1627) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x09d9), + .tx_fsk_scale_32mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1800) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x0800), +}; + +const xcvr_mode_datarate_config_t xcvr_MSK_500kbps_config = +{ + .radio_mode = MSK, + .data_rate = DR_500KBPS, + + .ana_sy_ctrl2.mask = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM_MASK, + .ana_sy_ctrl2.init = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM(0), /* VCO KVM */ + .ana_rx_bba.mask = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL_MASK | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL_MASK, + .ana_rx_bba.init = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL(5) | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL(5), /* BBA_BW_SEL and BBA2_BW_SEL */ + .ana_rx_tza.mask = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL_MASK, + .ana_rx_tza.init = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL(5), /* TZA_BW_SEL */ + + .phy_cfg2_init = XCVR_PHY_CFG2_PHY_FIFO_PRECHG(8) | + XCVR_PHY_CFG2_X2_DEMOD_GAIN(0xa) , + + /* AGC configs */ + .agc_ctrl_2_init_26mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(15) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + .agc_ctrl_2_init_32mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(18) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + + /* All constant values are represented as 16 bits, register writes will remove unused bits */ + /* MSK 500KBPS channel filter @ 26MHz RF OSC */ + .rx_chf_coeffs_26mhz.rx_chf_coef_0 = 0x0001, + .rx_chf_coeffs_26mhz.rx_chf_coef_1 = 0x0004, + .rx_chf_coeffs_26mhz.rx_chf_coef_2 = 0x0006, + .rx_chf_coeffs_26mhz.rx_chf_coef_3 = 0x0005, + .rx_chf_coeffs_26mhz.rx_chf_coef_4 = 0xFFFC, + .rx_chf_coeffs_26mhz.rx_chf_coef_5 = 0xFFED, + .rx_chf_coeffs_26mhz.rx_chf_coef_6 = 0xFFE2, + .rx_chf_coeffs_26mhz.rx_chf_coef_7 = 0xFFE7, + .rx_chf_coeffs_26mhz.rx_chf_coef_8 = 0x0005, + .rx_chf_coeffs_26mhz.rx_chf_coef_9 = 0x0038, + .rx_chf_coeffs_26mhz.rx_chf_coef_10 = 0x006F, + .rx_chf_coeffs_26mhz.rx_chf_coef_11 = 0x0092, + + /* MSK 500KBPS channel filter @ 32MHz RF OSC */ + .rx_chf_coeffs_32mhz.rx_chf_coef_0 = 0xFFFF, + .rx_chf_coeffs_32mhz.rx_chf_coef_1 = 0x0002, + .rx_chf_coeffs_32mhz.rx_chf_coef_2 = 0x0006, + .rx_chf_coeffs_32mhz.rx_chf_coef_3 = 0x0009, + .rx_chf_coeffs_32mhz.rx_chf_coef_4 = 0x0003, + .rx_chf_coeffs_32mhz.rx_chf_coef_5 = 0xFFF3, + .rx_chf_coeffs_32mhz.rx_chf_coef_6 = 0xFFE2, + .rx_chf_coeffs_32mhz.rx_chf_coef_7 = 0xFFE0, + .rx_chf_coeffs_32mhz.rx_chf_coef_8 = 0xFFFA, + .rx_chf_coeffs_32mhz.rx_chf_coef_9 = 0x0031, + .rx_chf_coeffs_32mhz.rx_chf_coef_10 = 0x0071, + .rx_chf_coeffs_32mhz.rx_chf_coef_11 = 0x009C, + + .rx_rccal_ctrl_0 = XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_SMP_DLY(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_COMP_INV(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_DIS(0) , + .rx_rccal_ctrl_1 = XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_DIS(0) , + + .tx_fsk_scale_26mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1627) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x09d9), + .tx_fsk_scale_32mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1800) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x0800), +}; + +const xcvr_mode_datarate_config_t xcvr_MSK_250kbps_config = +{ + .radio_mode = MSK, + .data_rate = DR_250KBPS, + + .ana_sy_ctrl2.mask = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM_MASK, + .ana_sy_ctrl2.init = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM(0), /* VCO KVM */ + .ana_rx_bba.mask = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL_MASK | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL_MASK, + .ana_rx_bba.init = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL(5) | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL(5), /* BBA_BW_SEL and BBA2_BW_SEL */ + .ana_rx_tza.mask = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL_MASK, + .ana_rx_tza.init = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL(5), /* TZA_BW_SEL */ + + .phy_cfg2_init = XCVR_PHY_CFG2_PHY_FIFO_PRECHG(8) | + XCVR_PHY_CFG2_X2_DEMOD_GAIN(0x8) , + + /* AGC configs */ + .agc_ctrl_2_init_26mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(18) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(2) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + .agc_ctrl_2_init_32mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(22) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(7) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + + /* All constant values are represented as 16 bits, register writes will remove unused bits */ + .rx_chf_coeffs_26mhz.rx_chf_coef_0 = 0x0002, + .rx_chf_coeffs_26mhz.rx_chf_coef_1 = 0xFFFF, + .rx_chf_coeffs_26mhz.rx_chf_coef_2 = 0xFFF8, + .rx_chf_coeffs_26mhz.rx_chf_coef_3 = 0xFFFA, + .rx_chf_coeffs_26mhz.rx_chf_coef_4 = 0x000A, + .rx_chf_coeffs_26mhz.rx_chf_coef_5 = 0x0019, + .rx_chf_coeffs_26mhz.rx_chf_coef_6 = 0x0009, + .rx_chf_coeffs_26mhz.rx_chf_coef_7 = 0xFFDB, + .rx_chf_coeffs_26mhz.rx_chf_coef_8 = 0xFFC1, + .rx_chf_coeffs_26mhz.rx_chf_coef_9 = 0xFFF6, + .rx_chf_coeffs_26mhz.rx_chf_coef_10 = 0x0072, + .rx_chf_coeffs_26mhz.rx_chf_coef_11 = 0x00DD, + + /* MSK 250KBPS channel filter @ 32MHz RF OSC */ + .rx_chf_coeffs_32mhz.rx_chf_coef_0 = 0x0002, + .rx_chf_coeffs_32mhz.rx_chf_coef_1 = 0x0003, + .rx_chf_coeffs_32mhz.rx_chf_coef_2 = 0xFFFC, + .rx_chf_coeffs_32mhz.rx_chf_coef_3 = 0xFFF4, + .rx_chf_coeffs_32mhz.rx_chf_coef_4 = 0xFFFD, + .rx_chf_coeffs_32mhz.rx_chf_coef_5 = 0x0016, + .rx_chf_coeffs_32mhz.rx_chf_coef_6 = 0x001A, + .rx_chf_coeffs_32mhz.rx_chf_coef_7 = 0xFFEC, + .rx_chf_coeffs_32mhz.rx_chf_coef_8 = 0xFFBC, + .rx_chf_coeffs_32mhz.rx_chf_coef_9 = 0xFFE0, + .rx_chf_coeffs_32mhz.rx_chf_coef_10 = 0x0069, + .rx_chf_coeffs_32mhz.rx_chf_coef_11 = 0x00ED, + + .rx_rccal_ctrl_0 = XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_DIS(1) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_SMP_DLY(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_COMP_INV(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_DIS(1) , + .rx_rccal_ctrl_1 = XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_MANUAL(31) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_DIS(1) , + + .tx_fsk_scale_26mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1627) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x09d9), + .tx_fsk_scale_32mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1800) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x0800), +}; + diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_zgbe_config.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_zgbe_config.c new file mode 100644 index 0000000000..47d6f5f057 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/cfgs_kw4x_3x_2x/fsl_xcvr_zgbe_config.c @@ -0,0 +1,244 @@ +/* + * 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 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_xcvr.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ +const xcvr_mode_config_t zgbe_mode_config = +{ + .radio_mode = ZIGBEE_MODE, + .scgc5_clock_ena_bits = SIM_SCGC5_PHYDIG_MASK | SIM_SCGC5_ZigBee_MASK, + + /* XCVR_MISC configs */ + .xcvr_ctrl.mask = XCVR_CTRL_XCVR_CTRL_PROTOCOL_MASK | + XCVR_CTRL_XCVR_CTRL_TGT_PWR_SRC_MASK | + XCVR_CTRL_XCVR_CTRL_DEMOD_SEL_MASK, + .xcvr_ctrl.init = XCVR_CTRL_XCVR_CTRL_PROTOCOL(4) | + XCVR_CTRL_XCVR_CTRL_TGT_PWR_SRC(7) | + XCVR_CTRL_XCVR_CTRL_DEMOD_SEL(2), + + /* XCVR_PHY configs */ + .phy_pre_ref0_init = 0x0, /* Not used in Zigbee */ + .phy_pre_ref1_init = 0x0, /* Not used in Zigbee */ + .phy_pre_ref2_init = 0x0, /* Not used in Zigbee */ + + .phy_cfg1_init = XCVR_PHY_CFG1_AA_PLAYBACK(0) | + XCVR_PHY_CFG1_AA_OUTPUT_SEL(1) | + XCVR_PHY_CFG1_FSK_BIT_INVERT(0) | + XCVR_PHY_CFG1_BSM_EN_BLE(0) | + XCVR_PHY_CFG1_DEMOD_CLK_MODE(0) | + XCVR_PHY_CFG1_CTS_THRESH(0xC0) | + XCVR_PHY_CFG1_FSK_FTS_TIMEOUT(2), + + .phy_el_cfg_init = XCVR_PHY_EL_CFG_EL_ENABLE(1) +#if !RADIO_IS_GEN_2P1 + | XCVR_PHY_EL_CFG_EL_ZB_ENABLE(0) +#endif /* !RADIO_IS_GEN_2P1 */ + , + + /* XCVR_PLL_DIG configs */ + + /* XCVR_RX_DIG configs */ + .rx_dig_ctrl_init_26mhz = XCVR_RX_DIG_RX_DIG_CTRL_RX_FSK_ZB_SEL(1) | /* Depends on protocol */ + XCVR_RX_DIG_RX_DIG_CTRL_RX_DC_RESID_EN(1) | /* Depends on protocol */ + XCVR_RX_DIG_RX_DIG_CTRL_RX_SRC_RATE(0), + + .rx_dig_ctrl_init_32mhz = XCVR_RX_DIG_RX_DIG_CTRL_RX_FSK_ZB_SEL(1) | /* Depends on protocol */ + XCVR_RX_DIG_RX_DIG_CTRL_RX_DC_RESID_EN(1), /* Depends on protocol */ + + .agc_ctrl_0_init = XCVR_RX_DIG_AGC_CTRL_0_AGC_DOWN_RSSI_THRESH(0xFF), + /* XCVR_TSM configs */ +#if (DATA_PADDING_EN) + .tsm_timing_35_init = B0(TX_DIG_EN_ASSERT+ZGBE_TX_DIG_EN_TX_HI_ADJ), /* DATA_PADDING adjustments are specified relative to the non-Zigbee base timing */ +#else + .tsm_timing_35_init = B0(ZGBE_TX_DIG_EN_ASSERT), +#endif /* (DATA_PADDING_EN) */ + + /* XCVR_TX_DIG configs */ + .tx_gfsk_ctrl = XCVR_TX_DIG_GFSK_CTRL_GFSK_MULTIPLY_TABLE_MANUAL(0x4000) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_MI(1) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_MLD(0) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_FLD(0) | + XCVR_TX_DIG_GFSK_CTRL_GFSK_MOD_INDEX_SCALING(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_OVRD_EN(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_0_OVRD(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_1_OVRD(0) | + XCVR_TX_DIG_GFSK_CTRL_TX_IMAGE_FILTER_2_OVRD(0) , + .tx_gfsk_coeff1_26mhz = 0, + .tx_gfsk_coeff2_26mhz = 0, + .tx_gfsk_coeff1_32mhz = 0, + .tx_gfsk_coeff2_32mhz = 0, +}; + +const xcvr_mode_datarate_config_t xcvr_ZIGBEE_500kbps_config = +{ + .radio_mode = ZIGBEE_MODE, + .data_rate = DR_500KBPS, + + .ana_sy_ctrl2.mask = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM_MASK, + .ana_sy_ctrl2.init = XCVR_ANALOG_SY_CTRL_2_SY_VCO_KVM(1), /* VCO KVM */ + + .ana_rx_bba.mask = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL_MASK | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL_MASK, + .ana_rx_bba.init = XCVR_ANALOG_RX_BBA_RX_BBA_BW_SEL(1) | XCVR_ANALOG_RX_BBA_RX_BBA2_BW_SEL(1), /* BBA_BW_SEL and BBA2_BW_SEL */ + .ana_rx_tza.mask = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL_MASK, + .ana_rx_tza.init = XCVR_ANALOG_RX_TZA_RX_TZA_BW_SEL(1), /*TZA_BW_SEL */ + + .phy_cfg2_init = XCVR_PHY_CFG2_PHY_FIFO_PRECHG(8) | + XCVR_PHY_CFG2_X2_DEMOD_GAIN(0xA) , + + /* AGC configs */ + .agc_ctrl_2_init_26mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(8) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(5) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + .agc_ctrl_2_init_32mhz = XCVR_RX_DIG_AGC_CTRL_2_BBA_GAIN_SETTLE_TIME(10) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_LO(5) | + XCVR_RX_DIG_AGC_CTRL_2_BBA_PDET_SEL_HI(6) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_LO(3) | + XCVR_RX_DIG_AGC_CTRL_2_TZA_PDET_SEL_HI(5) | + XCVR_RX_DIG_AGC_CTRL_2_AGC_FAST_EXPIRE(5), + + /* All constant values are represented as 16 bits, register writes will remove unused bits */ + .rx_chf_coeffs_26mhz.rx_chf_coef_0 = 0xFFFF, + .rx_chf_coeffs_26mhz.rx_chf_coef_1 = 0xFFFF, + .rx_chf_coeffs_26mhz.rx_chf_coef_2 = 0x0002, + .rx_chf_coeffs_26mhz.rx_chf_coef_3 = 0x0008, + .rx_chf_coeffs_26mhz.rx_chf_coef_4 = 0x000A, + .rx_chf_coeffs_26mhz.rx_chf_coef_5 = 0x0000, + .rx_chf_coeffs_26mhz.rx_chf_coef_6 = 0xFFE8, + .rx_chf_coeffs_26mhz.rx_chf_coef_7 = 0xFFD7, + .rx_chf_coeffs_26mhz.rx_chf_coef_8 = 0xFFE6, + .rx_chf_coeffs_26mhz.rx_chf_coef_9 = 0x0022, + .rx_chf_coeffs_26mhz.rx_chf_coef_10 = 0x0075, + .rx_chf_coeffs_26mhz.rx_chf_coef_11 = 0x00B2, + + /* IEEE 802.15.4 32MHz Channel Filter -- 1.55/1.25/5/0.97/B5 */ + .rx_chf_coeffs_32mhz.rx_chf_coef_0 = 0xFFFF, + .rx_chf_coeffs_32mhz.rx_chf_coef_1 = 0xFFFF, + .rx_chf_coeffs_32mhz.rx_chf_coef_2 = 0x0005, + .rx_chf_coeffs_32mhz.rx_chf_coef_3 = 0x0004, + .rx_chf_coeffs_32mhz.rx_chf_coef_4 = 0xFFF2, + .rx_chf_coeffs_32mhz.rx_chf_coef_5 = 0xFFF2, + .rx_chf_coeffs_32mhz.rx_chf_coef_6 = 0x001D, + .rx_chf_coeffs_32mhz.rx_chf_coef_7 = 0x0025, + .rx_chf_coeffs_32mhz.rx_chf_coef_8 = 0xFFCE, + .rx_chf_coeffs_32mhz.rx_chf_coef_9 = 0xFFA1, + .rx_chf_coeffs_32mhz.rx_chf_coef_10 = 0x0040, + .rx_chf_coeffs_32mhz.rx_chf_coef_11 = 0x0124, + + .rx_rccal_ctrl_0 = XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_BBA_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_SMP_DLY(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_RCCAL_COMP_INV(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL0_TZA_RCCAL_DIS(0) , + .rx_rccal_ctrl_1 = XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_ADC_RCCAL_DIS(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_OFFSET(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_MANUAL(0) | + XCVR_RX_DIG_RX_RCCAL_CTRL1_BBA2_RCCAL_DIS(0) , + + .tx_fsk_scale_26mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1627) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x09d9), + .tx_fsk_scale_32mhz = XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_0(0x1800) | XCVR_TX_DIG_FSK_SCALE_FSK_MODULATION_SCALE_1(0x0800), +}; + +/* CUSTOM datarate dependent config structure for ONLY 802.15.4 */ +/*! + * @brief XCVR 500K bps DATA RATE specific configure structure + */ +const xcvr_datarate_config_t xcvr_802_15_4_500kbps_config = +{ + .data_rate = DR_500KBPS, + .phy_el_cfg_init = XCVR_PHY_EL_CFG_EL_ZB_WIN_SIZE(0) | + XCVR_PHY_EL_CFG_EL_WIN_SIZE(0x8) | + XCVR_PHY_EL_CFG_EL_INTERVAL(0x10) , + .rx_dig_ctrl_init_26mhz = XCVR_RX_DIG_RX_DIG_CTRL_RX_DEC_FILT_OSR(1) | + XCVR_RX_DIG_RX_DIG_CTRL_RX_DEC_FILT_GAIN(16), + .rx_dig_ctrl_init_32mhz = XCVR_RX_DIG_RX_DIG_CTRL_RX_DEC_FILT_OSR(2) | + XCVR_RX_DIG_RX_DIG_CTRL_RX_DEC_FILT_GAIN(16), + + .agc_ctrl_1_init_26mhz = XCVR_RX_DIG_AGC_CTRL_1_LNA_GAIN_SETTLE_TIME(13) | + XCVR_RX_DIG_AGC_CTRL_1_PRESLOW_EN(PRESLOW_ENA), + .agc_ctrl_1_init_32mhz = XCVR_RX_DIG_AGC_CTRL_1_LNA_GAIN_SETTLE_TIME(10) | + XCVR_RX_DIG_AGC_CTRL_1_PRESLOW_EN(PRESLOW_ENA), + + .dcoc_ctrl_0_init_26mhz = XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CORR_DLY(13) | + XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CORR_HOLD_TIME(29), + .dcoc_ctrl_0_init_32mhz = XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CORR_DLY(21) | + XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CORR_HOLD_TIME(47), + + .dcoc_ctrl_1_init_26mhz = XCVR_RX_DIG_DCOC_CTRL_1_DCOC_SIGN_SCALE_IDX(1) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_ALPHAC_SCALE_IDX(3) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_ALPHA_RADIUS_IDX(2) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_TRK_EST_GS_CNT(0) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_SIGN_SCALE_GS_IDX(1) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_ALPHAC_SCALE_GS_IDX(3) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_ALPHA_RADIUS_GS_IDX(2), + + .dcoc_ctrl_1_init_32mhz = XCVR_RX_DIG_DCOC_CTRL_1_DCOC_SIGN_SCALE_IDX(1) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_ALPHAC_SCALE_IDX(3) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_ALPHA_RADIUS_IDX(2) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_TRK_EST_GS_CNT(0) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_SIGN_SCALE_GS_IDX(1) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_ALPHAC_SCALE_GS_IDX(3) | + XCVR_RX_DIG_DCOC_CTRL_1_DCOC_ALPHA_RADIUS_GS_IDX(2), + + .dcoc_cal_iir_init_26mhz = XCVR_RX_DIG_DCOC_CAL_IIR_DCOC_CAL_IIR3A_IDX(2) | + XCVR_RX_DIG_DCOC_CAL_IIR_DCOC_CAL_IIR2A_IDX(2) | + XCVR_RX_DIG_DCOC_CAL_IIR_DCOC_CAL_IIR1A_IDX(2), + .dcoc_cal_iir_init_32mhz = XCVR_RX_DIG_DCOC_CAL_IIR_DCOC_CAL_IIR3A_IDX(1) | + XCVR_RX_DIG_DCOC_CAL_IIR_DCOC_CAL_IIR2A_IDX(2) | + XCVR_RX_DIG_DCOC_CAL_IIR_DCOC_CAL_IIR1A_IDX(1), + + .dc_resid_ctrl_26mhz = XCVR_RX_DIG_DC_RESID_CTRL_DC_RESID_NWIN(26) | + XCVR_RX_DIG_DC_RESID_CTRL_DC_RESID_DLY(4), + .dc_resid_ctrl_32mhz = XCVR_RX_DIG_DC_RESID_CTRL_DC_RESID_NWIN(48) | + XCVR_RX_DIG_DC_RESID_CTRL_DC_RESID_DLY(0), +}; + diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/dbg_ram_capture.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/dbg_ram_capture.c new file mode 100644 index 0000000000..b119a82d4e --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/dbg_ram_capture.c @@ -0,0 +1,160 @@ +/* + * 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 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_device_registers.h" +#include "fsl_xcvr.h" +#include "dbg_ram_capture.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#if RADIO_IS_GEN_3P0 +#define PKT_RAM_SIZE_16B_WORDS (1152) /* Number of 16bit entries in each Packet RAM bank */ +#else +#define PKT_RAM_SIZE_16B_WORDS (544) /* Number of 16bit entries in each Packet RAM bank */ +#endif /* RADIO_IS_GEN_3P0 */ +#define SIGN_EXTND_12_16(x) ((x) | (((x) & 0x800) ? 0xF000 : 0x0)) +#define SIGN_EXTND_5_8(x) ((x) | (((x) & 0x10) ? 0xE0 : 0x0)) + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ +void dbg_ram_init(void) +{ + XCVR_RX_DIG->RX_DIG_CTRL |= XCVR_RX_DIG_RX_DIG_CTRL_RX_DMA_DTEST_EN_MASK; /* Turns on clocking to DMA/DBG blocks */ + XCVR_MISC->PACKET_RAM_CTRL |= XCVR_CTRL_PACKET_RAM_CTRL_XCVR_RAM_ALLOW_MASK; /* Make PKT RAM available to just XCVR */ + + /* Some external code must perform the RX warmup request. */ +} + + +dbgRamStatus_t dbg_ram_capture(uint8_t dbg_page, uint16_t buffer_sz_bytes, void * result_buffer) +{ + dbgRamStatus_t status = DBG_RAM_SUCCESS; + uint32_t temp; + volatile uint8_t *pkt_ram_ptr0, *pkt_ram_ptr1; + uint8_t * output_ptr; + uint16_t i; + + /* Some external code must perform the RX warmup request after the dbg_ram_init() call */ + + if (result_buffer == NULL) + { + status = DBG_RAM_FAIL_NULL_POINTER; + } + else + { + if (buffer_sz_bytes > (544*2*2)) + { + status = DBG_RAM_FAIL_SAMPLE_NUM_LIMIT; + } + else + { + temp = XCVR_MISC->PACKET_RAM_CTRL & ~XCVR_CTRL_PACKET_RAM_CTRL_DBG_PAGE_MASK; + switch (dbg_page) + { + case DBG_PAGE_RXDIGIQ: + case DBG_PAGE_RAWADCIQ: + case DBG_PAGE_DCESTIQ: + XCVR_MISC->PACKET_RAM_CTRL = temp | XCVR_CTRL_PACKET_RAM_CTRL_DBG_PAGE(dbg_page); + + while (!(XCVR_MISC->PACKET_RAM_CTRL & XCVR_CTRL_PACKET_RAM_CTRL_DBG_RAM_FULL(2))) + { + /* Waiting for PKT_RAM to fill, wait for PKT_RAM_1 full to ensure complete memory is filled. */ + } + /* Copy to output by bytes to avoid any access size problems in 16 bit packet RAM. */ + output_ptr = result_buffer; +#if !RADIO_IS_GEN_2P1 + pkt_ram_ptr0 = (volatile uint8_t *)&(XCVR_PKT_RAM->PACKET_RAM_0[0]); + pkt_ram_ptr1 = (volatile uint8_t *)&(XCVR_PKT_RAM->PACKET_RAM_1[0]); +#else + pkt_ram_ptr0 = (volatile uint8_t *)&(XCVR_PKT_RAM->PACKET_RAM[0]); + pkt_ram_ptr1 = (volatile uint8_t *)&(XCVR_PKT_RAM->PACKET_RAM[XCVR_PKT_RAM_PACKET_RAM_COUNT>>1]); /* Second packet RAM starts halfway through */ +#endif /* !RADIO_IS_GEN_2P1 */ + /* For *IQ pages I and Q are stored alternately in packet ram 0 & 1 */ + for (i = 0; i < buffer_sz_bytes / 4; i++) + { + *output_ptr++ = *pkt_ram_ptr0++; + *output_ptr++ = *pkt_ram_ptr0++; + *output_ptr++ = *pkt_ram_ptr1++; + *output_ptr++ = *pkt_ram_ptr1++; + } + + break; + case DBG_PAGE_RXINPH: + case DBG_PAGE_DEMOD_HARD: + case DBG_PAGE_DEMOD_SOFT: + case DBG_PAGE_DEMOD_DATA: + case DBG_PAGE_DEMOD_CFO_PH: + XCVR_MISC->PACKET_RAM_CTRL = temp | XCVR_CTRL_PACKET_RAM_CTRL_DBG_PAGE(dbg_page); + while (!(XCVR_MISC->PACKET_RAM_CTRL & XCVR_CTRL_PACKET_RAM_CTRL_DBG_RAM_FULL(2))) + { + /* Waiting for PKT_RAM to fill, wait for PKT_RAM_1 full to ensure complete memory is filled. */ + } + /* Copy to output by bytes to avoid any access size problems in 16 bit packet RAM. */ + output_ptr = result_buffer; +#if !RADIO_IS_GEN_2P1 + pkt_ram_ptr0 = (volatile uint8_t *)&(XCVR_PKT_RAM->PACKET_RAM_0[0]); +#else + pkt_ram_ptr0 = (volatile uint8_t *)&(XCVR_PKT_RAM->PACKET_RAM[0]); +#endif /* !RADIO_IS_GEN_2P1 */ + /* This is for non I/Q */ + for (i = 0; i < buffer_sz_bytes; i++) + { + *output_ptr = *pkt_ram_ptr0; + pkt_ram_ptr0++; + output_ptr++; + } + break; + case DBG_PAGE_IDLE: + default: + status = DBG_RAM_FAIL_PAGE_ERROR; /* Illegal capture page request. */ + break; + } + } + } + + XCVR_MISC->PACKET_RAM_CTRL &= ~XCVR_CTRL_PACKET_RAM_CTRL_DBG_PAGE_MASK; /* Clear DBG_PAGE to terminate the acquisition */ + + /* Process the samples and copy to output pointer */ + + XCVR_MISC->PACKET_RAM_CTRL &= ~XCVR_CTRL_PACKET_RAM_CTRL_XCVR_RAM_ALLOW_MASK; /* Make PKT RAM available to protocol blocks */ + XCVR_RX_DIG->RX_DIG_CTRL &= ~XCVR_RX_DIG_RX_DIG_CTRL_RX_DMA_DTEST_EN_MASK; /* Turns off clocking to DMA/DBG blocks */ + + return status; +} + diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/dbg_ram_capture.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/dbg_ram_capture.h new file mode 100644 index 0000000000..fabba7dae9 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/dbg_ram_capture.h @@ -0,0 +1,206 @@ +/* + * 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 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 _DBG_RAM_CAPTURE_H_ +/* clang-format off */ +#define _DBG_RAM_CAPTURE_H_ +/* clang-format on */ + +#include "fsl_common.h" +#include "fsl_device_registers.h" + +/*! + * @addtogroup xcvr + * @{ + */ + +/*! @file*/ + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/* Page definitions */ +#define DBG_PAGE_IDLE (0x00) +#define DBG_PAGE_RXDIGIQ (0x01) +#define DBG_PAGE_RAWADCIQ (0x04) +#define DBG_PAGE_DCESTIQ (0x07) +#define DBG_PAGE_RXINPH (0x0A) +#define DBG_PAGE_DEMOD_HARD (0x0B) +#define DBG_PAGE_DEMOD_SOFT (0x0C) +#define DBG_PAGE_DEMOD_DATA (0x0D) +#define DBG_PAGE_DEMOD_CFO_PH (0x0E) + +typedef enum _dbgRamStatus +{ + DBG_RAM_SUCCESS = 0, + DBG_RAM_FAIL_SAMPLE_NUM_LIMIT = 1, + DBG_RAM_FAIL_PAGE_ERROR = 2, + DBG_RAM_FAIL_NULL_POINTER = 3, + DBG_RAM_INVALID_TRIG_SETTING = 4, + DBG_RAM_FAIL_NOT_ENOUGH_SAMPLES = 5, + DBG_RAM_CAPTURE_NOT_COMPLETE = 6, /* Not an error response, but an indication that capture isn't complete for status polling */ +} dbgRamStatus_t; + +#if RADIO_IS_GEN_3P0 +typedef enum _dbgRamStartTriggerType +{ + NO_START_TRIG = 0, + START_ON_FSK_PREAMBLE_FOUND = 1, + START_ON_FSK_AA_MATCH = 2, + START_ON_ZBDEMOD_PREAMBLE_FOUND = 3, + START_ON_ZBDEMOD_SFD_MATCH = 4, + START_ON_AGC_DCOC_GAIN_CHG = 5, + START_ON_TSM_RX_DIG_EN = 6, + START_ON_TSM_SPARE2_EN = 7, + INVALID_START_TRIG = 8 +} dbgRamStartTriggerType; + +typedef enum _dbgRamStopTriggerType +{ + NO_STOP_TRIG = 0, + STOP_ON_FSK_PREAMBLE_FOUND = 1, + STOP_ON_FSK_AA_MATCH = 2, + STOP_ON_ZBDEMOD_PREAMBLE_FOUND = 3, + STOP_ON_ZBDEMOD_SFD_MATCH = 4, + STOP_ON_AGC_DCOC_GAIN_CHG = 5, + STOP_ON_TSM_RX_DIG_EN = 6, + STOP_ON_TSM_SPARE3_EN = 7, + STOP_ON_TSM_PLL_UNLOCK = 8, + STOP_ON_BLE_CRC_ERROR_INC = 9, + STOP_ON_CRC_FAIL_ZGBE_GENFSK = 10, + STOP_ON_GENFSK_HEADER_FAIL = 11, + INVALID_STOP_TRIG = 12 +} dbgRamStopTriggerType; +#endif /* RADIO_IS_GEN_3P0 */ + +/*! ********************************************************************************* + * \brief This function prepares for sample capture to packet RAM. + * + * \return None. + * + * \details + * This routine assumes that some other functions in the calling routine both set + * the channel and force RX warmup before calling ::dbg_ram_capture(). + ***********************************************************************************/ +void dbg_ram_init(void); + +/*! ********************************************************************************* + * \brief This function performs any state restoration at the completion of PKT RAM capture. + * + * \details + * Any clocks enabled to the packet RAM capture circuitry are disabled. + ***********************************************************************************/ +void dbg_ram_release(void); + +#if RADIO_IS_GEN_3P0 +/*! ********************************************************************************* + * \brief This function initiates the capture of transceiver data to the transceiver packet RAM. + * + * \param[in] dbg_page - The page selector (DBG_PAGE). + * \param[in] dbg_start_trigger - The trigger to start acquisition (must be "no trigger" if a stop trigger is enabled). + * \param[in] dbg_stop_trigger - The trigger to stop acquisition (must be "no trigger" if a start trigger is enabled). + * + * \return Status of the request. + * + * \details + * This function starts the process of capturing data to the packet RAM. Depending upon the start and stop trigger + * settings, the actual capture process can take an indeterminate amount of time. Other APIs are provided to + * perform a blocking wait for completion or allow polling for completion of the capture. + * After any capture has completed, a separate routine must be called to postprocess the capture and copy all + * data out of the packet RAM into a normal RAM buffer. + ***********************************************************************************/ +dbgRamStatus_t dbg_ram_start_capture(uint8_t dbg_page, dbgRamStartTriggerType start_trig, dbgRamStopTriggerType stop_trig); + +/*! ********************************************************************************* + * \brief This function performs a blocking wait for completion of the capture of transceiver data to the transceiver packet RAM. + * + * \return Status of the request, DBG_RAM_SUCCESS if capture is complete. + * + * \details + * This function performs a wait loop for capture completion and may take an indeterminate amount of time for + * some capture trigger types. + ***********************************************************************************/ +dbgRamStatus_t dbg_ram_wait_for_complete(void); /* Blocking wait for capture completion, no matter what trigger type */ + +/*! ********************************************************************************* + * \brief This function polls the state of the capture of transceiver data to the transceiver packet RAM. + * + * \return Status of the request, DBG_RAM_SUCCESS if capture is complete, DBG_RAM_CAPTURE_NOT_COMPLETE if not complete. + * + ***********************************************************************************/ +dbgRamStatus_t dbg_ram_poll_capture_status(void); /* Non-blocking completion check, just reads the current status of the capure */ + +/*! ********************************************************************************* + * \brief This function processes the captured data into a usable order and copies from packet RAM to normal RAM. + * + * \param[in] dbg_page - The page selector (DBG_PAGE). + * \param[in] buffer_sz_bytes - The size of the output buffer (in bytes) + * \param[in] result_buffer - The pointer to the output buffer of a size large enough for the samples. + * + * \return None. + * + * \details + * Data is copied from packet RAM in bytes to ensure no access problems. Data is unpacked from packet RAM + * (either sequentially captured or simultaneously captured) into a linear RAM buffer in system RAM. + * If a start trigger is enabled then the first buffer_sz_bytes that are captured are copied out. + * If a stop trigger is enabled then the last buffer_sz_bytes that are captured are copied out. + ***********************************************************************************/ +dbgRamStatus_t dbg_ram_postproc_capture(uint8_t dbg_page, uint16_t buffer_sz_bytes, void * result_buffer); /* postprocess a capture to unpack data */ + +#else +/*! ********************************************************************************* + * \brief This function captures transceiver data to the transceiver packet RAM. + * + * \param[in] dbg_page - The page selector (DBG_PAGE). + * \param[in] buffer_sz_bytes - The size of the output buffer (in bytes) + * \param[in] result_buffer - The pointer to the output buffer of a size large enough for the samples. + * + * \return None. + * + * \details + * The capture to packet RAM always captures a full PKT_RAM worth of samples. The samples will be + * copied to the buffer pointed to by result_buffer parameter until buffer_sz_bytes worth of data have + * been copied. Data will be copied + * NOTE: This routine has a slight hazard of getting stuck waiting for debug RAM to fill up when RX has + * not been enabled or RX ends before the RAM fills up (such as when capturing packet data ). It is + * intended to be used with manually triggered RX where RX data will continue as long as needed. + ***********************************************************************************/ +dbgRamStatus_t dbg_ram_capture(uint8_t dbg_page, uint16_t buffer_sz_bytes, void * result_buffer); +#endif /* RADIO_IS_GEN_3P0 */ + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _DBG_RAM_CAPTURE_H_ */ + diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/fsl_xcvr.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/fsl_xcvr.c new file mode 100644 index 0000000000..e1b9dcf552 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/fsl_xcvr.c @@ -0,0 +1,2123 @@ +/* + * 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 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 "EmbeddedTypes.h" +#include "fsl_device_registers.h" +#include "fsl_common.h" +#include "fsl_xcvr.h" +#include "fsl_xcvr_trim.h" +#include +#include "ifr_radio.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define channelMapTableSize (128U) +#define gPllDenom_c 0x02000000U /* Denominator is a constant value */ +#define ABS(x) ((x) > 0 ? (x) : -(x)) + +#ifndef TRUE +#define TRUE (true) +#endif + +#ifndef FALSE +#define FALSE (false) +#endif +#define RF_OSCILLATOR_STAYS_ON (false) /* Control whether RF_OSC can be left on all the time. */ +#define RF_OSCILLATOR_READY ((RSIM->CONTROL & RSIM_CONTROL_RF_OSC_READY_MASK) != 0x0U) + +#ifndef EXTERNAL_CLOCK_GEN +#define EXTERNAL_CLOCK_GEN 0 +#endif + +#define ANT_A 1 +#define ANT_B 0 + +#ifndef XCVR_COEX_RF_ACTIVE_PIN +#define XCVR_COEX_RF_ACTIVE_PIN ANT_B +#endif /* XCVR_COEX_RF_ACTIVE_PIN */ + +typedef struct xcvr_pllChannel_tag +{ + unsigned int integer; + unsigned int numerator; +} xcvr_pllChannel_t; + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +void XcvrPanic(XCVR_PANIC_ID_T panic_id, uint32_t panic_address); +void rf_osc_startup(void); +void rf_osc_shutdown(void); +extern double trunc (double); +extern double round (double); + +/******************************************************************************* + * Variables + ******************************************************************************/ +static panic_fptr s_PanicFunctionPtr = NULL; +const xcvr_pllChannel_t mapTable [channelMapTableSize] = +{ + {0x00000025, 0x07C00000}, /* 0 */ + {0x00000025, 0x07C80000}, /* 1 */ + {0x00000025, 0x07D00000}, /* 2 */ + {0x00000025, 0x07D80000}, /* 3 */ + {0x00000025, 0x07E00000}, /* 4 */ + {0x00000025, 0x07E80000}, /* 5 */ + {0x00000025, 0x07F00000}, /* 6 */ + {0x00000025, 0x07F80000}, /* 7 */ + {0x00000025, 0x00000000}, /* 8 */ + {0x00000025, 0x00080000}, /* 9 */ + {0x00000025, 0x00100000}, /* 10 */ + {0x00000025, 0x00180000}, /* 11 */ + {0x00000025, 0x00200000}, /* 12 */ + {0x00000025, 0x00280000}, /* 13 */ + {0x00000025, 0x00300000}, /* 14 */ + {0x00000025, 0x00380000}, /* 15 */ + {0x00000025, 0x00400000}, /* 16 */ + {0x00000025, 0x00480000}, /* 17 */ + {0x00000025, 0x00500000}, /* 18 */ + {0x00000025, 0x00580000}, /* 19 */ + {0x00000025, 0x00600000}, /* 20 */ + {0x00000025, 0x00680000}, /* 21 */ + {0x00000025, 0x00700000}, /* 22 */ + {0x00000025, 0x00780000}, /* 23 */ + {0x00000025, 0x00800000}, /* 24 */ + {0x00000025, 0x00880000}, /* 25 */ + {0x00000025, 0x00900000}, /* 26 */ + {0x00000025, 0x00980000}, /* 27 */ + {0x00000025, 0x00A00000}, /* 28 */ + {0x00000025, 0x00A80000}, /* 29 */ + {0x00000025, 0x00B00000}, /* 30 */ + {0x00000025, 0x00B80000}, /* 31 */ + {0x00000025, 0x00C00000}, /* 32 */ + {0x00000025, 0x00C80000}, /* 33 */ + {0x00000025, 0x00D00000}, /* 34 */ + {0x00000025, 0x00D80000}, /* 35 */ + {0x00000025, 0x00E00000}, /* 36 */ + {0x00000025, 0x00E80000}, /* 37 */ + {0x00000025, 0x00F00000}, /* 38 */ + {0x00000025, 0x00F80000}, /* 39 */ + {0x00000025, 0x01000000}, /* 40 */ + {0x00000026, 0x07080000}, /* 41 */ + {0x00000026, 0x07100000}, /* 42 */ + {0x00000026, 0x07180000}, /* 43 */ + {0x00000026, 0x07200000}, /* 44 */ + {0x00000026, 0x07280000}, /* 45 */ + {0x00000026, 0x07300000}, /* 46 */ + {0x00000026, 0x07380000}, /* 47 */ + {0x00000026, 0x07400000}, /* 48 */ + {0x00000026, 0x07480000}, /* 49 */ + {0x00000026, 0x07500000}, /* 50 */ + {0x00000026, 0x07580000}, /* 51 */ + {0x00000026, 0x07600000}, /* 52 */ + {0x00000026, 0x07680000}, /* 53 */ + {0x00000026, 0x07700000}, /* 54 */ + {0x00000026, 0x07780000}, /* 55 */ + {0x00000026, 0x07800000}, /* 56 */ + {0x00000026, 0x07880000}, /* 57 */ + {0x00000026, 0x07900000}, /* 58 */ + {0x00000026, 0x07980000}, /* 59 */ + {0x00000026, 0x07A00000}, /* 60 */ + {0x00000026, 0x07A80000}, /* 61 */ + {0x00000026, 0x07B00000}, /* 62 */ + {0x00000026, 0x07B80000}, /* 63 */ + {0x00000026, 0x07C00000}, /* 64 */ + {0x00000026, 0x07C80000}, /* 65 */ + {0x00000026, 0x07D00000}, /* 66 */ + {0x00000026, 0x07D80000}, /* 67 */ + {0x00000026, 0x07E00000}, /* 68 */ + {0x00000026, 0x07E80000}, /* 69 */ + {0x00000026, 0x07F00000}, /* 70 */ + {0x00000026, 0x07F80000}, /* 71 */ + {0x00000026, 0x00000000}, /* 72 */ + {0x00000026, 0x00080000}, /* 73 */ + {0x00000026, 0x00100000}, /* 74 */ + {0x00000026, 0x00180000}, /* 75 */ + {0x00000026, 0x00200000}, /* 76 */ + {0x00000026, 0x00280000}, /* 77 */ + {0x00000026, 0x00300000}, /* 78 */ + {0x00000026, 0x00380000}, /* 79 */ + {0x00000026, 0x00400000}, /* 80 */ + {0x00000026, 0x00480000}, /* 81 */ + {0x00000026, 0x00500000}, /* 82 */ + {0x00000026, 0x00580000}, /* 83 */ + {0x00000026, 0x00600000}, /* 84 */ + {0x00000026, 0x00680000}, /* 85 */ + {0x00000026, 0x00700000}, /* 86 */ + {0x00000026, 0x00780000}, /* 87 */ + {0x00000026, 0x00800000}, /* 88 */ + {0x00000026, 0x00880000}, /* 89 */ + {0x00000026, 0x00900000}, /* 90 */ + {0x00000026, 0x00980000}, /* 91 */ + {0x00000026, 0x00A00000}, /* 92 */ + {0x00000026, 0x00A80000}, /* 93 */ + {0x00000026, 0x00B00000}, /* 94 */ + {0x00000026, 0x00B80000}, /* 95 */ + {0x00000026, 0x00C00000}, /* 96 */ + {0x00000026, 0x00C80000}, /* 97 */ + {0x00000026, 0x00D00000}, /* 98 */ + {0x00000026, 0x00D80000}, /* 99 */ + {0x00000026, 0x00E00000}, /* 100 */ + {0x00000026, 0x00E80000}, /* 101 */ + {0x00000026, 0x00F00000}, /* 102 */ + {0x00000026, 0x00F80000}, /* 103 */ + {0x00000026, 0x01000000}, /* 104 */ + {0x00000027, 0x07080000}, /* 105 */ + {0x00000027, 0x07100000}, /* 106 */ + {0x00000027, 0x07180000}, /* 107 */ + {0x00000027, 0x07200000}, /* 108 */ + {0x00000027, 0x07280000}, /* 109 */ + {0x00000027, 0x07300000}, /* 110 */ + {0x00000027, 0x07380000}, /* 111 */ + {0x00000027, 0x07400000}, /* 112 */ + {0x00000027, 0x07480000}, /* 113 */ + {0x00000027, 0x07500000}, /* 114 */ + {0x00000027, 0x07580000}, /* 115 */ + {0x00000027, 0x07600000}, /* 116 */ + {0x00000027, 0x07680000}, /* 117 */ + {0x00000027, 0x07700000}, /* 118 */ + {0x00000027, 0x07780000}, /* 119 */ + {0x00000027, 0x07800000}, /* 120 */ + {0x00000027, 0x07880000}, /* 121 */ + {0x00000027, 0x07900000}, /* 122 */ + {0x00000027, 0x07980000}, /* 123 */ + {0x00000027, 0x07A00000}, /* 124 */ + {0x00000027, 0x07A80000}, /* 125 */ + {0x00000027, 0x07B00000}, /* 126 */ + {0x00000027, 0x07B80000} /* 127 */ +}; + +/* Registers for timing of TX & RX */ +#if RADIO_IS_GEN_3P0 +uint16_t tx_rx_on_delay = TX_RX_ON_DELinit; +uint16_t tx_rx_synth_delay = TX_RX_SYNTH_init; +#else +#if RF_OSC_26MHZ == 1 +uint16_t tx_rx_on_delay = TX_RX_ON_DELAY_VAL_26MHZ; +#else +uint16_t tx_rx_on_delay = TX_RX_ON_DELAY_VAL; +#endif /* RF_OSC_26MHZ == 1 */ +uint16_t tx_rx_synth_delay = TX_RX_SYNTH_DELAY_VAL; +#endif /* RADIO_IS_GEN_3P0 */ + +/* NOTE: These arrays MUST be ordered in the same order as the radio_mode_t enumeration. */ +#if RADIO_IS_GEN_3P0 +const xcvr_mode_datarate_config_t * mode_configs_dr_2mbps[NUM_RADIO_MODES] = +{ + (xcvr_mode_datarate_config_t *)NULL, /* 2Mbps rate not supported for this mode */ + (xcvr_mode_datarate_config_t *)NULL, /* 2Mbps rate not supported for this mode */ + (xcvr_mode_datarate_config_t *)NULL, /* 2Mbps rate not supported for this mode */ + &xcvr_GFSK_BT_0p5_h_0p5_2mbps_config, + &xcvr_GFSK_BT_0p5_h_0p32_2mbps_config, + (xcvr_mode_datarate_config_t *)NULL, /* 2Mbps rate not supported for this mode */ + (xcvr_mode_datarate_config_t *)NULL, /* 2Mbps rate not supported for this mode */ + &xcvr_GFSK_BT_0p3_h_0p5_2mbps_config, + &xcvr_GFSK_BT_0p7_h_0p5_2mbps_config, + &xcvr_MSK_2mbps_config, +}; +#endif /* RADIO_IS_GEN_3P0 */ + +const xcvr_mode_datarate_config_t * mode_configs_dr_1mbps[NUM_RADIO_MODES] = +{ + &xcvr_BLE_1mbps_config, +#if RADIO_IS_GEN_2P1 + NULL, + NULL, +#else + &xcvr_ZIGBEE_500kbps_config, /* 802.15.4 only supports one configuration */ + &xcvr_ANT_1mbps_config, +#endif /* RADIO_IS_GEN_2P1 */ + &xcvr_GFSK_BT_0p5_h_0p5_1mbps_config, + &xcvr_GFSK_BT_0p5_h_0p32_1mbps_config, + &xcvr_GFSK_BT_0p5_h_0p7_1mbps_config, + &xcvr_GFSK_BT_0p5_h_1p0_1mbps_config, + &xcvr_GFSK_BT_0p3_h_0p5_1mbps_config, + &xcvr_GFSK_BT_0p7_h_0p5_1mbps_config, + &xcvr_MSK_1mbps_config, +}; + +const xcvr_mode_datarate_config_t * mode_configs_dr_500kbps[NUM_RADIO_MODES] = +{ + &xcvr_BLE_1mbps_config, /* Invalid option */ +#if RADIO_IS_GEN_2P1 + NULL, + NULL, +#else + &xcvr_ZIGBEE_500kbps_config, /* 802.15.4 setting */ + &xcvr_ANT_1mbps_config, /* Invalid option */ +#endif /* RADIO_IS_GEN_2P1 */ + &xcvr_GFSK_BT_0p5_h_0p5_500kbps_config, + &xcvr_GFSK_BT_0p5_h_0p32_500kbps_config, + &xcvr_GFSK_BT_0p5_h_0p7_500kbps_config, + &xcvr_GFSK_BT_0p5_h_1p0_500kbps_config, + &xcvr_GFSK_BT_0p3_h_0p5_500kbps_config, + &xcvr_GFSK_BT_0p7_h_0p5_500kbps_config, + &xcvr_MSK_500kbps_config, +}; +const xcvr_mode_datarate_config_t * mode_configs_dr_250kbps[NUM_RADIO_MODES] = +{ + &xcvr_BLE_1mbps_config, /* Invalid option */ +#if RADIO_IS_GEN_2P1 + NULL, + NULL, +#else + &xcvr_ZIGBEE_500kbps_config, /* 802.15.4 only supports one configuration */ + &xcvr_ANT_1mbps_config, /* Invalid option */ +#endif /* RADIO_IS_GEN_2P1 */ + &xcvr_GFSK_BT_0p5_h_0p5_250kbps_config, + &xcvr_GFSK_BT_0p5_h_0p32_250kbps_config, + &xcvr_GFSK_BT_0p5_h_0p7_250kbps_config, + &xcvr_GFSK_BT_0p5_h_1p0_250kbps_config, + &xcvr_GFSK_BT_0p3_h_0p5_250kbps_config, + &xcvr_GFSK_BT_0p7_h_0p5_250kbps_config, + &xcvr_MSK_250kbps_config, +}; + +static xcvr_currConfig_t current_xcvr_config; + +void rf_osc_startup(void) +{ + if (!RF_OSCILLATOR_READY) + { + RSIM->CONTROL |= RSIM_CONTROL_RF_OSC_EN_MASK; + } + while (!RF_OSCILLATOR_READY) + { + /* Wait for RF_OSC_READY to be asserted before continuing */ + } +} + +void rf_osc_shutdown(void) +{ + if (!RF_OSCILLATOR_STAYS_ON) + { + RSIM->CONTROL &= ~RSIM_CONTROL_RF_OSC_EN_MASK; + } +} + +/******************************************************************************* + * Code + ******************************************************************************/ +xcvrStatus_t XCVR_Init(radio_mode_t radio_mode, data_rate_t data_rate) +{ + const xcvr_mode_datarate_config_t * mode_datarate_config; + const xcvr_datarate_config_t * datarate_config ; + const xcvr_mode_config_t * radio_mode_cfg; + const xcvr_common_config_t * radio_common_config; + + xcvrStatus_t status; + + IFR_SW_TRIM_TBL_ENTRY_T sw_trim_tbl[] = + { + {TRIM_STATUS, 0, FALSE}, /*< Fetch the trim status word if available.*/ + {TRIM_VERSION, 0, FALSE} /*< Fetch the trim version number if available.*/ + }; + const uint8_t NUM_TRIM_TBL_ENTRIES = sizeof(sw_trim_tbl)/sizeof(IFR_SW_TRIM_TBL_ENTRY_T); + +#ifndef SIMULATION + +#if (EXTERNAL_CLOCK_GEN) + RSIM->RF_OSC_CTRL |= RSIM_RF_OSC_CTRL_RF_OSC_BYPASS_EN_MASK; /* Only when external clock is being used */ +#endif /* EXTERNAL_CLOCK_GEN */ + +#if RADIO_IS_GEN_2P0 + RSIM->RF_OSC_CTRL &= ~RSIM_RF_OSC_CTRL_RADIO_EXT_OSC_OVRD_MASK; /* Set EXT_OSC_OVRD value to zero */ + RSIM->RF_OSC_CTRL |= RSIM_RF_OSC_CTRL_RADIO_EXT_OSC_OVRD_EN_MASK; /* Enable over-ride with zero value */ +#endif /* RADIO_IS_GEN_2P0 */ + + /* Check that this is the proper radio version */ + { + uint8_t radio_id = ((RSIM->MISC & RSIM_MISC_RADIO_VERSION_MASK)>>RSIM_MISC_RADIO_VERSION_SHIFT); + + if ( +#if RADIO_IS_GEN_3P0 + (radio_id != 0x5) /* KW3 Gen3 */ +#elif RADIO_IS_GEN_2P1 + (radio_id != 0x5) /* KW35 Gen2.1 */ +#else + (radio_id != 0x3) && /* KW41/31/21 v1 */ + (radio_id != 0xB) /* KW41/31/21 v1.1 */ +#endif /* RADIO_IS_GEN_3P0 */ + ) + { + XcvrPanic(WRONG_RADIO_ID_DETECTED, (uint32_t)&XCVR_Init); + } + } + +#if RADIO_IS_GEN_3P0 + /* Assert Radio Run Request and wait for ack from SPM. */ + RSIM->POWER |= RSIM_POWER_RSIM_RUN_REQUEST_MASK; + while ((RSIM->POWER & RSIM_POWER_SPM_RUN_ACK_STAT_MASK) == 0) + { + } + RSIM->CONTROL |= RSIM_CONTROL_RSIM_CGC_XCVR_EN_MASK; + rf_osc_startup(); /* Start RF_OSC to allow radio registers access */ +#else + SIM->SCGC5 |= SIM_SCGC5_PHYDIG_MASK; + + /* Load IFR trim values */ + handle_ifr(&sw_trim_tbl[0], NUM_TRIM_TBL_ENTRIES); +#endif /* RADIO_IS_GEN_3P0 */ + +#endif /* ifndef SIMULATION */ + + /* Perform the desired XCVR initialization and configuration */ + status = XCVR_GetDefaultConfig(radio_mode, data_rate, + (const xcvr_common_config_t **)&radio_common_config, + (const xcvr_mode_config_t **)&radio_mode_cfg, + (const xcvr_mode_datarate_config_t **)&mode_datarate_config, + (const xcvr_datarate_config_t **)&datarate_config); + + if (status == gXcvrSuccess_c) + { + status = XCVR_Configure((const xcvr_common_config_t *)radio_common_config, + (const xcvr_mode_config_t *)radio_mode_cfg, + (const xcvr_mode_datarate_config_t *)mode_datarate_config, + (const xcvr_datarate_config_t *)datarate_config, 25, XCVR_FIRST_INIT); + current_xcvr_config.radio_mode = radio_mode; + current_xcvr_config.data_rate = data_rate; + } + + return status; +} + +void XCVR_Deinit(void) +{ +#if RADIO_IS_GEN_3P0 + rf_osc_shutdown(); + RSIM->POWER |= RSIM_POWER_RSIM_STOP_MODE_MASK; /* Set radio stop mode to RVLLS */ + RSIM->POWER &= ~RSIM_POWER_RSIM_RUN_REQUEST_MASK; /* Clear RUN request */ +#else + +#endif /* RADIO_IS_GEN_3P0 */ +} + +xcvrStatus_t XCVR_GetDefaultConfig(radio_mode_t radio_mode, + data_rate_t data_rate, + const xcvr_common_config_t ** com_config, + const xcvr_mode_config_t ** mode_config, + const xcvr_mode_datarate_config_t ** mode_datarate_config, + const xcvr_datarate_config_t ** datarate_config) +{ + xcvrStatus_t status = gXcvrSuccess_c; + /* Common configuration pointer */ + *com_config = (const xcvr_common_config_t *)&xcvr_common_config; + + /* Mode dependent configuration pointer */ + switch (radio_mode) + { +#if !RADIO_IS_GEN_2P1 + case ZIGBEE_MODE: + *mode_config = ( const xcvr_mode_config_t *)&zgbe_mode_config; /* Zigbee configuration */ + break; + case ANT_MODE: + *mode_config = ( const xcvr_mode_config_t *)&ant_mode_config; /* ANT configuration */ + break; +#endif /* !RADIO_IS_GEN_2P1 */ + case BLE_MODE: + *mode_config = ( const xcvr_mode_config_t *)&ble_mode_config; /* BLE configuration */ + break; + case GFSK_BT_0p5_h_0p5: + *mode_config = ( const xcvr_mode_config_t *)&gfsk_bt_0p5_h_0p5_mode_config; /* GFSK_BT_0p5_h_0p5 configuration */ + break; + case GFSK_BT_0p5_h_0p32: + *mode_config = ( const xcvr_mode_config_t *)&gfsk_bt_0p5_h_0p32_mode_config; /* GFSK_BT_0p5_h_0p32 configuration */ + break; + case GFSK_BT_0p5_h_0p7: + *mode_config = ( const xcvr_mode_config_t *)&gfsk_bt_0p5_h_0p7_mode_config; /* GFSK_BT_0p5_h_0p7 configuration */ + break; + case GFSK_BT_0p5_h_1p0: + *mode_config = ( const xcvr_mode_config_t *)&gfsk_bt_0p5_h_1p0_mode_config; /* GFSK_BT_0p5_h_1p0 configuration */ + break; + case GFSK_BT_0p3_h_0p5: + *mode_config = ( const xcvr_mode_config_t *)&gfsk_bt_0p3_h_0p5_mode_config; /* GFSK_BT_0p3_h_0p5 configuration */ + break; + case GFSK_BT_0p7_h_0p5: + *mode_config = ( const xcvr_mode_config_t *)&gfsk_bt_0p7_h_0p5_mode_config; /* GFSK_BT_0p7_h_0p5 configuration */ + break; + case MSK: + *mode_config = ( const xcvr_mode_config_t *)&msk_mode_config; /* MSK configuration */ + break; + default: + status = gXcvrInvalidParameters_c; + break; + } + + /* Data rate dependent and modeXdatarate dependent configuration pointers */ + if (status == gXcvrSuccess_c) /* Only attempt this pointer assignment process if prior switch() statement completed successfully */ + { + switch (data_rate) + { +#if RADIO_IS_GEN_3P0 + case DR_2MBPS: + if ((radio_mode == GFSK_BT_0p5_h_0p7) || (radio_mode == GFSK_BT_0p5_h_1p0) || (radio_mode == ZIGBEE_MODE) || (radio_mode == BLE_MODE) || (radio_mode == ANT_MODE)) + { + status = gXcvrInvalidParameters_c; + } + else + { + *datarate_config = (const xcvr_datarate_config_t *)&xcvr_2mbps_config; /* 2Mbps datarate configurations */ + *mode_datarate_config = (const xcvr_mode_datarate_config_t *)mode_configs_dr_2mbps[radio_mode]; + } + break; +#endif /* RADIO_IS_GEN_3P0 */ + case DR_1MBPS: + *datarate_config = (const xcvr_datarate_config_t *)&xcvr_1mbps_config; /* 1Mbps datarate configurations */ + *mode_datarate_config = (const xcvr_mode_datarate_config_t *)mode_configs_dr_1mbps[radio_mode]; + break; + case DR_500KBPS: + if (radio_mode == ZIGBEE_MODE) + { + /* See fsl_xcvr_zgbe_config.c for settings */ +#if !RADIO_IS_GEN_2P1 + *datarate_config = (const xcvr_datarate_config_t *)&xcvr_802_15_4_500kbps_config; /* 500Kbps datarate configurations */ +#endif /* !RADIO_IS_GEN_2P1 */ + } + else + { + *datarate_config = (const xcvr_datarate_config_t *)&xcvr_500kbps_config; /* 500Kbps datarate configurations */ + } + *mode_datarate_config = (const xcvr_mode_datarate_config_t *)mode_configs_dr_500kbps[radio_mode]; + break; + case DR_250KBPS: + *datarate_config = (const xcvr_datarate_config_t *)&xcvr_250kbps_config; /* 250Kbps datarate configurations */ + *mode_datarate_config = (const xcvr_mode_datarate_config_t *)mode_configs_dr_250kbps[radio_mode]; + break; + default: + status = gXcvrInvalidParameters_c; + break; + } + } + + return status; +} + +xcvrStatus_t XCVR_Configure(const xcvr_common_config_t *com_config, + const xcvr_mode_config_t *mode_config, + const xcvr_mode_datarate_config_t *mode_datarate_config, + const xcvr_datarate_config_t *datarate_config, + int16_t tempDegC, + XCVR_INIT_MODE_CHG_T first_init) +{ + xcvrStatus_t config_status = gXcvrSuccess_c; + uint32_t temp; + + /* Turn on the module clocks before doing anything */ +#if RADIO_IS_GEN_3P0 + RSIM->CONTROL |= mode_config->scgc5_clock_ena_bits; /* Same bit storage is used but RSIM bit assignments are applied */ +#else + SIM->SCGC5 |= mode_config->scgc5_clock_ena_bits; +#endif /* RADIO_IS_GEN_3P0 */ + + /*******************************************************************************/ + /* XCVR_ANA configs */ + /*******************************************************************************/ + + /* Configure PLL Loop Filter */ + if (first_init) + { + XCVR_ANA->SY_CTRL_1 &= ~com_config->ana_sy_ctrl1.mask; + XCVR_ANA->SY_CTRL_1 |= com_config->ana_sy_ctrl1.init; + } + + /* Configure VCO KVM */ + XCVR_ANA->SY_CTRL_2 &= ~mode_datarate_config->ana_sy_ctrl2.mask; + XCVR_ANA->SY_CTRL_2 |= mode_datarate_config->ana_sy_ctrl2.init; + + /* Configure analog filter bandwidth */ + XCVR_ANA->RX_BBA &= ~mode_datarate_config->ana_rx_bba.mask; + XCVR_ANA->RX_BBA |= mode_datarate_config->ana_rx_bba.init; + XCVR_ANA->RX_TZA &= ~mode_datarate_config->ana_rx_tza.mask; + XCVR_ANA->RX_TZA |= mode_datarate_config->ana_rx_tza.init; + +#if RADIO_IS_GEN_2P0 + if (first_init) + { + temp = XCVR_ANA->TX_DAC_PA; + temp &= ~XCVR_ANALOG_TX_DAC_PA_TX_PA_BUMP_VBIAS_MASK; + temp |= XCVR_ANALOG_TX_DAC_PA_TX_PA_BUMP_VBIAS(4); + XCVR_ANA->TX_DAC_PA = temp; + + temp = XCVR_ANA->BB_LDO_2; + temp &= ~XCVR_ANALOG_BB_LDO_2_BB_LDO_VCOLO_TRIM_MASK; + temp |= XCVR_ANALOG_BB_LDO_2_BB_LDO_VCOLO_TRIM(0); + XCVR_ANA->BB_LDO_2 = temp; + + temp = XCVR_ANA->RX_LNA; + temp &= ~XCVR_ANALOG_RX_LNA_RX_LNA_BUMP_MASK; + temp |= XCVR_ANALOG_RX_LNA_RX_LNA_BUMP(1); + XCVR_ANA->RX_LNA = temp; + + temp = XCVR_ANA->BB_LDO_1; + temp &= ~XCVR_ANALOG_BB_LDO_1_BB_LDO_FDBK_TRIM_MASK; + temp |= XCVR_ANALOG_BB_LDO_1_BB_LDO_FDBK_TRIM(1); + XCVR_ANA->BB_LDO_1 = temp; + } +#endif /* RADIO_IS_GEN_2P0 */ + + /*******************************************************************************/ + /* XCVR_MISC configs */ + /*******************************************************************************/ + temp = XCVR_MISC->XCVR_CTRL; + temp &= ~(mode_config->xcvr_ctrl.mask | XCVR_CTRL_XCVR_CTRL_REF_CLK_FREQ_MASK); + temp |= mode_config->xcvr_ctrl.init; + +#if RF_OSC_26MHZ == 1 + { + temp |= XCVR_CTRL_XCVR_CTRL_REF_CLK_FREQ(1); + } +#endif /* RF_OSC_26MHZ == 1 */ + + XCVR_MISC->XCVR_CTRL = temp; + +#if RADIO_IS_GEN_2P1 + XCVR_MISC->FAD_CTRL &= ~XCVR_CTRL_FAD_CTRL_FAD_NOT_GPIO_MASK; +#endif /* RADIO_IS_GEN_2P1 */ + + /*******************************************************************************/ + /* XCVR_PHY configs */ + /*******************************************************************************/ +#if RADIO_IS_GEN_3P0 + XCVR_PHY->PHY_FSK_PD_CFG0 = mode_config->phy_fsk_pd_cfg0; + XCVR_PHY->PHY_FSK_PD_CFG1 = mode_config->phy_fsk_pd_cfg1; + XCVR_PHY->PHY_FSK_CFG = mode_config->phy_fsk_cfg; + XCVR_PHY->PHY_FSK_MISC = mode_config->phy_fsk_misc | mode_datarate_config->phy_fsk_misc_mode_datarate; + XCVR_PHY->FSK_FAD_CTRL = mode_config->phy_fad_ctrl; +#else + XCVR_PHY->PHY_PRE_REF0 = mode_config->phy_pre_ref0_init; + XCVR_PHY->PRE_REF1 = mode_config->phy_pre_ref1_init; + XCVR_PHY->PRE_REF2 = mode_config->phy_pre_ref2_init; + XCVR_PHY->CFG1 = mode_config->phy_cfg1_init; + XCVR_PHY->CFG2 = mode_datarate_config->phy_cfg2_init; + XCVR_PHY->EL_CFG = mode_config->phy_el_cfg_init | datarate_config->phy_el_cfg_init; /* EL_WIN_SIZE and EL_INTERVAL are datarate dependent, */ +#endif /* RADIO_IS_GEN_3P0 */ + + /*******************************************************************************/ + /* XCVR_PLL_DIG configs */ + /*******************************************************************************/ + if (first_init) + { + XCVR_PLL_DIG->HPM_BUMP = com_config->pll_hpm_bump; + XCVR_PLL_DIG->MOD_CTRL = com_config->pll_mod_ctrl; + XCVR_PLL_DIG->CHAN_MAP = com_config->pll_chan_map; + XCVR_PLL_DIG->LOCK_DETECT = com_config->pll_lock_detect; + XCVR_PLL_DIG->HPM_CTRL = com_config->pll_hpm_ctrl; +#if !RADIO_IS_GEN_2P1 + XCVR_PLL_DIG->HPMCAL_CTRL = com_config->pll_hpmcal_ctrl; +#endif /* !RADIO_IS_GEN_2P1 */ + XCVR_PLL_DIG->HPM_SDM_RES = com_config->pll_hpm_sdm_res; + XCVR_PLL_DIG->LPM_CTRL = com_config->pll_lpm_ctrl; + XCVR_PLL_DIG->LPM_SDM_CTRL1 = com_config->pll_lpm_sdm_ctrl1; + XCVR_PLL_DIG->DELAY_MATCH = com_config->pll_delay_match; + XCVR_PLL_DIG->CTUNE_CTRL = com_config->pll_ctune_ctrl; + } + + /*******************************************************************************/ + /* XCVR_RX_DIG configs */ + /*******************************************************************************/ + + /* Configure RF Aux PLL for proper operation based on external clock frequency */ + if (first_init) + { + temp = XCVR_ANA->RX_AUXPLL; + temp &= ~XCVR_ANALOG_RX_AUXPLL_VCO_DAC_REF_ADJUST_MASK; +#if RF_OSC_26MHZ == 1 + { + temp |= XCVR_ANALOG_RX_AUXPLL_VCO_DAC_REF_ADJUST(4); + } +#else + { + temp |= XCVR_ANALOG_RX_AUXPLL_VCO_DAC_REF_ADJUST(7); + } +#endif /* RF_OSC_26MHZ == 1 */ + XCVR_ANA->RX_AUXPLL = temp; + } + + /* Configure RX_DIG_CTRL */ +#if RF_OSC_26MHZ == 1 + { + temp = com_config->rx_dig_ctrl_init | /* Common portion of RX_DIG_CTRL init */ + mode_config->rx_dig_ctrl_init_26mhz | /* Mode specific portion of RX_DIG_CTRL init */ + datarate_config->rx_dig_ctrl_init_26mhz | /* Datarate specific portion of RX_DIG_CTRL init */ + XCVR_RX_DIG_RX_DIG_CTRL_RX_SRC_EN_MASK; /* Always enable the sample rate converter for 26MHz */ + } +#else + { + temp = com_config->rx_dig_ctrl_init | /* Common portion of RX_DIG_CTRL init */ + mode_config->rx_dig_ctrl_init_32mhz | /* Mode specific portion of RX_DIG_CTRL init */ + datarate_config->rx_dig_ctrl_init_32mhz | /* Datarate specific portion of RX_DIG_CTRL init */ + 0; /* Always disable the sample rate converter for 32MHz */ + } +#endif /* RF_OSC_26MHZ == 1 */ + + temp |= com_config->rx_dig_ctrl_init; /* Common portion of RX_DIG_CTRL init */ + XCVR_RX_DIG->RX_DIG_CTRL = temp; + + /* DCOC_CAL_IIR */ +#if RF_OSC_26MHZ == 1 + { + XCVR_RX_DIG->DCOC_CAL_IIR = datarate_config->dcoc_cal_iir_init_26mhz; + } +#else + { + XCVR_RX_DIG->DCOC_CAL_IIR = datarate_config->dcoc_cal_iir_init_32mhz; + } +#endif /* RF_OSC_26MHZ == 1 */ + + /* DC_RESID_CTRL */ +#if RF_OSC_26MHZ == 1 + { + XCVR_RX_DIG->DC_RESID_CTRL = com_config->dc_resid_ctrl_init | datarate_config->dc_resid_ctrl_26mhz; + } +#else + { + XCVR_RX_DIG->DC_RESID_CTRL = com_config->dc_resid_ctrl_init | datarate_config->dc_resid_ctrl_32mhz; + } +#endif /* RF_OSC_26MHZ == 1 */ + + /* DCOC_CTRL_0 & _1 */ +#if RF_OSC_26MHZ == 1 + { + XCVR_RX_DIG->DCOC_CTRL_0 = com_config->dcoc_ctrl_0_init_26mhz | datarate_config->dcoc_ctrl_0_init_26mhz; /* Combine common and datarate specific settings */ + XCVR_RX_DIG->DCOC_CTRL_1 = com_config->dcoc_ctrl_1_init | datarate_config->dcoc_ctrl_1_init_26mhz; /* Combine common and datarate specific settings */ +#if RADIO_IS_GEN_3P0 + XCVR_RX_DIG->DCOC_CTRL_2 = datarate_config->dcoc_ctrl_2_init_26mhz; +#endif /* RADIO_IS_GEN_3P0 */ + + } +#else + { + XCVR_RX_DIG->DCOC_CTRL_0 = com_config->dcoc_ctrl_0_init_32mhz | datarate_config->dcoc_ctrl_0_init_32mhz; /* Combine common and datarate specific settings */ + XCVR_RX_DIG->DCOC_CTRL_1 = com_config->dcoc_ctrl_1_init | datarate_config->dcoc_ctrl_1_init_32mhz; /* Combine common and datarate specific settings */ +#if RADIO_IS_GEN_3P0 + XCVR_RX_DIG->DCOC_CTRL_2 = datarate_config->dcoc_ctrl_2_init_32mhz; +#endif /* RADIO_IS_GEN_3P0 */ + } +#endif /* RF_OSC_26MHZ == 1 */ + if (first_init) + { + /* DCOC_CAL_GAIN */ + XCVR_RX_DIG->DCOC_CAL_GAIN = com_config->dcoc_cal_gain_init; + + /* DCOC_CAL_RCP */ + XCVR_RX_DIG->DCOC_CAL_RCP = com_config->dcoc_cal_rcp_init; + XCVR_RX_DIG->LNA_GAIN_VAL_3_0 = com_config->lna_gain_val_3_0; + XCVR_RX_DIG->LNA_GAIN_VAL_7_4 = com_config->lna_gain_val_7_4; + XCVR_RX_DIG->LNA_GAIN_VAL_8 = com_config->lna_gain_val_8; + XCVR_RX_DIG->BBA_RES_TUNE_VAL_7_0 = com_config->bba_res_tune_val_7_0; + XCVR_RX_DIG->BBA_RES_TUNE_VAL_10_8 = com_config->bba_res_tune_val_10_8; + + /* LNA_GAIN_LIN_VAL */ + XCVR_RX_DIG->LNA_GAIN_LIN_VAL_2_0 = com_config->lna_gain_lin_val_2_0_init; + XCVR_RX_DIG->LNA_GAIN_LIN_VAL_5_3 = com_config->lna_gain_lin_val_5_3_init; + XCVR_RX_DIG->LNA_GAIN_LIN_VAL_8_6 = com_config->lna_gain_lin_val_8_6_init; + XCVR_RX_DIG->LNA_GAIN_LIN_VAL_9 = com_config->lna_gain_lin_val_9_init; + + /* BBA_RES_TUNE_LIN_VAL */ + XCVR_RX_DIG->BBA_RES_TUNE_LIN_VAL_3_0 = com_config->bba_res_tune_lin_val_3_0_init; + XCVR_RX_DIG->BBA_RES_TUNE_LIN_VAL_7_4 = com_config->bba_res_tune_lin_val_7_4_init; + XCVR_RX_DIG->BBA_RES_TUNE_LIN_VAL_10_8 = com_config->bba_res_tune_lin_val_10_8_init; + + /* BBA_STEP */ + XCVR_RX_DIG->DCOC_BBA_STEP = com_config->dcoc_bba_step_init; + + /* DCOC_TZA_STEP */ + XCVR_RX_DIG->DCOC_TZA_STEP_0 = com_config->dcoc_tza_step_00_init; + XCVR_RX_DIG->DCOC_TZA_STEP_1 = com_config->dcoc_tza_step_01_init; + XCVR_RX_DIG->DCOC_TZA_STEP_2 = com_config->dcoc_tza_step_02_init; + XCVR_RX_DIG->DCOC_TZA_STEP_3 = com_config->dcoc_tza_step_03_init; + XCVR_RX_DIG->DCOC_TZA_STEP_4 = com_config->dcoc_tza_step_04_init; + XCVR_RX_DIG->DCOC_TZA_STEP_5 = com_config->dcoc_tza_step_05_init; + XCVR_RX_DIG->DCOC_TZA_STEP_6 = com_config->dcoc_tza_step_06_init; + XCVR_RX_DIG->DCOC_TZA_STEP_7 = com_config->dcoc_tza_step_07_init; + XCVR_RX_DIG->DCOC_TZA_STEP_8 = com_config->dcoc_tza_step_08_init; + XCVR_RX_DIG->DCOC_TZA_STEP_9 = com_config->dcoc_tza_step_09_init; + XCVR_RX_DIG->DCOC_TZA_STEP_10 = com_config->dcoc_tza_step_10_init; + +#if (RADIO_IS_GEN_3P0 || RADIO_IS_GEN_2P1) + /* DCOC_CAL_FAIL and DCOC_CAL_PASS */ + XCVR_RX_DIG->DCOC_CAL_FAIL_TH = com_config->dcoc_cal_fail_th_init; + XCVR_RX_DIG->DCOC_CAL_PASS_TH = com_config->dcoc_cal_pass_th_init; +#endif /* (RADIO_IS_GEN_3P0 || RADIO_IS_GEN_2P1) */ + } + + /* AGC_CTRL_0 .. _3 */ + XCVR_RX_DIG->AGC_CTRL_0 = com_config->agc_ctrl_0_init | mode_config->agc_ctrl_0_init; + +#if RF_OSC_26MHZ == 1 + { + XCVR_RX_DIG->AGC_CTRL_1 = com_config->agc_ctrl_1_init_26mhz | datarate_config->agc_ctrl_1_init_26mhz; /* Combine common and datarate specific settings */ + XCVR_RX_DIG->AGC_CTRL_2 = mode_datarate_config->agc_ctrl_2_init_26mhz; + } +#else + { + XCVR_RX_DIG->AGC_CTRL_1 = com_config->agc_ctrl_1_init_32mhz | datarate_config->agc_ctrl_1_init_32mhz; /* Combine common and datarate specific settings */ + XCVR_RX_DIG->AGC_CTRL_2 = mode_datarate_config->agc_ctrl_2_init_32mhz; + } +#endif /* RF_OSC_26MHZ == 1 */ + + if (first_init) + { + XCVR_RX_DIG->AGC_CTRL_3 = com_config->agc_ctrl_3_init; + + /* AGC_GAIN_TBL_** */ + XCVR_RX_DIG->AGC_GAIN_TBL_03_00 = com_config->agc_gain_tbl_03_00_init; + XCVR_RX_DIG->AGC_GAIN_TBL_07_04 = com_config->agc_gain_tbl_07_04_init; + XCVR_RX_DIG->AGC_GAIN_TBL_11_08 = com_config->agc_gain_tbl_11_08_init; + XCVR_RX_DIG->AGC_GAIN_TBL_15_12 = com_config->agc_gain_tbl_15_12_init; + XCVR_RX_DIG->AGC_GAIN_TBL_19_16 = com_config->agc_gain_tbl_19_16_init; + XCVR_RX_DIG->AGC_GAIN_TBL_23_20 = com_config->agc_gain_tbl_23_20_init; + XCVR_RX_DIG->AGC_GAIN_TBL_26_24 = com_config->agc_gain_tbl_26_24_init; + + /* RSSI_CTRL_0 */ + XCVR_RX_DIG->RSSI_CTRL_0 = com_config->rssi_ctrl_0_init; + +#if RADIO_IS_GEN_3P0 + XCVR_RX_DIG->RSSI_CTRL_1 = com_config->rssi_ctrl_1_init; +#endif /* RADIO_IS_GEN_3P0 */ + + /* CCA_ED_LQI_0 and _1 */ + XCVR_RX_DIG->CCA_ED_LQI_CTRL_0 = com_config->cca_ed_lqi_ctrl_0_init; + XCVR_RX_DIG->CCA_ED_LQI_CTRL_1 = com_config->cca_ed_lqi_ctrl_1_init; + } + + /* Channel filter coefficients */ +#if RF_OSC_26MHZ == 1 + { + XCVR_RX_DIG->RX_CHF_COEF_0 = mode_datarate_config->rx_chf_coeffs_26mhz.rx_chf_coef_0; + XCVR_RX_DIG->RX_CHF_COEF_1 = mode_datarate_config->rx_chf_coeffs_26mhz.rx_chf_coef_1; + XCVR_RX_DIG->RX_CHF_COEF_2 = mode_datarate_config->rx_chf_coeffs_26mhz.rx_chf_coef_2; + XCVR_RX_DIG->RX_CHF_COEF_3 = mode_datarate_config->rx_chf_coeffs_26mhz.rx_chf_coef_3; + XCVR_RX_DIG->RX_CHF_COEF_4 = mode_datarate_config->rx_chf_coeffs_26mhz.rx_chf_coef_4; + XCVR_RX_DIG->RX_CHF_COEF_5 = mode_datarate_config->rx_chf_coeffs_26mhz.rx_chf_coef_5; + XCVR_RX_DIG->RX_CHF_COEF_6 = mode_datarate_config->rx_chf_coeffs_26mhz.rx_chf_coef_6; + XCVR_RX_DIG->RX_CHF_COEF_7 = mode_datarate_config->rx_chf_coeffs_26mhz.rx_chf_coef_7; + XCVR_RX_DIG->RX_CHF_COEF_8 = mode_datarate_config->rx_chf_coeffs_26mhz.rx_chf_coef_8; + XCVR_RX_DIG->RX_CHF_COEF_9 = mode_datarate_config->rx_chf_coeffs_26mhz.rx_chf_coef_9; + XCVR_RX_DIG->RX_CHF_COEF_10 = mode_datarate_config->rx_chf_coeffs_26mhz.rx_chf_coef_10; + XCVR_RX_DIG->RX_CHF_COEF_11 = mode_datarate_config->rx_chf_coeffs_26mhz.rx_chf_coef_11; + } +#else + { + XCVR_RX_DIG->RX_CHF_COEF_0 = mode_datarate_config->rx_chf_coeffs_32mhz.rx_chf_coef_0; + XCVR_RX_DIG->RX_CHF_COEF_1 = mode_datarate_config->rx_chf_coeffs_32mhz.rx_chf_coef_1; + XCVR_RX_DIG->RX_CHF_COEF_2 = mode_datarate_config->rx_chf_coeffs_32mhz.rx_chf_coef_2; + XCVR_RX_DIG->RX_CHF_COEF_3 = mode_datarate_config->rx_chf_coeffs_32mhz.rx_chf_coef_3; + XCVR_RX_DIG->RX_CHF_COEF_4 = mode_datarate_config->rx_chf_coeffs_32mhz.rx_chf_coef_4; + XCVR_RX_DIG->RX_CHF_COEF_5 = mode_datarate_config->rx_chf_coeffs_32mhz.rx_chf_coef_5; + XCVR_RX_DIG->RX_CHF_COEF_6 = mode_datarate_config->rx_chf_coeffs_32mhz.rx_chf_coef_6; + XCVR_RX_DIG->RX_CHF_COEF_7 = mode_datarate_config->rx_chf_coeffs_32mhz.rx_chf_coef_7; + XCVR_RX_DIG->RX_CHF_COEF_8 = mode_datarate_config->rx_chf_coeffs_32mhz.rx_chf_coef_8; + XCVR_RX_DIG->RX_CHF_COEF_9 = mode_datarate_config->rx_chf_coeffs_32mhz.rx_chf_coef_9; + XCVR_RX_DIG->RX_CHF_COEF_10 = mode_datarate_config->rx_chf_coeffs_32mhz.rx_chf_coef_10; + XCVR_RX_DIG->RX_CHF_COEF_11 = mode_datarate_config->rx_chf_coeffs_32mhz.rx_chf_coef_11; + } +#endif /* RF_OSC_26MHZ == 1 */ + + XCVR_RX_DIG->RX_RCCAL_CTRL0 = mode_datarate_config->rx_rccal_ctrl_0; + XCVR_RX_DIG->RX_RCCAL_CTRL1 = mode_datarate_config->rx_rccal_ctrl_1; + + /*******************************************************************************/ + /* XCVR_TSM configs */ + /*******************************************************************************/ + XCVR_TSM->CTRL = com_config->tsm_ctrl; + +#if RADIO_IS_GEN_2P0 + if ((mode_config->radio_mode != ZIGBEE_MODE) && (mode_config->radio_mode != BLE_MODE)) + { + XCVR_TSM->CTRL &= ~XCVR_TSM_CTRL_DATA_PADDING_EN_MASK; + } +#endif /* RADIO_IS_GEN_2P0 */ + + if (first_init) + { +#if !RADIO_IS_GEN_2P1 + XCVR_MISC->LPPS_CTRL = com_config->lpps_ctrl_init; /* Register is in XCVR_MISC but grouped with TSM for intialization */ +#endif /* !RADIO_IS_GEN_2P1 */ + + XCVR_TSM->OVRD2 = com_config->tsm_ovrd2_init; + /* TSM registers and timings - dependent upon clock frequency */ +#if RF_OSC_26MHZ == 1 + { + XCVR_TSM->END_OF_SEQ = com_config->end_of_seq_init_26mhz; + XCVR_TSM->FAST_CTRL2 = com_config->tsm_fast_ctrl2_init_26mhz; + XCVR_TSM->RECYCLE_COUNT = com_config->recycle_count_init_26mhz; + XCVR_TSM->TIMING14 = com_config->tsm_timing_14_init_26mhz; + XCVR_TSM->TIMING16 = com_config->tsm_timing_16_init_26mhz; + XCVR_TSM->TIMING25 = com_config->tsm_timing_25_init_26mhz; + XCVR_TSM->TIMING27 = com_config->tsm_timing_27_init_26mhz; + XCVR_TSM->TIMING28 = com_config->tsm_timing_28_init_26mhz; + XCVR_TSM->TIMING29 = com_config->tsm_timing_29_init_26mhz; + XCVR_TSM->TIMING30 = com_config->tsm_timing_30_init_26mhz; + XCVR_TSM->TIMING31 = com_config->tsm_timing_31_init_26mhz; + XCVR_TSM->TIMING32 = com_config->tsm_timing_32_init_26mhz; + XCVR_TSM->TIMING33 = com_config->tsm_timing_33_init_26mhz; + XCVR_TSM->TIMING36 = com_config->tsm_timing_36_init_26mhz; + XCVR_TSM->TIMING37 = com_config->tsm_timing_37_init_26mhz; + XCVR_TSM->TIMING39 = com_config->tsm_timing_39_init_26mhz; + XCVR_TSM->TIMING40 = com_config->tsm_timing_40_init_26mhz; + XCVR_TSM->TIMING41 = com_config->tsm_timing_41_init_26mhz; + XCVR_TSM->TIMING52 = com_config->tsm_timing_52_init_26mhz; + XCVR_TSM->TIMING54 = com_config->tsm_timing_54_init_26mhz; + XCVR_TSM->TIMING55 = com_config->tsm_timing_55_init_26mhz; + XCVR_TSM->TIMING56 = com_config->tsm_timing_56_init_26mhz; + } +#else + { + XCVR_TSM->END_OF_SEQ = com_config->end_of_seq_init_32mhz; + XCVR_TSM->FAST_CTRL2 = com_config->tsm_fast_ctrl2_init_32mhz; + XCVR_TSM->RECYCLE_COUNT = com_config->recycle_count_init_32mhz; + XCVR_TSM->TIMING14 = com_config->tsm_timing_14_init_32mhz; + XCVR_TSM->TIMING16 = com_config->tsm_timing_16_init_32mhz; + XCVR_TSM->TIMING25 = com_config->tsm_timing_25_init_32mhz; + XCVR_TSM->TIMING27 = com_config->tsm_timing_27_init_32mhz; + XCVR_TSM->TIMING28 = com_config->tsm_timing_28_init_32mhz; + XCVR_TSM->TIMING29 = com_config->tsm_timing_29_init_32mhz; + XCVR_TSM->TIMING30 = com_config->tsm_timing_30_init_32mhz; + XCVR_TSM->TIMING31 = com_config->tsm_timing_31_init_32mhz; + XCVR_TSM->TIMING32 = com_config->tsm_timing_32_init_32mhz; + XCVR_TSM->TIMING33 = com_config->tsm_timing_33_init_32mhz; + XCVR_TSM->TIMING36 = com_config->tsm_timing_36_init_32mhz; + XCVR_TSM->TIMING37 = com_config->tsm_timing_37_init_32mhz; + XCVR_TSM->TIMING39 = com_config->tsm_timing_39_init_32mhz; + XCVR_TSM->TIMING40 = com_config->tsm_timing_40_init_32mhz; + XCVR_TSM->TIMING41 = com_config->tsm_timing_41_init_32mhz; + XCVR_TSM->TIMING52 = com_config->tsm_timing_52_init_32mhz; + XCVR_TSM->TIMING54 = com_config->tsm_timing_54_init_32mhz; + XCVR_TSM->TIMING55 = com_config->tsm_timing_55_init_32mhz; + XCVR_TSM->TIMING56 = com_config->tsm_timing_56_init_32mhz; + } +#endif /* RF_OSC_26MHZ == 1 */ + + /* TSM timings independent of clock frequency */ + XCVR_TSM->TIMING00 = com_config->tsm_timing_00_init; + XCVR_TSM->TIMING01 = com_config->tsm_timing_01_init; + XCVR_TSM->TIMING02 = com_config->tsm_timing_02_init; + XCVR_TSM->TIMING03 = com_config->tsm_timing_03_init; + XCVR_TSM->TIMING04 = com_config->tsm_timing_04_init; + XCVR_TSM->TIMING05 = com_config->tsm_timing_05_init; + XCVR_TSM->TIMING06 = com_config->tsm_timing_06_init; + XCVR_TSM->TIMING07 = com_config->tsm_timing_07_init; + XCVR_TSM->TIMING08 = com_config->tsm_timing_08_init; + XCVR_TSM->TIMING09 = com_config->tsm_timing_09_init; + XCVR_TSM->TIMING10 = com_config->tsm_timing_10_init; + XCVR_TSM->TIMING11 = com_config->tsm_timing_11_init; + XCVR_TSM->TIMING12 = com_config->tsm_timing_12_init; + XCVR_TSM->TIMING13 = com_config->tsm_timing_13_init; + XCVR_TSM->TIMING15 = com_config->tsm_timing_15_init; + XCVR_TSM->TIMING17 = com_config->tsm_timing_17_init; + XCVR_TSM->TIMING18 = com_config->tsm_timing_18_init; + XCVR_TSM->TIMING19 = com_config->tsm_timing_19_init; + XCVR_TSM->TIMING20 = com_config->tsm_timing_20_init; + XCVR_TSM->TIMING21 = com_config->tsm_timing_21_init; + XCVR_TSM->TIMING22 = com_config->tsm_timing_22_init; + XCVR_TSM->TIMING23 = com_config->tsm_timing_23_init; + XCVR_TSM->TIMING24 = com_config->tsm_timing_24_init; + XCVR_TSM->TIMING26 = com_config->tsm_timing_26_init; + XCVR_TSM->TIMING34 = com_config->tsm_timing_34_init; + XCVR_TSM->TIMING35 = com_config->tsm_timing_35_init; + XCVR_TSM->TIMING38 = com_config->tsm_timing_38_init; + XCVR_TSM->TIMING51 = com_config->tsm_timing_51_init; + XCVR_TSM->TIMING53 = com_config->tsm_timing_53_init; + XCVR_TSM->TIMING57 = com_config->tsm_timing_57_init; + XCVR_TSM->TIMING58 = com_config->tsm_timing_58_init; + +#if RF_OSC_26MHZ == 1 + { + XCVR_TSM->END_OF_SEQ = XCVR_TSM_END_OF_SEQ_END_OF_TX_WU(END_OF_TX_WU) | + XCVR_TSM_END_OF_SEQ_END_OF_TX_WD(END_OF_TX_WD) | + XCVR_TSM_END_OF_SEQ_END_OF_RX_WU(END_OF_RX_WU_26MHZ) | + XCVR_TSM_END_OF_SEQ_END_OF_RX_WD(END_OF_RX_WD_26MHZ); + } +#else + { + XCVR_TSM->END_OF_SEQ = XCVR_TSM_END_OF_SEQ_END_OF_TX_WU(END_OF_TX_WU) | + XCVR_TSM_END_OF_SEQ_END_OF_TX_WD(END_OF_TX_WD) | + XCVR_TSM_END_OF_SEQ_END_OF_RX_WU(END_OF_RX_WU) | + XCVR_TSM_END_OF_SEQ_END_OF_RX_WD(END_OF_RX_WD); + } +#endif /* RF_OSC_26MHZ == 1 */ + + XCVR_TSM->PA_RAMP_TBL0 = com_config->pa_ramp_tbl_0_init; + XCVR_TSM->PA_RAMP_TBL1 = com_config->pa_ramp_tbl_1_init; + +#if RADIO_IS_GEN_3P0 + XCVR_TSM->PA_RAMP_TBL2 = com_config->pa_ramp_tbl_2_init; + XCVR_TSM->PA_RAMP_TBL3 = com_config->pa_ramp_tbl_3_init; + + /* Apply PA_RAMP_TIME == 4usec adjustments to TX_WD signals */ +#if (PA_RAMP_TIME == 4) + XCVR_TSM->TIMING00 += B1(2); /* (bb_ldo_hf_en) */ + XCVR_TSM->TIMING01 += B1(2); /* (bb_ldo_adcdac_en) */ + XCVR_TSM->TIMING03 += B1(2); /* (bb_ldo_pd_en) */ + XCVR_TSM->TIMING04 += B1(2); /* (bb_ldo_fdbk_en) */ + XCVR_TSM->TIMING05 += B1(2); /* (bb_ldo_vcolo_en) */ + XCVR_TSM->TIMING06 += B1(2); /* (bb_ldo_vtref_en) */ + XCVR_TSM->TIMING10 += B1(2); /* (bb_xtal_pll_ref_clk_en) */ + XCVR_TSM->TIMING11 += B1(2); /* (bb_xtal_dac_ref_clk_en) */ + XCVR_TSM->TIMING15 += B1(2); /* (sy_vco_en) */ + XCVR_TSM->TIMING17 += B1(2); /* (sy_lo_tx_buf_en) */ + XCVR_TSM->TIMING18 += B1(2); /* (sy_divn_en) */ + XCVR_TSM->TIMING20 += B1(2); /* (sy_pd_en) */ + XCVR_TSM->TIMING21 += B1(2); /* (sy_lo_divn_en) */ + XCVR_TSM->TIMING23 += B1(2); /* (sy_lo_tx_en) */ + XCVR_TSM->TIMING26 += B1(2); /* (tx_pa_en) */ + XCVR_TSM->TIMING34 += B1(2); /* (pll_dig_en) */ + XCVR_TSM->TIMING35 += B1(2); /* (tx_dig_en) */ + XCVR_TSM->TIMING38 += B1(2); /* (sigma_delta_en) */ + XCVR_TSM->TIMING58 += B1(2) /* (tx_hpm_dac_en) */ + temp = XCVR_TSM->TIMING14; + temp &= 0xFFFF0000; + temp |= B0(END_OF_TX_WU - 4) | B1(END_OF_TX_WU + 1); /* (sy_pd_cycle_slip_ld_ft_en) */ + XCVR_TSM->TIMING14 = temp; +#endif /* (PA_RAMP_TIME == 4) */ +#endif /* RADIO_IS_GEN_3P0 */ + } + +#if RADIO_IS_GEN_3P0 + if (mode_config->radio_mode == ZIGBEE_MODE) + { + temp = XCVR_TSM->TIMING35; + temp &= ~(B0(0xFF)); + if (DATA_PADDING_EN == 1) + { + temp |= B0(END_OF_TX_WU - 2 - 8); /* Adjust for data padding time */ + } + else + { + temp |= B0(END_OF_TX_WU - 2); /* No data padding adjustment */ + } + XCVR_TSM->TIMING35 = temp; + } +#else + + if ((mode_datarate_config->radio_mode == MSK) && ((mode_datarate_config->data_rate == DR_500KBPS) || (mode_datarate_config->data_rate == DR_250KBPS))) + { + /* Apply a specific value of TX_DIG_EN which assumes no DATA PADDING */ + XCVR_TSM->TIMING35 = com_config->tsm_timing_35_init | B0(TX_DIG_EN_ASSERT_MSK500); /* LSbyte is mode specific */ + } + else + { + XCVR_TSM->TIMING35 = com_config->tsm_timing_35_init | mode_config->tsm_timing_35_init; /* LSbyte is mode specific, other bytes are common */ + } +#endif /* RADIO_IS_GEN_3P0 */ + + /*******************************************************************************/ + /* XCVR_TX_DIG configs */ + /*******************************************************************************/ +#if RF_OSC_26MHZ == 1 + { + XCVR_TX_DIG->FSK_SCALE = mode_datarate_config->tx_fsk_scale_26mhz; /* Applies only to 802.15.4 & MSK but won't harm other protocols */ + XCVR_TX_DIG->GFSK_COEFF1 = mode_config->tx_gfsk_coeff1_26mhz; + XCVR_TX_DIG->GFSK_COEFF2 = mode_config->tx_gfsk_coeff2_26mhz; + } +#else + { + XCVR_TX_DIG->FSK_SCALE = mode_datarate_config->tx_fsk_scale_32mhz; /* Applies only to 802.15.4 & MSK but won't harm other protocols */ + XCVR_TX_DIG->GFSK_COEFF1 = mode_config->tx_gfsk_coeff1_32mhz; + XCVR_TX_DIG->GFSK_COEFF2 = mode_config->tx_gfsk_coeff2_32mhz; + } +#endif /* RF_OSC_26MHZ == 1 */ + + if (first_init) + { + XCVR_TX_DIG->CTRL = com_config->tx_ctrl; + XCVR_TX_DIG->DATA_PADDING = com_config->tx_data_padding; + XCVR_TX_DIG->DFT_PATTERN = com_config->tx_dft_pattern; + +#if !RADIO_IS_GEN_2P1 + XCVR_TX_DIG->RF_DFT_BIST_1 = com_config->rf_dft_bist_1; + XCVR_TX_DIG->RF_DFT_BIST_2 = com_config->rf_dft_bist_2; +#endif /* !RADIO_IS_GEN_2P1 */ + } + + XCVR_TX_DIG->GFSK_CTRL = mode_config->tx_gfsk_ctrl; + +#ifndef SIMULATION +#if (TRIM_BBA_DCOC_DAC_AT_INIT) + if (first_init) + { + uint32_t end_of_rx_wu = 0; + XCVR_ForceRxWu(); + /* Wait for TSM to reach the end of warmup (unless you want to capture some samples during DCOC cal phase) */ + temp = XCVR_TSM->END_OF_SEQ; + end_of_rx_wu = (temp & XCVR_TSM_END_OF_SEQ_END_OF_RX_WU_MASK) >> XCVR_TSM_END_OF_SEQ_END_OF_RX_WU_SHIFT; + while ((( XCVR_MISC->XCVR_STATUS & XCVR_CTRL_XCVR_STATUS_TSM_COUNT_MASK) >> XCVR_CTRL_XCVR_STATUS_TSM_COUNT_SHIFT ) != end_of_rx_wu) {}; + +// if (!rx_bba_dcoc_dac_trim_shortIQ()) + if (!rx_bba_dcoc_dac_trim_DCest()) + { + config_status = gXcvrTrimFailure_c; + } + + XCVR_ForceRxWd(); + DCOC_DAC_INIT_Cal(1); + } +#endif /* TRIM_BBA_DCOC_DAC_AT_INIT */ +#endif /* ifndef SIMULATION */ + return config_status; +} + +void XCVR_Reset(void) +{ +#if RADIO_IS_GEN_3P0 +#else + RSIM->CONTROL |= RSIM_CONTROL_RADIO_RESET_BIT_MASK; /* Assert radio software reset */ + RSIM->CONTROL &= ~RSIM_CONTROL_RADIO_RESET_BIT_MASK; /* De-assert radio software reset */ + RSIM->CONTROL &= ~RSIM_CONTROL_RADIO_RESET_BIT_MASK; /* De-assert radio software reset a second time per RADIO_RESET bit description */ +#endif /* RADIO_IS_GEN_3P0 */ +} + +xcvrStatus_t XCVR_ChangeMode (radio_mode_t new_radio_mode, data_rate_t new_data_rate) /* Change from one radio mode to another */ +{ + xcvrStatus_t status; + const xcvr_mode_datarate_config_t * mode_datarate_config; + const xcvr_datarate_config_t * datarate_config ; + const xcvr_mode_config_t * radio_mode_cfg; + const xcvr_common_config_t * radio_common_config; + + status = XCVR_GetDefaultConfig(new_radio_mode, new_data_rate, (void *)&radio_common_config, (void *)&radio_mode_cfg, (void *)&mode_datarate_config, (void *)&datarate_config ); + + if (status == gXcvrSuccess_c) + { + status = XCVR_Configure((const xcvr_common_config_t *)radio_common_config, + (const xcvr_mode_config_t *)radio_mode_cfg, + (const xcvr_mode_datarate_config_t *)mode_datarate_config, + (const xcvr_datarate_config_t *)datarate_config, 25, XCVR_MODE_CHANGE); + current_xcvr_config.radio_mode = new_radio_mode; + current_xcvr_config.data_rate = new_data_rate; + } + + return status; +} + +void XCVR_EnaNBRSSIMeas( uint8_t IIRnbEnable ) +{ + if (IIRnbEnable) + { + XCVR_RX_DIG->RSSI_CTRL_0 |= XCVR_RX_DIG_RSSI_CTRL_0_RSSI_IIR_CW_WEIGHT_MASK; + } + else + { + XCVR_RX_DIG->RSSI_CTRL_0 &= ~XCVR_RX_DIG_RSSI_CTRL_0_RSSI_IIR_CW_WEIGHT_MASK; + } +} + +xcvrStatus_t XCVR_OverrideFrequency ( uint32_t freq, uint32_t refOsc ) +{ + double integer_used_in_Hz, + integer_used_in_LSB, + numerator_fraction, + numerator_in_Hz, + numerator_in_LSB, + numerator_unrounded, + real_int_and_fraction, + real_fraction, + requested_freq_in_LSB, + sdm_lsb; + uint32_t temp; + static uint32_t integer_truncated, + integer_to_use; + static int32_t numerator_rounded; + + /* Configure for Coarse Tune */ + uint32_t coarse_tune_target = freq / 1000000; + + temp = XCVR_PLL_DIG->CTUNE_CTRL; + temp &= ~XCVR_PLL_DIG_CTUNE_CTRL_CTUNE_TARGET_MANUAL_MASK; + temp |= XCVR_PLL_DIG_CTUNE_CTRL_CTUNE_TARGET_MANUAL(coarse_tune_target); + XCVR_PLL_DIG->CTUNE_CTRL = temp; + + /* Calculate the Low Port values */ + sdm_lsb = refOsc / 131072.0; + + real_int_and_fraction = freq / (refOsc * 2.0); + + integer_truncated = (uint32_t) trunc(real_int_and_fraction); + + real_fraction = real_int_and_fraction - integer_truncated; + + if (real_fraction > 0.5) + { + integer_to_use = integer_truncated + 1; + } + else + { + integer_to_use = integer_truncated; + } + + numerator_fraction = real_int_and_fraction - integer_to_use; + + integer_used_in_Hz = integer_to_use * refOsc * 2; + integer_used_in_LSB = integer_used_in_Hz / sdm_lsb; + + numerator_in_Hz = numerator_fraction * refOsc * 2; + numerator_in_LSB = numerator_in_Hz / sdm_lsb; + + requested_freq_in_LSB = integer_used_in_LSB + numerator_in_LSB; + + numerator_unrounded = (requested_freq_in_LSB - integer_used_in_LSB) * 256; + + numerator_rounded = (int32_t)round(numerator_unrounded); + + /* Write the Low Port Integer and Numerator */ + temp = XCVR_PLL_DIG->LPM_SDM_CTRL1; + temp &= ~XCVR_PLL_DIG_LPM_SDM_CTRL1_LPM_INTG_MASK; + temp |= (XCVR_PLL_DIG_LPM_SDM_CTRL1_LPM_INTG(integer_to_use) | + XCVR_PLL_DIG_LPM_SDM_CTRL1_SDM_MAP_DISABLE_MASK); + XCVR_PLL_DIG->LPM_SDM_CTRL1 = temp; + + XCVR_PLL_DIG->LPM_SDM_CTRL2 = numerator_rounded; + + return gXcvrSuccess_c; +} + +void XCVR_RegisterPanicCb ( panic_fptr fptr ) /* Allow upper layers to provide PANIC callback */ +{ + s_PanicFunctionPtr = fptr; +} + +void XcvrPanic(XCVR_PANIC_ID_T panic_id, uint32_t panic_address) +{ + if ( s_PanicFunctionPtr != NULL) + { + s_PanicFunctionPtr(panic_id, panic_address, 0, 0); + } + else + { + uint8_t dummy; + + while(1) + { + dummy = dummy; + } + } +} + +healthStatus_t XCVR_HealthCheck ( void ) /* Allow upper layers to poll the radio health */ +{ + return (healthStatus_t)NO_ERRORS; +} + +void XCVR_FadLppsControl(FAD_LPPS_CTRL_T control) +{ + +} + +/* Helper function to map radio mode to LL usage */ +link_layer_t map_mode_to_ll(radio_mode_t mode) +{ + link_layer_t llret; + switch (mode) + { + case BLE_MODE: + llret = BLE_LL; + break; + case ZIGBEE_MODE: + llret = ZIGBEE_LL; + break; + case ANT_MODE: + llret = ANT_LL; + break; + case GFSK_BT_0p5_h_0p5: + case GFSK_BT_0p5_h_0p32: + case GFSK_BT_0p5_h_0p7: + case GFSK_BT_0p5_h_1p0: + case GFSK_BT_0p3_h_0p5: + case GFSK_BT_0p7_h_0p5: + case MSK: + llret = GENFSK_LL; + break; + default: + llret = UNASSIGNED_LL; + break; + } + return llret; +} + +#if RADIO_IS_GEN_3P0 +void XCVR_SetBSM_NTW_Address(uint32_t bsm_ntw_address) +{ + XCVR_PHY->NTW_ADR_BSM = bsm_ntw_address; +} + +uint32_t XCVR_GetBSM_NTW_Address(void) +{ + return XCVR_PHY->NTW_ADR_BSM; +} +#endif /* RADIO_IS_GEN_3P0 */ + +/* Setup IRQ mapping to LL interrupt outputs in XCVR_CTRL */ +xcvrStatus_t XCVR_SetIRQMapping(radio_mode_t irq0_mapping, radio_mode_t irq1_mapping) +{ + link_layer_t int0 = map_mode_to_ll(irq0_mapping); + link_layer_t int1 = map_mode_to_ll(irq1_mapping); + xcvrStatus_t statusret; + /* Make sure the two LL's requested aren't the same */ + if (int0 == int1) + { + statusret = gXcvrInvalidParameters_c; + } + else + { + uint32_t temp; + temp = XCVR_MISC->XCVR_CTRL; + temp &= ~(XCVR_CTRL_XCVR_CTRL_RADIO0_IRQ_SEL_MASK | XCVR_CTRL_XCVR_CTRL_RADIO1_IRQ_SEL_MASK); + temp |= (XCVR_CTRL_XCVR_CTRL_RADIO0_IRQ_SEL(int0) | XCVR_CTRL_XCVR_CTRL_RADIO1_IRQ_SEL(int1)); + XCVR_MISC->XCVR_CTRL = temp; + statusret = gXcvrSuccess_c; + } + return statusret; +} + +/* Get current state of IRQ mapping for either radio INT0 or INT1 */ +link_layer_t XCVR_GetIRQMapping(uint8_t int_num) +{ + if (int_num == 0) + { + return (link_layer_t)((XCVR_MISC->XCVR_CTRL & XCVR_CTRL_XCVR_CTRL_RADIO0_IRQ_SEL_MASK)>>XCVR_CTRL_XCVR_CTRL_RADIO0_IRQ_SEL_SHIFT); + } + else + { + return (link_layer_t)((XCVR_MISC->XCVR_CTRL & XCVR_CTRL_XCVR_CTRL_RADIO1_IRQ_SEL_MASK)>>XCVR_CTRL_XCVR_CTRL_RADIO1_IRQ_SEL_SHIFT); + } +} + +/* Get current state of radio mode and data rate */ +xcvrStatus_t XCVR_GetCurrentConfig(xcvr_currConfig_t * curr_config) +{ + xcvrStatus_t status = gXcvrInvalidParameters_c; + if (curr_config != NULL) + { + curr_config->radio_mode = current_xcvr_config.radio_mode; + curr_config->data_rate = current_xcvr_config.data_rate; + status = gXcvrSuccess_c; + } + return status; +} + +/* Customer level trim functions */ +xcvrStatus_t XCVR_SetXtalTrim(uint8_t xtalTrim) +{ + xcvrStatus_t status = gXcvrInvalidParameters_c; + + if ((xtalTrim & 0x80) == 0) + { + uint32_t temp; + temp = RSIM->ANA_TRIM; + temp &= ~RSIM_ANA_TRIM_BB_XTAL_TRIM_MASK; + RSIM->ANA_TRIM = temp | RSIM_ANA_TRIM_BB_XTAL_TRIM(xtalTrim); + status = gXcvrSuccess_c; + } + return status; +} + +uint8_t XCVR_GetXtalTrim(void) +{ + uint8_t temp_xtal; + temp_xtal = ((RSIM->ANA_TRIM & RSIM_ANA_TRIM_BB_XTAL_TRIM_MASK)>>RSIM_ANA_TRIM_BB_XTAL_TRIM_SHIFT); + return temp_xtal; +} + +/* RSSI adjustment */ +xcvrStatus_t XCVR_SetRssiAdjustment(int8_t adj) +{ + XCVR_RX_DIG->RSSI_CTRL_0 &= ~XCVR_RX_DIG_RSSI_CTRL_0_RSSI_ADJ_MASK; + XCVR_RX_DIG->RSSI_CTRL_0 |= XCVR_RX_DIG_RSSI_CTRL_0_RSSI_ADJ(adj); + return gXcvrSuccess_c; +} + +int8_t XCVR_GetRssiAdjustment(void) +{ + int8_t adj; + adj = (XCVR_RX_DIG->RSSI_CTRL_0 & XCVR_RX_DIG_RSSI_CTRL_0_RSSI_ADJ_MASK) >> XCVR_RX_DIG_RSSI_CTRL_0_RSSI_ADJ_SHIFT; + return adj; +} + +/* Radio debug functions */ +xcvrStatus_t XCVR_OverrideChannel(uint8_t channel, uint8_t useMappedChannel) +{ + uint32_t temp; + + if (channel == 0xFF) + { + /* Clear all of the overrides and restore to LL channel control */ + temp = XCVR_PLL_DIG->CHAN_MAP; + temp &= ~(XCVR_PLL_DIG_CHAN_MAP_CHANNEL_NUM_MASK | XCVR_PLL_DIG_CHAN_MAP_BOC_MASK +#if !RADIO_IS_GEN_2P1 + | XCVR_PLL_DIG_CHAN_MAP_ZOC_MASK +#endif /* !RADIO_IS_GEN_2P1 */ +#if RADIO_IS_GEN_3P0 + | XCVR_PLL_DIG_CHAN_MAP_HOP_TBL_CFG_OVRD_EN_MASK +#endif /* RADIO_IS_GEN_3P0 */ + ); + + XCVR_PLL_DIG->CHAN_MAP = temp; + + /* Stop using the manual frequency setting */ + XCVR_PLL_DIG->LPM_SDM_CTRL1 &= ~XCVR_PLL_DIG_LPM_SDM_CTRL1_SDM_MAP_DISABLE_MASK; + + return gXcvrSuccess_c; + } + + if (channel >= 128) + { + return gXcvrInvalidParameters_c; + } + + if (useMappedChannel) + { + temp = (XCVR_MISC->XCVR_CTRL & XCVR_CTRL_XCVR_CTRL_PROTOCOL_MASK)>>XCVR_CTRL_XCVR_CTRL_PROTOCOL_SHIFT; /* Extract PROTOCOL bitfield */ + + switch (temp) + { +#if !RADIO_IS_GEN_2P1 + case 0x3: /* ANT protocol */ + ANT->CHANNEL_NUM = channel; + break; +#endif /* !RADIO_IS_GEN_2P1 */ + case 0x8: /* GENFSK protocol */ + case 0x9: /* MSK protocol */ + GENFSK->CHANNEL_NUM = channel; + break; + default: /* All other protocols */ + temp = XCVR_PLL_DIG->CHAN_MAP; + temp &= ~(XCVR_PLL_DIG_CHAN_MAP_CHANNEL_NUM_MASK +#if RADIO_IS_GEN_3P0 + | XCVR_PLL_DIG_CHAN_MAP_HOP_TBL_CFG_OVRD_EN_MASK +#endif /* RADIO_IS_GEN_3P0 */ + ); + temp |= (XCVR_PLL_DIG_CHAN_MAP_CHANNEL_NUM(channel) | XCVR_PLL_DIG_CHAN_MAP_BOC_MASK +#if !RADIO_IS_GEN_2P1 + | XCVR_PLL_DIG_CHAN_MAP_ZOC_MASK +#endif /* !RADIO_IS_GEN_2P1 */ + ); + XCVR_PLL_DIG->CHAN_MAP = temp; + break; + } + } + else + { + XCVR_PLL_DIG->CHAN_MAP |= (XCVR_PLL_DIG_CHAN_MAP_BOC_MASK +#if !RADIO_IS_GEN_2P1 + | XCVR_PLL_DIG_CHAN_MAP_ZOC_MASK +#endif /* !RADIO_IS_GEN_2P1 */ + ); + + XCVR_PLL_DIG->LPM_SDM_CTRL3 = XCVR_PLL_DIG_LPM_SDM_CTRL3_LPM_DENOM(gPllDenom_c); + XCVR_PLL_DIG->LPM_SDM_CTRL2 = XCVR_PLL_DIG_LPM_SDM_CTRL2_LPM_NUM(mapTable[channel].numerator); + + temp = XCVR_PLL_DIG->LPM_SDM_CTRL1; + temp &= ~XCVR_PLL_DIG_LPM_SDM_CTRL1_LPM_INTG_MASK; + temp |= XCVR_PLL_DIG_LPM_SDM_CTRL1_LPM_INTG(mapTable[channel].integer); + XCVR_PLL_DIG->LPM_SDM_CTRL1 = temp; + + /* Stop using the LL channel map and use the manual frequency setting */ + XCVR_PLL_DIG->LPM_SDM_CTRL1 |= XCVR_PLL_DIG_LPM_SDM_CTRL1_SDM_MAP_DISABLE_MASK; + } + + return gXcvrSuccess_c; +} + +uint32_t XCVR_GetFreq ( void ) +{ + uint32_t pll_int; + uint32_t pll_num_unsigned; + int32_t pll_num; + uint32_t pll_denom; + float freq_float; + + if (XCVR_PLL_DIG->LPM_SDM_CTRL1 & XCVR_PLL_DIG_LPM_SDM_CTRL1_SDM_MAP_DISABLE_MASK) /* Not using mapped channels */ + { + pll_int = (XCVR_PLL_DIG->LPM_SDM_CTRL1 & XCVR_PLL_DIG_LPM_SDM_CTRL1_LPM_INTG_MASK) >> + XCVR_PLL_DIG_LPM_SDM_CTRL1_LPM_INTG_SHIFT; + + pll_num_unsigned = XCVR_PLL_DIG->LPM_SDM_CTRL2; + pll_denom = XCVR_PLL_DIG->LPM_SDM_CTRL3; + } + else + { + /* Using mapped channels so need to read from the _SELECTED fields to get the values being used */ + pll_int = (XCVR_PLL_DIG->LPM_SDM_CTRL1 & XCVR_PLL_DIG_LPM_SDM_CTRL1_LPM_INTG_SELECTED_MASK) >> + XCVR_PLL_DIG_LPM_SDM_CTRL1_LPM_INTG_SELECTED_SHIFT; + + pll_num_unsigned = XCVR_PLL_DIG->LPM_SDM_RES1; + pll_denom = XCVR_PLL_DIG->LPM_SDM_RES2; + } + + uint32_t freq = 0; + +#if RF_OSC_26MHZ == 1 + uint32_t ref_clk = 26U; +#else + uint32_t ref_clk = 32U; +#endif /* RF_OSC_26MHZ == 1 */ + + /* Check if sign bit is asserted */ + if (pll_num_unsigned & 0x04000000U) + { + /* Sign extend the numerator */ + pll_num = (~pll_num_unsigned + 1) & 0x03FFFFFFU; + + /* Calculate the frequency in MHz */ + freq_float = (ref_clk * 2 * (pll_int - ((float)pll_num / pll_denom))); + } + else + { + /* Calculate the frequency in MHz */ + pll_num = pll_num_unsigned; + freq_float = (ref_clk * 2 * (pll_int + ((float)pll_num / (float)pll_denom))); + } + + freq = (uint32_t)freq_float; + + return freq; +} + +void XCVR_ForceRxWu(void) +{ + XCVR_TSM->CTRL |= XCVR_TSM_CTRL_FORCE_RX_EN_MASK; +} + +void XCVR_ForceRxWd(void) +{ + XCVR_TSM->CTRL &= ~XCVR_TSM_CTRL_FORCE_RX_EN_MASK; +} + +void XCVR_ForceTxWu(void) +{ + XCVR_TSM->CTRL |= XCVR_TSM_CTRL_FORCE_TX_EN_MASK; +} + +void XCVR_ForceTxWd(void) +{ + XCVR_TSM->CTRL &= ~XCVR_TSM_CTRL_FORCE_TX_EN_MASK; +} + +xcvrStatus_t XCVR_DftTxCW(uint16_t rf_channel_freq, uint8_t protocol) +{ + uint32_t temp; + if ((protocol != 6) && (protocol != 7)) + { + return gXcvrInvalidParameters_c; /* Failure */ + } + + if ((rf_channel_freq < 2360) || (rf_channel_freq >2487)) + { + return gXcvrInvalidParameters_c; /* failure */ + } + + /* Set the DFT Mode */ + temp = XCVR_TX_DIG->CTRL; + temp &= ~XCVR_TX_DIG_CTRL_RADIO_DFT_MODE_MASK; + temp |= XCVR_TX_DIG_CTRL_RADIO_DFT_MODE(1); + XCVR_TX_DIG->CTRL = temp; + + /* Choose Protocol 6 or 7 if using the Channel Number register */ + temp = XCVR_MISC->XCVR_CTRL; + temp &= ~XCVR_CTRL_XCVR_CTRL_PROTOCOL_MASK; + temp |= XCVR_CTRL_XCVR_CTRL_PROTOCOL(protocol); + XCVR_MISC->XCVR_CTRL = temp; + + /* Select the RF Channel, using the Channel Number register */ + XCVR_OverrideChannel(rf_channel_freq-2360,1); + + /* Warm-up the Radio */ + XCVR_ForceTxWu(); + + return gXcvrSuccess_c; /* Success */ +} + +xcvrStatus_t XCVR_DftTxPatternReg(uint16_t channel_num, radio_mode_t radio_mode, data_rate_t data_rate, uint32_t tx_pattern) +{ + uint32_t temp; + uint8_t dft_mode = 0; + uint8_t dft_clk_sel = 0; + xcvrStatus_t status = gXcvrSuccess_c; + + XCVR_ChangeMode(radio_mode, data_rate); + + /* Select the RF Channel, using the Channel Number register */ + XCVR_OverrideChannel(channel_num, 1); + + switch (radio_mode) + { + case ZIGBEE_MODE: + dft_mode = 6; /* OQPSK configuration */ + break; + case ANT_MODE: + case BLE_MODE: + case GFSK_BT_0p5_h_0p5: + case GFSK_BT_0p5_h_0p32: + case GFSK_BT_0p5_h_0p7: + case GFSK_BT_0p5_h_1p0: + case GFSK_BT_0p3_h_0p5: + case GFSK_BT_0p7_h_0p5: + dft_mode = 2; /* GFSK configuration */ + break; + case MSK: + dft_mode = 4; /* MSK configuration */ + break; + default: + status = gXcvrInvalidParameters_c; + break; + } + + if (status == gXcvrSuccess_c) /* Only attempt this pointer assignment process if prior switch() statement completed successfully */ + { + switch (data_rate) + { + case DR_1MBPS: + dft_clk_sel = 4; + break; + case DR_500KBPS: + dft_clk_sel = 3; + break; + case DR_250KBPS: + dft_clk_sel = 2; + break; + default: + status = gXcvrInvalidParameters_c; + break; + } + } + + temp = XCVR_TX_DIG->CTRL; + temp &= ~(XCVR_TX_DIG_CTRL_RADIO_DFT_MODE_MASK | XCVR_TX_DIG_CTRL_DFT_CLK_SEL_MASK | XCVR_TX_DIG_CTRL_TX_DFT_EN_MASK | XCVR_TX_DIG_CTRL_LFSR_EN_MASK); + temp |= XCVR_TX_DIG_CTRL_RADIO_DFT_MODE(dft_mode) | + XCVR_TX_DIG_CTRL_DFT_CLK_SEL(dft_clk_sel) | + XCVR_TX_DIG_CTRL_TX_DFT_EN(1) | + XCVR_TX_DIG_CTRL_LFSR_EN(0); + XCVR_TX_DIG->CTRL = temp; + + XCVR_TX_DIG->DFT_PATTERN = tx_pattern; + + if (status == gXcvrSuccess_c) + { + /* Warm-up the Radio */ + XCVR_ForceTxWu(); + } + + return status; +} + +xcvrStatus_t XCVR_DftTxLfsrReg(uint16_t channel_num, radio_mode_t radio_mode, data_rate_t data_rate, uint8_t lfsr_length) +{ + uint32_t temp; + uint8_t dft_mode = 0; + uint8_t dft_clk_sel = 0; + xcvrStatus_t status = gXcvrSuccess_c; + uint8_t bitrate_setting = 0xFF; + + if (lfsr_length > 5) + { + return gXcvrInvalidParameters_c; + } + + XCVR_ChangeMode(radio_mode, data_rate); + + /* Select the RF Channel, using the Channel Number register */ + XCVR_OverrideChannel(channel_num, 1); + + switch (radio_mode) + { + case ZIGBEE_MODE: + dft_mode = 7; /* OQPSK configuration */ + break; + case ANT_MODE: + case BLE_MODE: + case GFSK_BT_0p5_h_0p5: + case GFSK_BT_0p5_h_0p32: + case GFSK_BT_0p5_h_0p7: + case GFSK_BT_0p5_h_1p0: + case GFSK_BT_0p3_h_0p5: + case GFSK_BT_0p7_h_0p5: + dft_mode = 3; /* GFSK configuration */ + bitrate_setting = data_rate; + break; + case MSK: + dft_mode = 5; /* MSK configuration */ + break; + + default: + status = gXcvrInvalidParameters_c; + break; + } + + if (status == gXcvrSuccess_c) + { + switch (data_rate) + { + case DR_1MBPS: + dft_clk_sel = 4; + break; + case DR_500KBPS: + dft_clk_sel = 3; + break; + case DR_250KBPS: + dft_clk_sel = 2; + break; + default: + status = gXcvrInvalidParameters_c; + break; + } + } + + if (bitrate_setting < 4) + { + GENFSK->BITRATE = bitrate_setting; + } + + temp = XCVR_TX_DIG->CTRL; + temp &= ~(XCVR_TX_DIG_CTRL_RADIO_DFT_MODE_MASK | + XCVR_TX_DIG_CTRL_LFSR_LENGTH_MASK | + XCVR_TX_DIG_CTRL_DFT_CLK_SEL_MASK | + XCVR_TX_DIG_CTRL_TX_DFT_EN_MASK | + XCVR_TX_DIG_CTRL_LFSR_EN_MASK); + temp |= XCVR_TX_DIG_CTRL_RADIO_DFT_MODE(dft_mode) | + XCVR_TX_DIG_CTRL_LFSR_LENGTH(lfsr_length) | + XCVR_TX_DIG_CTRL_DFT_CLK_SEL(dft_clk_sel) | + XCVR_TX_DIG_CTRL_TX_DFT_EN(0) | + XCVR_TX_DIG_CTRL_LFSR_EN(1); + XCVR_TX_DIG->CTRL = temp; + + if (status == gXcvrSuccess_c) + { + /* Warm-up the Radio */ + XCVR_ForceTxWu(); + } + + return status; +} + +void XCVR_DftTxOff(void) +{ + XCVR_ForceTxWd(); + XCVR_MISC->XCVR_CTRL |= XCVR_CTRL_XCVR_CTRL_TGT_PWR_SRC_MASK; /* Use PA_POWER in LL registers */ + /* Clear the RF Channel over-ride */ + XCVR_OverrideChannel(0xFF,1); + XCVR_TX_DIG->CTRL &= ~(XCVR_TX_DIG_CTRL_RADIO_DFT_MODE_MASK | /* Clear DFT_MODE */ + XCVR_TX_DIG_CTRL_DFT_CLK_SEL_MASK | /* Clear DFT_CLK_SEL */ + XCVR_TX_DIG_CTRL_TX_DFT_EN_MASK | /* Clear DFT_EN */ + XCVR_TX_DIG_CTRL_LFSR_EN_MASK);/* Clear LFSR_EN */ +} + +xcvrStatus_t XCVR_ForcePAPower(uint8_t pa_power) +{ + if (pa_power > 0x3F) + { + return gXcvrInvalidParameters_c; /* Failure */ + } + + if (pa_power != 1) + { + pa_power = pa_power & 0xFEU; /* Ensure LSbit is cleared */ + } + + XCVR_MISC->XCVR_CTRL &= ~XCVR_CTRL_XCVR_CTRL_TGT_PWR_SRC_MASK; /* Use PA_POWER in TSM registers */ + XCVR_TSM->PA_POWER = pa_power; + + return gXcvrSuccess_c; /* Success */ +} + +xcvrStatus_t XCVR_CoexistenceInit(void) +{ +#if gMWS_UseCoexistence_d + uint32_t temp = 0x00U; + uint32_t end_of_tx_wu = 0x00U; + uint32_t end_of_rx_wu = 0x00U; + +#if (gMWS_Coex_Model_d == gMWS_Coex_Status_Prio_d) +#if (XCVR_COEX_RF_ACTIVE_PIN == ANT_A) + uint32_t tsm_timing47 = 0x00U; +#else /* (XCVR_COEX_RF_ACTIVE_PIN == ANT_B) */ + uint32_t tsm_timing48 = 0x00U; +#endif /* (XCVR_COEX_RF_ACTIVE_PIN == ANT_A) */ + uint32_t tsm_timing50 = 0x00U; +#endif /* (gMWS_Coex_Model_d == gMWS_Coex_Status_Prio_d) */ + +#if (gMWS_Coex_Model_d == gMWS_Coex_Prio_Only_d) + // RF_ACTIVE = ANT_B (PTC1, gpio1_trig_en) + uint32_t tsm_timing48 = 0x00U; + // RF_PRIORITY = ANT_A (PTC4, gpio0_trig_en) + uint32_t tsm_timing47 = 0x00U; +#endif /* (gMWS_Coex_Model_d == gMWS_Coex_Prio_Only_d) */ + + uint16_t tsm_timing43_rx = 0x00; + uint16_t tsm_timing43_tx = 0x00; + + /* Select GPIO mode for FAD pins */ + temp = XCVR_MISC->FAD_CTRL; + temp &= ~(XCVR_CTRL_FAD_CTRL_FAD_NOT_GPIO_MASK); + XCVR_MISC->FAD_CTRL = temp; + + /* Read the END_OF_TX_WU and END_OF_RX_WU for XCVR */ + end_of_tx_wu = (XCVR_TSM->END_OF_SEQ & XCVR_TSM_END_OF_SEQ_END_OF_TX_WU_MASK) >> + XCVR_TSM_END_OF_SEQ_END_OF_TX_WU_SHIFT; + end_of_rx_wu = (XCVR_TSM->END_OF_SEQ & XCVR_TSM_END_OF_SEQ_END_OF_RX_WU_MASK) >> + XCVR_TSM_END_OF_SEQ_END_OF_RX_WU_SHIFT; + +/***************** + * TX SEQUENCE * + *****************/ + + if (end_of_tx_wu < gMWS_CoexRfActiveAssertTime_d) + { + temp = end_of_tx_wu; + } + else + { + temp = gMWS_CoexRfActiveAssertTime_d; + } + + /* Save the TX RF_ACTIVE start time. */ + tsm_timing43_tx = end_of_tx_wu - temp; + +#if (gMWS_Coex_Model_d == gMWS_Coex_Status_Prio_d) + /* Set RF_ACTIVE pin HIGH gMWS_CoexRfActiveAssertTime_d uS prior to any TX sequence. */ +#if (XCVR_COEX_RF_ACTIVE_PIN == ANT_A) + tsm_timing47 = (((uint32_t)(end_of_tx_wu - temp) << XCVR_TSM_TIMING47_GPIO0_TRIG_EN_TX_HI_SHIFT) & + XCVR_TSM_TIMING47_GPIO0_TRIG_EN_TX_HI_MASK); +#else + tsm_timing48 = (((uint32_t)(end_of_tx_wu - temp) << XCVR_TSM_TIMING48_GPIO1_TRIG_EN_TX_HI_SHIFT) & + XCVR_TSM_TIMING48_GPIO1_TRIG_EN_TX_HI_MASK); +#endif /* (XCVR_COEX_RF_ACTIVE_PIN == ANT_A) */ + + /* Set STATUS pin HIGH gMWS_CoexRfActiveAssertTime_d uS prior to any TX sequence. */ + tsm_timing50 = (((uint32_t)(end_of_tx_wu - temp) << XCVR_TSM_TIMING50_GPIO3_TRIG_EN_TX_HI_SHIFT) & + XCVR_TSM_TIMING50_GPIO3_TRIG_EN_TX_HI_MASK); +#endif /* (gMWS_Coex_Model_d == gMWS_Coex_Status_Prio_d) */ + +#if (gMWS_Coex_Model_d == gMWS_Coex_Prio_Only_d) + /* Set RF_ACTIVE pin HIGH gMWS_CoexRfActiveAssertTime_d uS prior to any TX sequence. */ + tsm_timing48 = (((uint32_t)(end_of_tx_wu - temp) << XCVR_TSM_TIMING48_GPIO1_TRIG_EN_TX_HI_SHIFT) & + XCVR_TSM_TIMING48_GPIO1_TRIG_EN_TX_HI_MASK); + + /* Set STATUS pin HIGH gMWS_CoexRfActiveAssertTime_d uS prior to any TX sequence. */ + tsm_timing47 = (((uint32_t)(end_of_tx_wu - temp) << XCVR_TSM_TIMING47_GPIO0_TRIG_EN_TX_HI_SHIFT) & + XCVR_TSM_TIMING47_GPIO0_TRIG_EN_TX_HI_MASK); +#endif /* (gMWS_Coex_Model_d == gMWS_Coex_Prio_Only_d) */ + +/***************** + * RX SEQUENCE * + *****************/ + + if (end_of_rx_wu < gMWS_CoexRfActiveAssertTime_d) + { + temp = end_of_rx_wu; + } + else + { + temp = gMWS_CoexRfActiveAssertTime_d; + } + + /* Save the RX RF_ACTIVE start time. */ + tsm_timing43_rx = end_of_rx_wu - temp; + +#if (gMWS_Coex_Model_d == gMWS_Coex_Status_Prio_d) + /* Set RF_ACTIVE pin HIGH gMWS_CoexRfActiveAssertTime_d uS prior to any RX sequence. */ +#if (XCVR_COEX_RF_ACTIVE_PIN == ANT_A) + tsm_timing47 |= (((uint32_t)(end_of_rx_wu - temp) << XCVR_TSM_TIMING47_GPIO0_TRIG_EN_RX_HI_SHIFT) & + XCVR_TSM_TIMING47_GPIO0_TRIG_EN_RX_HI_MASK); +#else + tsm_timing48 |= (((uint32_t)(end_of_rx_wu - temp) << XCVR_TSM_TIMING48_GPIO1_TRIG_EN_RX_HI_SHIFT) & + XCVR_TSM_TIMING48_GPIO1_TRIG_EN_RX_HI_MASK); +#endif /* (XCVR_COEX_RF_ACTIVE_PIN == ANT_A) */ + + /* Set STATUS pin HIGH gMWS_CoexRfActiveAssertTime_d uS prior to any RX sequence and clear it gMWS_CoexPrioSignalTime_d uS before RX start. */ + tsm_timing50 |= ((((uint32_t)(end_of_rx_wu - temp) << XCVR_TSM_TIMING50_GPIO3_TRIG_EN_RX_HI_SHIFT) & + XCVR_TSM_TIMING50_GPIO3_TRIG_EN_RX_HI_MASK) | + (((uint32_t)(end_of_rx_wu - gMWS_CoexPrioSignalTime_d) << XCVR_TSM_TIMING50_GPIO3_TRIG_EN_RX_LO_SHIFT) & + XCVR_TSM_TIMING50_GPIO3_TRIG_EN_RX_LO_MASK)); + +#if (XCVR_COEX_RF_ACTIVE_PIN == ANT_A) + temp = XCVR_TSM->TIMING47; + temp &= ~(XCVR_TSM_TIMING47_GPIO0_TRIG_EN_TX_HI_MASK | XCVR_TSM_TIMING47_GPIO0_TRIG_EN_RX_HI_MASK); + temp |= tsm_timing47; + XCVR_TSM->TIMING47 = temp; +#else + temp = XCVR_TSM->TIMING48; + temp &= ~(XCVR_TSM_TIMING48_GPIO1_TRIG_EN_TX_HI_MASK | XCVR_TSM_TIMING48_GPIO1_TRIG_EN_RX_HI_MASK); + temp |= tsm_timing48; + XCVR_TSM->TIMING48 = temp; +#endif /* (XCVR_COEX_RF_ACTIVE_PIN == ANT_A) */ + + temp = XCVR_TSM->TIMING50; + temp &= ~(XCVR_TSM_TIMING50_GPIO3_TRIG_EN_TX_HI_MASK | + XCVR_TSM_TIMING50_GPIO3_TRIG_EN_RX_HI_MASK | + XCVR_TSM_TIMING50_GPIO3_TRIG_EN_RX_LO_MASK); + temp |= tsm_timing50; + XCVR_TSM->TIMING50 = temp; + +#if (XCVR_COEX_RF_ACTIVE_PIN == ANT_A) + GPIOC->PDDR |= 0x18; + PORTC->PCR[4] = (PORTC->PCR[4] & ~PORT_PCR_MUX_MASK) | PORT_PCR_MUX(2); + PORTC->PCR[3] = (PORTC->PCR[3] & ~PORT_PCR_MUX_MASK) | PORT_PCR_MUX(2); +#else + GPIOC->PDDR |= 0x0A; + PORTC->PCR[1] = (PORTC->PCR[1] & ~PORT_PCR_MUX_MASK) | PORT_PCR_MUX(2); + PORTC->PCR[3] = (PORTC->PCR[3] & ~PORT_PCR_MUX_MASK) | PORT_PCR_MUX(2); +#endif /* (XCVR_COEX_RF_ACTIVE_PIN == ANT_A) */ +#endif /* (gMWS_Coex_Model_d == gMWS_Coex_Status_Prio_d) */ + +#if (gMWS_Coex_Model_d == gMWS_Coex_Prio_Only_d) + /* Set RF_ACTIVE pin HIGH gMWS_CoexRfActiveAssertTime_d uS prior to any RX sequence. */ + tsm_timing48 |= (((uint32_t)(end_of_rx_wu - temp) << XCVR_TSM_TIMING48_GPIO1_TRIG_EN_RX_HI_SHIFT) & + XCVR_TSM_TIMING48_GPIO1_TRIG_EN_RX_HI_MASK); + + /* Set PRIORITY pin HIGH gMWS_CoexRfActiveAssertTime_d uS prior to any RX sequence and clear it gMWS_CoexPrioSignalTime_d uS before RX start. */ + tsm_timing47 |= (((uint32_t)(end_of_rx_wu - temp) << XCVR_TSM_TIMING47_GPIO0_TRIG_EN_RX_HI_SHIFT) & + XCVR_TSM_TIMING47_GPIO0_TRIG_EN_RX_HI_MASK); + + /* RF_ACTIVE */ + temp = XCVR_TSM->TIMING48; + temp &= ~(XCVR_TSM_TIMING48_GPIO1_TRIG_EN_TX_HI_MASK | XCVR_TSM_TIMING48_GPIO1_TRIG_EN_RX_HI_MASK); + temp |= tsm_timing48; + XCVR_TSM->TIMING48 = temp; + + /* RF_PRIORITY */ + temp = XCVR_TSM->TIMING47; + temp &= ~(XCVR_TSM_TIMING47_GPIO0_TRIG_EN_TX_HI_MASK | XCVR_TSM_TIMING47_GPIO0_TRIG_EN_RX_HI_MASK); + temp |= tsm_timing47; + XCVR_TSM->TIMING47 = temp; + + /* Overwrite pins settings */ + GPIOC->PDDR |= 0x12; + PORTC->PCR[4] = (PORTC->PCR[4] & ~PORT_PCR_MUX_MASK) | PORT_PCR_MUX(2); + PORTC->PCR[1] = (PORTC->PCR[1] & ~PORT_PCR_MUX_MASK) | PORT_PCR_MUX(2); +#endif /* (gMWS_Coex_Model_d == gMWS_Coex_Prio_Only_d) */ + + tsm_timing43_tx += gMWS_CoexConfirmWaitTime_d; + + if (tsm_timing43_tx > end_of_tx_wu - 1) + { + tsm_timing43_tx = end_of_tx_wu - 1; + } + + tsm_timing43_rx += gMWS_CoexConfirmWaitTime_d; + + if (tsm_timing43_rx > end_of_rx_wu - 1) + { + tsm_timing43_rx = end_of_rx_wu - 1; + } + + XCVR_TSM->TIMING43 = ((((uint32_t)(tsm_timing43_tx) << XCVR_TSM_TIMING43_TSM_SPARE0_EN_TX_HI_SHIFT) & XCVR_TSM_TIMING43_TSM_SPARE0_EN_TX_HI_MASK) | + (((uint32_t)(tsm_timing43_tx + 2) << XCVR_TSM_TIMING43_TSM_SPARE0_EN_TX_LO_SHIFT) & XCVR_TSM_TIMING43_TSM_SPARE0_EN_TX_LO_MASK) | + (((uint32_t)(tsm_timing43_rx) << XCVR_TSM_TIMING43_TSM_SPARE0_EN_RX_HI_SHIFT) & XCVR_TSM_TIMING43_TSM_SPARE0_EN_RX_HI_MASK) | + (((uint32_t)(tsm_timing43_rx + 2) << XCVR_TSM_TIMING43_TSM_SPARE0_EN_RX_LO_SHIFT) & XCVR_TSM_TIMING43_TSM_SPARE0_EN_RX_LO_MASK)); + + BTLE_RF->MISC_CTRL = 0x02; + + XCVR_TSM->CTRL |= XCVR_TSM_CTRL_TSM_IRQ0_EN_MASK; + + /* Save the updated registers values. */ + XCVR_CoexistenceSaveRestoreTimings(1); +#endif /* gMWS_UseCoexistence_d */ + + return gXcvrSuccess_c; +} + +xcvrStatus_t XCVR_CoexistenceSetPriority(XCVR_COEX_PRIORITY_T rxPriority, XCVR_COEX_PRIORITY_T txPriority) +{ +#if gMWS_UseCoexistence_d + uint32_t temp = 0x00U; + uint32_t end_of_tx_wu = 0x00U; + uint32_t end_of_rx_wu = 0x00U; +#if (gMWS_Coex_Model_d == gMWS_Coex_Status_Prio_d) + uint32_t tsm_timing50 = 0x00U; +#endif +#if (gMWS_Coex_Model_d == gMWS_Coex_Prio_Only_d) + uint32_t tsm_timing47 = 0x00U; +#endif + + /* Read the END_OF_TX_WU and END_OF_RX_WU for XCVR */ + end_of_tx_wu = (XCVR_TSM->END_OF_SEQ & XCVR_TSM_END_OF_SEQ_END_OF_TX_WU_MASK) >> + XCVR_TSM_END_OF_SEQ_END_OF_TX_WU_SHIFT; + end_of_rx_wu = (XCVR_TSM->END_OF_SEQ & XCVR_TSM_END_OF_SEQ_END_OF_RX_WU_MASK) >> + XCVR_TSM_END_OF_SEQ_END_OF_RX_WU_SHIFT; + +/***************** + * RX * + *****************/ + + if (XCVR_COEX_HIGH_PRIO == rxPriority) + { + if (end_of_rx_wu < gMWS_CoexRfActiveAssertTime_d) + { + temp = end_of_rx_wu; + } + else + { + temp = gMWS_CoexRfActiveAssertTime_d; + } + +#if (gMWS_Coex_Model_d == gMWS_Coex_Status_Prio_d) + /* Set STATUS pin HIGH gMWS_CoexRfActiveAssertTime_d uS prior to any RX sequence and clear it gMWS_CoexPrioSignalTime_d uS before RX start for high priority RX. */ + tsm_timing50 = ((((uint32_t)(end_of_rx_wu - temp) << XCVR_TSM_TIMING50_GPIO3_TRIG_EN_RX_HI_SHIFT) & + XCVR_TSM_TIMING50_GPIO3_TRIG_EN_RX_HI_MASK) | + (((uint32_t)(end_of_rx_wu - gMWS_CoexPrioSignalTime_d) << XCVR_TSM_TIMING50_GPIO3_TRIG_EN_RX_LO_SHIFT) & + XCVR_TSM_TIMING50_GPIO3_TRIG_EN_RX_LO_MASK)); +#endif /* (gMWS_Coex_Model_d == gMWS_Coex_Status_Prio_d) */ +#if (gMWS_Coex_Model_d == gMWS_Coex_Prio_Only_d) + /* Set STATUS pin HIGH gMWS_CoexRfActiveAssertTime_d uS prior to any RX sequence */ + tsm_timing47 = (((uint32_t)(end_of_rx_wu - temp) << XCVR_TSM_TIMING47_GPIO0_TRIG_EN_RX_HI_SHIFT) & + XCVR_TSM_TIMING47_GPIO0_TRIG_EN_RX_HI_MASK); +#endif /* (gMWS_Coex_Model_d == gMWS_Coex_Prio_Only_d) */ + } + else + { + /* Low priority RX */ +#if (gMWS_Coex_Model_d == gMWS_Coex_Status_Prio_d) + tsm_timing50 = (((0xFFU << XCVR_TSM_TIMING50_GPIO3_TRIG_EN_RX_HI_SHIFT) & + XCVR_TSM_TIMING50_GPIO3_TRIG_EN_RX_HI_MASK) | + ((0xFFU << XCVR_TSM_TIMING50_GPIO3_TRIG_EN_RX_LO_SHIFT) & + XCVR_TSM_TIMING50_GPIO3_TRIG_EN_RX_LO_MASK)); +#endif /* (gMWS_Coex_Model_d == gMWS_Coex_Status_Prio_d) */ +#if (gMWS_Coex_Model_d == gMWS_Coex_Prio_Only_d) + tsm_timing47 = (((0xFFU << XCVR_TSM_TIMING47_GPIO0_TRIG_EN_RX_HI_SHIFT) & + XCVR_TSM_TIMING47_GPIO0_TRIG_EN_RX_HI_MASK) | + ((0xFFU << XCVR_TSM_TIMING47_GPIO0_TRIG_EN_RX_LO_SHIFT) & + XCVR_TSM_TIMING47_GPIO0_TRIG_EN_RX_LO_MASK)); +#endif /* (gMWS_Coex_Model_d == gMWS_Coex_Prio_Only_d) */ + } + +/***************** + * TX * + *****************/ + if (XCVR_COEX_HIGH_PRIO == txPriority) + { + if (end_of_tx_wu < gMWS_CoexRfActiveAssertTime_d) + { + temp = end_of_tx_wu; + } + else + { + temp = gMWS_CoexRfActiveAssertTime_d; + } + + /* Set STATUS pin HIGH gMWS_CoexRfActiveAssertTime_d uS prior to any TX sequence for HIGH priority TX. */ +#if (gMWS_Coex_Model_d == gMWS_Coex_Status_Prio_d) + tsm_timing50 |= (((uint32_t)(end_of_tx_wu - temp) << XCVR_TSM_TIMING50_GPIO3_TRIG_EN_TX_HI_SHIFT) & + XCVR_TSM_TIMING50_GPIO3_TRIG_EN_TX_HI_MASK); +#endif /* (gMWS_Coex_Model_d == gMWS_Coex_Status_Prio_d) */ +#if (gMWS_Coex_Model_d == gMWS_Coex_Prio_Only_d) + tsm_timing47 |= (((uint32_t)(end_of_tx_wu - temp) << XCVR_TSM_TIMING47_GPIO0_TRIG_EN_TX_HI_SHIFT) & + XCVR_TSM_TIMING47_GPIO0_TRIG_EN_TX_HI_MASK); +#endif /* (gMWS_Coex_Model_d == gMWS_Coex_Prio_Only_d) */ + } + else + { +#if (gMWS_Coex_Model_d == gMWS_Coex_Status_Prio_d) + /* Set STATUS pin HIGH at END_OF_TX_WU prior to any TX sequence for LOW priority TX. */ + tsm_timing50 |= (((uint32_t)(end_of_tx_wu) << XCVR_TSM_TIMING50_GPIO3_TRIG_EN_TX_HI_SHIFT) & + XCVR_TSM_TIMING50_GPIO3_TRIG_EN_TX_HI_MASK); +#endif /* (gMWS_Coex_Model_d == gMWS_Coex_Status_Prio_d) */ +#if (gMWS_Coex_Model_d == gMWS_Coex_Prio_Only_d) + /* Set STATUS pin LOW at END_OF_TX_WU prior to any TX sequence for LOW priority TX. */ + tsm_timing47 = (((0xFFU << XCVR_TSM_TIMING47_GPIO0_TRIG_EN_TX_HI_SHIFT) & + XCVR_TSM_TIMING47_GPIO0_TRIG_EN_TX_HI_MASK) | + ((0xFFU << XCVR_TSM_TIMING47_GPIO0_TRIG_EN_TX_LO_SHIFT) & + XCVR_TSM_TIMING47_GPIO0_TRIG_EN_TX_LO_MASK)); +#endif /* (gMWS_Coex_Model_d == gMWS_Coex_Prio_Only_d) */ + } + +#if (gMWS_Coex_Model_d == gMWS_Coex_Status_Prio_d) + temp = XCVR_TSM->TIMING50; + temp &= ~(XCVR_TSM_TIMING50_GPIO3_TRIG_EN_TX_HI_MASK | + XCVR_TSM_TIMING50_GPIO3_TRIG_EN_RX_HI_MASK | + XCVR_TSM_TIMING50_GPIO3_TRIG_EN_RX_LO_MASK); + temp |= tsm_timing50; + XCVR_TSM->TIMING50 = temp; +#endif /* (gMWS_Coex_Model_d == gMWS_Coex_Status_Prio_d) */ +#if (gMWS_Coex_Model_d == gMWS_Coex_Prio_Only_d) + temp = XCVR_TSM->TIMING47; + temp &= ~(XCVR_TSM_TIMING47_GPIO0_TRIG_EN_TX_HI_MASK | + XCVR_TSM_TIMING47_GPIO0_TRIG_EN_TX_LO_MASK | + XCVR_TSM_TIMING47_GPIO0_TRIG_EN_RX_HI_MASK | + XCVR_TSM_TIMING47_GPIO0_TRIG_EN_RX_LO_MASK); + temp |= tsm_timing47; + XCVR_TSM->TIMING47 = temp; +#endif /* (gMWS_Coex_Model_d == gMWS_Coex_Prio_Only_d) */ + + /* Save the updated registers values. */ + XCVR_CoexistenceSaveRestoreTimings(1); +#endif /* gMWS_UseCoexistence_d */ + + return gXcvrSuccess_c; +} + +xcvrStatus_t XCVR_CoexistenceSaveRestoreTimings(uint8_t saveTimings) +{ +#if gMWS_UseCoexistence_d + static uint32_t tsm_ovrd0_saved = 0x00; + static uint32_t tsm_ovrd1_saved = 0x00; + static uint32_t tsm_ovrd2_saved = 0x00; + static uint32_t tsm_ovrd3_saved = 0x00; + static uint32_t tsm_timing47_saved = 0x00; + static uint32_t tsm_timing48_saved = 0x00; +#if (gMWS_Coex_Model_d == gMWS_Coex_Status_Prio_d) + static uint32_t tsm_timing49_saved = 0x00; + static uint32_t tsm_timing50_saved = 0x00; +#endif + + if (saveTimings == 0) + { + /* Restore registers values. */ + XCVR_TSM->OVRD0 = tsm_ovrd0_saved; + XCVR_TSM->OVRD1 = tsm_ovrd1_saved; + XCVR_TSM->OVRD2 = tsm_ovrd2_saved; + XCVR_TSM->OVRD3 = tsm_ovrd3_saved; + + XCVR_TSM->TIMING47 = tsm_timing47_saved; + XCVR_TSM->TIMING48 = tsm_timing48_saved; +#if (gMWS_Coex_Model_d == gMWS_Coex_Status_Prio_d) + XCVR_TSM->TIMING49 = tsm_timing49_saved; + XCVR_TSM->TIMING50 = tsm_timing50_saved; +#endif + } + else + { + /* Save registers values. */ + tsm_ovrd0_saved = XCVR_TSM->OVRD0; + tsm_ovrd1_saved = XCVR_TSM->OVRD1; + tsm_ovrd2_saved = XCVR_TSM->OVRD2; + tsm_ovrd3_saved = XCVR_TSM->OVRD3; + tsm_timing47_saved = XCVR_TSM->TIMING47; + tsm_timing48_saved = XCVR_TSM->TIMING48; +#if (gMWS_Coex_Model_d == gMWS_Coex_Status_Prio_d) + tsm_timing49_saved = XCVR_TSM->TIMING49; + tsm_timing50_saved = XCVR_TSM->TIMING50; +#endif + } +#endif /* gMWS_UseCoexistence_d */ + + return gXcvrSuccess_c; +} + diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/fsl_xcvr.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/fsl_xcvr.h new file mode 100644 index 0000000000..9403f81df9 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/fsl_xcvr.h @@ -0,0 +1,1236 @@ +/* + * 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 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_XCVR_H_ +/* clang-format off */ +#define _FSL_XCVR_H_ +/* clang-format on */ + +#include "fsl_device_registers.h" +#include "fsl_xcvr_trim.h" + +#if gMWS_UseCoexistence_d +#include "MWS.h" +#endif /* gMWS_UseCoexistence_d */ +/*! + * @addtogroup xcvr + * @{ + */ + +/*! @file*/ + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/* KW4xZ/KW3xZ/KW2xZ Radio type */ +#define RADIO_IS_GEN_2P0 (1) + +/* Default RF OSC definition. Allows for compile time clock frequency definition */ +#ifdef CLOCK_MAIN + +#else +#if RF_OSC_26MHZ == 1 +#define CLOCK_MAIN (EXT_CLK_26_MHZ) /* See ext_clock_config_t for this value */ +#else +#define CLOCK_MAIN (EXT_CLK_32_MHZ) /* See ext_clock_config_t for this value */ +#endif /* RF_OSC_26MHZ == 1 */ +#endif /* CLOCK_MAIN */ + +#define TBD_ZERO (0) +#define FSL_XCVR_DRIVER_VERSION (MAKE_VERSION(0, 1, 0)) + +#define B0(x) (((uint32_t)(((uint32_t)(x)) << 0)) & 0xFFU) +#define B1(x) (((uint32_t)(((uint32_t)(x)) << 8)) & 0xFF00U) +#define B2(x) (((uint32_t)(((uint32_t)(x)) << 16)) & 0xFF0000U) +#define B3(x) (((uint32_t)(((uint32_t)(x)) << 24)) & 0xFF000000U) + +#define USE_DEFAULT_PRE_REF (0) +#define TRIM_BBA_DCOC_DAC_AT_INIT (1) +#define PRESLOW_ENA (1) + +/* GEN3 TSM defines */ +#if RADIO_IS_GEN_3P0 + +/* TSM timings initializations for Gen3 radio */ +/* NOTE: These timings are stored in 32MHz or 26MHz "baseline" settings, selected by conditional compile below */ +/* The init structures for 32Mhz and 26MHz are made identical to allow the same code in fsl_xcvr.c to apply the */ +/* settings for all radio generations. The Gen2 radio init value storage had a different structure so this preserves compatibility */ +#if RF_OSC_26MHZ == 1 +#define TSM_TIMING00init (0x6d006f00U) /* (bb_ldo_hf_en) */ +#define TSM_TIMING01init (0x6d006f00U) /* (bb_ldo_adcdac_en) */ +#define TSM_TIMING02init (0x6d00ffffU) /* (bb_ldo_bba_en) */ +#define TSM_TIMING03init (0x6d006f00U) /* (bb_ldo_pd_en) */ +#define TSM_TIMING04init (0x6d006f00U) /* (bb_ldo_fdbk_en) */ +#define TSM_TIMING05init (0x6d006f00U) /* (bb_ldo_vcolo_en) */ +#define TSM_TIMING06init (0x6d006f00U) /* (bb_ldo_vtref_en) */ +#define TSM_TIMING07init (0x05000500U) /* (bb_ldo_fdbk_bleed_en) */ +#define TSM_TIMING08init (0x03000300U) /* (bb_ldo_vcolo_bleed_en) */ +#define TSM_TIMING09init (0x03000300U) /* (bb_ldo_vcolo_fastcharge_en) */ +#define TSM_TIMING10init (0x6d036f03U) /* (bb_xtal_pll_ref_clk_en) */ +#define TSM_TIMING11init (0xffff6f03U) /* (bb_xtal_dac_ref_clk_en) */ +#define TSM_TIMING12init (0x6d03ffffU) /* (rxtx_auxpll_vco_ref_clk_en) */ +#define TSM_TIMING13init (0x18004c00U) /* (sy_vco_autotune_en) */ +#define TSM_TIMING14init (0x6d356863U) /* (sy_pd_cycle_slip_ld_ft_en) */ +#define TSM_TIMING15init (0x6d036f03U) /* (sy_vco_en) */ +#define TSM_TIMING16init (0x6d20ffffU) /* (sy_lo_rx_buf_en) */ +#define TSM_TIMING17init (0xffff6f58U) /* (sy_lo_tx_buf_en) */ +#define TSM_TIMING18init (0x6d056f05U) /* (sy_divn_en) */ +#define TSM_TIMING19init (0x18034c03U) /* (sy_pd_filter_charge_en) */ +#define TSM_TIMING20init (0x6d036f03U) /* (sy_pd_en) */ +#define TSM_TIMING21init (0x6d046f04U) /* (sy_lo_divn_en) */ +#define TSM_TIMING22init (0x6d04ffffU) /* (sy_lo_rx_en) */ +#define TSM_TIMING23init (0xffff6f04U) /* (sy_lo_tx_en) */ +#define TSM_TIMING24init (0x18004c00U) /* (sy_divn_cal_en) */ +#define TSM_TIMING25init (0x6d21ffffU) /* (rx_lna_mixer_en) */ +#define TSM_TIMING26init (0xffff6e58U) /* (tx_pa_en) */ +#define TSM_TIMING27init (0x6d24ffffU) /* (rx_adc_i_q_en) */ +#define TSM_TIMING28init (0x2524ffffU) /* (rx_adc_reset_en) */ +#define TSM_TIMING29init (0x6d22ffffU) /* (rx_bba_i_q_en) */ +#define TSM_TIMING30init (0x6d24ffffU) /* (rx_bba_pdet_en) */ +#define TSM_TIMING31init (0x6d23ffffU) /* (rx_bba_tza_dcoc_en) */ +#define TSM_TIMING32init (0x6d21ffffU) /* (rx_tza_i_q_en) */ +#define TSM_TIMING33init (0x6d24ffffU) /* (rx_tza_pdet_en) */ +#define TSM_TIMING34init (0x6d076f07U) /* (pll_dig_en) */ +#define TSM_TIMING35init (0xffff6f5fU) /* (tx_dig_en) */ +#define TSM_TIMING36init (0x6d6affffU) /* (rx_dig_en) */ +#define TSM_TIMING37init (0x6b6affffU) /* (rx_init) */ +#define TSM_TIMING38init (0x6d0e6f42U) /* (sigma_delta_en) */ +#define TSM_TIMING39init (0x6d6affffU) /* (rx_phy_en) */ +#define TSM_TIMING40init (0x6d2affffU) /* (dcoc_en) */ +#define TSM_TIMING41init (0x2b2affffU) /* (dcoc_init) */ +#define TSM_TIMING42init (0xffffffffU) /* (sar_adc_trig_en) */ +#define TSM_TIMING43init (0xffffffffU) /* (tsm_spare0_en) */ +#define TSM_TIMING44init (0xffffffffU) /* (tsm_spare1_en) */ +#define TSM_TIMING45init (0xffffffffU) /* (tsm_spare2_en) */ +#define TSM_TIMING46init (0xffffffffU) /* (tsm_spare3_en) */ +#define TSM_TIMING47init (0xffffffffU) /* (gpio0_trig_en) */ +#define TSM_TIMING48init (0xffffffffU) /* (gpio1_trig_en) */ +#define TSM_TIMING49init (0xffffffffU) /* (gpio2_trig_en) */ +#define TSM_TIMING50init (0xffffffffU) /* (gpio3_trig_en) */ +#define TSM_TIMING51init (0x6d03ffffU) /* (rxtx_auxpll_bias_en) */ +#define TSM_TIMING52init (0x1b06ffffU) /* (rxtx_auxpll_fcal_en) */ +#define TSM_TIMING53init (0x6d03ffffU) /* (rxtx_auxpll_lf_pd_en) */ +#define TSM_TIMING54init (0x1b03ffffU) /* (rxtx_auxpll_pd_lf_filter_charge_en) */ +#define TSM_TIMING55init (0x6d24ffffU) /* (rxtx_auxpll_adc_buf_en) */ +#define TSM_TIMING56init (0x6d24ffffU) /* (rxtx_auxpll_dig_buf_en) */ +#define TSM_TIMING57init (0x1a03ffffU) /* (rxtx_rccal_en) */ +#define TSM_TIMING58init (0xffff6f03U) /* (tx_hpm_dac_en) */ +#define END_OF_SEQinit (0x6d6c6f67U) /* */ +#define TX_RX_ON_DELinit (0x00008a86U) /* */ +#define TX_RX_SYNTH_init (0x00002318U) /* */ +#else +#define TSM_TIMING00init (0x69006f00U) /* (bb_ldo_hf_en) */ +#define TSM_TIMING01init (0x69006f00U) /* (bb_ldo_adcdac_en) */ +#define TSM_TIMING02init (0x6900ffffU) /* (bb_ldo_bba_en) */ +#define TSM_TIMING03init (0x69006f00U) /* (bb_ldo_pd_en) */ +#define TSM_TIMING04init (0x69006f00U) /* (bb_ldo_fdbk_en) */ +#define TSM_TIMING05init (0x69006f00U) /* (bb_ldo_vcolo_en) */ +#define TSM_TIMING06init (0x69006f00U) /* (bb_ldo_vtref_en) */ +#define TSM_TIMING07init (0x05000500U) /* (bb_ldo_fdbk_bleed_en) */ +#define TSM_TIMING08init (0x03000300U) /* (bb_ldo_vcolo_bleed_en) */ +#define TSM_TIMING09init (0x03000300U) /* (bb_ldo_vcolo_fastcharge_en) */ +#define TSM_TIMING10init (0x69036f03U) /* (bb_xtal_pll_ref_clk_en) */ +#define TSM_TIMING11init (0xffff6f03U) /* (bb_xtal_dac_ref_clk_en) */ +#define TSM_TIMING12init (0x6903ffffU) /* (rxtx_auxpll_vco_ref_clk_en) */ +#define TSM_TIMING13init (0x18004c00U) /* (sy_vco_autotune_en) */ +#define TSM_TIMING14init (0x69316863U) /* (sy_pd_cycle_slip_ld_ft_en) */ +#define TSM_TIMING15init (0x69036f03U) /* (sy_vco_en) */ +#define TSM_TIMING16init (0x691cffffU) /* (sy_lo_rx_buf_en) */ +#define TSM_TIMING17init (0xffff6f58U) /* (sy_lo_tx_buf_en) */ +#define TSM_TIMING18init (0x69056f05U) /* (sy_divn_en) */ +#define TSM_TIMING19init (0x18034c03U) /* (sy_pd_filter_charge_en) */ +#define TSM_TIMING20init (0x69036f03U) /* (sy_pd_en) */ +#define TSM_TIMING21init (0x69046f04U) /* (sy_lo_divn_en) */ +#define TSM_TIMING22init (0x6904ffffU) /* (sy_lo_rx_en) */ +#define TSM_TIMING23init (0xffff6f04U) /* (sy_lo_tx_en) */ +#define TSM_TIMING24init (0x18004c00U) /* (sy_divn_cal_en) */ +#define TSM_TIMING25init (0x691dffffU) /* (rx_lna_mixer_en) */ +#define TSM_TIMING26init (0xffff6e58U) /* (tx_pa_en) */ +#define TSM_TIMING27init (0x6920ffffU) /* (rx_adc_i_q_en) */ +#define TSM_TIMING28init (0x2120ffffU) /* (rx_adc_reset_en) */ +#define TSM_TIMING29init (0x691effffU) /* (rx_bba_i_q_en) */ +#define TSM_TIMING30init (0x6920ffffU) /* (rx_bba_pdet_en) */ +#define TSM_TIMING31init (0x691fffffU) /* (rx_bba_tza_dcoc_en) */ +#define TSM_TIMING32init (0x691dffffU) /* (rx_tza_i_q_en) */ +#define TSM_TIMING33init (0x6920ffffU) /* (rx_tza_pdet_en) */ +#define TSM_TIMING34init (0x69076f07U) /* (pll_dig_en) */ +#define TSM_TIMING35init (0xffff6f5fU) /* (tx_dig_en) */ +#define TSM_TIMING36init (0x6966ffffU) /* (rx_dig_en) */ +#define TSM_TIMING37init (0x6766ffffU) /* (rx_init) */ +#define TSM_TIMING38init (0x690e6f42U) /* (sigma_delta_en) */ +#define TSM_TIMING39init (0x6966ffffU) /* (rx_phy_en) */ +#define TSM_TIMING40init (0x6926ffffU) /* (dcoc_en) */ +#define TSM_TIMING41init (0x2726ffffU) /* (dcoc_init) */ +#define TSM_TIMING42init (0xffffffffU) /* (sar_adc_trig_en) */ +#define TSM_TIMING43init (0xffffffffU) /* (tsm_spare0_en) */ +#define TSM_TIMING44init (0xffffffffU) /* (tsm_spare1_en) */ +#define TSM_TIMING45init (0xffffffffU) /* (tsm_spare2_en) */ +#define TSM_TIMING46init (0xffffffffU) /* (tsm_spare3_en) */ +#define TSM_TIMING47init (0xffffffffU) /* (gpio0_trig_en) */ +#define TSM_TIMING48init (0xffffffffU) /* (gpio1_trig_en) */ +#define TSM_TIMING49init (0xffffffffU) /* (gpio2_trig_en) */ +#define TSM_TIMING50init (0xffffffffU) /* (gpio3_trig_en) */ +#define TSM_TIMING51init (0x6903ffffU) /* (rxtx_auxpll_bias_en) */ +#define TSM_TIMING52init (0x1706ffffU) /* (rxtx_auxpll_fcal_en) */ +#define TSM_TIMING53init (0x6903ffffU) /* (rxtx_auxpll_lf_pd_en) */ +#define TSM_TIMING54init (0x1703ffffU) /* (rxtx_auxpll_pd_lf_filter_charge_en) */ +#define TSM_TIMING55init (0x6920ffffU) /* (rxtx_auxpll_adc_buf_en) */ +#define TSM_TIMING56init (0x6920ffffU) /* (rxtx_auxpll_dig_buf_en) */ +#define TSM_TIMING57init (0x1a03ffffU) /* (rxtx_rccal_en) */ +#define TSM_TIMING58init (0xffff6f03U) /* (tx_hpm_dac_en) */ +#define END_OF_SEQinit (0x69686f67U) /* */ +#define TX_RX_ON_DELinit (0x00008a86U) /* */ +#define TX_RX_SYNTH_init (0x00002318U) /* */ +#endif /* RF_OSC_26MHZ == 1 */ + +#define AUX_PLL_DELAY (0) +/* TSM bitfield shift and value definitions */ +#define TX_DIG_EN_ASSERT (95) /* Assertion time for TX_DIG_EN, used in mode specific settings */ +#define ZGBE_TX_DIG_EN_ASSERT (TX_DIG_EN_ASSERT - 1) /* Zigbee TX_DIG_EN must assert 1 tick sooner, see adjustment below based on data padding */ +/* EDIT THIS LINE TO CONTROL PA_RAMP! */ +#define PA_RAMP_TIME (2) /* Only allowable values are [0, 1, 2, or 4] in Gen3 */ +#define PA_RAMP_SEL_0US (0) +#define PA_RAMP_SEL_1US (1) +#define PA_RAMP_SEL_2US (2) +#define PA_RAMP_SEL_4US (3) +#if !((PA_RAMP_TIME == 0) || (PA_RAMP_TIME == 1) || (PA_RAMP_TIME == 2) || (PA_RAMP_TIME == 4)) +#error "Invalid value for PA_RAMP_TIME macro" +#endif /* Error check of PA RAMP TIME */ + +#define ADD_FOR_26MHZ (4) +#define END_OF_TX_WU_NORAMP (103) /* NOTE: NORAMP and 2us ramp time behaviors are identical for TX WU and WD */ +#define END_OF_TX_WD_NORAMP (111) /* NOTE: NORAMP and 2us ramp time behaviors are identical for TX WU and WD */ +/* Redefine the values of END_OF_TX_WU and END_OF_TX_WD based on whether DATA PADDING is enabled and the selection of ramp time */ +/* These two constants are then used on both common configuration and mode specific configuration files to define the TSM timing values */ +#if ((PA_RAMP_TIME == 0) || (PA_RAMP_TIME == 1) || (PA_RAMP_TIME == 2)) + #define END_OF_TX_WU (END_OF_TX_WU_NORAMP) + #define END_OF_TX_WD (END_OF_TX_WD_NORAMP) + #if (PA_RAMP_TIME == 0) + #define PA_RAMP_SEL PA_RAMP_SEL_0US + #define DATA_PADDING_EN (0) + #else + #define DATA_PADDING_EN (1) + #if (PA_RAMP_TIME == 1) + #define PA_RAMP_SEL PA_RAMP_SEL_1US + #else + #define PA_RAMP_SEL PA_RAMP_SEL_2US + #endif /* (PA_RAMP_TIME == 1) */ + #endif /* (PA_RAMP_TIME == 0) */ +#else /* ((PA_RAMP_TIME == 0) || (PA_RAMP_TIME == 1) || (PA_RAMP_TIME == 2)) */ + #if (PA_RAMP_TIME == 4) + #define END_OF_TX_WU (END_OF_TX_WU_NORAMP + 2) + #define END_OF_TX_WD (END_OF_TX_WD_NORAMP + 4) + #define PA_RAMP_SEL PA_RAMP_SEL_4US + #define DATA_PADDING_EN (1) + #else /* (PA_RAMP_TIME == 4) */ + #error "Invalid value for PA_RAMP_TIME macro" + #endif /* (PA_RAMP_TIME == 4) */ +#endif/* (PA_RAMP_TIME == 4) */ + +#define END_OF_RX_WU (104 + AUX_PLL_DELAY) + +#if RF_OSC_26MHZ == 1 +#define END_OF_RX_WD (END_OF_RX_WU + 1 + ADD_FOR_26MHZ) /* Need to handle normal signals extending when 26MHZ warmdown is extended */ +#else +#define END_OF_RX_WD (END_OF_RX_WU + 1) +#endif /* RF_OSC_26MHZ == 1 */ + +#define END_OF_RX_WU_26MHZ (END_OF_RX_WU + ADD_FOR_26MHZ) +#define END_OF_RX_WD_26MHZ (END_OF_RX_WU + 1 + ADD_FOR_26MHZ) + +/* PA Bias Table - Gen3 version */ +#define PA_RAMP_0 0x1 +#define PA_RAMP_1 0x2 +#define PA_RAMP_2 0x4 +#define PA_RAMP_3 0x6 +#define PA_RAMP_4 0x8 +#define PA_RAMP_5 0xc +#define PA_RAMP_6 0x10 +#define PA_RAMP_7 0x14 +#define PA_RAMP_8 0x18 +#define PA_RAMP_9 0x1c +#define PA_RAMP_10 0x22 +#define PA_RAMP_11 0x28 +#define PA_RAMP_12 0x2c +#define PA_RAMP_13 0x30 +#define PA_RAMP_14 0x36 +#define PA_RAMP_15 0x3c + +#else /* Gen2 TSM definitions */ +/* GEN2 TSM defines */ +#define AUX_PLL_DELAY (0) +/* TSM bitfield shift and value definitions */ +#define TX_DIG_EN_ASSERT (95) +#define ZGBE_TX_DIG_EN_ASSERT (TX_DIG_EN_ASSERT - 1) /* Zigbee TX_DIG_EN must assert 1 tick sooner, see adjustment below based on data padding */ +/* EDIT THIS LINE TO CONTROL PA_RAMP! */ +#define PA_RAMP_TIME (2) /* Only allowable values are [0, 2, 4, or 8] for PA RAMP times in Gen2.0 */ +#define PA_RAMP_SEL_0US (0) +#define PA_RAMP_SEL_2US (1) +#define PA_RAMP_SEL_4US (2) +#define PA_RAMP_SEL_8US (3) + +#if !((PA_RAMP_TIME == 0) || (PA_RAMP_TIME == 2) || (PA_RAMP_TIME == 4) || (PA_RAMP_TIME == 8)) +#error "Invalid value for PA_RAMP_TIME macro" +#endif /* Error check of PA RAMP TIME */ +#define ADD_FOR_26MHZ (4) +#define END_OF_TX_WU_NORAMP (103) /* NOTE: NORAMP and 2us ramp time behaviors are identical for TX WU and WD */ +#define END_OF_TX_WD_NORAMP (111) /* NOTE: NORAMP and 2us ramp time behaviors are identical for TX WU and WD */ +/* Redefine the values of END_OF_TX_WU and END_OF_TX_WD based on whether DATA PADDING is enabled and the selection of ramp time */ +/* These two constants are then used on both common configuration and mode specific configuration files to define the TSM timing values */ +#if ((PA_RAMP_TIME == 0) || (PA_RAMP_TIME == 2)) + #define END_OF_TX_WU (END_OF_TX_WU_NORAMP) + #define END_OF_TX_WD (END_OF_TX_WD_NORAMP) + #define TX_SYNTH_DELAY_ADJ (0) + #define PD_CYCLE_SLIP_TX_HI_ADJ (0) + #define PD_CYCLE_SLIP_TX_LO_ADJ (1) + #define ZGBE_TX_DIG_EN_TX_HI_ADJ (-5) /* Only applies to Zigbee mode */ + #if (PA_RAMP_TIME == 0) + #define PA_RAMP_SEL PA_RAMP_SEL_0US + #define DATA_PADDING_EN (0) + #define TX_DIG_EN_TX_HI_ADJ (-2) + #else + #define DATA_PADDING_EN (1) + #define TX_DIG_EN_TX_HI_ADJ (0) + #define PA_RAMP_SEL PA_RAMP_SEL_2US + #endif /* (PA_RAMP_TIME == 0) */ +#else /* ((PA_RAMP_TIME == 0) || (PA_RAMP_TIME == 2)) */ + #if (PA_RAMP_TIME == 4) + #define END_OF_TX_WU (END_OF_TX_WU_NORAMP + 2) + #define END_OF_TX_WD (END_OF_TX_WD_NORAMP + 4) + #define TX_SYNTH_DELAY_ADJ (2) + #define PD_CYCLE_SLIP_TX_HI_ADJ (2) + #define PD_CYCLE_SLIP_TX_LO_ADJ (1) + #define TX_DIG_EN_TX_HI_ADJ (0) + #define ZGBE_TX_DIG_EN_TX_HI_ADJ (-3) /* Only applies to Zigbee mode */ + #define PA_RAMP_SEL PA_RAMP_SEL_4US + #define DATA_PADDING_EN (1) + #else /* (PA_RAMP_TIME==4) */ + #if ((PA_RAMP_TIME == 8) && (!RADIO_IS_GEN_3P0)) + #define END_OF_TX_WU (END_OF_TX_WU_NORAMP + 6) + #define END_OF_TX_WD (END_OF_TX_WD_NORAMP + 12) + #define TX_SYNTH_DELAY_ADJ (6) + #define PD_CYCLE_SLIP_TX_HI_ADJ (6) + #define PD_CYCLE_SLIP_TX_LO_ADJ (1) + #define TX_DIG_EN_TX_HI_ADJ (4) + #define ZGBE_TX_DIG_EN_TX_HI_ADJ (1) /* Only applies to Zigbee mode */ + #define PA_RAMP_SEL PA_RAMP_SEL_8US + #define DATA_PADDING_EN (1) + #else /* (PA_RAMP_TIME == 8) */ + #error "Invalid value for PA_RAMP_TIME macro" + #endif /* (PA_RAMP_TIME == 8) */ + #endif/* (PA_RAMP_TIME == 4) */ +#endif /* ((PA_RAMP_TIME == 0) || (PA_RAMP_TIME == 2)) */ + +#define TX_DIG_EN_ASSERT_MSK500 (END_OF_TX_WU - 3) + +#define END_OF_RX_WU (104 + AUX_PLL_DELAY) +#if RF_OSC_26MHZ == 1 +#define END_OF_RX_WD (END_OF_RX_WU + 1 + ADD_FOR_26MHZ) /* Need to handle normal signals extending when 26MHZ warmdown is extended */ +#else +#define END_OF_RX_WD (END_OF_RX_WU + 1) +#endif /* RF_OSC_26MHZ == 1 */ +#define END_OF_RX_WU_26MHZ (END_OF_RX_WU + ADD_FOR_26MHZ) +#define END_OF_RX_WD_26MHZ (END_OF_RX_WU + 1 + ADD_FOR_26MHZ) + +/* PA Bias Table */ +#define PA_RAMP_0 0x1 +#define PA_RAMP_1 0x2 +#define PA_RAMP_2 0x4 +#define PA_RAMP_3 0x8 +#define PA_RAMP_4 0xe +#define PA_RAMP_5 0x16 +#define PA_RAMP_6 0x22 +#define PA_RAMP_7 0x2e + +/* BLE LL timing definitions */ +#define TX_ON_DELAY (0x85) /* Adjusted TX_ON_DELAY to make turnaround time 150usec */ +#define RX_ON_DELAY (29 + END_OF_RX_WU) +#define RX_ON_DELAY_26MHZ (29 + END_OF_RX_WU_26MHZ) +#define TX_RX_ON_DELAY_VAL (TX_ON_DELAY << 8 | RX_ON_DELAY) +#define TX_RX_ON_DELAY_VAL_26MHZ (TX_ON_DELAY << 8 | RX_ON_DELAY_26MHZ) +#define TX_SYNTH_DELAY (TX_ON_DELAY - END_OF_TX_WU - TX_SYNTH_DELAY_ADJ) /* Adjustment to TX_SYNTH_DELAY due to DATA_PADDING */ +#define RX_SYNTH_DELAY (0x18) +#define TX_RX_SYNTH_DELAY_VAL (TX_SYNTH_DELAY << 8 | RX_SYNTH_DELAY) + +/* PHY reference waveform assembly */ +#define RW0PS(loc, val) (((val) & 0x1F) << ((loc) * 5)) /* Ref Word 0 - loc is the phase info symbol number, val is the value of the phase info */ +#define RW1PS(loc, val) (((val) & 0x1F) << (((loc) * 5) - 32)) /* Ref Word 1 - loc is the phase info symbol number, val is the value of the phase info */ +#define RW2PS(loc, val) (((val) & 0x1F) << (((loc) * 5) - 64)) /* Ref Word 2 - loc is the phase info symbol number, val is the value of the phase info */ +#endif /* RADIO_IS_GEN_3P0 */ + +/*! @brief Error codes for the XCVR driver. */ +typedef enum _xcvrStatus +{ + gXcvrSuccess_c = 0, + gXcvrInvalidParameters_c, + gXcvrUnsupportedOperation_c, + gXcvrTrimFailure_c +} xcvrStatus_t; + +/*! @brief Health status returned from PHY upon status check function return. */ +typedef enum _healthStatus +{ + NO_ERRORS = 0, + PLL_CTUNE_FAIL = 1, + PLL_CYCLE_SLIP_FAIL = 2, + PLL_FREQ_TARG_FAIL = 4, + PLL_TSM_ABORT_FAIL = 8, +} healthStatus_t; + +/*! @brief Health status returned from PHY upon status check function return. */ +typedef enum _ext_clock_config +{ + EXT_CLK_32_MHZ = 0, + EXT_CLK_26_MHZ = 1, +} ext_clock_config_t; + +/*! @brief Radio operating mode setting types. */ +typedef enum _radio_mode +{ + BLE_MODE = 0, + ZIGBEE_MODE = 1, + ANT_MODE = 2, + + /* BT=0.5, h=** */ + GFSK_BT_0p5_h_0p5 = 3, /* < BT=0.5, h=0.5 [BLE at 1MBPS data rate; CS4 at 250KBPS data rate] */ + GFSK_BT_0p5_h_0p32 = 4, /* < BT=0.5, h=0.32*/ + GFSK_BT_0p5_h_0p7 = 5, /* < BT=0.5, h=0.7 [ CS1 at 500KBPS data rate] */ + GFSK_BT_0p5_h_1p0 = 6, /* < BT=0.5, h=1.0 [ CS4 at 250KBPS data rate] */ + + /* BT=** h=0.5 */ + GFSK_BT_0p3_h_0p5 = 7, /* < BT=0.3, h=0.5 [ CS2 at 1MBPS data rate] */ + GFSK_BT_0p7_h_0p5 = 8, /* < BT=0.7, h=0.5 */ + + MSK = 9, + NUM_RADIO_MODES = 10, +} radio_mode_t; + +/*! @brief Link layer types. */ +typedef enum _link_layer +{ + BLE_LL = 0, /* Must match bit assignment in RADIO1_IRQ_SEL */ + ZIGBEE_LL = 1, /* Must match bit assignment in RADIO1_IRQ_SEL */ + ANT_LL = 2, /* Must match bit assignment in RADIO1_IRQ_SEL */ + GENFSK_LL = 3, /* Must match bit assignment in RADIO1_IRQ_SEL */ + UNASSIGNED_LL = 4, /* Must match bit assignment in RADIO1_IRQ_SEL */ +} link_layer_t; + +/*! @brief Data rate selections. */ +typedef enum _data_rate +{ + DR_1MBPS = 0, /* Must match bit assignment in BITRATE field */ + DR_500KBPS = 1, /* Must match bit assignment in BITRATE field */ + DR_250KBPS = 2, /* Must match bit assignment in BITRATE field */ +#if RADIO_IS_GEN_3P0 + DR_2MBPS = 3, /* Must match bit assignment in BITRATE field */ +#endif /* RADIO_IS_GEN_3P0 */ + DR_UNASSIGNED = 4, /* Must match bit assignment in BITRATE field */ +} data_rate_t; + +/*! @brief Control settings for Fast Antenna Diversity */ +typedef enum _FAD_LPPS_CTRL +{ + NONE = 0, + FAD_ENABLED = 1, + LPPS_ENABLED = 2 +} FAD_LPPS_CTRL_T; + +/*! @brief XCVR XCVR Panic codes for indicating panic reason. */ +typedef enum _XCVR_PANIC_ID +{ + WRONG_RADIO_ID_DETECTED = 1, + CALIBRATION_INVALID = 2, +} XCVR_PANIC_ID_T; + +/*! @brief Initialization or mode change selection for config routine. */ +typedef enum _XCVR_INIT_MODE_CHG +{ + XCVR_MODE_CHANGE = 0, + XCVR_FIRST_INIT = 1, +} XCVR_INIT_MODE_CHG_T; + +typedef enum _XCVR_COEX_PRIORITY +{ + XCVR_COEX_LOW_PRIO = 0, + XCVR_COEX_HIGH_PRIO = 1 +} XCVR_COEX_PRIORITY_T; + +/*! @brief Current configuration of the radio. */ +typedef struct xcvr_currConfig_tag +{ + radio_mode_t radio_mode; + data_rate_t data_rate; +} xcvr_currConfig_t; + +/*! + * @brief XCVR RX_DIG channel filter coefficient storage + * Storage of the coefficients varies from 6 bits to 10 bits so all use int16_t for storage. + */ +typedef struct _xcvr_rx_chf_coeffs +{ + uint16_t rx_chf_coef_0; /* < 6 bit two's complement stored in a uint16_t */ + uint16_t rx_chf_coef_1; /* < 6 bit two's complement stored in a uint16_t */ + uint16_t rx_chf_coef_2; /* < 7 bit two's complement stored in a uint16_t */ + uint16_t rx_chf_coef_3; /* < 7 bit two's complement stored in a uint16_t */ + uint16_t rx_chf_coef_4; /* < 7 bit two's complement stored in a uint16_t */ + uint16_t rx_chf_coef_5; /* < 7 bit two's complement stored in a uint16_t */ + uint16_t rx_chf_coef_6; /* < 8 bit two's complement stored in a uint16_t */ + uint16_t rx_chf_coef_7; /* < 8 bit two's complement stored in a uint16_t */ + uint16_t rx_chf_coef_8; /* < 9 bit two's complement stored in a uint16_t */ + uint16_t rx_chf_coef_9; /* < 9 bit two's complement stored in a uint16_t */ + uint16_t rx_chf_coef_10; /* < 10 bit two's complement stored in a uint16_t */ + uint16_t rx_chf_coef_11; /* < 10 bit two's complement stored in a uint16_t */ +} xcvr_rx_chf_coeffs_t; + +/*! + * @brief XCVR masked init type for 32 bit registers + * Initialization uses the mask to clear selected fields of the register and then OR's in the init value. All init values must be in their proper field position. + */ +typedef struct _xcvr_masked_init_32 +{ + uint32_t mask; + uint32_t init; +} xcvr_masked_init_32_t; + +/*! + * @brief XCVR common configure structure + */ +typedef struct _xcvr_common_config +{ + /* XCVR_ANA configs */ + xcvr_masked_init_32_t ana_sy_ctrl1; + + /* XCVR_PLL_DIG configs */ + uint32_t pll_hpm_bump; + uint32_t pll_mod_ctrl; + uint32_t pll_chan_map; + uint32_t pll_lock_detect; + uint32_t pll_hpm_ctrl; +#if !RADIO_IS_GEN_2P1 + uint32_t pll_hpmcal_ctrl; +#endif /* !RADIO_IS_GEN_2P1 */ + uint32_t pll_hpm_sdm_res; + uint32_t pll_lpm_ctrl; + uint32_t pll_lpm_sdm_ctrl1; + uint32_t pll_delay_match; + uint32_t pll_ctune_ctrl; + + /* XCVR_RX_DIG configs */ + uint32_t rx_dig_ctrl_init; /* NOTE: Common init, mode init, and datarate init will be OR'd together for RX_DIG_CTRL to form complete register initialization */ + uint32_t dcoc_ctrl_0_init_26mhz; /* NOTE: This will be OR'd with mode specific init for DCOC_CTRL_0 to form complete register initialization */ + uint32_t dcoc_ctrl_0_init_32mhz; /* NOTE: This will be OR'd with mode specific init for DCOC_CTRL_0 to form complete register initialization */ + uint32_t dcoc_ctrl_1_init; + uint32_t dcoc_cal_gain_init; + uint32_t dc_resid_ctrl_init; /* NOTE: This will be OR'd with datarate specific init for DCOC_RESID_CTRL to form complete register initialization */ + uint32_t dcoc_cal_rcp_init; + uint32_t lna_gain_val_3_0; + uint32_t lna_gain_val_7_4; + uint32_t lna_gain_val_8; + uint32_t bba_res_tune_val_7_0; + uint32_t bba_res_tune_val_10_8; + uint32_t lna_gain_lin_val_2_0_init; + uint32_t lna_gain_lin_val_5_3_init; + uint32_t lna_gain_lin_val_8_6_init; + uint32_t lna_gain_lin_val_9_init; + uint32_t bba_res_tune_lin_val_3_0_init; + uint32_t bba_res_tune_lin_val_7_4_init; + uint32_t bba_res_tune_lin_val_10_8_init; + uint32_t dcoc_bba_step_init; + uint32_t dcoc_tza_step_00_init; + uint32_t dcoc_tza_step_01_init; + uint32_t dcoc_tza_step_02_init; + uint32_t dcoc_tza_step_03_init; + uint32_t dcoc_tza_step_04_init; + uint32_t dcoc_tza_step_05_init; + uint32_t dcoc_tza_step_06_init; + uint32_t dcoc_tza_step_07_init; + uint32_t dcoc_tza_step_08_init; + uint32_t dcoc_tza_step_09_init; + uint32_t dcoc_tza_step_10_init; +#if (RADIO_IS_GEN_3P0 || RADIO_IS_GEN_2P1) + uint32_t dcoc_cal_fail_th_init; + uint32_t dcoc_cal_pass_th_init; +#endif /* (RADIO_IS_GEN_3P0 || RADIO_IS_GEN_2P1) */ + uint32_t agc_ctrl_0_init; /* NOTE: Common init and mode init will be OR'd together for AGC_CTRL_0 to form complete register initialization */ + uint32_t agc_ctrl_1_init_26mhz; /* NOTE: This will be OR'd with datarate specific init to form complete register initialization */ + uint32_t agc_ctrl_1_init_32mhz; /* NOTE: This will be OR'd with datarate specific init to form complete register initialization */ + uint32_t agc_ctrl_3_init; + /* Other agc config inits moved to modeXdatarate config table */ + uint32_t agc_gain_tbl_03_00_init; + uint32_t agc_gain_tbl_07_04_init; + uint32_t agc_gain_tbl_11_08_init; + uint32_t agc_gain_tbl_15_12_init; + uint32_t agc_gain_tbl_19_16_init; + uint32_t agc_gain_tbl_23_20_init; + uint32_t agc_gain_tbl_26_24_init; + uint32_t rssi_ctrl_0_init; +#if RADIO_IS_GEN_3P0 + uint32_t rssi_ctrl_1_init; +#endif /* RADIO_IS_GEN_3P0 */ + uint32_t cca_ed_lqi_ctrl_0_init; + uint32_t cca_ed_lqi_ctrl_1_init; + + /* XCVR_TSM configs */ + uint32_t tsm_ctrl; + uint32_t tsm_ovrd2_init; + uint32_t end_of_seq_init_26mhz; + uint32_t end_of_seq_init_32mhz; +#if !RADIO_IS_GEN_2P1 + uint32_t lpps_ctrl_init; +#endif /* !RADIO_IS_GEN_2P1 */ + uint32_t tsm_fast_ctrl2_init_26mhz; + uint32_t tsm_fast_ctrl2_init_32mhz; + uint32_t recycle_count_init_26mhz; + uint32_t recycle_count_init_32mhz; + uint32_t pa_ramp_tbl_0_init; + uint32_t pa_ramp_tbl_1_init; +#if RADIO_IS_GEN_3P0 + uint32_t pa_ramp_tbl_2_init; + uint32_t pa_ramp_tbl_3_init; +#endif /* RADIO_IS_GEN_3P0 */ + uint32_t tsm_timing_00_init; + uint32_t tsm_timing_01_init; + uint32_t tsm_timing_02_init; + uint32_t tsm_timing_03_init; + uint32_t tsm_timing_04_init; + uint32_t tsm_timing_05_init; + uint32_t tsm_timing_06_init; + uint32_t tsm_timing_07_init; + uint32_t tsm_timing_08_init; + uint32_t tsm_timing_09_init; + uint32_t tsm_timing_10_init; + uint32_t tsm_timing_11_init; + uint32_t tsm_timing_12_init; + uint32_t tsm_timing_13_init; + uint32_t tsm_timing_14_init_26mhz; /* tsm_timing_14 has mode specific LSbyte (both LS bytes) */ + uint32_t tsm_timing_14_init_32mhz; /* tsm_timing_14 has mode specific LSbyte (both LS bytes) */ + uint32_t tsm_timing_15_init; + uint32_t tsm_timing_16_init_26mhz; + uint32_t tsm_timing_16_init_32mhz; + uint32_t tsm_timing_17_init; + uint32_t tsm_timing_18_init; + uint32_t tsm_timing_19_init; + uint32_t tsm_timing_20_init; + uint32_t tsm_timing_21_init; + uint32_t tsm_timing_22_init; + uint32_t tsm_timing_23_init; + uint32_t tsm_timing_24_init; + uint32_t tsm_timing_25_init_26mhz; + uint32_t tsm_timing_25_init_32mhz; + uint32_t tsm_timing_26_init; + uint32_t tsm_timing_27_init_26mhz; + uint32_t tsm_timing_27_init_32mhz; + uint32_t tsm_timing_28_init_26mhz; + uint32_t tsm_timing_28_init_32mhz; + uint32_t tsm_timing_29_init_26mhz; + uint32_t tsm_timing_29_init_32mhz; + uint32_t tsm_timing_30_init_26mhz; + uint32_t tsm_timing_30_init_32mhz; + uint32_t tsm_timing_31_init_26mhz; + uint32_t tsm_timing_31_init_32mhz; + uint32_t tsm_timing_32_init_26mhz; + uint32_t tsm_timing_32_init_32mhz; + uint32_t tsm_timing_33_init_26mhz; + uint32_t tsm_timing_33_init_32mhz; + uint32_t tsm_timing_34_init; + uint32_t tsm_timing_35_init; /* tsm_timing_35 has a mode specific LSbyte*/ + uint32_t tsm_timing_36_init_26mhz; + uint32_t tsm_timing_36_init_32mhz; + uint32_t tsm_timing_37_init_26mhz; + uint32_t tsm_timing_37_init_32mhz; + uint32_t tsm_timing_38_init; + uint32_t tsm_timing_39_init_26mhz; + uint32_t tsm_timing_39_init_32mhz; + uint32_t tsm_timing_40_init_26mhz; + uint32_t tsm_timing_40_init_32mhz; + uint32_t tsm_timing_41_init_26mhz; + uint32_t tsm_timing_41_init_32mhz; + uint32_t tsm_timing_51_init; + uint32_t tsm_timing_52_init_26mhz; + uint32_t tsm_timing_52_init_32mhz; + uint32_t tsm_timing_53_init; + uint32_t tsm_timing_54_init_26mhz; + uint32_t tsm_timing_54_init_32mhz; + uint32_t tsm_timing_55_init_26mhz; + uint32_t tsm_timing_55_init_32mhz; + uint32_t tsm_timing_56_init_26mhz; + uint32_t tsm_timing_56_init_32mhz; + uint32_t tsm_timing_57_init; + uint32_t tsm_timing_58_init; + + /* XCVR_TX_DIG configs */ + uint32_t tx_ctrl; + uint32_t tx_data_padding; + uint32_t tx_dft_pattern; +#if !RADIO_IS_GEN_2P1 + uint32_t rf_dft_bist_1; + uint32_t rf_dft_bist_2; +#endif /* !RADIO_IS_GEN_2P1 */ +} xcvr_common_config_t; + +/*! @brief XCVR mode specific configure structure (varies by radio mode) */ +typedef struct _xcvr_mode_config +{ + radio_mode_t radio_mode; + uint32_t scgc5_clock_ena_bits; + + /* XCVR_MISC configs */ + xcvr_masked_init_32_t xcvr_ctrl; + + /* XCVR_PHY configs */ +#if RADIO_IS_GEN_3P0 + uint32_t phy_fsk_pd_cfg0; + uint32_t phy_fsk_pd_cfg1; + uint32_t phy_fsk_cfg; + uint32_t phy_fsk_misc; + uint32_t phy_fad_ctrl; +#else + uint32_t phy_pre_ref0_init; + uint32_t phy_pre_ref1_init; + uint32_t phy_pre_ref2_init; + uint32_t phy_cfg1_init; + uint32_t phy_el_cfg_init; /* Should leave EL_WIN_SIZE and EL_INTERVAL to the data_rate specific configuration */ +#endif /* RADIO_IS_GEN_3P0 */ + + /* XCVR_RX_DIG configs */ + uint32_t rx_dig_ctrl_init_26mhz; /* NOTE: Common init, mode init, and datarate init will be OR'd together for RX_DIG_CTRL to form complete register initialization */ + uint32_t rx_dig_ctrl_init_32mhz; /* NOTE: Common init, mode init, and datarate init will be OR'd together for RX_DIG_CTRL to form complete register initialization */ + uint32_t agc_ctrl_0_init; /* NOTE: Common init and mode init will be OR'd together for AGC_CTRL_0 to form complete register initialization */ + + /* XCVR_TSM configs */ +#if (RADIO_IS_GEN_2P0 || RADIO_IS_GEN_2P1) + uint32_t tsm_timing_35_init; /* Only the LSbyte is mode specific */ +#endif /* (RADIO_IS_GEN_2P0 || RADIO_IS_GEN_2P1) */ + + /* XCVR_TX_DIG configs */ + uint32_t tx_gfsk_ctrl; + uint32_t tx_gfsk_coeff1_26mhz; + uint32_t tx_gfsk_coeff2_26mhz; + uint32_t tx_gfsk_coeff1_32mhz; + uint32_t tx_gfsk_coeff2_32mhz; +} xcvr_mode_config_t; + +/*! + * @brief XCVR modeXdatarate specific configure structure (varies by radio mode AND data rate) + * This structure is used to store all of the XCVR settings which are dependent upon both radio mode and data rate. It is used as an overlay + * on top of the xcvr_mode_config_t structure to supply definitions which are either not in that table or which must be overridden for data rate. + */ +typedef struct _xcvr_mode_datarate_config +{ + radio_mode_t radio_mode; + data_rate_t data_rate; + + /* XCVR_ANA configs */ + xcvr_masked_init_32_t ana_sy_ctrl2; + xcvr_masked_init_32_t ana_rx_bba; + xcvr_masked_init_32_t ana_rx_tza; + + /* XCVR_PHY configs */ +#if RADIO_IS_GEN_3P0 + uint32_t phy_fsk_misc_mode_datarate; +#else + uint32_t phy_cfg2_init; +#endif /* RADIO_IS_GEN_3P0 */ + + uint32_t agc_ctrl_2_init_26mhz; + uint32_t agc_ctrl_2_init_32mhz; + xcvr_rx_chf_coeffs_t rx_chf_coeffs_26mhz; /* 26MHz ext clk */ + xcvr_rx_chf_coeffs_t rx_chf_coeffs_32mhz; /* 32MHz ext clk */ + uint32_t rx_rccal_ctrl_0; + uint32_t rx_rccal_ctrl_1; + + /* XCVR_TX_DIG configs */ + uint32_t tx_fsk_scale_26mhz; /* Only used by MSK mode, but dependent on datarate */ + uint32_t tx_fsk_scale_32mhz; /* Only used by MSK mode, but dependent on datarate */ +} xcvr_mode_datarate_config_t; + +/*! + * @brief XCVR datarate specific configure structure (varies by data rate) + * This structure is used to store all of the XCVR settings which are dependent upon data rate. It is used as an overlay + * on top of the xcvr_mode_config_t structure to supply definitions which are either not in that table or which must be overridden for data rate. + */ +typedef struct _xcvr_datarate_config +{ + data_rate_t data_rate; + + /* XCVR_PHY configs */ + uint32_t phy_el_cfg_init; /* Note: EL_ENABLE is set in xcvr_mode_config_t settings */ + + /* XCVR_RX_DIG configs */ + uint32_t rx_dig_ctrl_init_26mhz; /* NOTE: Common init, mode init, and datarate init will be OR'd together for RX_DIG_CTRL to form complete register initialization */ + uint32_t rx_dig_ctrl_init_32mhz; /* NOTE: Common init, mode init, and datarate init will be OR'd together for RX_DIG_CTRL to form complete register initialization */ + uint32_t agc_ctrl_1_init_26mhz; + uint32_t agc_ctrl_1_init_32mhz; + uint32_t dcoc_ctrl_0_init_26mhz; /* NOTE: This will be OR'd with common init for DCOC_CTRL_0 to form complete register initialization */ + uint32_t dcoc_ctrl_0_init_32mhz; /* NOTE: This will be OR'd with common init for DCOC_CTRL_0 to form complete register initialization */ + uint32_t dcoc_ctrl_1_init_26mhz; /* NOTE: This will be OR'd with common init for DCOC_CTRL_1 to form complete register initialization */ + uint32_t dcoc_ctrl_1_init_32mhz; /* NOTE: This will be OR'd with common init for DCOC_CTRL_1 to form complete register initialization */ + uint32_t dcoc_ctrl_2_init_26mhz; + uint32_t dcoc_ctrl_2_init_32mhz; + uint32_t dcoc_cal_iir_init_26mhz; + uint32_t dcoc_cal_iir_init_32mhz; + uint32_t dc_resid_ctrl_26mhz;/* NOTE: This will be OR'd with common init for DCOC_RESID_CTRL to form complete register initialization */ + uint32_t dc_resid_ctrl_32mhz;/* NOTE: This will be OR'd with common init for DCOC_RESID_CTRL to form complete register initialization */ +} xcvr_datarate_config_t; + +/*! + * @brief LPUART callback function type + * + * The panic callback function is defined by system if system need to be informed of XCVR fatal errors. + * refer to #XCVR_RegisterPanicCb + */ +typedef void (*panic_fptr)(uint32_t panic_id, uint32_t location, uint32_t extra1, uint32_t extra2); + +/* Make available const structures from config files */ +extern const xcvr_common_config_t xcvr_common_config; +extern const xcvr_mode_config_t zgbe_mode_config; +extern const xcvr_mode_config_t ble_mode_config; +extern const xcvr_mode_config_t ant_mode_config; +extern const xcvr_mode_config_t gfsk_bt_0p5_h_0p5_mode_config; +extern const xcvr_mode_config_t gfsk_bt_0p5_h_0p7_mode_config; +extern const xcvr_mode_config_t gfsk_bt_0p5_h_0p32_mode_config; +extern const xcvr_mode_config_t gfsk_bt_0p5_h_1p0_mode_config; +extern const xcvr_mode_config_t gfsk_bt_0p3_h_0p5_mode_config; +extern const xcvr_mode_config_t gfsk_bt_0p7_h_0p5_mode_config; +extern const xcvr_mode_config_t msk_mode_config; + +#if RADIO_IS_GEN_3P0 +extern const xcvr_datarate_config_t xcvr_2mbps_config; +#endif /* RADIO_IS_GEN_3P0 */ +extern const xcvr_datarate_config_t xcvr_1mbps_config; +extern const xcvr_datarate_config_t xcvr_500kbps_config; +extern const xcvr_datarate_config_t xcvr_250kbps_config; +extern const xcvr_datarate_config_t xcvr_802_15_4_500kbps_config; /* Custom datarate settings for 802.15.4 since it is 2MChips/sec */ + +#if RADIO_IS_GEN_3P0 +extern const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p5_h_0p5_2mbps_config; +extern const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p5_h_0p32_2mbps_config; +extern const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p3_h_0p5_2mbps_config; +extern const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p7_h_0p5_2mbps_config; +extern const xcvr_mode_datarate_config_t xcvr_MSK_2mbps_config; +#endif /* RADIO_IS_GEN_3P0 */ +extern const xcvr_mode_datarate_config_t xcvr_BLE_1mbps_config; +extern const xcvr_mode_datarate_config_t xcvr_ZIGBEE_500kbps_config; +extern const xcvr_mode_datarate_config_t xcvr_ANT_1mbps_config; +extern const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p5_h_0p5_1mbps_config; +extern const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p5_h_0p5_500kbps_config; +extern const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p5_h_0p5_250kbps_config; +extern const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p5_h_0p32_1mbps_config; +extern const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p5_h_0p32_500kbps_config; +extern const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p5_h_0p32_250kbps_config; +extern const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p5_h_0p7_1mbps_config; +extern const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p5_h_0p7_500kbps_config; +extern const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p5_h_0p7_250kbps_config; +extern const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p5_h_1p0_1mbps_config; +extern const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p5_h_1p0_500kbps_config; +extern const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p5_h_1p0_250kbps_config; +extern const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p3_h_0p5_1mbps_config; +extern const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p3_h_0p5_500kbps_config; +extern const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p3_h_0p5_250kbps_config; +extern const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p7_h_0p5_1mbps_config; +extern const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p7_h_0p5_500kbps_config; +extern const xcvr_mode_datarate_config_t xcvr_GFSK_BT_0p7_h_0p5_250kbps_config; +extern const xcvr_mode_datarate_config_t xcvr_MSK_1mbps_config; +extern const xcvr_mode_datarate_config_t xcvr_MSK_500kbps_config; +extern const xcvr_mode_datarate_config_t xcvr_MSK_250kbps_config; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name XCVR functional Operation + * @{ + */ + +/*! + * @brief Initializes an XCVR instance. + * + * This function initializes the XCVR module according to the radio_mode and data_rate settings. This the only function call required to + * start up the XCVR in most situations. + * + * @param radio_mode The radio mode for which the XCVR should be configured. + * @param data_rate The data rate for which the XCVR should be configured. Only matters when GFSK/MSK radio_mode is selected. + * @note This function encompasses the ::XCVRGetDefafultConfig() and ::XCVR_Configure() functions. + */ +xcvrStatus_t XCVR_Init(radio_mode_t radio_mode, data_rate_t data_rate); + +/*! + * @brief Deinitializes an XCVR instance. + * + * This function gate the XCVR module clock and set all register value to reset value. + * + */ +void XCVR_Deinit(void); + +/*! + * @brief Initializes XCVR configure structure. + * + * This function updates pointers to the XCVR configure structures with default values. + * The configurations are divided into a common structure, a set of radio mode specific + * structures (one per radio_mode), a set of mode&datarate specific structures (for each mode at + * each datarate), and a set of data rate specific structures. + * The pointers provided by this routine point to const structures which can be + * copied to variable structures if changes to settings are required. + * + * @param radio_mode [in] The radio mode for which the configuration structures are requested. + * @param data_rate [in] The data rate for which the configuration structures are requested. + * @param com_config [in,out] Pointer to a pointer to the common configuration settings structure. + * @param mode_config [in,out] Pointer to a pointer to the mode specific configuration settings structure. + * @param mode_datarate_config [in,out] Pointer to a pointer to the modeXdata rate specific configuration settings structure. + * @param datarate_config [in,out] Pointer to a pointer to the data rate specific configuration settings structure. + * @return 0 success, others failure + * @see XCVR_Configure + */ +xcvrStatus_t XCVR_GetDefaultConfig(radio_mode_t radio_mode, + data_rate_t data_rate, + const xcvr_common_config_t ** com_config, + const xcvr_mode_config_t ** mode_config, + const xcvr_mode_datarate_config_t ** mode_datarate_config, + const xcvr_datarate_config_t ** datarate_config); + +/*! + * @brief Initializes an XCVR instance. + * + * This function initializes the XCVR module with user-defined settings. + * + * @param com_config Pointer to the common configuration settings structure. + * @param mode_config Pointer to the mode specific configuration settings structure. + * @param mode_datarate_config Pointer to a pointer to the modeXdata rate specific configuration settings structure. + * @param datarate_config Pointer to a pointer to the data rate specific configuration settings structure. + * @param tempDegC temperature of the die in degrees C. + * @param ext_clk indicates the external clock setting, 32MHz or 26MHz. + * @param first_init indicates whether the call is to initialize (== 1) or the call is to perform a mode change (== 0) + * @return 0 succeed, others failed + */ +xcvrStatus_t XCVR_Configure(const xcvr_common_config_t *com_config, + const xcvr_mode_config_t *mode_config, + const xcvr_mode_datarate_config_t *mode_datarate_config, + const xcvr_datarate_config_t *datarate_config, + int16_t tempDegC, + XCVR_INIT_MODE_CHG_T first_init); + +/*! + * @brief Set XCVR register to reset value. + * + * This function set XCVR register to the reset value. + * + */ +void XCVR_Reset(void); + +/*! + * @brief Change the operating mode of the radio. + * + * This function changes the XCVR to a new radio operating mode. + * + * @param new_radio_mode The radio mode for which the XCVR should be configured. + * @param new_data_rate The data rate for which the XCVR should be configured. Only matters when GFSK/MSK radio_mode is selected. + * @return status of the mode change. + */ + xcvrStatus_t XCVR_ChangeMode(radio_mode_t new_radio_mode, data_rate_t new_data_rate); + +/*! + * @brief Enable Narrowband RSSI measurement. + * + * This function enables the narrowband RSSI measurement + * + * @param IIRnbEnable true causes the NB RSSI to be enabled, false disabled. + */ +void XCVR_EnaNBRSSIMeas(uint8_t IIRnbEnable); + +/*! + * @brief Set an arbitrary frequency for RX and TX for the radio. + * + * This function sets the radio frequency used for RX and RX.. + * + * @param freq target frequency setting in Hz. + * @param refOsc reference oscillator setting in Hz. + * @return status of the frequency change. + * @details + */ + xcvrStatus_t XCVR_OverrideFrequency(uint32_t freq, uint32_t refOsc); + +/*! + * @brief Register a callback from upper layers. + * + * This function registers a callback from the upper layers for the radio to call in case of fatal errors. + * + * @param fptr The function pointer to a panic callback. + */ +void XCVR_RegisterPanicCb(panic_fptr fptr); /* allow upper layers to provide PANIC callback */ + +/*! + * @brief Read the health status of the XCVR to detect errors. + * + * This function enables the upper layers to request the current radio health. + * + * @return The health status of the radio.. + */ +healthStatus_t XCVR_HealthCheck(void); /* allow upper layers to poll the radio health */ + +/*! + * @brief Control FAD and LPPS features. + * + * This function controls the Fast Antenna Diversity (FAD) and Low Power Preamble Search. + * + * @param fptr control the FAD and LPPS settings. + * + */ + void XCVR_FadLppsControl(FAD_LPPS_CTRL_T control); + +/*! + * @brief Change the mapping of the radio IRQs. + * + * This function changes the mapping of the radio LL IRQ signals to the 2.4G Radio INT0 and 2.4G Radio INT1 lines. + * + * @param irq0_mapping the LL which should be mapped to the INT0 line. + * @param irq1_mapping the LL which should be mapped to the INT1 line. + * @return status of the mapping request. + * @ note The radio_mode_t parameters map to ::link_layer_t selections for the LL which is connected to the INT line. + * @warning + * The same LL must NOT be mapped to both INT lines. + */ + xcvrStatus_t XCVR_SetIRQMapping(radio_mode_t irq0_mapping, radio_mode_t irq1_mapping); + +#if RADIO_IS_GEN_3P0 +/*! + * @brief Sets the network address used by the PHY during BLE Bit Streaming Mode. + * + * This function programs the register in the PHY which contains the network address used during BSM. + * + * @param bsm_ntw_address the address to be used during BSM. + * @ note This routine does NOT enable BSM. + */ +void XCVR_SetBSM_NTW_Address(uint32_t bsm_ntw_address); + +/*! + * @brief Reads the currently programmed network address used by the PHY during BLE Bit Streaming Mode. + * + * This function reads the register in the PHY which contains the network address used during BSM. + * + * @return bsm_ntw_address the address to be used during BSM. + * @ note This routine does NOT enable BSM. + */ +uint32_t XCVR_GetBSM_NTW_Address(void); +#endif /* RADIO_IS_GEN_3P0 */ + +/*! + * @brief Get the mapping of the one of the radio IRQs. + * + * This function reads the setting for the mapping of one of the radio LL IRQ signals to the 2.4G Radio INT0 and 2.4G Radio INT1 lines. + * + * @param int_num the number, 0 or 1, of the INT line to fetched. + * @return the mapping setting of the specified line. + * @note Any value passed into this routine other than 0 will be treated as a 1. + */ + link_layer_t XCVR_GetIRQMapping(uint8_t int_num); + +/*! + * @brief Get the current configuration of the XCVR. + * + * This function fetches the current configuration (radio mode and radio data rate) of the XCVR to allow LL to properly config data rates, etc + * + * @param curr_config pointer to a structure to be updated with the current mode and data rate. + * @return the status of the request, success or invalid parameter (null pointer). + * @note This API will return meaningless results if called before the radio is initialized... + */ +xcvrStatus_t XCVR_GetCurrentConfig(xcvr_currConfig_t * curr_config); + +/******************************************************************************* + * Customer level trim functions + ******************************************************************************/ +/*! + * @brief Controls setting the XTAL trim value.. + * + * This function enables the upper layers set a crystal trim compensation facor + * + * @param xtalTrim the trim value to apply to the XTAL trimming register. Only the 7 LSB are valid, setting the 8th bit returns an error. + * @return The health status of the radio.. + */ +xcvrStatus_t XCVR_SetXtalTrim(uint8_t xtalTrim); + +/*! + * @brief Controls getting the XTAL trim value.. + * + * This function enables the upper layers to read the current XTAL compensation factors. + * The returned value is in the range 0..127 (7 bits). + * + * @return The XTAL trim compensation factors.. + */ +uint8_t XCVR_GetXtalTrim(void); + +/*! + * @brief Controls setting the RSSI adjustment.. + * + * This function enables the upper layers to set an RSSI adjustment value. + * + * @param adj the adjustment value to apply to the RSSI adjustment register. The value must be a signed 8-bit value, in 1/4 dBm step. + * @return The health status of the radio.. + */ +xcvrStatus_t XCVR_SetRssiAdjustment(int8_t adj); + +/*! + * @brief Controls getting the RSSI adjustment.. + * + * This function enables the upper layers to read the current XCVR RSSI adjustment value. + * The returned value is a signed 8-bit value, in 1/4 dBm step. + * + * @return The RSSI adjustment value.. + */ +int8_t XCVR_GetRssiAdjustment(void); + +/*! + * @brief Controls setting the PLL to a particular channel. + * + * This function enables setting the radio channel for TX and RX. + * + * @param channel the channel number to set + * @param useMappedChannel when true, channel is assumed to be from the protocol specific channel map. when false, channel is assumed to be from the 128 general channel list.. + * @return The status of the channel over-ride. + */ +xcvrStatus_t XCVR_OverrideChannel(uint8_t channel, uint8_t useMappedChannel); + +/*! + * @brief Reads the current frequency for RX and TX for the radio. + * + * This function reads the radio frequency used for RX and RX.. + * + * @return Current radio frequency setting. + */ +uint32_t XCVR_GetFreq(void); + +/*! + * @brief Force receiver warmup. + * + * This function forces the initiation of a receiver warmup sequence. + * + */ +void XCVR_ForceRxWu(void); + +/*! + * @brief Force receiver warmdown. + * + * This function forces the initiation of a receiver warmdown sequence. + * + */ + void XCVR_ForceRxWd(void); + +/*! + * @brief Force transmitter warmup. + * + * This function forces the initiation of a transmit warmup sequence. + * + */ +void XCVR_ForceTxWu(void); + +/*! + * @brief Force transmitter warmdown. + * + * This function forces the initiation of a transmit warmdown sequence. + * + */ +void XCVR_ForceTxWd(void); + +/*! + * @brief Starts transmit with a TX pattern register data sequence. + * + * This function starts transmitting using the DFT pattern register mode. + * + * @param channel_num - the protocol specific channel to transmit on. Valid values are defined in the CHANNEL_NUM register documentation. + * @param radio_mode The radio mode for which the XCVR should be configured. + * @param data_rate The data rate for which the XCVR should be configured. Only matters when GFSK/MSK radio_mode is selected. + * @param tx_pattern - the data pattern to transmit on. + * @return The status of the pattern reg transmit. + * @note The XCVR_DftTxOff() function must be called to turn off TX and revert all settings. This routine calls XCVR_ChangeMode() with the desired radio mode + * and data rate. + */ +xcvrStatus_t XCVR_DftTxPatternReg(uint16_t channel_num, radio_mode_t radio_mode, data_rate_t data_rate, uint32_t tx_pattern); + +/*! + * @brief Starts transmit with a TX LFSR register data sequence. + * + * This function starts transmitting using the DFT LFSR register mode. + * + * @param channel_num - the protocol specific channel to transmit on. Valid values are defined in the CHANNEL_NUM register documentation. + * @param radio_mode The radio mode for which the XCVR should be configured. + * @param data_rate The data rate for which the XCVR should be configured. Only matters when GFSK/MSK radio_mode is selected. + * @param lfsr_length - the length of the LFSR sequence to use. + * @return The status of the LFSR reg transmit. + * @note The XCVR_DftTxOff() function must be called to turn off TX and revert all settings. This routine calls XCVR_ChangeMode() with the desired radio mode + * and data rate. + */ +xcvrStatus_t XCVR_DftTxLfsrReg(uint16_t channel_num, radio_mode_t radio_mode, data_rate_t data_rate, uint8_t lfsr_length); + +/*! + * @brief Controls clearing all TX DFT settings. + * + * This function reverts all TX DFT settings from the test modes to normal operating mode. + * + */ +void XCVR_DftTxOff(void); + +/*! + * @brief Controls setting the PA power level. + * + * This function enables setting the PA power level to a specific setting, overriding any link layer settings. + * + * @param pa_power - the power level to set. Valid values are 0, 1, and even values from 2 to 0x3E, inclusive. + * @return The status of the PA power over-ride. + */ +xcvrStatus_t XCVR_ForcePAPower(uint8_t pa_power); + +/*! + * @brief Starts CW TX. + * + * This function starts transmitting CW (no modulation). + * + * @param rf_channel_freq - the RF channel to transmit on. Valid values are integer values from 2360 to 2487MHz, inclusive. + * @param protocol - the protocol setting to use, valid settings are 6 (GFSK) and 7 (FSK). + * @return The status of the CW transmit. + */ +xcvrStatus_t XCVR_DftTxCW(uint16_t rf_channel_freq, uint8_t protocol); + +xcvrStatus_t XCVR_CoexistenceInit(void); +xcvrStatus_t XCVR_CoexistenceSetPriority(XCVR_COEX_PRIORITY_T rxPriority, XCVR_COEX_PRIORITY_T txPriority); +xcvrStatus_t XCVR_CoexistenceSaveRestoreTimings(uint8_t saveTimings); + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_XCVR_H_ */ + diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/fsl_xcvr_trim.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/fsl_xcvr_trim.c new file mode 100644 index 0000000000..d91dd1eba3 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/fsl_xcvr_trim.c @@ -0,0 +1,995 @@ +/* +* 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 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_device_registers.h" +#include "fsl_common.h" +#include "fsl_xcvr.h" +#include "fsl_xcvr_trim.h" +#include "dbg_ram_capture.h" +#include "math.h" + +/******************************************************************************* +* Definitions +******************************************************************************/ + + +/******************************************************************************* +* Prototypes +******************************************************************************/ +void DC_Measure_short(IQ_t chan, DAC_SWEEP_STEP2_t dcoc_init_val); +float calc_dcoc_dac_step(GAIN_CALC_TBL_ENTRY2_T * meas_ptr, GAIN_CALC_TBL_ENTRY2_T * baseline_meas_ptr ); +extern float roundf (float); + +/******************************************************************************* +* Variables +******************************************************************************/ +const int8_t TsettleCal = 10; +static GAIN_CALC_TBL_ENTRY2_T measurement_tbl2[NUM_I_Q_CHAN][NUM_SWEEP_STEP_ENTRIES2]; +static const int8_t sweep_step_values2[NUM_SWEEP_STEP_ENTRIES2] = +{ + 0, /* Baseline entry is first and not used in this table */ + -16, + +16, + -4, + -4, + -4, + -4, + -4, + -4, + -4, + -4, + -4, + -4, + -4, + +4, + +4, + +4, + +4, + +4, + +4, + +4, + +4, + +4, + +4, + +4 +}; + +/******************************************************************************* + * Macros + ******************************************************************************/ +#define ISIGN(x) !((uint16_t)x & 0x8000) +#define ABS(x) ((x) > 0 ? (x) : -(x)) + +/******************************************************************************* + * Code + ******************************************************************************/ +/*! ********************************************************************************* + * \brief This function performs a trim of the BBA DCOC DAC on the DUT + * + * \return status - 1 if passed, 0 if failed. + * + * \ingroup PublicAPIs + * + * \details + * Requires the RX to be warmed up before this function is called. + * + ***********************************************************************************/ +uint8_t rx_bba_dcoc_dac_trim_shortIQ(void) +{ + uint8_t i; + float temp_mi = 0; + float temp_mq = 0; + float temp_pi = 0; + float temp_pq = 0; + float temp_step = 0; + uint8_t bbf_dacinit_i, bbf_dacinit_q; + + uint32_t dcoc_init_reg_value_dcgain = 0x80802020; /* Used in 2nd & 3rd Generation DCOC Trims only. */ + uint32_t bbf_dcoc_step; + uint32_t bbf_dcoc_step_rcp; + TZAdcocstep_t tza_dcoc_step[11]; + uint8_t status = 0; + + /* Save register values. */ + uint32_t dcoc_ctrl_0_stack; + uint32_t dcoc_ctrl_1_stack; + uint32_t agc_ctrl_1_stack; + uint32_t rx_dig_ctrl_stack; + uint32_t dcoc_cal_gain_state; + + XcvrCalDelay(1000); + dcoc_ctrl_0_stack = XCVR_RX_DIG->DCOC_CTRL_0; /* Save state of DCOC_CTRL_0 for later restore. */ + dcoc_ctrl_1_stack = XCVR_RX_DIG->DCOC_CTRL_1; /* Save state of DCOC_CTRL_1 for later restore. */ + rx_dig_ctrl_stack = XCVR_RX_DIG->RX_DIG_CTRL; /* Save state of RX_DIG_CTRL for later restore. */ + agc_ctrl_1_stack = XCVR_RX_DIG->AGC_CTRL_1; /* Save state of RX_DIG_CTRL for later restore. */ + dcoc_cal_gain_state = XCVR_RX_DIG->DCOC_CAL_GAIN; /* Save state of DCOC_CAL_GAIN for later restore. */ + + /* Ensure AGC, DCOC and RX_DIG_CTRL is in correct mode. */ + XCVR_RX_DIG->RX_DIG_CTRL = (XCVR_RX_DIG->RX_DIG_CTRL & ~XCVR_RX_DIG_RX_DIG_CTRL_RX_AGC_EN_MASK) | XCVR_RX_DIG_RX_DIG_CTRL_RX_AGC_EN(0); /* Turn OFF AGC */ + + XCVR_RX_DIG->AGC_CTRL_1 = (XCVR_RX_DIG->AGC_CTRL_1 & ~XCVR_RX_DIG_AGC_CTRL_1_USER_LNA_GAIN_EN_MASK) | XCVR_RX_DIG_AGC_CTRL_1_USER_LNA_GAIN_EN(1) ; /* Set LNA Manual Gain */ + XCVR_RX_DIG->AGC_CTRL_1 = (XCVR_RX_DIG->AGC_CTRL_1 & ~XCVR_RX_DIG_AGC_CTRL_1_USER_BBA_GAIN_EN_MASK) | XCVR_RX_DIG_AGC_CTRL_1_USER_BBA_GAIN_EN(1) ; /* Set BBA Manual Gain */ + + XCVR_RX_DIG->RX_DIG_CTRL = (XCVR_RX_DIG->RX_DIG_CTRL & ~XCVR_RX_DIG_RX_DIG_CTRL_RX_DCOC_CAL_EN_MASK) | XCVR_RX_DIG_RX_DIG_CTRL_RX_DCOC_CAL_EN(0); /* Enable HW DC Calibration -- Disable for SW-DCOC */ + XCVR_RX_DIG->DCOC_CTRL_0 = (XCVR_RX_DIG->DCOC_CTRL_0 & ~XCVR_RX_DIG_DCOC_CTRL_0_DCOC_MAN_MASK) | XCVR_RX_DIG_DCOC_CTRL_0_DCOC_MAN(1); /* Enable Manual DCOC */ + /* DCOC_CTRL_0 @ 4005_C02C -- Define default DCOC DAC settings in manual mode. */ + XCVR_RX_DIG->DCOC_DAC_INIT = XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_I(0x20) | XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_Q(0x20) | XCVR_RX_DIG_DCOC_DAC_INIT_TZA_DCOC_INIT_I(0x80) | XCVR_RX_DIG_DCOC_DAC_INIT_TZA_DCOC_INIT_Q(0x80); + /* Set DCOC Tracking State. */ + XCVR_RX_DIG->DCOC_CTRL_0 = (XCVR_RX_DIG->DCOC_CTRL_0 & ~XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CORRECT_SRC_MASK) | XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CORRECT_SRC(0); /* Disables DCOC Tracking when set to 0 */ + /* Apply Manual Gain. */ + XCVR_RX_DIG->AGC_CTRL_1 = XCVR_RX_DIG_AGC_CTRL_1_USER_LNA_GAIN_EN(1) | XCVR_RX_DIG_AGC_CTRL_1_USER_BBA_GAIN_EN(1) | XCVR_RX_DIG_AGC_CTRL_1_LNA_USER_GAIN(0x02) | XCVR_RX_DIG_AGC_CTRL_1_BBA_USER_GAIN(0x00) ; + XcvrCalDelay(TsettleCal); + + dcoc_init_reg_value_dcgain = XCVR_RX_DIG->DCOC_DAC_INIT; /* Capture DC null setting. */ + + bbf_dacinit_i = (dcoc_init_reg_value_dcgain & 0x000000FFU); + bbf_dacinit_q = (dcoc_init_reg_value_dcgain & 0x0000FF00U) >> 8; + + DC_Measure_short(I_CHANNEL, NOMINAL2); + DC_Measure_short(Q_CHANNEL, NOMINAL2); + + /* SWEEP Q CHANNEL */ + /* BBF NEG STEP */ + XCVR_RX_DIG->DCOC_DAC_INIT = (XCVR_RX_DIG->DCOC_DAC_INIT & ~XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_Q_MASK) | XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_Q(bbf_dacinit_q - 16); + XcvrCalDelay(TsettleCal); + DC_Measure_short(Q_CHANNEL, BBF_NEG); + + /* BBF POS STEP */ + XCVR_RX_DIG->DCOC_DAC_INIT = (XCVR_RX_DIG->DCOC_DAC_INIT & ~XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_Q_MASK) | XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_Q(bbf_dacinit_q + 16); + XcvrCalDelay(TsettleCal); + DC_Measure_short(Q_CHANNEL, BBF_POS); + + XCVR_RX_DIG->DCOC_DAC_INIT = dcoc_init_reg_value_dcgain; /* Return DAC setting to initial. */ + XcvrCalDelay(TsettleCal); + + /* SWEEP I CHANNEL */ + /* BBF NEG STEP */ + XCVR_RX_DIG->DCOC_DAC_INIT = (XCVR_RX_DIG->DCOC_DAC_INIT & ~XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_I_MASK) | XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_I(bbf_dacinit_i - 16); + XcvrCalDelay(TsettleCal); + DC_Measure_short(I_CHANNEL, BBF_NEG); + /* BBF POS STEP */ + XCVR_RX_DIG->DCOC_DAC_INIT = (XCVR_RX_DIG->DCOC_DAC_INIT & ~XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_I_MASK) | XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_I(bbf_dacinit_i + 16); + XcvrCalDelay(TsettleCal); + DC_Measure_short(I_CHANNEL, BBF_POS); + + XCVR_RX_DIG->DCOC_DAC_INIT = dcoc_init_reg_value_dcgain; /* Return DACs to initial. */ + XcvrCalDelay(TsettleCal); + + /* Calculate BBF DCOC STEPS, RECIPROCALS */ + temp_mi = calc_dcoc_dac_step(&measurement_tbl2[I_CHANNEL][BBF_NEG], &measurement_tbl2[I_CHANNEL][NOMINAL2]); + temp_mq = calc_dcoc_dac_step(&measurement_tbl2[Q_CHANNEL][BBF_NEG], &measurement_tbl2[Q_CHANNEL][NOMINAL2]); + temp_pi = calc_dcoc_dac_step(&measurement_tbl2[I_CHANNEL][BBF_POS], &measurement_tbl2[I_CHANNEL][NOMINAL2]); + temp_pq = calc_dcoc_dac_step(&measurement_tbl2[Q_CHANNEL][BBF_POS], &measurement_tbl2[Q_CHANNEL][NOMINAL2]); + + temp_step = (temp_mi+temp_pi + temp_mq+temp_pq) / 4; + + bbf_dcoc_step = (uint32_t)roundf(temp_step * 8U); + + if ((bbf_dcoc_step > 265) & (bbf_dcoc_step < 305)) + { + bbf_dcoc_step_rcp = (uint32_t)roundf((float)0x8000U / temp_step); + + /* Calculate TZA DCOC STEPS & RECIPROCALS and IQ_DC_GAIN_MISMATCH. */ + for (i = TZA_STEP_N0; i <= TZA_STEP_N10; i++) /* Relying on enumeration ordering. */ + { + /* Calculate TZA DCOC STEPSIZE & its RECIPROCAL. */ + switch(i){ + case TZA_STEP_N0: + temp_step = (bbf_dcoc_step >> 3U) / 3.6F; + break; + case TZA_STEP_N1: + temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_01_init >> 16)/(xcvr_common_config.dcoc_tza_step_00_init >> 16); + break; + case TZA_STEP_N2: + temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_02_init >> 16)/(xcvr_common_config.dcoc_tza_step_01_init >> 16); + break; + case TZA_STEP_N3: + temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_03_init >> 16)/(xcvr_common_config.dcoc_tza_step_02_init >> 16); + break; + case TZA_STEP_N4: + temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_04_init >> 16)/(xcvr_common_config.dcoc_tza_step_03_init >> 16); + break; + case TZA_STEP_N5: + temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_05_init >> 16)/(xcvr_common_config.dcoc_tza_step_04_init >> 16); + break; + case TZA_STEP_N6: + temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_06_init >> 16)/(xcvr_common_config.dcoc_tza_step_05_init >> 16); + break; + case TZA_STEP_N7: + temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_07_init >> 16)/(xcvr_common_config.dcoc_tza_step_06_init >> 16); + break; + case TZA_STEP_N8: + temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_08_init >> 16)/(xcvr_common_config.dcoc_tza_step_07_init >> 16); + break; + case TZA_STEP_N9: + temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_09_init >> 16)/(xcvr_common_config.dcoc_tza_step_08_init >> 16); + break; + case TZA_STEP_N10: + temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_10_init >> 16)/(xcvr_common_config.dcoc_tza_step_09_init >> 16); + break; + default: + break; + } + + tza_dcoc_step[i-TZA_STEP_N0].dcoc_step = (uint32_t)roundf(temp_step * 8); + tza_dcoc_step[i-TZA_STEP_N0].dcoc_step_rcp = (uint32_t)roundf((float)0x8000 / temp_step); + } + + /* Make the trims active. */ + XCVR_RX_DIG->DCOC_BBA_STEP = XCVR_RX_DIG_DCOC_BBA_STEP_BBA_DCOC_STEP(bbf_dcoc_step) | XCVR_RX_DIG_DCOC_BBA_STEP_BBA_DCOC_STEP_RECIP(bbf_dcoc_step_rcp) ; + XCVR_RX_DIG->DCOC_TZA_STEP_0 = XCVR_RX_DIG_DCOC_TZA_STEP_0_DCOC_TZA_STEP_GAIN_0(tza_dcoc_step[0].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_0_DCOC_TZA_STEP_RCP_0(tza_dcoc_step[0].dcoc_step_rcp) ; + XCVR_RX_DIG->DCOC_TZA_STEP_1 = XCVR_RX_DIG_DCOC_TZA_STEP_1_DCOC_TZA_STEP_GAIN_1(tza_dcoc_step[1].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_1_DCOC_TZA_STEP_RCP_1(tza_dcoc_step[1].dcoc_step_rcp) ; + XCVR_RX_DIG->DCOC_TZA_STEP_2 = XCVR_RX_DIG_DCOC_TZA_STEP_2_DCOC_TZA_STEP_GAIN_2(tza_dcoc_step[2].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_2_DCOC_TZA_STEP_RCP_2(tza_dcoc_step[2].dcoc_step_rcp) ; + XCVR_RX_DIG->DCOC_TZA_STEP_3 = XCVR_RX_DIG_DCOC_TZA_STEP_3_DCOC_TZA_STEP_GAIN_3(tza_dcoc_step[3].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_3_DCOC_TZA_STEP_RCP_3(tza_dcoc_step[3].dcoc_step_rcp) ; + XCVR_RX_DIG->DCOC_TZA_STEP_4 = XCVR_RX_DIG_DCOC_TZA_STEP_4_DCOC_TZA_STEP_GAIN_4(tza_dcoc_step[4].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_4_DCOC_TZA_STEP_RCP_4(tza_dcoc_step[4].dcoc_step_rcp) ; + XCVR_RX_DIG->DCOC_TZA_STEP_5 = XCVR_RX_DIG_DCOC_TZA_STEP_5_DCOC_TZA_STEP_GAIN_5(tza_dcoc_step[5].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_5_DCOC_TZA_STEP_RCP_5(tza_dcoc_step[5].dcoc_step_rcp) ; + XCVR_RX_DIG->DCOC_TZA_STEP_6 = XCVR_RX_DIG_DCOC_TZA_STEP_6_DCOC_TZA_STEP_GAIN_6(tza_dcoc_step[6].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_6_DCOC_TZA_STEP_RCP_6(tza_dcoc_step[6].dcoc_step_rcp) ; + XCVR_RX_DIG->DCOC_TZA_STEP_7 = XCVR_RX_DIG_DCOC_TZA_STEP_7_DCOC_TZA_STEP_GAIN_7(tza_dcoc_step[7].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_7_DCOC_TZA_STEP_RCP_7(tza_dcoc_step[7].dcoc_step_rcp) ; + XCVR_RX_DIG->DCOC_TZA_STEP_8 = XCVR_RX_DIG_DCOC_TZA_STEP_8_DCOC_TZA_STEP_GAIN_8(tza_dcoc_step[8].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_8_DCOC_TZA_STEP_RCP_8(tza_dcoc_step[8].dcoc_step_rcp) ; + XCVR_RX_DIG->DCOC_TZA_STEP_9 = XCVR_RX_DIG_DCOC_TZA_STEP_9_DCOC_TZA_STEP_GAIN_9(tza_dcoc_step[9].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_9_DCOC_TZA_STEP_RCP_9(tza_dcoc_step[9].dcoc_step_rcp) ; + XCVR_RX_DIG->DCOC_TZA_STEP_10 = XCVR_RX_DIG_DCOC_TZA_STEP_10_DCOC_TZA_STEP_GAIN_10(tza_dcoc_step[10].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_10_DCOC_TZA_STEP_RCP_10(tza_dcoc_step[10].dcoc_step_rcp) ; + + status = 1; /* Success */ + } + else + { + status = 0; /* Failure */ + } + + /* Restore Registers. */ + XCVR_RX_DIG->DCOC_CTRL_0 = dcoc_ctrl_0_stack; /* Restore DCOC_CTRL_0 state to prior settings. */ + XCVR_RX_DIG->DCOC_CTRL_1 = dcoc_ctrl_1_stack; /* Restore DCOC_CTRL_1 state to prior settings. */ + XCVR_RX_DIG->RX_DIG_CTRL = rx_dig_ctrl_stack; /* Restore RX_DIG_CTRL state to prior settings. */ + XCVR_RX_DIG->DCOC_CAL_GAIN = dcoc_cal_gain_state; /* Restore DCOC_CAL_GAIN state to prior setting. */ + XCVR_RX_DIG->AGC_CTRL_1 = agc_ctrl_1_stack; /* Save state of RX_DIG_CTRL for later restore. */ + + return status; +} + +/*! ********************************************************************************* + * \brief This function performs one point of the DC GAIN calibration process on the DUT + * + * \param[in] chan - whether the I or Q channel is being tested. + * \param[in] stage - whether the BBF or TZA gain stage is being tested. + * \param[in] dcoc_init_val - the value being set in the ***DCOC_INIT_* register by the parent. + * \param[in] ext_measmt - the external measurement (in milliVolts) captured by the parent after the ***DCOC_INIT_* register was setup. + * + * \ingroup PublicAPIs + * + * \details + * Relies on a static array to store each point of data for later processing in ::DC_GainCalc(). + * + ***********************************************************************************/ +void DC_Measure_short(IQ_t chan, DAC_SWEEP_STEP2_t dcoc_init_val) +{ + int16_t dc_meas_i = 0; + int16_t dc_meas_q = 0; + int16_t sum_dc_meas_i = 0; + int16_t sum_dc_meas_q = 0; + + { + int8_t i; + const int8_t iterations = 1; + sum_dc_meas_i = 0; + sum_dc_meas_q = 0; + + for (i = 0; i < iterations; i++) + { + rx_dc_sample_average(&dc_meas_i, &dc_meas_q); + sum_dc_meas_i = sum_dc_meas_i + dc_meas_i; + sum_dc_meas_q = sum_dc_meas_q + dc_meas_q; + } + sum_dc_meas_i = sum_dc_meas_i / iterations; + sum_dc_meas_q = sum_dc_meas_q / iterations; + } + + measurement_tbl2[chan][dcoc_init_val].step_value = sweep_step_values2[dcoc_init_val]; + + if (chan == I_CHANNEL) + { + measurement_tbl2[chan][dcoc_init_val].internal_measurement = dc_meas_i; + } + else + { + measurement_tbl2[chan][dcoc_init_val].internal_measurement = dc_meas_q; + } +} + +/*! ********************************************************************************* + * \brief This function calculates one point of DC DAC step based on digital samples of I or Q. + * + * \param[in] meas_ptr - pointer to the structure containing the measured data from internal measurement. + * \param[in] baseline_meas_ptr - pointer to the structure containing the baseline measured data from internal measurement. + * + * \return result of the calculation, the measurement DCOC DAC step value for this measurement point. + * + ***********************************************************************************/ +float calc_dcoc_dac_step(GAIN_CALC_TBL_ENTRY2_T * meas_ptr, GAIN_CALC_TBL_ENTRY2_T * baseline_meas_ptr ) +{ + static int16_t norm_dc_code; + static float dc_step; + + /* Normalize internal measurement */ + norm_dc_code = meas_ptr->internal_measurement - baseline_meas_ptr->internal_measurement; + dc_step = (float)(norm_dc_code) / (float)(meas_ptr->step_value); + dc_step = (dc_step < 0)? -dc_step: dc_step; + + return dc_step; +} + +/*! ********************************************************************************* + * \brief Temporary delay function + * + * \param[in] none. + * + * \return none. + * + * \details + * + ***********************************************************************************/ +void XcvrCalDelay(uint32_t time) +{ + while(time * 32 > 0) /* Time delay is roughly in uSec. */ + { + time--; + } +} + +/*! ********************************************************************************* + * \brief This function calculates the average (DC value) based on a smaller set of digital samples of I and Q. + * + * \param[in] i_avg - pointer to the location for storing the calculated average for I channel samples. + * \param[in] q_avg - pointer to the location for storing the calculated average for Q channel samples. + * + ***********************************************************************************/ +void rx_dc_sample_average(int16_t * i_avg, int16_t * q_avg) +{ + static uint32_t samples[128]; /* 544*2*2 (entire packet ram1/2 size) */ + uint16_t i; + uint32_t rx_sample; + uint16_t * sample_ptr; + uint32_t temp, end_of_rx_wu; + uint32_t num_iq_samples; + float avg_i = 0; + float avg_q = 0; + + num_iq_samples = 128; + + /* Clear the entire allocated sample buffer */ + for (i = 0; i < num_iq_samples; i++) + { + samples[i]=0; + } + + /* Assume this has been called *AFTER* RxWu has completed. */ + /* XCVR_ForceRxWu(); */ + + /* Wait for TSM to reach the end of warmup (unless you want to capture some samples during DCOC cal phase) */ + temp = XCVR_TSM->END_OF_SEQ; + end_of_rx_wu = (temp & XCVR_TSM_END_OF_SEQ_END_OF_RX_WU_MASK) >> XCVR_TSM_END_OF_SEQ_END_OF_RX_WU_SHIFT; + while ((( XCVR_MISC->XCVR_STATUS & XCVR_CTRL_XCVR_STATUS_TSM_COUNT_MASK) >> XCVR_CTRL_XCVR_STATUS_TSM_COUNT_SHIFT ) != end_of_rx_wu) {}; + + dbg_ram_init(); + /* Argument below is # of bytes, so *2 (I+Q) and *2 (2bytes/sample) */ +#if RADIO_IS_GEN_3P0 + dbg_ram_start_capture(DBG_PAGE_RXDIGIQ, NO_START_TRIG, NO_STOP_TRIG); + dbg_ram_wait_for_complete(); + dbg_ram_postproc_capture(DBG_PAGE_RXDIGIQ, num_iq_samples * 2 * 2, &samples[0]); + dbg_ram_release(); +#else + (void)dbg_ram_capture(DBG_PAGE_RXDIGIQ, num_iq_samples * 2 * 2, &samples[0]); +#endif /* RADIO_IS_GEN_3P0 */ + + /* Sign extend the IQ samples in place in the sample buffer. */ + sample_ptr = (uint16_t *)(&samples[0]); + for (i = 0; i < num_iq_samples * 2; i++) + { + rx_sample = *sample_ptr; + rx_sample |= ((rx_sample & 0x800U) ? 0xF000U : 0x0U); /* Sign extend from 12 to 16 bits. */ + *sample_ptr = rx_sample; + sample_ptr++; + } + + sample_ptr = (uint16_t *)(&samples[0]); + for (i = 0; i < num_iq_samples * 2; i += 2) + { + static int16_t i_value; + static int16_t q_value; + + /* Average I & Q channels separately. */ + i_value = *(sample_ptr + i); /* Sign extend from 12 to 16 bits. */ + q_value = *(sample_ptr + i + 1); /* Sign extend from 12 to 16 bits. */ + avg_i += ((float)i_value - avg_i) / (float)(i + 1); /* Rolling average I */ + avg_q += ((float)q_value - avg_q) / (float)(i + 1); /* Rolling average Q */ + } + XcvrCalDelay(10); + *i_avg = (int16_t)avg_i; + *q_avg = (int16_t)avg_q; +} + +/*! ********************************************************************************* + * \brief This function calculates the average (DC value) based on a larger set of digital samples of I and Q. + * + * \param[in] i_avg - pointer to the location for storing the calculated average for I channel samples. + * \param[in] q_avg - pointer to the location for storing the calculated average for Q channel samples. + * + ***********************************************************************************/ +void rx_dc_sample_average_long(int16_t * i_avg, int16_t * q_avg) +{ + static uint32_t samples[512]; /* 544*2*2 (entire packet ram1/2 size) */ + uint16_t i; + uint32_t rx_sample; + uint16_t * sample_ptr; + uint32_t temp, end_of_rx_wu; + uint32_t num_iq_samples; + float avg_i = 0; + float avg_q = 0; + + num_iq_samples = 512; + + /* Clear the entire allocated sample buffer. */ + for (i = 0; i < num_iq_samples; i++) + { + samples[i]=0; + } + + /* Assume this has been called *AFTER* RxWu has completed. */ + /* XCVR_ForceRxWu(); */ + + /* Wait for TSM to reach the end of warmup (unless you want to capture some samples during DCOC cal phase). */ + temp = XCVR_TSM->END_OF_SEQ; + end_of_rx_wu = (temp & XCVR_TSM_END_OF_SEQ_END_OF_RX_WU_MASK) >> XCVR_TSM_END_OF_SEQ_END_OF_RX_WU_SHIFT; + while ((( XCVR_MISC->XCVR_STATUS & XCVR_CTRL_XCVR_STATUS_TSM_COUNT_MASK) >> XCVR_CTRL_XCVR_STATUS_TSM_COUNT_SHIFT ) != end_of_rx_wu) {}; + + dbg_ram_init(); + /* Argument below is # of bytes, so *2 (I+Q) and *2 (2bytes/sample) */ +#if RADIO_IS_GEN_3P0 + dbg_ram_start_capture(DBG_PAGE_RXDIGIQ, NO_START_TRIG, NO_STOP_TRIG); + dbg_ram_wait_for_complete(); + dbg_ram_postproc_capture(DBG_PAGE_RXDIGIQ,num_iq_samples * 2 * 2, &samples[0]); + dbg_ram_release(); +#else + (void)dbg_ram_capture(DBG_PAGE_RXDIGIQ, num_iq_samples * 2 * 2, &samples[0]); +#endif /* RADIO_IS_GEN_3P0 */ + + /* Sign extend the IQ samples in place in the sample buffer. */ + + sample_ptr = (uint16_t *)(&samples[0]); + for (i = 0; i < num_iq_samples * 2; i++) + { + rx_sample = *sample_ptr; + rx_sample |= ((rx_sample & 0x800U) ? 0xF000U : 0x0U); /* Sign extend from 12 to 16 bits. */ + *sample_ptr = rx_sample; + sample_ptr++; + } + + sample_ptr = (uint16_t *)(&samples[0]); + for (i = 0; i < num_iq_samples * 2; i += 2) + { + static int16_t i_value; + static int16_t q_value; + + /* Average I & Q channels separately. */ + i_value = *(sample_ptr + i); /* Sign extend from 12 to 16 bits */ + q_value = *(sample_ptr + i + 1); /* Sign extend from 12 to 16 bits */ + avg_i += ((float)i_value - avg_i) / (float)(i + 1); /* Rolling average I */ + avg_q += ((float)q_value - avg_q) / (float)(i + 1); /* Rolling average Q */ + } + + XcvrCalDelay(10); + *i_avg = (int16_t)avg_i; + *q_avg = (int16_t)avg_q; +} + +/*! ********************************************************************************* + * rx_dc_est_average : Get DC EST values and return the Average + ***********************************************************************************/ +void rx_dc_est_average(int16_t * i_avg, int16_t * q_avg, uint16_t SampleNumber) +{ + float avg_i = 0; + float avg_q = 0; + uint16_t i = 0; + static uint32_t dc_temp, temp; + uint32_t end_of_rx_wu = 0; + static int16_t dc_meas_i; + static int16_t dc_meas_q; + + /* Wait for TSM to reach the end of warmup (unless you want to capture some samples during DCOC cal phase). */ + temp = XCVR_TSM->END_OF_SEQ; + end_of_rx_wu = (temp & XCVR_TSM_END_OF_SEQ_END_OF_RX_WU_MASK) >> XCVR_TSM_END_OF_SEQ_END_OF_RX_WU_SHIFT; + while ((( XCVR_MISC->XCVR_STATUS & XCVR_CTRL_XCVR_STATUS_TSM_COUNT_MASK) >> XCVR_CTRL_XCVR_STATUS_TSM_COUNT_SHIFT ) != end_of_rx_wu) {}; + + /* Read DCOC DC EST register. */ + for (i = 0; i < SampleNumber; i++) + { + dc_temp = XCVR_RX_DIG->DCOC_DC_EST; + dc_meas_i = dc_temp & XCVR_RX_DIG_DCOC_DC_EST_DC_EST_I_MASK; + temp = dc_meas_i; + temp |= ((temp & 0x800U) ? 0xF000U : 0x0U); /* Sign extend from 12 to 16 bits. */ + dc_meas_i = temp; + avg_i += (float) dc_meas_i; + + dc_meas_q = (dc_temp & XCVR_RX_DIG_DCOC_DC_EST_DC_EST_Q_MASK) >> XCVR_RX_DIG_DCOC_DC_EST_DC_EST_Q_SHIFT; + temp = dc_meas_q; + temp |= ((temp & 0x800U) ? 0xF000U : 0x0U); /* Sign extend from 12 to 16 bits. */ + dc_meas_q = temp; + avg_q += (float) dc_meas_q; + } + + avg_i /= (float) SampleNumber; + avg_q /= (float) SampleNumber; + + *i_avg = (int16_t)avg_i; + *q_avg = (int16_t)avg_q; +} + +/*! ********************************************************************************* + * \brief This function performs a trim of the BBA DCOC DAC on the DUT + * + * \return status - 1 if passed, 0 if failed. + * + * \ingroup PublicAPIs + * + * \details + * Requires the RX to be warmed up before this function is called. + * + ***********************************************************************************/ +uint8_t rx_bba_dcoc_dac_trim_DCest(void) +{ + uint8_t i; + float temp_mi = 0; + float temp_mq = 0; + float temp_pi = 0; + float temp_pq = 0; + float temp_step = 0; + + uint32_t bbf_dcoc_step; + uint32_t bbf_dcoc_step_rcp; + TZAdcocstep_t tza_dcoc_step[11]; + uint8_t status = 0; + + uint8_t bbf_dacinit_i, bbf_dacinit_q; + uint8_t tza_dacinit_i, tza_dacinit_q; + int16_t dc_meas_i; + int16_t dc_meas_q; + uint32_t dcoc_init_reg_value_dcgain = 0x80802020; /* Used in 2nd & 3rd Generation DCOC Trims only */ + uint32_t temp; + + uint32_t dcoc_ctrl_0_stack; + uint32_t dcoc_ctrl_1_stack; + uint32_t agc_ctrl_1_stack; + uint32_t rx_dig_ctrl_stack; + uint32_t dcoc_cal_gain_state; + + /* Save register */ + dcoc_ctrl_0_stack = XCVR_RX_DIG->DCOC_CTRL_0; /* Save state of DCOC_CTRL_0 for later restore */ + dcoc_ctrl_1_stack = XCVR_RX_DIG->DCOC_CTRL_1; /* Save state of DCOC_CTRL_1 for later restore */ + rx_dig_ctrl_stack = XCVR_RX_DIG->RX_DIG_CTRL; /* Save state of RX_DIG_CTRL for later restore */ + agc_ctrl_1_stack = XCVR_RX_DIG->AGC_CTRL_1; /* Save state of RX_DIG_CTRL for later restore */ + dcoc_cal_gain_state = XCVR_RX_DIG->DCOC_CAL_GAIN; /* Save state of DCOC_CAL_GAIN for later restore */ + + /* Register config */ + /* Ensure AGC, DCOC and RX_DIG_CTRL is in correct mode */ + temp = XCVR_RX_DIG->RX_DIG_CTRL; + temp &= ~XCVR_RX_DIG_RX_DIG_CTRL_RX_AGC_EN_MASK; /* Turn OFF AGC */ + temp &= ~XCVR_RX_DIG_RX_DIG_CTRL_RX_DCOC_CAL_EN_MASK; /* Disable for SW control of DCOC */ + temp &= ~XCVR_RX_DIG_RX_DIG_CTRL_RX_DC_RESID_EN_MASK; /* Disable for SW control of DCOC */ + XCVR_RX_DIG->RX_DIG_CTRL = temp; + + XCVR_RX_DIG->AGC_CTRL_1 = XCVR_RX_DIG_AGC_CTRL_1_USER_LNA_GAIN_EN(1) | /* Enable LNA Manual Gain */ + XCVR_RX_DIG_AGC_CTRL_1_USER_BBA_GAIN_EN(1) | /* Enable BBA Manual Gain */ + XCVR_RX_DIG_AGC_CTRL_1_LNA_USER_GAIN(0x0) | /* Set LNA Manual Gain */ + XCVR_RX_DIG_AGC_CTRL_1_BBA_USER_GAIN(0x0); /* Set BBA Manual Gain */ + + /* DCOC_CTRL_0 @ 4005_C02C -- Define default DCOC DAC settings in manual mode */ + temp = XCVR_RX_DIG->DCOC_CTRL_0; + temp |= XCVR_RX_DIG_DCOC_CTRL_0_DCOC_MAN(1); /* Enable Manual DCOC */ + temp |= XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CORRECT_SRC(1); /* Ensure DCOC Tracking is enabled */ + temp |= XCVR_RX_DIG_DCOC_CTRL_0_DCOC_TRK_EST_OVR(1); /* Enable DC Estimator */ + temp |= XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CORRECT_EN(1); /* Ensure DC correction is enabled */ + XCVR_RX_DIG->DCOC_CTRL_0 = temp; + + XCVR_RX_DIG->DCOC_DAC_INIT = XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_I(0x20) | + XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_Q(0x20) | + XCVR_RX_DIG_DCOC_DAC_INIT_TZA_DCOC_INIT_I(0x80) | + XCVR_RX_DIG_DCOC_DAC_INIT_TZA_DCOC_INIT_Q(0x80); + + XcvrCalDelay(TsettleCal); + + /* Set default DCOC DAC INIT Value */ + dcoc_init_reg_value_dcgain = XCVR_RX_DIG->DCOC_DAC_INIT; /* Store DCOC DAC INIT values */ + bbf_dacinit_i = (dcoc_init_reg_value_dcgain & 0x000000FFU); + bbf_dacinit_q = (dcoc_init_reg_value_dcgain & 0x0000FF00U)>>8; + tza_dacinit_i = (dcoc_init_reg_value_dcgain & 0x00FF0000U)>>16; + tza_dacinit_q = dcoc_init_reg_value_dcgain >> 24; + + XcvrCalDelay(TsettleCal * 4); + rx_dc_est_average(&dc_meas_i, &dc_meas_q, 64); + measurement_tbl2[I_CHANNEL][NOMINAL2].step_value = sweep_step_values2[NOMINAL2]; + measurement_tbl2[Q_CHANNEL][NOMINAL2].step_value = sweep_step_values2[NOMINAL2]; + measurement_tbl2[I_CHANNEL][NOMINAL2].internal_measurement = dc_meas_i; + measurement_tbl2[Q_CHANNEL][NOMINAL2].internal_measurement = dc_meas_q; + + /* SWEEP I/Q CHANNEL */ + /* BBF NEG STEP */ + XCVR_RX_DIG->DCOC_DAC_INIT = XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_I(bbf_dacinit_i - 16) | + XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_Q(bbf_dacinit_q - 16) | + XCVR_RX_DIG_DCOC_DAC_INIT_TZA_DCOC_INIT_I(tza_dacinit_i) | + XCVR_RX_DIG_DCOC_DAC_INIT_TZA_DCOC_INIT_Q(tza_dacinit_q); + XcvrCalDelay(TsettleCal * 2); + + rx_dc_est_average(&dc_meas_i, &dc_meas_q, 64); + measurement_tbl2[I_CHANNEL][BBF_NEG].step_value = -16; + measurement_tbl2[Q_CHANNEL][BBF_NEG].step_value = -16; + measurement_tbl2[I_CHANNEL][BBF_NEG].internal_measurement = dc_meas_i; + measurement_tbl2[Q_CHANNEL][BBF_NEG].internal_measurement = dc_meas_q; + + + /* BBF POS STEP */ + XCVR_RX_DIG->DCOC_DAC_INIT = XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_I(bbf_dacinit_i + 16) | + XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_Q(bbf_dacinit_q + 16) | + XCVR_RX_DIG_DCOC_DAC_INIT_TZA_DCOC_INIT_I(tza_dacinit_i) | + XCVR_RX_DIG_DCOC_DAC_INIT_TZA_DCOC_INIT_Q(tza_dacinit_q); + XcvrCalDelay(TsettleCal * 2); + rx_dc_est_average(&dc_meas_i, &dc_meas_q, 64); + measurement_tbl2[I_CHANNEL][BBF_POS].step_value = +16; + measurement_tbl2[Q_CHANNEL][BBF_POS].step_value = +16; + measurement_tbl2[I_CHANNEL][BBF_POS].internal_measurement = dc_meas_i; + measurement_tbl2[Q_CHANNEL][BBF_POS].internal_measurement = dc_meas_q; + + XCVR_RX_DIG->DCOC_DAC_INIT = dcoc_init_reg_value_dcgain; /* Return DAC setting to initial */ + + /* Calculate BBF DCOC STEPS, RECIPROCALS */ + temp_mi = calc_dcoc_dac_step(&measurement_tbl2[I_CHANNEL][BBF_NEG], &measurement_tbl2[I_CHANNEL][NOMINAL2]); + temp_mq = calc_dcoc_dac_step(&measurement_tbl2[Q_CHANNEL][BBF_NEG], &measurement_tbl2[Q_CHANNEL][NOMINAL2]); + temp_pi = calc_dcoc_dac_step(&measurement_tbl2[I_CHANNEL][BBF_POS], &measurement_tbl2[I_CHANNEL][NOMINAL2]); + temp_pq = calc_dcoc_dac_step(&measurement_tbl2[Q_CHANNEL][BBF_POS], &measurement_tbl2[Q_CHANNEL][NOMINAL2]); + + temp_step = (temp_mi + temp_pi + temp_mq + temp_pq) / 4; + bbf_dcoc_step = (uint32_t)roundf(temp_step * 8U); + + if ((bbf_dcoc_step > 265) & (bbf_dcoc_step < 305)) + { + bbf_dcoc_step_rcp = (uint32_t)roundf((float)0x8000U / temp_step); + + /* Calculate TZA DCOC STEPS & RECIPROCALS and IQ_DC_GAIN_MISMATCH */ + for (i = TZA_STEP_N0; i <= TZA_STEP_N10; i++) + { + /* Calculate TZA DCOC STEPSIZE & its RECIPROCAL */ + switch(i){ + case TZA_STEP_N0: + temp_step = (bbf_dcoc_step>>3U) / 3.6F; + break; + case TZA_STEP_N1: + temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_01_init >> 16) / (xcvr_common_config.dcoc_tza_step_00_init >> 16); + break; + case TZA_STEP_N2: + temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_02_init >> 16) / (xcvr_common_config.dcoc_tza_step_01_init >> 16); + break; + case TZA_STEP_N3: + temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_03_init >> 16) / (xcvr_common_config.dcoc_tza_step_02_init >> 16); + break; + case TZA_STEP_N4: + temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_04_init >> 16) / (xcvr_common_config.dcoc_tza_step_03_init >> 16); + break; + case TZA_STEP_N5: + temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_05_init >> 16) / (xcvr_common_config.dcoc_tza_step_04_init >> 16); + break; + case TZA_STEP_N6: + temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_06_init >> 16) / (xcvr_common_config.dcoc_tza_step_05_init >> 16); + break; + case TZA_STEP_N7: + temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_07_init >> 16) / (xcvr_common_config.dcoc_tza_step_06_init >> 16); + break; + case TZA_STEP_N8: + temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_08_init >> 16) / (xcvr_common_config.dcoc_tza_step_07_init >> 16); + break; + case TZA_STEP_N9: + temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_09_init >> 16) / (xcvr_common_config.dcoc_tza_step_08_init >> 16); + break; + case TZA_STEP_N10: + temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_10_init >> 16) / (xcvr_common_config.dcoc_tza_step_09_init >> 16); + break; + default: + break; + } + + tza_dcoc_step[i-TZA_STEP_N0].dcoc_step = (uint32_t)roundf(temp_step * 8); + tza_dcoc_step[i-TZA_STEP_N0].dcoc_step_rcp = (uint32_t)roundf((float)0x8000 / temp_step); + } + + /* Make the trims active */ + XCVR_RX_DIG->DCOC_BBA_STEP = XCVR_RX_DIG_DCOC_BBA_STEP_BBA_DCOC_STEP(bbf_dcoc_step) | XCVR_RX_DIG_DCOC_BBA_STEP_BBA_DCOC_STEP_RECIP(bbf_dcoc_step_rcp); + XCVR_RX_DIG->DCOC_TZA_STEP_0 = XCVR_RX_DIG_DCOC_TZA_STEP_0_DCOC_TZA_STEP_GAIN_0(tza_dcoc_step[0].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_0_DCOC_TZA_STEP_RCP_0(tza_dcoc_step[0].dcoc_step_rcp); + XCVR_RX_DIG->DCOC_TZA_STEP_1 = XCVR_RX_DIG_DCOC_TZA_STEP_1_DCOC_TZA_STEP_GAIN_1(tza_dcoc_step[1].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_1_DCOC_TZA_STEP_RCP_1(tza_dcoc_step[1].dcoc_step_rcp); + XCVR_RX_DIG->DCOC_TZA_STEP_2 = XCVR_RX_DIG_DCOC_TZA_STEP_2_DCOC_TZA_STEP_GAIN_2(tza_dcoc_step[2].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_2_DCOC_TZA_STEP_RCP_2(tza_dcoc_step[2].dcoc_step_rcp); + XCVR_RX_DIG->DCOC_TZA_STEP_3 = XCVR_RX_DIG_DCOC_TZA_STEP_3_DCOC_TZA_STEP_GAIN_3(tza_dcoc_step[3].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_3_DCOC_TZA_STEP_RCP_3(tza_dcoc_step[3].dcoc_step_rcp); + XCVR_RX_DIG->DCOC_TZA_STEP_4 = XCVR_RX_DIG_DCOC_TZA_STEP_4_DCOC_TZA_STEP_GAIN_4(tza_dcoc_step[4].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_4_DCOC_TZA_STEP_RCP_4(tza_dcoc_step[4].dcoc_step_rcp); + XCVR_RX_DIG->DCOC_TZA_STEP_5 = XCVR_RX_DIG_DCOC_TZA_STEP_5_DCOC_TZA_STEP_GAIN_5(tza_dcoc_step[5].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_5_DCOC_TZA_STEP_RCP_5(tza_dcoc_step[5].dcoc_step_rcp); + XCVR_RX_DIG->DCOC_TZA_STEP_6 = XCVR_RX_DIG_DCOC_TZA_STEP_6_DCOC_TZA_STEP_GAIN_6(tza_dcoc_step[6].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_6_DCOC_TZA_STEP_RCP_6(tza_dcoc_step[6].dcoc_step_rcp); + XCVR_RX_DIG->DCOC_TZA_STEP_7 = XCVR_RX_DIG_DCOC_TZA_STEP_7_DCOC_TZA_STEP_GAIN_7(tza_dcoc_step[7].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_7_DCOC_TZA_STEP_RCP_7(tza_dcoc_step[7].dcoc_step_rcp); + XCVR_RX_DIG->DCOC_TZA_STEP_8 = XCVR_RX_DIG_DCOC_TZA_STEP_8_DCOC_TZA_STEP_GAIN_8(tza_dcoc_step[8].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_8_DCOC_TZA_STEP_RCP_8(tza_dcoc_step[8].dcoc_step_rcp); + XCVR_RX_DIG->DCOC_TZA_STEP_9 = XCVR_RX_DIG_DCOC_TZA_STEP_9_DCOC_TZA_STEP_GAIN_9(tza_dcoc_step[9].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_9_DCOC_TZA_STEP_RCP_9(tza_dcoc_step[9].dcoc_step_rcp); + XCVR_RX_DIG->DCOC_TZA_STEP_10 = XCVR_RX_DIG_DCOC_TZA_STEP_10_DCOC_TZA_STEP_GAIN_10(tza_dcoc_step[10].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_10_DCOC_TZA_STEP_RCP_10(tza_dcoc_step[10].dcoc_step_rcp); + + status = 1; /* Success */ + } + else + { + status = 0; /* Failure */ + } + + /* Restore Registers */ + XCVR_RX_DIG->DCOC_CTRL_0 = dcoc_ctrl_0_stack; /* Restore DCOC_CTRL_0 state to prior settings */ + XCVR_RX_DIG->DCOC_CTRL_1 = dcoc_ctrl_1_stack; /* Restore DCOC_CTRL_1 state to prior settings */ + XCVR_RX_DIG->RX_DIG_CTRL = rx_dig_ctrl_stack; /* Restore RX_DIG_CTRL state to prior settings */ + XCVR_RX_DIG->DCOC_CAL_GAIN = dcoc_cal_gain_state; /* Restore DCOC_CAL_GAIN state to prior setting */ + XCVR_RX_DIG->AGC_CTRL_1 = agc_ctrl_1_stack; /* Save state of RX_DIG_CTRL for later restore */ + + return status; +} + +/*! ********************************************************************************* + * DCOC_DAC_INIT_Cal : slope sign seek depending on measure's sign + ***********************************************************************************/ +void DCOC_DAC_INIT_Cal(uint8_t standalone_operation) +{ + int16_t dc_meas_i = 2000, dc_meas_i_p = 2000; + int16_t dc_meas_q = 2000, dc_meas_q_p = 2000; + uint8_t curr_tza_dac_i, curr_tza_dac_q; + uint8_t curr_bba_dac_i, curr_bba_dac_q; + uint8_t p_tza_dac_i = 0, p_tza_dac_q = 0; + uint8_t p_bba_dac_i = 0, p_bba_dac_q = 0; + uint8_t i = 0; + uint8_t bba_gain = 11; + bool TZA_I_OK = 0, TZA_Q_OK = 0, BBA_I_OK = 0, BBA_Q_OK = 0; + + uint32_t dcoc_ctrl_0_stack; + uint32_t dcoc_ctrl_1_stack; + uint32_t agc_ctrl_1_stack; + uint32_t rx_dig_ctrl_stack; + uint32_t dcoc_cal_gain_state; + uint32_t xcvr_ctrl_stack = 0; + + uint32_t temp; + + /* Save registers */ + dcoc_ctrl_0_stack = XCVR_RX_DIG->DCOC_CTRL_0; /* Save state of DCOC_CTRL_0 for later restore */ + dcoc_ctrl_1_stack = XCVR_RX_DIG->DCOC_CTRL_1; /* Save state of DCOC_CTRL_1 for later restore */ + rx_dig_ctrl_stack = XCVR_RX_DIG->RX_DIG_CTRL; /* Save state of RX_DIG_CTRL for later restore */ + agc_ctrl_1_stack = XCVR_RX_DIG->AGC_CTRL_1; /* Save state of RX_DIG_CTRL for later restore */ + dcoc_cal_gain_state = XCVR_RX_DIG->DCOC_CAL_GAIN; /* Save state of DCOC_CAL_GAIN for later restore */ + + /* WarmUp */ + if (standalone_operation) + { + temp = XCVR_MISC->XCVR_CTRL; + xcvr_ctrl_stack = temp; + temp &= ~(XCVR_CTRL_XCVR_CTRL_PROTOCOL_MASK); + temp |= XCVR_CTRL_XCVR_CTRL_PROTOCOL(0); + XCVR_MISC->XCVR_CTRL = temp; + XCVR_OverrideChannel(12, 1); /* Calibrate on channel #12, 2.426 GHz in BLE map */ + XCVR_ForceRxWu(); + XcvrCalDelay(2000); + } + + /* Register config */ + /* Ensure AGC, DCOC and RX_DIG_CTRL is in correct mode */ + temp = XCVR_RX_DIG->RX_DIG_CTRL; + temp &= ~XCVR_RX_DIG_RX_DIG_CTRL_RX_AGC_EN_MASK; /* Turn OFF AGC */ + temp &= ~XCVR_RX_DIG_RX_DIG_CTRL_RX_DCOC_CAL_EN_MASK; /* Disable for SW control of DCOC */ + temp &= ~XCVR_RX_DIG_RX_DIG_CTRL_RX_DC_RESID_EN_MASK; /* Disable for SW control of DCOC */ + XCVR_RX_DIG->RX_DIG_CTRL = temp; + + XCVR_RX_DIG->AGC_CTRL_1 = XCVR_RX_DIG_AGC_CTRL_1_USER_LNA_GAIN_EN(1) | /* Enable LNA Manual Gain */ + XCVR_RX_DIG_AGC_CTRL_1_USER_BBA_GAIN_EN(1) | /* Enable BBA Manual Gain */ + XCVR_RX_DIG_AGC_CTRL_1_LNA_USER_GAIN(0x0) | /* Set LNA Manual Gain */ + XCVR_RX_DIG_AGC_CTRL_1_BBA_USER_GAIN(0x0); /* Set BBA Manual Gain */ + + /* DCOC_CTRL_0 @ 4005_C02C -- Define default DCOC DAC settings in manual mode */ + temp = XCVR_RX_DIG->DCOC_CTRL_0; + temp |= XCVR_RX_DIG_DCOC_CTRL_0_DCOC_MAN(1); /* Enable Manual DCOC */ + temp |= XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CORRECT_SRC(1); /* Ensure DCOC Tracking is enabled */ + temp |= XCVR_RX_DIG_DCOC_CTRL_0_DCOC_TRK_EST_OVR(1); /* Enable DC Estimator */ + temp |= XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CORRECT_EN(1); /* Ensure DC correction is enabled */ + XCVR_RX_DIG->DCOC_CTRL_0 = temp; + + XcvrCalDelay(TsettleCal); + + /* Set default DCOC DAC INIT Value */ + /* LNA and BBA DAC Sweep */ + curr_bba_dac_i = 0x20; + curr_bba_dac_q = 0x20; + curr_tza_dac_i = 0x80; + curr_tza_dac_q = 0x80; + + /* Perform a first DC measurement to ensure that measurement is not clipping */ + XCVR_RX_DIG->DCOC_DAC_INIT = XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_I(curr_bba_dac_i) | + XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_Q(curr_bba_dac_q) | + XCVR_RX_DIG_DCOC_DAC_INIT_TZA_DCOC_INIT_I(curr_tza_dac_i) | + XCVR_RX_DIG_DCOC_DAC_INIT_TZA_DCOC_INIT_Q(curr_tza_dac_q); + + do + { + bba_gain--; + /* Set DAC user gain */ + XCVR_RX_DIG->AGC_CTRL_1 = XCVR_RX_DIG_AGC_CTRL_1_USER_LNA_GAIN_EN(1) | + XCVR_RX_DIG_AGC_CTRL_1_LNA_USER_GAIN(0) | /* 2 */ + XCVR_RX_DIG_AGC_CTRL_1_USER_BBA_GAIN_EN(1) | + XCVR_RX_DIG_AGC_CTRL_1_BBA_USER_GAIN(bba_gain) ; /* 10 */ + XcvrCalDelay(TsettleCal * 2); + rx_dc_est_average(&dc_meas_i, &dc_meas_q, 64); + } while ((ABS(dc_meas_i) > 1900) | (ABS(dc_meas_q) > 1900)); + + for (i = 0; i < 0x0F; i++) + { + /* I channel : */ + if (!TZA_I_OK) + { + if ((ISIGN(dc_meas_i) != ISIGN(dc_meas_i_p)) && (i > 0)) + { + if (ABS(dc_meas_i) != MIN(ABS(dc_meas_i), ABS(dc_meas_i_p))) + { + curr_tza_dac_i = p_tza_dac_i; + } + + TZA_I_OK = 1; + } + else + { + p_tza_dac_i = curr_tza_dac_i; + + if (ISIGN(dc_meas_i)) /* If positif */ + { + curr_tza_dac_i--; + } + else + { + curr_tza_dac_i++; + } + } + } + else /* Sweep BBA I */ + { + if (!BBA_I_OK) + { + if ((ISIGN(dc_meas_i) != ISIGN(dc_meas_i_p)) && (curr_bba_dac_i != 0x20)) + { + if (ABS(dc_meas_i) != MIN(ABS(dc_meas_i), ABS(dc_meas_i_p))) + { + curr_bba_dac_i = p_bba_dac_i; + } + + BBA_I_OK = 1; + } + else + { + p_bba_dac_i = curr_bba_dac_i; + if (ISIGN(dc_meas_i)) /* If positif */ + { + curr_bba_dac_i--; + } + else + { + curr_bba_dac_i++; + } + } + } + } + + /* Q channel : */ + if (!TZA_Q_OK) + { + if ((ISIGN(dc_meas_q) != ISIGN(dc_meas_q_p)) && (i > 0)) + { + if (ABS(dc_meas_q) != MIN(ABS(dc_meas_q), ABS(dc_meas_q_p))) + { + curr_tza_dac_q = p_tza_dac_q; + } + TZA_Q_OK = 1; + } + else + { + p_tza_dac_q = curr_tza_dac_q; + if (ISIGN(dc_meas_q)) /* If positif */ + { + curr_tza_dac_q--; + } + else + { + curr_tza_dac_q++; + } + } + } + else /* Sweep BBA Q */ + { + if (!BBA_Q_OK) + { + if ((ISIGN(dc_meas_q) != ISIGN(dc_meas_q_p)) && (curr_bba_dac_q != 0x20)) + { + if (ABS(dc_meas_q) != MIN(ABS(dc_meas_q), ABS(dc_meas_q_p))) + { + curr_bba_dac_q = p_bba_dac_q; + } + BBA_Q_OK = 1; + } + else + { + p_bba_dac_q = curr_bba_dac_q; + if (ISIGN(dc_meas_q)) /* If positif */ + { + curr_bba_dac_q--; + } + else + { + curr_bba_dac_q++; + } + } + } + } + + /* DC OK break : */ + if (TZA_I_OK && TZA_Q_OK && BBA_I_OK && BBA_Q_OK) + { + break; + } + + dc_meas_i_p = dc_meas_i; /* Store as previous value */ + dc_meas_q_p = dc_meas_q; /* Store as previous value */ + XCVR_RX_DIG->DCOC_DAC_INIT = XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_I(curr_bba_dac_i) | + XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_Q(curr_bba_dac_q) | + XCVR_RX_DIG_DCOC_DAC_INIT_TZA_DCOC_INIT_I(curr_tza_dac_i) | + XCVR_RX_DIG_DCOC_DAC_INIT_TZA_DCOC_INIT_Q(curr_tza_dac_q); + XcvrCalDelay(TsettleCal * 2); + rx_dc_est_average(&dc_meas_i, &dc_meas_q, 64); + } + + /* Apply optimized DCOC DAC INIT : */ + XCVR_RX_DIG->DCOC_DAC_INIT = XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_I(curr_bba_dac_i) | + XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_Q(curr_bba_dac_q) | + XCVR_RX_DIG_DCOC_DAC_INIT_TZA_DCOC_INIT_I(curr_tza_dac_i) | + XCVR_RX_DIG_DCOC_DAC_INIT_TZA_DCOC_INIT_Q(curr_tza_dac_q); + + /* WarmDown */ + if (standalone_operation) + { + XCVR_ForceRxWd(); /* Don't leave the receiver running. */ + XcvrCalDelay(200); + XCVR_OverrideChannel(0xFF,1); /* Release channel overrides */ + XCVR_MISC->XCVR_CTRL = xcvr_ctrl_stack; + } + + /* Restore register */ + XCVR_RX_DIG->DCOC_CTRL_0 = dcoc_ctrl_0_stack; /* Restore DCOC_CTRL_0 state to prior settings */ + XCVR_RX_DIG->DCOC_CTRL_1 = dcoc_ctrl_1_stack; /* Restore DCOC_CTRL_1 state to prior settings */ + XCVR_RX_DIG->RX_DIG_CTRL = rx_dig_ctrl_stack; /* Restore RX_DIG_CTRL state to prior settings */ + XCVR_RX_DIG->DCOC_CAL_GAIN = dcoc_cal_gain_state; /* Restore DCOC_CAL_GAIN state to prior setting */ + XCVR_RX_DIG->AGC_CTRL_1 = agc_ctrl_1_stack; /* Save state of RX_DIG_CTRL for later restore */ +} + diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/fsl_xcvr_trim.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/fsl_xcvr_trim.h new file mode 100644 index 0000000000..2946ca3606 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/fsl_xcvr_trim.h @@ -0,0 +1,136 @@ +/* +* 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 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_XCVR_TRIM_H_ +/* Clang-format off. */ +#define _FSL_XCVR_TRIM_H_ +/* Clang-format on. */ + +#include "fsl_device_registers.h" +/*! +* @addtogroup xcvr +* @{ +*/ + +/*! @file*/ + +/************************************************************************************ +************************************************************************************* +* Public constant definitions +************************************************************************************* +************************************************************************************/ + +/************************************************************************************ +************************************************************************************* +* Public type definitions +************************************************************************************* +************************************************************************************/ + +/* \brief The enumerations used to define the I & Q channel selections. */ +typedef enum +{ + I_CHANNEL = 0, + Q_CHANNEL = 1, + NUM_I_Q_CHAN = 2 +} IQ_t; + +typedef enum /* Enumeration of ADC_GAIN_CAL 2 */ +{ + NOMINAL2 = 0, + BBF_NEG = 1, + BBF_POS = 2, + TZA_STEP_N0 = 3, + TZA_STEP_N1 = 4, + TZA_STEP_N2 = 5, + TZA_STEP_N3 = 6, + TZA_STEP_N4 = 7, + TZA_STEP_N5 = 8, + TZA_STEP_N6 = 9, + TZA_STEP_N7 = 10, + TZA_STEP_N8 = 11, + TZA_STEP_N9 = 12, + TZA_STEP_N10 = 13, + TZA_STEP_P0 = 14, + TZA_STEP_P1 = 15, + TZA_STEP_P2 = 16, + TZA_STEP_P3 = 17, + TZA_STEP_P4 = 18, + TZA_STEP_P5 = 19, + TZA_STEP_P6 = 20, + TZA_STEP_P7 = 21, + TZA_STEP_P8 = 22, + TZA_STEP_P9 = 23, + TZA_STEP_P10 = 24, + + NUM_SWEEP_STEP_ENTRIES2 = 25 /* Including the baseline entry #0. */ +} DAC_SWEEP_STEP2_t; + +/* \brief Defines an entry in an array of structs to describe TZA DCOC STEP and TZA_DCOC_STEP_RECIPROCAL. */ +typedef struct +{ + uint16_t dcoc_step; + uint16_t dcoc_step_rcp; +// uint16_t dcoc_step_q; +// uint16_t dcoc_step_rcp_q; +} TZAdcocstep_t; + +typedef struct +{ + int8_t step_value; /* The offset from nominal DAC value (see sweep_step_values[]) */ + int16_t internal_measurement; /* The value (average code) measured from DMA samples. */ +// uint8_t valid; /* Set to TRUE (non zero) when a value is written to this table entry. */ +} GAIN_CALC_TBL_ENTRY2_T; + +/******************************************************************************* +* Definitions +******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +void rx_dc_sample_average(int16_t * i_avg, int16_t * q_avg); +void rx_dc_sample_average_long(int16_t * i_avg, int16_t * q_avg); +uint8_t rx_bba_dcoc_dac_trim_shortIQ(void); +void XcvrCalDelay(uint32_t time); +void rx_dc_est_average(int16_t * i_avg, int16_t * q_avg, uint16_t SampleNumber); +uint8_t rx_bba_dcoc_dac_trim_DCest(void); +void DCOC_DAC_INIT_Cal(uint8_t standalone_operation); + + + + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_XCVR_TRIM_H_ */ + diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/ifr_radio.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/ifr_radio.c new file mode 100644 index 0000000000..a8680a7ee1 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/ifr_radio.c @@ -0,0 +1,530 @@ +/* + * 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 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_device_registers.h" +#include "fsl_xcvr.h" +#include "ifr_radio.h" +#include "fsl_os_abstraction.h" +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define IFR_RAM (0) + +#if RADIO_IS_GEN_3P0 +#define RDINDX (0x41U) +#define K3_BASE_INDEX (0x11U) /* Based for read index */ +#else +#define RDRSRC (0x03U) +#define KW4x_512_BASE (0x20000U) +#define KW4x_256_BASE (0x10000U) +#endif /* RADIO_IS_GEN_3P0 */ + +#if RADIO_IS_GEN_2P1 +#define FTFA (FTFE) +#endif /* RADIO_IS_GEN_2P1 */ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +uint32_t read_another_ifr_word(void); +uint32_t read_first_ifr_word(uint32_t read_addr); + +#if RADIO_IS_GEN_3P0 +uint64_t read_index_ifr(uint32_t read_addr); +#else +/*! ********************************************************************************* + * @brief Reads a location in block 1 IFR for use by the radio. + * + * This function handles reading IFR data from flash memory for trim loading. + * + * @param read_addr the address in the IFR to be read. + * + * @details This function wraps both the Gen2 read_resource command and the Gen2.1 and Gen3 read_index +***********************************************************************************/ +#if RADIO_IS_GEN_2P1 +uint64_t read_resource_ifr(uint32_t read_addr); +#else +uint32_t read_resource_ifr(uint32_t read_addr); +#endif /* RADIO_IS_GEN_2P1 */ +#endif /* RADIO_IS_GEN_3P0 */ + +void store_sw_trim(IFR_SW_TRIM_TBL_ENTRY_T * sw_trim_tbl, uint16_t num_entries, uint32_t addr, uint32_t data); + +/******************************************************************************* + * Variables + ******************************************************************************/ +static uint32_t ifr_read_addr; + +#if RADIO_IS_GEN_3P0 +static uint64_t packed_data_long; /* Storage for 2 32 bit values to be read by read_index */ +static uint8_t num_words_avail; /* Number of 32 bit words available in packed_data_long storage */ +const uint32_t BLOCK_1_IFR[]= +{ + /* Revised fallback table which should work with untrimmed parts */ + 0xABCDFFFEU, /* Version #FFFE indicates default trim values */ + + /* Trim table is empty for Gen3 by default */ + + /* No TRIM_STATUS in SW fallback array. */ + 0xFEED0E0FU /* End of File */ +}; +#else +#if RADIO_IS_GEN_2P0 +const uint32_t BLOCK_1_IFR[]= +{ + /* Revised fallback table which should work with untrimmed parts */ + 0xABCDFFFEU, /* Version #FFFE indicates default trim values */ + + 0x4005912CU, /* RSIM_ANA_TRIM address */ + 0x784B0000U, /* RSIM_ANA_TRIM default value */ + + /* No TRIM_STATUS in SW fallback array. */ + 0xFEED0E0FU /* End of File */ +}; +#else +static uint64_t packed_data_long; /* Storage for 2 32 bit values to be read by read_index */ +static uint8_t num_words_avail; /* Number of 32 bit words available in packed_data_long storage */ +const uint32_t BLOCK_1_IFR[]= +{ + /* Revised fallback table which should work with untrimmed parts */ + 0xABCDFFFEU, /* Version #FFFE indicates default trim values */ + + 0x4005912CU, /* RSIM_ANA_TRIM address */ + 0x784B0000U, /* RSIM_ANA_TRIM default value */ + + /* No TRIM_STATUS in SW fallback array. */ + 0xFEED0E0FU /* End of File */ +}; +#endif /* RADIO_IS_GEN_2P0 */ +#endif /* RADIO_IS_GEN_3P0 */ + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*! ********************************************************************************* + * \brief Read command for reading the first 32bit word from IFR, encapsulates different + * flash IFR read mechanisms for multiple generations of SOC + * + * \param read_addr flash address + * + * \return 8 bytes of packed data containing radio trims only + * +***********************************************************************************/ +uint32_t read_first_ifr_word(uint32_t read_addr) +{ + ifr_read_addr = read_addr; + return read_another_ifr_word(); +} + +/*! ********************************************************************************* + * \brief Read command for reading additional 32bit words from IFR. Encapsulates multiple IFR read mechanisms. + * + * \param read_addr flash address + * + * \return 8 bytes of packed data containing radio trims only + * + * \remarks PRE-CONDITIONS: + * The function read_first_ifr_word() must have been called so that the ifr_read_addr variable is setup prior to use. + * +***********************************************************************************/ +uint32_t read_another_ifr_word(void) +{ + uint32_t packed_data; + +#if (RADIO_IS_GEN_3P0 || RADIO_IS_GEN_2P1) + /* Using some static storage and alternating reads to read_index_ifr to replace read_resource_ifr */ + if (num_words_avail == 0) + { +#if RADIO_IS_GEN_3P0 + packed_data_long = read_index_ifr(ifr_read_addr); +#else /* Use 64 bit return version of read_resource */ + packed_data_long = read_resource_ifr(ifr_read_addr); +#endif /* RADIO_IS_GEN_3P0 */ + + num_words_avail = 2; + ifr_read_addr++; /* Read index addresses increment by 1 */ + } + + packed_data = (uint32_t)(packed_data_long & 0xFFFFFFFF); + packed_data_long = packed_data_long >> 32; + num_words_avail--; +#else + packed_data = read_resource_ifr(ifr_read_addr); + ifr_read_addr += 4; /* Read resource addresses increment by 4 */ +#endif /* (RADIO_IS_GEN_3P0 || RADIO_IS_GEN_2P1) */ + + return packed_data; +} + +#if RADIO_IS_GEN_3P0 +/*! ********************************************************************************* + * \brief Read command for reading from IFR using RDINDEX command + * + * \param read_addr flash address + * + * \return 8 bytes of packed data containing radio trims only + * +***********************************************************************************/ +uint64_t read_index_ifr(uint32_t read_addr) +{ + uint8_t rdindex = read_addr; + uint64_t read_data; + uint8_t i; + + while ((FTFE_FSTAT_CCIF_MASK & FTFE->FSTAT) == 0); /* Wait till CCIF=1 to make sure not interrupting a prior operation */ + + if ((FTFE->FSTAT & FTFE_FSTAT_ACCERR_MASK) == FTFE_FSTAT_ACCERR_MASK ) + { + FTFE->FSTAT = (1 << FTFE_FSTAT_ACCERR_SHIFT); /* Write 1 to ACCEER to clear errors */ + } + + FTFE->FCCOB[0] = RDINDX; + FTFE->FCCOB[1] = rdindex; + + OSA_InterrupDisable(); + FTFE->FSTAT = FTFE_FSTAT_CCIF_MASK; + while((FTFE_FSTAT_CCIF_MASK & FTFE->FSTAT) == 0); /* Wait till CCIF=1 */ + OSA_InterruptEnable(); + + /* Pack read data back into 64 bit type */ + read_data = FTFE->FCCOB[11]; /* MSB goes in first, will be shifted left sequentially */ + for (i = 10; i > 3; i--) + { + read_data = read_data << 8; + read_data |= FTFE->FCCOB[i]; + } + + return read_data; +} +#else + +/*! ********************************************************************************* + * \brief Read command for reading from IFR + * + * \param read_addr flash address + * + * \return packed data containing radio trims only + * +***********************************************************************************/ +#if RADIO_IS_GEN_2P0 +uint32_t read_resource_ifr(uint32_t read_addr) +{ + + uint32_t packed_data; + uint8_t flash_addr23_16, flash_addr15_8, flash_addr7_0; + uint32_t read_data31_24, read_data23_16, read_data15_8, read_data7_0; + + flash_addr23_16 = (uint8_t)((read_addr & 0xFF0000) >> 16); + flash_addr15_8 = (uint8_t)((read_addr & 0x00FF00) >> 8); + flash_addr7_0 = (uint8_t)(read_addr & 0xFF); + + while ((FTFA_FSTAT_CCIF_MASK & FTFA->FSTAT) == 0); /* Wait till CCIF=1 */ + + if ((FTFA->FSTAT & FTFA_FSTAT_ACCERR_MASK) == FTFA_FSTAT_ACCERR_MASK ) + { + FTFA->FSTAT = (1<FCCOB0 = RDRSRC; + FTFA->FCCOB1 = flash_addr23_16; + FTFA->FCCOB2 = flash_addr15_8; + FTFA->FCCOB3 = flash_addr7_0; + FTFA->FCCOB8 = 0x00; + + OSA_InterruptDisable(); + FTFA->FSTAT = FTFA_FSTAT_CCIF_MASK; + while ((FTFA_FSTAT_CCIF_MASK & FTFA->FSTAT) == 0); /* Wait till CCIF=1 */ + OSA_InterruptEnable(); + + /* Start reading */ + read_data31_24 = FTFA->FCCOB4; /* FTFA->FCCOB[4] */ + read_data23_16 = FTFA->FCCOB5; /* FTFA->FCCOB[5] */ + read_data15_8 = FTFA->FCCOB6; /* FTFA->FCCOB[6] */ + read_data7_0 = FTFA->FCCOB7; /* FTFA->FCCOB[7] */ + + packed_data = (read_data31_24 << 24) | (read_data23_16 << 16) | (read_data15_8 << 8) | (read_data7_0 << 0); + + return packed_data; +} +#else +uint64_t read_resource_ifr(uint32_t read_addr) +{ + + uint64_t packed_data; + uint8_t flash_addr23_16, flash_addr15_8, flash_addr7_0; + uint8_t read_data[8]; + uint64_t temp_64; + uint8_t i; + + flash_addr23_16 = (uint8_t)((read_addr & 0xFF0000) >> 16); + flash_addr15_8 = (uint8_t)((read_addr & 0x00FF00) >> 8); + flash_addr7_0 = (uint8_t)(read_addr & 0xFF); + while((FTFE_FSTAT_CCIF_MASK & FTFE->FSTAT) == 0); /* Wait till CCIF=1 */ + + if ((FTFE->FSTAT & FTFE_FSTAT_ACCERR_MASK) == FTFE_FSTAT_ACCERR_MASK ) + { + FTFE->FSTAT = (1<FCCOB0 = RDRSRC; + FTFE->FCCOB1 = flash_addr23_16; + FTFE->FCCOB2 = flash_addr15_8; + FTFE->FCCOB3 = flash_addr7_0; + FTFE->FCCOB4 = 0x00; + + OSA_InterruptDisable(); + FTFE->FSTAT = FTFE_FSTAT_CCIF_MASK; + while ((FTFE_FSTAT_CCIF_MASK & FTFE->FSTAT) == 0); /* Wait till CCIF=1 */ + OSA_InterruptEnable(); + + /* Start reading */ + read_data[7] = FTFE->FCCOB4; + read_data[6] = FTFE->FCCOB5; + read_data[5] = FTFE->FCCOB6; + read_data[4] = FTFE->FCCOB7; + read_data[3] = FTFE->FCCOB8; + read_data[2] = FTFE->FCCOB9; + read_data[1] = FTFE->FCCOBA; + read_data[0] = FTFE->FCCOBB; + + packed_data = 0; + for (i = 0; i < 8; i++) + { + temp_64 = read_data[i]; + packed_data |= temp_64 << (i * 8); + } + + return packed_data; +} + +#endif /* RADIO_IS_GEN_2P0 */ +#endif /* RADIO_IS_GEN_3P0 */ + +/*! ********************************************************************************* + * \brief Store a SW trim value in the table passed in from calling function. + * + * \param sw_trim_tbl pointer to the software trim table to hold SW trim values + * \param num_entries the number of entries in the SW trim table + * \param addr the software trim ID + * \param data the value of the software trim + * +***********************************************************************************/ +void store_sw_trim(IFR_SW_TRIM_TBL_ENTRY_T * sw_trim_tbl, uint16_t num_entries, uint32_t addr, uint32_t data) +{ + uint16_t i; + + if (sw_trim_tbl != NULL) + { + for (i = 0; i < num_entries; i++) + { + if (addr == sw_trim_tbl[i].trim_id) + { + sw_trim_tbl[i].trim_value = data; + sw_trim_tbl[i].valid = 1; + break; /* Don't need to scan the array any further... */ + } + } + } +} + +/*! ********************************************************************************* + * \brief Process block 1 IFR data. + * + * \param sw_trim_tbl pointer to the software trim table to hold SW trim values + * \param num_entries the number of entries in the SW trim table + * + * \remarks + * Uses a IFR v2 formatted default array if the IFR is blank or corrupted. + * Stores SW trim values to an array passed into this function. + * +***********************************************************************************/ +void handle_ifr(IFR_SW_TRIM_TBL_ENTRY_T * sw_trim_tbl, uint16_t num_entries) +{ + uint32_t dest_addr; + uint32_t read_addr; + uint32_t dest_data; + uint32_t packed_data; + uint32_t *ifr_ptr; + +#if RADIO_IS_GEN_3P0 + num_words_avail = 0; /* Prep for handling 64 bit words from flash */ +#endif /* RADIO_IS_GEN_3P0 */ + +#if RADIO_IS_GEN_3P0 + read_addr = K3_BASE_INDEX; +#else +#ifdef CPU_MKW41Z256VHT4 + read_addr = KW4x_256_BASE; +#else + read_addr = KW4x_512_BASE; +#endif /* CPU_MKW41Z256VHT4 */ +#endif /* RADIO_IS_GEN_3P0 */ + + /* Read first entry in IFR table */ + packed_data = read_first_ifr_word(read_addr); + if ((packed_data&~IFR_VERSION_MASK) == IFR_VERSION_HDR) + { + /* Valid header was found, process real IFR data */ + XCVR_MISC->OVERWRITE_VER = (packed_data & IFR_VERSION_MASK); + store_sw_trim(sw_trim_tbl, num_entries, 0xABCD, (packed_data & IFR_VERSION_MASK)); /* Place IFR version # in SW trim array*/ + packed_data = read_another_ifr_word(); + + while (packed_data !=IFR_EOF_SYMBOL) + { + if (IS_A_SW_ID(packed_data)) /* SW Trim case (non_reg writes) */ + { + dest_addr = packed_data; + packed_data = read_another_ifr_word(); + dest_data = packed_data; + /* Place SW trim in array for driver SW to use */ + store_sw_trim(sw_trim_tbl, num_entries, dest_addr, dest_data); + } + else + { + if (IS_VALID_REG_ADDR(packed_data)) /* Valid register write address */ + { + dest_addr = packed_data; + packed_data = read_another_ifr_word(); + dest_data = packed_data; + *(uint32_t *)(dest_addr) = dest_data; + } + else + { /* Invalid address case */ + + } + } + + packed_data=read_another_ifr_word(); + } + } + else + { + /* Valid header is not present, use blind IFR trim table */ + ifr_ptr = (void *)BLOCK_1_IFR; + packed_data = *ifr_ptr; + XCVR_MISC->OVERWRITE_VER = (packed_data & IFR_VERSION_MASK); + store_sw_trim(sw_trim_tbl, num_entries, 0xABCD, (packed_data & IFR_VERSION_MASK)); /* Place IFR version # in SW trim array */ + ifr_ptr++; + packed_data= *ifr_ptr; + + while (packed_data != IFR_EOF_SYMBOL) + { + if (IS_A_SW_ID(packed_data)) + { + /* SW Trim case (non_reg writes) */ + dest_addr = packed_data; + ifr_ptr++; + packed_data = *(ifr_ptr); + dest_data = packed_data; + /* Place SW trim in array for driver SW to use */ + store_sw_trim(sw_trim_tbl, num_entries, dest_addr, dest_data); + } + else + { + dest_addr = packed_data; + ifr_ptr++; + packed_data = *ifr_ptr; + dest_data = packed_data; + + /* Valid register write address */ + if (IS_VALID_REG_ADDR(dest_addr)) + { + *(uint32_t *)(dest_addr) = dest_data; + } + else + { + /* Invalid address case */ + } + } + + ifr_ptr++; + packed_data= *ifr_ptr; + } + } +} + +#if RADIO_IS_GEN_3P0 + +#else +uint32_t handle_ifr_die_id(void) +{ + uint32_t id_x, id_y; + uint32_t id; + + id = read_resource_ifr(0x90); + id_x = id & 0x00FF0000; + id_y = id & 0x000000FF; + + return (id_x | id_y); +} + +uint32_t handle_ifr_die_kw_type(void) +{ + uint32_t zb, ble; + + zb = read_resource_ifr(0x80) & 0x8000; + ble= read_resource_ifr(0x88) & 0x100000; + + return (zb | ble); +} + +#endif /* RADIO_IS_GEN_3P0 */ + +/*! ********************************************************************************* + * \brief Dumps block 1 IFR data to an array. + * + * \param dump_tbl pointer to the table to hold the dumped IFR values + * \param num_entries the number of entries to dump + * + * \remarks + * Starts at the first address in IFR and dumps sequential entries. + * +***********************************************************************************/ +void dump_ifr(uint32_t * dump_tbl, uint8_t num_entries) +{ +#if RADIO_IS_GEN_3P0 + uint32_t ifr_address = 0x20000; +#else + uint32_t ifr_address = 0x20000; +#endif /* RADIO_IS_GEN_3P0 */ + uint32_t * dump_ptr = dump_tbl; + uint8_t i; + + *dump_ptr = read_first_ifr_word(ifr_address); + dump_ptr++; + + for (i = 0; i < num_entries - 1; i++) + { + *dump_ptr = read_another_ifr_word(); + dump_ptr++; + } +} + diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/ifr_radio.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/ifr_radio.h new file mode 100644 index 0000000000..e02277f5ad --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/middleware/wireless/TARGET_FRAMEWORK_5_3_3/XCVR/MKW41Z4/ifr_radio.h @@ -0,0 +1,199 @@ +/* + * 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 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 __IFR_RADIO_H__ +/* clang-format off */ +#define __IFR_RADIO_H__ +/* clang-format on */ + +#include +/* clang-format off */ +#define _FSL_XCVR_H_ +/* clang-format on */ + +/*! + * @addtogroup xcvr + * @{ + */ + +/*! @file*/ + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define IFR_EOF_SYMBOL (0xFEED0E0FU) /* < Denotes the "End of File" for IFR data */ +#define IFR_VERSION_HDR (0xABCD0000U) /* < Constant value for upper 16 bits of IFR data header */ +#define IFR_VERSION_MASK (0x0000FFFFU) /* < Mask for version number (lower 16 bits) of IFR data header */ +#define IFR_SW_ID_MIN (0x00000000U) /* < Lower limit of SW trim IDs */ +#define IFR_SW_ID_MAX (0x0000FFFFU) /* < Lower limit of SW trim IDs */ + +#define IS_A_SW_ID(x) ((IFR_SW_ID_MIN < (x)) && (IFR_SW_ID_MAX >= (x))) + +/* K3 valid registers support */ +#if (defined(CPU_K32W042S1M2CAx_M0P) || defined(CPU_K32W042S1M2VPJ_M0P)) +#define IS_VALID_REG_ADDR(x) (((x) & 0xFFFF0000U) == 0x41000000U) /* Valid addresses are 0x410xxxxx */ +#endif /* (defined(CPU_K32W042S1M2CAx_M0P) || defined(CPU_K32W042S1M2VPJ_M0P)) */ +/* KW41 and KW35/36 valid registers support */ +#if (defined(CPU_MKW41Z256VHT4) || defined(CPU_MKW41Z512VHT4) || \ + defined(CPU_MKW31Z256VHT4) || defined(CPU_MKW31Z512VHT4) || \ + defined(CPU_MKW21Z256VHT4) || defined(CPU_MKW21Z512VHT4) || \ + defined(CPU_MKW35A512VFP4) || defined(CPU_MKW36A512VFP4) ) + +#define IS_VALID_REG_ADDR(x) (((x) & 0xFFFF0000U) == 0x40050000U) /* Valid addresses are 0x4005xxxx */ +#endif + +#define MAKE_MASK(size) ((1 << (size)) - 1) +#define MAKE_MASKSHFT(size, bitpos) (MAKE_MASK(size) << (bitpos)) + +#define IFR_TZA_CAP_TUNE_MASK (0x0000000FU) +#define IFR_TZA_CAP_TUNE_SHIFT (0) +#define IFR_BBF_CAP_TUNE_MASK (0x000F0000U) +#define IFR_BBF_CAP_TUNE_SHIFT (16) +#define IFR_RES_TUNE2_MASK (0x00F00000U) +#define IFR_RES_TUNE2_SHIFT (20) + +/* \var typedef uint8_t IFR_ERROR_T */ +/* \brief The IFR error reporting type. */ +/* See #IFR_ERROR_T_enum for the enumeration definitions. */ +typedef uint8_t IFR_ERROR_T; + +/* \brief The enumerations used to describe IFR errors. */ +enum IFR_ERROR_T_enum +{ + IFR_SUCCESS = 0, + INVALID_POINTER = 1, /* < NULL pointer error */ + INVALID_DEST_SIZE_SHIFT = 2, /* < the bits won't fit as specified in the destination */ +}; + +/* \var typedef uint16_t SW_TRIM_ID_T */ +/* \brief The SW trim ID type. */ +/* See #SW_TRIM_ID_T_enum for the enumeration definitions. */ +typedef uint16_t SW_TRIM_ID_T; + +/* \brief The enumerations used to define SW trim IDs. */ +enum SW_TRIM_ID_T_enum +{ + Q_RELATIVE_GAIN_BY_PART = 0, /* < Q vs I relative gain trim ID */ + ADC_GAIN = 1, /* < ADC gain trim ID */ + ZB_FILT_TRIM = 2, /* < Baseband Bandwidth filter trim ID for BLE */ + BLE_FILT_TRIM = 3, /* < Baseband Bandwidth filter trim ID for BLE */ + TRIM_STATUS = 4, /* < Status result of the trim process (error indications) */ + TRIM_VERSION = 0xABCD, /* < Version number of the IFR trim algorithm/format. */ +}; + +/* \var typedef uint32_t IFR_TRIM_STATUS_T */ +/* \brief The definition of failure bits stored in IFR trim status word. */ +/* See #IFR_TRIM_STATUS_T_enum for the enumeration definitions. */ +typedef uint32_t IFR_TRIM_STATUS_T; + +/* \brief The enumerations used to describe trim algorithm failures in the status entry in IFR. */ +/* This enum represents multiple values which can be OR'd together in a single status word. */ +enum IFR_TRIM_STATUS_T_enum +{ + TRIM_ALGORITHM_SUCCESS = 0, + BGAP_VOLTAGE_TRIM_FAILED = 1, /* < algorithm failure in BGAP voltagetrim */ + IQMC_GAIN_ADJ_FAILED = 2, /* < algorithm failure in IQMC gain trim */ + IQMC_PHASE_ADJ_FAILED = 4, /* < algorithm failure in IQMC phase trim */ + IQMC_DC_GAIN_ADJ_FAILED = 8, /* < */ + ADC_GAIN_TRIM_FAILED = 10, /* <*/ + ZB_FILT_TRIM_FAILED = 20, /* < */ + BLE_FILT_TRIM_FAILED = 40, /* < */ +}; + +/* \var typedef struct IFR_SW_TRIM_TBL_ENTRY_T */ +/* \brief Structure defining an entry in a table used to contain values to be passed back from IFR */ +/* handling routine to XCVR driver software. */ +typedef struct +{ + SW_TRIM_ID_T trim_id; /* < The assigned ID */ + uint32_t trim_value; /* < The value fetched from IFR.*/ + uint8_t valid; /* < validity of the trim_value field after IFR processing is complete (TRUE/FALSE).*/ +} IFR_SW_TRIM_TBL_ENTRY_T; + +/******************************************************************************* + * API + ******************************************************************************/ +/*! + * @brief Reads a location in block 1 IFR for use by the radio. + * + * This function handles reading IFR data from flash memory for trim loading. + * + * @param read_addr the address in the IFR to be read. + */ +uint32_t read_resource_ifr(uint32_t read_addr); + +/*! + * @brief Reads a location in a simulated data array to support IFR handler testing. + * + * This function handles reading data from a const table for testing the trim loading functions. + * + * @param read_addr the address in the IFR to be read. + */ +uint32_t read_resource(uint16_t resource_id); + +/*! + * @brief Main IFR handler function called by XCVR driver software to process trim table. + * + * This function handles reading data from IFR and either loading to registers or storing to a SW trim values table. + * + * @param sw_trim_tbl pointer to the table used to store software trim values. + * @param num_entries the number of entries that can be stored in the SW trim table. + */ +void handle_ifr(IFR_SW_TRIM_TBL_ENTRY_T * sw_trim_tbl, uint16_t num_entries); + +/*! + * @brief Handler function to read die_id from IFR locations.. + * + * This function handles reading die ID value for debug and testing usage. + * + * @return the value of the die ID field. + */ +uint32_t handle_ifr_die_id(void); + +/*! + * @brief Handler function to read KW chip version from IFR locations.. + * + * This function handles reading KW chip version for debug and testing usage. + * + * @return the value of the KW version field. + */ +uint32_t handle_ifr_die_kw_type(void); + +/*! + * @brief Debug function to dump the IFR contents to a RAM array. + * + * This function handles reading data from IFR and storing to a RAM array for debug. + * + * @param dump_tbl pointer to the table used to store IFR entry values. + * @param num_entries the number of entries that can be stored in the dump table. + */ +void dump_ifr(uint32_t * dump_tbl, uint8_t num_entries); + +#endif /*__IFR_RADIO_H__ */ + diff --git a/targets/TARGET_Maxim/TARGET_MAX32620C/device/TOOLCHAIN_IAR/MAX32620.icf b/targets/TARGET_Maxim/TARGET_MAX32620C/device/TOOLCHAIN_IAR/MAX32620.icf index 7edf37819c..09cb28c111 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32620C/device/TOOLCHAIN_IAR/MAX32620.icf +++ b/targets/TARGET_Maxim/TARGET_MAX32620C/device/TOOLCHAIN_IAR/MAX32620.icf @@ -16,7 +16,8 @@ define region RAM_region = mem:[from __region_RAM_start__ to __region_RAM /* Stack and Heap */ define symbol __size_cstack__ = 0x1000; -define symbol __size_heap__ = 0x4000; +define symbol __size_heap__ = 0xF000; + define block CSTACK with alignment = 8, size = __size_cstack__ { }; define block HEAP with alignment = 8, size = __size_heap__ { }; diff --git a/targets/TARGET_Maxim/TARGET_MAX32620C/flash_api.c b/targets/TARGET_Maxim/TARGET_MAX32620C/flash_api.c new file mode 100644 index 0000000000..2e654159a5 --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32620C/flash_api.c @@ -0,0 +1,172 @@ +/******************************************************************************* + * Copyright (C) 2018 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. + ******************************************************************************* + */ + +#if DEVICE_FLASH +#include "flash_api.h" +#include "mbed_critical.h" +#include "cmsis.h" +#include "flc.h" + + +/** + * * \defgroup flash_hal Flash HAL API + * * @{ + * */ + +/** Initialize the flash peripheral and the flash_t object + * * + * * @param obj The flash object + * * @return 0 for success, -1 for error + * */ +int32_t flash_init(flash_t *obj) +{ + return FLC_Init(); +} + +/** Uninitialize the flash peripheral and the flash_t object + * * + * * @param obj The flash object + * * @return 0 for success, -1 for error + * */ +int32_t flash_free(flash_t *obj) +{ + return 0; +} + +/** Erase one sector starting at defined address + * * + * * The address should be at sector boundary. This function does not do any check for address alignments + * * @param obj The flash object + * * @param address The sector starting address + * * @return 0 for success, -1 for error + * */ +int32_t flash_erase_sector(flash_t *obj, uint32_t address) +{ + if(FLC_PageErase(address, MXC_V_FLC_ERASE_CODE_PAGE_ERASE, MXC_V_FLC_FLSH_UNLOCK_KEY) != 0) + { + return -1; + } else { + return 0; + } + +} + +/** Program pages starting at defined address + * * + * * The pages should not cross multiple sectors. + * * This function does not do any check for address alignments or if size is aligned to a page size. + * * @param obj The flash object + * * @param address The sector starting address + * * @param data The data buffer to be programmed + * * @param size The number of bytes to program + * * @return 0 for success, -1 for error + * */ +int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data, uint32_t size) +{ + int32_t status = E_BUSY; + + while ( status == E_BUSY ) + { + status = FLC_Write(address, data, size, MXC_V_FLC_FLSH_UNLOCK_KEY); + } + + if (status != 0) + { + return -1; + } else { + return 0; + } + +} + +/** Get sector size + * * + * * @param obj The flash object + * * @param address The sector starting address + * * @return The size of a sector + * */ +uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address) +{ + /* 1 sector = 1 page */ + if (address >= (MXC_FLASH_MEM_BASE + MXC_FLASH_FULL_MEM_SIZE)) { + return MBED_FLASH_INVALID_SIZE; + } else { + return MXC_FLASH_PAGE_SIZE; + } +} + +/** Get page size + * * + * * The page size defines the writable page size + * * @param obj The flash object + * * @return The size of a page + * */ +uint32_t flash_get_page_size(const flash_t *obj) +{ + return MXC_FLASH_PAGE_SIZE; +} + +/** Get start address for the flash region + * * + * * @param obj The flash object + * * @return The start address for the flash region + * */ +uint32_t flash_get_start_address(const flash_t *obj) +{ + return MXC_FLASH_MEM_BASE; +} + +/** Get the flash region size + * * + * * @param obj The flash object + * * @return The flash region size + * */ +uint32_t flash_get_size(const flash_t *obj) +{ + return MXC_FLASH_FULL_MEM_SIZE; +} + +/** Get the flash erase value + * * + * * @param obj The flash object + * * @return The flash erase value + * */ +uint8_t flash_get_erase_value(const flash_t *obj) +{ + (void)obj; + + return 0xFF; +} + +#endif + diff --git a/targets/TARGET_Maxim/TARGET_MAX32620C/objects.h b/targets/TARGET_Maxim/TARGET_MAX32620C/objects.h index cb2167934b..a07ec432ae 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32620C/objects.h +++ b/targets/TARGET_Maxim/TARGET_MAX32620C/objects.h @@ -61,6 +61,10 @@ struct port_s { PinMode mode; }; +struct flash_s { + uint8_t notused; +}; + struct gpio_irq_s { uint8_t port; uint8_t pin; diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_SDK_14_2/drivers_nrf/hal/nrf_qspi.h b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_SDK_14_2/drivers_nrf/hal/nrf_qspi.h index 72b2d7237a..4c0d6df45f 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_SDK_14_2/drivers_nrf/hal/nrf_qspi.h +++ b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_SDK_14_2/drivers_nrf/hal/nrf_qspi.h @@ -230,6 +230,8 @@ typedef struct bool io3_level; /**< I/O line level during transmission. */ bool wipwait; /**< Wait if a Wait in Progress bit is set in the memory status byte. */ bool wren; /**< Send write enable before instruction. */ + bool lfen; /**< Enable long frame mode. */ + bool lfstop; /**< Stop long frame mode. */ } nrf_qspi_cinstr_conf_t; /** @@ -751,7 +753,9 @@ __STATIC_INLINE void nrf_qspi_cinstr_transfer_start(NRF_QSPI_Type * ((uint32_t)p_config->io2_level << QSPI_CINSTRCONF_LIO2_Pos) | ((uint32_t)p_config->io3_level << QSPI_CINSTRCONF_LIO3_Pos) | ((uint32_t)p_config->wipwait << QSPI_CINSTRCONF_WIPWAIT_Pos) | - ((uint32_t)p_config->wren << QSPI_CINSTRCONF_WREN_Pos)); + ((uint32_t)p_config->wren << QSPI_CINSTRCONF_WREN_Pos) | + ((uint32_t)p_config->lfen << QSPI_CINSTRCONF_LFEN_Pos) | + ((uint32_t)p_config->lfstop << QSPI_CINSTRCONF_LFSTOP_Pos) ); } #endif // SUPPRESS_INLINE_IMPLEMENTATION diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_SDK_14_2/drivers_nrf/qspi/nrf_drv_qspi.h b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_SDK_14_2/drivers_nrf/qspi/nrf_drv_qspi.h index 35ce036bcd..1301cacf71 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_SDK_14_2/drivers_nrf/qspi/nrf_drv_qspi.h +++ b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_SDK_14_2/drivers_nrf/qspi/nrf_drv_qspi.h @@ -135,7 +135,9 @@ typedef struct .io2_level = false, \ .io3_level = false, \ .wipwait = false, \ - .wren = false \ + .wren = false, \ + .lfen = false, \ + .lfstop = false \ } /** diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c b/targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c index 73b2cd757c..32633c73ab 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c +++ b/targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c @@ -56,11 +56,12 @@ TODO #define MBED_HAL_QSPI_MAX_FREQ 32000000UL // NRF supported R/W opcodes -#define FAST_READ_opcode 0x0B +#define FASTREAD_opcode 0x0B #define READ2O_opcode 0x3B #define READ2IO_opcode 0xBB #define READ4O_opcode 0x6B #define READ4IO_opcode 0xEB +#define READSFDP_opcode 0x5A #define PP_opcode 0x02 #define PP2O_opcode 0xA2 @@ -70,12 +71,21 @@ TODO #define SCK_DELAY 0x05 #define WORD_MASK 0x03 +// NRF SFDP defines +#define DWORD_LEN 4 +#define SFDP_CMD_LEN DWORD_LEN +#define SFDP_DATA_LEN 128 // SFPD data buffer length in bytes, may need to be increased for other flash parts +#define SFDP_READ_LEN 8 // 8 SFDP bytes can be read at a time +#define SFDP_READ_MAX (SFDP_DATA_LEN / SFDP_READ_LEN) + static nrf_drv_qspi_config_t config; // Private helper function to track initialization static ret_code_t _qspi_drv_init(void); // Private helper function to set NRF frequency divider nrf_qspi_frequency_t nrf_frequency(int hz); +// Private helper function to read SFDP data +qspi_status_t sfdp_read(qspi_t *obj, const qspi_command_t *command, void *data, size_t *length); qspi_status_t qspi_prepare_command(qspi_t *obj, const qspi_command_t *command, bool write) { @@ -93,7 +103,7 @@ qspi_status_t qspi_prepare_command(qspi_t *obj, const qspi_command_t *command, b return QSPI_STATUS_INVALID_PARAMETER; } } else { - if (command->instruction.value == FAST_READ_opcode) { + if (command->instruction.value == FASTREAD_opcode) { config.prot_if.readoc = NRF_QSPI_READOC_FASTREAD; } else { return QSPI_STATUS_INVALID_PARAMETER; @@ -277,9 +287,15 @@ qspi_status_t qspi_read(qspi_t *obj, const qspi_command_t *command, void *data, return QSPI_STATUS_INVALID_PARAMETER; } - qspi_status_t status = qspi_prepare_command(obj, command, false); - if (status != QSPI_STATUS_OK) { + // check to see if this is an SFDP read + if (command->instruction.value == READSFDP_opcode) { + qspi_status_t status = sfdp_read(obj, command, data, length ); return status; + } else { + qspi_status_t status = qspi_prepare_command(obj, command, false); + if (status != QSPI_STATUS_OK) { + return status; + } } ret_code_t ret = nrf_drv_qspi_read(data, *length, command->address.value); @@ -293,16 +309,16 @@ qspi_status_t qspi_read(qspi_t *obj, const qspi_command_t *command, void *data, qspi_status_t qspi_command_transfer(qspi_t *obj, const qspi_command_t *command, const void *tx_data, size_t tx_size, void *rx_data, size_t rx_size) { ret_code_t ret_code; - uint8_t data[8]; + uint8_t data[8] = { 0 }; uint32_t data_size = tx_size + rx_size; - nrf_qspi_cinstr_conf_t qspi_cinstr_config; + nrf_qspi_cinstr_conf_t qspi_cinstr_config = { 0 }; qspi_cinstr_config.opcode = command->instruction.value; qspi_cinstr_config.io2_level = true; qspi_cinstr_config.io3_level = true; qspi_cinstr_config.wipwait = false; qspi_cinstr_config.wren = false; - + if(!command->address.disabled && data_size == 0) { // erase command with address if (command->address.size == QSPI_CFG_ADDR_SIZE_24) { @@ -400,6 +416,112 @@ nrf_qspi_frequency_t nrf_frequency(int hz) return freq; } +// Private helper to read nRF5x SFDP data using QSPI +qspi_status_t sfdp_read(qspi_t *obj, const qspi_command_t *command, void *data, size_t *length) +{ + ret_code_t ret_code; + static bool b_init = false; + static uint8_t sfdp_rx[SFDP_DATA_LEN] = { 0 }; + + if (b_init == false) { + // get the SFDP data usig nRF5x QSPI custom instuctions and long frame mode (lfen) + nrf_qspi_cinstr_conf_t qspi_cinstr_config = { 0 }; + qspi_cinstr_config.opcode = command->instruction.value; + qspi_cinstr_config.io2_level = true; + qspi_cinstr_config.io3_level = true; + qspi_cinstr_config.wipwait = false; + qspi_cinstr_config.wren = false; + qspi_cinstr_config.lfen = true; + qspi_cinstr_config.lfstop = false; + + // read the SFDP data, cmd + 8 bytes at a time + uint8_t sfdp_data[SFDP_READ_LEN]; + qspi_cinstr_config.length = NRF_QSPI_CINSTR_LEN_9B; + + for (uint32_t i = 0; i < SFDP_READ_MAX; ++i) { + + static uint32_t rx_i = 0; + memset(sfdp_data, 0, SFDP_READ_LEN); + + if (i == (SFDP_READ_MAX - 1) ){ + qspi_cinstr_config.lfstop = true; + } + + ret_code = nrf_drv_qspi_cinstr_xfer(&qspi_cinstr_config, sfdp_data, sfdp_data); + if (ret_code != NRF_SUCCESS) { + return QSPI_STATUS_ERROR; + } + + // copy the second DWORD from the command data, the first DWORD is 0's + for (uint32_t c = DWORD_LEN; c < SFDP_READ_LEN; ++c) { + ((uint8_t *)sfdp_rx)[rx_i] = sfdp_data[c]; + ++rx_i; + } + rx_i += DWORD_LEN; + } + + // re-send just the SFDP CMD to offset the next read by DWORD + uint8_t sfdp_cmd[SFDP_CMD_LEN] = { 0 }; + qspi_cinstr_config.lfstop = false; + qspi_cinstr_config.length = NRF_QSPI_CINSTR_LEN_5B; + + ret_code = nrf_drv_qspi_cinstr_xfer(&qspi_cinstr_config, sfdp_cmd, sfdp_cmd); + if (ret_code != NRF_SUCCESS) { + return QSPI_STATUS_ERROR; + } + + // read the offset SFDP data, cmd + 8 bytes at a time + qspi_cinstr_config.length = NRF_QSPI_CINSTR_LEN_9B; + for (uint32_t i = 0; i < SFDP_READ_MAX; ++i) { + + static uint32_t rx_i = DWORD_LEN; // offset sfdp_rx data start + memset(sfdp_data, 0, SFDP_READ_LEN); + + if (i == (SFDP_READ_MAX - 1) ){ + qspi_cinstr_config.lfstop = true; + } + + ret_code = nrf_drv_qspi_cinstr_xfer(&qspi_cinstr_config, sfdp_data, sfdp_data); + if (ret_code != NRF_SUCCESS) { + return QSPI_STATUS_ERROR; + } + + // copy the second DWORD from the command data, the first DWORD is 0's + for (uint32_t c = DWORD_LEN; c < SFDP_READ_LEN; ++c) { + ((uint8_t *)sfdp_rx)[rx_i] = sfdp_data[c]; + ++rx_i; + } + rx_i += DWORD_LEN; + } + + b_init = true; + } + + if ( b_init == true) { + // check for valid SFDP data, last basic header byte is always 0xFF + // NOTE: "nRF52840-Preview-DK" boards do not support SFDP read + if (sfdp_rx[7] != 0xFF) { + return QSPI_STATUS_ERROR; + } + + // calculate the SFDP data length based on the parameter table offset + // provided at index 12, plus the table length in DWORDS at index 11 + uint32_t sfdp_length = sfdp_rx[12] + (sfdp_rx[11] * DWORD_LEN); + + // check if the data request is within the SFDP data array + // increase SFDP_DATA_LEN to match sfdp_length, if necessary + if ( sfdp_length <= SFDP_DATA_LEN && + sfdp_length >= (command->address.value + *length) ) { + memcpy(data, (sfdp_rx + command->address.value), *length); + return QSPI_STATUS_OK; + } else { + return QSPI_STATUS_INVALID_PARAMETER; + } + } else { + return QSPI_STATUS_ERROR; + } +} + #endif diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC54114/device/TARGET_LPC54114_M4/TOOLCHAIN_ARM_STD/LICENSE b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC54114/device/TARGET_LPC54114_M4/TOOLCHAIN_ARM_STD/LICENSE new file mode 100644 index 0000000000..42c2c16b86 --- /dev/null +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC54114/device/TARGET_LPC54114_M4/TOOLCHAIN_ARM_STD/LICENSE @@ -0,0 +1,31 @@ +Copyright 2016-2018 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: + +* 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 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. \ No newline at end of file diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC54114/device/TARGET_LPC54114_M4/TOOLCHAIN_ARM_STD/libpower.README b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC54114/device/TARGET_LPC54114_M4/TOOLCHAIN_ARM_STD/libpower.README new file mode 100644 index 0000000000..cfd5119d59 --- /dev/null +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC54114/device/TARGET_LPC54114_M4/TOOLCHAIN_ARM_STD/libpower.README @@ -0,0 +1,9 @@ +LPC54114 libpower.ar README + +The libpower.ar library provides the following functions for optimized power management on LPC54114 devices. Features include: +1. Simple APIs to control power consumption and wake-up in all power modes. +2. Manage power consumption for sleep and active modes +3. Prepare the part to enter low power modes (sleep, deep-sleep, and deep power-down). +4. Configure wake-up from deep-sleep via functions enabled by bits in the PDRUNCFG registers. + +The APIs provided by the library are fully described in the LPC54114 User Manual (document UM10914) which is available from https://www.nxp.com \ No newline at end of file diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC54114/device/TARGET_LPC54114_M4/TOOLCHAIN_GCC_ARM/LICENSE b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC54114/device/TARGET_LPC54114_M4/TOOLCHAIN_GCC_ARM/LICENSE new file mode 100644 index 0000000000..42c2c16b86 --- /dev/null +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC54114/device/TARGET_LPC54114_M4/TOOLCHAIN_GCC_ARM/LICENSE @@ -0,0 +1,31 @@ +Copyright 2016-2018 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: + +* 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 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. \ No newline at end of file diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC54114/device/TARGET_LPC54114_M4/TOOLCHAIN_GCC_ARM/libpower.README b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC54114/device/TARGET_LPC54114_M4/TOOLCHAIN_GCC_ARM/libpower.README new file mode 100644 index 0000000000..01d8795a4e --- /dev/null +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC54114/device/TARGET_LPC54114_M4/TOOLCHAIN_GCC_ARM/libpower.README @@ -0,0 +1,9 @@ +LPC54114 libpower.a README + +The libpower.a library provides the following functions for optimized power management on LPC54114 devices. Features include: +1. Simple APIs to control power consumption and wake-up in all power modes. +2. Manage power consumption for sleep and active modes +3. Prepare the part to enter low power modes (sleep, deep-sleep, and deep power-down). +4. Configure wake-up from deep-sleep via functions enabled by bits in the PDRUNCFG registers. + +The APIs provided by the library are fully described in the LPC54114 User Manual (document UM10914) which is available from https://www.nxp.com \ No newline at end of file diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC54114/device/TARGET_LPC54114_M4/TOOLCHAIN_IAR/LICENSE b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC54114/device/TARGET_LPC54114_M4/TOOLCHAIN_IAR/LICENSE new file mode 100644 index 0000000000..42c2c16b86 --- /dev/null +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC54114/device/TARGET_LPC54114_M4/TOOLCHAIN_IAR/LICENSE @@ -0,0 +1,31 @@ +Copyright 2016-2018 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: + +* 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 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. \ No newline at end of file diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC54114/device/TARGET_LPC54114_M4/TOOLCHAIN_IAR/libpower.README b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC54114/device/TARGET_LPC54114_M4/TOOLCHAIN_IAR/libpower.README new file mode 100644 index 0000000000..01d8795a4e --- /dev/null +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC54114/device/TARGET_LPC54114_M4/TOOLCHAIN_IAR/libpower.README @@ -0,0 +1,9 @@ +LPC54114 libpower.a README + +The libpower.a library provides the following functions for optimized power management on LPC54114 devices. Features include: +1. Simple APIs to control power consumption and wake-up in all power modes. +2. Manage power consumption for sleep and active modes +3. Prepare the part to enter low power modes (sleep, deep-sleep, and deep power-down). +4. Configure wake-up from deep-sleep via functions enabled by bits in the PDRUNCFG registers. + +The APIs provided by the library are fully described in the LPC54114 User Manual (document UM10914) which is available from https://www.nxp.com \ No newline at end of file diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MCU_LPC546XX/device/TOOLCHAIN_ARM_STD/LICENSE b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MCU_LPC546XX/device/TOOLCHAIN_ARM_STD/LICENSE new file mode 100644 index 0000000000..42c2c16b86 --- /dev/null +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MCU_LPC546XX/device/TOOLCHAIN_ARM_STD/LICENSE @@ -0,0 +1,31 @@ +Copyright 2016-2018 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: + +* 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 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. \ No newline at end of file diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MCU_LPC546XX/device/TOOLCHAIN_ARM_STD/libpower.README b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MCU_LPC546XX/device/TOOLCHAIN_ARM_STD/libpower.README new file mode 100644 index 0000000000..09d51a0659 --- /dev/null +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MCU_LPC546XX/device/TOOLCHAIN_ARM_STD/libpower.README @@ -0,0 +1,9 @@ +LPC546xx lib_power.ar README + +The lib_power.ar library provides the following functions for optimized power management on LPC546xx devices. Features include: +1. Simple APIs to control power consumption and wake-up in all power modes. +2. Manage power consumption for sleep and active modes +3. Prepare the part to enter low power modes (sleep, deep-sleep, and deep power-down). +4. Configure wake-up from deep-sleep via functions enabled by bits in the PDRUNCFG registers. + +The APIs provided by the library are fully described in the LPC546xx User Manual (document UM10921) which is available from https://www.nxp.com \ No newline at end of file diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MCU_LPC546XX/device/TOOLCHAIN_GCC_ARM/LICENSE b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MCU_LPC546XX/device/TOOLCHAIN_GCC_ARM/LICENSE new file mode 100644 index 0000000000..42c2c16b86 --- /dev/null +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MCU_LPC546XX/device/TOOLCHAIN_GCC_ARM/LICENSE @@ -0,0 +1,31 @@ +Copyright 2016-2018 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: + +* 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 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. \ No newline at end of file diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MCU_LPC546XX/device/TOOLCHAIN_GCC_ARM/libpower.README b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MCU_LPC546XX/device/TOOLCHAIN_GCC_ARM/libpower.README new file mode 100644 index 0000000000..1817664af5 --- /dev/null +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MCU_LPC546XX/device/TOOLCHAIN_GCC_ARM/libpower.README @@ -0,0 +1,9 @@ +LPC546xx libpower.a README + +The libpower.a library provides the following functions for optimized power management on LPC546xx devices. Features include: +1. Simple APIs to control power consumption and wake-up in all power modes. +2. Manage power consumption for sleep and active modes +3. Prepare the part to enter low power modes (sleep, deep-sleep, and deep power-down). +4. Configure wake-up from deep-sleep via functions enabled by bits in the PDRUNCFG registers. + +The APIs provided by the library are fully described in the LPC546xx User Manual (document UM10921) which is available from https://www.nxp.com \ No newline at end of file diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MCU_LPC546XX/device/TOOLCHAIN_IAR/LICENSE b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MCU_LPC546XX/device/TOOLCHAIN_IAR/LICENSE new file mode 100644 index 0000000000..42c2c16b86 --- /dev/null +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MCU_LPC546XX/device/TOOLCHAIN_IAR/LICENSE @@ -0,0 +1,31 @@ +Copyright 2016-2018 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: + +* 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 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. \ No newline at end of file diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MCU_LPC546XX/device/TOOLCHAIN_IAR/libpower.README b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MCU_LPC546XX/device/TOOLCHAIN_IAR/libpower.README new file mode 100644 index 0000000000..75b81e6a45 --- /dev/null +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MCU_LPC546XX/device/TOOLCHAIN_IAR/libpower.README @@ -0,0 +1,9 @@ +LPC546xx lib_power.a README + +The lib_power.a library provides the following functions for optimized power management on LPC546xx devices. Features include: +1. Simple APIs to control power consumption and wake-up in all power modes. +2. Manage power consumption for sleep and active modes +3. Prepare the part to enter low power modes (sleep, deep-sleep, and deep power-down). +4. Configure wake-up from deep-sleep via functions enabled by bits in the PDRUNCFG registers. + +The APIs provided by the library are fully described in the LPC546xx User Manual (document UM10921) which is available from https://www.nxp.com \ No newline at end of file diff --git a/targets/TARGET_RDA/TARGET_UNO_91H/lib/LICENSE-permissive-binary-license-1.0.txt b/targets/TARGET_RDA/TARGET_UNO_91H/lib/LICENSE-permissive-binary-license-1.0.txt deleted file mode 100644 index 2d906989d5..0000000000 --- a/targets/TARGET_RDA/TARGET_UNO_91H/lib/LICENSE-permissive-binary-license-1.0.txt +++ /dev/null @@ -1,49 +0,0 @@ -Permissive Binary License - -Version 1.0, September 2018 - -Redistribution. Redistribution and use in binary form, without -modification, are permitted provided that the following conditions are -met: - -1) Redistributions must reproduce the above copyright notice and the - following disclaimer in the documentation and/or other materials - provided with the distribution. - -2) Unless to the extent explicitly permitted by law, no reverse - engineering, decompilation, or disassembly of this software is - permitted. - -3) Redistribution as part of a software development kit must include the - accompanying file named “DEPENDENCIES” and any dependencies listed in - that file. - -4) 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. - -Limited patent license. The copyright holders (and contributors) grant a -worldwide, non-exclusive, no-charge, royalty-free patent license to -make, have made, use, offer to sell, sell, import, and otherwise -transfer this software, where such license applies only to those patent -claims licensable by the copyright holders (and contributors) that are -necessarily infringed by this software. This patent license shall not -apply to any combinations that include this software. No hardware is -licensed hereunder. - -If you institute patent litigation against any entity (including a -cross-claim or counterclaim in a lawsuit) alleging that the software -itself infringes your patent(s), then your rights granted under this -license shall terminate as of the date such litigation is filed. - -DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND -CONTRIBUTORS "AS IS." 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 -HOLDERS 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. \ No newline at end of file diff --git a/targets/TARGET_RDA/TARGET_UNO_91H/lib/README.md b/targets/TARGET_RDA/TARGET_UNO_91H/lib/README.md deleted file mode 100644 index beec409803..0000000000 --- a/targets/TARGET_RDA/TARGET_UNO_91H/lib/README.md +++ /dev/null @@ -1,7 +0,0 @@ -This directory tree contains binaries build from RDA SDK modified for Mbed OS and released under Permissive Binary License. - -libhal files in the subfolders are generated with toolchains: - -Arm Compiler 5 - version 5.06u1 -GNU Arm Embedded - version 6.3.1 -IAR EWARM - version 7.80.2 \ No newline at end of file diff --git a/targets/TARGET_RDA/TARGET_UNO_91H/lib/TOOLCHAIN_ARM_STD/libhal.ar b/targets/TARGET_RDA/TARGET_UNO_91H/lib/TOOLCHAIN_ARM_STD/libhal.ar deleted file mode 100644 index ec1a7e25a9..0000000000 Binary files a/targets/TARGET_RDA/TARGET_UNO_91H/lib/TOOLCHAIN_ARM_STD/libhal.ar and /dev/null differ diff --git a/targets/TARGET_RDA/TARGET_UNO_91H/lib/TOOLCHAIN_GCC_ARM/libhal.a b/targets/TARGET_RDA/TARGET_UNO_91H/lib/TOOLCHAIN_GCC_ARM/libhal.a deleted file mode 100644 index 4a3a8b749a..0000000000 Binary files a/targets/TARGET_RDA/TARGET_UNO_91H/lib/TOOLCHAIN_GCC_ARM/libhal.a and /dev/null differ diff --git a/targets/TARGET_RDA/TARGET_UNO_91H/lib/TOOLCHAIN_IAR/libhal.a b/targets/TARGET_RDA/TARGET_UNO_91H/lib/TOOLCHAIN_IAR/libhal.a deleted file mode 100644 index 3882386a10..0000000000 Binary files a/targets/TARGET_RDA/TARGET_UNO_91H/lib/TOOLCHAIN_IAR/libhal.a and /dev/null differ diff --git a/targets/TARGET_RDA/TARGET_UNO_91H/rda_ccfg_api.c b/targets/TARGET_RDA/TARGET_UNO_91H/rda_ccfg_api.c new file mode 100644 index 0000000000..30525e41ec --- /dev/null +++ b/targets/TARGET_RDA/TARGET_UNO_91H/rda_ccfg_api.c @@ -0,0 +1,411 @@ +/* + * 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 "rda_ccfg_api.h" +#include "RDA5991H.h" + +#define CLK_FREQ_40M (0x00U) +#define CLK_FREQ_80M (0x01U) +#define CLK_FREQ_160M (0x02U) +#define ADDR2REG(addr) (*((volatile unsigned int *)(addr))) + +#define RF_SPI_REG ADDR2REG(0x4001301CUL) +#define TRAP_CTRL_REG ADDR2REG(0x40011000UL) +#define TRAP0_SRC_REG ADDR2REG(0x40011004UL) +#define TRAP0_DST_REG ADDR2REG(0x40011024UL) +#define TRAP1_SRC_REG ADDR2REG(0x40011008UL) +#define TRAP1_DST_REG ADDR2REG(0x40011028UL) +#define SPIF_CFG_REG ADDR2REG(0x17FFF014UL) + +#define SYS_CPU_CLK CLK_FREQ_160M +#define AHB_BUS_CLK CLK_FREQ_80M + +extern void core_util_critical_section_enter(void); +extern void core_util_critical_section_exit(void); + +static int ChipHwVersion = 0; + +static inline void wr_rf_usb_reg(unsigned char a, unsigned short d, int isusb) +{ + core_util_critical_section_enter(); + while(RF_SPI_REG & (0x01UL << 31)); + while(RF_SPI_REG & (0x01UL << 31)); + RF_SPI_REG = (unsigned int)d | ((unsigned int)a << 16) | (0x01UL << 25) | ((isusb) ? (0x01UL << 27) : 0x00UL); + core_util_critical_section_exit(); +} + +static inline void rd_rf_usb_reg(unsigned char a, unsigned short *d, int isusb) +{ + core_util_critical_section_enter(); + while(RF_SPI_REG & (0x01UL << 31)); + while(RF_SPI_REG & (0x01UL << 31)); + RF_SPI_REG = ((unsigned int)a << 16) | (0x01UL << 24) | (0x01UL << 25) | ((isusb) ? (0x01UL << 27) : 0x00UL); + __asm volatile ("nop"); + while(RF_SPI_REG & (0x01UL << 31)); + while(RF_SPI_REG & (0x01UL << 31)); + *d = (unsigned short)(RF_SPI_REG & 0xFFFFUL); + core_util_critical_section_exit(); +} + +/* Power down the debug-usage I2C */ +static inline void rda_ccfg_pdi2c(void) +{ + unsigned int val = RDA_PINCFG->MUX2; + if(0x00UL == (val & 0x3FUL)) { + RDA_PINCFG->MUX2 = val | 0x09UL; + } + wr_rf_usb_reg(0xA1, 0x0000, 0); +} + +/* Config CPU & Bus clock */ +static inline void rda_ccfg_ck(void) +{ + unsigned short val = 0U, cfg = 0U; + + cfg = (RDA_SCU->CORECFG >> 11) & 0x07U; + rd_rf_usb_reg(0xA4, &val, 0); +#if ((SYS_CPU_CLK == CLK_FREQ_160M) && (AHB_BUS_CLK == CLK_FREQ_80M)) + /* HCLK inv */ + if(((CLK_FREQ_40M << 1) | CLK_FREQ_40M) == cfg) { + val |= (0x01U << 12); + } +#endif /* CLK_FREQ_160M && CLK_FREQ_80M */ + /* Config CPU & BUS clock */ + cfg ^= (((SYS_CPU_CLK << 1) | AHB_BUS_CLK) & 0x07U); + val &= ~(0x07U << 9); /* bit[11:10] = 2'b00:40M, 2'b01:80M, 2'b1x:160M */ + val |= (cfg << 9); /* bit[9] = 1'b0:40M, 1'b1:80M */ + val &= ~(0x01U); /* i2c_wakeup_en */ + wr_rf_usb_reg(0xA4, val, 0); +} + +/* Config SPI flash clock */ +static inline void rda_ccfg_spifck(void) +{ + unsigned int val; + __DSB(); + val = SPIF_CFG_REG & ~(0x00FFUL << 8); + SPIF_CFG_REG = val | (0x0004UL << 8); // divider + __DSB(); +} + +/* Handle abort booting */ +static inline int rda_ccfg_abort_hdlr(void) +{ + int ret = 0; + unsigned short val = 0U; + rd_rf_usb_reg(0xA1, &val, 0); + ret = (int)((val >> 2) & 0x01U); + if(ret) { + unsigned short val2 = 0U; + rd_rf_usb_reg(0xB2, &val2, 0); + wr_rf_usb_reg(0xB2, (val2 | (0x01U << 11)), 0); + RDA_GPIO->PCCTRL |= (0x01UL << 31); // set abort flag + for(val = 0; val < 0x00FFU; val++) { // delay + ; + } + wr_rf_usb_reg(0xB2, (val2 & ~(0x01U << 11)), 0); + } + return ret; +} + +/* Power up the always-on timer */ +void rda_ccfg_aontmr(void) +{ + unsigned short val = 0U; + rd_rf_usb_reg(0xA3, &val, 0); + if (0x00U == (val & (0x01U << 12))) { + wr_rf_usb_reg(0xA3, (val | (0x01U << 12)), 0); + } +} + +/* Config clock source of always-on timer */ +void rda_ccfg_aontmr_cksrc(int cksrc) +{ + unsigned short val; + if(0 == cksrc) { // use lpo 32K clk, hw default + wr_rf_usb_reg(0xDD, 0x5100U, 0); + rd_rf_usb_reg(0xD8, &val, 0); + wr_rf_usb_reg(0xD8, (val & ~(0x03U << 14)), 0); + rd_rf_usb_reg(0xA8, &val, 0); + val |= ((0x01U << 10) | (0x01U << 14)); + wr_rf_usb_reg(0xA8, (val & ~(0x01U << 12)), 0); + } else { // use 6m5xtal 32K clk, more accurate + int idx; + wr_rf_usb_reg(0xDD, 0x8100U, 0); + rd_rf_usb_reg(0xD8, &val, 0); + wr_rf_usb_reg(0xD8, (val | (0x01U << 15)), 0); + for(idx = 0; idx < 5; idx++) { // for dealy + rd_rf_usb_reg(0x00, &val, 0); + } + wr_rf_usb_reg(0xDD, 0x9100U, 0); + rd_rf_usb_reg(0xD8, &val, 0); + wr_rf_usb_reg(0xD8, (val | (0x01U << 15) | (0x01U << 14)), 0); + rd_rf_usb_reg(0xA8, &val, 0); + val &= ~((0x01U << 10) | (0x01U << 14)); + wr_rf_usb_reg(0xA8, (val | (0x01U << 12)), 0); + } +} + +/* Config GPIO6 to dig core */ +void rda_ccfg_gp6(unsigned short cfg) +{ + unsigned short val = 0U; + rd_rf_usb_reg(0xCD, &val, 0); + val &= ~(0x01U << 11); + wr_rf_usb_reg(0xCD, (val | ((cfg & 0x01U) << 11)), 0); +} + +/* Config GPIO7 to dig core */ +void rda_ccfg_gp7(unsigned short cfg) +{ + unsigned short val = 0U; + rd_rf_usb_reg(0xB0, &val, 0); + val &= ~(0x01U << 14); + wr_rf_usb_reg(0xB0, (val | ((cfg & 0x01U) << 14)), 0); +} + +/* Config GPIO6/7/8/9 to pmu intf or dig core */ +void rda_ccfg_gp(unsigned char gp, unsigned short cfg) +{ + unsigned short val = 0U; + unsigned char reg = 0xCDU; + const int ofs_lst[4] = {11, 14, 10, 9}; + if((6 > gp) || (9 < gp)) { + return; + } + if(7 == gp) { + reg = 0xB0U; + } + rd_rf_usb_reg(reg, &val, 0); + val &= ~(0x01U << ofs_lst[gp - 6]); + wr_rf_usb_reg(reg, (val | ((cfg & 0x01U) << ofs_lst[gp - 6])), 0); +} + +/* Set some core config when booting */ +int rda_ccfg_boot(void) +{ + int ret = 1; + int abort_flag = rda_ccfg_abort_hdlr(); + if(!abort_flag) { + rda_ccfg_pdi2c(); + } + /*close usb polling*/ + RDA_GPIO->CTRL &= ~(0x01UL << 12); + rda_ccfg_ck(); + /* Set flash clock */ + rda_ccfg_spifck(); + /* Set aon timer clock source */ + rda_ccfg_aontmr_cksrc(1); + return ret; +} + +/* Reset CPU & Bus clock config */ +void rda_ccfg_ckrst(void) +{ + unsigned short val = 0U; + + rd_rf_usb_reg(0xA4, &val, 0); + /* HCLK inv */ + val &= ~(0x01U << 12); + /* Config CPU clock */ + val &= ~(0x03U << 10); + val |= (0x00U << 10); /* 2'b00:40M, 2'b01:80M, 2'b1x:160M */ + /* Config BUS clock */ + val &= ~(0x01U << 9); + val |= (0x00U << 9); /* 1'b0:40M, 1'b1:80M */ + wr_rf_usb_reg(0xA4, val, 0); +} + +/* Reset peripheral module */ +void rda_ccfg_perrst(void) +{ + unsigned int idx = 0x0FUL; + RDA_SCU->RESETCTRL &= ~(0x01UL << 11); // soft_resetn_bb + for (; idx>0; idx--); + RDA_SCU->RESETCTRL |= (0x01UL << 11); +} + +/* Init ADC module */ +void rda_ccfg_adc_init(void) +{ + unsigned short val = 0U; + rd_rf_usb_reg(0xA3, &val, 0); /* adc en */ + wr_rf_usb_reg(0xA3, (val | (0x01U << 3)), 0); + rd_rf_usb_reg(0xD8, &val, 0); /* clk 6p5m en */ + wr_rf_usb_reg(0xD8, (val | (0x01U << 15)), 0); + rd_rf_usb_reg(0xB7, &val, 0); /* clk 26m en */ + wr_rf_usb_reg(0xB7, (val | (0x01U << 14)), 0); +} + +/* Config GPIO6/7/8 pdn or pup for ADC usage */ +void rda_ccfg_adc_gp(unsigned char gp, unsigned short cfg) +{ + unsigned short val = 0U; + const int ofs_lst[3] = {8, 9, 7}; + if((6 > gp) || (8 < gp)) { + return; + } + rd_rf_usb_reg(0xB2, &val, 0); + val &= ~(0x01U << ofs_lst[gp - 6]); + wr_rf_usb_reg(0xB2, (val | ((cfg & 0x01U) << ofs_lst[gp - 6])), 0); +} + +/* Config GPADC oenb, use be config to 1 in either Normal mode or GPADC mode */ +void rda_ccfg_adc_oenb(unsigned char ch, unsigned short cfg) +{ + unsigned short val = 0U; + unsigned char offset = 0U; + int ver = rda_ccfg_hwver(); + + if ((ch > 1) || (cfg > 1)) + return; + + if (0 == ch) { + offset = 2; + } else { + if (ver <= 2) + offset = 3; + else if (ver >= 4) + offset = 1; + } + + rd_rf_usb_reg(0xB0, &val, 0); + val &= ~(0x01U << offset); + val |= (cfg << offset); + wr_rf_usb_reg(0xB0, val, 0); +} + +/* Read ADC value */ +unsigned short rda_ccfg_adc_read(unsigned char ch) +{ + unsigned short val = 0U; + rd_rf_usb_reg(0xB7, &val, 0); /* set vref */ + val &= ~((0x03U) << 12); /* verf 1.7V */ + if(!((2U == ch) && (rda_ccfg_hwver() <= 4))) { + val |= ((0x02U) << 12); /* verf 2.0V */ + } + wr_rf_usb_reg(0xB7, val, 0); + + rd_rf_usb_reg(0xB6, &val, 0); /* channel select */ + val &= ~((0x03U) << 12); + wr_rf_usb_reg(0xB6, (val | ((ch & 0x03U) << 12)), 0); + + rd_rf_usb_reg(0xB6, &val, 0); /* set read en */ + wr_rf_usb_reg(0xB6, (val | (0x01U << 2)), 0); + for(val = 0; val < 0x0FFU; val++) { // delay + ; + } + rd_rf_usb_reg(0xB6, &val, 0); /* clr read en */ + wr_rf_usb_reg(0xB6, (val & ~(0x01U << 2)), 0); + + do { + rd_rf_usb_reg(0xB7, &val, 0); /* finish loop flag */ + } while(0x00U == (val & (0x01U << 10))); + return (val & 0x03FFU); +} + +/* Free ADC module */ +void rda_ccfg_adc_free(void) +{ + unsigned short val = 0U; + rd_rf_usb_reg(0xA3, &val, 0); /* adc disable */ + wr_rf_usb_reg(0xA3, (val & ~(0x01U << 3)), 0); + rd_rf_usb_reg(0xB7, &val, 0); /* clk 26m disable */ + wr_rf_usb_reg(0xB7, (val & ~(0x01U << 14)), 0); +} + +/* Get abort flag */ +int rda_ccfg_abort_flag(void) +{ + int ret = 0; + if(0x00UL != (RDA_GPIO->PCCTRL & (0x01UL << 31))) { + ret = 1; + } + return ret; +} + +/* Set wdt en */ +void rda_ccfg_wdt_en(void) +{ + unsigned short val = 0U; + rd_rf_usb_reg(0xC8, &val, 0); + wr_rf_usb_reg(0xC8, (val | (0x01U << 13)), 0); +} + +unsigned short rf_reg_read(unsigned short addr) +{ + unsigned short val = 0U; + if(addr <= 0x1FF) { + if((((addr & 0xFFU) >= 0xA0) && ((addr & 0xFFU) <= 0xDF)) || + (addr == 0x30U) || (addr == 0x34U) || (addr == 0x35U)) { /* PMU & RF_30H/34H/35H */ + rd_rf_usb_reg((unsigned char)(addr & 0xFFU), &val, 0); + } else { /* RF */ + char isrun = 0; + rd_rf_usb_reg(0x30U, &val, 0); + isrun = (val & 0x01U) ? 1 : 0; + if(isrun) { + wr_rf_usb_reg(0x02U, (0x5000U | addr), 0); + rd_rf_usb_reg(0x34U, &val, 0); + } else { + if(addr & (0x01U << 8)) { + wr_rf_usb_reg(0x3FU, 1, 0); + } + rd_rf_usb_reg((unsigned char)(addr & 0xFFU), &val, 0); + if(addr & (0x01U << 8)) { + wr_rf_usb_reg(0x3FU, 0, 0); + } + } + } + } + return val; +} + +void rf_reg_write(unsigned short addr, unsigned short val) +{ + if(addr <= 0x1FF) { + if((((addr & 0xFFU) >= 0xA0) && ((addr & 0xFFU) <= 0xDF)) || + (addr == 0x30U) || (addr == 0x34U) || (addr == 0x35U)) { /* PMU & RF_30H/34H/35H */ + wr_rf_usb_reg((unsigned char)(addr & 0xFFU), val, 0); + } else { /* RF */ + char isrun = 0; + rd_rf_usb_reg(0x30U, &val, 0); + isrun = (val & 0x01U) ? 1 : 0; + if(isrun) { + wr_rf_usb_reg(0x32U, val, 0); + wr_rf_usb_reg(0x02U, (0x4000U | addr), 0); + } else { + if(addr & (0x01U << 8)) { + wr_rf_usb_reg(0x3FU, 1, 0); + } + wr_rf_usb_reg((unsigned char)(addr & 0xFFU), val, 0); + if(addr & (0x01U << 8)) { + wr_rf_usb_reg(0x3FU, 0, 0); + } + } + } + } +} + +/* Get chip hw version */ +int rda_ccfg_hwver(void) +{ + if(0 == ChipHwVersion) { + ChipHwVersion = (int)((RDA_GPIO->REVID >> 16) & 0xFFUL) + 1; + } + return ChipHwVersion; +} + diff --git a/targets/TARGET_RDA/TARGET_UNO_91H/trng_api.c b/targets/TARGET_RDA/TARGET_UNO_91H/trng_api.c index d81f650897..810531b86b 100644 --- a/targets/TARGET_RDA/TARGET_UNO_91H/trng_api.c +++ b/targets/TARGET_RDA/TARGET_UNO_91H/trng_api.c @@ -70,6 +70,8 @@ void trng_init(trng_t *obj) regval = rTRNG_CTRL | ((0x01UL << 4) | (0xFFUL << 16)); rTRNG_CTRL = regval & ~((0x01UL << 1) | (0x01UL << 2) | (0x01UL << 3)); + us_ticker_init(); + /*Entropy data was mixed by TRNG seed and noise, so we add one 32us delay to ensure all 32 bits of seed is entropy when init and another delay to update noise data when get data. diff --git a/targets/TARGET_Realtek/TARGET_AMEBA/sdk/soc/realtek/common/bsp/basic_types.h b/targets/TARGET_Realtek/TARGET_AMEBA/sdk/soc/realtek/common/bsp/basic_types.h index 7719fa2fdf..d1e2c519d9 100644 --- a/targets/TARGET_Realtek/TARGET_AMEBA/sdk/soc/realtek/common/bsp/basic_types.h +++ b/targets/TARGET_Realtek/TARGET_AMEBA/sdk/soc/realtek/common/bsp/basic_types.h @@ -1,21 +1,17 @@ /****************************************************************************** + * Copyright (c) 2013-2019 Realtek Semiconductor Corp. * - * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * 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 __BASIC_TYPES_H__ #define __BASIC_TYPES_H__ diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/TARGET_UBLOX_C030/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/TARGET_UBLOX_C030/PeripheralPins.c index 0c2110186c..051b5ebb3d 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/TARGET_UBLOX_C030/PeripheralPins.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/TARGET_UBLOX_C030/PeripheralPins.c @@ -42,6 +42,9 @@ const PinMap PinMap_ADC[] = { {PA_4, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC1_IN4 {PA_6, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 6, 0)}, // ADC1_IN6 {PB_0, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 8, 0)}, // ADC1_IN8 +#ifdef TARGET_UBLOX_C030_R412M + {PB_1, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 9, 0)}, // ADC1_IN9 +#endif {PC_0, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 10, 0)}, // ADC1_IN10 {PC_2, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 12, 0)}, // ADC1_IN12 {PC_3, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 13, 0)}, // ADC1_IN13 @@ -80,7 +83,9 @@ const PinMap PinMap_DAC[] = { const PinMap PinMap_PWM[] = { {PE_13, PWM_1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 3, 0)}, // TIM1_CH3 {PE_9, PWM_1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 0)}, // TIM1_CH1N +#ifndef TARGET_UBLOX_C030_R412M {PB_1, PWM_3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 4, 0)}, // TIM3_CH4 +#endif {PD_12, PWM_4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 1, 0)}, // TIM4_CH1 {PB_8, PWM_10, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM10, 1, 0)}, // TIM10_CH1 {PB_15, PWM_12, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM12, 2, 0)}, // TIM12_CH2 diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/TARGET_UBLOX_C030/PinNames.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/TARGET_UBLOX_C030/PinNames.h index 3e7b07f08d..6b02420e5c 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/TARGET_UBLOX_C030/PinNames.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/TARGET_UBLOX_C030/PinNames.h @@ -82,7 +82,7 @@ typedef enum { // Cellular modem (a DCE) MDMPWRON = PE_14, // Power (active high) MDMRST = PB_5, // Reset (active low) -#if defined(TARGET_UBLOX_C030_R410M) +#if defined(TARGET_UBLOX_C030_R41XM) MDMTXD = PA_9, // Transmit Data MDMRXD = PA_10, // Receive Data MDMCTS = PA_11, // Clear to Send @@ -118,7 +118,11 @@ typedef enum { D1 = PD_8, // UART3-TX D2 = PD_11, // UART3-CTS D3 = PB_14, // UART3-RTS +#if defined(TARGET_UBLOX_C030_N211) || defined(TARGET_UBLOX_C030_R410M) || defined(TARGET_UBLOX_C030_U201) D4 = PB_1, +#else + D4 = PC_8, +#endif D5 = PA_5, D6 = PB_8, // UART3-CTS D7 = PB_15, // UART3-RTS @@ -165,7 +169,7 @@ typedef enum { #ifdef MBED_CONF_TARGET_STDIO_UART_TX STDIO_UART_TX = MBED_CONF_TARGET_STDIO_UART_TX, #else -#if defined(TARGET_UBLOX_C030_R410M) +#if defined(TARGET_UBLOX_C030_R41XM) STDIO_UART_TX = PD_5, #else STDIO_UART_TX = PA_9, @@ -174,7 +178,7 @@ typedef enum { #ifdef MBED_CONF_TARGET_STDIO_UART_RX STDIO_UART_RX = MBED_CONF_TARGET_STDIO_UART_RX, #else -#if defined(TARGET_UBLOX_C030_R410M) +#if defined(TARGET_UBLOX_C030_R41XM) STDIO_UART_RX = PD_6, #else STDIO_UART_RX = PA_10, 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 00281d2511..52b01ab155 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 @@ -28,7 +28,7 @@ static void press_power_button(int time_us) { gpio_t gpio; -#if defined(TARGET_UBLOX_C030_R410M) +#if defined(TARGET_UBLOX_C030_R41XM) gpio_init_inout(&gpio, MDMPWRON, PIN_OUTPUT, OpenDrain, 0); #else gpio_init_out_ex(&gpio, MDMPWRON, 0); @@ -42,21 +42,28 @@ void onboard_modem_init() { gpio_t gpio; +#if defined(TARGET_UBLOX_C030_R41XM) + // Set the pin to high so on powerup we can set low + gpio_init_inout(&gpio, MDMPWRON, PIN_OUTPUT, OpenDrain, 1); +#else // Take us out of reset gpio_init_out_ex(&gpio, MDMRST, 1); +#endif } void onboard_modem_deinit() { +#ifndef TARGET_UBLOX_C030_R41XM gpio_t gpio; // Back into reset gpio_init_out_ex(&gpio, MDMRST, 0); +#endif } void onboard_modem_power_up() { -#if defined(TARGET_UBLOX_C030_R410M) +#if defined(TARGET_UBLOX_C030_R41XM) /* keep the power line low for 1 seconds */ press_power_button(1000000); #else diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/TARGET_UBLOX_C030/ublox_low_level_api.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/TARGET_UBLOX_C030/ublox_low_level_api.c index d2b01c7c6b..6df2aaf2b5 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/TARGET_UBLOX_C030/ublox_low_level_api.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/TARGET_UBLOX_C030/ublox_low_level_api.c @@ -26,7 +26,7 @@ void ublox_board_init(void) { // start with modem disabled gpio_init_out_ex(&gpio, MDMRST, 0); -#if defined(TARGET_UBLOX_C030_R410M) +#if defined(TARGET_UBLOX_C030_R41XM) gpio_init_inout(&gpio, MDMPWRON, PIN_OUTPUT, OpenDrain, 1); #else gpio_init_out_ex(&gpio, MDMPWRON, 0); @@ -34,8 +34,8 @@ void ublox_board_init(void) { gpio_init_out_ex(&gpio, MDMRTS, 0); gpio_init_in_ex(&gpio, MDMCURRENTSENSE, PullNone); -#if !defined (TARGET_UBLOX_C030_R410M) - // start with GNSS disabled, this is ONLY TEMPORARY and that once the HW issue with the GNSSEN pin on the R410M board is resolved then this line will become default for all platforms. +#if !defined (TARGET_UBLOX_C030_R41XM) + // start with GNSS disabled, this is ONLY TEMPORARY and that once the HW issue with the GNSSEN pin on the R41XM board is resolved then this line will become default for all platforms. gpio_init_inout(&gpio, GNSSEN, PIN_OUTPUT, PushPullNoPull, 0); #endif diff --git a/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H743xI/TARGET_NUCLEO_H743ZI/system_clock.c b/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H743xI/TARGET_NUCLEO_H743ZI/system_clock.c index 77102818ee..42c013a9be 100644 --- a/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H743xI/TARGET_NUCLEO_H743ZI/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H743xI/TARGET_NUCLEO_H743ZI/system_clock.c @@ -127,10 +127,10 @@ uint8_t SetSysClock_PLL_HSE(uint8_t bypass) RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; - RCC_OscInitStruct.PLL.PLLM = 4; - RCC_OscInitStruct.PLL.PLLN = 400; - RCC_OscInitStruct.PLL.PLLP = 2; - RCC_OscInitStruct.PLL.PLLQ = 32; + RCC_OscInitStruct.PLL.PLLM = 4; // 2 MHz + RCC_OscInitStruct.PLL.PLLN = 400; // 800 MHz + RCC_OscInitStruct.PLL.PLLP = 2; // PLLCLK = SYSCLK = 400 MHz + RCC_OscInitStruct.PLL.PLLQ = 80; // PLL1Q used for FDCAN = 10 MHz RCC_OscInitStruct.PLL.PLLR = 2; RCC_OscInitStruct.PLL.PLLFRACN = 0; RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; diff --git a/targets/TARGET_STM/TARGET_STM32H7/can_device.h b/targets/TARGET_STM/TARGET_STM32H7/can_device.h deleted file mode 100644 index 1652fb9491..0000000000 --- a/targets/TARGET_STM/TARGET_STM32H7/can_device.h +++ /dev/null @@ -1,73 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2017 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef MBED_CAN_DEVICE_H -#define MBED_CAN_DEVICE_H - -#include "cmsis.h" -#include "stm32h7xx.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if DEVICE_CAN - -#if defined(CAN3_BASE) - -#define CAN_NUM 3 // Number of CAN peripherals present in the STM32 serie - -#define CAN3_IRQ_RX_IRQN CAN3_RX0_IRQn -#define CAN3_IRQ_RX_VECT CAN3_RX0_IRQHandler -#define CAN3_IRQ_TX_IRQN CAN3_TX_IRQn -#define CAN3_IRQ_TX_VECT CAN3_TX_IRQHandler -#define CAN3_IRQ_ERROR_IRQN CAN3_SCE_IRQn -#define CAN3_IRQ_ERROR_VECT CAN3_SCE_IRQHandler -#define CAN3_IRQ_PASSIVE_IRQN CAN3_SCE_IRQn -#define CAN3_IRQ_PASSIVE_VECT CAN3_SCE_IRQHandler -#define CAN3_IRQ_BUS_IRQN CAN3_SCE_IRQn -#define CAN3_IRQ_BUS_VECT CAN3_SCE_IRQHandler - -#else - -#define CAN_NUM 2 // Number of CAN peripherals present in the STM32 serie - -#endif - -#define CAN1_IRQ_RX_IRQN CAN1_RX0_IRQn -#define CAN1_IRQ_RX_VECT CAN1_RX0_IRQHandler -#define CAN1_IRQ_TX_IRQN CAN1_TX_IRQn -#define CAN1_IRQ_TX_VECT CAN1_TX_IRQHandler -#define CAN1_IRQ_ERROR_IRQN CAN1_SCE_IRQn -#define CAN1_IRQ_ERROR_VECT CAN1_SCE_IRQHandler -#define CAN1_IRQ_PASSIVE_IRQN CAN1_SCE_IRQn -#define CAN1_IRQ_PASSIVE_VECT CAN1_SCE_IRQHandler -#define CAN1_IRQ_BUS_IRQN CAN1_SCE_IRQn -#define CAN1_IRQ_BUS_VECT CAN1_SCE_IRQHandler - -#define CAN2_IRQ_RX_IRQN CAN2_RX0_IRQn -#define CAN2_IRQ_RX_VECT CAN2_RX0_IRQHandler -#define CAN2_IRQ_TX_IRQN CAN2_TX_IRQn -#define CAN2_IRQ_TX_VECT CAN2_TX_IRQHandler -#define CAN2_IRQ_ERROR_IRQN CAN2_SCE_IRQn -#define CAN2_IRQ_ERROR_VECT CAN2_SCE_IRQHandler -#define CAN2_IRQ_PASSIVE_IRQN CAN2_SCE_IRQn -#define CAN2_IRQ_PASSIVE_VECT CAN2_SCE_IRQHandler -#define CAN2_IRQ_BUS_IRQN CAN2_SCE_IRQn -#define CAN2_IRQ_BUS_VECT CAN2_SCE_IRQHandler - -#endif // DEVICE_CAN - -#endif diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L496xG/device/TOOLCHAIN_IAR/stm32l496xx.icf b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L496xG/device/TOOLCHAIN_IAR/stm32l496xx.icf index 1476d296f1..c3e6b76f33 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L496xG/device/TOOLCHAIN_IAR/stm32l496xx.icf +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L496xG/device/TOOLCHAIN_IAR/stm32l496xx.icf @@ -20,7 +20,8 @@ define region SRAM1_region = mem:[from __region_SRAM1_start__ to __region_SRAM1_ /* Stack 1/8 and Heap 1/4 of RAM */ define symbol __size_cstack__ = 0x8000; -define symbol __size_heap__ = 0xa000; +define symbol __size_heap__ = 0x10000; + 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/can_api.c b/targets/TARGET_STM/can_api.c index ecada7bb4b..d5fa84cd7a 100644 --- a/targets/TARGET_STM/can_api.c +++ b/targets/TARGET_STM/can_api.c @@ -17,6 +17,495 @@ #if DEVICE_CAN +#ifdef FDCAN1 + +#include "pinmap.h" +#include "PeripheralPins.h" +#include "mbed_error.h" + +static uint32_t can_irq_ids[2] = {0}; +static can_irq_handler irq_handler; + +/** Call all the init functions + * + * @returns + * 0 if mode change failed or unsupported, + * 1 if mode change was successful + */ +int can_internal_init(can_t *obj) +{ + if (HAL_FDCAN_Init(&obj->CanHandle) != HAL_OK) { + error("HAL_FDCAN_Init error\n"); + } + + if (can_filter(obj, 0, 0, CANStandard, 0) == 0) { + error("can_filter error\n"); + } + + if (can_filter(obj, 0, 0, CANExtended, 0) == 0) { + error("can_filter error\n"); + } + + if (HAL_FDCAN_ConfigGlobalFilter(&obj->CanHandle, FDCAN_REJECT, FDCAN_REJECT, FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE) != HAL_OK) { + error("HAL_FDCAN_ConfigGlobalFilter error\n"); + } + + if (HAL_FDCAN_Start(&obj->CanHandle) != HAL_OK) { + error("HAL_FDCAN_Start error\n"); + } + + return 1; +} + +void can_init(can_t *obj, PinName rd, PinName td) +{ + /* default frequency is 100 kHz */ + can_init_freq(obj, rd, td, 100000); +} + + +void can_init_freq(can_t *obj, PinName rd, PinName td, int hz) +{ + CANName can_rd = (CANName)pinmap_peripheral(rd, PinMap_CAN_RD); + CANName can_td = (CANName)pinmap_peripheral(td, PinMap_CAN_TD); + CANName can = (CANName)pinmap_merge(can_rd, can_td); + MBED_ASSERT((int)can != NC); + + __HAL_RCC_FDCAN_CLK_ENABLE(); + + if (can == CAN_1) { + obj->index = 0; + } +#if defined(FDCAN2_BASE) + else if (can == CAN_2) { + obj->index = 1; + } +#endif + else { + error("can_init wrong instance\n"); + return; + } + + // Select PLL1Q as source of FDCAN clock + RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit; + RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_FDCAN; + RCC_PeriphClkInit.FdcanClockSelection = RCC_FDCANCLKSOURCE_PLL; // 10 MHz (RCC_OscInitStruct.PLL.PLLQ = 80) + if (HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit) != HAL_OK) { + error("HAL_RCCEx_PeriphCLKConfig error\n"); + } + + // Configure CAN pins + pinmap_pinout(rd, PinMap_CAN_RD); + pinmap_pinout(td, PinMap_CAN_TD); + // Add pull-ups + if (rd != NC) { + pin_mode(rd, PullUp); + } + if (td != NC) { + pin_mode(td, PullUp); + } + + // Default values + obj->CanHandle.Instance = (FDCAN_GlobalTypeDef *)can; + + /* Bit time parameter + ex with 100 kHz requested frequency hz + fdcan_ker_ck | 10 MHz | 10 MHz + Prescaler | 1 | 1 + Time_quantum (tq) | 100 ns | 100 ns + Bit_rate | 0.1 MBit/s | + Bit_length | 10 µs = 100 tq | = 10 000 000 / + Synchronization_segment | 1 tq | 1 tq + Phase_segment_1 | 69 tq | = * 0.75 + Phase_segment_2 | 30 tq | = - 1 - + Synchronization_Jump_width | 30 tq | = + */ + int ntq = 10000000 / hz; + + obj->CanHandle.Init.FrameFormat = FDCAN_FRAME_CLASSIC; + obj->CanHandle.Init.Mode = FDCAN_MODE_NORMAL; + obj->CanHandle.Init.AutoRetransmission = ENABLE; + obj->CanHandle.Init.TransmitPause = DISABLE; + obj->CanHandle.Init.ProtocolException = ENABLE; + obj->CanHandle.Init.NominalPrescaler = 1; // Prescaler + obj->CanHandle.Init.NominalTimeSeg1 = ntq * 0.75; // Phase_segment_1 + obj->CanHandle.Init.NominalTimeSeg2 = ntq - 1 - obj->CanHandle.Init.NominalTimeSeg1; // Phase_segment_2 + obj->CanHandle.Init.NominalSyncJumpWidth = obj->CanHandle.Init.NominalTimeSeg2; // Synchronization_Jump_width + obj->CanHandle.Init.DataPrescaler = 0x1; // Not used - only in FDCAN + obj->CanHandle.Init.DataSyncJumpWidth = 0x1; // Not used - only in FDCAN + obj->CanHandle.Init.DataTimeSeg1 = 0x1; // Not used - only in FDCAN + obj->CanHandle.Init.DataTimeSeg2 = 0x1; // Not used - only in FDCAN + obj->CanHandle.Init.MessageRAMOffset = 0; + obj->CanHandle.Init.StdFiltersNbr = 1; // to be aligned with the handle parameter in can_filter + obj->CanHandle.Init.ExtFiltersNbr = 1; // to be aligned with the handle parameter in can_filter + obj->CanHandle.Init.RxFifo0ElmtsNbr = 8; + obj->CanHandle.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8; + obj->CanHandle.Init.RxFifo1ElmtsNbr = 0; + obj->CanHandle.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_8; + obj->CanHandle.Init.RxBuffersNbr = 0; + obj->CanHandle.Init.RxBufferSize = FDCAN_DATA_BYTES_8; + obj->CanHandle.Init.TxEventsNbr = 3; + obj->CanHandle.Init.TxBuffersNbr = 0; + obj->CanHandle.Init.TxFifoQueueElmtsNbr = 3; + obj->CanHandle.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; + obj->CanHandle.Init.TxElmtSize = FDCAN_DATA_BYTES_8; + + can_internal_init(obj); +} + + +void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id) +{ + irq_handler = handler; + can_irq_ids[obj->index] = id; +} + +void can_irq_free(can_t *obj) +{ + CANName can = (CANName)obj->CanHandle.Instance; + if (can == CAN_1) { + HAL_NVIC_DisableIRQ(FDCAN1_IT0_IRQn); + HAL_NVIC_DisableIRQ(FDCAN1_IT1_IRQn); + } +#if defined(FDCAN2_BASE) + else if (can == CAN_2) { + HAL_NVIC_DisableIRQ(FDCAN2_IT0_IRQn); + HAL_NVIC_DisableIRQ(FDCAN2_IT1_IRQn); + } +#endif + else { + return; + } + HAL_NVIC_DisableIRQ(FDCAN_CAL_IRQn); + can_irq_ids[obj->index] = 0; +} + +void can_free(can_t *obj) +{ + __HAL_RCC_FDCAN_FORCE_RESET(); + __HAL_RCC_FDCAN_RELEASE_RESET(); + __HAL_RCC_FDCAN_CLK_DISABLE(); +} + + +/** Reset CAN interface. + * + * To use after error overflow. + */ +void can_reset(can_t *obj) +{ + can_mode(obj, MODE_RESET); + HAL_FDCAN_ResetTimeoutCounter(&obj->CanHandle); + HAL_FDCAN_ResetTimestampCounter(&obj->CanHandle); +} + + +int can_frequency(can_t *obj, int f) +{ + if (HAL_FDCAN_Stop(&obj->CanHandle) != HAL_OK) { + error("HAL_FDCAN_Stop error\n"); + } + + /* See can_init_freq function for calculation details */ + int ntq = 10000000 / f; + obj->CanHandle.Init.NominalTimeSeg1 = ntq * 0.75; // Phase_segment_1 + obj->CanHandle.Init.NominalTimeSeg2 = ntq - 1 - obj->CanHandle.Init.NominalTimeSeg1; // Phase_segment_2 + obj->CanHandle.Init.NominalSyncJumpWidth = obj->CanHandle.Init.NominalTimeSeg2; // Synchronization_Jump_width + + return can_internal_init(obj); +} + + +/** Filter out incoming messages + * + * @param obj CAN object + * @param id the id to filter on + * @param mask the mask applied to the id + * @param format format to filter on + * @param handle message filter handle (not supported yet) + * + * @returns + * 0 if filter change failed or unsupported, + * new filter handle if successful (not supported yet => returns 1) + */ +int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) +{ + UNUSED(handle); // Not supported yet (seems to be a used in read function?) + + FDCAN_FilterTypeDef sFilterConfig = {0}; + + if (format == CANStandard) { + sFilterConfig.IdType = FDCAN_STANDARD_ID; + sFilterConfig.FilterIndex = 0; + sFilterConfig.FilterType = FDCAN_FILTER_MASK; + sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0; + sFilterConfig.FilterID1 = id; + sFilterConfig.FilterID2 = mask; + } else if (format == CANExtended) { + sFilterConfig.IdType = FDCAN_EXTENDED_ID; + sFilterConfig.FilterIndex = 0; + sFilterConfig.FilterType = FDCAN_FILTER_MASK; + sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0; + sFilterConfig.FilterID1 = id; + sFilterConfig.FilterID2 = mask; + } else { // Filter for CANAny format cannot be configured for STM32 + return 0; + } + + if (HAL_FDCAN_ConfigFilter(&obj->CanHandle, &sFilterConfig) != HAL_OK) { + return 0; + } + + return 1; +} + + +int can_write(can_t *obj, CAN_Message msg, int cc) +{ + FDCAN_TxHeaderTypeDef TxHeader = {0}; + + UNUSED(cc); + + // Configure Tx buffer message + TxHeader.Identifier = msg.id; + if (msg.format == CANStandard) { + TxHeader.IdType = FDCAN_STANDARD_ID; + } else { + TxHeader.IdType = FDCAN_EXTENDED_ID; + } + + TxHeader.TxFrameType = FDCAN_DATA_FRAME; + TxHeader.DataLength = msg.len << 16; + TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE; + TxHeader.BitRateSwitch = FDCAN_BRS_OFF; + TxHeader.FDFormat = FDCAN_CLASSIC_CAN; + TxHeader.TxEventFifoControl = FDCAN_STORE_TX_EVENTS; + TxHeader.MessageMarker = 0; + + if (HAL_FDCAN_AddMessageToTxFifoQ(&obj->CanHandle, &TxHeader, msg.data) != HAL_OK) { + // Note for debug: you can get the error code calling HAL_FDCAN_GetError(&obj->CanHandle) + return 0; + } + + return 1; +} + +int can_read(can_t *obj, CAN_Message *msg, int handle) +{ + UNUSED(handle); // Not supported yet (seems to be a handle to a filter configuration?) + + if (HAL_FDCAN_GetRxFifoFillLevel(&obj->CanHandle, FDCAN_RX_FIFO0) == 0) { + return 0; // No message arrived + } + + FDCAN_RxHeaderTypeDef RxHeader = {0}; + if (HAL_FDCAN_GetRxMessage(&obj->CanHandle, FDCAN_RX_FIFO0, &RxHeader, msg->data) != HAL_OK) { + error("HAL_FDCAN_GetRxMessage error\n"); // Should not occur as previous HAL_FDCAN_GetRxFifoFillLevel call reported some data + return 0; + } + + if (RxHeader.IdType == FDCAN_STANDARD_ID) { + msg->format = CANStandard; + } else { + msg->format = CANExtended; + } + msg->id = RxHeader.Identifier; + msg->type = CANData; + msg->len = RxHeader.DataLength >> 16; // see FDCAN_data_length_code value + + return 1; +} + +unsigned char can_rderror(can_t *obj) +{ + FDCAN_ErrorCountersTypeDef ErrorCounters; + + HAL_FDCAN_GetErrorCounters(&obj->CanHandle, &ErrorCounters); + + return (unsigned char)ErrorCounters.RxErrorCnt; +} + +unsigned char can_tderror(can_t *obj) +{ + FDCAN_ErrorCountersTypeDef ErrorCounters; + + HAL_FDCAN_GetErrorCounters(&obj->CanHandle, &ErrorCounters); + + return (unsigned char)ErrorCounters.TxErrorCnt; +} + +void can_monitor(can_t *obj, int silent) +{ + CanMode mode = MODE_NORMAL; + if (silent) { + switch (obj->CanHandle.Init.Mode) { + case FDCAN_MODE_INTERNAL_LOOPBACK: + mode = MODE_TEST_SILENT; + break; + default: + mode = MODE_SILENT; + break; + } + } else { + switch (obj->CanHandle.Init.Mode) { + case FDCAN_MODE_INTERNAL_LOOPBACK: + case FDCAN_MODE_EXTERNAL_LOOPBACK: + mode = MODE_TEST_LOCAL; + break; + default: + mode = MODE_NORMAL; + break; + } + } + + can_mode(obj, mode); +} + +/** Change CAN operation to the specified mode + * + * @param mode The new operation mode (MODE_RESET, MODE_NORMAL, MODE_SILENT, MODE_TEST_LOCAL, MODE_TEST_GLOBAL, MODE_TEST_SILENT) + * + * @returns + * 0 if mode change failed or unsupported, + * 1 if mode change was successful + */ +int can_mode(can_t *obj, CanMode mode) +{ + if (HAL_FDCAN_Stop(&obj->CanHandle) != HAL_OK) { + error("HAL_FDCAN_Stop error\n"); + } + + switch (mode) { + case MODE_RESET: + break; + case MODE_NORMAL: + obj->CanHandle.Init.Mode = FDCAN_MODE_NORMAL; + // obj->CanHandle.Init.NominalPrescaler = 100; // Prescaler + break; + case MODE_SILENT: // Bus Monitoring + obj->CanHandle.Init.Mode = FDCAN_MODE_BUS_MONITORING; + break; + case MODE_TEST_GLOBAL: // External LoopBack + case MODE_TEST_LOCAL: + obj->CanHandle.Init.Mode = FDCAN_MODE_EXTERNAL_LOOPBACK; + break; + case MODE_TEST_SILENT: // Internal LoopBack + obj->CanHandle.Init.Mode = FDCAN_MODE_INTERNAL_LOOPBACK; + // obj->CanHandle.Init.NominalPrescaler = 1; // Prescaler + break; + default: + return 0; + } + + return can_internal_init(obj); +} + + +static void can_irq(CANName name, int id) +{ + FDCAN_HandleTypeDef CanHandle; + CanHandle.Instance = (FDCAN_GlobalTypeDef *)name; + + if (__HAL_FDCAN_GET_IT_SOURCE(&CanHandle, FDCAN_IT_TX_COMPLETE)) { + if (__HAL_FDCAN_GET_FLAG(&CanHandle, FDCAN_FLAG_TX_COMPLETE)) { + __HAL_FDCAN_CLEAR_FLAG(&CanHandle, FDCAN_FLAG_TX_COMPLETE); + irq_handler(can_irq_ids[id], IRQ_TX); + } + } + + if (__HAL_FDCAN_GET_IT_SOURCE(&CanHandle, FDCAN_IT_RX_BUFFER_NEW_MESSAGE)) { + if (__HAL_FDCAN_GET_FLAG(&CanHandle, FDCAN_IT_RX_BUFFER_NEW_MESSAGE)) { + __HAL_FDCAN_CLEAR_FLAG(&CanHandle, FDCAN_IT_RX_BUFFER_NEW_MESSAGE); + irq_handler(can_irq_ids[id], IRQ_RX); + } + } + + if (__HAL_FDCAN_GET_IT_SOURCE(&CanHandle, FDCAN_IT_ERROR_WARNING)) { + if (__HAL_FDCAN_GET_FLAG(&CanHandle, FDCAN_FLAG_ERROR_WARNING)) { + __HAL_FDCAN_CLEAR_FLAG(&CanHandle, FDCAN_FLAG_ERROR_WARNING); + irq_handler(can_irq_ids[id], IRQ_ERROR); + } + } + + if (__HAL_FDCAN_GET_IT_SOURCE(&CanHandle, FDCAN_IT_ERROR_PASSIVE)) { + if (__HAL_FDCAN_GET_FLAG(&CanHandle, FDCAN_FLAG_ERROR_PASSIVE)) { + __HAL_FDCAN_CLEAR_FLAG(&CanHandle, FDCAN_FLAG_ERROR_PASSIVE); + irq_handler(can_irq_ids[id], IRQ_PASSIVE); + } + } + + if (__HAL_FDCAN_GET_IT_SOURCE(&CanHandle, FDCAN_IT_BUS_OFF)) { + if (__HAL_FDCAN_GET_FLAG(&CanHandle, FDCAN_FLAG_BUS_OFF)) { + __HAL_FDCAN_CLEAR_FLAG(&CanHandle, FDCAN_FLAG_BUS_OFF); + irq_handler(can_irq_ids[id], IRQ_BUS); + } + } +} + +void FDCAN1_IT0_IRQHandler(void) +{ + can_irq(CAN_1, 0); +} + +void FDCAN1_IT1_IRQHandler(void) +{ + can_irq(CAN_1, 0); +} + +void FDCAN2_IT0_IRQHandler(void) +{ + can_irq(CAN_2, 1); +} + +void FDCAN2_IT1_IRQHandler(void) +{ + can_irq(CAN_2, 1); +} + +// TODO Add other interrupts ? +void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable) +{ + uint32_t interrupts = 0; + + switch (type) { + case IRQ_TX: + interrupts = FDCAN_IT_TX_COMPLETE; + break; + case IRQ_RX: + interrupts = FDCAN_IT_RX_BUFFER_NEW_MESSAGE; + break; + case IRQ_ERROR: + interrupts = FDCAN_IT_ERROR_WARNING; + break; + case IRQ_PASSIVE: + interrupts = FDCAN_IT_ERROR_PASSIVE; + break; + case IRQ_BUS: + interrupts = FDCAN_IT_BUS_OFF; + default: + return; + } + + if (enable) { + HAL_FDCAN_ActivateNotification(&obj->CanHandle, interrupts, 0); + } else { + HAL_FDCAN_DeactivateNotification(&obj->CanHandle, interrupts); + } + + NVIC_SetVector(FDCAN1_IT0_IRQn, (uint32_t)&FDCAN1_IT0_IRQHandler); + NVIC_EnableIRQ(FDCAN1_IT0_IRQn); + NVIC_SetVector(FDCAN1_IT1_IRQn, (uint32_t)&FDCAN1_IT1_IRQHandler); + NVIC_EnableIRQ(FDCAN1_IT1_IRQn); +#if defined(FDCAN2_BASE) + NVIC_SetVector(FDCAN2_IT0_IRQn, (uint32_t)&FDCAN2_IT0_IRQHandler); + NVIC_EnableIRQ(FDCAN2_IT0_IRQn); + NVIC_SetVector(FDCAN2_IT1_IRQn, (uint32_t)&FDCAN2_IT1_IRQHandler); + NVIC_EnableIRQ(FDCAN2_IT1_IRQn); +#endif +} + +#else /* FDCAN1 */ + #include "cmsis.h" #include "pinmap.h" #include "PeripheralPins.h" @@ -454,8 +943,6 @@ int can_mode(can_t *obj, CanMode mode) int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) { - int retval = 0; - // filter for CANAny format cannot be configured for STM32 if ((format == CANStandard) || (format == CANExtended)) { CAN_FilterConfTypeDef sFilterConfig; @@ -480,9 +967,9 @@ int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t sFilterConfig.BankNumber = 14 + handle; HAL_CAN_ConfigFilter(&obj->CanHandle, &sFilterConfig); - retval = handle; } - return retval; + + return 1; } static void can_irq(CANName name, int id) @@ -716,4 +1203,6 @@ void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable) NVIC_EnableIRQ(irq_n); } +#endif /* FDCAN1 */ + #endif // DEVICE_CAN diff --git a/targets/TARGET_STM/mbed_crc_api.c b/targets/TARGET_STM/mbed_crc_api.c index 2a17ee2a63..33023261f5 100644 --- a/targets/TARGET_STM/mbed_crc_api.c +++ b/targets/TARGET_STM/mbed_crc_api.c @@ -7,26 +7,57 @@ static CRC_HandleTypeDef current_state; static uint32_t final_xor; +static uint32_t crc_mask; +/* STM32 CRC preipheral features + +-------------------------+-----------------------+---------------+---------------+ + | Feature | F1/L1/F2/F4 series | F0 series (#1)| L0/F3/L4/F7 | + +-========================+=======================+===============+===============+ + | Reversibility option | NO | YES | + | on I/O data | | | + +-------------------------+-----------------------+---------------+---------------+ + | CRC initial Value | Fixed to 0xFFFFFFFF | Programmable | Programmable | + | | | on 32 bits | on 8,16,32 | + +-------------------------+-----------------------+---------------+---------------+ + | Handled data size in bit| 32 | 8,16,32 | + +-------------------------+---------------------------------------+---------------+ + | Polynomial size in bit | 32 | 7,8,16,32 | + +-------------------------+---------------------------------------+---------------+ + | Polynomial coefficients | Fixed to 0x4C11DB7 | Programmable | + +-------------------------+---------------------------------------+---------------+ + + #1 The STM32F0 series which supported polynomial in 7, 8, 16, 32 bits as below list: + STM32F071xB + STM32F072xB + STM32F078xx + STM32F091xC + STM32F098xx +*/ bool hal_crc_is_supported(const crc_mbed_config_t *config) { if (config == NULL) { return false; } - if (config->polynomial != POLY_32BIT_ANSI) { +#if defined(TARGET_STM32F1) || defined(TARGET_STM32F2) || defined(TARGET_STM32F4) || defined(TARGET_STM32L1) + /* Currently, mbed supported input data format fix on bytes, + so those devices are not supported at default. */ + return false; +#elif !defined(CRC_POLYLENGTH_7B) + /* Some targets are not support polynomial in 7, 8, 16 bits, ex. STM32F070RB, + so those devices are not supported at default. */ + return false; +#else + if (config->width != 32 && config->width != 16 && config->width != 8 && config->width != 7) { return false; } - - if (config->width != 32) { - return false; - } - - if ((config->final_xor != 0xFFFFFFFFU) && (config->final_xor != 0)) { - return false; - } - return true; +#endif +} + +static uint32_t get_crc_mask(int width) +{ + return (width < 8 ? ((1u << 8) - 1) : (uint32_t)((uint64_t)(1ull << width) - 1)); } void hal_crc_compute_partial_start(const crc_mbed_config_t *config) @@ -36,21 +67,46 @@ void hal_crc_compute_partial_start(const crc_mbed_config_t *config) __HAL_RCC_CRC_CLK_ENABLE(); final_xor = config->final_xor; + crc_mask = get_crc_mask(config->width); current_state.Instance = CRC; +#if !defined(TARGET_STM32F1) && !defined(TARGET_STM32F2) && !defined(TARGET_STM32F4) && !defined(TARGET_STM32L1) && defined(CRC_POLYLENGTH_7B) current_state.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES; - current_state.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE; current_state.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_DISABLE; + current_state.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE; current_state.Init.InitValue = config->initial_xor; - current_state.Init.CRCLength = CRC_POLYLENGTH_32B; + current_state.Init.GeneratingPolynomial = config->polynomial; + + switch (config->width) + { + case HAL_CRC_LENGTH_32B: + current_state.Init.CRCLength = CRC_POLYLENGTH_32B; + break; + case HAL_CRC_LENGTH_16B: + current_state.Init.CRCLength = CRC_POLYLENGTH_16B; + break; + case HAL_CRC_LENGTH_8B: + current_state.Init.CRCLength = CRC_POLYLENGTH_8B; + break; + case HAL_CRC_LENGTH_7B: + current_state.Init.CRCLength = CRC_POLYLENGTH_7B; + break; + default: + MBED_ASSERT(false); + break; + } + current_state.Init.InputDataInversionMode = config->reflect_in ? CRC_INPUTDATA_INVERSION_BYTE : CRC_INPUTDATA_INVERSION_NONE; current_state.Init.OutputDataInversionMode = config->reflect_out ? CRC_OUTPUTDATA_INVERSION_ENABLE : CRC_OUTPUTDATA_INVERSION_DISABLE; +#endif - HAL_CRC_Init(¤t_state); + if (HAL_CRC_Init(¤t_state) != HAL_OK) { + MBED_ASSERT(false); + } } void hal_crc_compute_partial(const uint8_t *data, const size_t size) @@ -62,9 +118,29 @@ void hal_crc_compute_partial(const uint8_t *data, const size_t size) uint32_t hal_crc_get_result(void) { - const uint32_t result = current_state.Instance->DR; + uint32_t result = current_state.Instance->DR; - return (final_xor == 0xFFFFFFFFU) ? ~result : result; +#if !defined(TARGET_STM32F1) && !defined(TARGET_STM32F2) && !defined(TARGET_STM32F4) && !defined(TARGET_STM32L1) && defined(CRC_POLYLENGTH_7B) + /* The CRC-7 SD needs to shift left by 1 bit after obtaining the result, but the output + * inversion of CRC peripheral will convert the result before shift left by 1 bit, so + * the result seems to have shifted after the conversion. + * + * Example: + * [Gerenal setps] + * 1. Before output inversion: 0x75 (0111 0101) + * 2. Left shift by 1 bit: 0xEA (1110 1010) + * 3. After output inversion: 0x57 (0101 0111) + * + * [STM32 CRC peripheral steps] + * 1. Before output inversion: 0x75 (0111 0101) + * 2. After output inversion: 0x57 (0101 0111) <= no needs shift again + */ + if (current_state.Init.CRCLength == CRC_POLYLENGTH_7B && + current_state.Init.GeneratingPolynomial == POLY_7BIT_SD && + current_state.Init.OutputDataInversionMode == CRC_OUTPUTDATA_INVERSION_DISABLE) + result = result << 1; +#endif + return (result ^ final_xor) & crc_mask; } #endif // DEVICE_CRC diff --git a/targets/targets.json b/targets/targets.json index 6989f412e5..edf5e32e49 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -1357,7 +1357,7 @@ "supported_form_factors": ["ARDUINO"], "core": "Cortex-M0+", "supported_toolchains": ["ARM", "GCC_ARM", "IAR"], - "extra_labels": ["Freescale", "MCUXpresso_MCUS", "KSDK2_MCUS", "FRDM"], + "extra_labels": ["Freescale", "MCUXpresso_MCUS", "KSDK2_MCUS", "FRDM", "FRAMEWORK_5_3_3", "NXP"], "is_disk_virtual": true, "macros": ["CPU_MKW41Z512VHT4", "FSL_RTOS_MBED"], "inherits": ["Target"], @@ -1381,11 +1381,15 @@ "SPISLAVE", "TRNG", "STDIO_MESSAGES", - "FLASH" + "FLASH", + "802_15_4_PHY" ], "release_versions": ["2", "5"], "device_name": "MKW41Z512xxx4", - "bootloader_supported": true + "bootloader_supported": true, + "overrides": { + "network-default-interface-type": "MESH" + } }, "MCU_K24F1M": { "core": "Cortex-M4F", @@ -1997,7 +2001,8 @@ "inherits": ["MCU_LPC546XX"], "extra_labels_add": ["LPCXpresso"], "detect_code": ["1056"], - "release_versions": ["2", "5"] + "release_versions": ["2", "5"], + "components_add": ["QSPIF"] }, "FF_LPC546XX": { "inherits": ["MCU_LPC546XX"], @@ -2988,11 +2993,15 @@ "macro_name": "HSE_VALUE" } }, - "overrides": { "lpticker_delay_ticks": 3 }, + "macros_add": [ + "MBED_TICKLESS" + ], + "overrides": { "lpticker_delay_ticks": 4 }, "supported_form_factors": ["ARDUINO"], "detect_code": ["0813"], "device_has_add": [ "ANALOGOUT", + "CAN", "CRC", "TRNG", "FLASH", @@ -4273,10 +4282,18 @@ "inherits": ["UBLOX_C030"], "release_versions": ["5"] }, - "UBLOX_C030_R410M": { + "UBLOX_C030_R41XM": { "inherits": ["UBLOX_C030"], "release_versions": ["5"] }, + "UBLOX_C030_R410M": { + "inherits": ["UBLOX_C030_R41XM"], + "release_versions": ["5"] + }, + "UBLOX_C030_R412M": { + "inherits": ["UBLOX_C030_R41XM"], + "release_versions": ["5"] + }, "NZ32_SC151": { "inherits": ["FAMILY_STM32"], "core": "Cortex-M3", @@ -5221,6 +5238,7 @@ "supported_toolchains": ["GCC_ARM", "IAR", "ARM"], "device_has": [ "ANALOGIN", + "FLASH", "I2C", "INTERRUPTIN", "LPTICKER", @@ -5251,6 +5269,7 @@ "supported_toolchains": ["GCC_ARM", "IAR", "ARM"], "device_has": [ "ANALOGIN", + "FLASH", "I2C", "INTERRUPTIN", "LPTICKER", @@ -6780,6 +6799,7 @@ }, "MCU_NRF52840": { "inherits": ["Target"], + "components_add": ["QSPIF"], "core": "Cortex-M4F", "static_memory_defines": false, "macros": [ diff --git a/tools/build_api.py b/tools/build_api.py index 0faf8eadb8..54c39e59d7 100644 --- a/tools/build_api.py +++ b/tools/build_api.py @@ -121,6 +121,15 @@ def add_result_to_report(report, result): result_wrap = {0: result} report[target][toolchain][id_name].append(result_wrap) +def get_toolchain_name(target, toolchain_name): + if toolchain_name == "ARM": + if CORE_ARCH[target.core] == 8: + return "ARMC6" + elif getattr(target, "default_toolchain", None) == "uARM": + return "uARM" + + return toolchain_name + def get_config(src_paths, target, toolchain_name=None, app_config=None): """Get the configuration object for a target-toolchain combination @@ -316,8 +325,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" + + toolchain_name = get_toolchain_name(target, toolchain_name) try: cur_tc = TOOLCHAIN_CLASSES[toolchain_name] @@ -408,7 +417,7 @@ def merge_region_list(region_list, destination, notify, padding=b'\xFF'): Positional Arguments: region_list - list of regions, which should contain filenames destination - file name to write all regions to - padding - bytes to fill gapps with + padding - bytes to fill gaps with """ merged = IntelHex() _, format = splitext(destination) @@ -576,7 +585,6 @@ def build_project(src_paths, build_path, target, toolchain_name, copy_when_different(join(build_path, art), into_dir) memap_instance = getattr(toolchain, 'memap_instance', None) - memap_table = '' if memap_instance: # Write output to stdout in text (pretty table) format memap_table = memap_instance.generate_output('table', stats_depth) @@ -942,6 +950,8 @@ def build_mbed_libs(target, toolchain_name, clean=False, macros=None, Return - True if target + toolchain built correctly, False if not supported """ + toolchain_name = get_toolchain_name(target, toolchain_name) + if report is not None: start = time() id_name = "MBED" diff --git a/tools/export/iar/iar_definitions.json b/tools/export/iar/iar_definitions.json index 8b9fd819cf..0c3c9eeaed 100644 --- a/tools/export/iar/iar_definitions.json +++ b/tools/export/iar/iar_definitions.json @@ -285,9 +285,6 @@ "GFPUCoreSlave": 24, "GBECoreSlave": 24 }, - "STM32H743ZI": { - "OGChipSelectEditMenu": "STM32H743ZI\tST STM32H743ZI" - }, "STM32F446VE": { "OGChipSelectEditMenu": "STM32F446VE\tST STM32F446VE" }, diff --git a/tools/test/examples/examples.json b/tools/test/examples/examples.json index bb70d3b309..63d332c57b 100644 --- a/tools/test/examples/examples.json +++ b/tools/test/examples/examples.json @@ -62,8 +62,7 @@ ], "test-repo-source": "github", "features" : [], - "targets" : ["Freescale_EMAC", "NUVOTON_EMAC", "NXP_EMAC", "RZ_A1_EMAC", - "STM_EMAC"], + "targets" : ["K66F", "NUCLEO_F429ZI", "NUMAKER_PFM_NUC472"], "toolchains" : [], "exporters": [], "compile" : true, @@ -77,8 +76,7 @@ ], "test-repo-source": "github", "features" : [], - "targets" : ["Freescale_EMAC", "NUVOTON_EMAC", "NXP_EMAC", "RZ_A1_EMAC", - "STM_EMAC"], + "targets" : ["K64F", "DISCO_F746NG"], "toolchains" : [], "exporters": [], "compile" : true, @@ -144,7 +142,7 @@ "mbed": [], "test-repo-source": "github", "features" : [], - "targets" : ["K66F"], + "targets" : ["K66F", "FVP_MPS2_M3"], "toolchains" : [], "exporters": [], "compile" : true, @@ -170,7 +168,7 @@ "mbed": [], "test-repo-source": "github", "features" : [], - "targets" : ["K66F"], + "targets" : ["K66F", "FVP_MPS2_M3"], "toolchains" : [], "exporters": [], "compile" : true, @@ -183,7 +181,7 @@ "mbed": [], "test-repo-source": "github", "features" : [], - "targets" : ["K66F"], + "targets" : ["K66F", "FVP_MPS2_M3"], "toolchains" : [], "exporters": [], "compile" : true, @@ -222,8 +220,7 @@ "mbed": [], "test-repo-source": "github", "features" : [], - "targets" : ["Freescale_EMAC", "NUVOTON_EMAC", "NXP_EMAC", "RZ_A1_EMAC", - "STM_EMAC"], + "targets" : ["K66F"], "toolchains" : [], "exporters": [], "compile" : true, @@ -236,7 +233,7 @@ "mbed": [], "test-repo-source": "github", "features" : [], - "targets" : ["K64F"], + "targets" : ["K64F", "FVP_MPS2_M3"], "toolchains" : [], "exporters": [], "compile" : true, @@ -338,7 +335,7 @@ "mbed": [], "test-repo-source": "github", "features" : [], - "targets" : ["K64F"], + "targets" : ["K64F", "FVP_MPS2_M3"], "toolchains" : [], "exporters": [], "compile" : true, @@ -351,7 +348,7 @@ "mbed": [], "test-repo-source": "github", "features" : [], - "targets" : ["K64F", "DISCO_L475VG_IOT01A"], + "targets" : ["K64F", "DISCO_L475VG_IOT01A", "FVP_MPS2_M3"], "toolchains" : [], "exporters": [], "compile" : true, diff --git a/tools/test/toolchains/api_test.py b/tools/test/toolchains/api_test.py index b1a19c3300..f48ea1dc0d 100644 --- a/tools/test/toolchains/api_test.py +++ b/tools/test/toolchains/api_test.py @@ -4,7 +4,7 @@ import os from string import printable from copy import deepcopy from mock import MagicMock, patch -from hypothesis import given, settings +from hypothesis import given, settings, HealthCheck from hypothesis.strategies import text, lists, fixed_dictionaries, booleans ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", @@ -112,6 +112,7 @@ def test_gcc_version_check(_run_cmd): 'asm': lists(text()), 'ld': lists(text())}), lists(text(min_size=1, alphabet=ALPHABET), min_size=1)) +@settings(suppress_health_check=[HealthCheck.too_slow]) def test_toolchain_profile_c(profile, source_file): """Test that the appropriate profile parameters are passed to the C compiler""" @@ -144,6 +145,7 @@ def test_toolchain_profile_c(profile, source_file): 'asm': lists(text()), 'ld': lists(text())}), lists(text(min_size=1, alphabet=ALPHABET), min_size=1)) +@settings(suppress_health_check=[HealthCheck.too_slow]) def test_toolchain_profile_cpp(profile, source_file): """Test that the appropriate profile parameters are passed to the C++ compiler""" @@ -175,6 +177,7 @@ def test_toolchain_profile_cpp(profile, source_file): 'asm': lists(text()), 'ld': lists(text())}), lists(text(min_size=1, alphabet=ALPHABET), min_size=1)) +@settings(suppress_health_check=[HealthCheck.too_slow]) def test_toolchain_profile_asm(profile, source_file): """Test that the appropriate profile parameters are passed to the Assembler""" @@ -213,6 +216,7 @@ def test_toolchain_profile_asm(profile, source_file): 'asm': lists(text()), 'ld': lists(text(min_size=1))}), lists(text(min_size=1, alphabet=ALPHABET), min_size=1)) +@settings(suppress_health_check=[HealthCheck.too_slow]) def test_toolchain_profile_ld(profile, source_file): """Test that the appropriate profile parameters are passed to the Linker""" diff --git a/tools/test/travis-ci/doxy-spellchecker/en.dat b/tools/test/travis-ci/doxy-spellchecker/en.dat new file mode 100644 index 0000000000..ec2555ee21 --- /dev/null +++ b/tools/test/travis-ci/doxy-spellchecker/en.dat @@ -0,0 +1,6 @@ +name en +charset iso8859-1 +soundslike en +affix en +special ' -*- 0 *** 1 *** 2 *** 3 *** 4 *** 5 *** 6 *** 7 *** 8 *** 9 *** < *** > *** _ *** +#repl-table en_affix.dat diff --git a/tools/test/travis-ci/doxy-spellchecker/en_affix.dat b/tools/test/travis-ci/doxy-spellchecker/en_affix.dat new file mode 100644 index 0000000000..e753407a0d --- /dev/null +++ b/tools/test/travis-ci/doxy-spellchecker/en_affix.dat @@ -0,0 +1,226 @@ +# +# This affix file is based on Ispell, which is under the following +# copyright: +# +# Copyright 1992, 1993, 1999, 2000, 2001, Geoff Kuenning, Claremont, CA +# 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. All modifications to the source code must be clearly marked as +# such. Binary redistributions based on modified source code +# must be clearly marked as modified versions in the documentation +# and/or other materials provided with the distribution. +# (Clause 4 removed with permission from Geoff Kuenning.) +# 5. The name of Geoff Kuenning may not be used to endorse or promote +# products derived from this software without specific prior +# written permission. +# +# THIS SOFTWARE IS PROVIDED BY GEOFF KUENNING 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 GEOFF KUENNING 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. +# + +SET ISO8859-1 +TRY esianrtolcdugmphbyfvkwzESIANRTOLCDUGMPHBYFVKWZ' + +PFX A Y 1 +PFX A 0 re . + +PFX I Y 1 +PFX I 0 in . + +PFX U Y 1 +PFX U 0 un . + +PFX C Y 1 +PFX C 0 de . + +PFX E Y 1 +PFX E 0 dis . + +PFX F Y 1 +PFX F 0 con . + +PFX K Y 1 +PFX K 0 pro . + +SFX V N 2 +SFX V e ive e +SFX V 0 ive [^e] + +SFX N Y 3 +SFX N e ion e +SFX N y ication y +SFX N 0 en [^ey] + +SFX X Y 3 +SFX X e ions e +SFX X y ications y +SFX X 0 ens [^ey] + +SFX H N 2 +SFX H y ieth y +SFX H 0 th [^y] + +SFX Y Y 1 +SFX Y 0 ly . + +SFX G Y 2 +SFX G e ing e +SFX G 0 ing [^e] + +SFX J Y 2 +SFX J e ings e +SFX J 0 ings [^e] + +SFX D Y 4 +SFX D 0 d e +SFX D y ied [^aeiou]y +SFX D 0 ed [^ey] +SFX D 0 ed [aeiou]y + +SFX T N 4 +SFX T 0 st e +SFX T y iest [^aeiou]y +SFX T 0 est [aeiou]y +SFX T 0 est [^ey] + +SFX R Y 4 +SFX R 0 r e +SFX R y ier [^aeiou]y +SFX R 0 er [aeiou]y +SFX R 0 er [^ey] + +SFX Z Y 4 +SFX Z 0 rs e +SFX Z y iers [^aeiou]y +SFX Z 0 ers [aeiou]y +SFX Z 0 ers [^ey] + +SFX S Y 4 +SFX S y ies [^aeiou]y +SFX S 0 s [aeiou]y +SFX S 0 es [sxzh] +SFX S 0 s [^sxzhy] + +SFX P Y 3 +SFX P y iness [^aeiou]y +SFX P 0 ness [aeiou]y +SFX P 0 ness [^y] + +SFX M Y 1 +SFX M 0 's . + +SFX B Y 3 +SFX B 0 able [^aeiou] +SFX B 0 able ee +SFX B e able [^aeiou]e + +SFX L Y 1 +SFX L 0 ment . + +REP 88 +REP a ei +REP ei a +REP a ey +REP ey a +REP ai ie +REP ie ai +REP are air +REP are ear +REP are eir +REP air are +REP air ere +REP ere air +REP ere ear +REP ere eir +REP ear are +REP ear air +REP ear ere +REP eir are +REP eir ere +REP ch te +REP te ch +REP ch ti +REP ti ch +REP ch tu +REP tu ch +REP ch s +REP s ch +REP ch k +REP k ch +REP f ph +REP ph f +REP gh f +REP f gh +REP i igh +REP igh i +REP i uy +REP uy i +REP i ee +REP ee i +REP j di +REP di j +REP j gg +REP gg j +REP j ge +REP ge j +REP s ti +REP ti s +REP s ci +REP ci s +REP k cc +REP cc k +REP k qu +REP qu k +REP kw qu +REP o eau +REP eau o +REP o ew +REP ew o +REP oo ew +REP ew oo +REP ew ui +REP ui ew +REP oo ui +REP ui oo +REP ew u +REP u ew +REP oo u +REP u oo +REP u oe +REP oe u +REP u ieu +REP ieu u +REP ue ew +REP ew ue +REP uff ough +REP oo ieu +REP ieu oo +REP ier ear +REP ear ier +REP ear air +REP air ear +REP w qu +REP qu w +REP z ss +REP ss z +REP shun tion +REP shun sion +REP shun cion diff --git a/tools/test/travis-ci/doxy-spellchecker/en_phonet.dat b/tools/test/travis-ci/doxy-spellchecker/en_phonet.dat new file mode 100644 index 0000000000..3987f9c4e8 --- /dev/null +++ b/tools/test/travis-ci/doxy-spellchecker/en_phonet.dat @@ -0,0 +1 @@ +version 1.1 diff --git a/tools/test/travis-ci/doxy-spellchecker/ignore.en.pws b/tools/test/travis-ci/doxy-spellchecker/ignore.en.pws new file mode 100644 index 0000000000..d01b6d4f67 --- /dev/null +++ b/tools/test/travis-ci/doxy-spellchecker/ignore.en.pws @@ -0,0 +1,93 @@ +personal_ws-1.1 en 1600 utf-8 +_code_ +mbed +rtos +malloc +mutex +tx +rx +wi +fi +rr +sd +pc +vtable +nmemb +relloc +printf +arg +scanf +fclose +fputs +usb +or'd +MMmmpp +multithread +multithreaded +initializer +lookup +startup +unreferenced +singleshot +multishot +inlined +allocator +parameterized +XORed +unbuffered +sizeof +stringification +interoperability +memcpy +nack +mbit +retval +dequeue +assertation +destructor +constructor +ctor +dtor +dereference +ptr +templated +templatize +accessor +init +deleters +decrement +increment +deinitialize +deinitializes +atomicity +pointee +entrancy +Systick +noop +deassert +deasserts +deasserted +getter +setter +preallocated +ascii +IPv +param +struct +typedef +typedefs +onboard +enum +endian +emac +emacs +json +noncopyable +sendto +multicast +multicasts +singleshot +multishot +_doxy_ +sa +tparam diff --git a/tools/test/travis-ci/doxy-spellchecker/spell.sh b/tools/test/travis-ci/doxy-spellchecker/spell.sh new file mode 100755 index 0000000000..e56c33e646 --- /dev/null +++ b/tools/test/travis-ci/doxy-spellchecker/spell.sh @@ -0,0 +1,123 @@ +#!/bin/bash -eu +# mbed Microcontroller Library +# Copyright (c) 2018 ARM Limited +# SPDX-License-Identifier: Apache-2.0 + +set -o pipefail + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +ERRORS=0 + +# Loops use here strings to allow them to run in the main shell and modify the correct version of +# the error counter global variable +while read file; do + echo "${file}" + res=$(awk '/\/\*\*/,/\*\//' "${file}" | cut -d '/' -f2 | sed 's/0x[^ ]*//' | sed 's/[0-9]*//g') + + # Select a token to begin on, then a formating option such as strip all text between the start + # and end token, strip an entire line containing the start token, or strip a portion of a line + # containing the start token. Select an appropiate end token. The tokens and formats are index + # matched. + start_tokens=( "/@code" + "/addtogroup" + "defgroup" + "<" + "()" + ) + + formats=( 'strip_between' + 'strip_between' + 'strip_line' + 'strip_between_sameline' + 'strip_token' + ) + + end_tokens=( "/@endcode" + "/\*" + "" + ">" + "" + ) + + # Stripping strings between tokens P1-P2 and P3-P4 inclusively ran into issues depending + # on if the tokens were on the same line or not. + #_________________________________________ + # Don't remove this P1 remove me P2 + # Keep me + # P3 + # Remove me too please + # P4 + # Keep me too + # Still here P1 But this shouldn't be P2 + #_________________________________________ + # + # Opted for having two separate formats. In particular this formatting issue came up when + # trying to strip the code segments and template type arguments between '<, >' as the multiline + # sed command would strip the entire line, causing the removal string to span across the entire file + # when trying to match the next end token (above format when stripping everything between P1 and P2 + # would end up with just "Don't remove this" and the rest of the file stripped). + + for ((i=0;i<${#start_tokens[@]};++i)); do + filter="" + if [[ "${formats[i]}" == 'strip_between' ]]; then + filter=$(<<< "${res}" sed "${start_tokens[i]}/,${end_tokens[i]}/d") + elif [[ "${formats[i]}" == 'strip_between_sameline' ]]; then + filter=$(<<< "${res}" sed -e "s/"${start_tokens[i]}".*"${end_tokens[i]}"//") + elif [[ "${formats[i]}" == 'strip_line' ]]; then + filter=$(<<< "${res}" sed "/"${start_tokens[i]}"/ d") + elif [[ "${formats[i]}" == 'strip_token' ]]; then + filter=$(<<< "${res}" sed "s/"${start_tokens[i]}"//g") + fi + + if [ "${filter}" != "" ]; then + res=${filter} + fi + done + + if [ "${2:-}" == "-vv" ]; then + echo "${res}" + fi + + prev_err=("") + while read err; do + if [ $(echo "${res}" | grep "${err}" | wc -l) -eq $(grep "${err}" "${file}" | wc -l) ]; then + # Do not count all caps words as errors (RTOS, WTI, etc) or plural versions (APNs/MTD's) + if ! [[ ${err} =~ ^[A-Z]+$ || ${err} =~ ^[A-Z]+s$ || ${err} =~ ^[A-Z]+\'s$ ]]; then + + # Disregard camelcase/underscored words. Hex was stripped at the beginning + if ! echo "${err}" | grep --quiet -E '[a-z]{1,}[A-Z]|_'; then + + # The grep command to fetch the line numbers will report all instances, do not + # list repeated error words found from aspell in each file + if ! [[ ${prev_err[*]} =~ "${err}" ]]; then + prev_err+=("${err}") + + if [ ${#prev_err[@]} -eq 2 ]; then + echo "=================================" + echo "Errors: " + fi + + while read ln; do + echo "${ln} ${err}" + ERRORS=$((ERRORS + 1)) + done <<< "$(grep -n "${err}" "${file}" | cut -d ' ' -f1)" + fi + fi + fi + fi + done <<< "$(echo "${res}" | aspell list -C --ignore-case -p "${DIR}"/ignore.en.pws --local-data-dir "${DIR}")" + + if [ ${#prev_err[@]} -ne 1 ]; then + echo "_________________________________" + fi + +done < <(find "${1}" -type d -iname "*target*" -prune -o -name '*.h' -print) + +echo "----------------------------------------------------------------------------------" +echo "Total Errors Found: ${ERRORS}" + +if [ ${ERRORS} -ne 0 ]; then + echo "If any of the failed words should be considered valid please add them to the ignore.en.pws file"\ + "found in tools/test/scripts/doxy-spellchecker between the _code_ and _doxy_ tags." + exit 1 +fi diff --git a/tools/test_configs/6lowpanInterface_host.json b/tools/test_configs/6lowpanInterface_host.json index eb359ce40f..8fa01b90c4 100644 --- a/tools/test_configs/6lowpanInterface_host.json +++ b/tools/test_configs/6lowpanInterface_host.json @@ -7,6 +7,10 @@ "echo-server-port" : { "help" : "Port of echo server", "value" : "7" + }, + "echo-server-discard-port" : { + "help" : "Discard port of echo server", + "value" : "9" } }, "target_overrides": { diff --git a/tools/test_configs/6lowpanInterface_router.json b/tools/test_configs/6lowpanInterface_router.json index a9769eca85..8744b75bf8 100644 --- a/tools/test_configs/6lowpanInterface_router.json +++ b/tools/test_configs/6lowpanInterface_router.json @@ -7,6 +7,10 @@ "echo-server-port" : { "help" : "Port of echo server", "value" : "7" + }, + "echo-server-discard-port" : { + "help" : "Discard port of echo server", + "value" : "9" } }, "target_overrides": { diff --git a/tools/test_configs/ESP8266Interface.json b/tools/test_configs/ESP8266Interface.json index d313479814..12765af496 100644 --- a/tools/test_configs/ESP8266Interface.json +++ b/tools/test_configs/ESP8266Interface.json @@ -7,6 +7,10 @@ "echo-server-port" : { "help" : "Port of echo server", "value" : "7" + }, + "echo-server-discard-port" : { + "help" : "Discard port of echo server", + "value" : "9" } }, "target_overrides": { diff --git a/tools/test_configs/EthernetInterface.json b/tools/test_configs/EthernetInterface.json index 70253a2e9f..0a3684eb77 100644 --- a/tools/test_configs/EthernetInterface.json +++ b/tools/test_configs/EthernetInterface.json @@ -7,6 +7,10 @@ "echo-server-port" : { "help" : "Port of echo server", "value" : "7" + }, + "echo-server-discard-port" : { + "help" : "Discard port of echo server", + "value" : "9" } }, "target_overrides": { diff --git a/tools/test_configs/HeapBlockDeviceAndEthernetInterface.json b/tools/test_configs/HeapBlockDeviceAndEthernetInterface.json index 0969f7537a..4662fb2cdb 100644 --- a/tools/test_configs/HeapBlockDeviceAndEthernetInterface.json +++ b/tools/test_configs/HeapBlockDeviceAndEthernetInterface.json @@ -8,6 +8,10 @@ "help" : "Port of echo server", "value" : "7" }, + "echo-server-discard-port" : { + "help" : "Discard port of echo server", + "value" : "9" + }, "sim-blockdevice": { "help": "Simulated block device, requires sufficient heap", "macro_name": "MBED_TEST_SIM_BLOCKDEVICE", diff --git a/tools/test_configs/HeapBlockDeviceAndWifiInterface.json b/tools/test_configs/HeapBlockDeviceAndWifiInterface.json index b4d1f6f336..123d8e74c7 100644 --- a/tools/test_configs/HeapBlockDeviceAndWifiInterface.json +++ b/tools/test_configs/HeapBlockDeviceAndWifiInterface.json @@ -8,6 +8,10 @@ "help" : "Port of echo server", "value" : "7" }, + "echo-server-discard-port" : { + "help" : "Discard port of echo server", + "value" : "9" + }, "sim-blockdevice": { "help": "Simulated block device, requires sufficient heap", "macro_name": "MBED_TEST_SIM_BLOCKDEVICE", diff --git a/tools/test_configs/ISM43362Interface.json b/tools/test_configs/ISM43362Interface.json index defb21eb98..13934953a7 100644 --- a/tools/test_configs/ISM43362Interface.json +++ b/tools/test_configs/ISM43362Interface.json @@ -8,6 +8,10 @@ "help" : "Port of echo server", "value" : "7" }, + "echo-server-discard-port" : { + "help" : "Discard port of echo server", + "value" : "9" + }, "wifi-secure-ssid": { "help": "WiFi SSID for WPA2 secured network", "value": "\"SSID-SECURE\"" diff --git a/tools/test_configs/NanostackMACTester.json b/tools/test_configs/NanostackMACTester.json index f23f200df3..a3590ff2a2 100644 --- a/tools/test_configs/NanostackMACTester.json +++ b/tools/test_configs/NanostackMACTester.json @@ -12,8 +12,7 @@ "nanostack-hal.event_loop_thread_stack_size": 2000, "mbed-trace.enable": true, "nsapi.default-stack": "LWIP", - "target.device_has_add": ["802_15_4_PHY"], - "atmel-rf.provide-default": true + "target.device_has_add": ["802_15_4_PHY"] } } } diff --git a/tools/test_configs/SpwfSAInterface.json b/tools/test_configs/SpwfSAInterface.json index 776abcc901..526d1ab050 100644 --- a/tools/test_configs/SpwfSAInterface.json +++ b/tools/test_configs/SpwfSAInterface.json @@ -8,6 +8,10 @@ "help" : "Port of echo server", "value" : "7" }, + "echo-server-discard-port" : { + "help" : "Discard port of echo server", + "value" : "9" + }, "WIFI-TX" : { "help" : "Wifi TX pin", "value" : "D8" diff --git a/tools/test_configs/ThreadInterface_end_device.json b/tools/test_configs/ThreadInterface_end_device.json index 9e1b2d2c69..a708365aae 100644 --- a/tools/test_configs/ThreadInterface_end_device.json +++ b/tools/test_configs/ThreadInterface_end_device.json @@ -7,6 +7,10 @@ "echo-server-port" : { "help" : "Port of echo server", "value" : "7" + }, + "echo-server-discard-port" : { + "help" : "Discard port of echo server", + "value" : "9" } }, "target_overrides": { diff --git a/tools/test_configs/ThreadInterface_router.json b/tools/test_configs/ThreadInterface_router.json index 2d91762647..2e71293299 100644 --- a/tools/test_configs/ThreadInterface_router.json +++ b/tools/test_configs/ThreadInterface_router.json @@ -7,6 +7,10 @@ "echo-server-port" : { "help" : "Port of echo server", "value" : "7" + }, + "echo-server-discard-port" : { + "help" : "Discard port of echo server", + "value" : "9" } }, "target_overrides": { diff --git a/tools/test_configs/no_network.json b/tools/test_configs/no_network.json index ae7a9b028c..7a32b29917 100644 --- a/tools/test_configs/no_network.json +++ b/tools/test_configs/no_network.json @@ -7,6 +7,10 @@ "echo-server-port" : { "help" : "Port of echo server", "value" : null + }, + "echo-server-discard-port" : { + "help" : "Discard port of echo server", + "value" : null } }, "target_overrides": { diff --git a/tools/test_configs/target_configs.json b/tools/test_configs/target_configs.json index 8bcd9f56e3..5216eb41da 100644 --- a/tools/test_configs/target_configs.json +++ b/tools/test_configs/target_configs.json @@ -55,6 +55,10 @@ "default_test_configuration": "NO_NETWORK", "test_configurations": ["6LOWPAN_HOST", "6LOWPAN_ROUTER", "THREAD_END_DEVICE", "THREAD_ROUTER"] }, + "KW41Z": { + "default_test_configuration": "NO_NETWORK", + "test_configurations": ["6LOWPAN_HOST", "6LOWPAN_ROUTER", "THREAD_END_DEVICE", "THREAD_ROUTER"] + }, "TB_SENSE_12": { "default_test_configuration": "NO_NETWORK", "test_configurations": ["6LOWPAN_HOST", "6LOWPAN_ROUTER", "THREAD_END_DEVICE", "THREAD_ROUTER"] diff --git a/tools/toolchains/__init__.py b/tools/toolchains/__init__.py index 106fba98f7..e88fe8f02e 100644 --- a/tools/toolchains/__init__.py +++ b/tools/toolchains/__init__.py @@ -78,8 +78,8 @@ class mbedToolchain: "Cortex-M33": ["__CORTEX_M33", "ARM_MATH_ARMV8MML", "__CMSIS_RTOS", "__MBED_CMSIS_RTOS_CM"], "Cortex-M33F-NS": ["__CORTEX_M33", "ARM_MATH_ARMV8MML", "DOMAIN_NS=1", "__FPU_PRESENT=1U", "__CMSIS_RTOS", "__MBED_CMSIS_RTOS_CM"], "Cortex-M33F": ["__CORTEX_M33", "ARM_MATH_ARMV8MML", "__FPU_PRESENT=1U", "__CMSIS_RTOS", "__MBED_CMSIS_RTOS_CM"], - "Cortex-M33FD-NS": ["__CORTEX_M33", "ARM_MATH_ARMV8MML", "DOMAIN_NS=1", "__FPU_PRESENT=1U", "__CMSIS_RTOS", "__MBED_CMSIS_RTOS_CM"], - "Cortex-M33FD": ["__CORTEX_M33", "ARM_MATH_ARMV8MML", "__FPU_PRESENT=1U", "__CMSIS_RTOS", "__MBED_CMSIS_RTOS_CM"], + "Cortex-M33FD-NS": ["__CORTEX_M33", "ARM_MATH_ARMV8MML", "DOMAIN_NS=1", "__FPU_PRESENT=1U", "__CMSIS_RTOS", "__MBED_CMSIS_RTOS_CM", "__DSP_PRESENT=1U"], + "Cortex-M33FD": ["__CORTEX_M33", "ARM_MATH_ARMV8MML", "__FPU_PRESENT=1U", "__CMSIS_RTOS", "__MBED_CMSIS_RTOS_CM", "__DSP_PRESENT=1U"], } MBED_CONFIG_FILE_NAME="mbed_config.h" diff --git a/tools/toolchains/arm.py b/tools/toolchains/arm.py index 1fba7f06c5..eecd7cbbf8 100644 --- a/tools/toolchains/arm.py +++ b/tools/toolchains/arm.py @@ -453,12 +453,14 @@ class ARMC6(ARM_STD): "Cortex-M7F": "Cortex-M7.fp.sp", "Cortex-M7FD": "Cortex-M7.fp.dp", "Cortex-M23-NS": "Cortex-M23", - "Cortex-M33-NS": "Cortex-M33" }.get(target.core, target.core) + "Cortex-M33": "Cortex-M33.no_dsp.no_fp", + "Cortex-M33-NS": "Cortex-M33.no_dsp.no_fp", + "Cortex-M33F": "Cortex-M33.no_dsp", + "Cortex-M33F-NS": "Cortex-M33.no_dsp", + "Cortex-M33FD": "Cortex-M33", + "Cortex-M33FD-NS": "Cortex-M33"}.get(target.core, target.core) - if target.core.startswith("Cortex-M33"): - self.flags['asm'].append("--cpu=Cortex-M33.no_dsp.no_fp") - else : - self.flags['asm'].append("--cpu=%s" % asm_cpu) + self.flags['asm'].append("--cpu=%s" % asm_cpu) self.cc = ([join(TOOLCHAIN_PATHS["ARMC6"], "armclang")] + self.flags['common'] + self.flags['c'])