Multitech xDot Utils
MultitechDot.cpp
- Committer:
- Lucian Corduneanu
- Date:
- 2018-05-21
- Revision:
- 4:db99b2a7d062
- Parent:
- 3:7fa5603c10dc
- Child:
- 6:febbdd0d0e55
File content as of revision 4:db99b2a7d062:
#include "ChannelPlan.h" #include "plans/ChannelPlan_EU868.h" #include "MultitechDot.h" MultitechDot *MultitechDot::get_instance(struct dot_config *config) { using namespace lora; ChannelPlan *plan = new ChannelPlan_EU868(); MultitechDot *dot = (MultitechDot *) mDot::getInstance(plan); dot->config(config); return dot; } void MultitechDot::config(struct dot_config *config) { _config = config; this->setLogLevel(config->log_level); this->setDisableDutyCycle(config->disable_duty_cycle); logInfo("Start configuring the device"); if (!this->getStandbyFlag()) { logInfo("mbed-os library version: %d", MBED_LIBRARY_VERSION); // start from a well-known state logInfo("defaulting Dot configuration"); this->resetConfig(); this->resetNetworkSession(); // update configuration if necessary if (this->getJoinMode() != this->MANUAL) { logInfo("changing network join mode to MANUAL"); if (this->setJoinMode(this->MANUAL) != this->MDOT_OK) { logError("failed to set network join mode to MANUAL"); } } // in MANUAL join mode there is no join request/response transaction // as long as the Dot is configured correctly and provisioned correctly on the gateway, it should be able to communicate // network address - 4 bytes (00000001 - FFFFFFFE) // network session key - 16 bytes // data session key - 16 bytes // to provision your Dot with a Conduit gateway, follow the following steps // * ssh into the Conduit // * provision the Dot using the lora-query application: http://www.multitech.net/developer/software/lora/lora-network-server/ // lora-query -a 01020304 A 0102030401020304 <your Dot's device ID> 01020304010203040102030401020304 01020304010203040102030401020304 // * if you change the network address, network session key, or data session key, make sure you update them on the gateway // to provision your Dot with a 3rd party gateway, see the gateway or network provider documentation this->update_manual_config(config); // enable or disable Adaptive Data Rate this->setAdr(config->adr); // save changes to configuration logInfo("saving configuration"); if (!this->saveConfig()) { logError("failed to save configuration"); } // display configuration this->display_config(); } else { // restore the saved session if the dot woke from deepsleep mode // useful to use with deepsleep because session info is otherwise lost when the dot enters deepsleep logInfo("restoring network session from NVM"); this->restoreNetworkSession(); } } struct dot_config *MultitechDot::get_config() { return _config; } void MultitechDot::update_manual_config(struct dot_config *config) { BaseDot::update_manual_config( config->network_address, config->network_session_key, config->data_session_key, config->frequency_sub_band, config->public_network, config->ack ); } void MultitechDot::sleep_wake_rtc_or_interrupt(uint32_t delay_s, bool deepsleep) { if (deepsleep) { // for xDot, WAKE pin (connected to S2 on xDot-DK) is the only pin that can wake the processor from deepsleep // it is automatically configured when INTERRUPT or RTC_ALARM_OR_INTERRUPT is the wakeup source and deepsleep is true in the this->sleep call } else { // configure WAKE pin (connected to S2 on xDot-DK) as the pin that will wake the xDot from low power modes // other pins can be configured instead: GPIO0-3 or UART_RX this->setWakePin(WAKE); } logInfo("%s sleeping %lus or until interrupt on %s pin", deepsleep ? "deep" : "", delay_s, deepsleep ? "WAKE" : this->pinName2Str(this->getWakePin()).c_str()); logInfo("application will %s after waking up", deepsleep ? "execute from beginning" : "resume"); // lowest current consumption in sleep mode can only be achieved by configuring IOs as analog inputs with no pull resistors // the library handles all internal IOs automatically, but the external IOs are the application's responsibility // certain IOs may require internal pullup or pulldown resistors because leaving them floating would cause extra current consumption // for xDot: UART_*, I2C_*, SPI_*, GPIO*, WAKE // for mDot: XBEE_*, USBTX, USBRX, PB_0, PB_1 // steps are: // * save IO configuration // * configure IOs to reduce current consumption // * sleep // * restore IO configuration if (!deepsleep) { // save the GPIO state. this->sleep_save_io(); // configure GPIOs for lowest current this->sleep_configure_io(); } // go to sleep/deepsleep and wake using the RTC alarm after delay_s seconds or rising edge of configured wake pin (only the WAKE pin in deepsleep) // whichever comes first will wake the xDot this->sleep(delay_s, this->RTC_ALARM_OR_INTERRUPT, deepsleep); if (!deepsleep) { // restore the GPIO state. this->sleep_restore_io(); this->sleep_reset_hsi(); } } void MultitechDot::sleep_reset_hsi() { // Enable the HSI (to clock the ADC) RCC_OscInitTypeDef RCC_OscInitStruct; RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; HAL_RCC_OscConfig(&RCC_OscInitStruct); }