Skip to content

Commit caf421b

Browse files
authored
Merge pull request #1106 from oltaco/keepteen-lt1
Add support for Keepteen LT1
2 parents 838e83b + bc2256f commit caf421b

File tree

8 files changed

+483
-0
lines changed

8 files changed

+483
-0
lines changed

boards/keepteen_lt1.json

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
{
2+
"build": {
3+
"arduino":{
4+
"ldscript": "nrf52840_s140_v6.ld"
5+
},
6+
"core": "nRF5",
7+
"cpu": "cortex-m4",
8+
"extra_flags": "-DARDUINO_NRF52840_FEATHER -DNRF52840_XXAA",
9+
"f_cpu": "64000000L",
10+
"hwids": [
11+
[
12+
"0x239A",
13+
"0x00B3"
14+
],
15+
[
16+
"0x239A",
17+
"0x8029"
18+
],
19+
[
20+
"0x239A",
21+
"0x0029"
22+
],
23+
[
24+
"0x239A",
25+
"0x002A"
26+
],
27+
[
28+
"0x239A",
29+
"0x802A"
30+
]
31+
],
32+
"usb_product": "Keepteen LT1",
33+
"mcu": "nrf52840",
34+
"variant": "Keepteen LT1",
35+
"variants_dir": "variants",
36+
"bsp": {
37+
"name": "adafruit"
38+
},
39+
"softdevice": {
40+
"sd_flags": "-DS140",
41+
"sd_name": "s140",
42+
"sd_version": "6.1.1",
43+
"sd_fwid": "0x00B6"
44+
},
45+
"bootloader": {
46+
"settings_addr": "0xFF000"
47+
}
48+
},
49+
"connectivity": [
50+
"bluetooth"
51+
],
52+
"debug": {
53+
"jlink_device": "nRF52840_xxAA",
54+
"svd_path": "nrf52840.svd",
55+
"openocd_target": "nrf52.cfg"
56+
},
57+
"frameworks": [
58+
"arduino",
59+
"zephyr"
60+
],
61+
"name": "Keepteen LT1",
62+
"upload": {
63+
"maximum_ram_size": 248832,
64+
"maximum_size": 815104,
65+
"speed": 115200,
66+
"protocol": "nrfutil",
67+
"protocols": [
68+
"jlink",
69+
"nrfjprog",
70+
"nrfutil",
71+
"stlink"
72+
],
73+
"use_1200bps_touch": true,
74+
"require_upload_port": true,
75+
"wait_for_upload_port": true
76+
},
77+
"url": "http://www.keepteen.com/",
78+
"vendor": "Keepteen"
79+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#include <Arduino.h>
2+
#include "KeepteenLT1Board.h"
3+
4+
#include <bluefruit.h>
5+
#include <Wire.h>
6+
7+
static BLEDfu bledfu;
8+
9+
void KeepteenLT1Board::begin() {
10+
// for future use, sub-classes SHOULD call this from their begin()
11+
startup_reason = BD_STARTUP_NORMAL;
12+
btn_prev_state = HIGH;
13+
14+
pinMode(PIN_VBAT_READ, INPUT);
15+
16+
#if defined(PIN_BOARD_SDA) && defined(PIN_BOARD_SCL)
17+
Wire.setPins(PIN_BOARD_SDA, PIN_BOARD_SCL);
18+
#endif
19+
20+
Wire.begin();
21+
}
22+
23+
static void connect_callback(uint16_t conn_handle) {
24+
(void)conn_handle;
25+
MESH_DEBUG_PRINTLN("BLE client connected");
26+
}
27+
28+
static void disconnect_callback(uint16_t conn_handle, uint8_t reason) {
29+
(void)conn_handle;
30+
(void)reason;
31+
MESH_DEBUG_PRINTLN("BLE client disconnected");
32+
}
33+
34+
bool KeepteenLT1Board::startOTAUpdate(const char* id, char reply[]) {
35+
// Config the peripheral connection with maximum bandwidth
36+
// more SRAM required by SoftDevice
37+
// Note: All config***() function must be called before begin()
38+
Bluefruit.configPrphBandwidth(BANDWIDTH_MAX);
39+
Bluefruit.configPrphConn(92, BLE_GAP_EVENT_LENGTH_MIN, 16, 16);
40+
41+
Bluefruit.begin(1, 0);
42+
// Set max power. Accepted values are: -40, -30, -20, -16, -12, -8, -4, 0, 4
43+
Bluefruit.setTxPower(4);
44+
// Set the BLE device name
45+
Bluefruit.setName("KeepteenLT1_OTA");
46+
47+
Bluefruit.Periph.setConnectCallback(connect_callback);
48+
Bluefruit.Periph.setDisconnectCallback(disconnect_callback);
49+
50+
// To be consistent OTA DFU should be added first if it exists
51+
bledfu.begin();
52+
53+
// Set up and start advertising
54+
// Advertising packet
55+
Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
56+
Bluefruit.Advertising.addTxPower();
57+
Bluefruit.Advertising.addName();
58+
59+
/* Start Advertising
60+
- Enable auto advertising if disconnected
61+
- Interval: fast mode = 20 ms, slow mode = 152.5 ms
62+
- Timeout for fast mode is 30 seconds
63+
- Start(timeout) with timeout = 0 will advertise forever (until connected)
64+
65+
For recommended advertising interval
66+
https://developer.apple.com/library/content/qa/qa1931/_index.html
67+
*/
68+
Bluefruit.Advertising.restartOnDisconnect(true);
69+
Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms
70+
Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode
71+
Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds
72+
73+
strcpy(reply, "OK - started");
74+
return true;
75+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#pragma once
2+
3+
#include <MeshCore.h>
4+
#include <Arduino.h>
5+
6+
class KeepteenLT1Board : public mesh::MainBoard {
7+
protected:
8+
uint8_t startup_reason;
9+
uint8_t btn_prev_state;
10+
11+
public:
12+
void begin();
13+
14+
uint8_t getStartupReason() const override { return startup_reason; }
15+
16+
#define BATTERY_SAMPLES 8
17+
18+
uint16_t getBattMilliVolts() override {
19+
analogReadResolution(12);
20+
21+
uint32_t raw = 0;
22+
for (int i = 0; i < BATTERY_SAMPLES; i++) {
23+
raw += analogRead(PIN_VBAT_READ);
24+
}
25+
raw = raw / BATTERY_SAMPLES;
26+
return (ADC_MULTIPLIER * raw);
27+
}
28+
29+
const char* getManufacturerName() const override {
30+
return "Keepteen LT1";
31+
}
32+
33+
#if defined(P_LORA_TX_LED)
34+
void onBeforeTransmit() override {
35+
digitalWrite(P_LORA_TX_LED, HIGH); // turn TX LED on
36+
}
37+
void onAfterTransmit() override {
38+
digitalWrite(P_LORA_TX_LED, LOW); // turn TX LED off
39+
}
40+
#endif
41+
42+
void reboot() override {
43+
NVIC_SystemReset();
44+
}
45+
46+
void powerOff() override {
47+
sd_power_system_off();
48+
}
49+
50+
bool startOTAUpdate(const char* id, char reply[]) override;
51+
};
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
[KeepteenLT1]
2+
extends = nrf52_base
3+
board = keepteen_lt1
4+
build_flags = ${nrf52_base.build_flags}
5+
-I variants/keepteen_lt1
6+
-D KEEPTEEN_LT1
7+
-D RADIO_CLASS=CustomSX1262
8+
-D WRAPPER_CLASS=CustomSX1262Wrapper
9+
-D LORA_TX_POWER=22
10+
-D SX126X_CURRENT_LIMIT=140
11+
-D SX126X_RX_BOOSTED_GAIN=1
12+
-D PIN_BOARD_SDA=34
13+
-D PIN_BOARD_SCL=36
14+
-D ENV_INCLUDE_GPS=1
15+
build_src_filter = ${nrf52_base.build_src_filter}
16+
+<helpers/sensors>
17+
+<../variants/keepteen_lt1>
18+
lib_deps= ${nrf52_base.lib_deps}
19+
adafruit/Adafruit SSD1306 @ ^2.5.13
20+
stevemarple/MicroNMEA @ ^2.0.6
21+
22+
[env:KeepteenLT1_repeater]
23+
extends = KeepteenLT1
24+
build_src_filter = ${KeepteenLT1.build_src_filter}
25+
+<../examples/simple_repeater>
26+
+<helpers/ui/SSD1306Display.cpp>
27+
+<helpers/ui/MomentaryButton.cpp>
28+
build_flags =
29+
${KeepteenLT1.build_flags}
30+
-D ADVERT_NAME='"KeepteenLT1 Repeater"'
31+
-D ADVERT_LAT=0.0
32+
-D ADVERT_LON=0.0
33+
-D ADMIN_PASSWORD='"password"'
34+
-D MAX_NEIGHBOURS=50
35+
-D DISPLAY_CLASS=SSD1306Display
36+
; -D MESH_PACKET_LOGGING=1
37+
; -D MESH_DEBUG=1
38+
lib_deps = ${KeepteenLT1.lib_deps}
39+
adafruit/RTClib @ ^2.1.3
40+
41+
[env:KeepteenLT1_room_server]
42+
extends = KeepteenLT1
43+
build_src_filter = ${KeepteenLT1.build_src_filter}
44+
+<../examples/simple_room_server>
45+
+<helpers/ui/SSD1306Display.cpp>
46+
+<helpers/ui/MomentaryButton.cpp>
47+
build_flags = ${KeepteenLT1.build_flags}
48+
-D ADVERT_NAME='"KeepteenLT1 Room"'
49+
-D ADVERT_LAT=0.0
50+
-D ADVERT_LON=0.0
51+
-D ADMIN_PASSWORD='"password"'
52+
-D ROOM_PASSWORD='"hello"'
53+
-D DISPLAY_CLASS=SSD1306Display
54+
; -D MESH_PACKET_LOGGING=1
55+
; -D MESH_DEBUG=1
56+
lib_deps = ${KeepteenLT1.lib_deps}
57+
adafruit/RTClib @ ^2.1.3
58+
59+
[env:KeepteenLT1_companion_radio_usb]
60+
extends = KeepteenLT1
61+
board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
62+
board_upload.maximum_size = 712704
63+
build_flags = ${KeepteenLT1.build_flags}
64+
-I examples/companion_radio/ui-new
65+
-D MAX_CONTACTS=350
66+
-D MAX_GROUP_CHANNELS=40
67+
-D DISPLAY_CLASS=SSD1306Display
68+
; NOTE: DO NOT ENABLE --> -D MESH_PACKET_LOGGING=1
69+
; NOTE: DO NOT ENABLE --> -D MESH_DEBUG=1
70+
build_src_filter = ${KeepteenLT1.build_src_filter}
71+
+<helpers/ui/SSD1306Display.cpp>
72+
+<helpers/ui/MomentaryButton.cpp>
73+
+<../examples/companion_radio/*.cpp>
74+
+<../examples/companion_radio/ui-new/*.cpp>
75+
lib_deps = ${KeepteenLT1.lib_deps}
76+
adafruit/RTClib @ ^2.1.3
77+
densaugeo/base64 @ ~1.4.0
78+
79+
[env:KeepteenLT1_companion_radio_ble]
80+
extends = KeepteenLT1
81+
board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
82+
board_upload.maximum_size = 712704
83+
build_flags = ${KeepteenLT1.build_flags}
84+
-I examples/companion_radio/ui-new
85+
-D MAX_CONTACTS=350
86+
-D MAX_GROUP_CHANNELS=40
87+
-D BLE_PIN_CODE=123456
88+
-D BLE_DEBUG_LOGGING=1
89+
-D OFFLINE_QUEUE_SIZE=256
90+
-D DISPLAY_CLASS=SSD1306Display
91+
; -D MESH_PACKET_LOGGING=1
92+
-D MESH_DEBUG=1
93+
build_src_filter = ${KeepteenLT1.build_src_filter}
94+
+<helpers/nrf52/SerialBLEInterface.cpp>
95+
+<helpers/ui/SSD1306Display.cpp>
96+
+<helpers/ui/MomentaryButton.cpp>
97+
+<../examples/companion_radio/*.cpp>
98+
+<../examples/companion_radio/ui-new/*.cpp>
99+
lib_deps = ${KeepteenLT1.lib_deps}
100+
adafruit/RTClib @ ^2.1.3
101+
densaugeo/base64 @ ~1.4.0

variants/keepteen_lt1/target.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#include <Arduino.h>
2+
#include "target.h"
3+
#include <helpers/ArduinoHelpers.h>
4+
5+
KeepteenLT1Board board;
6+
7+
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, SPI);
8+
9+
WRAPPER_CLASS radio_driver(radio, board);
10+
11+
VolatileRTCClock fallback_clock;
12+
AutoDiscoverRTCClock rtc_clock(fallback_clock);
13+
#if ENV_INCLUDE_GPS
14+
#include <helpers/sensors/MicroNMEALocationProvider.h>
15+
MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1);
16+
EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea);
17+
#else
18+
EnvironmentSensorManager sensors;
19+
#endif
20+
21+
#ifdef DISPLAY_CLASS
22+
DISPLAY_CLASS display;
23+
MomentaryButton user_btn(PIN_USER_BTN, 1000, true, true);
24+
#endif
25+
26+
bool radio_init() {
27+
rtc_clock.begin(Wire);
28+
29+
return radio.std_init(&SPI);
30+
}
31+
32+
uint32_t radio_get_rng_seed() {
33+
return radio.random(0x7FFFFFFF);
34+
}
35+
36+
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) {
37+
radio.setFrequency(freq);
38+
radio.setSpreadingFactor(sf);
39+
radio.setBandwidth(bw);
40+
radio.setCodingRate(cr);
41+
}
42+
43+
void radio_set_tx_power(uint8_t dbm) {
44+
radio.setOutputPower(dbm);
45+
}
46+
47+
mesh::LocalIdentity radio_new_identity() {
48+
RadioNoiseListener rng(radio);
49+
return mesh::LocalIdentity(&rng); // create new random identity
50+
}
51+

variants/keepteen_lt1/target.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#pragma once
2+
3+
#define RADIOLIB_STATIC_ONLY 1
4+
#include <RadioLib.h>
5+
#include <helpers/radiolib/RadioLibWrappers.h>
6+
#include <KeepteenLT1Board.h>
7+
#include <helpers/radiolib/CustomSX1262Wrapper.h>
8+
#include <helpers/AutoDiscoverRTCClock.h>
9+
#ifdef DISPLAY_CLASS
10+
#include <helpers/ui/SSD1306Display.h>
11+
#include <helpers/ui/MomentaryButton.h>
12+
#endif
13+
14+
#include <helpers/sensors/EnvironmentSensorManager.h>
15+
16+
extern KeepteenLT1Board board;
17+
extern WRAPPER_CLASS radio_driver;
18+
extern AutoDiscoverRTCClock rtc_clock;
19+
extern EnvironmentSensorManager sensors;
20+
21+
#ifdef DISPLAY_CLASS
22+
extern DISPLAY_CLASS display;
23+
extern MomentaryButton user_btn;
24+
#endif
25+
26+
bool radio_init();
27+
uint32_t radio_get_rng_seed();
28+
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
29+
void radio_set_tx_power(uint8_t dbm);
30+
mesh::LocalIdentity radio_new_identity();

0 commit comments

Comments
 (0)