Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions variants/rak3401/RAK3401Board.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include <Arduino.h>
#include <Wire.h>

#include "RAK3401Board.h"

void RAK3401Board::begin() {
NRF52BoardDCDC::begin();
pinMode(PIN_VBAT_READ, INPUT);
#ifdef PIN_USER_BTN
pinMode(PIN_USER_BTN, INPUT_PULLUP);
#endif

#ifdef PIN_USER_BTN_ANA
pinMode(PIN_USER_BTN_ANA, INPUT_PULLUP);
#endif

#if defined(PIN_BOARD_SDA) && defined(PIN_BOARD_SCL)
Wire.setPins(PIN_BOARD_SDA, PIN_BOARD_SCL);
#endif

Wire.begin();

// Enable 3.3V periphery power rail (GPS, IO Module, etc.)
pinMode(PIN_3V3_EN, OUTPUT);
digitalWrite(PIN_3V3_EN, HIGH);

pinMode(SX126X_POWER_EN, OUTPUT);
digitalWrite(SX126X_POWER_EN, HIGH);
delay(10); // give sx1262 some time to power up

#ifdef P_LORA_PA_EN
// Initialize RAK13302 1W LoRa transceiver module PA control pin
pinMode(P_LORA_PA_EN, OUTPUT);
digitalWrite(P_LORA_PA_EN, LOW); // Start with PA disabled
delay(10); // Allow PA module to initialize
#endif
}
81 changes: 81 additions & 0 deletions variants/rak3401/RAK3401Board.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#pragma once

#include <MeshCore.h>
#include <Arduino.h>
#include <helpers/NRF52Board.h>

// LoRa radio module pins for RAK3401 with RAK13302 (uses SPI1)
#define P_LORA_DIO_1 10
#define P_LORA_NSS 26
#define P_LORA_RESET 4
#define P_LORA_BUSY 9
#define P_LORA_SCLK 3 // SPI1_SCK
#define P_LORA_MISO 29 // SPI1_MISO
#define P_LORA_MOSI 30 // SPI1_MOSI
#define SX126X_POWER_EN 21

//#define PIN_GPS_SDA 13 //GPS SDA pin (output option)
//#define PIN_GPS_SCL 14 //GPS SCL pin (output option)
//#define PIN_GPS_TX 16 //GPS TX pin
//#define PIN_GPS_RX 15 //GPS RX pin
#define PIN_GPS_1PPS 17 //GPS PPS pin
#define GPS_BAUD_RATE 9600
#define GPS_ADDRESS 0x42 //i2c address for GPS

// RAK13302 1W LoRa transceiver module PA control (WisBlock IO slot)
// The RAK13302 mounts to the IO slot and has an ANT_SW (antenna switch) pin that controls the PA
// This pin must be controlled during transmission to enable the 1W power amplifier
//
// According to RAK13302 datasheet: ANT_SW connects to IO3 on the IO slot
// RAK19007 base board pin mapping: IO3 = pin 31 (also available as AIN1/A1 for analog input)
//
// Default: Pin 31 (IO3) - ANT_SW pin from RAK13302 datasheet
// Override by defining P_LORA_PA_EN in platformio.ini if needed
#ifndef P_LORA_PA_EN
#define P_LORA_PA_EN 31 // ANT_SW pin from RAK13302 datasheet (IO3, pin 31 on RAK19007)
#endif

#define SX126X_DIO2_AS_RF_SWITCH true
#define SX126X_DIO3_TCXO_VOLTAGE 1.8

// built-ins
#define PIN_VBAT_READ 5
#define ADC_MULTIPLIER (3 * 1.73 * 1.187 * 1000)

// 3.3V periphery enable (GPS, IO Module, etc.)
#define PIN_3V3_EN (34)
#define WB_IO2 PIN_3V3_EN

class RAK3401Board : public NRF52BoardDCDC, public NRF52BoardOTA {
public:
RAK3401Board() : NRF52BoardOTA("RAK3401_OTA") {}
void begin();

#define BATTERY_SAMPLES 8

uint16_t getBattMilliVolts() override {
analogReadResolution(12);

uint32_t raw = 0;
for (int i = 0; i < BATTERY_SAMPLES; i++) {
raw += analogRead(PIN_VBAT_READ);
}
raw = raw / BATTERY_SAMPLES;

return (ADC_MULTIPLIER * raw) / 4096;
}

const char* getManufacturerName() const override {
return "RAK 3401";
}

#ifdef P_LORA_PA_EN
void onBeforeTransmit() override {
digitalWrite(P_LORA_PA_EN, HIGH); // Enable PA before transmission
}

void onAfterTransmit() override {
digitalWrite(P_LORA_PA_EN, LOW); // Disable PA after transmission to save power
}
#endif
};
135 changes: 135 additions & 0 deletions variants/rak3401/platformio.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
[rak3401]
extends = nrf52_base
board = rak4631
board_check = true
build_flags = ${nrf52_base.build_flags}
${sensor_base.build_flags}
-I variants/rak3401
-D RAK_4631
-D RAK_3401
-D RAK13302
-D RAK_BOARD
-D PIN_BOARD_SCL=14
-D PIN_BOARD_SDA=13
-D PIN_GPS_TX=PIN_SERIAL1_RX
-D PIN_GPS_RX=PIN_SERIAL1_TX
-D PIN_GPS_EN=-1
-D PIN_OLED_RESET=-1
-D RADIO_CLASS=CustomSX1262
-D WRAPPER_CLASS=CustomSX1262Wrapper
-D LORA_TX_POWER=22
-D SX126X_CURRENT_LIMIT=140
-D SX126X_RX_BOOSTED_GAIN=1
build_src_filter = ${nrf52_base.build_src_filter}
+<../variants/rak3401>
+<helpers/sensors>
+<helpers/ui/SSD1306Display.cpp>
+<helpers/ui/MomentaryButton.cpp>
lib_deps =
${nrf52_base.lib_deps}
${sensor_base.lib_deps}
adafruit/Adafruit SSD1306 @ ^2.5.13
sparkfun/SparkFun u-blox GNSS Arduino Library@^2.2.27

[env:RAK_3401_repeater]
extends = rak3401
build_flags =
${rak3401.build_flags}
-D DISPLAY_CLASS=SSD1306Display
-D ADVERT_NAME='"RAK3401 1W Repeater"'
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=50
;-D MESH_PACKET_LOGGING=1
;-D MESH_DEBUG=1
build_src_filter = ${rak3401.build_src_filter}
+<helpers/ui/SSD1306Display.cpp>
+<../examples/simple_repeater>

[env:RAK_3401_room_server]
extends = rak3401
build_flags =
${rak3401.build_flags}
-D DISPLAY_CLASS=SSD1306Display
-D ADVERT_NAME='"Test Room"'
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD='"hello"'
;-D MESH_PACKET_LOGGING=1
;-D MESH_DEBUG=1
build_src_filter = ${rak3401.build_src_filter}
+<helpers/ui/SSD1306Display.cpp>
+<../examples/simple_room_server>

[env:RAK_3401_companion_radio_usb]
extends = rak3401
board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
board_upload.maximum_size = 712704
build_flags =
${rak3401.build_flags}
-I examples/companion_radio/ui-new
-D DISPLAY_CLASS=SSD1306Display
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
; NOTE: DO NOT ENABLE --> -D MESH_PACKET_LOGGING=1
; NOTE: DO NOT ENABLE --> -D MESH_DEBUG=1
build_src_filter = ${rak3401.build_src_filter}
+<../examples/companion_radio/*.cpp>
+<../examples/companion_radio/ui-new/*.cpp>
lib_deps =
${rak3401.lib_deps}
densaugeo/base64 @ ~1.4.0

[env:RAK_3401_companion_radio_ble]
extends = rak3401
board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
board_upload.maximum_size = 712704
build_flags =
${rak3401.build_flags}
-I examples/companion_radio/ui-new
-D DISPLAY_CLASS=SSD1306Display
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
-D BLE_PIN_CODE=123456
-D BLE_DEBUG_LOGGING=1
-D OFFLINE_QUEUE_SIZE=256
;-D MESH_PACKET_LOGGING=1
;-D MESH_DEBUG=1
build_src_filter = ${rak3401.build_src_filter}
+<helpers/nrf52/SerialBLEInterface.cpp>
+<../examples/companion_radio/*.cpp>
+<../examples/companion_radio/ui-new/*.cpp>
lib_deps =
${rak3401.lib_deps}
densaugeo/base64 @ ~1.4.0

[env:RAK_3401_terminal_chat]
extends = rak3401
build_flags =
${rak3401.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=1
;-D MESH_PACKET_LOGGING=1
;-D MESH_DEBUG=1
build_src_filter = ${rak3401.build_src_filter}
+<../examples/simple_secure_chat/main.cpp>
lib_deps =
${rak3401.lib_deps}
densaugeo/base64 @ ~1.4.0

[env:RAK_3401_sensor]
extends = rak3401
build_flags =
${rak3401.build_flags}
-D DISPLAY_CLASS=SSD1306Display
-D ADVERT_NAME='"RAK3401 Sensor"'
-D ADVERT_LAT=0.0
-D ADVERT_LON=0.0
-D ADMIN_PASSWORD='"password"'
;-D MESH_PACKET_LOGGING=1
;-D MESH_DEBUG=1
build_src_filter = ${rak3401.build_src_filter}
+<helpers/ui/SSD1306Display.cpp>
+<../examples/simple_sensor>
66 changes: 66 additions & 0 deletions variants/rak3401/target.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#include <Arduino.h>
#include "target.h"
#include <helpers/ArduinoHelpers.h>

RAK3401Board board;

#ifndef PIN_USER_BTN
#define PIN_USER_BTN (-1)
#endif

#ifdef DISPLAY_CLASS
DISPLAY_CLASS display;
MomentaryButton user_btn(PIN_USER_BTN, 1000, true, true);

#if defined(PIN_USER_BTN_ANA)
MomentaryButton analog_btn(PIN_USER_BTN_ANA, 1000, 20);
#endif
#endif

// RAK3401 uses SPI1 for the RAK13302 LoRa module
// Note: nRF52 doesn't have a separate SPI1 object, so we use SPI but configure it with SPI1 pins
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);

#if ENV_INCLUDE_GPS
#include <helpers/sensors/MicroNMEALocationProvider.h>
MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1);
EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea);
#else
EnvironmentSensorManager sensors;
#endif

bool radio_init() {
rtc_clock.begin(Wire);

// Configure SPI with SPI1 pins for RAK13302
// nRF52 uses the same SPI peripheral but with different pin assignments
SPI.setPins(P_LORA_MISO, P_LORA_SCLK, P_LORA_MOSI);
SPI.begin();

return radio.std_init(&SPI);
}

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
}
30 changes: 30 additions & 0 deletions variants/rak3401/target.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#pragma once

#define RADIOLIB_STATIC_ONLY 1
#include <RadioLib.h>
#include <helpers/radiolib/RadioLibWrappers.h>
#include <RAK3401Board.h>
#include <helpers/radiolib/CustomSX1262Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
#include <helpers/sensors/EnvironmentSensorManager.h>

#ifdef DISPLAY_CLASS
#include <helpers/ui/SSD1306Display.h>
extern DISPLAY_CLASS display;
#include <helpers/ui/MomentaryButton.h>
extern MomentaryButton user_btn;
#if defined(PIN_USER_BTN_ANA)
extern MomentaryButton analog_btn;
#endif
#endif

extern RAK3401Board board;
extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
extern EnvironmentSensorManager 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();
43 changes: 43 additions & 0 deletions variants/rak3401/variant.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
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
0, 1, 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()
{
// LED1 & LED2
pinMode(PIN_LED1, OUTPUT);
ledOff(PIN_LED1);

pinMode(PIN_LED2, OUTPUT);
ledOff(PIN_LED2);

// 3V3 Power Rail
pinMode(PIN_3V3_EN, OUTPUT);
digitalWrite(PIN_3V3_EN, HIGH);
}
Loading