From a76cb948510105aa1cdb0330d38bb4815750015c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Mon, 17 Apr 2023 18:22:12 +0200 Subject: [PATCH 01/12] Revert "Trying to debug transient "disconnects" in iOS (#2312)" (#2435) This reverts commit d17aafa91a2475d5c3d7efaa4d22250f775f32eb. --- src/platform/nrf52/NRF52Bluetooth.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/nrf52/NRF52Bluetooth.cpp b/src/platform/nrf52/NRF52Bluetooth.cpp index 59d11717a..044b57ae6 100644 --- a/src/platform/nrf52/NRF52Bluetooth.cpp +++ b/src/platform/nrf52/NRF52Bluetooth.cpp @@ -92,12 +92,12 @@ void startAdv(void) Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE); // IncludeService UUID - Bluefruit.ScanResponse.addService(meshBleService); + // Bluefruit.ScanResponse.addService(meshBleService); Bluefruit.ScanResponse.addTxPower(); Bluefruit.ScanResponse.addName(); // Include Name - Bluefruit.Advertising.addName(); + // Bluefruit.Advertising.addName(); Bluefruit.Advertising.addService(meshBleService); /* Start Advertising From d43ddc9ec2aae5381a082a93c5479787861fc2b5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 17 Apr 2023 15:42:42 -0500 Subject: [PATCH 02/12] [create-pull-request] automated change (#2436) --- protobufs | 2 +- src/mesh/generated/meshtastic/mesh.pb.c | 6 +++ src/mesh/generated/meshtastic/mesh.pb.h | 50 +++++++++++++++++++++ src/mesh/generated/meshtastic/portnums.pb.h | 2 + 4 files changed, 59 insertions(+), 1 deletion(-) diff --git a/protobufs b/protobufs index ee6f408bb..ef2bc66bb 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit ee6f408bb3c27b8ca820477cbb3a84ac6c8b0ffc +Subproject commit ef2bc66bba41e8ef98ea893e46eb36a2da40cb5e diff --git a/src/mesh/generated/meshtastic/mesh.pb.c b/src/mesh/generated/meshtastic/mesh.pb.c index 0c3c155f6..ce7d48b14 100644 --- a/src/mesh/generated/meshtastic/mesh.pb.c +++ b/src/mesh/generated/meshtastic/mesh.pb.c @@ -48,6 +48,12 @@ PB_BIND(meshtastic_ToRadio, meshtastic_ToRadio, 2) PB_BIND(meshtastic_Compressed, meshtastic_Compressed, AUTO) +PB_BIND(meshtastic_NeighborInfo, meshtastic_NeighborInfo, AUTO) + + +PB_BIND(meshtastic_Neighbor, meshtastic_Neighbor, AUTO) + + PB_BIND(meshtastic_DeviceMetadata, meshtastic_DeviceMetadata, AUTO) diff --git a/src/mesh/generated/meshtastic/mesh.pb.h b/src/mesh/generated/meshtastic/mesh.pb.h index e95cffdfe..984939702 100644 --- a/src/mesh/generated/meshtastic/mesh.pb.h +++ b/src/mesh/generated/meshtastic/mesh.pb.h @@ -680,6 +680,25 @@ typedef struct _meshtastic_Compressed { meshtastic_Compressed_data_t data; } meshtastic_Compressed; +/* A single edge in the mesh */ +typedef struct _meshtastic_Neighbor { + /* Node ID of neighbor */ + uint32_t node_id; + /* SNR of last heard message */ + float snr; +} meshtastic_Neighbor; + +/* Full info on edges for a single node */ +typedef struct _meshtastic_NeighborInfo { + /* The node ID of the node sending info on its neighbors */ + uint32_t node_id; + /* Field to pass neighbor info for the next sending cycle */ + uint32_t last_sent_by_id; + /* The list of out edges from this node */ + pb_size_t neighbors_count; + meshtastic_Neighbor neighbors[10]; +} meshtastic_NeighborInfo; + /* Device metadata response */ typedef struct _meshtastic_DeviceMetadata { /* Device firmware version string */ @@ -813,6 +832,8 @@ extern "C" { #define meshtastic_Compressed_portnum_ENUMTYPE meshtastic_PortNum + + #define meshtastic_DeviceMetadata_role_ENUMTYPE meshtastic_Config_DeviceConfig_Role #define meshtastic_DeviceMetadata_hw_model_ENUMTYPE meshtastic_HardwareModel @@ -832,6 +853,8 @@ extern "C" { #define meshtastic_FromRadio_init_default {0, 0, {meshtastic_MeshPacket_init_default}} #define meshtastic_ToRadio_init_default {0, {meshtastic_MeshPacket_init_default}} #define meshtastic_Compressed_init_default {_meshtastic_PortNum_MIN, {0, {0}}} +#define meshtastic_NeighborInfo_init_default {0, 0, 0, {meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default}} +#define meshtastic_Neighbor_init_default {0, 0} #define meshtastic_DeviceMetadata_init_default {"", 0, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_Role_MIN, 0, _meshtastic_HardwareModel_MIN} #define meshtastic_Position_init_zero {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN, _meshtastic_Position_AltSource_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} #define meshtastic_User_init_zero {"", "", "", {0}, _meshtastic_HardwareModel_MIN, 0} @@ -847,6 +870,8 @@ extern "C" { #define meshtastic_FromRadio_init_zero {0, 0, {meshtastic_MeshPacket_init_zero}} #define meshtastic_ToRadio_init_zero {0, {meshtastic_MeshPacket_init_zero}} #define meshtastic_Compressed_init_zero {_meshtastic_PortNum_MIN, {0, {0}}} +#define meshtastic_NeighborInfo_init_zero {0, 0, 0, {meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero}} +#define meshtastic_Neighbor_init_zero {0, 0} #define meshtastic_DeviceMetadata_init_zero {"", 0, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_Role_MIN, 0, _meshtastic_HardwareModel_MIN} /* Field tags (for use in manual encoding/decoding) */ @@ -948,6 +973,11 @@ extern "C" { #define meshtastic_ToRadio_xmodemPacket_tag 5 #define meshtastic_Compressed_portnum_tag 1 #define meshtastic_Compressed_data_tag 2 +#define meshtastic_Neighbor_node_id_tag 1 +#define meshtastic_Neighbor_snr_tag 2 +#define meshtastic_NeighborInfo_node_id_tag 1 +#define meshtastic_NeighborInfo_last_sent_by_id_tag 2 +#define meshtastic_NeighborInfo_neighbors_tag 3 #define meshtastic_DeviceMetadata_firmware_version_tag 1 #define meshtastic_DeviceMetadata_device_state_version_tag 2 #define meshtastic_DeviceMetadata_canShutdown_tag 3 @@ -1157,6 +1187,20 @@ X(a, STATIC, SINGULAR, BYTES, data, 2) #define meshtastic_Compressed_CALLBACK NULL #define meshtastic_Compressed_DEFAULT NULL +#define meshtastic_NeighborInfo_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, UINT32, node_id, 1) \ +X(a, STATIC, SINGULAR, UINT32, last_sent_by_id, 2) \ +X(a, STATIC, REPEATED, MESSAGE, neighbors, 3) +#define meshtastic_NeighborInfo_CALLBACK NULL +#define meshtastic_NeighborInfo_DEFAULT NULL +#define meshtastic_NeighborInfo_neighbors_MSGTYPE meshtastic_Neighbor + +#define meshtastic_Neighbor_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, UINT32, node_id, 1) \ +X(a, STATIC, SINGULAR, FLOAT, snr, 2) +#define meshtastic_Neighbor_CALLBACK NULL +#define meshtastic_Neighbor_DEFAULT NULL + #define meshtastic_DeviceMetadata_FIELDLIST(X, a) \ X(a, STATIC, SINGULAR, STRING, firmware_version, 1) \ X(a, STATIC, SINGULAR, UINT32, device_state_version, 2) \ @@ -1184,6 +1228,8 @@ extern const pb_msgdesc_t meshtastic_QueueStatus_msg; extern const pb_msgdesc_t meshtastic_FromRadio_msg; extern const pb_msgdesc_t meshtastic_ToRadio_msg; extern const pb_msgdesc_t meshtastic_Compressed_msg; +extern const pb_msgdesc_t meshtastic_NeighborInfo_msg; +extern const pb_msgdesc_t meshtastic_Neighbor_msg; extern const pb_msgdesc_t meshtastic_DeviceMetadata_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ @@ -1201,6 +1247,8 @@ extern const pb_msgdesc_t meshtastic_DeviceMetadata_msg; #define meshtastic_FromRadio_fields &meshtastic_FromRadio_msg #define meshtastic_ToRadio_fields &meshtastic_ToRadio_msg #define meshtastic_Compressed_fields &meshtastic_Compressed_msg +#define meshtastic_NeighborInfo_fields &meshtastic_NeighborInfo_msg +#define meshtastic_Neighbor_fields &meshtastic_Neighbor_msg #define meshtastic_DeviceMetadata_fields &meshtastic_DeviceMetadata_msg /* Maximum encoded size of messages (where known) */ @@ -1211,6 +1259,8 @@ extern const pb_msgdesc_t meshtastic_DeviceMetadata_msg; #define meshtastic_LogRecord_size 81 #define meshtastic_MeshPacket_size 321 #define meshtastic_MyNodeInfo_size 179 +#define meshtastic_NeighborInfo_size 142 +#define meshtastic_Neighbor_size 11 #define meshtastic_NodeInfo_size 261 #define meshtastic_Position_size 137 #define meshtastic_QueueStatus_size 23 diff --git a/src/mesh/generated/meshtastic/portnums.pb.h b/src/mesh/generated/meshtastic/portnums.pb.h index 59cf0ebe5..ccf94372e 100644 --- a/src/mesh/generated/meshtastic/portnums.pb.h +++ b/src/mesh/generated/meshtastic/portnums.pb.h @@ -85,6 +85,8 @@ typedef enum _meshtastic_PortNum { /* Provides a traceroute functionality to show the route a packet towards a certain destination would take on the mesh. */ meshtastic_PortNum_TRACEROUTE_APP = 70, + /* Aggregates edge info for the network by sending out a list of each node's neighbors */ + meshtastic_PortNum_NEIGHBORINFO_APP = 71, /* Private applications should use portnums >= 256. To simplify initial development and testing you can use "PRIVATE_APP" in your code without needing to rebuild protobuf files (via [regen-protos.sh](https://github.com/meshtastic/firmware/blob/master/bin/regen-protos.sh)) */ From c452c2ab4080e2f9f6eb4225c05e6c30b97bae94 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 17 Apr 2023 19:42:54 -0500 Subject: [PATCH 03/12] [create-pull-request] automated change (#2437) Co-authored-by: thebentern --- version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.properties b/version.properties index 02e47fdf2..253a4d545 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 2 minor = 1 -build = 9 +build = 10 From 584615bb4b4b2813790ca574880cbc5871cd9286 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 18 Apr 2023 13:37:50 +0200 Subject: [PATCH 04/12] fix topic construction for mqtt debug --- src/Power.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Power.cpp b/src/Power.cpp index 06e887433..6d8efcb0a 100644 --- a/src/Power.cpp +++ b/src/Power.cpp @@ -351,14 +351,13 @@ void Power::readPowerStatus() sprintf(mac, "!%02x%02x%02x%02x", dmac[2], dmac[3], dmac[4], dmac[5]); auto newHeap = memGet.getFreeHeap(); - std::string heapTopic = (*moduleConfig.mqtt.root ? moduleConfig.mqtt.root : "msh") + "/2/heap/" + std::string(mac); + std::string heapTopic = (*moduleConfig.mqtt.root ? moduleConfig.mqtt.root : "msh") + std::string("/2/heap/") + std::string(mac); std::string heapString = std::to_string(newHeap); mqtt->pubSub.publish(heapTopic.c_str(), heapString.c_str(), false); - // auto fragHeap = memGet.getHeapFragmentation(); auto wifiRSSI = WiFi.RSSI(); - heapTopic = (*moduleConfig.mqtt.root ? moduleConfig.mqtt.root : "msh") + "/2/wifi/" + std::string(mac); + std::string wifiTopic = (*moduleConfig.mqtt.root ? moduleConfig.mqtt.root : "msh") + std::string("/2/wifi/") + std::string(mac); std::string wifiString = std::to_string(wifiRSSI); - mqtt->pubSub.publish(heapTopic.c_str(), wifiString.c_str(), false); + mqtt->pubSub.publish(wifiTopic.c_str(), wifiString.c_str(), false); } #endif From 87c59d7d61bf742491874882f6b8e61929fb6f21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 18 Apr 2023 14:08:06 +0200 Subject: [PATCH 05/12] fmt --- src/Power.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Power.cpp b/src/Power.cpp index 6d8efcb0a..6bd679ae2 100644 --- a/src/Power.cpp +++ b/src/Power.cpp @@ -351,11 +351,13 @@ void Power::readPowerStatus() sprintf(mac, "!%02x%02x%02x%02x", dmac[2], dmac[3], dmac[4], dmac[5]); auto newHeap = memGet.getFreeHeap(); - std::string heapTopic = (*moduleConfig.mqtt.root ? moduleConfig.mqtt.root : "msh") + std::string("/2/heap/") + std::string(mac); + std::string heapTopic = + (*moduleConfig.mqtt.root ? moduleConfig.mqtt.root : "msh") + std::string("/2/heap/") + std::string(mac); std::string heapString = std::to_string(newHeap); mqtt->pubSub.publish(heapTopic.c_str(), heapString.c_str(), false); auto wifiRSSI = WiFi.RSSI(); - std::string wifiTopic = (*moduleConfig.mqtt.root ? moduleConfig.mqtt.root : "msh") + std::string("/2/wifi/") + std::string(mac); + std::string wifiTopic = + (*moduleConfig.mqtt.root ? moduleConfig.mqtt.root : "msh") + std::string("/2/wifi/") + std::string(mac); std::string wifiString = std::to_string(wifiRSSI); mqtt->pubSub.publish(wifiTopic.c_str(), wifiString.c_str(), false); } From ac40f7769400e5eae7807cdb120ed855acfa9836 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Wed, 12 Apr 2023 10:04:29 +0200 Subject: [PATCH 06/12] Draft for now, please test --- platformio.ini | 2 +- src/modules/Telemetry/Sensor/BME680Sensor.cpp | 61 +++++++++++++++++-- src/modules/Telemetry/Sensor/BME680Sensor.h | 28 ++++++++- 3 files changed, 84 insertions(+), 7 deletions(-) diff --git a/platformio.ini b/platformio.ini index c339cf992..508f3615b 100644 --- a/platformio.ini +++ b/platformio.ini @@ -105,7 +105,7 @@ lib_deps = adafruit/Adafruit Unified Sensor@^1.1.9 adafruit/Adafruit BMP280 Library@^2.6.6 adafruit/Adafruit BME280 Library@^2.2.2 - adafruit/Adafruit BME680 Library@^2.0.1 + https://github.com/meshtastic/BSEC-Arduino-library.git#452f9a7ffa8b53e1debe2c454fe375dfad98b507 adafruit/Adafruit MCP9808 Library@^2.0.0 adafruit/Adafruit INA260 Library@^1.5.0 adafruit/Adafruit INA219@^1.2.0 diff --git a/src/modules/Telemetry/Sensor/BME680Sensor.cpp b/src/modules/Telemetry/Sensor/BME680Sensor.cpp index f05246d52..21beedcea 100644 --- a/src/modules/Telemetry/Sensor/BME680Sensor.cpp +++ b/src/modules/Telemetry/Sensor/BME680Sensor.cpp @@ -1,8 +1,8 @@ #include "BME680Sensor.h" #include "../mesh/generated/meshtastic/telemetry.pb.h" +#include "FSCommon.h" #include "TelemetrySensor.h" #include "configuration.h" -#include BME680Sensor::BME680Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_BME680, "BME680") {} @@ -12,7 +12,15 @@ int32_t BME680Sensor::runOnce() if (!hasSensor()) { return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; } - status = bme680.begin(nodeTelemetrySensorsMap[sensorType]); + bme680.begin(nodeTelemetrySensorsMap[sensorType], Wire); + if (bme680.bsecStatus == BSEC_OK) { + bme680.setConfig(bsec_config_iaq); + loadState(); + bme680.updateSubscription(sensorList, 13, BSEC_SAMPLE_RATE_LP); + status = 1; + } else { + status = 0; + } return initI2CSensor(); } @@ -21,11 +29,56 @@ void BME680Sensor::setup() {} bool BME680Sensor::getMetrics(meshtastic_Telemetry *measurement) { - bme680.performReading(); + bme680.run(); measurement->variant.environment_metrics.temperature = bme680.temperature; measurement->variant.environment_metrics.relative_humidity = bme680.humidity; measurement->variant.environment_metrics.barometric_pressure = bme680.pressure / 100.0F; - measurement->variant.environment_metrics.gas_resistance = bme680.gas_resistance / 1000.0; + measurement->variant.environment_metrics.gas_resistance = bme680.gasResistance / 1000.0; + updateState(); + + // Check if we need to save state to filesystem (every STATE_SAVE_PERIOD ms) return true; +} + +void BME680Sensor::loadState() +{ +#ifdef FSCom + if (File file = FSCom.open(bsecConfigFileName, FILE_O_READ)) { + file.read((uint8_t *)&bsecState, BSEC_MAX_STATE_BLOB_SIZE); + file.close(); + bme680.setState(bsecState); + } else { + FSCom.remove(bsecConfigFileName); + } +#endif +} + +void BME680Sensor::updateState() +{ +#ifdef FSCom + bool update = false; + if (stateUpdateCounter == 0) { + /* First state update when IAQ accuracy is >= 3 */ + if (bme680.iaqAccuracy >= 3) { + update = true; + stateUpdateCounter++; + } + } else { + /* Update every STATE_SAVE_PERIOD minutes */ + if ((stateUpdateCounter * STATE_SAVE_PERIOD) < millis()) { + update = true; + stateUpdateCounter++; + } + } + + if (update) { + bme680.getState(bsecState); + if (File file = FSCom.open(bsecConfigFileName, FILE_O_WRITE)) { + file.write((uint8_t *)&bsecState, BSEC_MAX_STATE_BLOB_SIZE); + file.flush(); + file.close(); + } + } +#endif } \ No newline at end of file diff --git a/src/modules/Telemetry/Sensor/BME680Sensor.h b/src/modules/Telemetry/Sensor/BME680Sensor.h index d59374803..78adad01e 100644 --- a/src/modules/Telemetry/Sensor/BME680Sensor.h +++ b/src/modules/Telemetry/Sensor/BME680Sensor.h @@ -1,14 +1,38 @@ #include "../mesh/generated/meshtastic/telemetry.pb.h" #include "TelemetrySensor.h" -#include +#include + +#define STATE_SAVE_PERIOD UINT32_C(360 * 60 * 1000) + +const uint8_t bsec_config_iaq[] = { +#include +}; class BME680Sensor : virtual public TelemetrySensor { private: - Adafruit_BME680 bme680; + Bsec bme680; protected: virtual void setup() override; + const char *bsecConfigFileName = "/prefs/bsec.dat"; + uint8_t bsecState[BSEC_MAX_STATE_BLOB_SIZE] = {0}; + uint16_t stateUpdateCounter = 0; + bsec_virtual_sensor_t sensorList[13] = {BSEC_OUTPUT_IAQ, + BSEC_OUTPUT_STATIC_IAQ, + BSEC_OUTPUT_CO2_EQUIVALENT, + BSEC_OUTPUT_BREATH_VOC_EQUIVALENT, + BSEC_OUTPUT_RAW_TEMPERATURE, + BSEC_OUTPUT_RAW_PRESSURE, + BSEC_OUTPUT_RAW_HUMIDITY, + BSEC_OUTPUT_RAW_GAS, + BSEC_OUTPUT_STABILIZATION_STATUS, + BSEC_OUTPUT_RUN_IN_STATUS, + BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE, + BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY, + BSEC_OUTPUT_GAS_PERCENTAGE}; + void loadState(); + void updateState(); public: BME680Sensor(); From 1621fbb5ab43189ca139211566d819ab946e1946 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Fri, 14 Apr 2023 10:38:57 +0200 Subject: [PATCH 07/12] add debug/info print --- src/modules/Telemetry/Sensor/BME680Sensor.cpp | 34 +++++++++++++++---- src/modules/Telemetry/Sensor/BME680Sensor.h | 2 +- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/modules/Telemetry/Sensor/BME680Sensor.cpp b/src/modules/Telemetry/Sensor/BME680Sensor.cpp index 21beedcea..df86da1bd 100644 --- a/src/modules/Telemetry/Sensor/BME680Sensor.cpp +++ b/src/modules/Telemetry/Sensor/BME680Sensor.cpp @@ -8,7 +8,7 @@ BME680Sensor::BME680Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_BM int32_t BME680Sensor::runOnce() { - LOG_INFO("Init sensor: %s\n", sensorName); + LOG_INFO("Init sensor: %s with the BSEC Library\n", sensorName); if (!hasSensor()) { return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; } @@ -34,23 +34,25 @@ bool BME680Sensor::getMetrics(meshtastic_Telemetry *measurement) measurement->variant.environment_metrics.relative_humidity = bme680.humidity; measurement->variant.environment_metrics.barometric_pressure = bme680.pressure / 100.0F; measurement->variant.environment_metrics.gas_resistance = bme680.gasResistance / 1000.0; - updateState(); - // Check if we need to save state to filesystem (every STATE_SAVE_PERIOD ms) - + updateState(); return true; } void BME680Sensor::loadState() { #ifdef FSCom - if (File file = FSCom.open(bsecConfigFileName, FILE_O_READ)) { + auto file = FSCom.open(bsecConfigFileName, FILE_O_READ); + if (file) { file.read((uint8_t *)&bsecState, BSEC_MAX_STATE_BLOB_SIZE); file.close(); bme680.setState(bsecState); + LOG_INFO("%s state read from %s.\n", sensorName, bsecConfigFileName); } else { - FSCom.remove(bsecConfigFileName); + LOG_INFO("No %s state found (File: %s).\n", sensorName, bsecConfigFileName); } +#else + LOG_ERROR("ERROR: Filesystem not implemented\n"); #endif } @@ -61,12 +63,16 @@ void BME680Sensor::updateState() if (stateUpdateCounter == 0) { /* First state update when IAQ accuracy is >= 3 */ if (bme680.iaqAccuracy >= 3) { + LOG_DEBUG("%s state update IAQ accuracy %u >= 3\n", sensorName, bme680.iaqAccuracy); update = true; stateUpdateCounter++; + } else { + LOG_DEBUG("%s not updated, IAQ accuracy is %u >= 3\n", sensorName, bme680.iaqAccuracy); } } else { /* Update every STATE_SAVE_PERIOD minutes */ if ((stateUpdateCounter * STATE_SAVE_PERIOD) < millis()) { + LOG_DEBUG("%s state update every %d minutes\n", sensorName, STATE_SAVE_PERIOD); update = true; stateUpdateCounter++; } @@ -74,11 +80,25 @@ void BME680Sensor::updateState() if (update) { bme680.getState(bsecState); - if (File file = FSCom.open(bsecConfigFileName, FILE_O_WRITE)) { + std::string filenameTmp = bsecConfigFileName; + filenameTmp += ".tmp"; + auto file = FSCom.open(bsecConfigFileName, FILE_O_WRITE); + if (file) { + LOG_INFO("%s state write to %s.\n", sensorName, bsecConfigFileName); file.write((uint8_t *)&bsecState, BSEC_MAX_STATE_BLOB_SIZE); file.flush(); file.close(); + // brief window of risk here ;-) + if (FSCom.exists(bsecConfigFileName) && !FSCom.remove(bsecConfigFileName)) + LOG_WARN("Can't remove old state file\n"); + if (!renameFile(filenameTmp.c_str(), bsecConfigFileName)) + LOG_ERROR("Error: can't rename new state file\n"); + + } else { + LOG_INFO("Can't write %s state (File: %s).\n", sensorName, bsecConfigFileName); } } +#else + LOG_ERROR("ERROR: Filesystem not implemented\n"); #endif } \ No newline at end of file diff --git a/src/modules/Telemetry/Sensor/BME680Sensor.h b/src/modules/Telemetry/Sensor/BME680Sensor.h index 78adad01e..74aff835a 100644 --- a/src/modules/Telemetry/Sensor/BME680Sensor.h +++ b/src/modules/Telemetry/Sensor/BME680Sensor.h @@ -2,7 +2,7 @@ #include "TelemetrySensor.h" #include -#define STATE_SAVE_PERIOD UINT32_C(360 * 60 * 1000) +#define STATE_SAVE_PERIOD UINT32_C(360 * 60 * 1000) // That's 6 hours worth of millis() const uint8_t bsec_config_iaq[] = { #include From e0bb95ca94b85ea8c5ef91e70db192ace57e9146 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 18 Apr 2023 14:22:37 +0200 Subject: [PATCH 08/12] implement dynamic userbutton overwrite. fix #2434 --- src/ButtonThread.h | 10 ++++++---- src/PowerFSM.cpp | 2 +- src/main.cpp | 14 ++++++++------ src/platform/esp32/main-esp32.cpp | 2 +- src/sleep.cpp | 6 ++++-- 5 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/ButtonThread.h b/src/ButtonThread.h index 0e9d060dc..0a8b2afa5 100644 --- a/src/ButtonThread.h +++ b/src/ButtonThread.h @@ -45,10 +45,10 @@ class ButtonThread : public concurrency::OSThread ButtonThread() : OSThread("Button") { #ifdef BUTTON_PIN - userButton = OneButton(BUTTON_PIN, true, true); + userButton = OneButton(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, true, true); #ifdef INPUT_PULLUP_SENSE // Some platforms (nrf52) have a SENSE variant which allows wake from sleep - override what OneButton did - pinMode(BUTTON_PIN, INPUT_PULLUP_SENSE); + pinMode(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, INPUT_PULLUP_SENSE); #endif userButton.attachClick(userButtonPressed); userButton.setClickTicks(300); @@ -57,7 +57,7 @@ class ButtonThread : public concurrency::OSThread userButton.attachMultiClick(userButtonMultiPressed); userButton.attachLongPressStart(userButtonPressedLongStart); userButton.attachLongPressStop(userButtonPressedLongStop); - wakeOnIrq(BUTTON_PIN, FALLING); + wakeOnIrq(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, FALLING); #endif #ifdef BUTTON_PIN_ALT userButtonAlt = OneButton(BUTTON_PIN_ALT, true, true); @@ -115,7 +115,9 @@ class ButtonThread : public concurrency::OSThread { // LOG_DEBUG("press!\n"); #ifdef BUTTON_PIN - if ((BUTTON_PIN != moduleConfig.canned_message.inputbroker_pin_press) || !moduleConfig.canned_message.enabled) { + if (((config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN) != + moduleConfig.canned_message.inputbroker_pin_press) || + !moduleConfig.canned_message.enabled) { powerFSM.trigger(EVENT_PRESS); } #endif diff --git a/src/PowerFSM.cpp b/src/PowerFSM.cpp index e6ebdcc93..7babc2067 100644 --- a/src/PowerFSM.cpp +++ b/src/PowerFSM.cpp @@ -99,7 +99,7 @@ static void lsIdle() LOG_INFO("wakeCause2 %d\n", wakeCause2); #ifdef BUTTON_PIN - bool pressed = !digitalRead(BUTTON_PIN); + bool pressed = !digitalRead(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN); #else bool pressed = false; #endif diff --git a/src/main.cpp b/src/main.cpp index 53ed53b9d..7af41116c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -218,10 +218,10 @@ void setup() // If the button is connected to GPIO 12, don't enable the ability to use // meshtasticAdmin on the device. - pinMode(BUTTON_PIN, INPUT); + pinMode(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, INPUT); #ifdef BUTTON_NEED_PULLUP - gpio_pullup_en((gpio_num_t)BUTTON_PIN); + gpio_pullup_en((gpio_num_t)(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN)); delay(10); #endif @@ -389,10 +389,7 @@ void setup() // scanEInkDevice(); #endif -#if HAS_BUTTON - // Buttons & LED - buttonThread = new ButtonThread(); -#endif + // LED init #ifdef LED_PIN pinMode(LED_PIN, OUTPUT); @@ -417,6 +414,11 @@ void setup() if (config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER) router = new FloodingRouter(); +#if HAS_BUTTON + // Buttons. Moved here cause we need NodeDB to be initialized + buttonThread = new ButtonThread(); +#endif + playStartMelody(); // fixed screen override? diff --git a/src/platform/esp32/main-esp32.cpp b/src/platform/esp32/main-esp32.cpp index 2068025c2..4cb7f4443 100644 --- a/src/platform/esp32/main-esp32.cpp +++ b/src/platform/esp32/main-esp32.cpp @@ -202,7 +202,7 @@ void cpuDeepSleep(uint32_t msecToWake) #ifdef BUTTON_PIN // Only GPIOs which are have RTC functionality can be used in this bit map: 0,2,4,12-15,25-27,32-39. #if SOC_RTCIO_HOLD_SUPPORTED - uint64_t gpioMask = (1ULL << BUTTON_PIN); + uint64_t gpioMask = (1ULL << config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN); #endif #ifdef BUTTON_NEED_PULLUP diff --git a/src/sleep.cpp b/src/sleep.cpp index 9468b7d09..c25e3473e 100644 --- a/src/sleep.cpp +++ b/src/sleep.cpp @@ -309,7 +309,8 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r // assert(esp_sleep_enable_uart_wakeup(0) == ESP_OK); #endif #ifdef BUTTON_PIN - esp_sleep_enable_ext0_wakeup((gpio_num_t)BUTTON_PIN, LOW); // when user presses, this button goes low + esp_sleep_enable_ext0_wakeup((gpio_num_t)(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN), + LOW); // when user presses, this button goes low #endif #if defined(LORA_DIO1) && (LORA_DIO1 != RADIOLIB_NC) gpio_wakeup_enable((gpio_num_t)LORA_DIO1, GPIO_INTR_HIGH_LEVEL); // SX126x/SX128x interrupt, active high @@ -338,7 +339,8 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause(); #ifdef BUTTON_PIN if (cause == ESP_SLEEP_WAKEUP_GPIO) - LOG_INFO("Exit light sleep gpio: btn=%d\n", !digitalRead(BUTTON_PIN)); + LOG_INFO("Exit light sleep gpio: btn=%d\n", + !digitalRead(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN)); #endif return cause; From 5dfb5172c2647a4ddeaa1c4e50510b71136119ab Mon Sep 17 00:00:00 2001 From: Manuel Verch Date: Sat, 22 Apr 2023 00:22:09 +0200 Subject: [PATCH 09/12] try-fix: router goes sporadically into DS --- src/Power.cpp | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/Power.cpp b/src/Power.cpp index 6bd679ae2..358fc4683 100644 --- a/src/Power.cpp +++ b/src/Power.cpp @@ -365,27 +365,24 @@ void Power::readPowerStatus() #endif -// If we have a battery at all and it is less than 10% full, force deep sleep if we have more than 3 low readings in a row -// Supect fluctuating voltage on the RAK4631 to force it to deep sleep even if battery is at 85% after only a few days -#ifdef ARCH_NRF52 + // If we have a battery at all and it is less than 10% full, force deep sleep if we have more than 10 low readings in a row if (powerStatus2.getHasBattery() && !powerStatus2.getHasUSB()) { if (batteryLevel->getBattVoltage() < MIN_BAT_MILLIVOLTS) { low_voltage_counter++; - LOG_DEBUG("Warning RAK4631 Low voltage counter: %d/10\n", low_voltage_counter); + LOG_DEBUG("Low voltage counter: %d/10\n", low_voltage_counter); if (low_voltage_counter > 10) { +#ifdef ARCH_NRF52 // We can't trigger deep sleep on NRF52, it's freezing the board - // powerFSM.trigger(EVENT_LOW_BATTERY); LOG_DEBUG("Low voltage detected, but not triggering deep sleep\n"); +#else + LOG_INFO("Low voltage detected, triggering deep sleep\n"); + powerFSM.trigger(EVENT_LOW_BATTERY); +#endif } } else { low_voltage_counter = 0; } } -#else - // If we have a battery at all and it is less than 10% full, force deep sleep - if (powerStatus2.getHasBattery() && !powerStatus2.getHasUSB() && batteryLevel->getBattVoltage() < MIN_BAT_MILLIVOLTS) - powerFSM.trigger(EVENT_LOW_BATTERY); -#endif } else { // No power sensing on this board - tell everyone else we have no idea what is happening const PowerStatus powerStatus3 = PowerStatus(OptUnknown, OptUnknown, OptUnknown, -1, -1); @@ -539,7 +536,6 @@ bool Power::axpChipInit() // Set up the charging voltage PMU->setChargeTargetVoltage(XPOWERS_AXP192_CHG_VOL_4V2); - } else if (PMU->getChipModel() == XPOWERS_AXP2101) { /*The alternative version of T-Beam 1.1 differs from T-Beam V1.1 in that it uses an AXP2101 power chip*/ @@ -731,4 +727,4 @@ bool Power::axpChipInit() #else return false; #endif -} +} \ No newline at end of file From 6e26f95df9f438b8818f8769811ce6c2854b9fc1 Mon Sep 17 00:00:00 2001 From: Manuel Verch Date: Sat, 22 Apr 2023 01:15:09 +0200 Subject: [PATCH 10/12] Make trunk happy again --- src/Power.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Power.cpp b/src/Power.cpp index 358fc4683..b129fbcd0 100644 --- a/src/Power.cpp +++ b/src/Power.cpp @@ -365,7 +365,8 @@ void Power::readPowerStatus() #endif - // If we have a battery at all and it is less than 10% full, force deep sleep if we have more than 10 low readings in a row + // If we have a battery at all and it is less than 10% full, force deep sleep if we have more than 10 low readings in a + // row if (powerStatus2.getHasBattery() && !powerStatus2.getHasUSB()) { if (batteryLevel->getBattVoltage() < MIN_BAT_MILLIVOLTS) { low_voltage_counter++; From 1eff8fdba8101e13961ddda13f9ef34a2b2c3ba9 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Thu, 23 Mar 2023 19:35:51 -0500 Subject: [PATCH 11/12] WIP scaffolding --- arch/apollo3/apollo3.ini | 14 ++++++++++++++ src/platform/apollo3/architecture.h | 15 +++++++++++++++ src/platform/apollo3/main-apollo3.cpp | 24 ++++++++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 arch/apollo3/apollo3.ini create mode 100644 src/platform/apollo3/architecture.h create mode 100644 src/platform/apollo3/main-apollo3.cpp diff --git a/arch/apollo3/apollo3.ini b/arch/apollo3/apollo3.ini new file mode 100644 index 000000000..b9bb36b50 --- /dev/null +++ b/arch/apollo3/apollo3.ini @@ -0,0 +1,14 @@ +[apollo3_base] +platform_packages = platform_packages=framework-arduinoapollo3@https://github.com/sparkfun/Arduino_Apollo3#v2.2.0 +board = RAK11722 +framework = arduino +build_type = debug +build_flags = + ${arduino_base.build_flags} + -Isrc/platform/apollo3 -g +build_src_filter = + ${arduino_base.build_src_filter} - - - - - - - - - - - - - - - +lib_deps = + ${env.lib_deps} +lib_ignore = + mathertel/OneButton@^2.0.3 diff --git a/src/platform/apollo3/architecture.h b/src/platform/apollo3/architecture.h new file mode 100644 index 000000000..a80dd24d4 --- /dev/null +++ b/src/platform/apollo3/architecture.h @@ -0,0 +1,15 @@ +#pragma once + +#define ARCH_APOLLO3 + +// +// defaults for ARCH_APOLLO3 architecture +// + +// +// set HW_VENDOR +// + +#ifndef HW_VENDOR +#define HW_VENDOR HardwareModel_PRIVATE_HW +#endif diff --git a/src/platform/apollo3/main-apollo3.cpp b/src/platform/apollo3/main-apollo3.cpp new file mode 100644 index 000000000..31534768d --- /dev/null +++ b/src/platform/apollo3/main-apollo3.cpp @@ -0,0 +1,24 @@ +#include "RTC.h" +#include "configuration.h" + +void setBluetoothEnable(bool on) {} + +void playStartMelody() {} + +void updateBatteryLevel(uint8_t level) {} + +void getMacAddr(uint8_t *dmac) +{ + for (int i = 0; i < 6; i++) + dmac[i] = i; +} + +void cpuDeepSleep(uint64_t msecToWake) {} + +/* pacify libc_nano */ +extern "C" { +int _gettimeofday(struct timeval *tv, void *tzvp) +{ + return -1; +} +} From 681377cc97396002ef0989c3d5a95b1ea7d695a8 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 28 Mar 2023 07:48:32 -0500 Subject: [PATCH 12/12] Moar --- arch/apollo3/apollo3.ini | 4 +- boards/wiscore_rak11720.json | 45 ++++++++ variants/rak11720/pins_arduino.h | 7 ++ variants/rak11720/platformio.ini | 5 + variants/rak11720/variant.h | 190 +++++++++++++++++++++++++++++++ 5 files changed, 249 insertions(+), 2 deletions(-) create mode 100644 boards/wiscore_rak11720.json create mode 100644 variants/rak11720/pins_arduino.h create mode 100644 variants/rak11720/platformio.ini create mode 100644 variants/rak11720/variant.h diff --git a/arch/apollo3/apollo3.ini b/arch/apollo3/apollo3.ini index b9bb36b50..2842e33b0 100644 --- a/arch/apollo3/apollo3.ini +++ b/arch/apollo3/apollo3.ini @@ -1,6 +1,6 @@ [apollo3_base] -platform_packages = platform_packages=framework-arduinoapollo3@https://github.com/sparkfun/Arduino_Apollo3#v2.2.0 -board = RAK11722 +platform = apollo3blue +platform_packages=framework-arduinoapollo3@https://github.com/sparkfun/Arduino_Apollo3#v2.2.0 framework = arduino build_type = debug build_flags = diff --git a/boards/wiscore_rak11720.json b/boards/wiscore_rak11720.json new file mode 100644 index 000000000..74c39f45f --- /dev/null +++ b/boards/wiscore_rak11720.json @@ -0,0 +1,45 @@ +{ + "build": { + "cpu": "cortex-m4", + "f_cpu": "48000000L", + "mcu": "AMA3B1KK", + "part": "apollo3", + "fabi": "hard", + "specs": "nosys.specs", + "framework": { + "arduino": { + "v1": { + "variant": "artemis", + "extra_flags": "-DSFE_ARTEMIS" + }, + "v2": { + "variant": "WisCore_RAK11720_Board", + "extra_flags": "-DARDUINO_RAK_11720_MODULE" + } + }, + "ambiqsdk-sfe": { + "variant": ["boards_sfe", "artemis_module"], + "extra_flags": "", + "variant_lib_src_filter": "" + } + } + }, + "debug": { + "jlink_device": "AMA3B1KK-KBR", + "svd_path": "apollo3.svd", + "swo_freq": 12000000, + "init": { + "break": "tbreak setup" + } + }, + "frameworks": ["arduino", "ambiqsdk-sfe"], + "name": "WisCore RAK11720 Board", + "upload": { + "maximum_ram_size": 393216, + "maximum_size": 983040, + "protocol": "svl", + "protocols": ["svl", "asb", "jlink"] + }, + "url": "https://www.rakwireless.com", + "vendor": "RAKwireless" +} diff --git a/variants/rak11720/pins_arduino.h b/variants/rak11720/pins_arduino.h new file mode 100644 index 000000000..7dbd253c0 --- /dev/null +++ b/variants/rak11720/pins_arduino.h @@ -0,0 +1,7 @@ +#ifndef _PINS_ARDUINO_H_ +#define _PINS_ARDUINO_H_ + +// API Competibility +#include "variant.h" + +#endif /*_PINS_ARDUINO_H_*/ diff --git a/variants/rak11720/platformio.ini b/variants/rak11720/platformio.ini new file mode 100644 index 000000000..311461133 --- /dev/null +++ b/variants/rak11720/platformio.ini @@ -0,0 +1,5 @@ +[env:rak11720] +extends = apollo3_base +board = wiscore_rak11720 +board_level = extra +build_flags = ${apollo3_base.build_flags} -Ivariants/rak11720 diff --git a/variants/rak11720/variant.h b/variants/rak11720/variant.h new file mode 100644 index 000000000..1fb30627d --- /dev/null +++ b/variants/rak11720/variant.h @@ -0,0 +1,190 @@ +#ifndef _VARIANT_RAK11720_ +#define _VARIANT_RAK11720_ + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +// TODO + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ +#include + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +extern const uint32_t g_ADigitalPinMap[]; +#define pgm_read_byte(addr) (*(const unsigned char *)(addr)) + +#define portOutputRegister(port) (&AM_REGVAL(port + offsetof(GPIO_Type, WTA))) +#define portInputRegister(port) ((volatile uint32_t *)&AM_REGVAL(port + offsetof(GPIO_Type, RDA))) +#define portModeRegister(port) () +#define digitalPinHasPWM(P) (g_ADigitalPinMap[P] > 1) // FIXME +#define digitalPinToBitMask(P) ((uint32_t)0x1 << (P % 32)) +#define digitalPinToPinName(P) g_ADigitalPinMap[P] + +#define digitalPinToPort(P) (GPIO_BASE + ((P & 0x20) >> 3)) + +// Interrupts +#define digitalPinToInterrupt(P) (P) // FIXME + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +#define PINS_COUNT (50u) +#define NUM_DIGITAL_PINS (0u) +#define NUM_ANALOG_INPUTS (0u) +#define NUM_ANALOG_OUTPUTS (0u) + +#define P44 44 // LED1 +#define P45 45 // LED2 + +#define P39 39 // UART0_TX +#define P40 40 // UART0_RX +#define P42 42 // UART1_TX +#define P43 43 // UART1_RX + +#define P25 25 // I2C2_SDA +#define P27 27 // I2C2_SCL + +#define P1 1 // SPI0_NSS +#define P5 5 // SPI0_SCK +#define P6 6 // SPI0_MISO +#define P7 7 // SPI0_MOSI + +#define P20 20 // SWDIO +#define P21 21 // SWCLK +#define P41 41 // BOOT0 - SWO + +// GP4 - GP36 - GP37 - GP38 - GP44(LED1) -GP45(LED2) +// ADC9(12), ADC8(13), ADC3(31), ADC4(32), ADC5(33) +#define P38 38 // IO1 +#define P4 4 // IO2 +#define P37 37 // IO3 +#define P31 31 // IO4 - ADC3(31) +#define P12 12 // IO5 - ADC9(12) +#define P36 36 // IO6 +#define P32 32 // IO7 - ADC4(32) + +#define P13 13 // AN0 - ADC8(13) +#define P33 33 // AN1 - ADC5(33) + +#define P18 18 // ANT_SW(LORA internal) +#define P17 17 // NRESET(LORA internal) +#define P16 16 // BUSY(LORA internal) +#define P15 15 // DIO1(LORA internal) +#define P14 14 // DIO2(LORA internal) +#define P11 11 // SPI_NSS(LORA internal) +#define P8 8 // SPI_CLK(LORA internal) +#define P10 10 // SPI_MOSI(LORA internal) +#define P9 9 // SPI_MISO(LORA internal) + +/* + * WisBlock Base GPIO definitions + */ + +#define WB_IO1 P38 // SLOT_A SLOT_B +#define WB_IO2 P4 // SLOT_A SLOT_B +#define WB_IO3 P37 // SLOT_C +#define WB_IO4 P31 // SLOT_C +#define WB_IO5 P12 // SLOT_D +#define WB_IO6 P36 // SLOT_D +#define WB_IO7 P32 +#define WB_SW1 0xFF // IO_SLOT +#define WB_A0 P13 // IO_SLOT +#define WB_A1 P33 // IO_SLOT +#define WB_I2C1_SDA P25 // SENSOR_SLOT IO_SLOT +#define WB_I2C1_SCL P27 // SENSOR_SLOT IO_SLOT +#define WB_I2C2_SDA 0xFF // IO_SLOT +#define WB_I2C2_SCL 0xFF // IO_SLOT +#define WB_SPI_CS P1 // IO_SLOT +#define WB_SPI_CLK P5 // IO_SLOT +#define WB_SPI_MISO P6 // IO_SLOT +#define WB_SPI_MOSI P7 // IO_SLOT +#define WB_RXD0 P40 // IO_SLOT +#define WB_TXD0 P39 // IO_SLOT +#define WB_RXD1 P43 // SLOT_A IO_SLOT +#define WB_TXD1 P42 // SLOT_A IO_SLOT +#define WB_LED1 P44 // IO_SLOT +#define WB_LED2 P45 // IO_SLOT + +// LEDs +#define PIN_LED1 WB_LED1 // PA0 +#define PIN_LED2 WB_LED2 // PA1 + +#define LED_BUILTIN PIN_LED1 +#define LED_CONN PIN_LED2 + +#define LED_GREEN PIN_LED1 +#define LED_BLUE PIN_LED2 + +#define LED_STATE_ON 1 // State when LED is litted + +/* + * Analog pins + */ +#define PIN_A0 P13 +#define PIN_A1 P33 + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; + +#define PIN_A3 P5 // channel1 +#define PIN_A4 P31 // channel2 +#define PIN_A5 P32 // channel4 +#define PIN_A6 P36 +#define PIN_A7 P7 // channel6 + +static const uint8_t A3 = PIN_A3; +static const uint8_t A4 = PIN_A4; +static const uint8_t A5 = PIN_A5; +static const uint8_t A6 = PIN_A6; +static const uint8_t A7 = PIN_A7; + +#define ADC_RESOLUTION 14 +// Other pins +#define PIN_AREF (0) + +static const uint8_t AREF = PIN_AREF; + +/* + * Serial interfaces + */ +#define PIN_SERIAL0_RX WB_RXD0 // PB7 +#define PIN_SERIAL0_TX WB_TXD0 // PB6 + +#define PIN_SERIAL1_RX WB_RXD1 // PA3 +#define PIN_SERIAL1_TX WB_TXD1 // PA2 + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 1 + +#define PIN_SPI_CS WB_SPI_CS +#define PIN_SPI_MISO WB_SPI_MISO +#define PIN_SPI_MOSI WB_SPI_MOSI +#define PIN_SPI_SCK WB_SPI_CLK + +static const uint8_t SS = PIN_SPI_CS; +static const uint8_t MOSI = PIN_SPI_MOSI; +static const uint8_t MISO = PIN_SPI_MISO; +static const uint8_t SCK = PIN_SPI_SCK; + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA WB_I2C1_SDA +#define PIN_WIRE_SCL WB_I2C1_SCL + +#ifdef __cplusplus +} +#endif + +#endif /* _VARIANT_RAK11720_ */ \ No newline at end of file