Просмотр исходного кода

Initial support for nano g2 ultra

not yet implemented are GPS and external notification LED and buzzer
Rob Loranger 1 год назад
Родитель
Сommit
7e14fb3f65

+ 72 - 0
boards/nano-g2-ultra.json

@@ -0,0 +1,72 @@
+{
+    "build": {
+        "arduino": {
+            "ldscript": "nrf52840_s140_v6.ld"
+        },
+        "core": "nRF5",
+        "cpu": "cortex-m4",
+        "extra_flags": "-DARDUINO_NRF52840_FEATHER -DNRF52840_XXAA",
+        "f_cpu": "64000000L",
+        "hwids": [
+            [
+                "0x239A",
+                "0x8029"
+            ],
+            [
+                "0x239A",
+                "0x0029"
+            ],
+            [
+                "0x239A",
+                "0x002A"
+            ],
+            [
+                "0x239A",
+                "0x802A"
+            ]
+        ],
+        "usb_product": "BQ nRF52840",
+        "mcu": "nrf52840",
+        "variant": "nano-g2-ultra",
+        "bsp": {
+            "name": "adafruit"
+        },
+        "softdevice": {
+            "sd_flags": "-DS140",
+            "sd_name": "s140",
+            "sd_version": "6.1.1",
+            "sd_fwid": "0x00B6"
+        },
+        "bootloader": {
+            "settings_addr": "0xFF000"
+        }
+    },
+    "connectivity": [
+        "bluetooth"
+    ],
+    "debug": {
+        "jlink_device": "nRF52840_xxAA",
+        "svd_path": "nrf52840.svd"
+    },
+    "frameworks": [
+        "arduino"
+    ],
+    "name": "BQ nRF52840",
+    "upload": {
+        "maximum_ram_size": 248832,
+        "maximum_size": 815104,
+        "speed": 115200,
+        "protocol": "nrfutil",
+        "protocols": [
+            "jlink",
+            "nrfjprog",
+            "nrfutil",
+            "stlink"
+        ],
+        "use_1200bps_touch": true,
+        "require_upload_port": true,
+        "wait_for_upload_port": true
+    },
+    "url": "https://wiki.uniteng.com/en/meshtastic/nano-g2-ultra",
+    "vendor": "BQ Consulting"
+}

+ 103 - 0
variants/nano_g2_ultra/nano-g2.cpp

@@ -0,0 +1,103 @@
+#include <Arduino.h>
+#include "nano-g2.h"
+
+#ifdef NANO_G2_ULTRA
+
+#include <bluefruit.h>
+#include <Wire.h>
+
+static BLEDfu bledfu;
+
+static void connect_callback(uint16_t conn_handle)
+{
+  (void)conn_handle;
+  MESH_DEBUG_PRINTLN("BLE client connected");
+}
+
+static void disconnect_callback(uint16_t conn_handle, uint8_t reason)
+{
+  (void)conn_handle;
+  (void)reason;
+
+  MESH_DEBUG_PRINTLN("BLE client disconnected");
+}
+
+void NanoG2Ultra::begin()
+{
+  // for future use, sub-classes SHOULD call this from their begin()
+  startup_reason = BD_STARTUP_NORMAL;
+
+  pinMode(PIN_BUTTON1, INPUT);
+  // the external notification circuit is shared for both buzzer and led
+  // need to find out the switch state or somehow write a function that can
+  // sound the buzzer or signal the led. the led will stay on once brought HIGH
+  // and can be then brought LOW. It turns off with a hardware btn.
+  pinMode(EXT_NOTIFY_OUT, OUTPUT);
+  digitalWrite(EXT_NOTIFY_OUT, LOW);
+
+  Wire.begin();
+  pinMode(SX126X_POWER_EN, OUTPUT);
+  digitalWrite(SX126X_POWER_EN, HIGH);
+
+  delay(10);
+}
+
+uint16_t NanoG2Ultra::getBattMilliVolts()
+{
+  int adcvalue = 0;
+
+  analogReference(AR_INTERNAL_3_0);
+  analogReadResolution(12);
+  delay(10);
+
+  // ADC range is 0..3000mV and resolution is 12-bit (0..4095)
+  adcvalue = analogRead(PIN_VBAT_READ);
+  // Convert the raw value to compensated mv, taking the resistor-
+  // divider into account (providing the actual LIPO voltage)
+  return (uint16_t)((float)adcvalue * REAL_VBAT_MV_PER_LSB);
+}
+
+bool NanoG2Ultra::startOTAUpdate(const char *id, char reply[])
+{
+  // Config the peripheral connection with maximum bandwidth
+  // more SRAM required by SoftDevice
+  // Note: All config***() function must be called before begin()
+  Bluefruit.configPrphBandwidth(BANDWIDTH_MAX);
+  Bluefruit.configPrphConn(92, BLE_GAP_EVENT_LENGTH_MIN, 16, 16);
+
+  Bluefruit.begin(1, 0);
+  // Set max power. Accepted values are: -40, -30, -20, -16, -12, -8, -4, 0, 4
+  Bluefruit.setTxPower(4);
+  // Set the BLE device name
+  Bluefruit.setName("TECHO_OTA");
+
+  Bluefruit.Periph.setConnectCallback(connect_callback);
+  Bluefruit.Periph.setDisconnectCallback(disconnect_callback);
+
+  // To be consistent OTA DFU should be added first if it exists
+  bledfu.begin();
+
+  // Set up and start advertising
+  // Advertising packet
+  Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
+  Bluefruit.Advertising.addTxPower();
+  Bluefruit.Advertising.addName();
+
+  /* Start Advertising
+    - Enable auto advertising if disconnected
+    - Interval:  fast mode = 20 ms, slow mode = 152.5 ms
+    - Timeout for fast mode is 30 seconds
+    - Start(timeout) with timeout = 0 will advertise forever (until connected)
+
+    For recommended advertising interval
+    https://developer.apple.com/library/content/qa/qa1931/_index.html
+  */
+  Bluefruit.Advertising.restartOnDisconnect(true);
+  Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms
+  Bluefruit.Advertising.setFastTimeout(30);   // number of seconds in fast mode
+  Bluefruit.Advertising.start(0);             // 0 = Don't stop advertising after n seconds
+
+  strcpy(reply, "OK - started");
+  return true;
+}
+#endif

+ 57 - 0
variants/nano_g2_ultra/nano-g2.h

@@ -0,0 +1,57 @@
+#pragma once
+
+#include <MeshCore.h>
+#include <Arduino.h>
+
+// LoRa radio module pins
+#define P_LORA_DIO_1 (32 + 10)
+#define P_LORA_NSS (32 + 13)
+#define P_LORA_RESET (32 + 15)
+#define P_LORA_BUSY (32 + 11)
+#define P_LORA_SCLK (0 + 12)
+#define P_LORA_MISO (32 + 9)
+#define P_LORA_MOSI (0 + 11)
+
+#define SX126X_DIO2_AS_RF_SWITCH true
+#define SX126X_DIO3_TCXO_VOLTAGE 1.8
+#define SX126X_POWER_EN 37
+
+// buttons
+#define PIN_BUTTON1 (32 + 6)
+#define BUTTON_PIN PIN_BUTTON1
+#define PIN_USER_BTN BUTTON_PIN
+
+// built-ins
+#define VBAT_MV_PER_LSB (0.73242188F) // 3.0V ADC range and 12-bit ADC resolution = 3000mV/4096
+
+#define VBAT_DIVIDER (0.5F)      // 150K + 150K voltage divider on VBAT, actually 100K + 100K
+#define VBAT_DIVIDER_COMP (2.0F) // Compensation factor for the VBAT divider
+
+#define PIN_VBAT_READ (0 + 2)
+#define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB)
+
+class NanoG2Ultra : public mesh::MainBoard
+{
+protected:
+  uint8_t startup_reason;
+
+public:
+  void begin();
+  uint16_t getBattMilliVolts() override;
+  bool startOTAUpdate(const char *id, char reply[]) override;
+
+  uint8_t getStartupReason() const override
+  {
+    return startup_reason;
+  }
+
+  const char *getManufacturerName() const override
+  {
+    return "Nano G2 Ultra";
+  }
+
+  void reboot() override
+  {
+    NVIC_SystemReset();
+  }
+};

+ 57 - 0
variants/nano_g2_ultra/platformio.ini

@@ -0,0 +1,57 @@
+[nrf52840_g2_ultra]
+extends = nrf52_base
+platform_packages = framework-arduinoadafruitnrf52
+build_flags = ${nrf52_base.build_flags}
+  -I src/helpers/nrf52
+  -I lib/nrf52/s140_nrf52_6.1.1_API/include
+  -I lib/nrf52/s140_nrf52_6.1.1_API/include/nrf52
+lib_deps =
+  ${nrf52_base.lib_deps}
+  rweather/Crypto @ ^0.4.0
+  lewisxhe/PCF8563_Library@^1.0.1
+
+[Nano_G2_Ultra]
+extends = nrf52840_g2_ultra
+board = nano-g2-ultra
+board_build.ldscript = boards/nrf52840_s140_v6.ld
+build_flags = ${nrf52840_g2_ultra.build_flags}
+  -I variants/nano_g2_ultra
+  -D NANO_G2_ULTRA
+  -D RADIO_CLASS=CustomSX1262
+  -D WRAPPER_CLASS=CustomSX1262Wrapper
+  -D LORA_TX_POWER=22
+  -D SX126X_CURRENT_LIMIT=140
+  -D SX126X_RX_BOOSTED_GAIN=1
+  -D PIN_USER_BTN=38
+build_src_filter = ${nrf52840_g2_ultra.build_src_filter}
+  +<helpers/*.cpp>
+  +<../variants/nano_g2_ultra>
+debug_tool = jlink
+upload_protocol = nrfutil
+
+[env:Nano_G2_Ultra_companion_radio_ble]
+extends = Nano_G2_Ultra
+build_flags =
+  ${Nano_G2_Ultra.build_flags}
+  -I src/helpers/ui
+  -D MAX_CONTACTS=100
+  -D MAX_GROUP_CHANNELS=8
+  -D BLE_PIN_CODE=0
+  -D BLE_DEBUG_LOGGING=1
+  -D OFFLINE_QUEUE_SIZE=256
+  -D SH1106
+  -D DISPLAY_CLASS=SH1106Display
+;  -D ENABLE_PRIVATE_KEY_IMPORT=1
+;  -D ENABLE_PRIVATE_KEY_EXPORT=1
+;  -D MESH_PACKET_LOGGING=1
+;  -D MESH_DEBUG=1
+build_src_filter = ${Nano_G2_Ultra.build_src_filter}
+  +<helpers/nrf52/SerialBLEInterface.cpp>
+  +<helpers/ui/SH1106Display.cpp>
+  +<../examples/companion_radio>
+lib_deps =
+  ${Nano_G2_Ultra.lib_deps}
+  densaugeo/base64 @ ~1.4.0
+  adafruit/Adafruit SH110X @ ~2.1.13
+  adafruit/Adafruit GFX Library @ ^1.12.1
+

+ 76 - 0
variants/nano_g2_ultra/target.cpp

@@ -0,0 +1,76 @@
+#include <Arduino.h>
+#include "target.h"
+#include <helpers/ArduinoHelpers.h>
+
+NanoG2Ultra board;
+
+RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, SPI);
+
+WRAPPER_CLASS radio_driver(radio, board);
+
+VolatileRTCClock fallback_clock;
+AutoDiscoverRTCClock rtc_clock(fallback_clock);
+SensorManager sensors;
+
+#ifndef LORA_CR
+#define LORA_CR 5
+#endif
+
+bool radio_init()
+{
+  rtc_clock.begin(Wire);
+
+#ifdef SX126X_DIO3_TCXO_VOLTAGE
+  float tcxo = SX126X_DIO3_TCXO_VOLTAGE;
+#else
+  float tcxo = 1.6f;
+#endif
+
+  SPI.setPins(P_LORA_MISO, P_LORA_SCLK, P_LORA_MOSI);
+  SPI.begin();
+  int status = radio.begin(LORA_FREQ, LORA_BW, LORA_SF, LORA_CR, RADIOLIB_SX126X_SYNC_WORD_PRIVATE, LORA_TX_POWER, 8, tcxo);
+  if (status != RADIOLIB_ERR_NONE)
+  {
+    Serial.print("ERROR: radio init failed: ");
+    Serial.println(status);
+    return false; // fail
+  }
+
+  radio.setCRC(1);
+
+#ifdef SX126X_CURRENT_LIMIT
+  radio.setCurrentLimit(SX126X_CURRENT_LIMIT);
+#endif
+#ifdef SX126X_DIO2_AS_RF_SWITCH
+  radio.setDio2AsRfSwitch(SX126X_DIO2_AS_RF_SWITCH);
+#endif
+#ifdef SX126X_RX_BOOSTED_GAIN
+  radio.setRxBoostedGainMode(SX126X_RX_BOOSTED_GAIN);
+#endif
+
+  return true; // success
+}
+
+uint32_t radio_get_rng_seed()
+{
+  return radio.random(0x7FFFFFFF);
+}
+
+void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr)
+{
+  radio.setFrequency(freq);
+  radio.setSpreadingFactor(sf);
+  radio.setBandwidth(bw);
+  radio.setCodingRate(cr);
+}
+
+void radio_set_tx_power(uint8_t dbm)
+{
+  radio.setOutputPower(dbm);
+}
+
+mesh::LocalIdentity radio_new_identity()
+{
+  RadioNoiseListener rng(radio);
+  return mesh::LocalIdentity(&rng); // create new random identity
+}

+ 20 - 0
variants/nano_g2_ultra/target.h

@@ -0,0 +1,20 @@
+#pragma once
+
+#define RADIOLIB_STATIC_ONLY 1
+#include <RadioLib.h>
+#include "nano-g2.h"
+#include <helpers/RadioLibWrappers.h>
+#include <helpers/CustomSX1262Wrapper.h>
+#include <helpers/AutoDiscoverRTCClock.h>
+#include <helpers/SensorManager.h>
+
+extern NanoG2Ultra board;
+extern WRAPPER_CLASS radio_driver;
+extern AutoDiscoverRTCClock rtc_clock;
+extern SensorManager sensors;
+
+bool radio_init();
+uint32_t radio_get_rng_seed();
+void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
+void radio_set_tx_power(uint8_t dbm);
+mesh::LocalIdentity radio_new_identity();

+ 36 - 0
variants/nano_g2_ultra/variant.cpp

@@ -0,0 +1,36 @@
+/*
+  Copyright (c) 2014-2015 Arduino LLC.  All right reserved.
+  Copyright (c) 2016 Sandeep Mistry All right reserved.
+  Copyright (c) 2018, Adafruit Industries (adafruit.com)
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the GNU Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#include "variant.h"
+#include "nrf.h"
+#include "wiring_constants.h"
+#include "wiring_digital.h"
+
+const uint32_t g_ADigitalPinMap[] = {
+    // P0 - pins 0 and 1 are hardwired for xtal and should never be enabled
+    0xff, 0xff, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+
+    // P1
+    32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47};
+
+void initVariant()
+{
+  // Nothing need to be inited for now
+}

+ 189 - 0
variants/nano_g2_ultra/variant.h

@@ -0,0 +1,189 @@
+/*
+ Copyright (c) 2014-2015 Arduino LLC.  All right reserved.
+ Copyright (c) 2016 Sandeep Mistry All right reserved.
+ Copyright (c) 2018, Adafruit Industries (adafruit.com)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Lesser General Public License for more details.
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifndef _VARIANT_Nano_G2_
+#define _VARIANT_Nano_G2_
+
+/** Master clock frequency */
+#define VARIANT_MCK (64000000ul)
+
+#define USE_LFXO // Board uses 32khz crystal for LF
+// #define USE_LFRC  // Board uses 32khz RC for LF
+
+/*----------------------------------------------------------------------------
+ *        Headers
+ *----------------------------------------------------------------------------*/
+
+#include "WVariant.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif // __cplusplus
+
+// Number of pins defined in PinDescription array
+#define PINS_COUNT (48)
+#define NUM_DIGITAL_PINS (48)
+#define NUM_ANALOG_INPUTS (1)
+#define NUM_ANALOG_OUTPUTS (0)
+
+// LEDs
+#define PIN_LED1 (-1)
+#define PIN_LED2 (-1)
+#define PIN_LED3 (-1)
+
+#define LED_RED PIN_LED3
+#define LED_BLUE PIN_LED1
+#define LED_GREEN PIN_LED2
+
+#define LED_BUILTIN LED_BLUE
+#define LED_CONN PIN_GREEN
+
+#define LED_STATE_ON 0 // State when LED is lit
+
+/*
+ * Buttons
+ */
+#define PIN_BUTTON1 (32 + 6)
+
+#define EXT_NOTIFY_OUT (0 + 4) // Default pin to use for Ext Notify Module.
+
+/*
+ * Analog pins
+ */
+#define PIN_A4 (0 + 2) // Battery ADC
+
+#define BATTERY_PIN PIN_A4
+
+    static const uint8_t A4 = PIN_A4;
+
+#define ADC_RESOLUTION 14
+
+/*
+ * Serial interfaces
+ */
+#define PIN_SERIAL2_RX (0 + 22)
+#define PIN_SERIAL2_TX (0 + 20)
+
+/**
+    Wire Interfaces
+    */
+#define WIRE_INTERFACES_COUNT 1
+
+#define PIN_WIRE_SDA (0 + 17)
+#define PIN_WIRE_SCL (0 + 15)
+
+#define PIN_RTC_INT (0 + 14) // Interrupt from the PCF8563 RTC
+
+/*
+External serial flash W25Q16JV_IQ
+*/
+
+// QSPI Pins
+#define PIN_QSPI_SCK (0 + 8)
+#define PIN_QSPI_CS (32 + 7)
+#define PIN_QSPI_IO0 (0 + 6)  // MOSI if using two bit interface
+#define PIN_QSPI_IO1 (0 + 26) // MISO if using two bit interface
+#define PIN_QSPI_IO2 (32 + 4) // WP if using two bit interface (i.e. not used)
+#define PIN_QSPI_IO3 (32 + 2) // HOLD if using two bit interface (i.e. not used)
+
+// On-board QSPI Flash
+#define EXTERNAL_FLASH_DEVICES W25Q16JV_IQ
+#define EXTERNAL_FLASH_USE_QSPI
+
+    /*
+     * Lora radio
+     */
+
+#define USE_SX1262
+#define SX126X_CS (32 + 13) // FIXME - we really should define LORA_CS instead
+#define SX126X_DIO1 (32 + 10)
+// Note DIO2 is attached internally to the module to an analog switch for TX/RX switching
+// #define SX1262_DIO3 (0 + 21)
+// This is used as an *output* from the sx1262 and connected internally to power the tcxo, do not drive from the main CPU?
+#define SX126X_BUSY (32 + 11)
+#define SX126X_RESET (32 + 15)
+//  DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
+#define SX126X_DIO2_AS_RF_SWITCH
+#define SX126X_DIO3_TCXO_VOLTAGE 1.8
+
+    // #define LORA_DISABLE_SENDING // Define this to disable transmission for testing (power testing etc...)
+
+    // #undef SX126X_CS
+
+    /*
+     * GPS pins
+     */
+
+#define GPS_L76K
+
+#define PIN_GPS_STANDBY (0 + 13) // An output to wake GPS, low means allow sleep, high means force wake STANDBY
+#define PIN_GPS_TX (0 + 9)       // This is for bits going TOWARDS the CPU
+#define PIN_GPS_RX (0 + 10)      // This is for bits going TOWARDS the GPS
+
+    // #define GPS_THREAD_INTERVAL 50
+
+#define PIN_SERIAL1_RX PIN_GPS_TX
+#define PIN_SERIAL1_TX PIN_GPS_RX
+
+// PCF8563 RTC Module
+#define PCF8563_RTC 0x51
+
+/*
+ * SPI Interfaces
+ */
+#define SPI_INTERFACES_COUNT 1
+
+// For LORA, spi 0
+#define PIN_SPI_MISO (32 + 9)
+#define PIN_SPI_MOSI (0 + 11)
+#define PIN_SPI_SCK (0 + 12)
+
+// #define PIN_PWR_EN (0 + 6)
+
+// To debug via the segger JLINK console rather than the CDC-ACM serial device
+// #define USE_SEGGER
+
+// Battery
+// The battery sense is hooked to pin A0 (2)
+// it is defined in the anlaolgue pin section of this file
+// and has 12 bit resolution
+#define BATTERY_SENSE_RESOLUTION_BITS 12
+#define BATTERY_SENSE_RESOLUTION 4096.0
+#undef AREF_VOLTAGE
+#define AREF_VOLTAGE 3.0
+#define VBAT_AR_INTERNAL AR_INTERNAL_3_0
+#define ADC_MULTIPLIER (2.0F)
+
+#define HAS_RTC 1
+
+/**
+    OLED Screen Model
+    */
+#define ARDUINO_ARCH_AVR
+#define USE_SH1107_128_64
+
+#ifdef __cplusplus
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ *        Arduino objects - C++ only
+ *----------------------------------------------------------------------------*/
+
+#endif