diff --git a/README.md b/README.md index 011a8b24..8e01ed99 100644 --- a/README.md +++ b/README.md @@ -168,7 +168,7 @@ Hard resetting via RTS pin... # Meshtastic Android app -The companion (optional) Meshtastic Android app is [here](https://github.com/meshtastic/Meshtastic-Android). You can also download it on Google Play. +The companion (optional) Meshtastic Android app is [here](https://play.google.com/store/apps/details?id=com.geeksville.mesh&referrer=utm_source%3Dgithub-dev-readme). You can also download it on Google Play. # Python API diff --git a/bin/dump-ram-users.sh b/bin/dump-ram-users.sh new file mode 100755 index 00000000..f0438834 --- /dev/null +++ b/bin/dump-ram-users.sh @@ -0,0 +1,3 @@ +arm-none-eabi-readelf -s -e .pio/build/nrf52dk/firmware.elf | head -80 + +nm -CSr --size-sort .pio/build/nrf52dk/firmware.elf | grep '^200' diff --git a/docs/README.md b/docs/README.md index 48e8d998..bd5c2d2c 100644 --- a/docs/README.md +++ b/docs/README.md @@ -28,7 +28,7 @@ Not all of these features are fully implemented yet - see **important** disclaim - Shows direction and distance to all members of your channel - Directed or broadcast text messages for channel members - Open and extensible codebase supporting multiple hardware vendors - no lock in to one vendor -- Communication API for bluetooth devices (such as our Android app) to use the mesh. An iOS application is in the works. And [Meshtastic-python](https://pypi.org/project/meshtastic/) provides access from desktop computers. +- Communication API for bluetooth devices (such as our Android app) to use the mesh. An iOS application is in the works. And [Meshtastic-python](https://pypi.org/project/meshtastic/) provides access from desktop computers. - Very easy sharing of private secured channels. Just share a special link or QR code with friends and they can join your encrypted mesh This project is currently in beta testing but it is fairly stable and feature complete - if you have questions please [join our discussion forum](https://meshtastic.discourse.group/). @@ -51,7 +51,7 @@ Note: Updates are happening almost daily, only major updates are listed below. F Our Android application is available here: -[![Download at https://play.google.com/store/apps/details?id=com.geeksville.mesh](https://play.google.com/intl/en_us/badges/static/images/badges/en_badge_web_generic.png)](https://play.google.com/store/apps/details?id=com.geeksville.mesh&referrer=utm_source%3Dhomepage%26anid%3Dadmob) +[![Download at https://play.google.com/store/apps/details?id=com.geeksville.mesh](https://play.google.com/intl/en_us/badges/static/images/badges/en_badge_web_generic.png)](https://play.google.com/store/apps/details?id=com.geeksville.mesh&referrer=utm_source%3Dgithub-homepage) The link above will return older more stable releases. We would prefer if you join our alpha-test group, because the application is rapidly improving. Three steps to opt-in to the alpha- test: diff --git a/docs/software/TODO.md b/docs/software/TODO.md index e01d525b..a47d73e6 100644 --- a/docs/software/TODO.md +++ b/docs/software/TODO.md @@ -1,19 +1,22 @@ # High priority -- why is the net so chatty now? -- modem sleep should work if we lower serial rate to 115kb? -- device wakes, turns BLE on and phone doesn't notice (while phone was sitting in auto-connect) -- E22 bringup +- nrf52 free memory https://learn.adafruit.com/bluefruit-nrf52-feather-learning-guide/hathach-memory-map - encryption review findings writeup +- NRF52 BLE +- cubecell +- DSR - turn on modem-sleep mode - https://github.com/espressif/arduino-esp32/issues/1142#issuecomment-512428852 -last EDF release in arduino is: https://github.com/espressif/arduino-esp32/commit/1977370e6fc069e93ffd8818798fbfda27ae7d99 -IDF release/v3.3 46b12a560 -IDF release/v3.3 367c3c09c -https://docs.espressif.com/projects/esp-idf/en/release-v3.3/get-started/linux-setup.html -kevinh@kevin-server:~/development/meshtastic/esp32-arduino-lib-builder$ python /home/kevinh/development/meshtastic/esp32-arduino-lib-builder/esp-idf/components/esptool_py/esptool/esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dout --flash_freq 40m --flash_size detect 0x1000 /home/kevinh/development/meshtastic/esp32-arduino-lib-builder/build/bootloader/bootloader.bin -cp -a out/tools/sdk/* components/arduino/tools/sdk -cp -ar components/arduino/* ~/.platformio/packages/framework-arduinoespressif32@src-fba9d33740f719f712e9f8b07da6ea13/ + +``` + last EDF release in arduino is: https://github.com/espressif/arduino-esp32/commit/1977370e6fc069e93ffd8818798fbfda27ae7d99 + IDF release/v3.3 46b12a560 + IDF release/v3.3 367c3c09c + https://docs.espressif.com/projects/esp-idf/en/release-v3.3/get-started/linux-setup.html + kevinh@kevin-server:~/development/meshtastic/esp32-arduino-lib-builder\$ python /home/kevinh/development/meshtastic/esp32-arduino-lib-builder/esp-idf/components/esptool*py/esptool/esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dout --flash_freq 40m --flash_size detect 0x1000 /home/kevinh/development/meshtastic/esp32-arduino-lib-builder/build/bootloader/bootloader.bin + cp -a out/tools/sdk/* components/arduino/tools/sdk + cp -ar components/arduino/ ~/.platformio/packages/framework-arduinoespressif32@src-fba9d33740f719f712e9f8b07da6ea13/ +``` # Medium priority @@ -40,6 +43,7 @@ During the beta timeframe the following improvements 'would be nice' Items after the first final candidate release. +- dynamic frequency scaling could save a lot of power on ESP32, but it seems to corrupt uart (even with ref_tick set correctly) - Change back to using a fixed sized MemoryPool rather than MemoryDynamic (see bug #149) - scan to find channels with low background noise? (Use CAD mode of the RF95 to automatically find low noise channels) - If the phone doesn't read fromradio mailbox within X seconds, assume the phone is gone and we can stop queing location msgs diff --git a/docs/software/nrf52-TODO.md b/docs/software/nrf52-TODO.md index 55b781d2..d6d91868 100644 --- a/docs/software/nrf52-TODO.md +++ b/docs/software/nrf52-TODO.md @@ -2,11 +2,24 @@ ## Misc work items +RAM investigation. +nRF52832-QFAA 64KB ram, 512KB flash vs +nrf52832-QFAB 32KB ram, 512kb flash +nrf52840 256KB RAM, 1MB flash + +platform.json + + "framework-arduinoadafruitnrf52": { + "type": "framework", + "optional": true, + "version": "https://github.com/meshtastic/Adafruit_nRF52_Arduino.git" + }, + ## Initial work items Minimum items needed to make sure hardware is good. -- set power UICR per https://devzone.nordicsemi.com/f/nordic-q-a/28562/nrf52840-regulator-configuration +- DONE set power UICR per https://devzone.nordicsemi.com/f/nordic-q-a/28562/nrf52840-regulator-configuration - switch charge controller into / out of performance mode (see 8.3.1 in datasheet) - write UC1701 wrapper - Test hardfault handler for null ptrs (if one isn't already installed) diff --git a/docs/software/ramusage-nrf52.txt b/docs/software/ramusage-nrf52.txt new file mode 100644 index 00000000..7258539f --- /dev/null +++ b/docs/software/ramusage-nrf52.txt @@ -0,0 +1,190 @@ +23K + messages ++ heap of 30ish packets, 300ish bytes per packet: 8KB ++ 14KB soft device RAM + +therefore: +a) we should store all ToPhone message queued messages compressed as protobufs (since they will become that anyways) +b) shrink packet pool size because none of that storage will be used for ToPhone packets +c) don't allocate any storage in RAM for the tophone messages we save inside device state, instead just use nanopb callbacks to save/load those +d) a smarter MeshPacket in memory representation would save about 4KB of RAM? + +2000790c 00003558 B devicestate // 16KB +2000b53c 00001000 b _cache_buffer // 4KB flash filesystem support +20003b1c 000006b0 B console +2000d5f4 00000400 b vApplicationGetTimerTaskMemory::uxTimerTaskStack +2000da04 00000400 b _acUpBuffer +2000c558 0000036c B Bluefruit +2000c8d8 00000358 b _cdcd_itf +2000e54c 00000258 B _midid_itf +2000d0dc 00000200 b ucStaticTimerQueueStorage.9390 +2000e044 00000200 b _mscd_buf +2000e284 000001cc b _vendord_itf +2000d410 00000190 b vApplicationGetIdleTaskMemory::uxIdleTaskStack +2000374c 0000016c D __global_locale +2000de48 0000012c B USBDevice +2000afa4 00000100 b Router::send(_MeshPacket*)::bytes +2000aea4 00000100 b Router::perhapsDecode(_MeshPacket*)::bytes +200039b0 000000f4 B powerFSM +20004258 000000f0 B screen +2000cd7c 000000c4 b _dcd +2000cc68 000000c0 b _usbd_qdef_buf +2000b3c4 000000bc B Wire +2000cef4 000000a8 B Serial2 +2000ce4c 000000a8 B Serial1 +2000e498 000000a8 B _SEGGER_RTT +2000b498 000000a4 B InternalFS +2000dfb8 0000008c b _hidd_itf +2000b260 00000088 b meshtastic::normalFrames +2000cfdc 00000064 b pxReadyTasksLists +2000b340 00000060 b meshtastic::drawTextMessageFrame(OLEDDisplay*, OLEDDisplayUiState*, short, short)::tempBuf +200036ec 00000060 d impure_data +2000b104 00000060 B bledfu +2000b0a4 00000060 B blebas +20003684 00000058 D _usbd_qdef +200038c0 00000058 d tzinfo +2000d5a0 00000054 b vApplicationGetTimerTaskMemory::xTimerTaskTCB +2000d3bc 00000054 b vApplicationGetIdleTaskMemory::xIdleTaskTCB +2000d308 00000050 b xStaticTimerQueue.9389 +2000b1f4 00000050 B hrmc +2000b1a4 00000050 B bslc +20004360 0000004c B service +2000d374 00000048 b m_cb +2000df74 00000042 b _desc_str +2000cd3c 00000040 b _usbd_ctrl_buf +20004214 00000040 B realRouter +2000e244 00000040 b _mscd_itf +2000b164 00000040 B bledis +20003634 00000038 d _InternalFSConfig +2000cc30 00000031 b _usbd_dev +2000398c 00000020 B periodicScheduler +2000cfa4 00000020 b callbacksInt +2000de10 0000001f b fw_str.13525 +20003974 00000018 b object.9934 +2000ae68 00000018 B nodeDB +2000366c 00000018 d _cache +2000b314 00000014 b meshtastic::drawNodeInfo(OLEDDisplay*, OLEDDisplayUiState*, short, short)::signalStr +2000b300 00000014 b meshtastic::drawNodeInfo(OLEDDisplay*, OLEDDisplayUiState*, short, short)::lastStr +2000b2ec 00000014 b meshtastic::drawNodeInfo(OLEDDisplay*, OLEDDisplayUiState*, short, short)::distStr +200041e0 00000014 b getDeviceName()::name +2000d0b8 00000014 b xTasksWaitingTermination +2000d0a4 00000014 b xSuspendedTaskList +2000d08c 00000014 b xPendingReadyList +2000d06c 00000014 b xDelayedTaskList2 +2000d058 00000014 b xDelayedTaskList1 +2000d2f0 00000014 b xActiveTimerList2 +2000d2dc 00000014 b xActiveTimerList1 +2000b480 00000014 B SPI +2000c8c4 00000014 B Serial +2000cd28 00000014 b _ctrl_xfer +2000de30 00000011 b serial_str.13534 +2000c544 00000010 b BLEAdvertising::_start(unsigned short, unsigned short)::gap_adv +20003614 00000010 d meshtastic::btPIN +2000434c 00000010 b sendOwnerPeriod +2000ae8c 00000010 b staticPool +2000e484 00000010 B xQueueRegistry +20003b04 00000010 B stateSERIAL +20003af4 00000010 B stateSDS +20003ae4 00000010 B stateON +20003ad4 00000010 B stateNB +20003ac4 00000010 B stateLS +20003ab4 00000010 B stateDARK +20003aa4 00000010 B stateBOOT +200041f8 00000010 B ledPeriodic +2000b244 00000010 B hrms +2000d9f4 00000010 b _acDownBuffer +2000b3b8 0000000c B preflightSleep +20004208 0000000c B powerStatus +2000e540 0000000c B nrf_nvic_state +2000b3ac 0000000c B notifySleep +2000b3a0 0000000c B notifyDeepSleep +2000e463 0000000b b __tzname_std +2000e458 0000000b b __tzname_dst +2000b338 00000008 b meshtastic::estimatedHeading(double, double)::oldLon +2000b330 00000008 b meshtastic::estimatedHeading(double, double)::oldLat +200041d0 00000008 b zeroOffsetSecs +2000ae80 00000008 b spiSettings +200038b8 00000008 D _tzname +20003b14 00000008 B noopPrint +2000cfc4 00000008 b channelMap +2000cf9c 00000008 b callbackDeferred +200043ac 00000006 b ourMacAddr +2000435c 00000004 b MeshService::onGPSChanged(void*)::lastGpsSend +2000b32c 00000004 b meshtastic::estimatedHeading(double, double)::b +2000b328 00000004 b meshtastic::drawNodeInfo(OLEDDisplay*, OLEDDisplayUiState*, short, short)::simRadian +2000362c 00000004 d meshtastic::Screen::setup()::bootFrames +20003628 00000004 d meshtastic::Screen::handleStartBluetoothPinScreen(unsigned long)::btFrames +200039ac 00000004 b onEnter()::lastPingMs +2000ae9c 00000004 b generatePacketId()::i +2000ae88 00000004 B RadioLibInterface::instance +2000b2e8 00000004 b meshtastic::nodeIndex +20003610 00000004 d meshtastic::targetFramerate +2000c554 00000004 B BLEService::lastService +200041cc 00000004 b timeStartMsec +200036dc 00000004 d sbrk_heap_top +2000d364 00000004 b _loopHandle +2000c540 00000004 b guard variable for BLEAdvertising::_start(unsigned short, unsigned short)::gap_adv +2000d0d0 00000004 b xYieldPending +2000d35c 00000004 b xTimerTaskHandle +2000d358 00000004 b xTimerQueue +2000d0cc 00000004 b xTickCount +2000d0a0 00000004 b xSchedulerRunning +2000d088 00000004 b xNumOfOverflows +2000d084 00000004 b xNextTaskUnblockTime +2000d304 00000004 b xLastTime.9343 +2000d080 00000004 b xIdleTaskHandle +2000d054 00000004 b uxTopReadyPriority +2000d050 00000004 b uxTaskNumber +2000d04c 00000004 b uxSchedulerSuspended +2000d048 00000004 b uxPendedTicks +2000d044 00000004 b uxDeletedTasksWaitingCleanUp +2000d040 00000004 b uxCurrentNumberOfTasks +2000d360 00000004 b uxCriticalNesting +2000cc64 00000004 b _usbd_q +2000e478 00000004 B _timezone +200036e0 00000004 D SystemCoreClock +2000c53c 00000004 b _sem +2000d0d8 00000004 b pxOverflowTimerList +2000cfd8 00000004 b pxOverflowDelayedTaskList +2000cfd4 00000004 b pxDelayedTaskList +2000d0d4 00000004 b pxCurrentTimerList +2000cfd0 00000004 B pxCurrentTCB +2000e470 00000004 b prev_tzenv +2000360c 00000004 D preftmp +20003608 00000004 D preffile +2000b25c 00000004 B nrf52Bluetooth +2000d370 00000004 b m_usbevt_handler +2000d36c 00000004 b m_sleepevt_handler +2000d368 00000004 b m_pofwarn_handler +2000e454 00000004 B __malloc_sbrk_start +2000e450 00000004 B __malloc_free_list +2000e480 00000004 B MAIN_MonCnt +2000e47c 00000004 b initial_env +200036e8 00000004 D _impure_ptr +200041d8 00000004 B gps +2000e7a4 00000004 B errno +20003918 00000004 D environ +2000cfcc 00000004 b enabled +2000ae64 00000004 B displayedNodeNum +2000e474 00000004 B _daylight +2000b254 00000004 B crypto +2000ce44 00000004 B count_duration +2000de0c 00000004 b _cb_task +2000de08 00000004 b _cb_queue +2000de04 00000004 b _cb_qdepth +2000de44 00000004 B bootloaderVersion +200041f5 00000001 b ledBlinker()::ledOn +20003604 00000001 d loop::showingBootScreen +200041f4 00000001 b loop::wasPressed +2000b494 00000001 b DefaultFontTableLookup(unsigned char)::LASTCHAR +2000aea0 00000001 b generatePacketId()::didInit +20003624 00000001 d meshtastic::prevFrame +2000b258 00000001 b bleOn +200041dc 00000001 B timeSetFromGPS +20004348 00000001 B ssd1306_found +2000ce49 00000001 B pin_sound +2000e494 00000001 B nrfx_power_irq_enabled +2000ce48 00000001 B no_stop +20003630 00000001 D neo6M +2000ce40 00000001 b _initialized +200036e4 00000001 D __fdlib_version +20003970 00000001 b completed.9929 diff --git a/linker/nrf52840_s140_sim832.ld b/linker/nrf52840_s140_sim832.ld new file mode 100644 index 00000000..27374668 --- /dev/null +++ b/linker/nrf52840_s140_sim832.ld @@ -0,0 +1,46 @@ +/* Linker script to configure memory regions. + +geeksville: modified this to simulate a nrf52832 but with a sd140 soft device. So I can +see how the memory footprint works on this lower end CPU. Note: to work with sd140 in my bootloader +I need to start ram at 0x6000 (instead of the correct 0x3600 for sd132) - so I have less +RAM available than on a real 832. +*/ + +SEARCH_DIR(.) +GROUP(-lgcc -lc -lnosys) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0x6D000 - 0x26000 + /* FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0xED000 - 0x26000 */ + + /* SRAM required by S132 depend on + * - Attribute Table Size + * - Vendor UUID count + * - Max ATT MTU + * - Concurrent connection peripheral + central + secure links + * - Event Len, HVN queue, Write CMD queue + */ + /* RAM (rwx) : ORIGIN = 0x20003600, LENGTH = 0x20010000 - 0x20003600 */ + RAM (rwx) : ORIGIN = 0x20006000, LENGTH = 0x20010000 - 0x20006000 +} + +SECTIONS +{ + . = ALIGN(4); + .svc_data : + { + PROVIDE(__start_svc_data = .); + KEEP(*(.svc_data)) + PROVIDE(__stop_svc_data = .); + } > RAM + + .fs_data : + { + PROVIDE(__start_fs_data = .); + KEEP(*(.fs_data)) + PROVIDE(__stop_fs_data = .); + } > RAM +} INSERT AFTER .data; + +INCLUDE "nrf52_common.ld" diff --git a/platformio.ini b/platformio.ini index 643f9fd6..c235f94c 100644 --- a/platformio.ini +++ b/platformio.ini @@ -143,7 +143,7 @@ debug_tool = jlink build_type = debug ; I'm debugging with ICE a lot now ; note: liboberon provides the AES256 implementation for NRF52 (though not using the hardware acceleration of the NRF52840 - FIXME) build_flags = - ${env.build_flags} -Wno-unused-variable -Isrc/nrf52 -Isdk-nrfxlib/crypto/nrf_oberon/include -Lsdk-nrfxlib/crypto/nrf_oberon/lib/cortex-m4/hard-float/ -lliboberon_3.0.3 + ${env.build_flags} -Wno-unused-variable -Isrc/nrf52 -Isdk-nrfxlib/crypto/nrf_oberon/include -Lsdk-nrfxlib/crypto/nrf_oberon/lib/cortex-m4/hard-float/ -lliboberon_3.0.3 ;-DCFG_DEBUG=3 src_filter = ${env.src_filter} - @@ -166,8 +166,9 @@ debug_init_break = [env:nrf52dk] extends = nrf52_base board = nrf52840_dk_modified -lib_deps = - UC1701 ; for temp testing + +# For experimenting with RAM sizes +# board_build.ldscript = linker/nrf52840_s140_sim832.ld ; The PPR board [env:ppr] @@ -176,7 +177,7 @@ board = ppr lib_deps = ${env.lib_deps} UC1701 - https://github.com/meshtastic/BQ25703A.git + diff --git a/proto b/proto index e7f181ef..72cbde93 160000 --- a/proto +++ b/proto @@ -1 +1 @@ -Subproject commit e7f181ef6fd4e38c40e0d0be552149f8bbe75a66 +Subproject commit 72cbde93ffbc2ee917f9d7328558475e02a91cba diff --git a/src/main.cpp b/src/main.cpp index ded027f5..e6820e84 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -152,7 +152,10 @@ void setup() #else Wire.begin(); #endif + // i2c still busted on new board +#ifndef ARDUINO_NRF52840_PPR scanI2Cdevice(); +#endif // Buttons & LED #ifdef BUTTON_PIN @@ -234,7 +237,7 @@ void setup() new SimRadio(); #endif - if (!rIf->init()) + if (!rIf || !rIf->init()) recordCriticalError(ErrNoRadio); else router.addInterface(rIf); diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 4e87ac77..2c2204c6 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -110,8 +110,10 @@ void NodeDB::resetRadioConfig() */ } -void NodeDB::init() +void NodeDB::installDefaultDeviceState() { + memset(&devicestate, 0, sizeof(devicestate)); + // init our devicestate with valid flags so protobuf writing/reading will work devicestate.has_my_node = true; devicestate.has_radio = true; @@ -119,7 +121,7 @@ void NodeDB::init() devicestate.radio.has_channel_settings = true; devicestate.radio.has_preferences = true; devicestate.node_db_count = 0; - devicestate.receive_queue_count = 0; + devicestate.receive_queue_count = 0; // Not yet implemented FIXME resetRadioConfig(); @@ -139,12 +141,17 @@ void NodeDB::init() pickNewNodeNum(); // Note: we will repick later, just in case the settings are corrupted, but we need a valid // owner.short_name now sprintf(owner.long_name, "Unknown %02x%02x", ourMacAddr[4], ourMacAddr[5]); - sprintf(owner.short_name, "?%02X", myNodeInfo.my_node_num & 0xff); + sprintf(owner.short_name, "?%02X", (unsigned)(myNodeInfo.my_node_num & 0xff)); +} + +void NodeDB::init() +{ + installDefaultDeviceState(); if (!FSBegin()) // FIXME - do this in main? { DEBUG_MSG("ERROR filesystem mount Failed\n"); - // FIXME - report failure to phone + assert(0); // FIXME - report failure to phone } // saveToDisk(); @@ -210,7 +217,7 @@ const char *preftmp = "/db.proto.tmp"; void NodeDB::loadFromDisk() { #ifdef FS - static DeviceState scratch; + // static DeviceState scratch; We no longer read into a tempbuf because this structure is 15KB of valuable RAM auto f = FS.open(preffile); if (f) { @@ -219,16 +226,17 @@ void NodeDB::loadFromDisk() // DEBUG_MSG("Preload channel name=%s\n", channelSettings.name); - memset(&scratch, 0, sizeof(scratch)); - if (!pb_decode(&stream, DeviceState_fields, &scratch)) { + memset(&devicestate, 0, sizeof(devicestate)); + if (!pb_decode(&stream, DeviceState_fields, &devicestate)) { DEBUG_MSG("Error: can't decode protobuf %s\n", PB_GET_ERROR(&stream)); + installDefaultDeviceState(); // Our in RAM copy might now be corrupt // FIXME - report failure to phone } else { - if (scratch.version < DEVICESTATE_MIN_VER) + if (devicestate.version < DEVICESTATE_MIN_VER) { DEBUG_MSG("Warn: devicestate is old, discarding\n"); - else { - DEBUG_MSG("Loaded saved preferences version %d\n", scratch.version); - devicestate = scratch; + installDefaultDeviceState(); + } else { + DEBUG_MSG("Loaded saved preferences version %d\n", devicestate.version); } // DEBUG_MSG("Postload channel name=%s\n", channelSettings.name); @@ -238,6 +246,7 @@ void NodeDB::loadFromDisk() } else { DEBUG_MSG("No saved preferences found\n"); } + #else DEBUG_MSG("ERROR: Filesystem not implemented\n"); #endif diff --git a/src/mesh/NodeDB.h b/src/mesh/NodeDB.h index 0171228a..611024e2 100644 --- a/src/mesh/NodeDB.h +++ b/src/mesh/NodeDB.h @@ -93,6 +93,9 @@ class NodeDB /// read our db from flash void loadFromDisk(); + + /// Reinit device state from scratch (not loading from disk) + void installDefaultDeviceState(); }; /** diff --git a/src/mesh/RadioLibInterface.cpp b/src/mesh/RadioLibInterface.cpp index 8fb1ce78..f0451079 100644 --- a/src/mesh/RadioLibInterface.cpp +++ b/src/mesh/RadioLibInterface.cpp @@ -304,6 +304,8 @@ void RadioLibInterface::startSend(MeshPacket *txp) printPacket("Starting low level send", txp); setStandby(); // Cancel any already in process receives + configHardwareForSend(); // must be after setStandby + size_t numbytes = beginSending(txp); int res = iface->startTransmit(radiobuf, numbytes); diff --git a/src/mesh/RadioLibInterface.h b/src/mesh/RadioLibInterface.h index 6619337b..706fcdf0 100644 --- a/src/mesh/RadioLibInterface.h +++ b/src/mesh/RadioLibInterface.h @@ -91,9 +91,6 @@ class RadioLibInterface : public RadioInterface, private PeriodicTask virtual void startReceive() = 0; private: - /** start an immediate transmit */ - void startSend(MeshPacket *txp); - /** if we have something waiting to send, start a short random timer so we can come check for collision before actually doing * the transmit * @@ -108,12 +105,20 @@ class RadioLibInterface : public RadioInterface, private PeriodicTask virtual void doTask(); + /** start an immediate transmit + * This method is virtual so subclasses can hook as needed, subclasses should not call directly + */ + virtual void startSend(MeshPacket *txp); + protected: /// Initialise the Driver transport hardware and software. /// Make sure the Driver is properly configured before calling init(). /// \return true if initialisation succeeded. virtual bool init(); - + + /** Do any hardware setup needed on entry into send configuration for the radio. Subclasses can customize */ + virtual void configHardwareForSend() {} + /** * Convert our modemConfig enum into wf, sf, etc... * diff --git a/src/mesh/SX1262Interface.cpp b/src/mesh/SX1262Interface.cpp index 69e7f8ee..e9ec8e7f 100644 --- a/src/mesh/SX1262Interface.cpp +++ b/src/mesh/SX1262Interface.cpp @@ -14,7 +14,19 @@ bool SX1262Interface::init() { RadioLibInterface::init(); - float tcxoVoltage = 0; // None - we use an XTAL +#ifdef SX1262_RXEN // set not rx or tx mode + pinMode(SX1262_RXEN, OUTPUT); +#endif +#ifdef SX1262_TXEN + pinMode(SX1262_TXEN, OUTPUT); +#endif + +#ifndef SX1262_E22 + float tcxoVoltage = 0; // None - we use an XTAL +#else + float tcxoVoltage = + 1.8; // E22 uses DIO3 to power tcxo per https://github.com/jgromes/RadioLib/issues/12#issuecomment-520695575 +#endif bool useRegulatorLDO = false; // Seems to depend on the connection to pin 9/DCC_SW - if an inductor DCDC? applyModemConfig(); @@ -23,6 +35,12 @@ bool SX1262Interface::init() int res = lora.begin(freq, bw, sf, cr, syncWord, power, currentLimit, preambleLength, tcxoVoltage, useRegulatorLDO); DEBUG_MSG("LORA init result %d\n", res); +#ifdef SX1262_TXEN + // lora.begin sets Dio2 as RF switch control, which is not true if we are manually controlling RX and TX + if (res == ERR_NONE) + res = lora.setDio2AsRfSwitch(false); +#endif + if (res == ERR_NONE) res = lora.setCRC(SX126X_LORA_CRC_ON); @@ -81,6 +99,13 @@ void SX1262Interface::setStandby() int err = lora.standby(); assert(err == ERR_NONE); +#ifdef SX1262_RXEN // we have RXEN/TXEN control - turn off RX and TX power + digitalWrite(SX1262_RXEN, LOW); +#endif +#ifdef SX1262_TXEN + digitalWrite(SX1262_TXEN, LOW); +#endif + isReceiving = false; // If we were receiving, not any more disableInterrupt(); completeSending(); // If we were sending, not anymore @@ -94,6 +119,18 @@ void SX1262Interface::addReceiveMetadata(MeshPacket *mp) mp->rx_snr = lora.getSNR(); } +/** start an immediate transmit + * We override to turn on transmitter power as needed. + */ +void SX1262Interface::configHardwareForSend() +{ +#ifdef SX1262_TXEN // we have RXEN/TXEN control - turn on TX power / off RX power + digitalWrite(SX1262_TXEN, HIGH); +#endif + + RadioLibInterface::configHardwareForSend(); +} + // For power draw measurements, helpful to force radio to stay sleeping // #define SLEEP_ONLY @@ -102,7 +139,13 @@ void SX1262Interface::startReceive() #ifdef SLEEP_ONLY sleep(); #else + setStandby(); + +#ifdef SX1262_RXEN // we have RXEN/TXEN control - turn on RX power / off TX power + digitalWrite(SX1262_RXEN, HIGH); +#endif + // int err = lora.startReceive(); int err = lora.startReceiveDutyCycleAuto(); // We use a 32 bit preamble so this should save some power by letting radio sit in // standby mostly. diff --git a/src/mesh/SX1262Interface.h b/src/mesh/SX1262Interface.h index 92b301bf..30167bc2 100644 --- a/src/mesh/SX1262Interface.h +++ b/src/mesh/SX1262Interface.h @@ -43,6 +43,12 @@ class SX1262Interface : public RadioLibInterface * Start waiting to receive a message */ virtual void startReceive(); + + /** + * We override to turn on transmitter power as needed. + */ + virtual void configHardwareForSend(); + /** * Add SNR data to received messages */ @@ -51,5 +57,4 @@ class SX1262Interface : public RadioLibInterface virtual void setStandby(); private: - }; \ No newline at end of file diff --git a/src/mesh/mesh-pb-constants.h b/src/mesh/mesh-pb-constants.h index baa9f5b5..789eb14a 100644 --- a/src/mesh/mesh-pb-constants.h +++ b/src/mesh/mesh-pb-constants.h @@ -8,7 +8,9 @@ #define member_size(type, member) sizeof(((type *)0)->member) /// max number of packets which can be waiting for delivery to android - note, this value comes from mesh.options protobuf -#define MAX_RX_TOPHONE (member_size(DeviceState, receive_queue) / member_size(DeviceState, receive_queue[0])) +// FIXME - max_count is actually 32 but we save/load this as one long string of preencoded MeshPacket bytes - not a big array in RAM +// #define MAX_RX_TOPHONE (member_size(DeviceState, receive_queue) / member_size(DeviceState, receive_queue[0])) +#define MAX_RX_TOPHONE 32 /// max number of nodes allowed in the mesh #define MAX_NUM_NODES (member_size(DeviceState, node_db) / member_size(DeviceState, node_db[0])) diff --git a/src/mesh/mesh.pb.c b/src/mesh/mesh.pb.c index 88db1a21..ddc720cf 100644 --- a/src/mesh/mesh.pb.c +++ b/src/mesh/mesh.pb.c @@ -39,7 +39,7 @@ PB_BIND(NodeInfo, NodeInfo, AUTO) PB_BIND(MyNodeInfo, MyNodeInfo, AUTO) -PB_BIND(DeviceState, DeviceState, 4) +PB_BIND(DeviceState, DeviceState, 2) PB_BIND(DebugString, DebugString, 2) diff --git a/src/mesh/mesh.pb.h b/src/mesh/mesh.pb.h index 8e4ba34b..2651d6cb 100644 --- a/src/mesh/mesh.pb.h +++ b/src/mesh/mesh.pb.h @@ -183,7 +183,7 @@ typedef struct _DeviceState { pb_size_t node_db_count; NodeInfo node_db[32]; pb_size_t receive_queue_count; - MeshPacket receive_queue[32]; + MeshPacket receive_queue[1]; bool has_rx_text_message; MeshPacket rx_text_message; uint32_t version; @@ -244,7 +244,7 @@ typedef struct _ToRadio { #define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}} #define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0, 0} #define MyNodeInfo_init_default {0, 0, 0, "", "", "", 0, 0, 0, 0, 0, 0, 0, 0} -#define DeviceState_init_default {false, RadioConfig_init_default, false, MyNodeInfo_init_default, false, User_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default}, false, MeshPacket_init_default, 0} +#define DeviceState_init_default {false, RadioConfig_init_default, false, MyNodeInfo_init_default, false, User_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default}, false, MeshPacket_init_default, 0} #define DebugString_init_default {""} #define FromRadio_init_default {0, 0, {MeshPacket_init_default}} #define ToRadio_init_default {0, {MeshPacket_init_default}} @@ -260,7 +260,7 @@ typedef struct _ToRadio { #define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}} #define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0, 0} #define MyNodeInfo_init_zero {0, 0, 0, "", "", "", 0, 0, 0, 0, 0, 0, 0, 0} -#define DeviceState_init_zero {false, RadioConfig_init_zero, false, MyNodeInfo_init_zero, false, User_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero}, false, MeshPacket_init_zero, 0} +#define DeviceState_init_zero {false, RadioConfig_init_zero, false, MyNodeInfo_init_zero, false, User_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero}, false, MeshPacket_init_zero, 0} #define DebugString_init_zero {""} #define FromRadio_init_zero {0, 0, {MeshPacket_init_zero}} #define ToRadio_init_zero {0, {MeshPacket_init_zero}} @@ -596,7 +596,7 @@ extern const pb_msgdesc_t ManufacturingData_msg; #define RadioConfig_UserPreferences_size 93 #define NodeInfo_size 132 #define MyNodeInfo_size 110 -#define DeviceState_size 15100 +#define DeviceState_size 5305 #define DebugString_size 258 #define FromRadio_size 322 #define ToRadio_size 316 diff --git a/src/nrf52/UC1701Spi.cpp b/src/nrf52/UC1701Spi.cpp index d653b645..dcb6435c 100644 --- a/src/nrf52/UC1701Spi.cpp +++ b/src/nrf52/UC1701Spi.cpp @@ -36,15 +36,18 @@ class UC1701Spi : public OLEDDisplay }; #include "variant.h" + +#ifdef ERC12864_CS #include static UC1701 lcd(PIN_SPI_SCK, PIN_SPI_MOSI, ERC12864_CS, ERC12864_CD); +void testLCD() +{ + // PCD8544-compatible displays may have a different resolution... + lcd.begin(); -void testLCD() { - // PCD8544-compatible displays may have a different resolution... - lcd.begin(); - - // Write a piece of text on the first line... - lcd.setCursor(0, 0); - lcd.print("Hello, World!"); -} \ No newline at end of file + // Write a piece of text on the first line... + lcd.setCursor(0, 0); + lcd.print("Hello, World!"); +} +#endif \ No newline at end of file diff --git a/src/nrf52/main-nrf52.cpp b/src/nrf52/main-nrf52.cpp index ce3fe7e3..93798462 100644 --- a/src/nrf52/main-nrf52.cpp +++ b/src/nrf52/main-nrf52.cpp @@ -59,12 +59,6 @@ void setBluetoothEnable(bool on) } } -#ifdef ARDUINO_NRF52840_PPR -#include "PmuBQ25703A.h" - -PmuBQ25703A pmu; -#endif - void nrf52Setup() { diff --git a/src/sleep.cpp b/src/sleep.cpp index 2dfee04f..2d3ad4d3 100644 --- a/src/sleep.cpp +++ b/src/sleep.cpp @@ -129,7 +129,7 @@ static void waitEnterSleep() if (millis() - now > 30 * 1000) { // If we wait too long just report an error and go to sleep recordCriticalError(ErrSleepEnterWait); - ESP.restart(); // FIXME - for now we just restart, need to fix bug #167 + assert(0); // FIXME - for now we just restart, need to fix bug #167 break; } } @@ -289,8 +289,6 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r return cause; } -#endif - // not legal on the stock android ESP build @@ -310,4 +308,4 @@ void enableModemSleep() config.light_sleep_enable = false; DEBUG_MSG("Sleep request result %x\n", esp_pm_configure(&config)); } - +#endif diff --git a/variants/ppr/variant.h b/variants/ppr/variant.h index 95b2803b..bbdda306 100644 --- a/variants/ppr/variant.h +++ b/variants/ppr/variant.h @@ -137,6 +137,7 @@ static const uint8_t SCK = PIN_SPI_SCK; // #define SX1262_ANT_SW (32 + 10) #define SX1262_RXEN (22) #define SX1262_TXEN (24) +#define SX1262_E22 // Indicates this SX1262 is inside of an ebyte E22 module and special config should be done for that // ERC12864-10 LCD #define ERC12864_CS (32 + 4)