|
| 1 | +/* mbed Microcontroller Library |
| 2 | + * Copyright (c) 2017 ARM Limited |
| 3 | + * |
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | + * you may not use this file except in compliance with the License. |
| 6 | + * You may obtain a copy of the License at |
| 7 | + * |
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | + * |
| 10 | + * Unless required by applicable law or agreed to in writing, software |
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | + * See the License for the specific language governing permissions and |
| 14 | + * limitations under the License. |
| 15 | + */ |
| 16 | + |
| 17 | +#include "utest.h" |
| 18 | +#include "unity.h" |
| 19 | +#include "greentea-client/test_env.h" |
| 20 | + |
| 21 | +#include "Semaphore.h" |
| 22 | + |
| 23 | +#include "mbed_trace.h" |
| 24 | +#define TRACE_GROUP "RTST" |
| 25 | + |
| 26 | +#include "LoRaRadio.h" |
| 27 | + |
| 28 | +#define SX1272 0xFF |
| 29 | +#define SX1276 0xEE |
| 30 | + |
| 31 | +#if (MBED_CONF_APP_LORA_RADIO == SX1272) |
| 32 | + #include "SX1272_LoRaRadio.h" |
| 33 | +#elif (MBED_CONF_APP_LORA_RADIO == SX1276) |
| 34 | + #include "SX1276_LoRaRadio.h" |
| 35 | +#else |
| 36 | + #error [NOT_SUPPORTED] Requires parameters from application config file. |
| 37 | +#endif |
| 38 | + |
| 39 | + |
| 40 | +using namespace utest::v1; |
| 41 | + |
| 42 | +static LoRaRadio* radio = NULL; |
| 43 | +rtos::Semaphore event_sem(0); |
| 44 | + |
| 45 | +enum event_t |
| 46 | +{ |
| 47 | + EV_NONE, |
| 48 | + EV_TX_DONE, |
| 49 | + EV_TX_TIMEOUT, |
| 50 | + EV_RX_DONE, |
| 51 | + EV_RX_TIMEOUT, |
| 52 | + EV_RX_ERROR, |
| 53 | +}; |
| 54 | +static volatile event_t received_event; |
| 55 | + |
| 56 | + |
| 57 | +static void tx_done() |
| 58 | +{ |
| 59 | + wait_ms(2); |
| 60 | + TEST_ASSERT_EQUAL(EV_NONE, received_event); |
| 61 | + received_event = EV_TX_DONE; |
| 62 | + TEST_ASSERT_EQUAL(osOK, event_sem.release()); |
| 63 | +} |
| 64 | + |
| 65 | +static void tx_timeout() |
| 66 | +{ |
| 67 | + wait_ms(2); |
| 68 | + TEST_ASSERT_EQUAL(EV_NONE, received_event); |
| 69 | + received_event = EV_TX_TIMEOUT; |
| 70 | + TEST_ASSERT_EQUAL(osOK, event_sem.release()); |
| 71 | +} |
| 72 | + |
| 73 | +static void rx_done(const uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr) |
| 74 | +{ |
| 75 | + wait_ms(2); |
| 76 | + TEST_ASSERT_EQUAL(EV_NONE, received_event); |
| 77 | + received_event = EV_RX_DONE; |
| 78 | + TEST_ASSERT_EQUAL(osOK, event_sem.release()); |
| 79 | +} |
| 80 | + |
| 81 | +static void rx_timeout() |
| 82 | +{ |
| 83 | + wait_ms(2); |
| 84 | + TEST_ASSERT_EQUAL(EV_NONE, received_event); |
| 85 | + received_event = EV_RX_TIMEOUT; |
| 86 | + TEST_ASSERT_EQUAL(osOK, event_sem.release()); |
| 87 | +} |
| 88 | + |
| 89 | +static void rx_error() |
| 90 | +{ |
| 91 | + wait_ms(2); |
| 92 | + TEST_ASSERT_EQUAL(EV_NONE, received_event); |
| 93 | + received_event = EV_RX_ERROR; |
| 94 | + TEST_ASSERT_EQUAL(osOK, event_sem.release()); |
| 95 | +} |
| 96 | + |
| 97 | +static radio_events radio_callbacks = |
| 98 | +{ |
| 99 | + .tx_done = tx_done, |
| 100 | + .tx_timeout = tx_timeout, |
| 101 | + .rx_done = rx_done, |
| 102 | + .rx_timeout = rx_timeout, |
| 103 | + .rx_error = rx_error |
| 104 | +}; |
| 105 | + |
| 106 | + |
| 107 | +void test_random() |
| 108 | +{ |
| 109 | + const uint32_t rand1 = radio->random(); |
| 110 | + const uint32_t rand2 = radio->random(); |
| 111 | + TEST_ASSERT_NOT_EQUAL(rand1, rand2); |
| 112 | +} |
| 113 | + |
| 114 | +void test_set_tx_config() |
| 115 | +{ |
| 116 | + uint8_t buffer[] = {0}; |
| 117 | + |
| 118 | + TEST_ASSERT_EQUAL(RF_IDLE, radio->get_status()); |
| 119 | + |
| 120 | + radio->set_tx_config(MODEM_LORA, 13, 0, |
| 121 | + 0, 7, |
| 122 | + 1, 8, |
| 123 | + false, true, false, |
| 124 | + 0, false, 100); |
| 125 | + radio->send(buffer, sizeof(buffer)); |
| 126 | + |
| 127 | + TEST_ASSERT_EQUAL(RF_TX_RUNNING, radio->get_status()); |
| 128 | + |
| 129 | + TEST_ASSERT_EQUAL(1, event_sem.wait(1000)); |
| 130 | + TEST_ASSERT_EQUAL(EV_TX_DONE, received_event); |
| 131 | + received_event = EV_NONE; |
| 132 | +} |
| 133 | + |
| 134 | +void test_set_rx_config() |
| 135 | +{ |
| 136 | + TEST_ASSERT_EQUAL(RF_IDLE, radio->get_status()); |
| 137 | + |
| 138 | + radio->set_rx_config(MODEM_LORA, 0, // modem, bandwidth, |
| 139 | + 7, 1, // datarate, coderate, |
| 140 | + 0, 8, // bandwidth_afc, preamble_len, |
| 141 | + 24, false, // symb_timeout, fix_len, |
| 142 | + 0, // payload_len, |
| 143 | + false, false, 0, // crc_on, freq_hop_on, hop_period, |
| 144 | + true, false); // iq_inverted, rx_continuous |
| 145 | + radio->receive(100); |
| 146 | + |
| 147 | + TEST_ASSERT_EQUAL(RF_RX_RUNNING, radio->get_status()); |
| 148 | + |
| 149 | + TEST_ASSERT_EQUAL(1, event_sem.wait(1000)); |
| 150 | + |
| 151 | + // Nobody was sending to us so timeout is expected. |
| 152 | + TEST_ASSERT_EQUAL(EV_RX_TIMEOUT, received_event); |
| 153 | + received_event = EV_NONE; |
| 154 | +} |
| 155 | + |
| 156 | +void test_time_on_air() |
| 157 | +{ |
| 158 | + radio->set_rx_config(MODEM_LORA, 0, |
| 159 | + 7, 1, |
| 160 | + 0, 8, |
| 161 | + 24, false, |
| 162 | + 0, |
| 163 | + false, false, 0, |
| 164 | + true, false); |
| 165 | + TEST_ASSERT_EQUAL(52, radio->time_on_air(MODEM_LORA, 20)); |
| 166 | + |
| 167 | + radio->set_tx_config(MODEM_LORA, 13, 0, |
| 168 | + 0, 7, |
| 169 | + 1, 8, |
| 170 | + false, true, false, |
| 171 | + 0, false, 100); |
| 172 | + TEST_ASSERT_EQUAL(72, radio->time_on_air(MODEM_LORA, 32)); |
| 173 | + |
| 174 | + // TODO: Add FSK tests |
| 175 | +} |
| 176 | + |
| 177 | +void test_perform_carrier_sense() |
| 178 | +{ |
| 179 | + TEST_ASSERT_TRUE(radio->perform_carrier_sense(MODEM_FSK, 865000000, -20, 1)); |
| 180 | + TEST_ASSERT_TRUE(radio->perform_carrier_sense(MODEM_LORA, 865000000, -20, 1)); |
| 181 | +} |
| 182 | + |
| 183 | +void test_check_rf_frequency() |
| 184 | +{ |
| 185 | + // Test EU868 frequency |
| 186 | + TEST_ASSERT_TRUE(radio->check_rf_frequency(865000000)); |
| 187 | +} |
| 188 | + |
| 189 | +// Test setup |
| 190 | +utest::v1::status_t test_setup(const size_t number_of_cases) { |
| 191 | + GREENTEA_SETUP(20, "default_auto"); |
| 192 | + |
| 193 | + mbed_trace_init(); |
| 194 | + |
| 195 | + return verbose_test_setup_handler(number_of_cases); |
| 196 | +} |
| 197 | + |
| 198 | +utest::v1::status_t case_setup_handler(const Case *const source, const size_t index_of_case) |
| 199 | +{ |
| 200 | +#if (MBED_CONF_APP_LORA_RADIO == SX1272) |
| 201 | + |
| 202 | + radio = new SX1272_LoRaRadio(MBED_CONF_APP_LORA_SPI_MOSI, |
| 203 | + MBED_CONF_APP_LORA_SPI_MISO, |
| 204 | + MBED_CONF_APP_LORA_SPI_SCLK, |
| 205 | + MBED_CONF_APP_LORA_CS, |
| 206 | + MBED_CONF_APP_LORA_RESET, |
| 207 | + MBED_CONF_APP_LORA_DIO0, |
| 208 | + MBED_CONF_APP_LORA_DIO1, |
| 209 | + MBED_CONF_APP_LORA_DIO2, |
| 210 | + MBED_CONF_APP_LORA_DIO3, |
| 211 | + MBED_CONF_APP_LORA_DIO4, |
| 212 | + MBED_CONF_APP_LORA_DIO5, |
| 213 | + MBED_CONF_APP_LORA_RF_SWITCH_CTL1, |
| 214 | + MBED_CONF_APP_LORA_RF_SWITCH_CTL2, |
| 215 | + MBED_CONF_APP_LORA_TXCTL, |
| 216 | + MBED_CONF_APP_LORA_RXCTL, |
| 217 | + MBED_CONF_APP_LORA_ANT_SWITCH, |
| 218 | + MBED_CONF_APP_LORA_PWR_AMP_CTL, |
| 219 | + MBED_CONF_APP_LORA_TCXO); |
| 220 | + |
| 221 | +#elif (MBED_CONF_APP_LORA_RADIO == SX1276) |
| 222 | + |
| 223 | + radio = new SX1276_LoRaRadio(MBED_CONF_APP_LORA_SPI_MOSI, |
| 224 | + MBED_CONF_APP_LORA_SPI_MISO, |
| 225 | + MBED_CONF_APP_LORA_SPI_SCLK, |
| 226 | + MBED_CONF_APP_LORA_CS, |
| 227 | + MBED_CONF_APP_LORA_RESET, |
| 228 | + MBED_CONF_APP_LORA_DIO0, |
| 229 | + MBED_CONF_APP_LORA_DIO1, |
| 230 | + MBED_CONF_APP_LORA_DIO2, |
| 231 | + MBED_CONF_APP_LORA_DIO3, |
| 232 | + MBED_CONF_APP_LORA_DIO4, |
| 233 | + MBED_CONF_APP_LORA_DIO5, |
| 234 | + MBED_CONF_APP_LORA_RF_SWITCH_CTL1, |
| 235 | + MBED_CONF_APP_LORA_RF_SWITCH_CTL2, |
| 236 | + MBED_CONF_APP_LORA_TXCTL, |
| 237 | + MBED_CONF_APP_LORA_RXCTL, |
| 238 | + MBED_CONF_APP_LORA_ANT_SWITCH, |
| 239 | + MBED_CONF_APP_LORA_PWR_AMP_CTL, |
| 240 | + MBED_CONF_APP_LORA_TCXO); |
| 241 | + |
| 242 | +#else |
| 243 | + #error [NOT_SUPPORTED] Unknown LoRa radio specified (SX1272,SX1276 are valid) |
| 244 | +#endif |
| 245 | + |
| 246 | + TEST_ASSERT(radio); |
| 247 | + radio->init_radio(&radio_callbacks); |
| 248 | + radio->sleep(); |
| 249 | + |
| 250 | + return greentea_case_setup_handler(source, index_of_case); |
| 251 | +} |
| 252 | + |
| 253 | +utest::v1::status_t case_teardown_handler(const Case *const source, const size_t passed, const size_t failed, const failure_t reason) |
| 254 | +{ |
| 255 | + radio->sleep(); |
| 256 | + |
| 257 | +#if (MBED_CONF_APP_LORA_RADIO == SX1272) |
| 258 | + delete static_cast<SX1272_LoRaRadio*>(radio); |
| 259 | +#elif (MBED_CONF_APP_LORA_RADIO == SX1276) |
| 260 | + delete static_cast<SX1276_LoRaRadio*>(radio); |
| 261 | +#else |
| 262 | + #error [NOT_SUPPORTED] Unknown LoRa radio specified (SX1272,SX1276 are valid) |
| 263 | +#endif |
| 264 | + radio = NULL; |
| 265 | + |
| 266 | + return greentea_case_teardown_handler(source, passed, failed, reason); |
| 267 | +} |
| 268 | + |
| 269 | +const Case cases[] = { |
| 270 | + Case("Test random", case_setup_handler, test_random, case_teardown_handler), |
| 271 | + Case("Test set_tx_config", case_setup_handler, test_set_tx_config, case_teardown_handler), |
| 272 | + Case("Test set_rx_config", case_setup_handler, test_set_rx_config, case_teardown_handler), |
| 273 | + Case("Test time_on_air", case_setup_handler, test_time_on_air, case_teardown_handler), |
| 274 | + Case("Test perform_carrier_sense", case_setup_handler, test_perform_carrier_sense, case_teardown_handler), |
| 275 | + Case("Test check_rf_frequency", case_setup_handler, test_check_rf_frequency, case_teardown_handler), |
| 276 | +}; |
| 277 | + |
| 278 | +Specification specification(test_setup, cases); |
| 279 | + |
| 280 | +int main() { |
| 281 | + return !Harness::run(specification); |
| 282 | +} |
0 commit comments