2020-09-06 09:24:08 -07:00
|
|
|
#include "CryptoEngine.h"
|
2021-01-02 11:06:38 +08:00
|
|
|
#include "PortduinoGPIO.h"
|
2021-05-23 12:00:54 +08:00
|
|
|
#include "SPIChip.h"
|
2021-01-02 14:14:59 +08:00
|
|
|
#include "mesh/RF95Interface.h"
|
2020-10-31 15:50:39 +08:00
|
|
|
#include "sleep.h"
|
2021-04-02 09:14:12 +08:00
|
|
|
#include "target_specific.h"
|
2020-09-06 09:24:08 -07:00
|
|
|
|
2021-01-02 14:14:59 +08:00
|
|
|
#include <Utility.h>
|
|
|
|
|
#include <assert.h>
|
2023-11-15 20:33:53 -06:00
|
|
|
|
2023-11-15 17:04:41 -06:00
|
|
|
#ifdef ARCH_RASPBERRY_PI
|
2023-11-18 08:12:34 -06:00
|
|
|
#include "PortduinoGlue.h"
|
2023-11-15 17:04:41 -06:00
|
|
|
#include "pigpio.h"
|
2023-11-18 08:12:34 -06:00
|
|
|
#include "yaml-cpp/yaml.h"
|
|
|
|
|
#include <iostream>
|
|
|
|
|
#include <map>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
|
|
std::map<int, int> settingsMap;
|
2023-11-15 20:33:53 -06:00
|
|
|
|
2023-11-15 17:04:41 -06:00
|
|
|
#else
|
2021-04-22 14:28:56 +08:00
|
|
|
#include <linux/gpio/LinuxGPIOPin.h>
|
2023-11-15 17:04:41 -06:00
|
|
|
#endif
|
2020-09-06 09:24:08 -07:00
|
|
|
|
2023-11-15 20:33:53 -06:00
|
|
|
// FIXME - move setBluetoothEnable into a HALPlatform class
|
2020-09-06 09:24:08 -07:00
|
|
|
void setBluetoothEnable(bool on)
|
|
|
|
|
{
|
2021-03-17 20:29:27 +08:00
|
|
|
// not needed
|
2020-09-06 09:24:08 -07:00
|
|
|
}
|
|
|
|
|
|
2023-04-11 13:32:19 +02:00
|
|
|
void cpuDeepSleep(uint32_t msecs)
|
2021-04-02 09:14:12 +08:00
|
|
|
{
|
2020-10-31 15:50:39 +08:00
|
|
|
notImplemented("cpuDeepSleep");
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-02 11:06:38 +08:00
|
|
|
void updateBatteryLevel(uint8_t level) NOT_IMPLEMENTED("updateBatteryLevel");
|
2023-11-18 08:12:34 -06:00
|
|
|
#ifndef ARCH_RASPBERRY_PI
|
2021-04-28 14:47:29 +08:00
|
|
|
/** a simulated pin for busted IRQ hardware
|
|
|
|
|
* Porduino helper class to do this i2c based polling:
|
|
|
|
|
*/
|
|
|
|
|
class PolledIrqPin : public GPIOPin
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
PolledIrqPin() : GPIOPin(LORA_DIO1, "loraIRQ") {}
|
|
|
|
|
|
|
|
|
|
/// Read the low level hardware for this pin
|
|
|
|
|
virtual PinStatus readPinHardware()
|
|
|
|
|
{
|
|
|
|
|
if (isrPinStatus < 0)
|
|
|
|
|
return LOW; // No interrupt handler attached, don't bother polling i2c right now
|
|
|
|
|
else {
|
|
|
|
|
extern RadioInterface *rIf; // FIXME, temporary hack until we know if we need to keep this
|
|
|
|
|
|
|
|
|
|
assert(rIf);
|
|
|
|
|
RadioLibInterface *rIf95 = static_cast<RadioLibInterface *>(rIf);
|
|
|
|
|
bool p = rIf95->isIRQPending();
|
|
|
|
|
log(SysGPIO, LogDebug, "PolledIrqPin::readPinHardware(%s, %d, %d)", getName(), getPinNum(), p);
|
|
|
|
|
return p ? HIGH : LOW;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2021-05-23 11:46:57 +08:00
|
|
|
static GPIOPin *loraIrq;
|
2023-11-18 08:12:34 -06:00
|
|
|
#endif
|
2023-01-21 14:34:29 +01:00
|
|
|
int TCPPort = 4403;
|
|
|
|
|
|
|
|
|
|
static error_t parse_opt(int key, char *arg, struct argp_state *state)
|
|
|
|
|
{
|
|
|
|
|
switch (key) {
|
|
|
|
|
case 'p':
|
|
|
|
|
if (sscanf(arg, "%d", &TCPPort) < 1)
|
|
|
|
|
return ARGP_ERR_UNKNOWN;
|
|
|
|
|
else
|
|
|
|
|
printf("Using TCP port %d\n", TCPPort);
|
|
|
|
|
break;
|
|
|
|
|
case ARGP_KEY_ARG:
|
|
|
|
|
return 0;
|
|
|
|
|
default:
|
|
|
|
|
return ARGP_ERR_UNKNOWN;
|
|
|
|
|
}
|
2022-10-01 12:02:29 +02:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-21 14:34:29 +01:00
|
|
|
void portduinoCustomInit()
|
|
|
|
|
{
|
2022-10-01 12:02:29 +02:00
|
|
|
static struct argp_option options[] = {{"port", 'p', "PORT", 0, "The TCP port to use."}, {0}};
|
2023-01-21 14:34:29 +01:00
|
|
|
static void *childArguments;
|
2022-10-01 12:02:29 +02:00
|
|
|
static char doc[] = "Meshtastic native build.";
|
|
|
|
|
static char args_doc[] = "...";
|
|
|
|
|
static struct argp argp = {options, parse_opt, args_doc, doc, 0, 0, 0};
|
|
|
|
|
const struct argp_child child = {&argp, OPTION_ARG_OPTIONAL, 0, 0};
|
|
|
|
|
portduinoAddArguments(child, childArguments);
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-02 09:14:12 +08:00
|
|
|
/** apps run under portduino can optionally define a portduinoSetup() to
|
2021-01-02 11:06:38 +08:00
|
|
|
* use portduino specific init code (such as gpioBind) to setup portduino on their host machine,
|
|
|
|
|
* before running 'arduino' code.
|
|
|
|
|
*/
|
2021-04-02 09:14:12 +08:00
|
|
|
void portduinoSetup()
|
|
|
|
|
{
|
2022-10-01 12:00:31 +02:00
|
|
|
printf("Setting up Meshtastic on Portduino...\n");
|
2021-03-15 19:59:09 +08:00
|
|
|
|
2022-12-30 21:44:51 +01:00
|
|
|
#ifdef ARCH_RASPBERRY_PI
|
2023-11-18 08:12:34 -06:00
|
|
|
YAML::Node yamlConfig;
|
|
|
|
|
|
|
|
|
|
if (access("config.yaml", R_OK) == 0) {
|
|
|
|
|
try {
|
|
|
|
|
yamlConfig = YAML::LoadFile("config.yaml");
|
|
|
|
|
} catch (YAML::Exception e) {
|
|
|
|
|
std::cout << "*** Exception " << e.what() << std::endl;
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
} else if (access("/etc/meshtasticd/config.yaml", R_OK) == 0) {
|
|
|
|
|
try {
|
|
|
|
|
yamlConfig = YAML::LoadFile("/etc/meshtasticd/config.yaml");
|
|
|
|
|
} catch (YAML::Exception e) {
|
|
|
|
|
std::cout << "*** Exception " << e.what() << std::endl;
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
std::cout << "No 'config.yaml' found, exiting." << std::endl;
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
settingsMap[use_sx1262] = yamlConfig["USE_SX1262"].as<bool>(false);
|
|
|
|
|
settingsMap[sx126x_dio2_as_rf_switch] = yamlConfig["SX126X_DIO2_AS_RF_SWITCH"].as<bool>(false);
|
|
|
|
|
settingsMap[sx126x_cs] = yamlConfig["SX126X_CS"].as<int>(RADIOLIB_NC);
|
|
|
|
|
settingsMap[sx126x_dio1] = yamlConfig["SX126X_DIO1"].as<int>(RADIOLIB_NC);
|
|
|
|
|
settingsMap[sx126x_busy] = yamlConfig["SX126X_BUSY"].as<int>(RADIOLIB_NC);
|
|
|
|
|
settingsMap[sx126x_reset] = yamlConfig["SX126X_RESET"].as<int>(RADIOLIB_NC);
|
|
|
|
|
settingsMap[use_rf95] = yamlConfig["USE_RF95"].as<bool>(false);
|
|
|
|
|
settingsMap[rf95_nss] = yamlConfig["RF95_NSS"].as<int>(RADIOLIB_NC);
|
|
|
|
|
settingsMap[rf95_irq] = yamlConfig["RF95_IRQ"].as<int>(RADIOLIB_NC);
|
|
|
|
|
settingsMap[rf95_reset] = yamlConfig["RF95_RESET"].as<int>(RADIOLIB_NC);
|
|
|
|
|
settingsMap[rf95_dio1] = yamlConfig["RF95_DIO1"].as<int>(RADIOLIB_NC);
|
|
|
|
|
|
|
|
|
|
} catch (YAML::Exception e) {
|
|
|
|
|
std::cout << "*** Exception " << e.what() << std::endl;
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
if (access("/sys/kernel/debug/bluetooth/hci0/identity", R_OK) != 0) {
|
|
|
|
|
std::cout << "Cannot read Bluetooth MAC Address. Please run as root" << std::endl;
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
2023-11-15 17:04:41 -06:00
|
|
|
return;
|
2022-12-30 21:44:51 +01:00
|
|
|
#endif
|
|
|
|
|
|
2023-11-15 20:33:53 -06:00
|
|
|
#ifdef defined(PORTDUINO_LINUX_HARDWARE)
|
2023-01-21 14:34:29 +01:00
|
|
|
SPI.begin(); // We need to create SPI
|
2021-05-23 12:00:54 +08:00
|
|
|
bool usePineLora = !spiChip->isSimulated();
|
2023-01-21 14:34:29 +01:00
|
|
|
if (usePineLora) {
|
2021-05-23 11:46:57 +08:00
|
|
|
printf("Connecting to PineLora board...\n");
|
|
|
|
|
|
|
|
|
|
// FIXME: remove this hack once interrupts are confirmed to work on new pine64 board
|
|
|
|
|
// loraIrq = new PolledIrqPin();
|
|
|
|
|
loraIrq = new LinuxGPIOPin(LORA_DIO1, "ch341", "int", "loraIrq"); // or "err"?
|
|
|
|
|
loraIrq->setSilent();
|
|
|
|
|
gpioBind(loraIrq);
|
|
|
|
|
|
|
|
|
|
// BUSY hw was busted on current board - just use the simulated pin (which will read low)
|
2021-09-12 00:35:16 +03:00
|
|
|
auto busy = new LinuxGPIOPin(SX126X_BUSY, "ch341", "slct", "loraBusy");
|
2021-05-23 11:46:57 +08:00
|
|
|
busy->setSilent();
|
|
|
|
|
gpioBind(busy);
|
|
|
|
|
|
2021-09-12 00:35:16 +03:00
|
|
|
gpioBind(new LinuxGPIOPin(SX126X_RESET, "ch341", "ini", "loraReset"));
|
2021-05-23 11:46:57 +08:00
|
|
|
|
2021-09-12 00:35:16 +03:00
|
|
|
auto loraCs = new LinuxGPIOPin(SX126X_CS, "ch341", "cs0", "loraCs");
|
2021-05-23 11:46:57 +08:00
|
|
|
loraCs->setSilent();
|
|
|
|
|
gpioBind(loraCs);
|
2023-01-21 14:34:29 +01:00
|
|
|
} else
|
2021-05-23 17:57:20 +08:00
|
|
|
#endif
|
2023-11-18 08:12:34 -06:00
|
|
|
#ifndef ARCH_RASPBERRY_PI
|
2021-05-23 17:57:20 +08:00
|
|
|
{
|
2022-10-01 12:02:29 +02:00
|
|
|
// Set the random seed equal to TCPPort to have a different seed per instance
|
|
|
|
|
randomSeed(TCPPort);
|
|
|
|
|
|
2021-09-12 00:35:16 +03:00
|
|
|
auto fakeBusy = new SimGPIOPin(SX126X_BUSY, "fakeBusy");
|
2021-05-23 11:46:57 +08:00
|
|
|
fakeBusy->writePin(LOW);
|
|
|
|
|
fakeBusy->setSilent(true);
|
|
|
|
|
gpioBind(fakeBusy);
|
|
|
|
|
|
2021-09-12 00:35:16 +03:00
|
|
|
auto cs = new SimGPIOPin(SX126X_CS, "fakeLoraCS");
|
2021-05-23 11:46:57 +08:00
|
|
|
cs->setSilent(true);
|
|
|
|
|
gpioBind(cs);
|
|
|
|
|
|
2021-09-12 00:35:16 +03:00
|
|
|
gpioBind(new SimGPIOPin(SX126X_RESET, "fakeLoraReset"));
|
2021-05-23 11:46:57 +08:00
|
|
|
gpioBind(new SimGPIOPin(LORA_DIO1, "fakeLoraIrq"));
|
|
|
|
|
}
|
2021-04-02 09:14:12 +08:00
|
|
|
// gpioBind((new SimGPIOPin(LORA_RESET, "LORA_RESET")));
|
|
|
|
|
// gpioBind((new SimGPIOPin(RF95_NSS, "RF95_NSS"))->setSilent());
|
2023-11-18 08:12:34 -06:00
|
|
|
#endif
|
2023-11-15 17:04:41 -06:00
|
|
|
}
|