├── .editorconfig ├── .eslintrc.js ├── .github ├── ISSUE_TEMPLATE │ └── custom.md ├── renovate.json └── workflows │ ├── build.yml │ ├── labels.yml │ ├── release-latest.yml │ ├── release.yml │ ├── zoomin-publish-dev.yml │ ├── zoomin-publish.yml │ └── zoomin.yml ├── .gitignore ├── .husky └── pre-push ├── .vscode ├── launch.json └── tasks.json ├── Changelog.md ├── LICENSE ├── README.md ├── azure-pipelines.yml ├── doc ├── docs │ ├── index.md │ ├── installing.md │ ├── overview.md │ └── screenshots │ │ ├── rssi_overview.png │ │ ├── rssi_viewer_showcase.gif │ │ └── rssi_viewer_working.gif ├── mkdocs.yml └── zoomin │ ├── custom.properties │ └── tags.yml ├── fw ├── graviton_bootloader_v1.0.1-[nRF5_SDK_15.0.1-1.alpha_f76d012].zip ├── rssi-10040.hex ├── rssi-10056.hex ├── rssi-10059.hex └── src │ ├── .gitignore │ ├── bootstrap.sh │ ├── build.sh │ ├── rssi_cdc_acm │ ├── config │ │ └── app_usbd_string_config.h │ ├── main.c │ ├── pca10056 │ │ └── blank │ │ │ ├── arm5_no_packs │ │ │ └── rssi_cdc_acm.uvprojx │ │ │ └── config │ │ │ └── sdk_config.h │ └── pca10059 │ │ └── blank │ │ ├── arm5_no_packs │ │ └── rssi_cdc_acm.uvprojx │ │ └── config │ │ └── sdk_config.h │ ├── rssi_uart │ ├── main.c │ └── rssi_pca10040.uvprojx │ └── usdb.patch ├── jest.config.js ├── package-lock.json ├── package.json ├── resources ├── icon.icns ├── icon.ico ├── icon.png └── icon.svg ├── src ├── app │ ├── DeviceSelector.tsx │ ├── SidePanel │ │ ├── AnimationSpeed.tsx │ │ ├── ChannelRange.tsx │ │ ├── ControlButtons.tsx │ │ ├── Delay.tsx │ │ ├── LevelRange.tsx │ │ ├── MaxCount.tsx │ │ ├── SampleCount.tsx │ │ ├── SidePanel.tsx │ │ └── ToggleLed.tsx │ └── store.ts ├── features │ ├── Chart │ │ ├── Chart.tsx │ │ ├── alert.scss │ │ └── rssiColors.ts │ └── rssiDevice │ │ ├── createRssiDevice.ts │ │ ├── rssiDeviceEffects.ts │ │ ├── rssiDeviceSlice.ts │ │ └── useRssiDevice.ts └── index.tsx ├── svg.d.ts ├── tailwind.config.js └── tsconfig.json /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 4 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Nordic Semiconductor ASA 3 | * 4 | * SPDX-License-Identifier: LicenseRef-Nordic-4-Clause 5 | */ 6 | 7 | module.exports = require('@nordicsemiconductor/pc-nrfconnect-shared/config/eslintrc'); 8 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Custom issue template 3 | about: Please report bugs and feedback in DevZone 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | Please use the [Nordic DevZone](https://devzone.nordicsemi.com) portal to report bugs, questions or feedback in general. If you would like to suggest code changes, feel free to submit a pull request. 11 | -------------------------------------------------------------------------------- /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": ["config:recommended"], 4 | "labels": ["doc not required", "ui not required"], 5 | "packageRules": [ 6 | { 7 | "enabled": false, 8 | "matchPackageNames": ["!@nordicsemiconductor/pc-nrfconnect-shared"] 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches-ignore: 7 | - main # Skip for main because we build while releasing to "latest" 8 | 9 | jobs: 10 | build: 11 | uses: NordicSemiconductor/pc-nrfconnect-shared/.github/workflows/build-app.yml@main 12 | -------------------------------------------------------------------------------- /.github/workflows/labels.yml: -------------------------------------------------------------------------------- 1 | name: Check labels 2 | 3 | on: 4 | pull_request: 5 | types: 6 | - opened 7 | - labeled 8 | - unlabeled 9 | - synchronize 10 | 11 | jobs: 12 | check_labels: 13 | uses: NordicSemiconductor/pc-nrfconnect-shared/.github/workflows/labels.yml@main 14 | secrets: inherit 15 | -------------------------------------------------------------------------------- /.github/workflows/release-latest.yml: -------------------------------------------------------------------------------- 1 | name: Release to latest 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | 7 | jobs: 8 | release: 9 | uses: NordicSemiconductor/pc-nrfconnect-shared/.github/workflows/release-app.yml@main 10 | with: 11 | source: latest (internal) 12 | secrets: inherit 13 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | source: 7 | description: 'Source to release to' 8 | type: choice 9 | options: 10 | - release-test (internal) 11 | - test (internal) 12 | - official (external) 13 | ref: 14 | description: 15 | 'Ref (Tag, branch, commit SHA) to release. Default to the 16 | default branch' 17 | type: string 18 | 19 | jobs: 20 | release: 21 | uses: NordicSemiconductor/pc-nrfconnect-shared/.github/workflows/release-app.yml@main 22 | with: 23 | source: ${{ inputs.source }} 24 | ref: ${{ inputs.ref }} 25 | secrets: inherit 26 | -------------------------------------------------------------------------------- /.github/workflows/zoomin-publish-dev.yml: -------------------------------------------------------------------------------- 1 | name: Publish documentation to Zoomin dev 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - doc/docs 9 | workflow_dispatch: 10 | 11 | jobs: 12 | create-zoomin-bundle: 13 | name: Create Zoomin bundle 14 | uses: './.github/workflows/zoomin.yml' 15 | publish-zoomin-bundle: 16 | name: Publish Zoomin bundle to dev 17 | needs: create-zoomin-bundle 18 | runs-on: ubuntu-latest 19 | steps: 20 | - name: Get bundle 21 | uses: actions/download-artifact@v4 22 | with: 23 | name: nrf-connect-rssi-viewer 24 | - name: Upload documentation 25 | run: | 26 | # trust server 27 | mkdir -p ~/.ssh 28 | ssh-keyscan upload-v1.zoominsoftware.io >> ~/.ssh/known_hosts 29 | 30 | # prepare key 31 | echo "${{ secrets.ZOOMIN_KEY }}" > zoomin_key 32 | chmod 600 zoomin_key 33 | 34 | # upload bundle: 35 | sftp -v -i zoomin_key nordic@upload-v1.zoominsoftware.io <> ~/.ssh/known_hosts 24 | 25 | # prepare key 26 | echo "${{ secrets.ZOOMIN_KEY }}" > zoomin_key 27 | chmod 600 zoomin_key 28 | 29 | # upload bundle: 30 | sftp -v -i zoomin_key nordic@upload-v1.zoominsoftware.io </dev/null 2>&1 || { fatal "Unzip is not available"; } 49 | command -v curl >/dev/null 2>&1 || { fatal "Curl is not available"; } 50 | command -v git >/dev/null 2>&1 || { fatal "Git is not available"; } 51 | } 52 | 53 | # Check if the SDK folder already exist 54 | function sdk_exists () { 55 | if [[ -d $DL_LOCATION ]]; then 56 | # Erase the existing SDK folder if needed 57 | echo "> SDK folder is already available" 58 | read -p "> Do you want to erase the existing SDK folder [Y/n]? " -n 1 -r 59 | echo 60 | 61 | if [[ $REPLY =~ ^[Y]$ ]]; then 62 | echo "> Deleting existing SDK folder..." 63 | rm -rf $DL_LOCATION 64 | else 65 | return 0 # Exists 66 | fi 67 | fi 68 | 69 | # No SDK folder available 70 | return 1 71 | } 72 | 73 | # Download the SDK. Check if it is already available 74 | function sdk_download () { 75 | # First check if the SDK already exist 76 | if sdk_exists $1; then 77 | # SDK folder already available 78 | return 0 79 | fi 80 | 81 | if [[ -z "${SDK_NAME}" ]]; then 82 | fatal "Invalid SDK link" 83 | fi 84 | 85 | # Create the destination folder and download the SDK 86 | echo "> Downloading nRF SDK '${SDK_NAME}'..." 87 | 88 | mkdir -p $DL_LOCATION 89 | 90 | curl --progress-bar -o $DL_LOCATION/$SDK_FILE $SDK_LINK 91 | 92 | err_code=$? 93 | if [ "$err_code" != "0" ]; then 94 | fatal "Could not download SDK from '${SDK_LINK}'" 95 | fi 96 | 97 | echo "> Unzipping SDK..." 98 | unzip -q $DL_LOCATION/$SDK_FILE "${SDK_NAME}/components/**" "${SDK_NAME}/config/**" "${SDK_NAME}/modules/**" "${SDK_NAME}/integration/**" "${SDK_NAME}/external/**" -d $DL_LOCATION 99 | 100 | mv ${DL_LOCATION}/${SDK_NAME}/components ${DL_LOCATION}/ 101 | mv ${DL_LOCATION}/${SDK_NAME}/config ${DL_LOCATION}/ 102 | mv ${DL_LOCATION}/${SDK_NAME}/modules ${DL_LOCATION}/ 103 | mv ${DL_LOCATION}/${SDK_NAME}/integration ${DL_LOCATION}/ 104 | mv ${DL_LOCATION}/${SDK_NAME}/external ${DL_LOCATION}/ 105 | 106 | err_code=$? 107 | if [ "$err_code" != "0" ]; then 108 | fatal "Could not unzip the SDK file" 109 | fi 110 | 111 | echo "> Clean up. Removing SDK zip file..." 112 | rm $DL_LOCATION/$SDK_FILE 113 | 114 | err_code=$? 115 | if [ "$err_code" != "0" ]; then 116 | fatal "Could not remove the SDK zip file" 117 | fi 118 | 119 | # FIXME: unused files from the modified SDK should be deleted 120 | # Keep only the components and the connectivity application ? 121 | 122 | echo "Patching..." 123 | patch sdk/components/drivers_nrf/usbd/nrf_drv_usbd_errata.h usdb.patch 124 | } 125 | 126 | function main() { 127 | 128 | while [ "$1" != "" ]; do 129 | case $1 in 130 | -l | --link ) shift 131 | set_sdk_link $1 132 | ;; 133 | -d | --dest ) shift 134 | set_dl_location $1 135 | ;; 136 | -h | --help ) usage 137 | exit 138 | ;; 139 | * ) usage 140 | exit 1 141 | esac 142 | shift 143 | done 144 | 145 | check_requirements 146 | sdk_download 147 | 148 | echo "> SDK ready to use. Exit." 149 | exit 150 | } 151 | 152 | main "$@" 153 | -------------------------------------------------------------------------------- /fw/src/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ABS_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 4 | KEIL="c:/Keil_v5/UV4/UV4.exe" 5 | 6 | # Display an error message 7 | function error () { 8 | printf "\e[1;31m[ERROR] $1\e[0;0m\r\n" 9 | } 10 | 11 | # Display a fatal error and exit 12 | function fatal () { 13 | error "$@" 14 | exit 15 | } 16 | 17 | # Check if the required program are available 18 | function check_requirements () { 19 | command -v $KEIL >/dev/null 2>&1 || { fatal "KEIL is not available"; } 20 | } 21 | 22 | check_requirements 23 | 24 | $ABS_PATH/bootstrap.sh \ 25 | -l "http://developer.nordicsemi.com/nRF5_SDK/nRF5_SDK_v15.x.x/nRF5_SDK_15.0.0_a53641a.zip" \ 26 | -d "./sdk" 27 | 28 | command $KEIL -b rssi_cdc_acm/pca10059/blank/arm5_no_packs/rssi_cdc_acm.uvprojx 29 | command $KEIL -b rssi_cdc_acm/pca10056/blank/arm5_no_packs/rssi_cdc_acm.uvprojx 30 | # command $KEIL -b rssi_uart/rssi_pca10040.uvprojx 31 | -------------------------------------------------------------------------------- /fw/src/rssi_cdc_acm/config/app_usbd_string_config.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA 3 | * 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, this 10 | * list of conditions and the following disclaimer. 11 | * 12 | * 2. Redistributions in binary form, except as embedded into a Nordic 13 | * Semiconductor ASA integrated circuit in a product or a software update for 14 | * such product, must reproduce the above copyright notice, this list of 15 | * conditions and the following disclaimer in the documentation and/or other 16 | * materials provided with the distribution. 17 | * 18 | * 3. Neither the name of Nordic Semiconductor ASA nor the names of its 19 | * contributors may be used to endorse or promote products derived from this 20 | * software without specific prior written permission. 21 | * 22 | * 4. This software, with or without modification, must only be used with a 23 | * Nordic Semiconductor ASA integrated circuit. 24 | * 25 | * 5. Any software provided in binary form under this license must not be reverse 26 | * engineered, decompiled, modified and/or disassembled. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS 29 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 30 | * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 31 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE 32 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 33 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 34 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 37 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 | * 39 | */ 40 | #ifndef APP_USBD_STRING_CONFIG_H 41 | #define APP_USBD_STRING_CONFIG_H 42 | 43 | /** 44 | * @defgroup app_usbd_string_conf USBD string configuration 45 | * @ingroup app_usbd_string_desc 46 | * 47 | * @brief @tagAPI52840 Configuration of the string module that can be easily affected by the final 48 | * user. 49 | * @{ 50 | */ 51 | 52 | /** 53 | * @brief Supported languages identifiers 54 | * 55 | * Comma separated list of supported languages. 56 | */ 57 | #define APP_USBD_STRINGS_LANGIDS \ 58 | ((uint16_t)APP_USBD_LANG_ENGLISH | (uint16_t)APP_USBD_SUBLANG_ENGLISH_US) 59 | 60 | /** 61 | * @brief Manufacturer name string descriptor 62 | * 63 | * Comma separated list of manufacturer names for each defined language. 64 | * Use @ref APP_USBD_STRING_DESC macro to create string descriptor. 65 | * 66 | * The order of manufacturer names has to be the same like in 67 | * @ref APP_USBD_STRINGS_LANGIDS. 68 | */ 69 | #define APP_USBD_STRINGS_MANUFACTURER \ 70 | APP_USBD_STRING_DESC('N', 'o', 'r', 'd', 'i', 'c', ' ', 'S', 'e', 'm', 'i', 'c', 'o', 'n', 'd', 'u', 'c', 't', 'o', 'r') 71 | 72 | /** 73 | * @brief Define whether @ref APP_USBD_STRINGS_MANUFACTURER is created by @ref APP_USBD_STRING_DESC 74 | * or declared as global variable. 75 | * */ 76 | #define APP_USBD_STRINGS_MANUFACTURER_EXTERN 0 77 | 78 | /** 79 | * @brief Product name string descriptor 80 | * 81 | * List of product names defined the same way like in @ref APP_USBD_STRINGS_MANUFACTURER 82 | */ 83 | 84 | #ifdef BOARD_PCA10059 85 | #define APP_USBD_STRINGS_PRODUCT \ 86 | APP_USBD_STRING_DESC('n', 'R', 'F', '5', '2', ' ', 'R', 'S', 'S', 'I', ' ', 'D', 'o', 'n', 'g', 'l', 'e') 87 | #elif BOARD_PCA10056 88 | #define APP_USBD_STRINGS_PRODUCT \ 89 | APP_USBD_STRING_DESC('n', 'R', 'F', '5', '2', ' ', 'R', 'S', 'S', 'I', ' ', 'D', 'e', 'v', 'K', 'i', 't') 90 | #endif 91 | 92 | 93 | /** 94 | * @brief Define whether @ref APP_USBD_STRINGS_PRODUCT is created by @ref APP_USBD_STRING_DESC 95 | * or declared as global variable. 96 | * */ 97 | #define APP_USBD_STRINGS_PRODUCT_EXTERN 0 98 | 99 | /** 100 | * @brief Serial number string descriptor 101 | * 102 | * Create serial number string descriptor using @ref APP_USBD_STRING_DESC, 103 | * or configure it to point to any internal variable pointer filled with descriptor. 104 | * 105 | * @note 106 | * There is only one SERIAL number inside the library and it is Language independent. 107 | */ 108 | #define APP_USBD_STRING_SERIAL g_extern_serial_number 109 | 110 | /** 111 | * @brief Define whether @ref APP_USBD_STRING_SERIAL is created by @ref APP_USBD_STRING_DESC 112 | * or declared as global variable. 113 | * */ 114 | #define APP_USBD_STRING_SERIAL_EXTERN 1 115 | 116 | /** 117 | * @brief User strings default values 118 | * 119 | * This value stores all application specific user strings with its default initialization. 120 | * The setup is done by X-macros. 121 | * Expected macro parameters: 122 | * @code 123 | * X(mnemonic, [=str_idx], ...) 124 | * @endcode 125 | * - @c mnemonic: Mnemonic of the string descriptor that would be added to 126 | * @ref app_usbd_string_desc_idx_t enumerator. 127 | * - @c str_idx : String index value, may be set or left empty. 128 | * For example WinUSB driver requires descriptor to be present on 0xEE index. 129 | * Then use X(USBD_STRING_WINUSB, =0xEE, (APP_USBD_STRING_DESC(...))) 130 | * - @c ... : List of string descriptors for each defined language. 131 | */ 132 | #define APP_USBD_STRINGS_USER \ 133 | X(APP_USER_1, , APP_USBD_STRING_DESC('U', 's', 'e', 'r', ' ', '1')) 134 | 135 | /** @} */ 136 | #endif /* APP_USBD_STRING_CONFIG_H */ 137 | -------------------------------------------------------------------------------- /fw/src/rssi_cdc_acm/main.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA 3 | * 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, this 10 | * list of conditions and the following disclaimer. 11 | * 12 | * 2. Redistributions in binary form, except as embedded into a Nordic 13 | * Semiconductor ASA integrated circuit in a product or a software update for 14 | * such product, must reproduce the above copyright notice, this list of 15 | * conditions and the following disclaimer in the documentation and/or other 16 | * materials provided with the distribution. 17 | * 18 | * 3. Neither the name of Nordic Semiconductor ASA nor the names of its 19 | * contributors may be used to endorse or promote products derived from this 20 | * software without specific prior written permission. 21 | * 22 | * 4. This software, with or without modification, must only be used with a 23 | * Nordic Semiconductor ASA integrated circuit. 24 | * 25 | * 5. Any software provided in binary form under this license must not be reverse 26 | * engineered, decompiled, modified and/or disassembled. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS 29 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 30 | * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 31 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE 32 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 33 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 34 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 37 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 | * 39 | */ 40 | #include 41 | #include 42 | #include 43 | #include 44 | 45 | #include "nrf.h" 46 | #include "nrf_drv_usbd.h" 47 | #include "nrf_drv_clock.h" 48 | #include "nrf_gpio.h" 49 | #include "nrf_delay.h" 50 | #include "nrf_drv_power.h" 51 | #include "nrf_dfu_trigger_usb.h" 52 | 53 | #include "app_error.h" 54 | #include "app_fifo.h" 55 | #include "app_util.h" 56 | #include "app_usbd_core.h" 57 | #include "app_usbd.h" 58 | #include "app_usbd_serial_num.h" 59 | #include "app_usbd_string_desc.h" 60 | #include "app_usbd_cdc_acm.h" 61 | #include "app_usbd_nrf_dfu_trigger.h" 62 | #include "app_timer.h" 63 | 64 | #include "boards.h" 65 | 66 | #define FREQ_ADV_CHANNEL_37 (2) /**TASKS_START = 1; 231 | 232 | // Start 16 MHz crystal oscillator 233 | NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; 234 | NRF_CLOCK->TASKS_HFCLKSTART = 1; 235 | while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0); 236 | } 237 | 238 | #define WAIT_FOR( m ) do { while (!m); m = 0; } while(0) 239 | 240 | uint8_t rssi_measurer_scan_channel(uint8_t channel_number) 241 | { 242 | uint8_t sample; 243 | 244 | NRF_RADIO->FREQUENCY = channel_number; 245 | NRF_RADIO->TASKS_RXEN = 1; 246 | 247 | WAIT_FOR(NRF_RADIO->EVENTS_READY); 248 | NRF_RADIO->TASKS_RSSISTART = 1; 249 | WAIT_FOR(NRF_RADIO->EVENTS_RSSIEND); 250 | 251 | sample = 127 & NRF_RADIO->RSSISAMPLE; 252 | 253 | NRF_RADIO->TASKS_DISABLE = 1; 254 | WAIT_FOR(NRF_RADIO->EVENTS_DISABLED); 255 | 256 | return sample; 257 | } 258 | 259 | uint8_t rssi_measurer_scan_channel_repeat(uint8_t channel_number) 260 | { 261 | uint8_t sample; 262 | uint8_t max = RSSI_NO_SIGNAL; 263 | for (int i = 0; i <= scan_repeat_times; ++i) { 264 | sample = rssi_measurer_scan_channel(channel_number); 265 | // taking minimum since sample = -dBm. 266 | max = MIN(sample, max); 267 | } 268 | return max; 269 | } 270 | 271 | void rssi_measurer_start_timer() 272 | { 273 | APP_ERROR_CHECK(app_timer_start(m_rssi_timer, APP_TIMER_TICKS(sweep_delay), NULL)); 274 | } 275 | 276 | void rssi_measurer_timeout_handler(void* p_context) 277 | { 278 | uint8_t sample; 279 | if (scan_ble_adv) { 280 | sample = rssi_measurer_scan_channel_repeat(FREQ_ADV_CHANNEL_37); 281 | queue_packet(FREQ_ADV_CHANNEL_37, sample); 282 | sample = rssi_measurer_scan_channel_repeat(FREQ_ADV_CHANNEL_38); 283 | queue_packet(FREQ_ADV_CHANNEL_38, sample); 284 | sample = rssi_measurer_scan_channel_repeat(FREQ_ADV_CHANNEL_39); 285 | queue_packet(FREQ_ADV_CHANNEL_39, sample); 286 | } else { 287 | for (uint8_t i = FIRST_CHANNEL; i <= LAST_CHANNEL; i++) 288 | { 289 | sample = rssi_measurer_scan_channel_repeat(i); 290 | queue_packet(i, sample); 291 | } 292 | } 293 | 294 | rssi_measurer_start_timer(); 295 | } 296 | 297 | void set_sweep_delay(uint32_t sd) 298 | { 299 | sweep_delay = sd; 300 | } 301 | 302 | void stop() 303 | { 304 | app_fifo_flush(&m_fifo); 305 | APP_ERROR_CHECK(app_timer_stop(m_rssi_timer)); 306 | } 307 | 308 | void start() 309 | { 310 | stop(); 311 | memset(input, 32, 0); 312 | tx_done = true; 313 | rssi_measurer_start_timer(); 314 | } 315 | 316 | void get_line() 317 | { 318 | char* q = input; 319 | if (strncmp(q, "set ", 4) == 0) { 320 | q += 4; 321 | if (strncmp(q, "delay ", 6) == 0) { 322 | q += 6; 323 | int d = atoi(q); 324 | set_sweep_delay(MAX(1, MIN(d, 1000))); 325 | return; 326 | } 327 | if (strncmp(q, "repeat ", 7) == 0) { 328 | q += 7; 329 | int d = atoi(q); 330 | scan_repeat_times = MAX(1, MIN(d, 100)); 331 | return; 332 | } 333 | return; 334 | } 335 | if (strncmp(q, "start", 5) == 0) { 336 | start(); 337 | return; 338 | } 339 | if (strncmp(q, "stop", 4) == 0) { 340 | stop(); 341 | return; 342 | } 343 | if (strncmp(q, "scan adv ", 9) == 0) { 344 | q += 9; 345 | if (strncmp(q, "true", 4) == 0) { 346 | set_scan_ble_adv(true); 347 | return; 348 | } 349 | if (strncmp(q, "false", 5) == 0) { 350 | set_scan_ble_adv(false); 351 | } 352 | return; 353 | } 354 | if (strncmp(q, "led", 3) == 0) { 355 | my_led_invert(LED_CDC_ACM_USER); 356 | return; 357 | } 358 | } 359 | 360 | void one_byte_received(char c) 361 | { 362 | static char* p = input; 363 | *(p++) = c; 364 | if (c == '\0' || c == '\r') { 365 | *p = '\0'; 366 | get_line(); 367 | memset(input, 32, 0); 368 | p = input; 369 | } 370 | } 371 | 372 | /** 373 | * @brief User event handler @ref app_usbd_cdc_acm_user_ev_handler_t 374 | * */ 375 | static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst, 376 | app_usbd_cdc_acm_user_event_t event) 377 | { 378 | static char acm_buffer[32]; 379 | ret_code_t ret; 380 | 381 | switch (event) 382 | { 383 | case APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN: 384 | { 385 | my_led_set(LED_CDC_ACM_OPEN, 1); 386 | my_led_set(LED_CDC_ACM_USER, 0); 387 | app_usbd_cdc_acm_read(&m_app_cdc_acm, acm_buffer, 1); 388 | break; 389 | } 390 | case APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE: 391 | { 392 | my_led_set(LED_CDC_ACM_OPEN, 0); 393 | my_led_set(LED_CDC_ACM_USER, 0); 394 | stop(); 395 | 396 | break; 397 | } 398 | case APP_USBD_CDC_ACM_USER_EVT_TX_DONE: 399 | { 400 | tx_done = true; 401 | send_more(); 402 | 403 | break; 404 | } 405 | case APP_USBD_CDC_ACM_USER_EVT_RX_DONE: 406 | { 407 | do { 408 | one_byte_received(acm_buffer[0]); 409 | ret = app_usbd_cdc_acm_read(&m_app_cdc_acm, acm_buffer, 1); 410 | } while (ret == NRF_SUCCESS); 411 | 412 | break; 413 | } 414 | default: 415 | break; 416 | } 417 | } 418 | 419 | void enable_reset() { 420 | if (((NRF_UICR->PSELRESET[0] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos)) || 421 | ((NRF_UICR->PSELRESET[1] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos))){ 422 | NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos; 423 | while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} 424 | NRF_UICR->PSELRESET[0] = 18; 425 | while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} 426 | NRF_UICR->PSELRESET[1] = 18; 427 | while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} 428 | NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos; 429 | while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} 430 | NVIC_SystemReset(); 431 | } 432 | } 433 | 434 | /** 435 | * Function for configuring UICR_REGOUT0 register 436 | * to set GPIO output voltage to 3.0V. 437 | */ 438 | static void gpio_output_voltage_setup(void) 439 | { 440 | // Configure UICR_REGOUT0 register only if it is set to default value. 441 | if ((NRF_UICR->REGOUT0 & UICR_REGOUT0_VOUT_Msk) == 442 | (UICR_REGOUT0_VOUT_DEFAULT << UICR_REGOUT0_VOUT_Pos)) 443 | { 444 | NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen; 445 | while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} 446 | 447 | NRF_UICR->REGOUT0 = (NRF_UICR->REGOUT0 & ~((uint32_t)UICR_REGOUT0_VOUT_Msk)) | 448 | (UICR_REGOUT0_VOUT_3V0 << UICR_REGOUT0_VOUT_Pos); 449 | 450 | NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren; 451 | while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} 452 | 453 | // System reset is needed to update UICR registers. 454 | NVIC_SystemReset(); 455 | } 456 | } 457 | 458 | void power_init() 459 | { 460 | if (board == DONGLE) { 461 | if (NRF_POWER->MAINREGSTATUS & 462 | (POWER_MAINREGSTATUS_MAINREGSTATUS_High << POWER_MAINREGSTATUS_MAINREGSTATUS_Pos)) 463 | { 464 | gpio_output_voltage_setup(); 465 | } 466 | } 467 | } 468 | 469 | int main(void) 470 | { 471 | my_leds_init(); 472 | 473 | static const app_usbd_config_t usbd_config = { 474 | .ev_state_proc = usbd_user_ev_handler 475 | }; 476 | 477 | power_init(); 478 | enable_reset(); 479 | 480 | APP_ERROR_CHECK(nrf_drv_clock_init()); 481 | 482 | nrf_drv_clock_lfclk_request(NULL); 483 | 484 | while(!nrf_drv_clock_lfclk_is_running()); 485 | 486 | app_usbd_serial_num_generate(); 487 | APP_ERROR_CHECK(app_usbd_init(&usbd_config)); 488 | 489 | APP_ERROR_CHECK(nrf_dfu_trigger_usb_init()); 490 | 491 | app_usbd_class_inst_t const * class_cdc_acm = app_usbd_cdc_acm_class_inst_get(&m_app_cdc_acm); 492 | APP_ERROR_CHECK(app_usbd_class_append(class_cdc_acm)); 493 | 494 | APP_ERROR_CHECK(app_usbd_power_events_enable()); 495 | 496 | APP_ERROR_CHECK(app_fifo_init(&m_fifo, m_fifo_buf, M_FIFO_BUFSIZE)); 497 | 498 | APP_ERROR_CHECK(app_timer_init()); 499 | APP_ERROR_CHECK(app_timer_create(&m_rssi_timer, APP_TIMER_MODE_SINGLE_SHOT, rssi_measurer_timeout_handler)); 500 | 501 | rssi_measurer_configure_radio(); 502 | 503 | while (true) 504 | { 505 | while (app_usbd_event_queue_process()) 506 | ; 507 | } 508 | } 509 | 510 | /** @} */ 511 | -------------------------------------------------------------------------------- /fw/src/rssi_cdc_acm/pca10056/blank/arm5_no_packs/rssi_cdc_acm.uvprojx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 2.1 5 | 6 |
### uVision Project, (C) Keil Software
7 | 8 | 9 | 10 | nrf52840_xxaa 11 | 0x4 12 | ARM-ADS 13 | 5060061::V5.06 update 1 (build 61)::ARMCC 14 | 15 | 16 | nRF52840_xxAA 17 | Nordic Semiconductor 18 | NordicSemiconductor.nRF_DeviceFamilyPack.8.16.0 19 | http://developer.nordicsemi.com/nRF5_SDK/pieces/nRF_DeviceFamilyPack/ 20 | IROM(0x00000000,0x80000) IRAM(0x20000000,0x10000) CPUTYPE("Cortex-M4") FPU2 CLOCK(64000000) ELITTLE 21 | 22 | 23 | 24 | 0 25 | $$Device:nRF52832_xxAA$Device\Include\nrf.h 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | ..\..\..\..\sdk\modules\nrfx\mdk\nrf52840.svd 36 | 0 37 | 0 38 | 39 | 40 | 41 | 42 | 43 | 44 | 0 45 | 0 46 | 0 47 | 0 48 | 1 49 | 50 | .\_build\ 51 | rssi-10056 52 | 1 53 | 0 54 | 1 55 | 1 56 | 1 57 | .\_build\ 58 | 1 59 | 0 60 | 0 61 | 62 | 0 63 | 0 64 | 65 | 66 | 0 67 | 0 68 | 0 69 | 0 70 | 71 | 72 | 0 73 | 0 74 | 75 | 76 | 0 77 | 0 78 | 0 79 | 0 80 | 81 | 82 | 0 83 | 0 84 | 85 | 86 | 0 87 | 0 88 | 0 89 | 0 90 | 91 | 0 92 | 93 | 94 | 95 | 0 96 | 0 97 | 0 98 | 0 99 | 0 100 | 1 101 | 0 102 | 0 103 | 0 104 | 0 105 | 3 106 | 107 | 108 | 1 109 | 110 | 111 | 112 | 113 | 114 | 115 | SARMCM3.DLL 116 | -MPU 117 | TCM.DLL 118 | -pCM4 119 | 120 | 121 | 122 | 1 123 | 0 124 | 0 125 | 0 126 | 16 127 | 128 | 129 | 130 | 131 | 1 132 | 0 133 | 0 134 | 1 135 | 1 136 | 4096 137 | 138 | 1 139 | BIN\UL2CM3.DLL 140 | "" () 141 | 142 | 143 | 144 | 145 | 0 146 | 147 | 148 | 149 | 0 150 | 1 151 | 1 152 | 1 153 | 1 154 | 1 155 | 1 156 | 1 157 | 0 158 | 1 159 | 1 160 | 0 161 | 1 162 | 1 163 | 0 164 | 0 165 | 1 166 | 1 167 | 1 168 | 1 169 | 1 170 | 1 171 | 1 172 | 1 173 | 1 174 | 0 175 | 0 176 | "Cortex-M4" 177 | 178 | 0 179 | 0 180 | 0 181 | 1 182 | 1 183 | 0 184 | 0 185 | 2 186 | 0 187 | 0 188 | 8 189 | 1 190 | 0 191 | 0 192 | 0 193 | 3 194 | 3 195 | 0 196 | 0 197 | 0 198 | 0 199 | 0 200 | 0 201 | 0 202 | 0 203 | 0 204 | 0 205 | 1 206 | 0 207 | 0 208 | 0 209 | 0 210 | 1 211 | 0 212 | 213 | 214 | 0 215 | 0x0 216 | 0x0 217 | 218 | 219 | 0 220 | 0x0 221 | 0x0 222 | 223 | 224 | 0 225 | 0x0 226 | 0x0 227 | 228 | 229 | 0 230 | 0x0 231 | 0x0 232 | 233 | 234 | 0 235 | 0x0 236 | 0x0 237 | 238 | 239 | 0 240 | 0x0 241 | 0x0 242 | 243 | 244 | 0 245 | 0x20000000 246 | 0x10000 247 | 248 | 249 | 1 250 | 0x0 251 | 0x80000 252 | 253 | 254 | 0 255 | 0x0 256 | 0x0 257 | 258 | 259 | 1 260 | 0x0 261 | 0x0 262 | 263 | 264 | 1 265 | 0x0 266 | 0x0 267 | 268 | 269 | 1 270 | 0x0 271 | 0x0 272 | 273 | 274 | 1 275 | 0x1000 276 | 0xff000 277 | 278 | 279 | 1 280 | 0x0 281 | 0x0 282 | 283 | 284 | 0 285 | 0x0 286 | 0x0 287 | 288 | 289 | 0 290 | 0x0 291 | 0x0 292 | 293 | 294 | 0 295 | 0x0 296 | 0x0 297 | 298 | 299 | 0 300 | 0x20000008 301 | 0x3fff8 302 | 303 | 304 | 0 305 | 0x0 306 | 0x0 307 | 308 | 309 | 310 | 311 | 312 | 1 313 | 1 314 | 0 315 | 0 316 | 1 317 | 0 318 | 0 319 | 0 320 | 0 321 | 0 322 | 0 323 | 0 324 | 0 325 | 1 326 | 0 327 | 0 328 | 0 329 | 0 330 | 0 331 | 332 | --reduce_paths 333 | BOARD_PCA10056 FLOAT_ABI_HARD NRF52840_XXAA SWI_DISABLE0 DEBUG 334 | 335 | ..\..\..\config;..\..\..\..\sdk\components;..\..\..\..\sdk\components\boards;..\..\..\..\sdk\components\device;..\..\..\..\sdk\components\drivers_nrf\nrf_soc_nosd;..\..\..\..\sdk\components\drivers_nrf\usbd;..\..\..\..\sdk\components\libraries\atomic;..\..\..\..\sdk\components\libraries\atomic_fifo;..\..\..\..\sdk\components\libraries\balloc;..\..\..\..\sdk\components\libraries\bsp;..\..\..\..\sdk\components\libraries\button;..\..\..\..\sdk\components\libraries\delay;..\..\..\..\sdk\components\libraries\experimental_log;..\..\..\..\sdk\components\libraries\experimental_log\src;..\..\..\..\sdk\components\libraries\experimental_memobj;..\..\..\..\sdk\components\libraries\experimental_section_vars;..\..\..\..\sdk\components\libraries\fifo;..\..\..\..\sdk\components\libraries\hardfault;..\..\..\..\sdk\components\libraries\hardfault\nrf52;..\..\..\..\sdk\components\libraries\scheduler;..\..\..\..\sdk\components\libraries\strerror;..\..\..\..\sdk\components\libraries\timer;..\..\..\..\sdk\components\libraries\uart;..\..\..\..\sdk\components\libraries\usbd;..\..\..\..\sdk\components\libraries\usbd\class\cdc;..\..\..\..\sdk\components\libraries\usbd\class\cdc\acm;..\..\..\..\sdk\components\libraries\usbd\config;..\..\..\..\sdk\components\libraries\util;..\..\..;..\..\..\..\sdk\external\fprintf;..\..\..\..\sdk\external\protothreads;..\..\..\..\sdk\external\protothreads\pt-1.4;..\..\..\..\sdk\external\segger_rtt;..\..\..\..\sdk\integration\nrfx;..\..\..\..\sdk\integration\nrfx\legacy;..\..\..\..\sdk\modules\nrfx;..\..\..\..\sdk\modules\nrfx\drivers\include;..\..\..\..\sdk\modules\nrfx\hal;..\..\..\..\sdk\modules\nrfx\mdk;..\config;..\..\..\..\sdk\components\libraries\simple_timer;..\..\..\..\sdk\components\libraries\usbd\class\nrf_dfu_trigger;..\..\..\..\sdk\components\libraries\block_dev;..\..\..\..\sdk\components\libraries\usb_dfu_trigger;..\..\..\..\sdk\components\libraries\bootloader\dfu 336 | 337 | 338 | 339 | 1 340 | 0 341 | 0 342 | 0 343 | 0 344 | 0 345 | 0 346 | 0 347 | 0 348 | 349 | --cpreproc_opts=-DBOARD_PCA10056,-DCONFIG_GPIO_AS_PINRESET,-DFLOAT_ABI_HARD,-DNRF52840_XXAA,-DSWI_DISABLE0 350 | BOARD_PCA10056 CONFIG_GPIO_AS_PINRESET FLOAT_ABI_HARD NRF52840_XXAA SWI_DISABLE0 351 | 352 | ..\..\..\config;..\..\..\..\sdk\components;..\..\..\..\sdk\components\boards;..\..\..\..\sdk\components\device;..\..\..\..\sdk\components\drivers_nrf\nrf_soc_nosd;..\..\..\..\sdk\components\drivers_nrf\usbd;..\..\..\..\sdk\components\libraries\atomic;..\..\..\..\sdk\components\libraries\atomic_fifo;..\..\..\..\sdk\components\libraries\balloc;..\..\..\..\sdk\components\libraries\bsp;..\..\..\..\sdk\components\libraries\button;..\..\..\..\sdk\components\libraries\delay;..\..\..\..\sdk\components\libraries\experimental_log;..\..\..\..\sdk\components\libraries\experimental_log\src;..\..\..\..\sdk\components\libraries\experimental_memobj;..\..\..\..\sdk\components\libraries\experimental_section_vars;..\..\..\..\sdk\components\libraries\fifo;..\..\..\..\sdk\components\libraries\hardfault;..\..\..\..\sdk\components\libraries\hardfault\nrf52;..\..\..\..\sdk\components\libraries\scheduler;..\..\..\..\sdk\components\libraries\strerror;..\..\..\..\sdk\components\libraries\timer;..\..\..\..\sdk\components\libraries\uart;..\..\..\..\sdk\components\libraries\usbd;..\..\..\..\sdk\components\libraries\usbd\class\cdc;..\..\..\..\sdk\components\libraries\usbd\class\cdc\acm;..\..\..\..\sdk\components\libraries\usbd\config;..\..\..\..\sdk\components\libraries\util;..\..\..;..\..\..\..\sdk\external\fprintf;..\..\..\..\sdk\external\protothreads;..\..\..\..\sdk\external\protothreads\pt-1.4;..\..\..\..\sdk\external\segger_rtt;..\..\..\..\sdk\integration\nrfx;..\..\..\..\sdk\integration\nrfx\legacy;..\..\..\..\sdk\modules\nrfx;..\..\..\..\sdk\modules\nrfx\drivers\include;..\..\..\..\sdk\modules\nrfx\hal;..\..\..\..\sdk\modules\nrfx\mdk;..\config 353 | 354 | 355 | 356 | 1 357 | 0 358 | 0 359 | 0 360 | 1 361 | 0 362 | 0x00000000 363 | 0x20000000 364 | 365 | 366 | 367 | 368 | --diag_suppress 6330 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | Application 377 | 378 | 379 | main.c 380 | 1 381 | ..\..\..\main.c 382 | 383 | 384 | sdk_config.h 385 | 5 386 | ..\config\sdk_config.h 387 | 388 | 389 | 390 | 391 | Board Definition 392 | 393 | 394 | boards.c 395 | 1 396 | ..\..\..\..\sdk\components\boards\boards.c 397 | 398 | 399 | 400 | 401 | Board Support 402 | 403 | 404 | bsp.c 405 | 1 406 | ..\..\..\..\sdk\components\libraries\bsp\bsp.c 407 | 408 | 409 | bsp_nfc.c 410 | 1 411 | ..\..\..\..\sdk\components\libraries\bsp\bsp_nfc.c 412 | 413 | 414 | 415 | 416 | nRF_Drivers 417 | 418 | 419 | nrf_drv_clock.c 420 | 1 421 | ..\..\..\..\sdk\integration\nrfx\legacy\nrf_drv_clock.c 422 | 423 | 424 | nrf_drv_power.c 425 | 1 426 | ..\..\..\..\sdk\integration\nrfx\legacy\nrf_drv_power.c 427 | 428 | 429 | nrf_drv_uart.c 430 | 1 431 | ..\..\..\..\sdk\integration\nrfx\legacy\nrf_drv_uart.c 432 | 433 | 434 | nrf_drv_usbd.c 435 | 1 436 | ..\..\..\..\sdk\components\drivers_nrf\usbd\nrf_drv_usbd.c 437 | 438 | 439 | nrf_nvic.c 440 | 1 441 | ..\..\..\..\sdk\components\drivers_nrf\nrf_soc_nosd\nrf_nvic.c 442 | 443 | 444 | nrf_soc.c 445 | 1 446 | ..\..\..\..\sdk\components\drivers_nrf\nrf_soc_nosd\nrf_soc.c 447 | 448 | 449 | nrfx_clock.c 450 | 1 451 | ..\..\..\..\sdk\modules\nrfx\drivers\src\nrfx_clock.c 452 | 453 | 454 | nrfx_gpiote.c 455 | 1 456 | ..\..\..\..\sdk\modules\nrfx\drivers\src\nrfx_gpiote.c 457 | 458 | 459 | nrfx_power.c 460 | 1 461 | ..\..\..\..\sdk\modules\nrfx\drivers\src\nrfx_power.c 462 | 463 | 464 | nrfx_power_clock.c 465 | 1 466 | ..\..\..\..\sdk\modules\nrfx\drivers\src\nrfx_power_clock.c 467 | 468 | 469 | nrfx_prs.c 470 | 1 471 | ..\..\..\..\sdk\modules\nrfx\drivers\src\prs\nrfx_prs.c 472 | 473 | 474 | nrfx_systick.c 475 | 1 476 | ..\..\..\..\sdk\modules\nrfx\drivers\src\nrfx_systick.c 477 | 478 | 479 | nrfx_uart.c 480 | 1 481 | ..\..\..\..\sdk\modules\nrfx\drivers\src\nrfx_uart.c 482 | 483 | 484 | nrfx_uarte.c 485 | 1 486 | ..\..\..\..\sdk\modules\nrfx\drivers\src\nrfx_uarte.c 487 | 488 | 489 | nrfx_timer.c 490 | 1 491 | ..\..\..\..\sdk\modules\nrfx\drivers\src\nrfx_timer.c 492 | 493 | 494 | 495 | 496 | nRF_Libraries 497 | 498 | 499 | app_button.c 500 | 1 501 | ..\..\..\..\sdk\components\libraries\button\app_button.c 502 | 503 | 504 | app_error.c 505 | 1 506 | ..\..\..\..\sdk\components\libraries\util\app_error.c 507 | 508 | 509 | app_error_handler_keil.c 510 | 1 511 | ..\..\..\..\sdk\components\libraries\util\app_error_handler_keil.c 512 | 513 | 514 | app_error_weak.c 515 | 1 516 | ..\..\..\..\sdk\components\libraries\util\app_error_weak.c 517 | 518 | 519 | app_fifo.c 520 | 1 521 | ..\..\..\..\sdk\components\libraries\fifo\app_fifo.c 522 | 523 | 524 | app_scheduler.c 525 | 1 526 | ..\..\..\..\sdk\components\libraries\scheduler\app_scheduler.c 527 | 528 | 529 | app_timer.c 530 | 1 531 | ..\..\..\..\sdk\components\libraries\timer\app_timer.c 532 | 533 | 534 | app_uart_fifo.c 535 | 1 536 | ..\..\..\..\sdk\components\libraries\uart\app_uart_fifo.c 537 | 538 | 539 | app_usbd.c 540 | 1 541 | ..\..\..\..\sdk\components\libraries\usbd\app_usbd.c 542 | 543 | 544 | app_usbd_cdc_acm.c 545 | 1 546 | ..\..\..\..\sdk\components\libraries\usbd\class\cdc\acm\app_usbd_cdc_acm.c 547 | 548 | 549 | app_usbd_core.c 550 | 1 551 | ..\..\..\..\sdk\components\libraries\usbd\app_usbd_core.c 552 | 553 | 554 | app_usbd_string_desc.c 555 | 1 556 | ..\..\..\..\sdk\components\libraries\usbd\app_usbd_string_desc.c 557 | 558 | 559 | app_util_platform.c 560 | 1 561 | ..\..\..\..\sdk\components\libraries\util\app_util_platform.c 562 | 563 | 564 | hardfault_handler_keil.c 565 | 1 566 | ..\..\..\..\sdk\components\libraries\hardfault\nrf52\handler\hardfault_handler_keil.c 567 | 568 | 569 | hardfault_implementation.c 570 | 1 571 | ..\..\..\..\sdk\components\libraries\hardfault\hardfault_implementation.c 572 | 573 | 574 | nrf_assert.c 575 | 1 576 | ..\..\..\..\sdk\components\libraries\util\nrf_assert.c 577 | 578 | 579 | nrf_atfifo.c 580 | 1 581 | ..\..\..\..\sdk\components\libraries\atomic_fifo\nrf_atfifo.c 582 | 583 | 584 | nrf_balloc.c 585 | 1 586 | ..\..\..\..\sdk\components\libraries\balloc\nrf_balloc.c 587 | 588 | 589 | nrf_fprintf.c 590 | 1 591 | ..\..\..\..\sdk\external\fprintf\nrf_fprintf.c 592 | 593 | 594 | nrf_fprintf_format.c 595 | 1 596 | ..\..\..\..\sdk\external\fprintf\nrf_fprintf_format.c 597 | 598 | 599 | nrf_memobj.c 600 | 1 601 | ..\..\..\..\sdk\components\libraries\experimental_memobj\nrf_memobj.c 602 | 603 | 604 | nrf_strerror.c 605 | 1 606 | ..\..\..\..\sdk\components\libraries\strerror\nrf_strerror.c 607 | 608 | 609 | app_simple_timer.c 610 | 1 611 | ..\..\..\..\sdk\components\libraries\simple_timer\app_simple_timer.c 612 | 613 | 614 | app_usbd_nrf_dfu_trigger.c 615 | 1 616 | ..\..\..\..\sdk\components\libraries\usbd\class\nrf_dfu_trigger\app_usbd_nrf_dfu_trigger.c 617 | 618 | 619 | nrf_atomic.c 620 | 1 621 | ..\..\..\..\sdk\components\libraries\atomic\nrf_atomic.c 622 | 623 | 624 | app_usbd_serial_num.c 625 | 1 626 | ..\..\..\..\sdk\components\libraries\usbd\app_usbd_serial_num.c 627 | 628 | 629 | nrf_dfu_trigger_usb.c 630 | 1 631 | ..\..\..\..\sdk\components\libraries\bootloader\dfu\nrf_dfu_trigger_usb.c 632 | 633 | 634 | 635 | 636 | ::CMSIS 637 | 638 | 639 | ::Device 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | RTE\Device\nRF52840_xxAA\arm_startup_nrf52840.s 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | RTE\Device\nRF52840_xxAA\system_nrf52840.c 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 |
697 | -------------------------------------------------------------------------------- /fw/src/rssi_uart/main.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA 3 | * 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, this 10 | * list of conditions and the following disclaimer. 11 | * 12 | * 2. Redistributions in binary form, except as embedded into a Nordic 13 | * Semiconductor ASA integrated circuit in a product or a software update for 14 | * such product, must reproduce the above copyright notice, this list of 15 | * conditions and the following disclaimer in the documentation and/or other 16 | * materials provided with the distribution. 17 | * 18 | * 3. Neither the name of Nordic Semiconductor ASA nor the names of its 19 | * contributors may be used to endorse or promote products derived from this 20 | * software without specific prior written permission. 21 | * 22 | * 4. This software, with or without modification, must only be used with a 23 | * Nordic Semiconductor ASA integrated circuit. 24 | * 25 | * 5. Any software provided in binary form under this license must not be reverse 26 | * engineered, decompiled, modified and/or disassembled. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS 29 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 30 | * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 31 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE 32 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 33 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 34 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 37 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 | * 39 | */ 40 | 41 | #include 42 | #include "app_uart.h" 43 | #include "nrf_delay.h" 44 | #include "bsp.h" 45 | 46 | #define FREQ_ADV_CHANNEL_37 2 /**POWER = 1; 106 | NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_DISABLE_Msk; 107 | NVIC_EnableIRQ(RADIO_IRQn); 108 | 109 | NRF_CLOCK->TASKS_HFCLKSTART = 1; 110 | while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0); 111 | } 112 | 113 | #define WAIT_FOR( m ) do { while (!m); m = 0; } while(0) 114 | 115 | uint8_t rssi_measurer_scan_channel(uint8_t channel_number) 116 | { 117 | uint8_t sample; 118 | 119 | NRF_RADIO->FREQUENCY = channel_number; 120 | NRF_RADIO->TASKS_RXEN = 1; 121 | 122 | WAIT_FOR(NRF_RADIO->EVENTS_READY); 123 | NRF_RADIO->TASKS_RSSISTART = 1; 124 | WAIT_FOR(NRF_RADIO->EVENTS_RSSIEND); 125 | 126 | sample = 127 & NRF_RADIO->RSSISAMPLE; 127 | 128 | NRF_RADIO->TASKS_DISABLE = 1; 129 | WAIT_FOR(NRF_RADIO->EVENTS_DISABLED); 130 | 131 | return sample; 132 | } 133 | 134 | uint8_t rssi_measurer_scan_channel_repeat(uint8_t channel_number) 135 | { 136 | uint8_t sample; 137 | uint8_t max = RSSI_NO_SIGNAL; 138 | for (int i = 0; i <= scan_repeat_times; ++i) { 139 | sample = rssi_measurer_scan_channel(channel_number); 140 | // taking minimum since sample = -dBm. 141 | max = MIN(sample, max); 142 | } 143 | return max; 144 | } 145 | 146 | void uart_error_handle(app_uart_evt_t * p_event) 147 | { 148 | if (p_event->evt_type == APP_UART_COMMUNICATION_ERROR) 149 | { 150 | APP_ERROR_HANDLER(p_event->data.error_communication); 151 | } 152 | else if (p_event->evt_type == APP_UART_FIFO_ERROR) 153 | { 154 | APP_ERROR_HANDLER(p_event->data.error_code); 155 | } 156 | } 157 | 158 | void uart_get_line() 159 | { 160 | static const int bufsize = 64; 161 | uint8_t buf[bufsize]; 162 | uint8_t* p = &buf[0]; 163 | 164 | if (app_uart_get(p) != NRF_SUCCESS) { 165 | return; 166 | } 167 | 168 | memset(buf+1, bufsize-1, 0); 169 | 170 | while (*p != 0x0d && *p != 0x00 && (p-buf < bufsize)) { 171 | if (app_uart_get(++p) != NRF_SUCCESS) { 172 | break; 173 | } 174 | } 175 | 176 | char* q = (char*)&buf[0]; 177 | if (strncmp(q, "set ", 4) == 0) { 178 | q += 4; 179 | if (strncmp(q, "delay ", 6) == 0) { 180 | q += 6; 181 | int d = atoi(q); 182 | sweep_delay = MAX(5, MIN(d, 1000)); 183 | return; 184 | } 185 | if (strncmp(q, "repeat ", 7) == 0) { 186 | q += 7; 187 | int d = atoi(q); 188 | scan_repeat_times = MAX(1, MIN(d, 100)); 189 | return; 190 | } 191 | if (strncmp(q, "channel min ", 12) == 0) { 192 | q += 12; 193 | int d = atoi(q); 194 | min_channel = MAX(1, MIN(d, max_channel)); 195 | return; 196 | } 197 | if (strncmp(q, "channel max ", 12) == 0) { 198 | q += 12; 199 | int d = atoi(q); 200 | max_channel = MAX(min_channel, MIN(d, 100)); 201 | return; 202 | } 203 | return; 204 | } 205 | if (strncmp(q, "start", 5) == 0) { 206 | set_uart_send_enable(true); 207 | return; 208 | } 209 | if (strncmp(q, "stop", 4) == 0) { 210 | set_uart_send_enable(false); 211 | return; 212 | } 213 | if (strncmp(q, "scan adv ", 9) == 0) { 214 | q += 9; 215 | if (strncmp(q, "true", 4) == 0) { 216 | set_scan_ble_adv(true); 217 | return; 218 | } 219 | if (strncmp(q, "false", 5) == 0) { 220 | set_scan_ble_adv(false); 221 | } 222 | return; 223 | } 224 | if (strncmp(q, "led", 3) == 0) { 225 | bsp_board_led_invert(0); 226 | return; 227 | } 228 | } 229 | 230 | void uart_loopback() 231 | { 232 | uint8_t sample; 233 | if (scan_ble_adv) { 234 | sample = rssi_measurer_scan_channel_repeat(FREQ_ADV_CHANNEL_37); 235 | uart_send_packet(FREQ_ADV_CHANNEL_37, sample); 236 | sample = rssi_measurer_scan_channel_repeat(FREQ_ADV_CHANNEL_38); 237 | uart_send_packet(FREQ_ADV_CHANNEL_38, sample); 238 | sample = rssi_measurer_scan_channel_repeat(FREQ_ADV_CHANNEL_39); 239 | uart_send_packet(FREQ_ADV_CHANNEL_39, sample); 240 | } else { 241 | for (uint8_t i = min_channel; i <= max_channel; ++i) 242 | { 243 | sample = rssi_measurer_scan_channel_repeat(i); 244 | uart_send_packet(i, sample); 245 | } 246 | } 247 | 248 | uart_get_line(); 249 | 250 | if (uart_error) { 251 | nrf_delay_ms(MAX(sweep_delay, 500)); 252 | uart_error = false; 253 | set_uart_send_enable(uart_send); 254 | } 255 | 256 | nrf_delay_ms(sweep_delay); 257 | } 258 | 259 | 260 | /** 261 | * @brief Function for main application entry. 262 | */ 263 | int main(void) 264 | { 265 | uint32_t err_code; 266 | 267 | bsp_board_leds_init(); 268 | 269 | const app_uart_comm_params_t comm_params = { 270 | RX_PIN_NUMBER, 271 | TX_PIN_NUMBER, 272 | RTS_PIN_NUMBER, 273 | CTS_PIN_NUMBER, 274 | APP_UART_FLOW_CONTROL_DISABLED, 275 | false, 276 | UART_BAUDRATE_BAUDRATE_Baud115200 277 | }; 278 | 279 | APP_UART_FIFO_INIT( 280 | &comm_params, 281 | UART_RX_BUF_SIZE, 282 | UART_TX_BUF_SIZE, 283 | uart_error_handle, 284 | APP_IRQ_PRIORITY_LOWEST, 285 | err_code 286 | ); 287 | 288 | APP_ERROR_CHECK(err_code); 289 | app_uart_flush(); 290 | 291 | rssi_measurer_configure_radio(); 292 | 293 | while (true) 294 | { 295 | uart_loopback(); 296 | } 297 | } 298 | 299 | 300 | /** @} */ 301 | -------------------------------------------------------------------------------- /fw/src/rssi_uart/rssi_pca10040.uvprojx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 2.1 5 | 6 |
### uVision Project, (C) Keil Software
7 | 8 | 9 | 10 | nrf52832_xxaa 11 | 0x4 12 | ARM-ADS 13 | 5060061::V5.06 update 1 (build 61)::ARMCC 14 | 15 | 16 | nRF52832_xxAA 17 | Nordic Semiconductor 18 | NordicSemiconductor.nRF_DeviceFamilyPack.8.12.0 19 | http://developer.nordicsemi.com/nRF5_SDK/pieces/nRF_DeviceFamilyPack/ 20 | IROM(0x00000000,0x80000) IRAM(0x20000000,0x10000) CPUTYPE("Cortex-M4") FPU2 CLOCK(64000000) ELITTLE 21 | 22 | 23 | 24 | 0 25 | $$Device:nRF52832_xxAA$Device\Include\nrf.h 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | sdk\SVD\nrf52.xml 36 | 0 37 | 0 38 | 39 | 40 | 41 | 42 | 43 | 44 | 0 45 | 0 46 | 0 47 | 0 48 | 1 49 | 50 | .\_build\ 51 | nrf52832_xxaa 52 | 1 53 | 0 54 | 1 55 | 1 56 | 1 57 | .\_build\ 58 | 1 59 | 0 60 | 0 61 | 62 | 0 63 | 0 64 | 65 | 66 | 0 67 | 0 68 | 0 69 | 0 70 | 71 | 72 | 0 73 | 0 74 | 75 | 76 | 0 77 | 0 78 | 0 79 | 0 80 | 81 | 82 | 0 83 | 0 84 | 85 | 86 | 0 87 | 0 88 | 0 89 | 0 90 | 91 | 0 92 | 93 | 94 | 95 | 0 96 | 0 97 | 0 98 | 0 99 | 0 100 | 1 101 | 0 102 | 0 103 | 0 104 | 0 105 | 3 106 | 107 | 108 | 1 109 | 110 | 111 | 112 | 113 | 114 | 115 | SARMCM3.DLL 116 | -MPU 117 | TCM.DLL 118 | -pCM4 119 | 120 | 121 | 122 | 1 123 | 0 124 | 0 125 | 0 126 | 16 127 | 128 | 129 | 130 | 131 | 1 132 | 0 133 | 0 134 | 1 135 | 1 136 | 4099 137 | 138 | 1 139 | BIN\UL2CM3.DLL 140 | 141 | 142 | 143 | 144 | 145 | 0 146 | 147 | 148 | 149 | 0 150 | 1 151 | 1 152 | 1 153 | 1 154 | 1 155 | 1 156 | 1 157 | 0 158 | 1 159 | 1 160 | 0 161 | 1 162 | 1 163 | 0 164 | 0 165 | 1 166 | 1 167 | 1 168 | 1 169 | 1 170 | 1 171 | 1 172 | 1 173 | 1 174 | 0 175 | 0 176 | "Cortex-M4" 177 | 178 | 0 179 | 0 180 | 0 181 | 1 182 | 1 183 | 0 184 | 0 185 | 2 186 | 0 187 | 0 188 | 8 189 | 1 190 | 0 191 | 0 192 | 0 193 | 3 194 | 3 195 | 0 196 | 0 197 | 0 198 | 0 199 | 0 200 | 0 201 | 0 202 | 0 203 | 0 204 | 0 205 | 1 206 | 0 207 | 0 208 | 0 209 | 0 210 | 1 211 | 0 212 | 213 | 214 | 0 215 | 0x0 216 | 0x0 217 | 218 | 219 | 0 220 | 0x0 221 | 0x0 222 | 223 | 224 | 0 225 | 0x0 226 | 0x0 227 | 228 | 229 | 0 230 | 0x0 231 | 0x0 232 | 233 | 234 | 0 235 | 0x0 236 | 0x0 237 | 238 | 239 | 0 240 | 0x0 241 | 0x0 242 | 243 | 244 | 0 245 | 0x20000000 246 | 0x10000 247 | 248 | 249 | 1 250 | 0x0 251 | 0x80000 252 | 253 | 254 | 0 255 | 0x0 256 | 0x0 257 | 258 | 259 | 1 260 | 0x0 261 | 0x0 262 | 263 | 264 | 1 265 | 0x0 266 | 0x0 267 | 268 | 269 | 1 270 | 0x0 271 | 0x0 272 | 273 | 274 | 1 275 | 0x0 276 | 0x80000 277 | 278 | 279 | 1 280 | 0x0 281 | 0x0 282 | 283 | 284 | 0 285 | 0x0 286 | 0x0 287 | 288 | 289 | 0 290 | 0x0 291 | 0x0 292 | 293 | 294 | 0 295 | 0x0 296 | 0x0 297 | 298 | 299 | 0 300 | 0x20000000 301 | 0x10000 302 | 303 | 304 | 0 305 | 0x0 306 | 0x0 307 | 308 | 309 | 310 | 311 | 312 | 1 313 | 4 314 | 0 315 | 0 316 | 1 317 | 0 318 | 0 319 | 0 320 | 0 321 | 0 322 | 0 323 | 0 324 | 0 325 | 1 326 | 0 327 | 0 328 | 0 329 | 0 330 | 0 331 | 332 | --reduce_paths 333 | USE_APP_CONFIG BOARD_PCA10040 BSP_DEFINES_ONLY CONFIG_GPIO_AS_PINRESET NRF52 NRF52832_XXAA NRF52_PAN_12 NRF52_PAN_15 NRF52_PAN_20 NRF52_PAN_31 NRF52_PAN_36 NRF52_PAN_51 NRF52_PAN_54 NRF52_PAN_55 NRF52_PAN_58 NRF52_PAN_64 NRF52_PAN_74 334 | 335 | .;sdk\config\uart_pca10040;sdk\config;sdk\components;sdk\components\boards;sdk\components\drivers_nrf\common;sdk\components\drivers_nrf\delay;sdk\components\drivers_nrf\hal;sdk\components\drivers_nrf\nrf_soc_nosd;sdk\components\drivers_nrf\uart;sdk\components\libraries\bsp;sdk\components\libraries\fifo;sdk\components\libraries\log;sdk\components\libraries\log\src;sdk\components\libraries\strerror;sdk\components\libraries\uart;sdk\components\libraries\util;sdk\components\toolchain;sdk\components\libraries\timer 336 | 337 | 338 | 339 | 1 340 | 0 341 | 0 342 | 0 343 | 0 344 | 0 345 | 0 346 | 0 347 | 0 348 | 349 | --cpreproc_opts=-DBOARD_PCA10040,-DBSP_DEFINES_ONLY,-DCONFIG_GPIO_AS_PINRESET,-DNRF52,-DNRF52832_XXAA,-DNRF52_PAN_12,-DNRF52_PAN_15,-DNRF52_PAN_20,-DNRF52_PAN_31,-DNRF52_PAN_36,-DNRF52_PAN_51,-DNRF52_PAN_54,-DNRF52_PAN_55,-DNRF52_PAN_58,-DNRF52_PAN_64,-DNRF52_PAN_74 350 | BOARD_PCA10040 BSP_DEFINES_ONLY CONFIG_GPIO_AS_PINRESET NRF52 NRF52832_XXAA NRF52_PAN_12 NRF52_PAN_15 NRF52_PAN_20 NRF52_PAN_31 NRF52_PAN_36 NRF52_PAN_51 NRF52_PAN_54 NRF52_PAN_55 NRF52_PAN_58 NRF52_PAN_64 NRF52_PAN_74 351 | 352 | sdk\config\uart_pca10040;sdk\config;sdk\components;sdk\components\boards;sdk\components\drivers_nrf\common;sdk\components\drivers_nrf\delay;sdk\components\drivers_nrf\hal;sdk\components\drivers_nrf\nrf_soc_nosd;sdk\components\drivers_nrf\uart;sdk\components\libraries\bsp;sdk\components\libraries\fifo;sdk\components\libraries\log;sdk\components\libraries\log\src;sdk\components\libraries\strerror;sdk\components\libraries\uart;sdk\components\libraries\util;sdk\components\toolchain 353 | 354 | 355 | 356 | 1 357 | 0 358 | 0 359 | 0 360 | 1 361 | 0 362 | 0x00000000 363 | 0x20000000 364 | 365 | 366 | 367 | 368 | --diag_suppress 6330 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | Application 377 | 378 | 379 | main.c 380 | 1 381 | .\main.c 382 | 383 | 384 | 385 | 386 | Board Definition 387 | 388 | 389 | boards.c 390 | 1 391 | sdk\components\boards\boards.c 392 | 393 | 394 | 395 | 396 | nRF_Drivers 397 | 398 | 399 | nrf_drv_common.c 400 | 1 401 | sdk\components\drivers_nrf\common\nrf_drv_common.c 402 | 403 | 404 | nrf_drv_uart.c 405 | 1 406 | sdk\components\drivers_nrf\uart\nrf_drv_uart.c 407 | 408 | 409 | 410 | 411 | nRF_Libraries 412 | 413 | 414 | app_error.c 415 | 1 416 | sdk\components\libraries\util\app_error.c 417 | 418 | 419 | app_error_weak.c 420 | 1 421 | sdk\components\libraries\util\app_error_weak.c 422 | 423 | 424 | app_fifo.c 425 | 1 426 | sdk\components\libraries\fifo\app_fifo.c 427 | 428 | 429 | app_uart_fifo.c 430 | 1 431 | sdk\components\libraries\uart\app_uart_fifo.c 432 | 433 | 434 | app_util_platform.c 435 | 1 436 | sdk\components\libraries\util\app_util_platform.c 437 | 438 | 439 | nrf_assert.c 440 | 1 441 | sdk\components\libraries\util\nrf_assert.c 442 | 443 | 444 | nrf_strerror.c 445 | 1 446 | sdk\components\libraries\strerror\nrf_strerror.c 447 | 448 | 449 | retarget.c 450 | 1 451 | sdk\components\libraries\uart\retarget.c 452 | 453 | 454 | 455 | 456 | ::CMSIS 457 | 458 | 459 | ::Device 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | RTE\Device\nRF52832_xxAA\arm_startup_nrf52.s 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | RTE\Device\nRF52832_xxAA\startup_config.h 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | RTE\Device\nRF52832_xxAA\system_nrf52.c 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 |
536 | -------------------------------------------------------------------------------- /fw/src/usdb.patch: -------------------------------------------------------------------------------- 1 | --- sdk/components/drivers_nrf/usbd/nrf_drv_usbd_errata.h 2018-03-22 15:25:08.000000000 +0100 2 | +++ sdk/components/drivers_nrf/usbd/nrf_drv_usbd_errata-fixed.h 2018-05-22 10:28:46.995420800 +0200 3 | @@ -99,6 +99,19 @@ 4 | } 5 | 6 | /** 7 | + * @brief Internal auxiliary function to check if the program is running on second final product of 8 | + * NRF52840 chip 9 | + * @retval true It is NRF52480 chip and it is second final product 10 | + * @retval false It is other chip 11 | + */ 12 | +static inline bool nrf_drv_usbd_errata_type_52840_fp2(void) 13 | +{ 14 | + return ( nrf_drv_usbd_errata_type_52840() && 15 | + ( ((*(uint32_t *)0xF0000FE8) & 0xF0) == 0x20 ) && 16 | + ( ((*(uint32_t *)0xF0000FEC) & 0xF0) == 0x00 ) ); 17 | +} 18 | + 19 | +/** 20 | * @brief Function to check if chip requires errata 104 21 | * 22 | * Errata: USBD: EPDATA event is not always generated. 23 | @@ -160,7 +173,8 @@ 24 | */ 25 | static inline bool nrf_drv_usbd_errata_187(void) 26 | { 27 | - return NRF_DRV_USBD_ERRATA_ENABLE && nrf_drv_usbd_errata_type_52840_fp1(); 28 | + return NRF_DRV_USBD_ERRATA_ENABLE && 29 | + (nrf_drv_usbd_errata_type_52840_fp1() || nrf_drv_usbd_errata_type_52840_fp2()); 30 | } 31 | 32 | /** 33 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Nordic Semiconductor ASA 3 | * 4 | * SPDX-License-Identifier: LicenseRef-Nordic-4-Clause 5 | */ 6 | 7 | module.exports = 8 | require('@nordicsemiconductor/pc-nrfconnect-shared/config/jest.config')(); 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pc-nrfconnect-rssi", 3 | "version": "1.7.3", 4 | "displayName": "RSSI Viewer", 5 | "description": "Live visualization of RSSI vs frequency in the 2.4 GHz band", 6 | "homepage": "https://github.com/NordicSemiconductor/pc-nrfconnect-rssi", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/NordicSemiconductor/pc-nrfconnect-rssi.git" 10 | }, 11 | "author": "Nordic Semiconductor ASA", 12 | "license": "SEE LICENSE IN LICENSE", 13 | "engines": { 14 | "nrfconnect": ">=5.2.0" 15 | }, 16 | "nrfConnectForDesktop": { 17 | "nrfutil": { 18 | "device": [ 19 | "2.10.2" 20 | ] 21 | }, 22 | "html": "dist/index.html" 23 | }, 24 | "files": [ 25 | "dist/", 26 | "fw/*.hex", 27 | "fw/*.zip", 28 | "resources/icon.*", 29 | "Changelog.md", 30 | "LICENSE" 31 | ], 32 | "main": "dist/bundle.js", 33 | "prettier": "@nordicsemiconductor/pc-nrfconnect-shared/config/prettier.config.js", 34 | "scripts": { 35 | "watch": "run-p --silent --continue-on-error watch:*", 36 | "watch:build": "run-esbuild --watch --include-bootloader", 37 | "watch:types": "tsc --noEmit --pretty --watch --preserveWatchOutput", 38 | "build:dev": "run-esbuild --include-bootloader", 39 | "build:prod": "run-esbuild --prod --include-bootloader", 40 | "test": "jest --passWithNoTests", 41 | "check": "run-p --silent --continue-on-error --print-label check:*", 42 | "check:app": "check-app-properties", 43 | "check:lint": "eslint --color .", 44 | "check:types": "check-for-typescript tsc --noEmit --pretty", 45 | "check:license": "nrfconnect-license check", 46 | "nordic-publish": "node ./dist/nordic-publish.js", 47 | "prepare": "husky install" 48 | }, 49 | "devDependencies": { 50 | "@nordicsemiconductor/pc-nrfconnect-shared": "^210.0.0", 51 | "chart.js": "^4.0.1", 52 | "chartjs-plugin-datalabels": "2.2.0", 53 | "react-chartjs-2": "^5.0.1" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /resources/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NordicSemiconductor/pc-nrfconnect-rssi/203eb814185fbfd01cd896675d0cc3a58b087587/resources/icon.icns -------------------------------------------------------------------------------- /resources/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NordicSemiconductor/pc-nrfconnect-rssi/203eb814185fbfd01cd896675d0cc3a58b087587/resources/icon.ico -------------------------------------------------------------------------------- /resources/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NordicSemiconductor/pc-nrfconnect-rssi/203eb814185fbfd01cd896675d0cc3a58b087587/resources/icon.png -------------------------------------------------------------------------------- /resources/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 9 | 10 | 12 | 14 | 16 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/app/DeviceSelector.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Nordic Semiconductor ASA 3 | * 4 | * SPDX-License-Identifier: LicenseRef-Nordic-4-Clause 5 | */ 6 | 7 | import React from 'react'; 8 | import { useDispatch } from 'react-redux'; 9 | import { DeviceSelector } from '@nordicsemiconductor/pc-nrfconnect-shared'; 10 | import { DeviceTraits } from '@nordicsemiconductor/pc-nrfconnect-shared/nrfutil/device'; 11 | 12 | import { 13 | closeDevice, 14 | deviceSetupConfig, 15 | openDevice, 16 | } from '../features/rssiDevice/rssiDeviceEffects'; 17 | 18 | const deviceListing: DeviceTraits = { 19 | nordicUsb: true, 20 | serialPorts: true, 21 | jlink: true, 22 | nordicDfu: true, 23 | }; 24 | 25 | export default () => { 26 | const dispatch = useDispatch(); 27 | 28 | return ( 29 | { 33 | dispatch(openDevice(device)); 34 | }} 35 | onDeviceDeselected={() => { 36 | dispatch(closeDevice()); 37 | }} 38 | /> 39 | ); 40 | }; 41 | -------------------------------------------------------------------------------- /src/app/SidePanel/AnimationSpeed.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Nordic Semiconductor ASA 3 | * 4 | * SPDX-License-Identifier: LicenseRef-Nordic-4-Clause 5 | */ 6 | 7 | import React from 'react'; 8 | import { useDispatch, useSelector } from 'react-redux'; 9 | import { NumberInput } from '@nordicsemiconductor/pc-nrfconnect-shared'; 10 | 11 | import { 12 | getAnimationDuration, 13 | setAnimationDuration, 14 | } from '../../features/rssiDevice/rssiDeviceSlice'; 15 | 16 | export default () => { 17 | const dispatch = useDispatch(); 18 | const animationDuration = useSelector(getAnimationDuration); 19 | 20 | return ( 21 | 26 | dispatch(setAnimationDuration(newAnimationDuration)) 27 | } 28 | label="Hold values for" 29 | unit="ms" 30 | showSlider 31 | /> 32 | ); 33 | }; 34 | -------------------------------------------------------------------------------- /src/app/SidePanel/ChannelRange.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Nordic Semiconductor ASA 3 | * 4 | * SPDX-License-Identifier: LicenseRef-Nordic-4-Clause 5 | */ 6 | 7 | import React from 'react'; 8 | import { useDispatch, useSelector } from 'react-redux'; 9 | import { 10 | bleChannels, 11 | NumberInlineInput, 12 | Slider, 13 | } from '@nordicsemiconductor/pc-nrfconnect-shared'; 14 | 15 | import { 16 | getChannelRange, 17 | setChannelRange, 18 | } from '../../features/rssiDevice/rssiDeviceSlice'; 19 | 20 | export default () => { 21 | const dispatch = useDispatch(); 22 | const channelRange = useSelector(getChannelRange); 23 | 24 | const min = Math.min(...channelRange); 25 | const max = Math.max(...channelRange); 26 | 27 | return ( 28 |
29 |
30 | Channels from{' '} 31 | 35 | dispatch(setChannelRange([newMin, max])) 36 | } 37 | />{' '} 38 | to{' '} 39 | 43 | dispatch(setChannelRange([min, newMax])) 44 | } 45 | /> 46 |
47 | 52 | dispatch(setChannelRange([newValue, channelRange[1]])), 53 | newValue => 54 | dispatch(setChannelRange([channelRange[0], newValue])), 55 | ]} 56 | /> 57 |
58 | ); 59 | }; 60 | -------------------------------------------------------------------------------- /src/app/SidePanel/ControlButtons.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Nordic Semiconductor ASA 3 | * 4 | * SPDX-License-Identifier: LicenseRef-Nordic-4-Clause 5 | */ 6 | 7 | import React from 'react'; 8 | import { useDispatch, useSelector } from 'react-redux'; 9 | import { 10 | Button, 11 | StartStopButton, 12 | useHotKey, 13 | } from '@nordicsemiconductor/pc-nrfconnect-shared'; 14 | 15 | import { 16 | clearRssiData, 17 | getDelay, 18 | getIsConnected, 19 | getIsPaused, 20 | getRssiDevice, 21 | getScanRepeat, 22 | toggleIsPaused, 23 | } from '../../features/rssiDevice/rssiDeviceSlice'; 24 | 25 | export default () => { 26 | const isConnected = useSelector(getIsConnected); 27 | const isPaused = useSelector(getIsPaused); 28 | const delay = useSelector(getDelay); 29 | const scanRepeat = useSelector(getScanRepeat); 30 | const rssiDevice = useSelector(getRssiDevice); 31 | const dispatch = useDispatch(); 32 | 33 | const togglePause = () => { 34 | dispatch(toggleIsPaused()); 35 | 36 | if (isPaused) { 37 | rssiDevice?.resumeReading(delay, scanRepeat); 38 | } else { 39 | rssiDevice?.pauseReading(); 40 | } 41 | }; 42 | 43 | useHotKey({ 44 | hotKey: 'alt+r', 45 | title: 'Reset', 46 | isGlobal: false, 47 | action: () => dispatch(clearRssiData()), 48 | }); 49 | 50 | useHotKey( 51 | { 52 | hotKey: 'alt+t', 53 | title: 'Start/Pause', 54 | isGlobal: false, 55 | action: () => togglePause(), 56 | }, 57 | [isPaused] 58 | ); 59 | 60 | return ( 61 | <> 62 | 69 | 70 | 81 | 82 | ); 83 | }; 84 | -------------------------------------------------------------------------------- /src/app/SidePanel/Delay.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Nordic Semiconductor ASA 3 | * 4 | * SPDX-License-Identifier: LicenseRef-Nordic-4-Clause 5 | */ 6 | 7 | import React, { useCallback } from 'react'; 8 | import { useDispatch, useSelector } from 'react-redux'; 9 | import { NumberInput } from '@nordicsemiconductor/pc-nrfconnect-shared'; 10 | 11 | import { 12 | getDelay, 13 | getRssiDevice, 14 | setDelay, 15 | } from '../../features/rssiDevice/rssiDeviceSlice'; 16 | 17 | export default () => { 18 | const dispatch = useDispatch(); 19 | const delay = useSelector(getDelay); 20 | const rssiDevice = useSelector(getRssiDevice); 21 | 22 | const setAndWriteDelay = useCallback( 23 | newDelay => { 24 | dispatch(setDelay(newDelay)); 25 | rssiDevice?.writeDelay(newDelay); 26 | }, 27 | [dispatch, rssiDevice] 28 | ); 29 | 30 | return ( 31 | 40 | ); 41 | }; 42 | -------------------------------------------------------------------------------- /src/app/SidePanel/LevelRange.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Nordic Semiconductor ASA 3 | * 4 | * SPDX-License-Identifier: LicenseRef-Nordic-4-Clause 5 | */ 6 | 7 | import React from 'react'; 8 | import { useDispatch, useSelector } from 'react-redux'; 9 | import { 10 | NumberInlineInput, 11 | Slider, 12 | } from '@nordicsemiconductor/pc-nrfconnect-shared'; 13 | 14 | import { 15 | getLevelRange, 16 | initialLevelRange, 17 | setLevelRange, 18 | } from '../../features/rssiDevice/rssiDeviceSlice'; 19 | 20 | const sliderId = 'ble-level-slider'; 21 | 22 | export default () => { 23 | const dispatch = useDispatch(); 24 | const levelRange = useSelector(getLevelRange); 25 | 26 | const min = Math.min(...levelRange); 27 | const max = Math.max(...levelRange); 28 | 29 | const setNewLevelRangeIfUnequal = (value1: number, value2: number) => { 30 | if (value1 !== value2) { 31 | dispatch(setLevelRange([value1, value2])); 32 | } 33 | }; 34 | 35 | return ( 36 |
37 |
38 | Levels from{' '} 39 | 43 | setNewLevelRangeIfUnequal(min, -newMax) 44 | } 45 | />{' '} 46 | to{' '} 47 | 51 | setNewLevelRangeIfUnequal(-newMin, max) 52 | } 53 | />{' '} 54 | dBm 55 |
56 | -v)} 59 | range={{ 60 | min: -initialLevelRange.max, 61 | max: -initialLevelRange.min, 62 | }} 63 | onChange={[ 64 | newValue => 65 | setNewLevelRangeIfUnequal(-newValue, levelRange[1]), 66 | newValue => 67 | setNewLevelRangeIfUnequal(levelRange[0], -newValue), 68 | ]} 69 | /> 70 |
71 | ); 72 | }; 73 | -------------------------------------------------------------------------------- /src/app/SidePanel/MaxCount.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Nordic Semiconductor ASA 3 | * 4 | * SPDX-License-Identifier: LicenseRef-Nordic-4-Clause 5 | */ 6 | 7 | import React from 'react'; 8 | import { useDispatch, useSelector } from 'react-redux'; 9 | import { NumberInput } from '@nordicsemiconductor/pc-nrfconnect-shared'; 10 | 11 | import { 12 | getMaxScans, 13 | setMaxScans, 14 | } from '../../features/rssiDevice/rssiDeviceSlice'; 15 | 16 | export default () => { 17 | const dispatch = useDispatch(); 18 | const maxScans = useSelector(getMaxScans); 19 | 20 | return ( 21 | dispatch(setMaxScans(newMaxScans))} 27 | label="Show max for last" 28 | unit="scans" 29 | /> 30 | ); 31 | }; 32 | -------------------------------------------------------------------------------- /src/app/SidePanel/SampleCount.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Nordic Semiconductor ASA 3 | * 4 | * SPDX-License-Identifier: LicenseRef-Nordic-4-Clause 5 | */ 6 | 7 | import React, { useCallback } from 'react'; 8 | import { useDispatch, useSelector } from 'react-redux'; 9 | import { NumberInput } from '@nordicsemiconductor/pc-nrfconnect-shared'; 10 | 11 | import { 12 | getRssiDevice, 13 | getScanRepeat, 14 | setScanRepeat, 15 | } from '../../features/rssiDevice/rssiDeviceSlice'; 16 | 17 | export default () => { 18 | const dispatch = useDispatch(); 19 | const scanRepeat = useSelector(getScanRepeat); 20 | const rssiDevice = useSelector(getRssiDevice); 21 | 22 | const setAndWriteScanRepeat = useCallback( 23 | newScanRepeat => { 24 | dispatch(setScanRepeat(newScanRepeat)); 25 | rssiDevice?.writeScanRepeat(newScanRepeat); 26 | }, 27 | [dispatch, rssiDevice] 28 | ); 29 | 30 | return ( 31 | 40 | ); 41 | }; 42 | -------------------------------------------------------------------------------- /src/app/SidePanel/SidePanel.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Nordic Semiconductor ASA 3 | * 4 | * SPDX-License-Identifier: LicenseRef-Nordic-4-Clause 5 | */ 6 | 7 | import React from 'react'; 8 | import { Group, SidePanel } from '@nordicsemiconductor/pc-nrfconnect-shared'; 9 | 10 | import useRssiDevice from '../../features/rssiDevice/useRssiDevice'; 11 | import AnimationSpeed from './AnimationSpeed'; 12 | import ChannelRange from './ChannelRange'; 13 | import ControlButtons from './ControlButtons'; 14 | import Delay from './Delay'; 15 | import LevelRange from './LevelRange'; 16 | import MaxCount from './MaxCount'; 17 | import SampleCount from './SampleCount'; 18 | import ToggleLed from './ToggleLed'; 19 | 20 | export default () => { 21 | useRssiDevice(); 22 | 23 | return ( 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | ); 49 | }; 50 | -------------------------------------------------------------------------------- /src/app/SidePanel/ToggleLed.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Nordic Semiconductor ASA 3 | * 4 | * SPDX-License-Identifier: LicenseRef-Nordic-4-Clause 5 | */ 6 | 7 | import React from 'react'; 8 | import { useSelector } from 'react-redux'; 9 | import { Button } from '@nordicsemiconductor/pc-nrfconnect-shared'; 10 | 11 | import { 12 | getIsConnected, 13 | getRssiDevice, 14 | } from '../../features/rssiDevice/rssiDeviceSlice'; 15 | 16 | export default () => { 17 | const isConnected = useSelector(getIsConnected); 18 | const rssiDevice = useSelector(getRssiDevice); 19 | 20 | return ( 21 | 29 | ); 30 | }; 31 | -------------------------------------------------------------------------------- /src/app/store.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Nordic Semiconductor ASA 3 | * 4 | * SPDX-License-Identifier: LicenseRef-Nordic-4-Clause 5 | */ 6 | 7 | import { NrfConnectState } from '@nordicsemiconductor/pc-nrfconnect-shared'; 8 | import { combineReducers } from 'redux'; 9 | 10 | import rssi from '../features/rssiDevice/rssiDeviceSlice'; 11 | 12 | export const reducer = combineReducers({ 13 | rssi, 14 | }); 15 | 16 | type AppState = ReturnType; 17 | 18 | export type RootState = NrfConnectState; 19 | -------------------------------------------------------------------------------- /src/features/Chart/Chart.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Nordic Semiconductor ASA 3 | * 4 | * SPDX-License-Identifier: LicenseRef-Nordic-4-Clause 5 | */ 6 | 7 | import React from 'react'; 8 | import { Bar } from 'react-chartjs-2'; 9 | import { useDispatch, useSelector } from 'react-redux'; 10 | import { 11 | Alert, 12 | bleChannels, 13 | getReadbackProtection, 14 | Main, 15 | selectedDevice, 16 | } from '@nordicsemiconductor/pc-nrfconnect-shared'; 17 | import { BarElement, CategoryScale, Chart, LinearScale } from 'chart.js'; 18 | import ChartDataLabels from 'chartjs-plugin-datalabels'; 19 | 20 | import { recoverHex } from '../rssiDevice/rssiDeviceEffects'; 21 | import { 22 | getAnimationDuration, 23 | getChannelRangeSorted, 24 | getLevelRangeSorted, 25 | getNoDataReceived, 26 | getRssi, 27 | getRssiMax, 28 | } from '../rssiDevice/rssiDeviceSlice'; 29 | import color from './rssiColors'; 30 | 31 | import './alert.scss'; 32 | 33 | Chart.register(ChartDataLabels, BarElement, CategoryScale, LinearScale); 34 | 35 | const rssiColors = bleChannels.map(channel => 36 | bleChannels.isAdvertisement(channel) 37 | ? color.bar.advertisement 38 | : color.bar.normal 39 | ); 40 | 41 | const rssiMaxColors = bleChannels.map(channel => 42 | bleChannels.isAdvertisement(channel) 43 | ? color.bar.advertisementMax 44 | : color.bar.normalMax 45 | ); 46 | 47 | const labels = bleChannels; 48 | 49 | const selectBLEValues = (allData: readonly number[]) => 50 | allData.slice(2).filter((_, index) => index % 2 === 0); 51 | 52 | const isInRange = ([min, max]: readonly [number, number], value: number) => 53 | value >= min && value <= max; 54 | 55 | export default () => { 56 | const rssi = useSelector(getRssi); 57 | const rssiMax = useSelector(getRssiMax); 58 | const animationDuration = useSelector(getAnimationDuration); 59 | const channelRange = useSelector(getChannelRangeSorted); 60 | const [levelMin, levelMax] = useSelector(getLevelRangeSorted); 61 | const device = useSelector(selectedDevice); 62 | const readbackProtection = useSelector(getReadbackProtection); 63 | const noData = useSelector(getNoDataReceived); 64 | const dispatch = useDispatch(); 65 | 66 | const convertInLevel = (v: number) => levelMin + levelMax - v; 67 | const limitToLevelRange = (v: number) => { 68 | if (v < levelMin) return levelMin; 69 | if (v > levelMax) return levelMax; 70 | return v; 71 | }; 72 | 73 | const maskValuesOutsideChannelRange = (value: number, index: number) => 74 | isInRange(channelRange, bleChannels[index]) ? value : levelMin - 1; 75 | 76 | const convertToScreenValue = (rawRssi: readonly number[]) => 77 | selectBLEValues(rawRssi) 78 | .map(convertInLevel) 79 | .map(limitToLevelRange) 80 | .map(maskValuesOutsideChannelRange); 81 | 82 | return ( 83 |
84 | {device && 85 | noData && 86 | readbackProtection !== 'NRFDL_PROTECTION_STATUS_NONE' && ( 87 | 88 |
89 | No data received. Unable to verify compatible 90 | firmware because the selected device has readback 91 | protection enabled. 92 | 98 |
99 |
100 | )} 101 |
102 |
103 | 124 | v <= levelMin || v >= levelMax 125 | ? '' 126 | : convertInLevel(v), 127 | offset: -3, 128 | font: { size: 9 }, 129 | }, 130 | }, 131 | { 132 | label: 'bgBars', 133 | backgroundColor: color.bar.background, 134 | borderWidth: 0, 135 | data: Array(81).fill(levelMax), 136 | datalabels: { display: false }, 137 | }, 138 | ], 139 | }} 140 | options={{ 141 | responsive: true, 142 | animation: { duration: animationDuration }, 143 | maintainAspectRatio: false, 144 | plugins: { 145 | legend: { display: false }, 146 | tooltip: { enabled: false }, 147 | }, 148 | scales: { 149 | xAxesTop: { 150 | type: 'category', 151 | position: 'top', 152 | offset: true, 153 | ticks: { 154 | callback: (_, index: number) => 155 | String(bleChannels[index]).padStart( 156 | 2, 157 | '0' 158 | ), 159 | minRotation: 0, 160 | maxRotation: 0, 161 | labelOffset: 0, 162 | autoSkipPadding: 5, 163 | color: color.label, 164 | }, 165 | stacked: true, 166 | title: { 167 | display: true, 168 | text: 'Bluetooth Low Energy Channel', 169 | color: color.label, 170 | font: { size: 14 }, 171 | }, 172 | grid: { 173 | display: false, 174 | }, 175 | border: { 176 | display: false, 177 | }, 178 | }, 179 | x: { 180 | type: 'category', 181 | position: 'bottom', 182 | offset: true, 183 | ticks: { 184 | callback: (_, index) => 185 | 2402 + 2 * index, 186 | minRotation: 90, 187 | labelOffset: 0, 188 | autoSkipPadding: 5, 189 | color: color.label, 190 | }, 191 | title: { 192 | display: true, 193 | text: 'MHz', 194 | color: color.label, 195 | font: { size: 14 }, 196 | padding: { top: 10 }, 197 | }, 198 | grid: { 199 | offset: true, 200 | display: false, 201 | }, 202 | border: { 203 | display: false, 204 | }, 205 | stacked: true, 206 | }, 207 | y: { 208 | type: 'linear', 209 | title: { 210 | display: true, 211 | text: 'dBm', 212 | color: color.label, 213 | font: { size: 14 }, 214 | }, 215 | grid: { 216 | display: false, 217 | }, 218 | border: { 219 | display: false, 220 | }, 221 | ticks: { 222 | callback: v => 223 | Number.parseFloat(v.toString()) - 224 | levelMin - 225 | levelMax, 226 | color: color.label, 227 | }, 228 | min: levelMin, 229 | max: levelMax, 230 | }, 231 | }, 232 | }} 233 | /> 234 |
235 |
236 |
237 | ); 238 | }; 239 | -------------------------------------------------------------------------------- /src/features/Chart/alert.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Nordic Semiconductor ASA 3 | * 4 | * SPDX-License-Identifier: LicenseRef-Nordic-4-Clause 5 | */ 6 | 7 | @use 'sass:color'; 8 | @import '~@nordicsemiconductor/pc-nrfconnect-shared/styles'; 9 | 10 | .readback-protection-warning { 11 | gap: 8px; 12 | 13 | button { 14 | border: 1px solid #b75300; 15 | color: #b75300; 16 | background-color: white; 17 | 18 | &:hover:not([disabled]) { 19 | color: #b75300; 20 | background-color: white; 21 | border-color: #b75300; 22 | } 23 | 24 | &:focus:not([disabled]) { 25 | background-color: white; 26 | border-color: #b75300 !important; 27 | } 28 | 29 | &:active:not([disabled]) { 30 | background-color: color.scale(white, $lightness: -10%); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/features/Chart/rssiColors.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Nordic Semiconductor ASA 3 | * 4 | * SPDX-License-Identifier: LicenseRef-Nordic-4-Clause 5 | */ 6 | 7 | import { colors } from '@nordicsemiconductor/pc-nrfconnect-shared'; 8 | 9 | export default { 10 | label: colors.gray300, 11 | bar: { 12 | normal: colors.blueSlate, 13 | normalMax: colors.blueSlateLighter, 14 | advertisement: colors.green, 15 | advertisementMax: colors.green200, 16 | background: colors.gray50, 17 | }, 18 | }; 19 | -------------------------------------------------------------------------------- /src/features/rssiDevice/createRssiDevice.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Nordic Semiconductor ASA 3 | * 4 | * SPDX-License-Identifier: LicenseRef-Nordic-4-Clause 5 | */ 6 | 7 | import { SerialPort } from 'serialport'; 8 | 9 | export type RssiDevice = Awaited>; 10 | 11 | export const createRssiDevice = (serialPort: SerialPort) => { 12 | const writeAndDrain = async (cmd: string) => { 13 | await new Promise(resolve => { 14 | serialPort.write(cmd, () => { 15 | serialPort.drain(resolve); 16 | }); 17 | }); 18 | }; 19 | 20 | const writeDelay = (delay: number) => writeAndDrain(`set delay ${delay}\r`); 21 | 22 | const writeScanRepeat = (scanRepeat: number) => 23 | writeAndDrain(`set repeat ${scanRepeat}\r`); 24 | 25 | const pauseReading = () => writeAndDrain('stop\r'); 26 | 27 | return { 28 | pauseReading, 29 | stopReading: async () => { 30 | await pauseReading(); 31 | }, 32 | resumeReading: async (delay: number, scanRepeat: number) => { 33 | await writeDelay(delay); 34 | await writeScanRepeat(scanRepeat); 35 | await writeAndDrain('start\r'); 36 | }, 37 | toggleLED: () => writeAndDrain('led\r'), 38 | writeScanRepeat, 39 | writeDelay: (delay: number) => writeAndDrain(`set delay ${delay}\r`), 40 | }; 41 | }; 42 | -------------------------------------------------------------------------------- /src/features/rssiDevice/rssiDeviceEffects.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Nordic Semiconductor ASA 3 | * 4 | * SPDX-License-Identifier: LicenseRef-Nordic-4-Clause 5 | */ 6 | 7 | import { 8 | AppThunk, 9 | Device, 10 | DeviceSetupConfig, 11 | getAppFile, 12 | isDeviceInDFUBootloader, 13 | jprogDeviceSetup, 14 | logger, 15 | prepareDevice, 16 | sdfuDeviceSetup, 17 | } from '@nordicsemiconductor/pc-nrfconnect-shared'; 18 | import { SerialPort } from 'serialport'; 19 | 20 | import { clearSerialPort, setSerialPort } from './rssiDeviceSlice'; 21 | 22 | export const deviceSetupConfig: DeviceSetupConfig = { 23 | deviceSetups: [ 24 | sdfuDeviceSetup( 25 | [ 26 | { 27 | key: 'pca10059', 28 | application: getAppFile('fw/rssi-10059.hex'), 29 | semver: 'rssi_cdc_acm 2.0.0+dfuMay-22-2018-10-43-22', 30 | params: {}, 31 | }, 32 | ], 33 | true, 34 | d => 35 | !isDeviceInDFUBootloader(d) && 36 | !!d.serialPorts && 37 | d.serialPorts.length > 0 && 38 | !!d.traits.nordicUsb && 39 | !!d.usb && 40 | d.usb.device.descriptor.idProduct === 0xc00a 41 | ), 42 | jprogDeviceSetup( 43 | [ 44 | { 45 | key: 'nrf52_family', 46 | fw: getAppFile('fw/rssi-10040.hex'), 47 | fwVersion: 'rssi-fw-1.0.0', 48 | fwIdAddress: 0x2000, 49 | }, 50 | ], 51 | true, 52 | true 53 | ), 54 | ], 55 | }; 56 | 57 | export const closeDevice = (): AppThunk => dispatch => { 58 | dispatch(clearSerialPort()); 59 | }; 60 | 61 | export const openDevice = 62 | (device: Device): AppThunk => 63 | dispatch => { 64 | // Reset serial port settings 65 | const ports = device.serialPorts; 66 | 67 | if (ports) { 68 | const comPort = ports[0].comName; // We want to connect to vComIndex 0 69 | if (comPort) { 70 | logger.info(`Opening Serial port ${comPort}`); 71 | const serialPort = new SerialPort( 72 | { path: comPort, baudRate: 115200 }, 73 | error => { 74 | if (error) { 75 | logger.error( 76 | `Failed to open serial port ${comPort}.` 77 | ); 78 | logger.error(`Error ${error}.`); 79 | return; 80 | } 81 | 82 | dispatch(setSerialPort(serialPort)); 83 | logger.info(`Serial Port ${comPort} has been opened`); 84 | } 85 | ); 86 | } 87 | } 88 | }; 89 | 90 | export const recoverHex = 91 | (device: Device): AppThunk => 92 | (dispatch, getState) => { 93 | getState().app.rssi.serialPort?.close(() => { 94 | dispatch(clearSerialPort()); 95 | dispatch( 96 | prepareDevice( 97 | device, 98 | deviceSetupConfig, 99 | programmedDevice => { 100 | dispatch(openDevice(programmedDevice)); 101 | }, 102 | () => {}, 103 | undefined, 104 | false, 105 | false 106 | ) 107 | ); 108 | }); 109 | }; 110 | -------------------------------------------------------------------------------- /src/features/rssiDevice/rssiDeviceSlice.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Nordic Semiconductor ASA 3 | * 4 | * SPDX-License-Identifier: LicenseRef-Nordic-4-Clause 5 | */ 6 | 7 | import { bleChannels } from '@nordicsemiconductor/pc-nrfconnect-shared'; 8 | import { createSlice, PayloadAction } from '@reduxjs/toolkit'; 9 | import type { AutoDetectTypes } from '@serialport/bindings-cpp'; 10 | import { SerialPort } from 'serialport'; 11 | 12 | import type { RootState } from '../../app/store'; 13 | import { RssiDevice } from './createRssiDevice'; 14 | 15 | const initialData = () => new Array(81).fill(undefined).map(() => []); 16 | 17 | type NumberPair = readonly [number, number]; 18 | 19 | const sortedPair = ([a, b]: NumberPair): NumberPair => 20 | a < b ? [a, b] : [b, a]; 21 | 22 | export const initialLevelRange = { 23 | min: 20, 24 | max: 110, 25 | }; 26 | 27 | interface RssiState { 28 | isPaused: boolean; 29 | buffer: readonly number[]; 30 | data: readonly (readonly number[])[]; 31 | dataMax: readonly number[]; 32 | delay: number; 33 | scanRepeat: number; 34 | maxScans: number; 35 | animationDuration: number; 36 | channelRange: NumberPair; 37 | levelRange: NumberPair; 38 | noDataReceived: boolean; 39 | serialPort?: SerialPort; 40 | rssiDevice?: RssiDevice; 41 | } 42 | 43 | const initialState: RssiState = { 44 | isPaused: false, 45 | buffer: [], 46 | data: initialData(), 47 | dataMax: [], 48 | delay: 10, 49 | scanRepeat: 1, 50 | maxScans: 30, 51 | animationDuration: 500, 52 | channelRange: [bleChannels.min, bleChannels.max], 53 | levelRange: [initialLevelRange.min, initialLevelRange.max], 54 | noDataReceived: false, 55 | }; 56 | 57 | const rssiSlice = createSlice({ 58 | name: 'rssi', 59 | initialState, 60 | reducers: { 61 | setSerialPort: ( 62 | state, 63 | action: PayloadAction> 64 | ) => { 65 | state.serialPort = action.payload; 66 | }, 67 | setRssiDevice: (state, action: PayloadAction) => { 68 | state.rssiDevice = action.payload; 69 | }, 70 | 71 | clearSerialPort: state => { 72 | state.serialPort = undefined; 73 | state.rssiDevice = undefined; 74 | }, 75 | 76 | toggleIsPaused: state => { 77 | state.isPaused = !state.isPaused; 78 | }, 79 | 80 | clearRssiData: state => { 81 | state.data = initialData(); 82 | state.dataMax = []; 83 | state.noDataReceived = false; 84 | }, 85 | 86 | resetRssiStore: state => { 87 | state.buffer = []; 88 | state.data = initialData(); 89 | state.dataMax = []; 90 | state.noDataReceived = false; 91 | state.isPaused = false; 92 | }, 93 | 94 | setDelay: (state, action: PayloadAction) => { 95 | state.delay = action.payload; 96 | }, 97 | 98 | setMaxScans: (state, action: PayloadAction) => { 99 | state.maxScans = action.payload; 100 | }, 101 | 102 | setScanRepeat: (state, action: PayloadAction) => { 103 | state.scanRepeat = action.payload; 104 | }, 105 | 106 | setAnimationDuration: (state, action: PayloadAction) => { 107 | state.animationDuration = action.payload; 108 | }, 109 | 110 | setChannelRange: (state, action: PayloadAction<[number, number]>) => { 111 | state.channelRange = action.payload; 112 | }, 113 | 114 | setLevelRange: (state, action: PayloadAction<[number, number]>) => { 115 | state.levelRange = action.payload; 116 | }, 117 | 118 | onReceiveRssiData: (state, action: PayloadAction) => { 119 | if (!state.serialPort || !state.serialPort.isOpen) { 120 | state.data = initialData(); 121 | state.dataMax = []; 122 | return; 123 | } 124 | 125 | if (state.isPaused) { 126 | return; 127 | } 128 | 129 | state.buffer = [...state.buffer, ...action.payload]; 130 | 131 | if (state.buffer.length > 246) { 132 | state.buffer.splice(0, state.buffer.length - 246); 133 | } 134 | while (state.buffer.length >= 3) { 135 | while (state.buffer.length && state.buffer.shift() !== 0xff); 136 | 137 | const [ch, d] = state.buffer.splice(0, 2); 138 | if (ch !== 0xff && d !== 0xff) { 139 | state.data[ch] = [d, ...state.data[ch]]; 140 | state.data[ch].splice(state.maxScans); 141 | state.dataMax[ch] = Math.min(...state.data[ch]); 142 | } 143 | } 144 | }, 145 | 146 | onReceiveNoRssiData: state => { 147 | if (state.isPaused) { 148 | return; 149 | } 150 | state.noDataReceived = true; 151 | }, 152 | }, 153 | }); 154 | 155 | export const getSerialPort = (state: RootState) => state.app.rssi.serialPort; 156 | export const getRssiDevice = (state: RootState) => state.app.rssi.rssiDevice; 157 | export const getIsConnected = (state: RootState) => !!state.app.rssi.serialPort; 158 | export const getIsPaused = (state: RootState) => state.app.rssi.isPaused; 159 | 160 | export const getRssi = (state: RootState) => 161 | state.app.rssi.data.map(scan => scan[0]); 162 | export const getRssiMax = (state: RootState) => state.app.rssi.dataMax; 163 | export const getAnimationDuration = (state: RootState) => 164 | state.app.rssi.animationDuration; 165 | export const getDelay = (state: RootState) => state.app.rssi.delay; 166 | export const getMaxScans = (state: RootState) => state.app.rssi.maxScans; 167 | export const getScanRepeat = (state: RootState) => state.app.rssi.scanRepeat; 168 | 169 | export const getChannelRange = (state: RootState) => 170 | state.app.rssi.channelRange; 171 | export const getChannelRangeSorted = (state: RootState) => 172 | sortedPair(getChannelRange(state)); 173 | 174 | export const getLevelRange = (state: RootState) => state.app.rssi.levelRange; 175 | export const getLevelRangeSorted = (state: RootState) => 176 | sortedPair(getLevelRange(state)); 177 | 178 | export const getNoDataReceived = (state: RootState) => 179 | state.app.rssi.noDataReceived; 180 | 181 | export const { 182 | setSerialPort, 183 | setRssiDevice, 184 | clearSerialPort, 185 | toggleIsPaused, 186 | resetRssiStore, 187 | clearRssiData, 188 | setDelay, 189 | setMaxScans, 190 | setScanRepeat, 191 | setAnimationDuration, 192 | setChannelRange, 193 | setLevelRange, 194 | onReceiveRssiData, 195 | onReceiveNoRssiData, 196 | } = rssiSlice.actions; 197 | export default rssiSlice.reducer; 198 | -------------------------------------------------------------------------------- /src/features/rssiDevice/useRssiDevice.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Nordic Semiconductor ASA 3 | * 4 | * SPDX-License-Identifier: LicenseRef-Nordic-4-Clause 5 | */ 6 | 7 | import { useEffect } from 'react'; 8 | import { useDispatch, useSelector } from 'react-redux'; 9 | import { 10 | AppThunk, 11 | getReadbackProtection, 12 | logger, 13 | } from '@nordicsemiconductor/pc-nrfconnect-shared'; 14 | 15 | import { createRssiDevice } from './createRssiDevice'; 16 | import { 17 | clearRssiData, 18 | getSerialPort, 19 | onReceiveNoRssiData, 20 | onReceiveRssiData, 21 | resetRssiStore, 22 | setRssiDevice, 23 | } from './rssiDeviceSlice'; 24 | 25 | export default () => { 26 | const dispatch = useDispatch(); 27 | const serialPort = useSelector(getSerialPort); 28 | 29 | useEffect(() => { 30 | if (serialPort) { 31 | const device = createRssiDevice(serialPort); 32 | dispatch(setRssiDevice(device)); 33 | 34 | dispatch(resetRssiStore()); 35 | 36 | dispatch((_, getState) => { 37 | device.resumeReading( 38 | getState().app.rssi.delay, 39 | getState().app.rssi.scanRepeat 40 | ); 41 | }); 42 | 43 | let noDataTimeout: NodeJS.Timeout; 44 | dispatch((_, getState) => { 45 | noDataTimeout = setTimeout(() => { 46 | if ( 47 | getReadbackProtection(getState()) !== 48 | 'NRFDL_PROTECTION_STATUS_NONE' 49 | ) { 50 | dispatch(onReceiveNoRssiData()); 51 | } 52 | }, 3000); 53 | }); 54 | 55 | serialPort.on('data', data => { 56 | clearTimeout(noDataTimeout); 57 | dispatch(onReceiveRssiData(data)); 58 | }); 59 | serialPort.on('error', console.log); 60 | 61 | serialPort.on('close', () => { 62 | logger.info(`Serial Port ${serialPort.path} has been closed`); 63 | dispatch(clearRssiData()); 64 | }); 65 | 66 | return () => { 67 | if (serialPort.isOpen) { 68 | device.stopReading(); 69 | logger.info(`Stop RSSI Device`); 70 | serialPort.close(); 71 | logger.info(`Closing Serial Port ${serialPort.path}`); 72 | } 73 | }; 74 | } 75 | }, [dispatch, serialPort]); 76 | }; 77 | -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Nordic Semiconductor ASA 3 | * 4 | * SPDX-License-Identifier: LicenseRef-Nordic-4-Clause 5 | */ 6 | 7 | import React from 'react'; 8 | import { 9 | App, 10 | render, 11 | telemetry, 12 | } from '@nordicsemiconductor/pc-nrfconnect-shared'; 13 | 14 | import DeviceSelector from './app/DeviceSelector'; 15 | import SidePanel from './app/SidePanel/SidePanel'; 16 | import { reducer } from './app/store'; 17 | import Chart from './features/Chart/Chart'; 18 | 19 | telemetry.enableTelemetry(); 20 | 21 | render( 22 | } 25 | sidePanel={} 26 | panes={[{ name: 'RSSI Viewer', Main: Chart }]} 27 | /> 28 | ); 29 | -------------------------------------------------------------------------------- /svg.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Nordic Semiconductor ASA 3 | * 4 | * SPDX-License-Identifier: LicenseRef-Nordic-4-Clause 5 | */ 6 | 7 | declare module '!!@svgr!*.svg' { 8 | const svg: React.ElementType; 9 | export default svg; 10 | } 11 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Nordic Semiconductor ASA 3 | * 4 | * SPDX-License-Identifier: LicenseRef-Nordic-4-Clause 5 | */ 6 | 7 | const baseConfig = require('@nordicsemiconductor/pc-nrfconnect-shared/config/tailwind.config.js'); 8 | 9 | module.exports = { 10 | ...baseConfig, 11 | }; 12 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@nordicsemiconductor/pc-nrfconnect-shared/config/tsconfig.json" 3 | } 4 | --------------------------------------------------------------------------------