Full functions
Dependencies: DHT22 libmDot-mbed5
Fork of mDot_LoRa_Connect_ABPA by
dot_util.cpp
00001 #include "dot_util.h" 00002 #if defined(TARGET_XDOT_L151CC) 00003 #include "xdot_low_power.h" 00004 #endif 00005 00006 #if defined(TARGET_MTS_MDOT_F411RE) 00007 uint32_t portA[6]; 00008 uint32_t portB[6]; 00009 uint32_t portC[6]; 00010 uint32_t portD[6]; 00011 uint32_t portH[6]; 00012 #endif 00013 00014 00015 void display_config() { 00016 // display configuration and library version information 00017 logInfo("====================="); 00018 logInfo("general configuration"); 00019 logInfo("====================="); 00020 logInfo("version ------------------ %s", dot->getId().c_str()); 00021 logInfo("device ID/EUI ------------ %s", mts::Text::bin2hexString(dot->getDeviceId()).c_str()); 00022 logInfo("default channel plan ----- %s", mDot::FrequencyBandStr(dot->getDefaultFrequencyBand()).c_str()); 00023 logInfo("current channel plan ----- %s", mDot::FrequencyBandStr(dot->getFrequencyBand()).c_str()); 00024 if (lora::ChannelPlan::IsPlanFixed(dot->getFrequencyBand())) { 00025 logInfo("frequency sub band ------- %u", dot->getFrequencySubBand()); 00026 } 00027 logInfo("public network ----------- %s", dot->getPublicNetwork() ? "on" : "off"); 00028 logInfo("========================="); 00029 logInfo("credentials configuration"); 00030 logInfo("========================="); 00031 logInfo("device class ------------- %s", dot->getClass().c_str()); 00032 logInfo("network join mode -------- %s", mDot::JoinModeStr(dot->getJoinMode()).c_str()); 00033 if (dot->getJoinMode() == mDot::MANUAL || dot->getJoinMode() == mDot::PEER_TO_PEER) { 00034 logInfo("network address ---------- %s", mts::Text::bin2hexString(dot->getNetworkAddress()).c_str()); 00035 logInfo("network session key------- %s", mts::Text::bin2hexString(dot->getNetworkSessionKey()).c_str()); 00036 logInfo("data session key---------- %s", mts::Text::bin2hexString(dot->getDataSessionKey()).c_str()); 00037 } else { 00038 logInfo("network name ------------- %s", dot->getNetworkName().c_str()); 00039 logInfo("network phrase ----------- %s", dot->getNetworkPassphrase().c_str()); 00040 logInfo("network EUI -------------- %s", mts::Text::bin2hexString(dot->getNetworkId()).c_str()); 00041 logInfo("network KEY -------------- %s", mts::Text::bin2hexString(dot->getNetworkKey()).c_str()); 00042 } 00043 logInfo("========================"); 00044 logInfo("communication parameters"); 00045 logInfo("========================"); 00046 if (dot->getJoinMode() == mDot::PEER_TO_PEER) { 00047 logInfo("TX frequency ------------- %lu", dot->getTxFrequency()); 00048 } else { 00049 logInfo("acks --------------------- %s, %u attempts", dot->getAck() > 0 ? "on" : "off", dot->getAck()); 00050 } 00051 logInfo("TX datarate -------------- %s", mDot::DataRateStr(dot->getTxDataRate()).c_str()); 00052 logInfo("TX power ----------------- %lu dBm", dot->getTxPower()); 00053 logInfo("antenna gain ------------- %u dBm", dot->getAntennaGain()); 00054 logInfo("LBT ---------------------- %s", dot->getLbtTimeUs() ? "on" : "off"); 00055 if (dot->getLbtTimeUs()) { 00056 logInfo("LBT time ----------------- %lu us", dot->getLbtTimeUs()); 00057 logInfo("LBT threshold ------------ %d dBm", dot->getLbtThreshold()); 00058 } 00059 } 00060 00061 void update_ota_config_name_phrase(std::string network_name, std::string network_passphrase, uint8_t frequency_sub_band, bool public_network, uint8_t ack) { 00062 std::string current_network_name = dot->getNetworkName(); 00063 std::string current_network_passphrase = dot->getNetworkPassphrase(); 00064 uint8_t current_frequency_sub_band = dot->getFrequencySubBand(); 00065 bool current_public_network = dot->getPublicNetwork(); 00066 uint8_t current_ack = dot->getAck(); 00067 00068 if (current_network_name != network_name) { 00069 logInfo("changing network name from \"%s\" to \"%s\"", current_network_name.c_str(), network_name.c_str()); 00070 if (dot->setNetworkName(network_name) != mDot::MDOT_OK) { 00071 logError("failed to set network name to \"%s\"", network_name.c_str()); 00072 } 00073 } 00074 00075 if (current_network_passphrase != network_passphrase) { 00076 logInfo("changing network passphrase from \"%s\" to \"%s\"", current_network_passphrase.c_str(), network_passphrase.c_str()); 00077 if (dot->setNetworkPassphrase(network_passphrase) != mDot::MDOT_OK) { 00078 logError("failed to set network passphrase to \"%s\"", network_passphrase.c_str()); 00079 } 00080 } 00081 00082 if (lora::ChannelPlan::IsPlanFixed(dot->getFrequencyBand())) { 00083 if (current_frequency_sub_band != frequency_sub_band) { 00084 logInfo("changing frequency sub band from %u to %u", current_frequency_sub_band, frequency_sub_band); 00085 if (dot->setFrequencySubBand(frequency_sub_band) != mDot::MDOT_OK) { 00086 logError("failed to set frequency sub band to %u", frequency_sub_band); 00087 } 00088 } 00089 } 00090 00091 if (current_public_network != public_network) { 00092 logInfo("changing public network from %s to %s", current_public_network ? "on" : "off", public_network ? "on" : "off"); 00093 if (dot->setPublicNetwork(public_network) != mDot::MDOT_OK) { 00094 logError("failed to set public network to %s", public_network ? "on" : "off"); 00095 } 00096 } 00097 00098 if (current_ack != ack) { 00099 logInfo("changing acks from %u to %u", current_ack, ack); 00100 if (dot->setAck(ack) != mDot::MDOT_OK) { 00101 logError("failed to set acks to %u", ack); 00102 } 00103 } 00104 } 00105 00106 void update_ota_config_id_key(uint8_t *network_id, uint8_t *network_key, uint8_t frequency_sub_band, bool public_network, uint8_t ack) { 00107 std::vector<uint8_t> current_network_id = dot->getNetworkId(); 00108 std::vector<uint8_t> current_network_key = dot->getNetworkKey(); 00109 uint8_t current_frequency_sub_band = dot->getFrequencySubBand(); 00110 bool current_public_network = dot->getPublicNetwork(); 00111 uint8_t current_ack = dot->getAck(); 00112 00113 std::vector<uint8_t> network_id_vector(network_id, network_id + 8); 00114 std::vector<uint8_t> network_key_vector(network_key, network_key + 16); 00115 00116 if (current_network_id != network_id_vector) { 00117 logInfo("changing network ID from \"%s\" to \"%s\"", mts::Text::bin2hexString(current_network_id).c_str(), mts::Text::bin2hexString(network_id_vector).c_str()); 00118 if (dot->setNetworkId(network_id_vector) != mDot::MDOT_OK) { 00119 logError("failed to set network ID to \"%s\"", mts::Text::bin2hexString(network_id_vector).c_str()); 00120 } 00121 } 00122 00123 if (current_network_key != network_key_vector) { 00124 logInfo("changing network KEY from \"%s\" to \"%s\"", mts::Text::bin2hexString(current_network_key).c_str(), mts::Text::bin2hexString(network_key_vector).c_str()); 00125 if (dot->setNetworkKey(network_key_vector) != mDot::MDOT_OK) { 00126 logError("failed to set network KEY to \"%s\"", mts::Text::bin2hexString(network_key_vector).c_str()); 00127 } 00128 } 00129 00130 if (lora::ChannelPlan::IsPlanFixed(dot->getFrequencyBand())) { 00131 if (current_frequency_sub_band != frequency_sub_band) { 00132 logInfo("changing frequency sub band from %u to %u", current_frequency_sub_band, frequency_sub_band); 00133 if (dot->setFrequencySubBand(frequency_sub_band) != mDot::MDOT_OK) { 00134 logError("failed to set frequency sub band to %u", frequency_sub_band); 00135 } 00136 } 00137 } 00138 00139 if (current_public_network != public_network) { 00140 logInfo("changing public network from %s to %s", current_public_network ? "on" : "off", public_network ? "on" : "off"); 00141 if (dot->setPublicNetwork(public_network) != mDot::MDOT_OK) { 00142 logError("failed to set public network to %s", public_network ? "on" : "off"); 00143 } 00144 } 00145 00146 if (current_ack != ack) { 00147 logInfo("changing acks from %u to %u", current_ack, ack); 00148 if (dot->setAck(ack) != mDot::MDOT_OK) { 00149 logError("failed to set acks to %u", ack); 00150 } 00151 } 00152 } 00153 00154 void update_manual_config(uint8_t *network_address, uint8_t *network_session_key, uint8_t *data_session_key, uint8_t frequency_sub_band, bool public_network, uint8_t ack) { 00155 std::vector<uint8_t> current_network_address = dot->getNetworkAddress(); 00156 std::vector<uint8_t> current_network_session_key = dot->getNetworkSessionKey(); 00157 std::vector<uint8_t> current_data_session_key = dot->getDataSessionKey(); 00158 uint8_t current_frequency_sub_band = dot->getFrequencySubBand(); 00159 bool current_public_network = dot->getPublicNetwork(); 00160 uint8_t current_ack = dot->getAck(); 00161 00162 std::vector<uint8_t> network_address_vector(network_address, network_address + 4); 00163 std::vector<uint8_t> network_session_key_vector(network_session_key, network_session_key + 16); 00164 std::vector<uint8_t> data_session_key_vector(data_session_key, data_session_key + 16); 00165 00166 if (current_network_address != network_address_vector) { 00167 logInfo("changing network address from \"%s\" to \"%s\"", mts::Text::bin2hexString(current_network_address).c_str(), mts::Text::bin2hexString(network_address_vector).c_str()); 00168 if (dot->setNetworkAddress(network_address_vector) != mDot::MDOT_OK) { 00169 logError("failed to set network address to \"%s\"", mts::Text::bin2hexString(network_address_vector).c_str()); 00170 } 00171 } 00172 00173 if (current_network_session_key != network_session_key_vector) { 00174 logInfo("changing network session key from \"%s\" to \"%s\"", mts::Text::bin2hexString(current_network_session_key).c_str(), mts::Text::bin2hexString(network_session_key_vector).c_str()); 00175 if (dot->setNetworkSessionKey(network_session_key_vector) != mDot::MDOT_OK) { 00176 logError("failed to set network session key to \"%s\"", mts::Text::bin2hexString(network_session_key_vector).c_str()); 00177 } 00178 } 00179 00180 if (current_data_session_key != data_session_key_vector) { 00181 logInfo("changing data session key from \"%s\" to \"%s\"", mts::Text::bin2hexString(current_data_session_key).c_str(), mts::Text::bin2hexString(data_session_key_vector).c_str()); 00182 if (dot->setDataSessionKey(data_session_key_vector) != mDot::MDOT_OK) { 00183 logError("failed to set data session key to \"%s\"", mts::Text::bin2hexString(data_session_key_vector).c_str()); 00184 } 00185 } 00186 00187 if (current_frequency_sub_band != frequency_sub_band) { 00188 logInfo("changing frequency sub band from %u to %u", current_frequency_sub_band, frequency_sub_band); 00189 if (dot->setFrequencySubBand(frequency_sub_band) != mDot::MDOT_OK) { 00190 logError("failed to set frequency sub band to %u", frequency_sub_band); 00191 } 00192 } 00193 00194 if (current_public_network != public_network) { 00195 logInfo("changing public network from %s to %s", current_public_network ? "on" : "off", public_network ? "on" : "off"); 00196 if (dot->setPublicNetwork(public_network) != mDot::MDOT_OK) { 00197 logError("failed to set public network to %s", public_network ? "on" : "off"); 00198 } 00199 } 00200 00201 if (current_ack != ack) { 00202 logInfo("changing acks from %u to %u", current_ack, ack); 00203 if (dot->setAck(ack) != mDot::MDOT_OK) { 00204 logError("failed to set acks to %u", ack); 00205 } 00206 } 00207 } 00208 00209 void update_peer_to_peer_config(uint8_t *network_address, uint8_t *network_session_key, uint8_t *data_session_key, uint32_t tx_frequency, uint8_t tx_datarate, uint8_t tx_power) { 00210 std::vector<uint8_t> current_network_address = dot->getNetworkAddress(); 00211 std::vector<uint8_t> current_network_session_key = dot->getNetworkSessionKey(); 00212 std::vector<uint8_t> current_data_session_key = dot->getDataSessionKey(); 00213 uint32_t current_tx_frequency = dot->getTxFrequency(); 00214 uint8_t current_tx_datarate = dot->getTxDataRate(); 00215 uint8_t current_tx_power = dot->getTxPower(); 00216 00217 std::vector<uint8_t> network_address_vector(network_address, network_address + 4); 00218 std::vector<uint8_t> network_session_key_vector(network_session_key, network_session_key + 16); 00219 std::vector<uint8_t> data_session_key_vector(data_session_key, data_session_key + 16); 00220 00221 if (current_network_address != network_address_vector) { 00222 logInfo("changing network address from \"%s\" to \"%s\"", mts::Text::bin2hexString(current_network_address).c_str(), mts::Text::bin2hexString(network_address_vector).c_str()); 00223 if (dot->setNetworkAddress(network_address_vector) != mDot::MDOT_OK) { 00224 logError("failed to set network address to \"%s\"", mts::Text::bin2hexString(network_address_vector).c_str()); 00225 } 00226 } 00227 00228 if (current_network_session_key != network_session_key_vector) { 00229 logInfo("changing network session key from \"%s\" to \"%s\"", mts::Text::bin2hexString(current_network_session_key).c_str(), mts::Text::bin2hexString(network_session_key_vector).c_str()); 00230 if (dot->setNetworkSessionKey(network_session_key_vector) != mDot::MDOT_OK) { 00231 logError("failed to set network session key to \"%s\"", mts::Text::bin2hexString(network_session_key_vector).c_str()); 00232 } 00233 } 00234 00235 if (current_data_session_key != data_session_key_vector) { 00236 logInfo("changing data session key from \"%s\" to \"%s\"", mts::Text::bin2hexString(current_data_session_key).c_str(), mts::Text::bin2hexString(data_session_key_vector).c_str()); 00237 if (dot->setDataSessionKey(data_session_key_vector) != mDot::MDOT_OK) { 00238 logError("failed to set data session key to \"%s\"", mts::Text::bin2hexString(data_session_key_vector).c_str()); 00239 } 00240 } 00241 00242 if (current_tx_frequency != tx_frequency) { 00243 logInfo("changing TX frequency from %lu to %lu", current_tx_frequency, tx_frequency); 00244 if (dot->setTxFrequency(tx_frequency) != mDot::MDOT_OK) { 00245 logError("failed to set TX frequency to %lu", tx_frequency); 00246 } 00247 } 00248 00249 if (current_tx_datarate != tx_datarate) { 00250 logInfo("changing TX datarate from %u to %u", current_tx_datarate, tx_datarate); 00251 if (dot->setTxDataRate(tx_datarate) != mDot::MDOT_OK) { 00252 logError("failed to set TX datarate to %u", tx_datarate); 00253 } 00254 } 00255 00256 if (current_tx_power != tx_power) { 00257 logInfo("changing TX power from %u to %u", current_tx_power, tx_power); 00258 if (dot->setTxPower(tx_power) != mDot::MDOT_OK) { 00259 logError("failed to set TX power to %u", tx_power); 00260 } 00261 } 00262 } 00263 00264 void update_network_link_check_config(uint8_t link_check_count, uint8_t link_check_threshold) { 00265 uint8_t current_link_check_count = dot->getLinkCheckCount(); 00266 uint8_t current_link_check_threshold = dot->getLinkCheckThreshold(); 00267 00268 if (current_link_check_count != link_check_count) { 00269 logInfo("changing link check count from %u to %u", current_link_check_count, link_check_count); 00270 if (dot->setLinkCheckCount(link_check_count) != mDot::MDOT_OK) { 00271 logError("failed to set link check count to %u", link_check_count); 00272 } 00273 } 00274 00275 if (current_link_check_threshold != link_check_threshold) { 00276 logInfo("changing link check threshold from %u to %u", current_link_check_threshold, link_check_threshold); 00277 if (dot->setLinkCheckThreshold(link_check_threshold) != mDot::MDOT_OK) { 00278 logError("failed to set link check threshold to %u", link_check_threshold); 00279 } 00280 } 00281 } 00282 00283 void join_network() { 00284 int32_t j_attempts = 0; 00285 int32_t ret = mDot::MDOT_ERROR; 00286 00287 // attempt to join the network 00288 while (ret != mDot::MDOT_OK) { 00289 logInfo("attempt %d to join network", ++j_attempts); 00290 ret = dot->joinNetwork(); 00291 if (ret != mDot::MDOT_OK) { 00292 logError("failed to join network %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); 00293 // in some frequency bands we need to wait until another channel is available before transmitting again 00294 uint32_t delay_s = (dot->getNextTxMs() / 1000) + 1; 00295 if (delay_s < 2) { 00296 logInfo("waiting %lu s until next free channel", delay_s); 00297 wait(delay_s); 00298 } else { 00299 logInfo("sleeping %lu s until next free channel", delay_s); 00300 dot->sleep(delay_s, mDot::RTC_ALARM, false); 00301 } 00302 } 00303 } 00304 } 00305 00306 void sleep_wake_rtc_only(bool deepsleep) { 00307 // in some frequency bands we need to wait until another channel is available before transmitting again 00308 // wait at least 10s between transmissions 00309 uint32_t delay_s = dot->getNextTxMs() / 1000; 00310 if (delay_s < 10) { 00311 delay_s = 10; 00312 } 00313 00314 logInfo("%ssleeping %lus", deepsleep ? "deep" : "", delay_s); 00315 logInfo("application will %s after waking up", deepsleep ? "execute from beginning" : "resume"); 00316 00317 // lowest current consumption in sleep mode can only be achieved by configuring IOs as analog inputs with no pull resistors 00318 // the library handles all internal IOs automatically, but the external IOs are the application's responsibility 00319 // certain IOs may require internal pullup or pulldown resistors because leaving them floating would cause extra current consumption 00320 // for xDot: UART_*, I2C_*, SPI_*, GPIO*, WAKE 00321 // for mDot: XBEE_*, USBTX, USBRX, PB_0, PB_1 00322 // steps are: 00323 // * save IO configuration 00324 // * configure IOs to reduce current consumption 00325 // * sleep 00326 // * restore IO configuration 00327 if (! deepsleep) { 00328 // save the GPIO state. 00329 sleep_save_io(); 00330 00331 // configure GPIOs for lowest current 00332 sleep_configure_io(); 00333 } 00334 00335 // go to sleep/deepsleep for delay_s seconds and wake using the RTC alarm 00336 dot->sleep(delay_s, mDot::RTC_ALARM, deepsleep); 00337 00338 if (! deepsleep) { 00339 // restore the GPIO state. 00340 sleep_restore_io(); 00341 } 00342 } 00343 00344 void sleep_wake_interrupt_only(bool deepsleep) { 00345 #if defined (TARGET_XDOT_L151CC) 00346 if (deepsleep) { 00347 // for xDot, WAKE pin (connected to S2 on xDot-DK) is the only pin that can wake the processor from deepsleep 00348 // it is automatically configured when INTERRUPT or RTC_ALARM_OR_INTERRUPT is the wakeup source and deepsleep is true in the mDot::sleep call 00349 } else { 00350 // configure WAKE pin (connected to S2 on xDot-DK) as the pin that will wake the xDot from low power modes 00351 // other pins can be confgured instead: GPIO0-3 or UART_RX 00352 dot->setWakePin(WAKE); 00353 } 00354 00355 logInfo("%ssleeping until interrupt on %s pin", deepsleep ? "deep" : "", deepsleep ? "WAKE" : mDot::pinName2Str(dot->getWakePin()).c_str()); 00356 #else 00357 00358 if (deepsleep) { 00359 // for mDot, XBEE_DIO7 pin is the only pin that can wake the processor from deepsleep 00360 // it is automatically configured when INTERRUPT or RTC_ALARM_OR_INTERRUPT is the wakeup source and deepsleep is true in the mDot::sleep call 00361 } else { 00362 // configure XBEE_DIO7 pin as the pin that will wake the mDot from low power modes 00363 // other pins can be confgured instead: XBEE_DIO2-6, XBEE_DI8, XBEE_DIN 00364 dot->setWakePin(XBEE_DIO7); 00365 } 00366 00367 logInfo("%ssleeping until interrupt on %s pin", deepsleep ? "deep" : "", deepsleep ? "DIO7" : mDot::pinName2Str(dot->getWakePin()).c_str()); 00368 #endif 00369 00370 logInfo("application will %s after waking up", deepsleep ? "execute from beginning" : "resume"); 00371 00372 // lowest current consumption in sleep mode can only be achieved by configuring IOs as analog inputs with no pull resistors 00373 // the library handles all internal IOs automatically, but the external IOs are the application's responsibility 00374 // certain IOs may require internal pullup or pulldown resistors because leaving them floating would cause extra current consumption 00375 // for xDot: UART_*, I2C_*, SPI_*, GPIO*, WAKE 00376 // for mDot: XBEE_*, USBTX, USBRX, PB_0, PB_1 00377 // steps are: 00378 // * save IO configuration 00379 // * configure IOs to reduce current consumption 00380 // * sleep 00381 // * restore IO configuration 00382 if (! deepsleep) { 00383 // save the GPIO state. 00384 sleep_save_io(); 00385 00386 // configure GPIOs for lowest current 00387 sleep_configure_io(); 00388 } 00389 00390 // go to sleep/deepsleep and wake on rising edge of configured wake pin (only the WAKE pin in deepsleep) 00391 // since we're not waking on the RTC alarm, the interval is ignored 00392 dot->sleep(0, mDot::INTERRUPT, deepsleep); 00393 00394 if (! deepsleep) { 00395 // restore the GPIO state. 00396 sleep_restore_io(); 00397 } 00398 } 00399 00400 void sleep_wake_rtc_or_interrupt(bool deepsleep) { 00401 // in some frequency bands we need to wait until another channel is available before transmitting again 00402 // wait at least 10s between transmissions 00403 uint32_t delay_s = dot->getNextTxMs() / 1000; 00404 if (delay_s < 10) { 00405 delay_s = 10; 00406 } 00407 00408 #if defined (TARGET_XDOT_L151CC) 00409 if (deepsleep) { 00410 // for xDot, WAKE pin (connected to S2 on xDot-DK) is the only pin that can wake the processor from deepsleep 00411 // it is automatically configured when INTERRUPT or RTC_ALARM_OR_INTERRUPT is the wakeup source and deepsleep is true in the mDot::sleep call 00412 } else { 00413 // configure WAKE pin (connected to S2 on xDot-DK) as the pin that will wake the xDot from low power modes 00414 // other pins can be confgured instead: GPIO0-3 or UART_RX 00415 dot->setWakePin(WAKE); 00416 } 00417 00418 logInfo("%ssleeping %lus or until interrupt on %s pin", deepsleep ? "deep" : "", delay_s, deepsleep ? "WAKE" : mDot::pinName2Str(dot->getWakePin()).c_str()); 00419 #else 00420 if (deepsleep) { 00421 // for mDot, XBEE_DIO7 pin is the only pin that can wake the processor from deepsleep 00422 // it is automatically configured when INTERRUPT or RTC_ALARM_OR_INTERRUPT is the wakeup source and deepsleep is true in the mDot::sleep call 00423 } else { 00424 // configure XBEE_DIO7 pin as the pin that will wake the mDot from low power modes 00425 // other pins can be confgured instead: XBEE_DIO2-6, XBEE_DI8, XBEE_DIN 00426 dot->setWakePin(XBEE_DIO7); 00427 } 00428 00429 logInfo("%ssleeping %lus or until interrupt on %s pin", deepsleep ? "deep" : "", delay_s, deepsleep ? "DIO7" : mDot::pinName2Str(dot->getWakePin()).c_str()); 00430 #endif 00431 00432 logInfo("application will %s after waking up", deepsleep ? "execute from beginning" : "resume"); 00433 00434 // lowest current consumption in sleep mode can only be achieved by configuring IOs as analog inputs with no pull resistors 00435 // the library handles all internal IOs automatically, but the external IOs are the application's responsibility 00436 // certain IOs may require internal pullup or pulldown resistors because leaving them floating would cause extra current consumption 00437 // for xDot: UART_*, I2C_*, SPI_*, GPIO*, WAKE 00438 // for mDot: XBEE_*, USBTX, USBRX, PB_0, PB_1 00439 // steps are: 00440 // * save IO configuration 00441 // * configure IOs to reduce current consumption 00442 // * sleep 00443 // * restore IO configuration 00444 if (! deepsleep) { 00445 // save the GPIO state. 00446 sleep_save_io(); 00447 00448 // configure GPIOs for lowest current 00449 sleep_configure_io(); 00450 } 00451 00452 // 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) 00453 // whichever comes first will wake the xDot 00454 dot->sleep(delay_s, mDot::RTC_ALARM_OR_INTERRUPT, deepsleep); 00455 00456 if (! deepsleep) { 00457 // restore the GPIO state. 00458 sleep_restore_io(); 00459 } 00460 } 00461 00462 void sleep_save_io() { 00463 #if defined(TARGET_XDOT_L151CC) 00464 xdot_save_gpio_state(); 00465 #else 00466 portA[0] = GPIOA->MODER; 00467 portA[1] = GPIOA->OTYPER; 00468 portA[2] = GPIOA->OSPEEDR; 00469 portA[3] = GPIOA->PUPDR; 00470 portA[4] = GPIOA->AFR[0]; 00471 portA[5] = GPIOA->AFR[1]; 00472 00473 portB[0] = GPIOB->MODER; 00474 portB[1] = GPIOB->OTYPER; 00475 portB[2] = GPIOB->OSPEEDR; 00476 portB[3] = GPIOB->PUPDR; 00477 portB[4] = GPIOB->AFR[0]; 00478 portB[5] = GPIOB->AFR[1]; 00479 00480 portC[0] = GPIOC->MODER; 00481 portC[1] = GPIOC->OTYPER; 00482 portC[2] = GPIOC->OSPEEDR; 00483 portC[3] = GPIOC->PUPDR; 00484 portC[4] = GPIOC->AFR[0]; 00485 portC[5] = GPIOC->AFR[1]; 00486 00487 portD[0] = GPIOD->MODER; 00488 portD[1] = GPIOD->OTYPER; 00489 portD[2] = GPIOD->OSPEEDR; 00490 portD[3] = GPIOD->PUPDR; 00491 portD[4] = GPIOD->AFR[0]; 00492 portD[5] = GPIOD->AFR[1]; 00493 00494 portH[0] = GPIOH->MODER; 00495 portH[1] = GPIOH->OTYPER; 00496 portH[2] = GPIOH->OSPEEDR; 00497 portH[3] = GPIOH->PUPDR; 00498 portH[4] = GPIOH->AFR[0]; 00499 portH[5] = GPIOH->AFR[1]; 00500 #endif 00501 } 00502 00503 void sleep_configure_io() { 00504 #if defined(TARGET_XDOT_L151CC) 00505 // GPIO Ports Clock Enable 00506 __GPIOA_CLK_ENABLE(); 00507 __GPIOB_CLK_ENABLE(); 00508 __GPIOC_CLK_ENABLE(); 00509 __GPIOH_CLK_ENABLE(); 00510 00511 GPIO_InitTypeDef GPIO_InitStruct; 00512 00513 // UART1_TX, UART1_RTS & UART1_CTS to analog nopull - RX could be a wakeup source 00514 GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_11 | GPIO_PIN_12; 00515 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 00516 GPIO_InitStruct.Pull = GPIO_NOPULL; 00517 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 00518 00519 // I2C_SDA & I2C_SCL to analog nopull 00520 GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9; 00521 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 00522 GPIO_InitStruct.Pull = GPIO_NOPULL; 00523 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); 00524 00525 // SPI_MOSI, SPI_MISO, SPI_SCK, & SPI_NSS to analog nopull 00526 GPIO_InitStruct.Pin = GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15; 00527 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 00528 GPIO_InitStruct.Pull = GPIO_NOPULL; 00529 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); 00530 00531 // iterate through potential wake pins - leave the configured wake pin alone if one is needed 00532 if (dot->getWakePin() != WAKE || dot->getWakeMode() == mDot::RTC_ALARM) { 00533 GPIO_InitStruct.Pin = GPIO_PIN_0; 00534 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 00535 GPIO_InitStruct.Pull = GPIO_NOPULL; 00536 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 00537 } 00538 if (dot->getWakePin() != GPIO0 || dot->getWakeMode() == mDot::RTC_ALARM) { 00539 GPIO_InitStruct.Pin = GPIO_PIN_4; 00540 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 00541 GPIO_InitStruct.Pull = GPIO_NOPULL; 00542 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 00543 } 00544 if (dot->getWakePin() != GPIO1 || dot->getWakeMode() == mDot::RTC_ALARM) { 00545 GPIO_InitStruct.Pin = GPIO_PIN_5; 00546 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 00547 GPIO_InitStruct.Pull = GPIO_NOPULL; 00548 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 00549 } 00550 if (dot->getWakePin() != GPIO2 || dot->getWakeMode() == mDot::RTC_ALARM) { 00551 GPIO_InitStruct.Pin = GPIO_PIN_0; 00552 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 00553 GPIO_InitStruct.Pull = GPIO_NOPULL; 00554 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); 00555 } 00556 if (dot->getWakePin() != GPIO3 || dot->getWakeMode() == mDot::RTC_ALARM) { 00557 GPIO_InitStruct.Pin = GPIO_PIN_2; 00558 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 00559 GPIO_InitStruct.Pull = GPIO_NOPULL; 00560 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); 00561 } 00562 if (dot->getWakePin() != UART1_RX || dot->getWakeMode() == mDot::RTC_ALARM) { 00563 GPIO_InitStruct.Pin = GPIO_PIN_10; 00564 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 00565 GPIO_InitStruct.Pull = GPIO_NOPULL; 00566 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 00567 } 00568 #else 00569 /* GPIO Ports Clock Enable */ 00570 __GPIOA_CLK_ENABLE(); 00571 __GPIOB_CLK_ENABLE(); 00572 __GPIOC_CLK_ENABLE(); 00573 00574 GPIO_InitTypeDef GPIO_InitStruct; 00575 00576 // XBEE_DOUT, XBEE_DIN, XBEE_DO8, XBEE_RSSI, USBTX, USBRX, PA_12, PA_13, PA_14 & PA_15 to analog nopull 00577 GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_6 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 00578 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15; 00579 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 00580 GPIO_InitStruct.Pull = GPIO_NOPULL; 00581 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 00582 00583 // PB_0, PB_1, PB_3 & PB_4 to analog nopull 00584 GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_3 | GPIO_PIN_4; 00585 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 00586 GPIO_InitStruct.Pull = GPIO_NOPULL; 00587 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); 00588 00589 // PC_9 & PC_13 to analog nopull 00590 GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_13; 00591 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 00592 GPIO_InitStruct.Pull = GPIO_NOPULL; 00593 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); 00594 00595 // iterate through potential wake pins - leave the configured wake pin alone if one is needed 00596 // XBEE_DIN - PA3 00597 // XBEE_DIO2 - PA5 00598 // XBEE_DIO3 - PA4 00599 // XBEE_DIO4 - PA7 00600 // XBEE_DIO5 - PC1 00601 // XBEE_DIO6 - PA1 00602 // XBEE_DIO7 - PA0 00603 // XBEE_SLEEPRQ - PA11 00604 00605 if (dot->getWakePin() != XBEE_DIN || dot->getWakeMode() == mDot::RTC_ALARM) { 00606 GPIO_InitStruct.Pin = GPIO_PIN_3; 00607 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 00608 GPIO_InitStruct.Pull = GPIO_NOPULL; 00609 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 00610 } 00611 00612 if (dot->getWakePin() != XBEE_DIO2 || dot->getWakeMode() == mDot::RTC_ALARM) { 00613 GPIO_InitStruct.Pin = GPIO_PIN_5; 00614 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 00615 GPIO_InitStruct.Pull = GPIO_NOPULL; 00616 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 00617 } 00618 00619 if (dot->getWakePin() != XBEE_DIO3 || dot->getWakeMode() == mDot::RTC_ALARM) { 00620 GPIO_InitStruct.Pin = GPIO_PIN_4; 00621 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 00622 GPIO_InitStruct.Pull = GPIO_NOPULL; 00623 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 00624 } 00625 00626 if (dot->getWakePin() != XBEE_DIO4 || dot->getWakeMode() == mDot::RTC_ALARM) { 00627 GPIO_InitStruct.Pin = GPIO_PIN_7; 00628 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 00629 GPIO_InitStruct.Pull = GPIO_NOPULL; 00630 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 00631 } 00632 00633 if (dot->getWakePin() != XBEE_DIO5 || dot->getWakeMode() == mDot::RTC_ALARM) { 00634 GPIO_InitStruct.Pin = GPIO_PIN_1; 00635 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 00636 GPIO_InitStruct.Pull = GPIO_NOPULL; 00637 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); 00638 } 00639 00640 if (dot->getWakePin() != XBEE_DIO6 || dot->getWakeMode() == mDot::RTC_ALARM) { 00641 GPIO_InitStruct.Pin = GPIO_PIN_1; 00642 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 00643 GPIO_InitStruct.Pull = GPIO_NOPULL; 00644 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 00645 } 00646 00647 if (dot->getWakePin() != XBEE_DIO7 || dot->getWakeMode() == mDot::RTC_ALARM) { 00648 GPIO_InitStruct.Pin = GPIO_PIN_0; 00649 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 00650 GPIO_InitStruct.Pull = GPIO_NOPULL; 00651 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 00652 } 00653 00654 if (dot->getWakePin() != XBEE_SLEEPRQ|| dot->getWakeMode() == mDot::RTC_ALARM) { 00655 GPIO_InitStruct.Pin = GPIO_PIN_11; 00656 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 00657 GPIO_InitStruct.Pull = GPIO_NOPULL; 00658 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 00659 } 00660 #endif 00661 } 00662 00663 void sleep_restore_io() { 00664 #if defined(TARGET_XDOT_L151CC) 00665 xdot_restore_gpio_state(); 00666 #else 00667 GPIOA->MODER = portA[0]; 00668 GPIOA->OTYPER = portA[1]; 00669 GPIOA->OSPEEDR = portA[2]; 00670 GPIOA->PUPDR = portA[3]; 00671 GPIOA->AFR[0] = portA[4]; 00672 GPIOA->AFR[1] = portA[5]; 00673 00674 GPIOB->MODER = portB[0]; 00675 GPIOB->OTYPER = portB[1]; 00676 GPIOB->OSPEEDR = portB[2]; 00677 GPIOB->PUPDR = portB[3]; 00678 GPIOB->AFR[0] = portB[4]; 00679 GPIOB->AFR[1] = portB[5]; 00680 00681 GPIOC->MODER = portC[0]; 00682 GPIOC->OTYPER = portC[1]; 00683 GPIOC->OSPEEDR = portC[2]; 00684 GPIOC->PUPDR = portC[3]; 00685 GPIOC->AFR[0] = portC[4]; 00686 GPIOC->AFR[1] = portC[5]; 00687 00688 GPIOD->MODER = portD[0]; 00689 GPIOD->OTYPER = portD[1]; 00690 GPIOD->OSPEEDR = portD[2]; 00691 GPIOD->PUPDR = portD[3]; 00692 GPIOD->AFR[0] = portD[4]; 00693 GPIOD->AFR[1] = portD[5]; 00694 00695 GPIOH->MODER = portH[0]; 00696 GPIOH->OTYPER = portH[1]; 00697 GPIOH->OSPEEDR = portH[2]; 00698 GPIOH->PUPDR = portH[3]; 00699 GPIOH->AFR[0] = portH[4]; 00700 GPIOH->AFR[1] = portH[5]; 00701 #endif 00702 } 00703 00704 void send_data(std::vector<uint8_t> data) { 00705 int32_t ret; 00706 00707 ret = dot->send(data); 00708 if (ret != mDot::MDOT_OK) { 00709 logError("failed to send data to %s [%d][%s]", dot->getJoinMode() == mDot::PEER_TO_PEER ? "peer" : "gateway", ret, mDot::getReturnCodeString(ret).c_str()); 00710 } else { 00711 logInfo("successfully sent data to %s", dot->getJoinMode() == mDot::PEER_TO_PEER ? "peer" : "gateway"); 00712 } 00713 } 00714
Generated on Mon Jul 18 2022 13:34:57 by 1.7.2