firmware/src/mesh/RadioLibInterface.cpp

485 lines
17 KiB
C++
Raw Normal View History

#include "RadioLibInterface.h"
2020-04-30 19:37:58 +00:00
#include "MeshTypes.h"
#include "NodeDB.h"
Add PowerMon support (#4155) * Turn off vscode cmake prompt - we don't use cmake on meshtastic * Add rak4631_dap variant for debugging with NanoDAP debug probe device. * The rak device can also run freertos (which is underneath nrf52 arduino) * Add semihosting support for nrf52840 devices Initial platformio.ini file only supports rak4630 Default to non TCP for the semihosting log output for now... Fixes https://github.com/meshtastic/firmware/issues/4135 * powermon WIP (for https://github.com/meshtastic/firmware/issues/4136 ) * oops - mean't to mark the _dbg variant as an 'extra' board. * powermon wip * Make serial port on wio-sdk-wm1110 board work By disabling the (inaccessible) adafruit USB * Instrument (radiolib only for now) lora for powermon per https://github.com/meshtastic/firmware/issues/4136 * powermon gps support https://github.com/meshtastic/firmware/issues/4136 * Add CPU deep and light sleep powermon states https://github.com/meshtastic/firmware/issues/4136 * Change the board/swversion bootstring so it is a new "structured" log msg. * powermon wip * add example script for getting esp S3 debugging working Not yet used but I didn't want these nasty tricks to get lost yet. * Add PowerMon reporting for screen and bluetooth pwr. * make power.powermon_enables config setting work. * update to latest protobufs * fix bogus shellcheck warning * make powermon optional (but default enabled because tiny and no runtime impact) * tell vscode, if formatting, use whatever our trunk formatter wants without this flag if the user has set some other formatter (clang) in their user level settings, it will be looking in the wrong directory for the clang options (we want the options in .trunk/clang) Note: formatOnSave is true in master, which means a bunch of our older files are non compliant and if you edit them it will generate lots of formatting related diffs. I guess I'll start letting that happen with my future commits ;-). * add PowerStress module * nrf52 arduino is built upon freertos, so let platformio debug it * don't accidentally try to Segger ICE if we are using another ICE * clean up RedirectablePrint::log so it doesn't have three very different implementations inline. * remove NoopPrint - it is no longer needed * when talking to API clients via serial, don't turn off log msgs instead encapsuate them * fix the build - would loop forever if there were no files to send * don't use Segger code if not talking to a Segger debugger * when encapsulating logs, make sure the strings always has nul terminators * nrf52 soft device will watchdog if you use ICE while BT on... so have debugger disable bluetooth. * Important to not print debug messages while writing to the toPhone scratch buffer * don't include newlines if encapsulating log records as protobufs * update to latest protobufs (needed for powermon goo) * PowerStress WIP * fix linter warning
2024-07-03 23:02:20 +00:00
#include "PowerMon.h"
#include "SPILock.h"
#include "Throttle.h"
2022-04-10 05:42:43 +00:00
#include "configuration.h"
#include "error.h"
2023-01-21 12:01:19 +00:00
#include "main.h"
#include "mesh-pb-constants.h"
2020-04-30 19:37:58 +00:00
#include <pb_decode.h>
#include <pb_encode.h>
2023-05-08 11:18:28 +00:00
void LockingArduinoHal::spiBeginTransaction()
{
2022-06-13 14:10:16 +00:00
spiLock->lock();
2023-05-08 11:18:28 +00:00
ArduinoHal::spiBeginTransaction();
2022-06-13 14:10:16 +00:00
}
2023-05-08 11:18:28 +00:00
void LockingArduinoHal::spiEndTransaction()
2022-06-13 14:10:16 +00:00
{
spiLock->unlock();
2023-05-08 11:18:28 +00:00
ArduinoHal::spiEndTransaction();
}
#if ARCH_PORTDUINO
void LockingArduinoHal::spiTransfer(uint8_t *out, size_t len, uint8_t *in)
{
if (busy == RADIOLIB_NC) {
spi->transfer(out, in, len);
} else {
uint16_t offset = 0;
while (len) {
uint8_t block_size = (len < 20 ? len : 20);
spi->transfer((out != NULL ? out + offset : NULL), (in != NULL ? in + offset : NULL), block_size);
if (block_size == len)
return;
// ensure GPIO is low
uint32_t start = millis();
while (digitalRead(busy)) {
if (!Throttle::isWithinTimespanMs(start, 2000)) {
LOG_ERROR("GPIO mid-transfer timeout, is it connected?");
return;
}
}
offset += block_size;
len -= block_size;
}
}
}
#endif
2023-05-08 11:18:28 +00:00
RadioLibInterface::RadioLibInterface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst,
RADIOLIB_PIN_TYPE busy, PhysicalLayer *_iface)
: NotifiedWorkerThread("RadioIf"), module(hal, cs, irq, rst, busy), iface(_iface)
{
instance = this;
#if defined(ARCH_STM32WL) && defined(USE_SX1262)
module.setCb_digitalWrite(stm32wl_emulate_digitalWrite);
module.setCb_digitalRead(stm32wl_emulate_digitalRead);
#endif
}
#ifdef ARCH_ESP32
// ESP32 doesn't use that flag
#define YIELD_FROM_ISR(x) portYIELD_FROM_ISR()
#else
#define YIELD_FROM_ISR(x) portYIELD_FROM_ISR(x)
#endif
void INTERRUPT_ATTR RadioLibInterface::isrLevel0Common(PendingISR cause)
{
instance->disableInterrupt();
BaseType_t xHigherPriorityTaskWoken;
2020-10-10 01:57:57 +00:00
instance->notifyFromISR(&xHigherPriorityTaskWoken, cause, true);
/* Force a context switch if xHigherPriorityTaskWoken is now set to pdTRUE.
The macro used to do this is dependent on the port and may be called
portEND_SWITCHING_ISR. */
YIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
void INTERRUPT_ATTR RadioLibInterface::isrRxLevel0()
{
isrLevel0Common(ISR_RX);
}
void INTERRUPT_ATTR RadioLibInterface::isrTxLevel0()
{
isrLevel0Common(ISR_TX);
}
/** Our ISR code currently needs this to find our active instance
*/
RadioLibInterface *RadioLibInterface::instance;
/** Could we send right now (i.e. either not actively receiving or transmitting)? */
bool RadioLibInterface::canSendImmediately()
{
// We wait _if_ we are partially though receiving a packet (rather than just merely waiting for one).
// To do otherwise would be doubly bad because not only would we drop the packet that was on the way in,
// we almost certainly guarantee no one outside will like the packet we are sending.
bool busyTx = sendingPacket != NULL;
bool busyRx = isReceiving && isActivelyReceiving();
2020-05-03 02:51:25 +00:00
if (busyTx || busyRx) {
if (busyTx) {
LOG_WARN("Can not send yet, busyTx\n");
}
// If we've been trying to send the same packet more than one minute and we haven't gotten a
// TX IRQ from the radio, the radio is probably broken.
if (busyTx && !Throttle::isWithinTimespanMs(lastTxStart, 60000)) {
LOG_ERROR("Hardware Failure! busyTx for more than 60s\n");
RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_TRANSMIT_FAILED);
// reboot in 5 seconds when this condition occurs.
rebootAtMsec = lastTxStart + 65000;
}
if (busyRx) {
LOG_WARN("Can not send yet, busyRx\n");
}
2020-05-03 02:51:25 +00:00
return false;
} else
return true;
}
bool RadioLibInterface::receiveDetected(uint16_t irq, ulong syncWordHeaderValidFlag, ulong preambleDetectedFlag)
{
bool detected = (irq & (syncWordHeaderValidFlag | preambleDetectedFlag));
// Handle false detections
if (detected) {
if (!activeReceiveStart) {
activeReceiveStart = millis();
} else if (!Throttle::isWithinTimespanMs(activeReceiveStart, 2 * preambleTimeMsec) && !(irq & syncWordHeaderValidFlag)) {
// The HEADER_VALID flag should be set by now if it was really a packet, so ignore PREAMBLE_DETECTED flag
activeReceiveStart = 0;
LOG_DEBUG("Ignore false preamble detection.\n");
return false;
} else if (!Throttle::isWithinTimespanMs(activeReceiveStart, maxPacketTimeMsec)) {
// We should have gotten an RX_DONE IRQ by now if it was really a packet, so ignore HEADER_VALID flag
activeReceiveStart = 0;
LOG_DEBUG("Ignore false header detection.\n");
return false;
}
}
return detected;
}
/// Send a packet (possibly by enquing in a private fifo). This routine will
/// later free() the packet to pool. This routine is not allowed to stall because it is called from
/// bluetooth comms code. If the txmit queue is empty it might return an error
ErrorCode RadioLibInterface::send(meshtastic_MeshPacket *p)
{
2022-05-25 01:06:53 +00:00
2022-04-25 15:02:51 +00:00
#ifndef DISABLE_WELCOME_UNSET
2022-05-25 01:06:53 +00:00
if (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_UNSET) {
if (disabled || !config.lora.tx_enabled) {
2023-01-30 16:14:12 +00:00
LOG_WARN("send - !config.lora.tx_enabled\n");
packetPool.release(p);
return ERRNO_DISABLED;
2022-04-10 05:42:43 +00:00
}
2023-01-30 16:14:12 +00:00
} else {
LOG_WARN("send - lora tx disable because RegionCode_Unset\n");
packetPool.release(p);
return ERRNO_DISABLED;
}
2022-04-25 15:02:51 +00:00
#else
if (disabled || !config.lora.tx_enabled) {
LOG_WARN("send - !config.lora.tx_enabled\n");
2022-04-25 15:02:51 +00:00
packetPool.release(p);
return ERRNO_DISABLED;
}
#endif
2023-01-21 12:01:19 +00:00
// Sometimes when testing it is useful to be able to never turn on the xmitter
#ifndef LORA_DISABLE_SENDING
2023-01-21 12:01:19 +00:00
printPacket("enqueuing for send", p);
2023-01-21 12:01:19 +00:00
LOG_DEBUG("txGood=%d,rxGood=%d,rxBad=%d\n", txGood, rxGood, rxBad);
ErrorCode res = txQueue.enqueue(p) ? ERRNO_OK : ERRNO_UNKNOWN;
2023-01-21 12:01:19 +00:00
if (res != ERRNO_OK) { // we weren't able to queue it, so we must drop it to prevent leaks
packetPool.release(p);
return res;
}
2023-01-21 12:01:19 +00:00
// set (random) transmit delay to let others reconfigure their radio,
// to avoid collisions and implement timing-based flooding
// LOG_DEBUG("Set random delay before transmitting.\n");
setTransmitDelay();
2023-01-21 12:01:19 +00:00
return res;
#else
packetPool.release(p);
return ERRNO_DISABLED;
#endif
2023-01-21 12:01:19 +00:00
}
meshtastic_QueueStatus RadioLibInterface::getQueueStatus()
{
meshtastic_QueueStatus qs;
qs.res = qs.mesh_packet_id = 0;
qs.free = txQueue.getFree();
qs.maxlen = txQueue.getMaxLen();
return qs;
}
2023-01-21 12:01:19 +00:00
bool RadioLibInterface::canSleep()
{
bool res = txQueue.empty();
if (!res) { // only print debug messages if we are vetoing sleep
2023-01-21 12:01:19 +00:00
LOG_DEBUG("radio wait to sleep, txEmpty=%d\n", res);
}
2023-01-21 12:01:19 +00:00
return res;
}
2023-01-21 12:01:19 +00:00
/** Attempt to cancel a previously sent packet. Returns true if a packet was found we could cancel */
bool RadioLibInterface::cancelSending(NodeNum from, PacketId id)
{
auto p = txQueue.remove(from, id);
if (p)
packetPool.release(p); // free the packet we just removed
2023-01-21 12:01:19 +00:00
bool result = (p != NULL);
LOG_DEBUG("cancelSending id=0x%x, removed=%d\n", id, result);
return result;
}
2023-01-21 12:01:19 +00:00
/** radio helper thread callback.
We never immediately transmit after any operation (either Rx or Tx). Instead we should wait a random multiple of
'slotTimes' (see definition in RadioInterface.h) taken from a contention window (CW) to lower the chance of collision.
The CW size is determined by setTransmitDelay() and depends either on the current channel utilization or SNR in case
of a flooding message. After this, we perform channel activity detection (CAD) and reset the transmit delay if it is
currently active.
*/
void RadioLibInterface::onNotify(uint32_t notification)
{
switch (notification) {
case ISR_TX:
handleTransmitInterrupt();
startReceive();
// LOG_DEBUG("tx complete - starting timer\n");
startTransmitTimer();
break;
case ISR_RX:
handleReceiveInterrupt();
startReceive();
// LOG_DEBUG("rx complete - starting timer\n");
startTransmitTimer();
break;
case TRANSMIT_DELAY_COMPLETED:
// LOG_DEBUG("delay done\n");
// If we are not currently in receive mode, then restart the random delay (this can happen if the main thread
// has placed the unit into standby) FIXME, how will this work if the chipset is in sleep mode?
if (!txQueue.empty()) {
if (!canSendImmediately()) {
// LOG_DEBUG("Currently Rx/Tx-ing: set random delay\n");
setTransmitDelay(); // currently Rx/Tx-ing: reset random delay
} else {
if (isChannelActive()) { // check if there is currently a LoRa packet on the channel
// LOG_DEBUG("Channel is active, try receiving first.\n");
startReceive(); // try receiving this packet, afterwards we'll be trying to transmit again
setTransmitDelay();
} else {
2023-01-21 12:01:19 +00:00
// Send any outgoing packets we have ready
meshtastic_MeshPacket *txp = txQueue.dequeue();
2023-01-21 12:01:19 +00:00
assert(txp);
startSend(txp);
// Packet has been sent, count it toward our TX airtime utilization.
uint32_t xmitMsec = getPacketTime(txp);
airTime->logAirtime(TX_LOG, xmitMsec);
}
}
2022-05-25 01:06:53 +00:00
} else {
2023-01-21 12:01:19 +00:00
// LOG_DEBUG("done with txqueue\n");
2022-05-25 01:06:53 +00:00
}
2023-01-21 12:01:19 +00:00
break;
default:
assert(0); // We expected to receive a valid notification from the ISR
}
2023-01-21 12:01:19 +00:00
}
2023-01-21 12:01:19 +00:00
void RadioLibInterface::setTransmitDelay()
{
meshtastic_MeshPacket *p = txQueue.getFront();
2023-01-21 12:01:19 +00:00
// We want all sending/receiving to be done by our daemon thread.
// We use a delay here because this packet might have been sent in response to a packet we just received.
// So we want to make sure the other side has had a chance to reconfigure its radio.
/* We assume if rx_snr = 0 and rx_rssi = 0, the packet was generated locally.
* This assumption is valid because of the offset generated by the radio to account for the noise
* floor.
*/
if (p->rx_snr == 0 && p->rx_rssi == 0) {
startTransmitTimer(true);
} else {
// If there is a SNR, start a timer scaled based on that SNR.
LOG_DEBUG("rx_snr found. hop_limit:%d rx_snr:%f\n", p->hop_limit, p->rx_snr);
startTransmitTimerSNR(p->rx_snr);
}
2023-01-21 12:01:19 +00:00
}
2023-01-21 12:01:19 +00:00
void RadioLibInterface::startTransmitTimer(bool withDelay)
{
// If we have work to do and the timer wasn't already scheduled, schedule it now
if (!txQueue.empty()) {
uint32_t delay = !withDelay ? 1 : getTxDelayMsec();
// LOG_DEBUG("xmit timer %d\n", delay);
notifyLater(delay, TRANSMIT_DELAY_COMPLETED, false); // This will implicitly enable
}
2023-01-21 12:01:19 +00:00
}
2023-01-21 12:01:19 +00:00
void RadioLibInterface::startTransmitTimerSNR(float snr)
{
// If we have work to do and the timer wasn't already scheduled, schedule it now
if (!txQueue.empty()) {
uint32_t delay = getTxDelayMsecWeighted(snr);
// LOG_DEBUG("xmit timer %d\n", delay);
notifyLater(delay, TRANSMIT_DELAY_COMPLETED, false); // This will implicitly enable
2020-04-30 20:50:40 +00:00
}
2023-01-21 12:01:19 +00:00
}
2023-01-21 12:01:19 +00:00
void RadioLibInterface::handleTransmitInterrupt()
{
// LOG_DEBUG("handling lora TX interrupt\n");
// This can be null if we forced the device to enter standby mode. In that case
// ignore the transmit interrupt
if (sendingPacket)
completeSending();
Add PowerMon support (#4155) * Turn off vscode cmake prompt - we don't use cmake on meshtastic * Add rak4631_dap variant for debugging with NanoDAP debug probe device. * The rak device can also run freertos (which is underneath nrf52 arduino) * Add semihosting support for nrf52840 devices Initial platformio.ini file only supports rak4630 Default to non TCP for the semihosting log output for now... Fixes https://github.com/meshtastic/firmware/issues/4135 * powermon WIP (for https://github.com/meshtastic/firmware/issues/4136 ) * oops - mean't to mark the _dbg variant as an 'extra' board. * powermon wip * Make serial port on wio-sdk-wm1110 board work By disabling the (inaccessible) adafruit USB * Instrument (radiolib only for now) lora for powermon per https://github.com/meshtastic/firmware/issues/4136 * powermon gps support https://github.com/meshtastic/firmware/issues/4136 * Add CPU deep and light sleep powermon states https://github.com/meshtastic/firmware/issues/4136 * Change the board/swversion bootstring so it is a new "structured" log msg. * powermon wip * add example script for getting esp S3 debugging working Not yet used but I didn't want these nasty tricks to get lost yet. * Add PowerMon reporting for screen and bluetooth pwr. * make power.powermon_enables config setting work. * update to latest protobufs * fix bogus shellcheck warning * make powermon optional (but default enabled because tiny and no runtime impact) * tell vscode, if formatting, use whatever our trunk formatter wants without this flag if the user has set some other formatter (clang) in their user level settings, it will be looking in the wrong directory for the clang options (we want the options in .trunk/clang) Note: formatOnSave is true in master, which means a bunch of our older files are non compliant and if you edit them it will generate lots of formatting related diffs. I guess I'll start letting that happen with my future commits ;-). * add PowerStress module * nrf52 arduino is built upon freertos, so let platformio debug it * don't accidentally try to Segger ICE if we are using another ICE * clean up RedirectablePrint::log so it doesn't have three very different implementations inline. * remove NoopPrint - it is no longer needed * when talking to API clients via serial, don't turn off log msgs instead encapsuate them * fix the build - would loop forever if there were no files to send * don't use Segger code if not talking to a Segger debugger * when encapsulating logs, make sure the strings always has nul terminators * nrf52 soft device will watchdog if you use ICE while BT on... so have debugger disable bluetooth. * Important to not print debug messages while writing to the toPhone scratch buffer * don't include newlines if encapsulating log records as protobufs * update to latest protobufs (needed for powermon goo) * PowerStress WIP * fix linter warning
2024-07-03 23:02:20 +00:00
powerMon->clearState(meshtastic_PowerMon_State_Lora_TXOn); // But our transmitter is deffinitely off now
2023-01-21 12:01:19 +00:00
}
2020-04-30 20:50:40 +00:00
2023-01-21 12:01:19 +00:00
void RadioLibInterface::completeSending()
{
// We are careful to clear sending packet before calling printPacket because
// that can take a long time
auto p = sendingPacket;
sendingPacket = NULL;
2023-01-21 12:01:19 +00:00
if (p) {
txGood++;
printPacket("Completed sending", p);
// We are done sending that packet, release it
packetPool.release(p);
// LOG_DEBUG("Done with send\n");
2022-05-25 01:06:53 +00:00
}
2023-01-21 12:01:19 +00:00
}
2020-12-27 17:29:48 +00:00
2023-01-21 12:01:19 +00:00
void RadioLibInterface::handleReceiveInterrupt()
{
uint32_t xmitMsec;
2023-01-21 12:01:19 +00:00
// when this is called, we should be in receive mode - if we are not, just jump out instead of bombing. Possible Race
// Condition?
if (!isReceiving) {
LOG_ERROR("handleReceiveInterrupt called when not in receive mode, which shouldn't happen.\n");
2023-01-21 12:01:19 +00:00
return;
}
2023-01-21 12:01:19 +00:00
isReceiving = false;
2023-01-21 12:01:19 +00:00
// read the number of actually received bytes
size_t length = iface->getPacketLength();
2022-05-25 01:06:53 +00:00
2023-01-21 12:01:19 +00:00
xmitMsec = getPacketTime(length);
2022-05-25 01:06:53 +00:00
2023-01-21 12:01:19 +00:00
int state = iface->readData(radiobuf, length);
if (state != RADIOLIB_ERR_NONE) {
LOG_ERROR("ignoring received packet due to error=%d\n", state);
rxBad++;
airTime->logAirtime(RX_ALL_LOG, xmitMsec);
} else {
// Skip the 4 headers that are at the beginning of the rxBuf
int32_t payloadLen = length - sizeof(PacketHeader);
const uint8_t *payload = radiobuf + sizeof(PacketHeader);
// check for short packets
if (payloadLen < 0) {
LOG_WARN("ignoring received packet too short\n");
rxBad++;
airTime->logAirtime(RX_ALL_LOG, xmitMsec);
2020-04-30 19:37:58 +00:00
} else {
2023-01-21 12:01:19 +00:00
const PacketHeader *h = (PacketHeader *)radiobuf;
rxGood++;
// altered packet with "from == 0" can do Remote Node Administration without permission
if (h->from == 0) {
LOG_WARN("ignoring received packet without sender\n");
return;
}
2023-01-21 12:01:19 +00:00
// Note: we deliver _all_ packets to our router (i.e. our interface is intentionally promiscuous).
// This allows the router and other apps on our node to sniff packets (usually routing) between other
// nodes.
meshtastic_MeshPacket *mp = packetPool.allocZeroed();
2020-04-30 23:36:59 +00:00
2023-01-21 12:01:19 +00:00
mp->from = h->from;
mp->to = h->to;
mp->id = h->id;
mp->channel = h->channel;
assert(HOP_MAX <= PACKET_FLAGS_HOP_LIMIT_MASK); // If hopmax changes, carefully check this code
mp->hop_limit = h->flags & PACKET_FLAGS_HOP_LIMIT_MASK;
mp->hop_start = (h->flags & PACKET_FLAGS_HOP_START_MASK) >> PACKET_FLAGS_HOP_START_SHIFT;
2023-01-21 12:01:19 +00:00
mp->want_ack = !!(h->flags & PACKET_FLAGS_WANT_ACK_MASK);
mp->via_mqtt = !!(h->flags & PACKET_FLAGS_VIA_MQTT_MASK);
2023-01-21 12:01:19 +00:00
addReceiveMetadata(mp);
2023-01-21 17:39:58 +00:00
mp->which_payload_variant =
meshtastic_MeshPacket_encrypted_tag; // Mark that the payload is still encrypted at this point
2023-01-21 12:01:19 +00:00
assert(((uint32_t)payloadLen) <= sizeof(mp->encrypted.bytes));
memcpy(mp->encrypted.bytes, payload, payloadLen);
mp->encrypted.size = payloadLen;
2023-01-21 12:01:19 +00:00
printPacket("Lora RX", mp);
2020-12-27 17:29:48 +00:00
2023-01-21 12:01:19 +00:00
airTime->logAirtime(RX_LOG, xmitMsec);
deliverToReceiver(mp);
}
}
2023-01-21 12:01:19 +00:00
}
2020-12-27 17:29:48 +00:00
Add PowerMon support (#4155) * Turn off vscode cmake prompt - we don't use cmake on meshtastic * Add rak4631_dap variant for debugging with NanoDAP debug probe device. * The rak device can also run freertos (which is underneath nrf52 arduino) * Add semihosting support for nrf52840 devices Initial platformio.ini file only supports rak4630 Default to non TCP for the semihosting log output for now... Fixes https://github.com/meshtastic/firmware/issues/4135 * powermon WIP (for https://github.com/meshtastic/firmware/issues/4136 ) * oops - mean't to mark the _dbg variant as an 'extra' board. * powermon wip * Make serial port on wio-sdk-wm1110 board work By disabling the (inaccessible) adafruit USB * Instrument (radiolib only for now) lora for powermon per https://github.com/meshtastic/firmware/issues/4136 * powermon gps support https://github.com/meshtastic/firmware/issues/4136 * Add CPU deep and light sleep powermon states https://github.com/meshtastic/firmware/issues/4136 * Change the board/swversion bootstring so it is a new "structured" log msg. * powermon wip * add example script for getting esp S3 debugging working Not yet used but I didn't want these nasty tricks to get lost yet. * Add PowerMon reporting for screen and bluetooth pwr. * make power.powermon_enables config setting work. * update to latest protobufs * fix bogus shellcheck warning * make powermon optional (but default enabled because tiny and no runtime impact) * tell vscode, if formatting, use whatever our trunk formatter wants without this flag if the user has set some other formatter (clang) in their user level settings, it will be looking in the wrong directory for the clang options (we want the options in .trunk/clang) Note: formatOnSave is true in master, which means a bunch of our older files are non compliant and if you edit them it will generate lots of formatting related diffs. I guess I'll start letting that happen with my future commits ;-). * add PowerStress module * nrf52 arduino is built upon freertos, so let platformio debug it * don't accidentally try to Segger ICE if we are using another ICE * clean up RedirectablePrint::log so it doesn't have three very different implementations inline. * remove NoopPrint - it is no longer needed * when talking to API clients via serial, don't turn off log msgs instead encapsuate them * fix the build - would loop forever if there were no files to send * don't use Segger code if not talking to a Segger debugger * when encapsulating logs, make sure the strings always has nul terminators * nrf52 soft device will watchdog if you use ICE while BT on... so have debugger disable bluetooth. * Important to not print debug messages while writing to the toPhone scratch buffer * don't include newlines if encapsulating log records as protobufs * update to latest protobufs (needed for powermon goo) * PowerStress WIP * fix linter warning
2024-07-03 23:02:20 +00:00
void RadioLibInterface::startReceive()
{
isReceiving = true;
powerMon->setState(meshtastic_PowerMon_State_Lora_RXOn);
}
void RadioLibInterface::configHardwareForSend()
{
powerMon->setState(meshtastic_PowerMon_State_Lora_TXOn);
}
void RadioLibInterface::setStandby()
{
// neither sending nor receiving
powerMon->clearState(meshtastic_PowerMon_State_Lora_RXOn);
powerMon->clearState(meshtastic_PowerMon_State_Lora_TXOn);
}
2023-01-21 12:01:19 +00:00
/** start an immediate transmit */
void RadioLibInterface::startSend(meshtastic_MeshPacket *txp)
2023-01-21 12:01:19 +00:00
{
printPacket("Starting low level send", txp);
if (disabled || !config.lora.tx_enabled) {
LOG_WARN("startSend is dropping tx packet because we are disabled\n");
packetPool.release(txp);
} else {
configHardwareForSend(); // must be after setStandby
2023-01-21 12:01:19 +00:00
size_t numbytes = beginSending(txp);
2021-05-01 03:27:37 +00:00
2023-01-21 12:01:19 +00:00
int res = iface->startTransmit(radiobuf, numbytes);
if (res != RADIOLIB_ERR_NONE) {
LOG_ERROR("startTransmit failed, error=%d\n", res);
RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_RADIO_SPI_BUG);
2023-01-21 12:01:19 +00:00
// This send failed, but make sure to 'complete' it properly
completeSending();
Add PowerMon support (#4155) * Turn off vscode cmake prompt - we don't use cmake on meshtastic * Add rak4631_dap variant for debugging with NanoDAP debug probe device. * The rak device can also run freertos (which is underneath nrf52 arduino) * Add semihosting support for nrf52840 devices Initial platformio.ini file only supports rak4630 Default to non TCP for the semihosting log output for now... Fixes https://github.com/meshtastic/firmware/issues/4135 * powermon WIP (for https://github.com/meshtastic/firmware/issues/4136 ) * oops - mean't to mark the _dbg variant as an 'extra' board. * powermon wip * Make serial port on wio-sdk-wm1110 board work By disabling the (inaccessible) adafruit USB * Instrument (radiolib only for now) lora for powermon per https://github.com/meshtastic/firmware/issues/4136 * powermon gps support https://github.com/meshtastic/firmware/issues/4136 * Add CPU deep and light sleep powermon states https://github.com/meshtastic/firmware/issues/4136 * Change the board/swversion bootstring so it is a new "structured" log msg. * powermon wip * add example script for getting esp S3 debugging working Not yet used but I didn't want these nasty tricks to get lost yet. * Add PowerMon reporting for screen and bluetooth pwr. * make power.powermon_enables config setting work. * update to latest protobufs * fix bogus shellcheck warning * make powermon optional (but default enabled because tiny and no runtime impact) * tell vscode, if formatting, use whatever our trunk formatter wants without this flag if the user has set some other formatter (clang) in their user level settings, it will be looking in the wrong directory for the clang options (we want the options in .trunk/clang) Note: formatOnSave is true in master, which means a bunch of our older files are non compliant and if you edit them it will generate lots of formatting related diffs. I guess I'll start letting that happen with my future commits ;-). * add PowerStress module * nrf52 arduino is built upon freertos, so let platformio debug it * don't accidentally try to Segger ICE if we are using another ICE * clean up RedirectablePrint::log so it doesn't have three very different implementations inline. * remove NoopPrint - it is no longer needed * when talking to API clients via serial, don't turn off log msgs instead encapsuate them * fix the build - would loop forever if there were no files to send * don't use Segger code if not talking to a Segger debugger * when encapsulating logs, make sure the strings always has nul terminators * nrf52 soft device will watchdog if you use ICE while BT on... so have debugger disable bluetooth. * Important to not print debug messages while writing to the toPhone scratch buffer * don't include newlines if encapsulating log records as protobufs * update to latest protobufs (needed for powermon goo) * PowerStress WIP * fix linter warning
2024-07-03 23:02:20 +00:00
powerMon->clearState(meshtastic_PowerMon_State_Lora_TXOn); // Transmitter off now
2023-01-21 12:01:19 +00:00
startReceive(); // Restart receive mode (because startTransmit failed to put us in xmit mode)
2022-05-25 01:06:53 +00:00
}
2023-01-21 12:01:19 +00:00
// Must be done AFTER, starting transmit, because startTransmit clears (possibly stale) interrupt pending register
// bits
enableInterrupt(isrTxLevel0);
}
}