Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial support for RadioMaster Bandit. #4523

Merged
merged 8 commits into from
Aug 23, 2024
Merged
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
1 change: 1 addition & 0 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ default_envs = tbeam
;default_envs = wio-e5
;default_envs = radiomaster_900_bandit_nano
;default_envs = radiomaster_900_bandit_micro
;default_envs = radiomaster_900_bandit
;default_envs = heltec_capsule_sensor_v3
;default_envs = heltec_vision_master_t190
;default_envs = heltec_vision_master_e213
Expand Down
59 changes: 58 additions & 1 deletion src/AmbientLightingThread.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include "Observer.h"
#include "configuration.h"

#ifdef HAS_NCP5623
Expand All @@ -22,10 +23,18 @@ class AmbientLightingThread : public concurrency::OSThread
public:
explicit AmbientLightingThread(ScanI2C::DeviceType type) : OSThread("AmbientLightingThread")
{
notifyDeepSleepObserver.observe(&notifyDeepSleep); // Let us know when shutdown() is issued.

// Enables Ambient Lighting by default if conditions are meet.
#if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE)
#ifdef ENABLE_AMBIENTLIGHTING
moduleConfig.ambient_lighting.led_state = true;
#endif
#endif
// Uncomment to test module
// moduleConfig.ambient_lighting.led_state = true;
// moduleConfig.ambient_lighting.current = 10;
// // Default to a color based on our node number
// Default to a color based on our node number
// moduleConfig.ambient_lighting.red = (myNodeInfo.my_node_num & 0xFF0000) >> 16;
// moduleConfig.ambient_lighting.green = (myNodeInfo.my_node_num & 0x00FF00) >> 8;
// moduleConfig.ambient_lighting.blue = myNodeInfo.my_node_num & 0x0000FF;
Expand Down Expand Up @@ -82,9 +91,46 @@ class AmbientLightingThread : public concurrency::OSThread
return disable();
}

// When shutdown() is issued, setLightingOff will be called.
CallbackObserver<AmbientLightingThread, void *> notifyDeepSleepObserver =
CallbackObserver<AmbientLightingThread, void *>(this, &AmbientLightingThread::setLightingOff);

private:
ScanI2C::DeviceType _type = ScanI2C::DeviceType::NONE;

// Turn RGB lighting off, is used in junction to shutdown()
int setLightingOff(void *unused)
{
#ifdef HAS_NCP5623
rgb.setCurrent(0);
rgb.setRed(0);
rgb.setGreen(0);
rgb.setBlue(0);
LOG_INFO("Turn Off NCP5623 Ambient lighting.\n");
#endif
#ifdef HAS_NEOPIXEL
pixels.clear();
pixels.show();
LOG_INFO("Turn Off NeoPixel Ambient lighting.\n");
#endif
#ifdef RGBLED_CA
analogWrite(RGBLED_RED, 255 - 0);
analogWrite(RGBLED_GREEN, 255 - 0);
analogWrite(RGBLED_BLUE, 255 - 0);
LOG_INFO("Turn Off Ambient lighting RGB Common Anode.\n");
#elif defined(RGBLED_RED)
analogWrite(RGBLED_RED, 0);
analogWrite(RGBLED_GREEN, 0);
analogWrite(RGBLED_BLUE, 0);
LOG_INFO("Turn Off Ambient lighting RGB Common Cathode.\n");
#endif
#ifdef UNPHONE
unphone.rgb(0, 0, 0);
LOG_INFO("Turn Off unPhone Ambient lighting.\n");
#endif
return 0;
}

void setLighting()
{
#ifdef HAS_NCP5623
Expand All @@ -100,6 +146,17 @@ class AmbientLightingThread : public concurrency::OSThread
pixels.fill(pixels.Color(moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green,
moduleConfig.ambient_lighting.blue),
0, NEOPIXEL_COUNT);

// RadioMaster Bandit has addressable LED at the two buttons
// this allow us to set different lighting for them in variant.h file.
#ifdef RADIOMASTER_900_BANDIT
#if defined(BUTTON1_COLOR) && defined(BUTTON1_COLOR_INDEX)
pixels.fill(BUTTON1_COLOR, BUTTON1_COLOR_INDEX, 1);
#endif
#if defined(BUTTON2_COLOR) && defined(BUTTON2_COLOR_INDEX)
pixels.fill(BUTTON2_COLOR, BUTTON1_COLOR_INDEX, 1);
#endif
#endif
pixels.show();
LOG_DEBUG("Initializing NeoPixel Ambient lighting w/ brightness(current)=%d, red=%d, green=%d, blue=%d\n",
moduleConfig.ambient_lighting.current, moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green,
Expand Down
26 changes: 21 additions & 5 deletions src/mesh/RF95Interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
// In theory up to 27 dBm is possible, but the modules installed in most radios can cope with a max of 20. So BIG WARNING
// if you set power to something higher than 17 or 20 you might fry your board.

#ifdef RADIOMASTER_900_BANDIT_NANO
#if defined(RADIOMASTER_900_BANDIT_NANO) || defined(RADIOMASTER_900_BANDIT)
// Structure to hold DAC and DB values
typedef struct {
uint8_t dac;
Expand All @@ -40,12 +40,23 @@ DACDB getDACandDB(uint8_t dbm)
static const struct {
uint8_t dbm;
DACDB values;
} dbmToDACDB[] = {
}
#ifdef RADIOMASTER_900_BANDIT_NANO
dbmToDACDB[] = {
{20, {168, 2}}, // 100mW
{24, {148, 6}}, // 250mW
{27, {128, 9}}, // 500mW
{30, {90, 12}} // 1000mW
};
#endif
#ifdef RADIOMASTER_900_BANDIT
dbmToDACDB[] = {
{20, {165, 2}}, // 100mW
{24, {155, 6}}, // 250mW
{27, {142, 9}}, // 500mW
{30, {110, 10}} // 1000mW
};
#endif
const int numValues = sizeof(dbmToDACDB) / sizeof(dbmToDACDB[0]);

// Find the interval dbm falls within and interpolate
Expand All @@ -56,7 +67,12 @@ DACDB getDACandDB(uint8_t dbm)
}

// Return a default value if no match is found and default to 100mW
#ifdef RADIOMASTER_900_BANDIT_NANO
DACDB defaultValue = {168, 2};
#endif
#ifdef RADIOMASTER_900_BANDIT
DACDB defaultValue = {165, 2};
#endif
return defaultValue;
}
#endif
Expand Down Expand Up @@ -95,7 +111,7 @@ bool RF95Interface::init()
{
RadioLibInterface::init();

#ifdef RADIOMASTER_900_BANDIT_NANO
#if defined(RADIOMASTER_900_BANDIT_NANO) || defined(RADIOMASTER_900_BANDIT)
// DAC and DB values based on dBm using interpolation
DACDB dacDbValues = getDACandDB(power);
int8_t powerDAC = dacDbValues.dac;
Expand All @@ -117,7 +133,7 @@ bool RF95Interface::init()
// enable PA
#ifdef RF95_PA_EN
#if defined(RF95_PA_DAC_EN)
#ifdef RADIOMASTER_900_BANDIT_NANO
#if defined(RADIOMASTER_900_BANDIT_NANO) || defined(RADIOMASTER_900_BANDIT)
// Use calculated DAC value
dacWrite(RF95_PA_EN, powerDAC);
#else
Expand Down Expand Up @@ -163,7 +179,7 @@ bool RF95Interface::init()
LOG_INFO("Frequency set to %f\n", getFreq());
LOG_INFO("Bandwidth set to %f\n", bw);
LOG_INFO("Power output set to %d\n", power);
#ifdef RADIOMASTER_900_BANDIT_NANO
#if defined(RADIOMASTER_900_BANDIT_NANO) || defined(RADIOMASTER_900_BANDIT)
LOG_INFO("DAC output set to %d\n", powerDAC);
#endif

Expand Down
2 changes: 2 additions & 0 deletions src/platform/esp32/architecture.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@
#define HW_VENDOR meshtastic_HardwareModel_WIPHONE
#elif defined(RADIOMASTER_900_BANDIT_NANO)
#define HW_VENDOR meshtastic_HardwareModel_RADIOMASTER_900_BANDIT_NANO
#elif defined(RADIOMASTER_900_BANDIT)
#define HW_VENDOR meshtastic_HardwareModel_RADIOMASTER_900_BANDIT
#elif defined(HELTEC_CAPSULE_SENSOR_V3)
#define HW_VENDOR meshtastic_HardwareModel_HELTEC_CAPSULE_SENSOR_V3
#elif defined(HELTEC_VISION_MASTER_T190)
Expand Down
14 changes: 14 additions & 0 deletions variants/radiomaster_900_bandit/platformio.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[env:radiomaster_900_bandit]
extends = esp32_base
board = esp32doit-devkit-v1
build_flags =
${esp32_base.build_flags}
-DRADIOMASTER_900_BANDIT
-DVTABLES_IN_FLASH=1
-DCONFIG_DISABLE_HAL_LOCKS=1
-O2
-Ivariants/radiomaster_900_bandit
board_build.f_cpu = 240000000L
upload_protocol = esptool
lib_deps =
${esp32_base.lib_deps}
121 changes: 121 additions & 0 deletions variants/radiomaster_900_bandit/variant.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
Initial settings and work by https://github.com/gjelsoe
Unit provided by Radio Master RC
https://radiomasterrc.com/products/bandit-expresslrs-rf-module with 1.29" OLED display CH1115 driver
*/

/*
On this model then screen is NOT upside down, don't flip it for the user.
*/
#undef DISPLAY_FLIP_SCREEN

/*
I2C SDA and SCL.
0x18 - STK8XXX Accelerometer, Not supported yet.
0x3C - SH1115 Display Driver
*/
#define I2C_SDA 14
#define I2C_SCL 12

/*
No GPS - but free pins are available.
*/
#define HAS_GPS 0
#undef GPS_RX_PIN
#undef GPS_TX_PIN

/*
Pin connections from ESP32-D0WDQ6 to SX1276.
*/
#define LORA_DIO0 22
#define LORA_DIO1 21
#define LORA_SCK 18
#define LORA_MISO 19
#define LORA_MOSI 23
#define LORA_CS 4
#define LORA_RESET 5
#define LORA_TXEN 33

/*
This unit has a FAN built-in.
FAN is active at 250mW on it's ExpressLRS Firmware.
This FAN has TACHO signal on Pin 27 for use with PWM.
*/
#define RF95_FAN_EN 2

/*
LED PIN setup and it has a NeoPixel LED.
It's possible to setup colors for Button 1 and 2,
look at BUTTON1_COLOR, BUTTON1_COLOR_INDEX, BUTTON2_COLOR and BUTTON2_COLOR_INDEX
this is done here for now.
*/
#define HAS_NEOPIXEL // Enable the use of neopixels
#define NEOPIXEL_COUNT 6 // How many neopixels are connected
#define NEOPIXEL_DATA 15 // GPIO pin used to send data to the neopixels
#define NEOPIXEL_TYPE (NEO_GRB + NEO_KHZ800) // Type of neopixels in use
#define ENABLE_AMBIENTLIGHTING // Turn on Ambient Lighting
// #define BUTTON1_COLOR 0xFF0000 // Background light for Button 1 in HEX RGB Color (RadioMaster Bandit only).
// #define BUTTON1_COLOR_INDEX 0 // NeoPixel Index ID for Button 1
// #define BUTTON2_COLOR 0x0000FF // Background light for Button 2 in HEX RGB Color (RadioMaster Bandit only).
// #define BUTTON2_COLOR_INDEX 1 // NeoPixel Index ID for Button 2

/*
It has 1 x five-way and 2 x normal buttons.

Button GPIO RGB Index
---------------------------
Five-way 39 -
Button 1 34 0
Button 2 35 1

Five way button when using ADC.
2.632V, 2.177V, 1.598V, 1.055V, 0V

ADC Values:
{ UP, DOWN, LEFT, RIGHT, ENTER, IDLE }
3227, 0 ,1961, 2668, 1290, 4095

Five way button when using ADC.
https://github.com/ExpressLRS/targets/blob/f3215b5ec891108db1a13523e4163950cfcadaac/TX/Radiomaster%20Bandit.json#L41

*/
#define INPUTBROKER_EXPRESSLRSFIVEWAY_TYPE
#define PIN_JOYSTICK 39
#define JOYSTICK_ADC_VALS /*UP*/ 3227, /*DOWN*/ 0, /*LEFT*/ 1961, /*RIGHT*/ 2668, /*OK*/ 1290, /*IDLE*/ 4095

/*
Normal Button Pin setup.
*/
#define BUTTON_PIN 34
#define BUTTON_NEED_PULLUP

/*
No External notification.
*/
#undef EXT_NOTIFY_OUT

/*
Remapping PIN Names.
Note, that this unit uses RFO
*/
#define USE_RF95
#define USE_RF95_RFO
#define RF95_CS LORA_CS
#define RF95_DIO1 LORA_DIO1
#define RF95_TXEN LORA_TXEN
#define RF95_RESET LORA_RESET
#define RF95_MAX_POWER 10

/*
This module has Skyworks SKY66122 controlled by dacWrite
power ranging from 100mW to 1000mW.

Mapping of PA_LEVEL to Power output: GPIO26/dacWrite
168 -> 100mW
155 -> 250mW
142 -> 500mW
110 -> 1000mW
*/
#define RF95_PA_EN 26
#define RF95_PA_DAC_EN
#define RF95_PA_LEVEL 110
Loading