diff --git a/packages/outdoor-location-engine/.clangd b/packages/outdoor-location-engine/.clangd new file mode 100644 index 0000000..c8ef57c --- /dev/null +++ b/packages/outdoor-location-engine/.clangd @@ -0,0 +1,19 @@ +CompileFlags: + # Point to the west build output directory + CompilationDatabase: build/ + # Remove flags clangd doesn't understand from the ARM cross-compiler + Remove: + - -mfp16-format=ieee + - -fno-rerun-cse-after-loop + - -mno-thumb-interwork + - -fno-defer-pop + - --param=min-pagesize=0 + - -mfpu=* + - -mabi=aapcs + - -mthumb + - -fno-reorder-functions + Add: + - -Wno-unknown-warning-option + +Diagnostics: + UnusedIncludes: None diff --git a/packages/outdoor-location-engine/README.md b/packages/outdoor-location-engine/README.md index bf30ee9..4c54ea9 100644 --- a/packages/outdoor-location-engine/README.md +++ b/packages/outdoor-location-engine/README.md @@ -6,7 +6,58 @@ Software Architecture: ![arch](./arch.png) +## Getting Started +### 1. Install nRF Connect SDK + +1. Download and install [nRF Connect for Desktop](https://www.nordicsemi.com/Products/Development-tools/nRF-Connect-for-Desktop) +2. Open the **Toolchain Manager** inside it +3. Install **nRF Connect SDK v2.3.0** + +### 2. Set up your terminal + +Run this every time you open a new terminal: + +```bash +source scripts/env.sh +``` + +### 3. Build + +```bash +west build -b nrf9160dk_nrf9160_ns +``` + +### 4. Flash + +Plug in your nRF9160-DK via USB, then: + +```bash +west flash +``` + +### Troubleshooting + +Build fails with a cmake cache error - do a clean build: +```bash +west build -b nrf9160dk_nrf9160_ns --pristine +``` + +`west: command not found` - you forgot to source the env: +```bash +source scripts/env.sh +``` + +### Editor setup (Neovim + clangd) + +Run this once after cloning to generate `compile_commands.json` for LSP support: + +```bash +source scripts/env.sh +west build -b nrf9160dk_nrf9160_ns -- -DCMAKE_EXPORT_COMPILE_COMMANDS=ON +``` + +The `.clangd` config is already in the repo, clangd picks it up from there. ## MQTT Data format When sending data over mqtt the following format is used to send a comma separated string to save as much data as possible. diff --git a/packages/outdoor-location-engine/scripts/env.sh b/packages/outdoor-location-engine/scripts/env.sh new file mode 100755 index 0000000..0cbf405 --- /dev/null +++ b/packages/outdoor-location-engine/scripts/env.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# Source this file to set up the nRF Connect SDK environment in your current shell: +# source scripts/env.sh +# +# Requirements: nRF Connect SDK v2.3.0 installed via nRF Connect for Desktop +# macOS: /opt/nordic/ncs/v2.3.0 +# Linux: ~/ncs/v2.3.0 + +NCS_VERSION="v2.3.0" + +if [ -d "/opt/nordic/ncs/${NCS_VERSION}" ]; then + NCS_BASE="/opt/nordic/ncs" +elif [ -d "${HOME}/ncs/${NCS_VERSION}" ]; then + NCS_BASE="${HOME}/ncs" +else + echo "ERROR: nRF Connect SDK ${NCS_VERSION} not found." + echo "Install it via nRF Connect for Desktop, then update NCS_BASE in this script." + return 1 +fi + +export ZEPHYR_BASE="${NCS_BASE}/${NCS_VERSION}/zephyr" +export ZEPHYR_TOOLCHAIN_VARIANT=zephyr +export ZEPHYR_SDK_INSTALL_DIR="${NCS_BASE}/toolchains/${NCS_VERSION}/opt/zephyr-sdk" + +# Alias west/cmake directly instead of adding the whole toolchain bin to PATH +# This avoids shadowing system tools like git +alias west="${NCS_BASE}/toolchains/${NCS_VERSION}/bin/west" +export CMAKE="${NCS_BASE}/toolchains/${NCS_VERSION}/bin/cmake" + +echo "nRF Connect SDK ${NCS_VERSION} environment ready." +echo " ZEPHYR_BASE=${ZEPHYR_BASE}" diff --git a/packages/outdoor-location-engine/src/LocationEngine/LocationEngine.c b/packages/outdoor-location-engine/src/LocationEngine/LocationEngine.c index 01234af..e75b2a1 100644 --- a/packages/outdoor-location-engine/src/LocationEngine/LocationEngine.c +++ b/packages/outdoor-location-engine/src/LocationEngine/LocationEngine.c @@ -160,6 +160,7 @@ void location_gnss_low_accuracy_get(void) location_config_defaults_set(&config, ARRAY_SIZE(methods), methods); config.methods[0].gnss.accuracy = LOCATION_ACCURACY_LOW; + config.methods[0].gnss.priority_mode = true; LOG_INF("Requesting low accuracy GNSS location...\n"); @@ -183,6 +184,7 @@ void location_gnss_high_accuracy_get(void) location_config_defaults_set(&config, ARRAY_SIZE(methods), methods); config.methods[0].gnss.accuracy = LOCATION_ACCURACY_HIGH; + config.methods[0].gnss.priority_mode = true; LOG_INF("Requesting high accuracy GNSS location...\n"); @@ -205,6 +207,7 @@ void location_gnss_periodic_get(int period) enum location_method methods[] = {LOCATION_METHOD_GNSS, LOCATION_METHOD_CELLULAR}; location_config_defaults_set(&config, ARRAY_SIZE(methods), methods); + config.methods[0].gnss.priority_mode = true; config.interval = period; printk("Requesting %d s periodic GNSS location with cellular fallback...\n", period); diff --git a/packages/outdoor-location-engine/src/Responder/Responder.c b/packages/outdoor-location-engine/src/Responder/Responder.c index 7b69e51..dda9337 100644 --- a/packages/outdoor-location-engine/src/Responder/Responder.c +++ b/packages/outdoor-location-engine/src/Responder/Responder.c @@ -26,8 +26,9 @@ void turn_on_active_mode(void) void respond_to_ping(void) { // connect mqttsn, get location, publish, disconnect. - k_timer_init(&periodic_timer, periodic_work_handler, NULL); - k_timer_start(&periodic_timer, K_SECONDS(2), K_SECONDS(CONFIG_MQTT_SN_REFRESH_PERIOD_SECONDS)); + // TEST: pausing mqtt-sn polling to give GNSS full radio time + // k_timer_init(&periodic_timer, periodic_work_handler, NULL); + // k_timer_start(&periodic_timer, K_SECONDS(2), K_SECONDS(CONFIG_MQTT_SN_REFRESH_PERIOD_SECONDS)); location_gnss_high_accuracy_get(); k_sleep(K_SECONDS(30)); changeDispatcherState(DISPATCHER_STATE_IDLE); diff --git a/packages/outdoor-location-engine/src/main.c b/packages/outdoor-location-engine/src/main.c index 949c8b1..cdbfe03 100644 --- a/packages/outdoor-location-engine/src/main.c +++ b/packages/outdoor-location-engine/src/main.c @@ -41,6 +41,31 @@ static void lte_event_handler(const struct lte_lc_evt *const evt) LOG_INF("Connected to LTE"); k_sem_give(<e_connected); } + if (evt->nw_reg_status == LTE_LC_NW_REG_SEARCHING) { + char resp[256]; + + nrf_modem_at_cmd(resp, sizeof(resp), "AT%%XSIM?"); + LOG_INF("SIM status: %s", resp); + + nrf_modem_at_cmd(resp, sizeof(resp), "AT+CIMI"); + LOG_INF("IMSI: %s", resp); + + nrf_modem_at_cmd(resp, sizeof(resp), "AT+CRSM=176,28539,0,0,12"); + LOG_INF("FPLMN: %s", resp); + + nrf_modem_at_cmd(resp, sizeof(resp), "AT%%XMONITOR"); + LOG_INF("Monitor: %s", resp); + + nrf_modem_at_cmd(resp, sizeof(resp), "AT+CESQ"); + LOG_INF("Signal: %s", resp); + + nrf_modem_at_cmd(resp, sizeof(resp), "AT%%CONEVAL"); + LOG_INF("Connection eval: %s", resp); + + nrf_modem_at_cmd(resp, sizeof(resp), "AT%%XCBAND"); + LOG_INF("Current band: %s", resp); + } + break; default: break; @@ -76,12 +101,17 @@ static int initializeLte() { LOG_INF("Requesting EDRX mode"); // Todo: Turn on EDRX mode after development complete. - err = lte_lc_edrx_req(true); + err = lte_lc_edrx_req(false); if (err) { LOG_INF("lte_lc_edrx_req, error: %d\n", err); } + /* Unlock all bands — let modem scan freely and pick the best available. */ + char band_resp[64]; + nrf_modem_at_cmd(band_resp, sizeof(band_resp), "AT%%XBANDLOCK=0"); + LOG_INF("Band lock cleared: %s", band_resp); + err = lte_lc_connect(); k_sem_take(<e_connected, K_FOREVER);