This commit is contained in:
geeksville 2020-02-01 11:25:07 -08:00
parent 1bda9c953e
commit 240d5955e9
4 changed files with 123 additions and 40 deletions

18
TODO.md
View File

@ -2,13 +2,27 @@
# High priority # High priority
* add mesh layer * make protobufs more real
* wrap in nice MeshRadio class * attach mesh service to radio and bluetooth
# Medium priority # Medium priority
* add interrupt detach/sleep mode config to lora radio so we can enable deepsleep without panicing * add interrupt detach/sleep mode config to lora radio so we can enable deepsleep without panicing
* figure out if we can use PA_BOOST
* scrub default radio config settings for bandwidth/range/speed
* use a freertos thread to remain blocked reading from recvfromAckTimeout, so that we don't need to keep polling it from our main thread
* override peekAtMessage so we can see any messages that pass through our node (even if not broadcast)? would that be useful?
# Pre-beta priority
* make sure main cpu is not woken for packets with bad crc or not addressed to this node - do that in the radio hw
* enable fast init inside the gps chip
* dynamically select node nums
* triple check fcc compliance
* allow setting full radio params from android
# Done # Done
* change the partition table to take advantage of the 4MB flash on the wroom: http://docs.platformio.org/en/latest/platforms/espressif32.html#partition-tables * change the partition table to take advantage of the 4MB flash on the wroom: http://docs.platformio.org/en/latest/platforms/espressif32.html#partition-tables
* wrap in nice MeshRadio class
* add mesh send & rx

View File

@ -43,7 +43,7 @@ public:
mesh sw does if it does conflict? would it be better for people who are replying with denynode num to just broadcast their denial?) mesh sw does if it does conflict? would it be better for people who are replying with denynode num to just broadcast their denial?)
}; };
class Mesh { class MeshRadio {
public: public:
@ -51,11 +51,11 @@ public:
void handleFromMesh(NodeNum fromNode, NodeNum toNode, std::string s); void handleFromMesh(NodeNum fromNode, NodeNum toNode, std::string s);
/// handle a packet from the phone, send it on the mesh /// handle a packet from the phone, send it on the mesh
void handleFromRadio(MeshPacket p); void handleToMesh(MeshPacket p);
}; };
/// Top level app for this service. keeps the mesh, the radio config and the queue of received packets. /// Top level app for this service. keeps the mesh, the radio config and the queue of received packets.
class MeshRadio { class MeshService {
public: public:
}; };

View File

@ -1,47 +1,84 @@
#include <SPI.h> #include <SPI.h>
#include <RH_RF95.h> #include <RH_RF95.h>
#include <RHMesh.h>
#include <assert.h>
#include "MeshRadio.h" #include "MeshRadio.h"
#include "configuration.h" #include "configuration.h"
// Singleton instance of the radio driver
RH_RF95 rf95(NSS_GPIO, DIO0_GPIO);
// Change to 434.0 or other frequency, must match RX's freq! // Change to 434.0 or other frequency, must match RX's freq!
#define RF95_FREQ 915.0 #define RF95_FREQ 915.0
MeshRadio radio;
/**
* get our starting (provisional) nodenum from flash. But check first if anyone else is using it, by trying to send a message to it (arping)
*/
NodeNum getDesiredNodeNum() {
uint8_t dmac[6];
esp_efuse_mac_get_default(dmac);
// FIXME
uint8_t r = dmac[5];
assert(r != 0xff); // It better not be the broadcast address
return r;
}
MeshRadio::MeshRadio() : rf95(NSS_GPIO, DIO0_GPIO), manager(rf95, getDesiredNodeNum()) {
}
bool MeshRadio::init() {
pinMode(RESET_GPIO, OUTPUT); // Deassert reset
digitalWrite(RESET_GPIO, HIGH);
// pulse reset
digitalWrite(RESET_GPIO, LOW);
delay(10);
digitalWrite(RESET_GPIO, HIGH);
delay(10);
if (!manager.init()) {
Serial.println("LoRa radio init failed");
Serial.println("Uncomment '#define SERIAL_DEBUG' in RH_RF95.cpp for detailed debug info");
return false;
}
Serial.println("LoRa radio init OK!");
// Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM
if (!rf95.setFrequency(RF95_FREQ)) {
Serial.println("setFrequency failed");
while (1);
}
Serial.print("Set Freq to: "); Serial.println(RF95_FREQ);
// Defaults after init are 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on
// The default transmitter power is 13dBm, using PA_BOOST.
// If you are using RFM95/96/97/98 modules which uses the PA_BOOST transmitter pin, then
// you can set transmitter powers from 5 to 23 dBm:
// FIXME - can we do this?
// rf95.setTxPower(23, false);
}
ErrorCode MeshRadio::sendTo(NodeNum dest, const uint8_t *buf, size_t len) {
return manager.sendtoWait((uint8_t *) buf, len, dest);
}
void MeshRadio::loop() {
// FIXME read from radio with recvfromAckTimeout
}
void mesh_init() { void mesh_init() {
pinMode(RESET_GPIO, OUTPUT); while (!radio.init()) {
digitalWrite(RESET_GPIO, HIGH); Serial.println("radio init failed");
// manual reset
digitalWrite(RESET_GPIO, LOW);
delay(10);
digitalWrite(RESET_GPIO, HIGH);
delay(10);
while (!rf95.init()) {
Serial.println("LoRa radio init failed");
Serial.println("Uncomment '#define SERIAL_DEBUG' in RH_RF95.cpp for detailed debug info");
while (1); while (1);
} }
Serial.println("LoRa radio init OK!");
// Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM
if (!rf95.setFrequency(RF95_FREQ)) {
Serial.println("setFrequency failed");
while (1);
}
Serial.print("Set Freq to: "); Serial.println(RF95_FREQ);
// Defaults after init are 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on
// The default transmitter power is 13dBm, using PA_BOOST.
// If you are using RFM95/96/97/98 modules which uses the PA_BOOST transmitter pin, then
// you can set transmitter powers from 5 to 23 dBm:
rf95.setTxPower(23, false);
} }
@ -49,15 +86,14 @@ int16_t packetnum = 0; // packet counter, we increment per xmission
void mesh_loop() void mesh_loop()
{ {
radio.loop();
delay(1000); // Wait 1 second between transmits, could also 'sleep' here! delay(1000); // Wait 1 second between transmits, could also 'sleep' here!
Serial.println("Transmitting..."); // Send a message to rf95_server Serial.println("Transmitting..."); // Send a message to rf95_server
char radiopacket[20] = "Hello World # "; char radiopacket[20] = "Hello World # ";
itoa(packetnum++, radiopacket+13, 10); sprintf(radiopacket, "hello %d", packetnum++);
Serial.print("Sending "); Serial.println(radiopacket);
radiopacket[19] = 0;
Serial.println("Sending..."); Serial.println("Sending...");
delay(10); radio.sendTo(NODENUM_BROADCAST, (uint8_t *)radiopacket, sizeof(radiopacket));
rf95.send((uint8_t *)radiopacket, 20);
} }

View File

@ -1,4 +1,37 @@
#pragma once #pragma once
#include <RH_RF95.h>
#include <RHMesh.h>
#define NODENUM_BROADCAST 255
typedef int ErrorCode;
typedef uint8_t NodeNum;
/**
* A raw low level interface to our mesh. Only understands nodenums and bytes (not protobufs or node ids)
*/
class MeshRadio {
public:
MeshRadio();
bool init();
/// Send a packet - the current implementation blocks for a while possibly (FIXME)
ErrorCode sendTo(NodeNum dest, const uint8_t *buf, size_t len);
/// Do loop callback operations (we currently FIXME poll the receive mailbox here)
void loop();
private:
RH_RF95 rf95; // the raw radio interface
RHMesh manager;
};
extern MeshRadio radio;
void mesh_init(); void mesh_init();
void mesh_loop(); void mesh_loop();