Example of using the mDot UDK with the X-NUCLEO-IKS01A1 shield

Dependencies:   mDot_X_NUCLEO_IKS01A1 libmDot-dev-mbed5-deprecated

Hardware

Hardware List

Setup

  • Install the mDot on the developer board.
  • Install the IKS01A1 on the developer board.
  • If using a MTUDK-ST-CELL (white board) plug in the AC power adapter
  • Connect the microusb power to your development PC
    • if using a MTUDK-ST-CELL there are 2 microusb ports. Use the one closest to the serial port.

Your developer board should look like the following:

/media/uploads/pferland/udk_iks01a1.jpg

Software

This example program uses LoRa utility functions from Dot-Examples and the IKS01A1 library from ST Micro.

LoRa Configuration

Senet

By default this program is configured to connect to the Senet network. To connect to Senet you will need to register your mDot's Node ID with the Senet developer portal and change the network_key array in main.cpp.

Others

To connect to a different LoRa gateway change the arrays network_id and network_key. If you are using passphrases, edit the strings network_name and network_key, uncomment the function "update_ota_config_name_phrase" and comment out the function "update_ota_config_id_key".

Committer:
pferland
Date:
Tue Feb 14 20:36:21 2017 +0000
Revision:
11:1425f2e65663
Parent:
10:1e3e3ab9c29c
Updated libmDot-dev to latest

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pferland 0:9e88a9018fc0 1 #include "dot_util.h"
pferland 0:9e88a9018fc0 2 #if defined(TARGET_XDOT_L151CC)
pferland 0:9e88a9018fc0 3 #include "xdot_low_power.h"
pferland 0:9e88a9018fc0 4 #endif
pferland 0:9e88a9018fc0 5
pferland 0:9e88a9018fc0 6 #if defined(TARGET_MTS_MDOT_F411RE)
pferland 0:9e88a9018fc0 7 uint32_t portA[6];
pferland 0:9e88a9018fc0 8 uint32_t portB[6];
pferland 0:9e88a9018fc0 9 uint32_t portC[6];
pferland 0:9e88a9018fc0 10 uint32_t portD[6];
pferland 0:9e88a9018fc0 11 uint32_t portH[6];
pferland 0:9e88a9018fc0 12 #endif
pferland 0:9e88a9018fc0 13
pferland 0:9e88a9018fc0 14
pferland 0:9e88a9018fc0 15 void display_config() {
pferland 0:9e88a9018fc0 16 // display configuration and library version information
pferland 0:9e88a9018fc0 17 logInfo("=====================");
pferland 0:9e88a9018fc0 18 logInfo("general configuration");
pferland 0:9e88a9018fc0 19 logInfo("=====================");
pferland 0:9e88a9018fc0 20 logInfo("version ------------------ %s", dot->getId().c_str());
pferland 0:9e88a9018fc0 21 logInfo("device ID/EUI ------------ %s", mts::Text::bin2hexString(dot->getDeviceId()).c_str());
pferland 0:9e88a9018fc0 22 logInfo("frequency band ----------- %s", mDot::FrequencyBandStr(dot->getFrequencyBand()).c_str());
pferland 0:9e88a9018fc0 23 if (dot->getFrequencySubBand() != mDot::FB_EU868) {
pferland 0:9e88a9018fc0 24 logInfo("frequency sub band ------- %u", dot->getFrequencySubBand());
pferland 0:9e88a9018fc0 25 }
pferland 0:9e88a9018fc0 26 logInfo("public network ----------- %s", dot->getPublicNetwork() ? "on" : "off");
pferland 0:9e88a9018fc0 27 logInfo("=========================");
pferland 0:9e88a9018fc0 28 logInfo("credentials configuration");
pferland 0:9e88a9018fc0 29 logInfo("=========================");
pferland 0:9e88a9018fc0 30 logInfo("device class ------------- %s", dot->getClass().c_str());
pferland 0:9e88a9018fc0 31 logInfo("network join mode -------- %s", mDot::JoinModeStr(dot->getJoinMode()).c_str());
pferland 0:9e88a9018fc0 32 if (dot->getJoinMode() == mDot::MANUAL || dot->getJoinMode() == mDot::PEER_TO_PEER) {
pferland 0:9e88a9018fc0 33 logInfo("network address ---------- %s", mts::Text::bin2hexString(dot->getNetworkAddress()).c_str());
pferland 0:9e88a9018fc0 34 logInfo("network session key------- %s", mts::Text::bin2hexString(dot->getNetworkSessionKey()).c_str());
pferland 0:9e88a9018fc0 35 logInfo("data session key---------- %s", mts::Text::bin2hexString(dot->getDataSessionKey()).c_str());
pferland 0:9e88a9018fc0 36 } else {
pferland 0:9e88a9018fc0 37 logInfo("network name ------------- %s", dot->getNetworkName().c_str());
pferland 0:9e88a9018fc0 38 logInfo("network phrase ----------- %s", dot->getNetworkPassphrase().c_str());
pferland 0:9e88a9018fc0 39 logInfo("network EUI -------------- %s", mts::Text::bin2hexString(dot->getNetworkId()).c_str());
pferland 0:9e88a9018fc0 40 logInfo("network KEY -------------- %s", mts::Text::bin2hexString(dot->getNetworkKey()).c_str());
pferland 0:9e88a9018fc0 41 }
pferland 0:9e88a9018fc0 42 logInfo("========================");
pferland 0:9e88a9018fc0 43 logInfo("communication parameters");
pferland 0:9e88a9018fc0 44 logInfo("========================");
pferland 0:9e88a9018fc0 45 if (dot->getJoinMode() == mDot::PEER_TO_PEER) {
pferland 0:9e88a9018fc0 46 logInfo("TX frequency ------------- %lu", dot->getTxFrequency());
pferland 0:9e88a9018fc0 47 } else {
pferland 0:9e88a9018fc0 48 logInfo("acks --------------------- %s, %u attempts", dot->getAck() > 0 ? "on" : "off", dot->getAck());
pferland 0:9e88a9018fc0 49 }
pferland 0:9e88a9018fc0 50 logInfo("TX datarate -------------- %s", mDot::DataRateStr(dot->getTxDataRate()).c_str());
pferland 0:9e88a9018fc0 51 logInfo("TX power ----------------- %lu dBm", dot->getTxPower());
pferland 0:9e88a9018fc0 52 logInfo("atnenna gain ------------- %u dBm", dot->getAntennaGain());
pferland 0:9e88a9018fc0 53 }
pferland 0:9e88a9018fc0 54
pferland 0:9e88a9018fc0 55 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) {
pferland 0:9e88a9018fc0 56 std::string current_network_name = dot->getNetworkName();
pferland 0:9e88a9018fc0 57 std::string current_network_passphrase = dot->getNetworkPassphrase();
pferland 0:9e88a9018fc0 58 uint8_t current_frequency_sub_band = dot->getFrequencySubBand();
pferland 0:9e88a9018fc0 59 bool current_public_network = dot->getPublicNetwork();
pferland 0:9e88a9018fc0 60 uint8_t current_ack = dot->getAck();
pferland 0:9e88a9018fc0 61
pferland 0:9e88a9018fc0 62 if (current_network_name != network_name) {
pferland 0:9e88a9018fc0 63 logInfo("changing network name from \"%s\" to \"%s\"", current_network_name.c_str(), network_name.c_str());
pferland 0:9e88a9018fc0 64 if (dot->setNetworkName(network_name) != mDot::MDOT_OK) {
pferland 0:9e88a9018fc0 65 logError("failed to set network name to \"%s\"", network_name.c_str());
pferland 0:9e88a9018fc0 66 }
pferland 0:9e88a9018fc0 67 }
pferland 0:9e88a9018fc0 68
pferland 0:9e88a9018fc0 69 if (current_network_passphrase != network_passphrase) {
pferland 0:9e88a9018fc0 70 logInfo("changing network passphrase from \"%s\" to \"%s\"", current_network_passphrase.c_str(), network_passphrase.c_str());
pferland 0:9e88a9018fc0 71 if (dot->setNetworkPassphrase(network_passphrase) != mDot::MDOT_OK) {
pferland 0:9e88a9018fc0 72 logError("failed to set network passphrase to \"%s\"", network_passphrase.c_str());
pferland 0:9e88a9018fc0 73 }
pferland 0:9e88a9018fc0 74 }
pferland 0:9e88a9018fc0 75
pferland 0:9e88a9018fc0 76 if (current_frequency_sub_band != frequency_sub_band) {
pferland 0:9e88a9018fc0 77 logInfo("changing frequency sub band from %u to %u", current_frequency_sub_band, frequency_sub_band);
pferland 0:9e88a9018fc0 78 if (dot->setFrequencySubBand(frequency_sub_band) != mDot::MDOT_OK) {
pferland 0:9e88a9018fc0 79 logError("failed to set frequency sub band to %u", frequency_sub_band);
pferland 0:9e88a9018fc0 80 }
pferland 0:9e88a9018fc0 81 }
pferland 0:9e88a9018fc0 82
pferland 0:9e88a9018fc0 83 if (current_public_network != public_network) {
pferland 0:9e88a9018fc0 84 logInfo("changing public network from %s to %s", current_public_network ? "on" : "off", public_network ? "on" : "off");
pferland 0:9e88a9018fc0 85 if (dot->setPublicNetwork(public_network) != mDot::MDOT_OK) {
pferland 0:9e88a9018fc0 86 logError("failed to set public network to %s", public_network ? "on" : "off");
pferland 0:9e88a9018fc0 87 }
pferland 0:9e88a9018fc0 88 }
pferland 0:9e88a9018fc0 89
pferland 0:9e88a9018fc0 90 if (current_ack != ack) {
pferland 0:9e88a9018fc0 91 logInfo("changing acks from %u to %u", current_ack, ack);
pferland 0:9e88a9018fc0 92 if (dot->setAck(ack) != mDot::MDOT_OK) {
pferland 0:9e88a9018fc0 93 logError("failed to set acks to %u", ack);
pferland 0:9e88a9018fc0 94 }
pferland 0:9e88a9018fc0 95 }
pferland 0:9e88a9018fc0 96 }
pferland 0:9e88a9018fc0 97
pferland 0:9e88a9018fc0 98 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) {
pferland 0:9e88a9018fc0 99 std::vector<uint8_t> current_network_id = dot->getNetworkId();
pferland 0:9e88a9018fc0 100 std::vector<uint8_t> current_network_key = dot->getNetworkKey();
pferland 0:9e88a9018fc0 101 uint8_t current_frequency_sub_band = dot->getFrequencySubBand();
pferland 0:9e88a9018fc0 102 bool current_public_network = dot->getPublicNetwork();
pferland 0:9e88a9018fc0 103 uint8_t current_ack = dot->getAck();
pferland 0:9e88a9018fc0 104
pferland 0:9e88a9018fc0 105 std::vector<uint8_t> network_id_vector(network_id, network_id + 8);
pferland 0:9e88a9018fc0 106 std::vector<uint8_t> network_key_vector(network_key, network_key + 16);
pferland 0:9e88a9018fc0 107
pferland 0:9e88a9018fc0 108 if (current_network_id != network_id_vector) {
pferland 0:9e88a9018fc0 109 logInfo("changing network ID from \"%s\" to \"%s\"", mts::Text::bin2hexString(current_network_id).c_str(), mts::Text::bin2hexString(network_id_vector).c_str());
pferland 0:9e88a9018fc0 110 if (dot->setNetworkId(network_id_vector) != mDot::MDOT_OK) {
pferland 0:9e88a9018fc0 111 logError("failed to set network ID to \"%s\"", mts::Text::bin2hexString(network_id_vector).c_str());
pferland 0:9e88a9018fc0 112 }
pferland 0:9e88a9018fc0 113 }
pferland 0:9e88a9018fc0 114
pferland 0:9e88a9018fc0 115 if (current_network_key != network_key_vector) {
pferland 0:9e88a9018fc0 116 logInfo("changing network KEY from \"%s\" to \"%s\"", mts::Text::bin2hexString(current_network_key).c_str(), mts::Text::bin2hexString(network_key_vector).c_str());
pferland 0:9e88a9018fc0 117 if (dot->setNetworkKey(network_key_vector) != mDot::MDOT_OK) {
pferland 0:9e88a9018fc0 118 logError("failed to set network KEY to \"%s\"", mts::Text::bin2hexString(network_key_vector).c_str());
pferland 0:9e88a9018fc0 119 }
pferland 0:9e88a9018fc0 120 }
pferland 0:9e88a9018fc0 121
pferland 0:9e88a9018fc0 122 if (current_frequency_sub_band != frequency_sub_band) {
pferland 0:9e88a9018fc0 123 logInfo("changing frequency sub band from %u to %u", current_frequency_sub_band, frequency_sub_band);
pferland 0:9e88a9018fc0 124 if (dot->setFrequencySubBand(frequency_sub_band) != mDot::MDOT_OK) {
pferland 0:9e88a9018fc0 125 logError("failed to set frequency sub band to %u", frequency_sub_band);
pferland 0:9e88a9018fc0 126 }
pferland 0:9e88a9018fc0 127 }
pferland 0:9e88a9018fc0 128
pferland 0:9e88a9018fc0 129 if (current_public_network != public_network) {
pferland 0:9e88a9018fc0 130 logInfo("changing public network from %s to %s", current_public_network ? "on" : "off", public_network ? "on" : "off");
pferland 0:9e88a9018fc0 131 if (dot->setPublicNetwork(public_network) != mDot::MDOT_OK) {
pferland 0:9e88a9018fc0 132 logError("failed to set public network to %s", public_network ? "on" : "off");
pferland 0:9e88a9018fc0 133 }
pferland 0:9e88a9018fc0 134 }
pferland 0:9e88a9018fc0 135
pferland 0:9e88a9018fc0 136 if (current_ack != ack) {
pferland 0:9e88a9018fc0 137 logInfo("changing acks from %u to %u", current_ack, ack);
pferland 0:9e88a9018fc0 138 if (dot->setAck(ack) != mDot::MDOT_OK) {
pferland 0:9e88a9018fc0 139 logError("failed to set acks to %u", ack);
pferland 0:9e88a9018fc0 140 }
pferland 0:9e88a9018fc0 141 }
pferland 0:9e88a9018fc0 142 }
pferland 0:9e88a9018fc0 143
pferland 0:9e88a9018fc0 144 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) {
pferland 0:9e88a9018fc0 145 std::vector<uint8_t> current_network_address = dot->getNetworkAddress();
pferland 0:9e88a9018fc0 146 std::vector<uint8_t> current_network_session_key = dot->getNetworkSessionKey();
pferland 0:9e88a9018fc0 147 std::vector<uint8_t> current_data_session_key = dot->getDataSessionKey();
pferland 0:9e88a9018fc0 148 uint8_t current_frequency_sub_band = dot->getFrequencySubBand();
pferland 0:9e88a9018fc0 149 bool current_public_network = dot->getPublicNetwork();
pferland 0:9e88a9018fc0 150 uint8_t current_ack = dot->getAck();
pferland 0:9e88a9018fc0 151
pferland 0:9e88a9018fc0 152 std::vector<uint8_t> network_address_vector(network_address, network_address + 4);
pferland 0:9e88a9018fc0 153 std::vector<uint8_t> network_session_key_vector(network_session_key, network_session_key + 16);
pferland 0:9e88a9018fc0 154 std::vector<uint8_t> data_session_key_vector(data_session_key, data_session_key + 16);
pferland 0:9e88a9018fc0 155
pferland 0:9e88a9018fc0 156 if (current_network_address != network_address_vector) {
pferland 0:9e88a9018fc0 157 logInfo("changing network address from \"%s\" to \"%s\"", mts::Text::bin2hexString(current_network_address).c_str(), mts::Text::bin2hexString(network_address_vector).c_str());
pferland 0:9e88a9018fc0 158 if (dot->setNetworkAddress(network_address_vector) != mDot::MDOT_OK) {
pferland 0:9e88a9018fc0 159 logError("failed to set network address to \"%s\"", mts::Text::bin2hexString(network_address_vector).c_str());
pferland 0:9e88a9018fc0 160 }
pferland 0:9e88a9018fc0 161 }
pferland 0:9e88a9018fc0 162
pferland 0:9e88a9018fc0 163 if (current_network_session_key != network_session_key_vector) {
pferland 0:9e88a9018fc0 164 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());
pferland 0:9e88a9018fc0 165 if (dot->setNetworkSessionKey(network_session_key_vector) != mDot::MDOT_OK) {
pferland 0:9e88a9018fc0 166 logError("failed to set network session key to \"%s\"", mts::Text::bin2hexString(network_session_key_vector).c_str());
pferland 0:9e88a9018fc0 167 }
pferland 0:9e88a9018fc0 168 }
pferland 0:9e88a9018fc0 169
pferland 0:9e88a9018fc0 170 if (current_data_session_key != data_session_key_vector) {
pferland 0:9e88a9018fc0 171 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());
pferland 0:9e88a9018fc0 172 if (dot->setDataSessionKey(data_session_key_vector) != mDot::MDOT_OK) {
pferland 0:9e88a9018fc0 173 logError("failed to set data session key to \"%s\"", mts::Text::bin2hexString(data_session_key_vector).c_str());
pferland 0:9e88a9018fc0 174 }
pferland 0:9e88a9018fc0 175 }
pferland 0:9e88a9018fc0 176
pferland 0:9e88a9018fc0 177 if (current_frequency_sub_band != frequency_sub_band) {
pferland 0:9e88a9018fc0 178 logInfo("changing frequency sub band from %u to %u", current_frequency_sub_band, frequency_sub_band);
pferland 0:9e88a9018fc0 179 if (dot->setFrequencySubBand(frequency_sub_band) != mDot::MDOT_OK) {
pferland 0:9e88a9018fc0 180 logError("failed to set frequency sub band to %u", frequency_sub_band);
pferland 0:9e88a9018fc0 181 }
pferland 0:9e88a9018fc0 182 }
pferland 0:9e88a9018fc0 183
pferland 0:9e88a9018fc0 184 if (current_public_network != public_network) {
pferland 0:9e88a9018fc0 185 logInfo("changing public network from %s to %s", current_public_network ? "on" : "off", public_network ? "on" : "off");
pferland 0:9e88a9018fc0 186 if (dot->setPublicNetwork(public_network) != mDot::MDOT_OK) {
pferland 0:9e88a9018fc0 187 logError("failed to set public network to %s", public_network ? "on" : "off");
pferland 0:9e88a9018fc0 188 }
pferland 0:9e88a9018fc0 189 }
pferland 0:9e88a9018fc0 190
pferland 0:9e88a9018fc0 191 if (current_ack != ack) {
pferland 0:9e88a9018fc0 192 logInfo("changing acks from %u to %u", current_ack, ack);
pferland 0:9e88a9018fc0 193 if (dot->setAck(ack) != mDot::MDOT_OK) {
pferland 0:9e88a9018fc0 194 logError("failed to set acks to %u", ack);
pferland 0:9e88a9018fc0 195 }
pferland 0:9e88a9018fc0 196 }
pferland 0:9e88a9018fc0 197 }
pferland 0:9e88a9018fc0 198
pferland 0:9e88a9018fc0 199 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) {
pferland 0:9e88a9018fc0 200 std::vector<uint8_t> current_network_address = dot->getNetworkAddress();
pferland 0:9e88a9018fc0 201 std::vector<uint8_t> current_network_session_key = dot->getNetworkSessionKey();
pferland 0:9e88a9018fc0 202 std::vector<uint8_t> current_data_session_key = dot->getDataSessionKey();
pferland 0:9e88a9018fc0 203 uint32_t current_tx_frequency = dot->getTxFrequency();
pferland 0:9e88a9018fc0 204 uint8_t current_tx_datarate = dot->getTxDataRate();
pferland 0:9e88a9018fc0 205 uint8_t current_tx_power = dot->getTxPower();
pferland 0:9e88a9018fc0 206
pferland 0:9e88a9018fc0 207 std::vector<uint8_t> network_address_vector(network_address, network_address + 4);
pferland 0:9e88a9018fc0 208 std::vector<uint8_t> network_session_key_vector(network_session_key, network_session_key + 16);
pferland 0:9e88a9018fc0 209 std::vector<uint8_t> data_session_key_vector(data_session_key, data_session_key + 16);
pferland 0:9e88a9018fc0 210
pferland 0:9e88a9018fc0 211 if (current_network_address != network_address_vector) {
pferland 0:9e88a9018fc0 212 logInfo("changing network address from \"%s\" to \"%s\"", mts::Text::bin2hexString(current_network_address).c_str(), mts::Text::bin2hexString(network_address_vector).c_str());
pferland 0:9e88a9018fc0 213 if (dot->setNetworkAddress(network_address_vector) != mDot::MDOT_OK) {
pferland 0:9e88a9018fc0 214 logError("failed to set network address to \"%s\"", mts::Text::bin2hexString(network_address_vector).c_str());
pferland 0:9e88a9018fc0 215 }
pferland 0:9e88a9018fc0 216 }
pferland 0:9e88a9018fc0 217
pferland 0:9e88a9018fc0 218 if (current_network_session_key != network_session_key_vector) {
pferland 0:9e88a9018fc0 219 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());
pferland 0:9e88a9018fc0 220 if (dot->setNetworkSessionKey(network_session_key_vector) != mDot::MDOT_OK) {
pferland 0:9e88a9018fc0 221 logError("failed to set network session key to \"%s\"", mts::Text::bin2hexString(network_session_key_vector).c_str());
pferland 0:9e88a9018fc0 222 }
pferland 0:9e88a9018fc0 223 }
pferland 0:9e88a9018fc0 224
pferland 0:9e88a9018fc0 225 if (current_data_session_key != data_session_key_vector) {
pferland 0:9e88a9018fc0 226 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());
pferland 0:9e88a9018fc0 227 if (dot->setDataSessionKey(data_session_key_vector) != mDot::MDOT_OK) {
pferland 0:9e88a9018fc0 228 logError("failed to set data session key to \"%s\"", mts::Text::bin2hexString(data_session_key_vector).c_str());
pferland 0:9e88a9018fc0 229 }
pferland 0:9e88a9018fc0 230 }
pferland 0:9e88a9018fc0 231
pferland 0:9e88a9018fc0 232 if (current_tx_frequency != tx_frequency) {
pferland 0:9e88a9018fc0 233 logInfo("changing TX frequency from %lu to %lu", current_tx_frequency, tx_frequency);
pferland 0:9e88a9018fc0 234 if (dot->setTxFrequency(tx_frequency) != mDot::MDOT_OK) {
pferland 0:9e88a9018fc0 235 logError("failed to set TX frequency to %lu", tx_frequency);
pferland 0:9e88a9018fc0 236 }
pferland 0:9e88a9018fc0 237 }
pferland 0:9e88a9018fc0 238
pferland 0:9e88a9018fc0 239 if (current_tx_datarate != tx_datarate) {
pferland 0:9e88a9018fc0 240 logInfo("changing TX datarate from %u to %u", current_tx_datarate, tx_datarate);
pferland 0:9e88a9018fc0 241 if (dot->setTxDataRate(tx_datarate) != mDot::MDOT_OK) {
pferland 0:9e88a9018fc0 242 logError("failed to set TX datarate to %u", tx_datarate);
pferland 0:9e88a9018fc0 243 }
pferland 0:9e88a9018fc0 244 }
pferland 0:9e88a9018fc0 245
pferland 0:9e88a9018fc0 246 if (current_tx_power != tx_power) {
pferland 0:9e88a9018fc0 247 logInfo("changing TX power from %u to %u", current_tx_power, tx_power);
pferland 0:9e88a9018fc0 248 if (dot->setTxPower(tx_power) != mDot::MDOT_OK) {
pferland 0:9e88a9018fc0 249 logError("failed to set TX power to %u", tx_power);
pferland 0:9e88a9018fc0 250 }
pferland 0:9e88a9018fc0 251 }
pferland 0:9e88a9018fc0 252 }
pferland 0:9e88a9018fc0 253
pferland 0:9e88a9018fc0 254 void update_network_link_check_config(uint8_t link_check_count, uint8_t link_check_threshold) {
pferland 0:9e88a9018fc0 255 uint8_t current_link_check_count = dot->getLinkCheckCount();
pferland 0:9e88a9018fc0 256 uint8_t current_link_check_threshold = dot->getLinkCheckThreshold();
pferland 0:9e88a9018fc0 257
pferland 0:9e88a9018fc0 258 if (current_link_check_count != link_check_count) {
pferland 0:9e88a9018fc0 259 logInfo("changing link check count from %u to %u", current_link_check_count, link_check_count);
pferland 0:9e88a9018fc0 260 if (dot->setLinkCheckCount(link_check_count) != mDot::MDOT_OK) {
pferland 0:9e88a9018fc0 261 logError("failed to set link check count to %u", link_check_count);
pferland 0:9e88a9018fc0 262 }
pferland 0:9e88a9018fc0 263 }
pferland 0:9e88a9018fc0 264
pferland 0:9e88a9018fc0 265 if (current_link_check_threshold != link_check_threshold) {
pferland 0:9e88a9018fc0 266 logInfo("changing link check threshold from %u to %u", current_link_check_threshold, link_check_threshold);
pferland 0:9e88a9018fc0 267 if (dot->setLinkCheckThreshold(link_check_threshold) != mDot::MDOT_OK) {
pferland 0:9e88a9018fc0 268 logError("failed to set link check threshold to %u", link_check_threshold);
pferland 0:9e88a9018fc0 269 }
pferland 0:9e88a9018fc0 270 }
pferland 0:9e88a9018fc0 271 }
pferland 0:9e88a9018fc0 272
pferland 0:9e88a9018fc0 273 void join_network() {
pferland 0:9e88a9018fc0 274 int32_t j_attempts = 0;
pferland 0:9e88a9018fc0 275 int32_t ret = mDot::MDOT_ERROR;
pferland 0:9e88a9018fc0 276
pferland 0:9e88a9018fc0 277 // attempt to join the network
pferland 0:9e88a9018fc0 278 while (ret != mDot::MDOT_OK) {
pferland 0:9e88a9018fc0 279 logInfo("attempt %d to join network", ++j_attempts);
pferland 0:9e88a9018fc0 280 ret = dot->joinNetwork();
pferland 0:9e88a9018fc0 281 if (ret != mDot::MDOT_OK) {
pferland 0:9e88a9018fc0 282 logError("failed to join network %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
pferland 0:9e88a9018fc0 283 // in some frequency bands we need to wait until another channel is available before transmitting again
pferland 0:9e88a9018fc0 284 uint32_t delay_s = (dot->getNextTxMs() / 1000) + 1;
pferland 0:9e88a9018fc0 285 if (delay_s < 2) {
pferland 0:9e88a9018fc0 286 logInfo("waiting %lu s until next free channel", delay_s);
pferland 0:9e88a9018fc0 287 wait(delay_s);
pferland 0:9e88a9018fc0 288 } else {
pferland 0:9e88a9018fc0 289 logInfo("sleeping %lu s until next free channel", delay_s);
pferland 0:9e88a9018fc0 290 dot->sleep(delay_s, mDot::RTC_ALARM, false);
pferland 0:9e88a9018fc0 291 }
pferland 0:9e88a9018fc0 292 }
pferland 0:9e88a9018fc0 293 }
pferland 0:9e88a9018fc0 294 }
pferland 0:9e88a9018fc0 295
pferland 0:9e88a9018fc0 296 void sleep_wake_rtc_only(bool deepsleep) {
pferland 0:9e88a9018fc0 297 // in some frequency bands we need to wait until another channel is available before transmitting again
pferland 0:9e88a9018fc0 298 // wait at least 10s between transmissions
pferland 0:9e88a9018fc0 299 uint32_t delay_s = dot->getNextTxMs() / 1000;
pferland 9:e642e8f9ea37 300 if (delay_s < 10) {
pferland 10:1e3e3ab9c29c 301 delay_s = 60;
pferland 0:9e88a9018fc0 302 }
pferland 0:9e88a9018fc0 303
pferland 0:9e88a9018fc0 304 logInfo("%ssleeping %lus", deepsleep ? "deep" : "", delay_s);
pferland 0:9e88a9018fc0 305 logInfo("application will %s after waking up", deepsleep ? "execute from beginning" : "resume");
pferland 0:9e88a9018fc0 306
pferland 0:9e88a9018fc0 307 // lowest current consumption in sleep mode can only be achieved by configuring IOs as analog inputs with no pull resistors
pferland 0:9e88a9018fc0 308 // the library handles all internal IOs automatically, but the external IOs are the application's responsibility
pferland 0:9e88a9018fc0 309 // certain IOs may require internal pullup or pulldown resistors because leaving them floating would cause extra current consumption
pferland 0:9e88a9018fc0 310 // for xDot: UART_*, I2C_*, SPI_*, GPIO*, WAKE
pferland 0:9e88a9018fc0 311 // for mDot: XBEE_*, USBTX, USBRX, PB_0, PB_1
pferland 0:9e88a9018fc0 312 // steps are:
pferland 0:9e88a9018fc0 313 // * save IO configuration
pferland 0:9e88a9018fc0 314 // * configure IOs to reduce current consumption
pferland 0:9e88a9018fc0 315 // * sleep
pferland 0:9e88a9018fc0 316 // * restore IO configuration
pferland 0:9e88a9018fc0 317 if (! deepsleep) {
pferland 0:9e88a9018fc0 318 // save the GPIO state.
pferland 0:9e88a9018fc0 319 sleep_save_io();
pferland 0:9e88a9018fc0 320
pferland 0:9e88a9018fc0 321 // configure GPIOs for lowest current
pferland 0:9e88a9018fc0 322 sleep_configure_io();
pferland 0:9e88a9018fc0 323 }
pferland 0:9e88a9018fc0 324
pferland 0:9e88a9018fc0 325 // go to sleep/deepsleep for delay_s seconds and wake using the RTC alarm
pferland 0:9e88a9018fc0 326 dot->sleep(delay_s, mDot::RTC_ALARM, deepsleep);
pferland 0:9e88a9018fc0 327
pferland 0:9e88a9018fc0 328 if (! deepsleep) {
pferland 0:9e88a9018fc0 329 // restore the GPIO state.
pferland 0:9e88a9018fc0 330 sleep_restore_io();
pferland 0:9e88a9018fc0 331 }
pferland 0:9e88a9018fc0 332 }
pferland 0:9e88a9018fc0 333
pferland 0:9e88a9018fc0 334 void sleep_wake_interrupt_only(bool deepsleep) {
pferland 0:9e88a9018fc0 335 #if defined (TARGET_XDOT_L151CC)
pferland 0:9e88a9018fc0 336 if (deepsleep) {
pferland 0:9e88a9018fc0 337 // for xDot, WAKE pin (connected to S2 on xDot-DK) is the only pin that can wake the processor from deepsleep
pferland 0:9e88a9018fc0 338 // it is automatically configured when INTERRUPT or RTC_ALARM_OR_INTERRUPT is the wakeup source and deepsleep is true in the mDot::sleep call
pferland 0:9e88a9018fc0 339 } else {
pferland 0:9e88a9018fc0 340 // configure WAKE pin (connected to S2 on xDot-DK) as the pin that will wake the xDot from low power modes
pferland 0:9e88a9018fc0 341 // other pins can be confgured instead: GPIO0-3 or UART_RX
pferland 0:9e88a9018fc0 342 dot->setWakePin(WAKE);
pferland 0:9e88a9018fc0 343 }
pferland 0:9e88a9018fc0 344
pferland 0:9e88a9018fc0 345 logInfo("%ssleeping until interrupt on %s pin", deepsleep ? "deep" : "", deepsleep ? "WAKE" : mDot::pinName2Str(dot->getWakePin()).c_str());
pferland 0:9e88a9018fc0 346 #else
pferland 0:9e88a9018fc0 347
pferland 0:9e88a9018fc0 348 if (deepsleep) {
pferland 0:9e88a9018fc0 349 // for mDot, XBEE_DIO7 pin is the only pin that can wake the processor from deepsleep
pferland 0:9e88a9018fc0 350 // it is automatically configured when INTERRUPT or RTC_ALARM_OR_INTERRUPT is the wakeup source and deepsleep is true in the mDot::sleep call
pferland 0:9e88a9018fc0 351 } else {
pferland 0:9e88a9018fc0 352 // configure XBEE_DIO7 pin as the pin that will wake the mDot from low power modes
pferland 0:9e88a9018fc0 353 // other pins can be confgured instead: XBEE_DIO2-6, XBEE_DI8, XBEE_DIN
pferland 0:9e88a9018fc0 354 dot->setWakePin(XBEE_DIO7);
pferland 0:9e88a9018fc0 355 }
pferland 0:9e88a9018fc0 356
pferland 0:9e88a9018fc0 357 logInfo("%ssleeping until interrupt on %s pin", deepsleep ? "deep" : "", deepsleep ? "DIO7" : mDot::pinName2Str(dot->getWakePin()).c_str());
pferland 0:9e88a9018fc0 358 #endif
pferland 0:9e88a9018fc0 359
pferland 0:9e88a9018fc0 360 logInfo("application will %s after waking up", deepsleep ? "execute from beginning" : "resume");
pferland 0:9e88a9018fc0 361
pferland 0:9e88a9018fc0 362 // lowest current consumption in sleep mode can only be achieved by configuring IOs as analog inputs with no pull resistors
pferland 0:9e88a9018fc0 363 // the library handles all internal IOs automatically, but the external IOs are the application's responsibility
pferland 0:9e88a9018fc0 364 // certain IOs may require internal pullup or pulldown resistors because leaving them floating would cause extra current consumption
pferland 0:9e88a9018fc0 365 // for xDot: UART_*, I2C_*, SPI_*, GPIO*, WAKE
pferland 0:9e88a9018fc0 366 // for mDot: XBEE_*, USBTX, USBRX, PB_0, PB_1
pferland 0:9e88a9018fc0 367 // steps are:
pferland 0:9e88a9018fc0 368 // * save IO configuration
pferland 0:9e88a9018fc0 369 // * configure IOs to reduce current consumption
pferland 0:9e88a9018fc0 370 // * sleep
pferland 0:9e88a9018fc0 371 // * restore IO configuration
pferland 0:9e88a9018fc0 372 if (! deepsleep) {
pferland 0:9e88a9018fc0 373 // save the GPIO state.
pferland 0:9e88a9018fc0 374 sleep_save_io();
pferland 0:9e88a9018fc0 375
pferland 0:9e88a9018fc0 376 // configure GPIOs for lowest current
pferland 0:9e88a9018fc0 377 sleep_configure_io();
pferland 0:9e88a9018fc0 378 }
pferland 0:9e88a9018fc0 379
pferland 0:9e88a9018fc0 380 // go to sleep/deepsleep and wake on rising edge of configured wake pin (only the WAKE pin in deepsleep)
pferland 0:9e88a9018fc0 381 // since we're not waking on the RTC alarm, the interval is ignored
pferland 0:9e88a9018fc0 382 dot->sleep(0, mDot::INTERRUPT, deepsleep);
pferland 0:9e88a9018fc0 383
pferland 0:9e88a9018fc0 384 if (! deepsleep) {
pferland 0:9e88a9018fc0 385 // restore the GPIO state.
pferland 0:9e88a9018fc0 386 sleep_restore_io();
pferland 0:9e88a9018fc0 387 }
pferland 0:9e88a9018fc0 388 }
pferland 0:9e88a9018fc0 389
pferland 0:9e88a9018fc0 390 void sleep_wake_rtc_or_interrupt(bool deepsleep) {
pferland 0:9e88a9018fc0 391 // in some frequency bands we need to wait until another channel is available before transmitting again
pferland 0:9e88a9018fc0 392 // wait at least 10s between transmissions
pferland 0:9e88a9018fc0 393 uint32_t delay_s = dot->getNextTxMs() / 1000;
pferland 0:9e88a9018fc0 394 if (delay_s < 10) {
pferland 0:9e88a9018fc0 395 delay_s = 10;
pferland 0:9e88a9018fc0 396 }
pferland 0:9e88a9018fc0 397
pferland 0:9e88a9018fc0 398 #if defined (TARGET_XDOT_L151CC)
pferland 0:9e88a9018fc0 399 if (deepsleep) {
pferland 0:9e88a9018fc0 400 // for xDot, WAKE pin (connected to S2 on xDot-DK) is the only pin that can wake the processor from deepsleep
pferland 0:9e88a9018fc0 401 // it is automatically configured when INTERRUPT or RTC_ALARM_OR_INTERRUPT is the wakeup source and deepsleep is true in the mDot::sleep call
pferland 0:9e88a9018fc0 402 } else {
pferland 0:9e88a9018fc0 403 // configure WAKE pin (connected to S2 on xDot-DK) as the pin that will wake the xDot from low power modes
pferland 0:9e88a9018fc0 404 // other pins can be confgured instead: GPIO0-3 or UART_RX
pferland 0:9e88a9018fc0 405 dot->setWakePin(WAKE);
pferland 0:9e88a9018fc0 406 }
pferland 0:9e88a9018fc0 407
pferland 0:9e88a9018fc0 408 logInfo("%ssleeping %lus or until interrupt on %s pin", deepsleep ? "deep" : "", delay_s, deepsleep ? "WAKE" : mDot::pinName2Str(dot->getWakePin()).c_str());
pferland 0:9e88a9018fc0 409 #else
pferland 0:9e88a9018fc0 410 if (deepsleep) {
pferland 0:9e88a9018fc0 411 // for mDot, XBEE_DIO7 pin is the only pin that can wake the processor from deepsleep
pferland 0:9e88a9018fc0 412 // it is automatically configured when INTERRUPT or RTC_ALARM_OR_INTERRUPT is the wakeup source and deepsleep is true in the mDot::sleep call
pferland 0:9e88a9018fc0 413 } else {
pferland 0:9e88a9018fc0 414 // configure XBEE_DIO7 pin as the pin that will wake the mDot from low power modes
pferland 0:9e88a9018fc0 415 // other pins can be confgured instead: XBEE_DIO2-6, XBEE_DI8, XBEE_DIN
pferland 0:9e88a9018fc0 416 dot->setWakePin(XBEE_DIO7);
pferland 0:9e88a9018fc0 417 }
pferland 0:9e88a9018fc0 418
pferland 0:9e88a9018fc0 419 logInfo("%ssleeping %lus or until interrupt on %s pin", deepsleep ? "deep" : "", delay_s, deepsleep ? "DIO7" : mDot::pinName2Str(dot->getWakePin()).c_str());
pferland 0:9e88a9018fc0 420 #endif
pferland 0:9e88a9018fc0 421
pferland 0:9e88a9018fc0 422 logInfo("application will %s after waking up", deepsleep ? "execute from beginning" : "resume");
pferland 0:9e88a9018fc0 423
pferland 0:9e88a9018fc0 424 // lowest current consumption in sleep mode can only be achieved by configuring IOs as analog inputs with no pull resistors
pferland 0:9e88a9018fc0 425 // the library handles all internal IOs automatically, but the external IOs are the application's responsibility
pferland 0:9e88a9018fc0 426 // certain IOs may require internal pullup or pulldown resistors because leaving them floating would cause extra current consumption
pferland 0:9e88a9018fc0 427 // for xDot: UART_*, I2C_*, SPI_*, GPIO*, WAKE
pferland 0:9e88a9018fc0 428 // for mDot: XBEE_*, USBTX, USBRX, PB_0, PB_1
pferland 0:9e88a9018fc0 429 // steps are:
pferland 0:9e88a9018fc0 430 // * save IO configuration
pferland 0:9e88a9018fc0 431 // * configure IOs to reduce current consumption
pferland 0:9e88a9018fc0 432 // * sleep
pferland 0:9e88a9018fc0 433 // * restore IO configuration
pferland 0:9e88a9018fc0 434 if (! deepsleep) {
pferland 0:9e88a9018fc0 435 // save the GPIO state.
pferland 0:9e88a9018fc0 436 sleep_save_io();
pferland 0:9e88a9018fc0 437
pferland 0:9e88a9018fc0 438 // configure GPIOs for lowest current
pferland 0:9e88a9018fc0 439 sleep_configure_io();
pferland 0:9e88a9018fc0 440 }
pferland 0:9e88a9018fc0 441
pferland 0:9e88a9018fc0 442 // 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)
pferland 0:9e88a9018fc0 443 // whichever comes first will wake the xDot
pferland 0:9e88a9018fc0 444 dot->sleep(delay_s, mDot::RTC_ALARM_OR_INTERRUPT, deepsleep);
pferland 0:9e88a9018fc0 445
pferland 0:9e88a9018fc0 446 if (! deepsleep) {
pferland 0:9e88a9018fc0 447 // restore the GPIO state.
pferland 0:9e88a9018fc0 448 sleep_restore_io();
pferland 0:9e88a9018fc0 449 }
pferland 0:9e88a9018fc0 450 }
pferland 0:9e88a9018fc0 451
pferland 0:9e88a9018fc0 452 void sleep_save_io() {
pferland 0:9e88a9018fc0 453 #if defined(TARGET_XDOT_L151CC)
pferland 0:9e88a9018fc0 454 xdot_save_gpio_state();
pferland 0:9e88a9018fc0 455 #else
pferland 0:9e88a9018fc0 456 portA[0] = GPIOA->MODER;
pferland 0:9e88a9018fc0 457 portA[1] = GPIOA->OTYPER;
pferland 0:9e88a9018fc0 458 portA[2] = GPIOA->OSPEEDR;
pferland 0:9e88a9018fc0 459 portA[3] = GPIOA->PUPDR;
pferland 0:9e88a9018fc0 460 portA[4] = GPIOA->AFR[0];
pferland 0:9e88a9018fc0 461 portA[5] = GPIOA->AFR[1];
pferland 0:9e88a9018fc0 462
pferland 0:9e88a9018fc0 463 portB[0] = GPIOB->MODER;
pferland 0:9e88a9018fc0 464 portB[1] = GPIOB->OTYPER;
pferland 0:9e88a9018fc0 465 portB[2] = GPIOB->OSPEEDR;
pferland 0:9e88a9018fc0 466 portB[3] = GPIOB->PUPDR;
pferland 0:9e88a9018fc0 467 portB[4] = GPIOB->AFR[0];
pferland 0:9e88a9018fc0 468 portB[5] = GPIOB->AFR[1];
pferland 0:9e88a9018fc0 469
pferland 0:9e88a9018fc0 470 portC[0] = GPIOC->MODER;
pferland 0:9e88a9018fc0 471 portC[1] = GPIOC->OTYPER;
pferland 0:9e88a9018fc0 472 portC[2] = GPIOC->OSPEEDR;
pferland 0:9e88a9018fc0 473 portC[3] = GPIOC->PUPDR;
pferland 0:9e88a9018fc0 474 portC[4] = GPIOC->AFR[0];
pferland 0:9e88a9018fc0 475 portC[5] = GPIOC->AFR[1];
pferland 0:9e88a9018fc0 476
pferland 0:9e88a9018fc0 477 portD[0] = GPIOD->MODER;
pferland 0:9e88a9018fc0 478 portD[1] = GPIOD->OTYPER;
pferland 0:9e88a9018fc0 479 portD[2] = GPIOD->OSPEEDR;
pferland 0:9e88a9018fc0 480 portD[3] = GPIOD->PUPDR;
pferland 0:9e88a9018fc0 481 portD[4] = GPIOD->AFR[0];
pferland 0:9e88a9018fc0 482 portD[5] = GPIOD->AFR[1];
pferland 0:9e88a9018fc0 483
pferland 0:9e88a9018fc0 484 portH[0] = GPIOH->MODER;
pferland 0:9e88a9018fc0 485 portH[1] = GPIOH->OTYPER;
pferland 0:9e88a9018fc0 486 portH[2] = GPIOH->OSPEEDR;
pferland 0:9e88a9018fc0 487 portH[3] = GPIOH->PUPDR;
pferland 0:9e88a9018fc0 488 portH[4] = GPIOH->AFR[0];
pferland 0:9e88a9018fc0 489 portH[5] = GPIOH->AFR[1];
pferland 0:9e88a9018fc0 490 #endif
pferland 0:9e88a9018fc0 491 }
pferland 0:9e88a9018fc0 492
pferland 0:9e88a9018fc0 493 void sleep_configure_io() {
pferland 0:9e88a9018fc0 494 #if defined(TARGET_XDOT_L151CC)
pferland 0:9e88a9018fc0 495 // GPIO Ports Clock Enable
pferland 0:9e88a9018fc0 496 __GPIOA_CLK_ENABLE();
pferland 0:9e88a9018fc0 497 __GPIOB_CLK_ENABLE();
pferland 0:9e88a9018fc0 498 __GPIOC_CLK_ENABLE();
pferland 0:9e88a9018fc0 499 __GPIOH_CLK_ENABLE();
pferland 0:9e88a9018fc0 500
pferland 0:9e88a9018fc0 501 GPIO_InitTypeDef GPIO_InitStruct;
pferland 0:9e88a9018fc0 502
pferland 0:9e88a9018fc0 503 // UART1_TX, UART1_RTS & UART1_CTS to analog nopull - RX could be a wakeup source
pferland 0:9e88a9018fc0 504 GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_11 | GPIO_PIN_12;
pferland 0:9e88a9018fc0 505 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
pferland 0:9e88a9018fc0 506 GPIO_InitStruct.Pull = GPIO_NOPULL;
pferland 0:9e88a9018fc0 507 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
pferland 0:9e88a9018fc0 508
pferland 0:9e88a9018fc0 509 // I2C_SDA & I2C_SCL to analog nopull
pferland 0:9e88a9018fc0 510 GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9;
pferland 0:9e88a9018fc0 511 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
pferland 0:9e88a9018fc0 512 GPIO_InitStruct.Pull = GPIO_NOPULL;
pferland 0:9e88a9018fc0 513 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
pferland 0:9e88a9018fc0 514
pferland 0:9e88a9018fc0 515 // SPI_MOSI, SPI_MISO, SPI_SCK, & SPI_NSS to analog nopull
pferland 0:9e88a9018fc0 516 GPIO_InitStruct.Pin = GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
pferland 0:9e88a9018fc0 517 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
pferland 0:9e88a9018fc0 518 GPIO_InitStruct.Pull = GPIO_NOPULL;
pferland 0:9e88a9018fc0 519 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
pferland 0:9e88a9018fc0 520
pferland 0:9e88a9018fc0 521 // iterate through potential wake pins - leave the configured wake pin alone if one is needed
pferland 0:9e88a9018fc0 522 if (dot->getWakePin() != WAKE || dot->getWakeMode() == mDot::RTC_ALARM) {
pferland 0:9e88a9018fc0 523 GPIO_InitStruct.Pin = GPIO_PIN_0;
pferland 0:9e88a9018fc0 524 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
pferland 0:9e88a9018fc0 525 GPIO_InitStruct.Pull = GPIO_NOPULL;
pferland 0:9e88a9018fc0 526 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
pferland 0:9e88a9018fc0 527 }
pferland 0:9e88a9018fc0 528 if (dot->getWakePin() != GPIO0 || dot->getWakeMode() == mDot::RTC_ALARM) {
pferland 0:9e88a9018fc0 529 GPIO_InitStruct.Pin = GPIO_PIN_4;
pferland 0:9e88a9018fc0 530 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
pferland 0:9e88a9018fc0 531 GPIO_InitStruct.Pull = GPIO_NOPULL;
pferland 0:9e88a9018fc0 532 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
pferland 0:9e88a9018fc0 533 }
pferland 0:9e88a9018fc0 534 if (dot->getWakePin() != GPIO1 || dot->getWakeMode() == mDot::RTC_ALARM) {
pferland 0:9e88a9018fc0 535 GPIO_InitStruct.Pin = GPIO_PIN_5;
pferland 0:9e88a9018fc0 536 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
pferland 0:9e88a9018fc0 537 GPIO_InitStruct.Pull = GPIO_NOPULL;
pferland 0:9e88a9018fc0 538 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
pferland 0:9e88a9018fc0 539 }
pferland 0:9e88a9018fc0 540 if (dot->getWakePin() != GPIO2 || dot->getWakeMode() == mDot::RTC_ALARM) {
pferland 0:9e88a9018fc0 541 GPIO_InitStruct.Pin = GPIO_PIN_0;
pferland 0:9e88a9018fc0 542 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
pferland 0:9e88a9018fc0 543 GPIO_InitStruct.Pull = GPIO_NOPULL;
pferland 0:9e88a9018fc0 544 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
pferland 0:9e88a9018fc0 545 }
pferland 0:9e88a9018fc0 546 if (dot->getWakePin() != GPIO3 || dot->getWakeMode() == mDot::RTC_ALARM) {
pferland 0:9e88a9018fc0 547 GPIO_InitStruct.Pin = GPIO_PIN_2;
pferland 0:9e88a9018fc0 548 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
pferland 0:9e88a9018fc0 549 GPIO_InitStruct.Pull = GPIO_NOPULL;
pferland 0:9e88a9018fc0 550 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
pferland 0:9e88a9018fc0 551 }
pferland 0:9e88a9018fc0 552 if (dot->getWakePin() != UART1_RX || dot->getWakeMode() == mDot::RTC_ALARM) {
pferland 0:9e88a9018fc0 553 GPIO_InitStruct.Pin = GPIO_PIN_10;
pferland 0:9e88a9018fc0 554 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
pferland 0:9e88a9018fc0 555 GPIO_InitStruct.Pull = GPIO_NOPULL;
pferland 0:9e88a9018fc0 556 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
pferland 0:9e88a9018fc0 557 }
pferland 0:9e88a9018fc0 558 #else
pferland 0:9e88a9018fc0 559 /* GPIO Ports Clock Enable */
pferland 0:9e88a9018fc0 560 __GPIOA_CLK_ENABLE();
pferland 0:9e88a9018fc0 561 __GPIOB_CLK_ENABLE();
pferland 0:9e88a9018fc0 562 __GPIOC_CLK_ENABLE();
pferland 0:9e88a9018fc0 563
pferland 0:9e88a9018fc0 564 GPIO_InitTypeDef GPIO_InitStruct;
pferland 0:9e88a9018fc0 565
pferland 0:9e88a9018fc0 566 // XBEE_DOUT, XBEE_DIN, XBEE_DO8, XBEE_RSSI, USBTX, USBRX, PA_12, PA_13, PA_14 & PA_15 to analog nopull
pferland 0:9e88a9018fc0 567 GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_6 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10
pferland 0:9e88a9018fc0 568 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
pferland 0:9e88a9018fc0 569 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
pferland 0:9e88a9018fc0 570 GPIO_InitStruct.Pull = GPIO_NOPULL;
pferland 0:9e88a9018fc0 571 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
pferland 0:9e88a9018fc0 572
pferland 0:9e88a9018fc0 573 // PB_0, PB_1, PB_3 & PB_4 to analog nopull
pferland 0:9e88a9018fc0 574 GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_3 | GPIO_PIN_4;
pferland 0:9e88a9018fc0 575 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
pferland 0:9e88a9018fc0 576 GPIO_InitStruct.Pull = GPIO_NOPULL;
pferland 0:9e88a9018fc0 577 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
pferland 0:9e88a9018fc0 578
pferland 0:9e88a9018fc0 579 // PC_9 & PC_13 to analog nopull
pferland 0:9e88a9018fc0 580 GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_13;
pferland 0:9e88a9018fc0 581 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
pferland 0:9e88a9018fc0 582 GPIO_InitStruct.Pull = GPIO_NOPULL;
pferland 0:9e88a9018fc0 583 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
pferland 0:9e88a9018fc0 584
pferland 0:9e88a9018fc0 585 // iterate through potential wake pins - leave the configured wake pin alone if one is needed
pferland 0:9e88a9018fc0 586 // XBEE_DIN - PA3
pferland 0:9e88a9018fc0 587 // XBEE_DIO2 - PA5
pferland 0:9e88a9018fc0 588 // XBEE_DIO3 - PA4
pferland 0:9e88a9018fc0 589 // XBEE_DIO4 - PA7
pferland 0:9e88a9018fc0 590 // XBEE_DIO5 - PC1
pferland 0:9e88a9018fc0 591 // XBEE_DIO6 - PA1
pferland 0:9e88a9018fc0 592 // XBEE_DIO7 - PA0
pferland 0:9e88a9018fc0 593 // XBEE_SLEEPRQ - PA11
pferland 0:9e88a9018fc0 594
pferland 0:9e88a9018fc0 595 if (dot->getWakePin() != XBEE_DIN || dot->getWakeMode() == mDot::RTC_ALARM) {
pferland 0:9e88a9018fc0 596 GPIO_InitStruct.Pin = GPIO_PIN_3;
pferland 0:9e88a9018fc0 597 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
pferland 0:9e88a9018fc0 598 GPIO_InitStruct.Pull = GPIO_NOPULL;
pferland 0:9e88a9018fc0 599 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
pferland 0:9e88a9018fc0 600 }
pferland 0:9e88a9018fc0 601
pferland 0:9e88a9018fc0 602 if (dot->getWakePin() != XBEE_DIO2 || dot->getWakeMode() == mDot::RTC_ALARM) {
pferland 0:9e88a9018fc0 603 GPIO_InitStruct.Pin = GPIO_PIN_5;
pferland 0:9e88a9018fc0 604 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
pferland 0:9e88a9018fc0 605 GPIO_InitStruct.Pull = GPIO_NOPULL;
pferland 0:9e88a9018fc0 606 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
pferland 0:9e88a9018fc0 607 }
pferland 0:9e88a9018fc0 608
pferland 0:9e88a9018fc0 609 if (dot->getWakePin() != XBEE_DIO3 || dot->getWakeMode() == mDot::RTC_ALARM) {
pferland 0:9e88a9018fc0 610 GPIO_InitStruct.Pin = GPIO_PIN_4;
pferland 0:9e88a9018fc0 611 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
pferland 0:9e88a9018fc0 612 GPIO_InitStruct.Pull = GPIO_NOPULL;
pferland 0:9e88a9018fc0 613 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
pferland 0:9e88a9018fc0 614 }
pferland 0:9e88a9018fc0 615
pferland 0:9e88a9018fc0 616 if (dot->getWakePin() != XBEE_DIO4 || dot->getWakeMode() == mDot::RTC_ALARM) {
pferland 0:9e88a9018fc0 617 GPIO_InitStruct.Pin = GPIO_PIN_7;
pferland 0:9e88a9018fc0 618 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
pferland 0:9e88a9018fc0 619 GPIO_InitStruct.Pull = GPIO_NOPULL;
pferland 0:9e88a9018fc0 620 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
pferland 0:9e88a9018fc0 621 }
pferland 0:9e88a9018fc0 622
pferland 0:9e88a9018fc0 623 if (dot->getWakePin() != XBEE_DIO5 || dot->getWakeMode() == mDot::RTC_ALARM) {
pferland 0:9e88a9018fc0 624 GPIO_InitStruct.Pin = GPIO_PIN_1;
pferland 0:9e88a9018fc0 625 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
pferland 0:9e88a9018fc0 626 GPIO_InitStruct.Pull = GPIO_NOPULL;
pferland 0:9e88a9018fc0 627 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
pferland 0:9e88a9018fc0 628 }
pferland 0:9e88a9018fc0 629
pferland 0:9e88a9018fc0 630 if (dot->getWakePin() != XBEE_DIO6 || dot->getWakeMode() == mDot::RTC_ALARM) {
pferland 0:9e88a9018fc0 631 GPIO_InitStruct.Pin = GPIO_PIN_1;
pferland 0:9e88a9018fc0 632 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
pferland 0:9e88a9018fc0 633 GPIO_InitStruct.Pull = GPIO_NOPULL;
pferland 0:9e88a9018fc0 634 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
pferland 0:9e88a9018fc0 635 }
pferland 0:9e88a9018fc0 636
pferland 0:9e88a9018fc0 637 if (dot->getWakePin() != XBEE_DIO7 || dot->getWakeMode() == mDot::RTC_ALARM) {
pferland 0:9e88a9018fc0 638 GPIO_InitStruct.Pin = GPIO_PIN_0;
pferland 0:9e88a9018fc0 639 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
pferland 0:9e88a9018fc0 640 GPIO_InitStruct.Pull = GPIO_NOPULL;
pferland 0:9e88a9018fc0 641 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
pferland 0:9e88a9018fc0 642 }
pferland 0:9e88a9018fc0 643
pferland 0:9e88a9018fc0 644 if (dot->getWakePin() != XBEE_SLEEPRQ|| dot->getWakeMode() == mDot::RTC_ALARM) {
pferland 0:9e88a9018fc0 645 GPIO_InitStruct.Pin = GPIO_PIN_11;
pferland 0:9e88a9018fc0 646 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
pferland 0:9e88a9018fc0 647 GPIO_InitStruct.Pull = GPIO_NOPULL;
pferland 0:9e88a9018fc0 648 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
pferland 0:9e88a9018fc0 649 }
pferland 0:9e88a9018fc0 650 #endif
pferland 0:9e88a9018fc0 651 }
pferland 0:9e88a9018fc0 652
pferland 0:9e88a9018fc0 653 void sleep_restore_io() {
pferland 0:9e88a9018fc0 654 #if defined(TARGET_XDOT_L151CC)
pferland 0:9e88a9018fc0 655 xdot_restore_gpio_state();
pferland 0:9e88a9018fc0 656 #else
pferland 0:9e88a9018fc0 657 GPIOA->MODER = portA[0];
pferland 0:9e88a9018fc0 658 GPIOA->OTYPER = portA[1];
pferland 0:9e88a9018fc0 659 GPIOA->OSPEEDR = portA[2];
pferland 0:9e88a9018fc0 660 GPIOA->PUPDR = portA[3];
pferland 0:9e88a9018fc0 661 GPIOA->AFR[0] = portA[4];
pferland 0:9e88a9018fc0 662 GPIOA->AFR[1] = portA[5];
pferland 0:9e88a9018fc0 663
pferland 0:9e88a9018fc0 664 GPIOB->MODER = portB[0];
pferland 0:9e88a9018fc0 665 GPIOB->OTYPER = portB[1];
pferland 0:9e88a9018fc0 666 GPIOB->OSPEEDR = portB[2];
pferland 0:9e88a9018fc0 667 GPIOB->PUPDR = portB[3];
pferland 0:9e88a9018fc0 668 GPIOB->AFR[0] = portB[4];
pferland 0:9e88a9018fc0 669 GPIOB->AFR[1] = portB[5];
pferland 0:9e88a9018fc0 670
pferland 0:9e88a9018fc0 671 GPIOC->MODER = portC[0];
pferland 0:9e88a9018fc0 672 GPIOC->OTYPER = portC[1];
pferland 0:9e88a9018fc0 673 GPIOC->OSPEEDR = portC[2];
pferland 0:9e88a9018fc0 674 GPIOC->PUPDR = portC[3];
pferland 0:9e88a9018fc0 675 GPIOC->AFR[0] = portC[4];
pferland 0:9e88a9018fc0 676 GPIOC->AFR[1] = portC[5];
pferland 0:9e88a9018fc0 677
pferland 0:9e88a9018fc0 678 GPIOD->MODER = portD[0];
pferland 0:9e88a9018fc0 679 GPIOD->OTYPER = portD[1];
pferland 0:9e88a9018fc0 680 GPIOD->OSPEEDR = portD[2];
pferland 0:9e88a9018fc0 681 GPIOD->PUPDR = portD[3];
pferland 0:9e88a9018fc0 682 GPIOD->AFR[0] = portD[4];
pferland 0:9e88a9018fc0 683 GPIOD->AFR[1] = portD[5];
pferland 0:9e88a9018fc0 684
pferland 0:9e88a9018fc0 685 GPIOH->MODER = portH[0];
pferland 0:9e88a9018fc0 686 GPIOH->OTYPER = portH[1];
pferland 0:9e88a9018fc0 687 GPIOH->OSPEEDR = portH[2];
pferland 0:9e88a9018fc0 688 GPIOH->PUPDR = portH[3];
pferland 0:9e88a9018fc0 689 GPIOH->AFR[0] = portH[4];
pferland 0:9e88a9018fc0 690 GPIOH->AFR[1] = portH[5];
pferland 0:9e88a9018fc0 691 #endif
pferland 0:9e88a9018fc0 692 }
pferland 0:9e88a9018fc0 693
pferland 0:9e88a9018fc0 694 void send_data(std::vector<uint8_t> data) {
pferland 0:9e88a9018fc0 695 uint32_t ret;
pferland 0:9e88a9018fc0 696
pferland 0:9e88a9018fc0 697 ret = dot->send(data);
pferland 0:9e88a9018fc0 698 if (ret != mDot::MDOT_OK) {
pferland 0:9e88a9018fc0 699 logError("failed to send data to %s [%d][%s]", dot->getJoinMode() == mDot::PEER_TO_PEER ? "peer" : "gateway", ret, mDot::getReturnCodeString(ret).c_str());
pferland 0:9e88a9018fc0 700 } else {
pferland 0:9e88a9018fc0 701 logInfo("successfully sent data to %s", dot->getJoinMode() == mDot::PEER_TO_PEER ? "peer" : "gateway");
pferland 0:9e88a9018fc0 702 }
pferland 0:9e88a9018fc0 703 }