From e1288ab6c2f69c01ef68fc44faa1f0351bd294c2 Mon Sep 17 00:00:00 2001 From: Kimmo Vaisanen Date: Thu, 24 May 2018 15:37:59 +0300 Subject: [PATCH] Lora: Add greentea tests for LoRaRadio API This LoRaRadio test set adds basic tests which can be run with a single HW. --- TESTS/lorawan/loraradio/README.md | 17 ++ TESTS/lorawan/loraradio/main.cpp | 282 ++++++++++++++++++ TESTS/lorawan/loraradio/template_mbed_app.txt | 226 ++++++++++++++ 3 files changed, 525 insertions(+) create mode 100644 TESTS/lorawan/loraradio/README.md create mode 100644 TESTS/lorawan/loraradio/main.cpp create mode 100644 TESTS/lorawan/loraradio/template_mbed_app.txt diff --git a/TESTS/lorawan/loraradio/README.md b/TESTS/lorawan/loraradio/README.md new file mode 100644 index 0000000000..562a24eee3 --- /dev/null +++ b/TESTS/lorawan/loraradio/README.md @@ -0,0 +1,17 @@ +# Description + +This document describes how to run LoRaRadio API tests. + +## Configuring target HW + +Before starting to test, the target HW must be configured for the test. This can be done by either modifying the application configuration `json` file (if using currently supported Semtech SX1272 or SX1276 radios) or implementing driver construction into test source. + +The default mbed_app.json file provides configuration for some already supported HWs. + +## Running tests + +You can use the following command to run tests: + +`mbed test -n mbed-os-tests-lorawan-loraradio -m TARGET -t GCC_ARM --app-config mbed-os/TESTS/lorawan/loraradio/template_mbed_app.txt` + +Replace TARGET with the target device. diff --git a/TESTS/lorawan/loraradio/main.cpp b/TESTS/lorawan/loraradio/main.cpp new file mode 100644 index 0000000000..1f5c6d171b --- /dev/null +++ b/TESTS/lorawan/loraradio/main.cpp @@ -0,0 +1,282 @@ +/* mbed Microcontroller Library + * Copyright (c) 2017 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "utest.h" +#include "unity.h" +#include "greentea-client/test_env.h" + +#include "Semaphore.h" + +#include "mbed_trace.h" +#define TRACE_GROUP "RTST" + +#include "LoRaRadio.h" + +#define SX1272 0xFF +#define SX1276 0xEE + +#if (MBED_CONF_APP_LORA_RADIO == SX1272) + #include "SX1272_LoRaRadio.h" +#elif (MBED_CONF_APP_LORA_RADIO == SX1276) + #include "SX1276_LoRaRadio.h" +#else + #error [NOT_SUPPORTED] Requires parameters from application config file. +#endif + + +using namespace utest::v1; + +static LoRaRadio* radio = NULL; +rtos::Semaphore event_sem(0); + +enum event_t +{ + EV_NONE, + EV_TX_DONE, + EV_TX_TIMEOUT, + EV_RX_DONE, + EV_RX_TIMEOUT, + EV_RX_ERROR, +}; +static volatile event_t received_event; + + +static void tx_done() +{ + wait_ms(2); + TEST_ASSERT_EQUAL(EV_NONE, received_event); + received_event = EV_TX_DONE; + TEST_ASSERT_EQUAL(osOK, event_sem.release()); +} + +static void tx_timeout() +{ + wait_ms(2); + TEST_ASSERT_EQUAL(EV_NONE, received_event); + received_event = EV_TX_TIMEOUT; + TEST_ASSERT_EQUAL(osOK, event_sem.release()); +} + +static void rx_done(const uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr) +{ + wait_ms(2); + TEST_ASSERT_EQUAL(EV_NONE, received_event); + received_event = EV_RX_DONE; + TEST_ASSERT_EQUAL(osOK, event_sem.release()); +} + +static void rx_timeout() +{ + wait_ms(2); + TEST_ASSERT_EQUAL(EV_NONE, received_event); + received_event = EV_RX_TIMEOUT; + TEST_ASSERT_EQUAL(osOK, event_sem.release()); +} + +static void rx_error() +{ + wait_ms(2); + TEST_ASSERT_EQUAL(EV_NONE, received_event); + received_event = EV_RX_ERROR; + TEST_ASSERT_EQUAL(osOK, event_sem.release()); +} + +static radio_events radio_callbacks = +{ + .tx_done = tx_done, + .tx_timeout = tx_timeout, + .rx_done = rx_done, + .rx_timeout = rx_timeout, + .rx_error = rx_error +}; + + +void test_random() +{ + const uint32_t rand1 = radio->random(); + const uint32_t rand2 = radio->random(); + TEST_ASSERT_NOT_EQUAL(rand1, rand2); +} + +void test_set_tx_config() +{ + uint8_t buffer[] = {0}; + + TEST_ASSERT_EQUAL(RF_IDLE, radio->get_status()); + + radio->set_tx_config(MODEM_LORA, 13, 0, + 0, 7, + 1, 8, + false, true, false, + 0, false, 100); + radio->send(buffer, sizeof(buffer)); + + TEST_ASSERT_EQUAL(RF_TX_RUNNING, radio->get_status()); + + TEST_ASSERT_EQUAL(1, event_sem.wait(1000)); + TEST_ASSERT_EQUAL(EV_TX_DONE, received_event); + received_event = EV_NONE; +} + +void test_set_rx_config() +{ + TEST_ASSERT_EQUAL(RF_IDLE, radio->get_status()); + + radio->set_rx_config(MODEM_LORA, 0, // modem, bandwidth, + 7, 1, // datarate, coderate, + 0, 8, // bandwidth_afc, preamble_len, + 24, false, // symb_timeout, fix_len, + 0, // payload_len, + false, false, 0, // crc_on, freq_hop_on, hop_period, + true, false); // iq_inverted, rx_continuous + radio->receive(100); + + TEST_ASSERT_EQUAL(RF_RX_RUNNING, radio->get_status()); + + TEST_ASSERT_EQUAL(1, event_sem.wait(1000)); + + // Nobody was sending to us so timeout is expected. + TEST_ASSERT_EQUAL(EV_RX_TIMEOUT, received_event); + received_event = EV_NONE; +} + +void test_time_on_air() +{ + radio->set_rx_config(MODEM_LORA, 0, + 7, 1, + 0, 8, + 24, false, + 0, + false, false, 0, + true, false); + TEST_ASSERT_EQUAL(52, radio->time_on_air(MODEM_LORA, 20)); + + radio->set_tx_config(MODEM_LORA, 13, 0, + 0, 7, + 1, 8, + false, true, false, + 0, false, 100); + TEST_ASSERT_EQUAL(72, radio->time_on_air(MODEM_LORA, 32)); + + // TODO: Add FSK tests +} + +void test_perform_carrier_sense() +{ + TEST_ASSERT_TRUE(radio->perform_carrier_sense(MODEM_FSK, 865000000, -20, 1)); + TEST_ASSERT_TRUE(radio->perform_carrier_sense(MODEM_LORA, 865000000, -20, 1)); +} + +void test_check_rf_frequency() +{ + // Test EU868 frequency + TEST_ASSERT_TRUE(radio->check_rf_frequency(865000000)); +} + +// Test setup +utest::v1::status_t test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(20, "default_auto"); + + mbed_trace_init(); + + return verbose_test_setup_handler(number_of_cases); +} + +utest::v1::status_t case_setup_handler(const Case *const source, const size_t index_of_case) +{ +#if (MBED_CONF_APP_LORA_RADIO == SX1272) + + radio = new SX1272_LoRaRadio(MBED_CONF_APP_LORA_SPI_MOSI, + MBED_CONF_APP_LORA_SPI_MISO, + MBED_CONF_APP_LORA_SPI_SCLK, + MBED_CONF_APP_LORA_CS, + MBED_CONF_APP_LORA_RESET, + MBED_CONF_APP_LORA_DIO0, + MBED_CONF_APP_LORA_DIO1, + MBED_CONF_APP_LORA_DIO2, + MBED_CONF_APP_LORA_DIO3, + MBED_CONF_APP_LORA_DIO4, + MBED_CONF_APP_LORA_DIO5, + MBED_CONF_APP_LORA_RF_SWITCH_CTL1, + MBED_CONF_APP_LORA_RF_SWITCH_CTL2, + MBED_CONF_APP_LORA_TXCTL, + MBED_CONF_APP_LORA_RXCTL, + MBED_CONF_APP_LORA_ANT_SWITCH, + MBED_CONF_APP_LORA_PWR_AMP_CTL, + MBED_CONF_APP_LORA_TCXO); + +#elif (MBED_CONF_APP_LORA_RADIO == SX1276) + + radio = new SX1276_LoRaRadio(MBED_CONF_APP_LORA_SPI_MOSI, + MBED_CONF_APP_LORA_SPI_MISO, + MBED_CONF_APP_LORA_SPI_SCLK, + MBED_CONF_APP_LORA_CS, + MBED_CONF_APP_LORA_RESET, + MBED_CONF_APP_LORA_DIO0, + MBED_CONF_APP_LORA_DIO1, + MBED_CONF_APP_LORA_DIO2, + MBED_CONF_APP_LORA_DIO3, + MBED_CONF_APP_LORA_DIO4, + MBED_CONF_APP_LORA_DIO5, + MBED_CONF_APP_LORA_RF_SWITCH_CTL1, + MBED_CONF_APP_LORA_RF_SWITCH_CTL2, + MBED_CONF_APP_LORA_TXCTL, + MBED_CONF_APP_LORA_RXCTL, + MBED_CONF_APP_LORA_ANT_SWITCH, + MBED_CONF_APP_LORA_PWR_AMP_CTL, + MBED_CONF_APP_LORA_TCXO); + +#else + #error [NOT_SUPPORTED] Unknown LoRa radio specified (SX1272,SX1276 are valid) +#endif + + TEST_ASSERT(radio); + radio->init_radio(&radio_callbacks); + radio->sleep(); + + return greentea_case_setup_handler(source, index_of_case); +} + +utest::v1::status_t case_teardown_handler(const Case *const source, const size_t passed, const size_t failed, const failure_t reason) +{ + radio->sleep(); + +#if (MBED_CONF_APP_LORA_RADIO == SX1272) + delete static_cast(radio); +#elif (MBED_CONF_APP_LORA_RADIO == SX1276) + delete static_cast(radio); +#else + #error [NOT_SUPPORTED] Unknown LoRa radio specified (SX1272,SX1276 are valid) +#endif + radio = NULL; + + return greentea_case_teardown_handler(source, passed, failed, reason); +} + +const Case cases[] = { + Case("Test random", case_setup_handler, test_random, case_teardown_handler), + Case("Test set_tx_config", case_setup_handler, test_set_tx_config, case_teardown_handler), + Case("Test set_rx_config", case_setup_handler, test_set_rx_config, case_teardown_handler), + Case("Test time_on_air", case_setup_handler, test_time_on_air, case_teardown_handler), + Case("Test perform_carrier_sense", case_setup_handler, test_perform_carrier_sense, case_teardown_handler), + Case("Test check_rf_frequency", case_setup_handler, test_check_rf_frequency, case_teardown_handler), +}; + +Specification specification(test_setup, cases); + +int main() { + return !Harness::run(specification); +} diff --git a/TESTS/lorawan/loraradio/template_mbed_app.txt b/TESTS/lorawan/loraradio/template_mbed_app.txt new file mode 100644 index 0000000000..da5d12d0a7 --- /dev/null +++ b/TESTS/lorawan/loraradio/template_mbed_app.txt @@ -0,0 +1,226 @@ +{ + "config": { + "lora-radio": { + "help": "Which radio to use (options: SX1272,SX1276)", + "value": "SX1276" + }, + + "lora-spi-mosi": { "value": "NC" }, + "lora-spi-miso": { "value": "NC" }, + "lora-spi-sclk": { "value": "NC" }, + "lora-cs": { "value": "NC" }, + "lora-reset": { "value": "NC" }, + "lora-dio0": { "value": "NC" }, + "lora-dio1": { "value": "NC" }, + "lora-dio2": { "value": "NC" }, + "lora-dio3": { "value": "NC" }, + "lora-dio4": { "value": "NC" }, + "lora-dio5": { "value": "NC" }, + "lora-rf-switch-ctl1": { "value": "NC" }, + "lora-rf-switch-ctl2": { "value": "NC" }, + "lora-txctl": { "value": "NC" }, + "lora-rxctl": { "value": "NC" }, + "lora-ant-switch": { "value": "NC" }, + "lora-pwr-amp-ctl": { "value": "NC" }, + "lora-tcxo": { "value": "NC" } + }, + "target_overrides": { + + "K64F": { + "lora-spi-mosi": "D11", + "lora-spi-miso": "D12", + "lora-spi-sclk": "D13", + "lora-cs": "D10", + "lora-reset": "A0", + "lora-dio0": "D2", + "lora-dio1": "D3", + "lora-dio2": "D4", + "lora-dio3": "D5", + "lora-dio4": "D8", + "lora-dio5": "D9", + "lora-rf-switch-ctl1": "NC", + "lora-rf-switch-ctl2": "NC", + "lora-txctl": "NC", + "lora-rxctl": "NC", + "lora-ant-switch": "A4", + "lora-pwr-amp-ctl": "NC", + "lora-tcxo": "NC" + }, + + "DISCO_L072CZ_LRWAN1": { + "lora-radio": "SX1276", + "lora-spi-mosi": "PA_7", + "lora-spi-miso": "PA_6", + "lora-spi-sclk": "PB_3", + "lora-cs": "PA_15", + "lora-reset": "PC_0", + "lora-dio0": "PB_4", + "lora-dio1": "PB_1", + "lora-dio2": "PB_0", + "lora-dio3": "PC_13", + "lora-dio4": "NC", + "lora-dio5": "NC", + "lora-rf-switch-ctl1": "NC", + "lora-rf-switch-ctl2": "NC", + "lora-txctl": "PC_2", + "lora-rxctl": "PA_1", + "lora-ant-switch": "NC", + "lora-pwr-amp-ctl": "PC_1", + "lora-tcxo": "PA_12" + }, + + "MTB_MURATA_ABZ": { + "lora-radio": "SX1276", + "lora-spi-mosi": "PA_7", + "lora-spi-miso": "PA_6", + "lora-spi-sclk": "PB_3", + "lora-cs": "PA_15", + "lora-reset": "PC_0", + "lora-dio0": "PB_4", + "lora-dio1": "PB_1", + "lora-dio2": "PB_0", + "lora-dio3": "PC_13", + "lora-dio4": "NC", + "lora-dio5": "NC", + "lora-rf-switch-ctl1": "NC", + "lora-rf-switch-ctl2": "NC", + "lora-txctl": "PC_2", + "lora-rxctl": "PA_1", + "lora-ant-switch": "NC", + "lora-pwr-amp-ctl": "PC_1", + "lora-tcxo": "PA_12" + }, + + "XDOT_L151CC": { + "lora-radio": "SX1272", + "lora-spi-mosi": "LORA_MOSI", + "lora-spi-miso": "LORA_MISO", + "lora-spi-sclk": "LORA_SCK", + "lora-cs": "LORA_NSS", + "lora-reset": "LORA_RESET", + "lora-dio0": "LORA_DIO0", + "lora-dio1": "LORA_DIO1", + "lora-dio2": "LORA_DIO2", + "lora-dio3": "LORA_DIO3", + "lora-dio4": "LORA_DIO4", + "lora-dio5": "NC", + "lora-rf-switch-ctl1": "NC", + "lora-rf-switch-ctl2": "NC", + "lora-txctl": "NC", + "lora-rxctl": "NC", + "lora-ant-switch": "NC", + "lora-pwr-amp-ctl": "NC", + "lora-tcxo": "NC" + }, + + "MTB_MTS_XDOT": { + "lora-radio": "SX1272", + "lora-spi-mosi": "LORA_MOSI", + "lora-spi-miso": "LORA_MISO", + "lora-spi-sclk": "LORA_SCK", + "lora-cs": "LORA_NSS", + "lora-reset": "LORA_RESET", + "lora-dio0": "LORA_DIO0", + "lora-dio1": "LORA_DIO1", + "lora-dio2": "LORA_DIO2", + "lora-dio3": "LORA_DIO3", + "lora-dio4": "LORA_DIO4", + "lora-dio5": "NC", + "lora-rf-switch-ctl1": "NC", + "lora-rf-switch-ctl2": "NC", + "lora-txctl": "NC", + "lora-rxctl": "NC", + "lora-ant-switch": "NC", + "lora-pwr-amp-ctl": "NC", + "lora-tcxo": "NC" + }, + + "LTEK_FF1705": { + "lora-radio": "SX1272", + "lora-spi-mosi": "LORA_MOSI", + "lora-spi-miso": "LORA_MISO", + "lora-spi-sclk": "LORA_SCK", + "lora-cs": "LORA_NSS", + "lora-reset": "LORA_RESET", + "lora-dio0": "LORA_DIO0", + "lora-dio1": "LORA_DIO1", + "lora-dio2": "LORA_DIO2", + "lora-dio3": "LORA_DIO3", + "lora-dio4": "LORA_DIO4", + "lora-dio5": "NC", + "lora-rf-switch-ctl1": "NC", + "lora-rf-switch-ctl2": "NC", + "lora-txctl": "NC", + "lora-rxctl": "NC", + "lora-ant-switch": "NC", + "lora-pwr-amp-ctl": "NC", + "lora-tcxo": "NC" + }, + + "MTS_MDOT_F411RE": { + "lora-radio": "SX1272", + "lora-spi-mosi": "LORA_MOSI", + "lora-spi-miso": "LORA_MISO", + "lora-spi-sclk": "LORA_SCK", + "lora-cs": "LORA_NSS", + "lora-reset": "LORA_RESET", + "lora-dio0": "LORA_DIO0", + "lora-dio1": "LORA_DIO1", + "lora-dio2": "LORA_DIO2", + "lora-dio3": "LORA_DIO3", + "lora-dio4": "LORA_DIO4", + "lora-dio5": "LORA_DIO5", + "lora-rf-switch-ctl1": "NC", + "lora-rf-switch-ctl2": "NC", + "lora-txctl": "LORA_TXCTL", + "lora-rxctl": "LORA_RXCTL", + "lora-ant-switch": "NC", + "lora-pwr-amp-ctl": "NC", + "lora-tcxo": "NC" + }, + + "MTB_ADV_WISE_1510": { + "lora-radio": "SX1276", + "lora-spi-mosi": "SPI_RF_MOSI", + "lora-spi-miso": "SPI_RF_MISO", + "lora-spi-sclk": "SPI_RF_SCK", + "lora-cs": "SPI_RF_CS", + "lora-reset": "SPI_RF_RESET", + "lora-dio0": "DIO0", + "lora-dio1": "DIO1", + "lora-dio2": "DIO2", + "lora-dio3": "DIO3", + "lora-dio4": "DIO4", + "lora-dio5": "DIO5", + "lora-rf-switch-ctl1": "NC", + "lora-rf-switch-ctl2": "NC", + "lora-txctl": "NC", + "lora-rxctl": "NC", + "lora-ant-switch": "ANT_SWITCH", + "lora-pwr-amp-ctl": "NC", + "lora-tcxo": "NC" + }, + + "MTB_RAK811": { + "lora-radio": "SX1276", + "lora-spi-mosi": "SPI_RF_MOSI", + "lora-spi-miso": "SPI_RF_MISO", + "lora-spi-sclk": "SPI_RF_SCK", + "lora-cs": "SPI_RF_CS", + "lora-reset": "SPI_RF_RESET", + "lora-dio0": "DIO0", + "lora-dio1": "DIO1", + "lora-dio2": "DIO2", + "lora-dio3": "DIO3", + "lora-dio4": "DIO4", + "lora-dio5": "NC", + "lora-rf-switch-ctl1": "NC", + "lora-rf-switch-ctl2": "NC", + "lora-txctl": "ANT_CTX_PA", + "lora-rxctl": "ANT_CRX_RX", + "lora-ant-switch": "NC", + "lora-pwr-amp-ctl": "NC", + "lora-tcxo": "RF_TCXO_EN" + } + } +}