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