Skip to content

Commit 20fa45f

Browse files
authored
Merge branch 'master' into Exp_Desync_C
2 parents 8988d55 + e9272e9 commit 20fa45f

40 files changed

+3292
-585
lines changed

.github/workflows/build.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,18 @@ jobs:
108108
mkdir -p $OUTDIR
109109
mv .pio/build/${{ matrix.target }}/*.{elrs,bin} $OUTDIR >& /dev/null || :
110110
;;
111+
*LR1121*)
112+
# release builds
113+
PLATFORMIO_BUILD_FLAGS="-DRegulatory_Domain_EU_CE_2400 -DRegulatory_Domain_FCC_915" pio run -e ${{ matrix.target }}
114+
OUTDIR=~/artifacts/firmware/LBT/`echo ${{ matrix.target }} | sed s/_via.*//`
115+
mkdir -p $OUTDIR
116+
mv .pio/build/${{ matrix.target }}/*.{elrs,bin} $OUTDIR >& /dev/null || :
117+
118+
PLATFORMIO_BUILD_FLAGS="-DRegulatory_Domain_FCC_915" pio run -e ${{ matrix.target }}
119+
OUTDIR=~/artifacts/firmware/FCC/`echo ${{ matrix.target }} | sed s/_via.*//`
120+
mkdir -p $OUTDIR
121+
mv .pio/build/${{ matrix.target }}/*.{elrs,bin} $OUTDIR >& /dev/null || :
122+
;;
111123
*)
112124
# release build
113125
PLATFORMIO_BUILD_FLAGS="-DRegulatory_Domain_FCC_915" pio run -e ${{ matrix.target }}

src/html/libs.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,38 @@
44

55
// =========================================================
66

7+
function postWithFeedback(title, msg, url, getdata, success) {
8+
return function(e) {
9+
e.stopPropagation();
10+
e.preventDefault();
11+
xmlhttp = new XMLHttpRequest();
12+
xmlhttp.onreadystatechange = function() {
13+
if (this.readyState === 4) {
14+
if (this.status === 200) {
15+
if (success) success();
16+
cuteAlert({
17+
type: 'info',
18+
title: title,
19+
message: this.responseText
20+
});
21+
} else {
22+
cuteAlert({
23+
type: 'error',
24+
title: title,
25+
message: msg
26+
});
27+
}
28+
}
29+
};
30+
xmlhttp.open('POST', url, true);
31+
if (getdata) data = getdata(xmlhttp);
32+
else data = null;
33+
xmlhttp.send(data);
34+
};
35+
}
36+
37+
// =========================================================
38+
739
// Alert box design by Igor Ferrão de Souza: https://www.linkedin.com/in/igor-ferr%C3%A3o-de-souza-4122407b/
840

941
// eslint-disable-next-line no-unused-vars

src/html/lr1121.html

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ <h1><b>ExpressLRS</b></h1>
1818
</header>
1919
<br>
2020
<div class="mui-container-fluid mui-col-sm-10 mui-col-sm-offset-1">
21+
<div id="manual_upload" class="mui-panel" style="display:none; background-color: #FFC107;">
22+
LR1121 firmware has been manually flashed before, to revert to the ExpressLRS provided version you can click the button below.<br>
23+
<button id="reset" class="mui-btn mui-btn--small">Reset and reboot</button>
24+
</div>
2125
<div class="mui-panel">
2226
<div id="radios" style="display: none;">
2327
<div class="mui-radio">
@@ -59,13 +63,11 @@ <h3 id="status"></h3>
5963
<tr><td>Type</td><td><span id="radio_type1"></span></td><td><span id="radio_type2"></span></td></tr>
6064
<tr><td>Hardware</td><td><span id="radio_hardware1"></span></td><td><span id="radio_hardware2"></span></td></tr>
6165
<tr><td>Firmware</td><td><span id="radio_firmware1"></span></td><td><span id="radio_firmware2"></span></td></tr>
62-
<!-- <tr><td>PIN</td><td><span id="radio_pin1"></span></td><td><span id="radio_pin2"></span></td></tr>-->
63-
<!-- <tr><td>Chip EUI</td><td><span id="radio_ceui1"></span></td><td><span id="radio_ceui2"></span></td></tr>-->
64-
<!-- <tr><td>Join EUI</td><td><span id="radio_jeui1"></span></td><td><span id="radio_jeui2"></span></td></tr>-->
6566
</tbody>
6667
</table>
6768
</div>
6869
</div>
6970
</body>
71+
<script src="mui.js"></script>
7072
<script src="lr1121.js"></script>
7173
</html>

src/html/lr1121.js

Lines changed: 25 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,14 @@ function dec2hex(i, len) {
1919
return "0x" + (i+0x10000).toString(16).substr(-len).toUpperCase();
2020
}
2121

22+
_('reset').addEventListener('click', postWithFeedback('Reset LR1121 Firmware', 'An error occurred resetting the custom firmware flag', '/reset?lr1121', null))
23+
2224
function loadData() {
23-
xmlhttp = new XMLHttpRequest();
25+
let xmlhttp = new XMLHttpRequest();
2426
xmlhttp.onreadystatechange = function() {
2527
if (this.readyState === 4 && this.status === 200) {
2628
const data = JSON.parse(this.responseText);
29+
if (data['manual']) _('manual_upload').style.display = 'block';
2730
_('radio_type1').textContent = dec2hex(data['radio1']['type'], 2)
2831
_('radio_hardware1').textContent = dec2hex(data['radio1']['hardware'], 2)
2932
_('radio_firmware1').textContent = dec2hex(data['radio1']['firmware'], 4)
@@ -68,6 +71,10 @@ function fileSelectHandler(e) {
6871
}
6972

7073
function uploadFile(file) {
74+
mui.overlay('on', {
75+
'keyboard': false,
76+
'static': true
77+
})
7178
_('upload_btn').disabled = true
7279
try {
7380
const formdata = new FormData();
@@ -84,6 +91,7 @@ function uploadFile(file) {
8491
}
8592
catch (e) {
8693
_('upload_btn').disabled = false
94+
mui.overlay('off')
8795
}
8896
}
8997

@@ -94,68 +102,34 @@ function progressHandler(event) {
94102
_('status').innerHTML = percent + '% uploaded... please wait';
95103
}
96104

97-
function completeHandler(event) {
105+
async function completeHandler(event) {
98106
_('status').innerHTML = '';
99107
_('progressBar').value = 0;
100-
_('upload_btn').disabled = false
101108
const data = JSON.parse(event.target.responseText);
102109
if (data.status === 'ok') {
103-
function showMessage() {
104-
cuteAlert({
105-
type: 'success',
106-
title: 'Update Succeeded',
107-
message: data.msg
108-
});
109-
}
110110
// This is basically a delayed display of the success dialog with a fake progress
111111
let percent = 0;
112-
const interval = setInterval(()=>{
112+
const interval = setInterval(async ()=>{
113113
percent = percent + 2;
114114
_('progressBar').value = percent;
115115
_('status').innerHTML = percent + '% flashed... please wait';
116116
if (percent === 100) {
117117
clearInterval(interval);
118118
_('status').innerHTML = '';
119119
_('progressBar').value = 0;
120-
showMessage();
120+
_('upload_btn').disabled = false
121+
mui.overlay('off')
122+
await cuteAlert({
123+
type: 'success',
124+
title: 'Update Succeeded',
125+
message: data.msg
126+
});
121127
}
122128
}, 100);
123-
} else if (data.status === 'mismatch') {
124-
cuteAlert({
125-
type: 'question',
126-
title: 'Targets Mismatch',
127-
message: data.msg,
128-
confirmText: 'Flash anyway',
129-
cancelText: 'Cancel'
130-
}).then((e)=>{
131-
const xmlhttp = new XMLHttpRequest();
132-
xmlhttp.onreadystatechange = function() {
133-
if (this.readyState === 4) {
134-
_('status').innerHTML = '';
135-
_('progressBar').value = 0;
136-
if (this.status === 200) {
137-
const data = JSON.parse(this.responseText);
138-
cuteAlert({
139-
type: 'info',
140-
title: 'Force Update',
141-
message: data.msg
142-
});
143-
} else {
144-
cuteAlert({
145-
type: 'error',
146-
title: 'Force Update',
147-
message: 'An error occurred trying to force the update'
148-
});
149-
}
150-
}
151-
};
152-
xmlhttp.open('POST', '/forceupdate', true);
153-
const data = new FormData();
154-
data.append('action', e);
155-
xmlhttp.send(data);
156-
});
157129
} else {
158-
cuteAlert({
130+
_('upload_btn').disabled = false
131+
mui.overlay('off')
132+
await cuteAlert({
159133
type: 'error',
160134
title: 'Update Failed',
161135
message: data.msg
@@ -167,7 +141,8 @@ function errorHandler(event) {
167141
_('status').innerHTML = '';
168142
_('progressBar').value = 0;
169143
_('upload_btn').disabled = false
170-
cuteAlert({
144+
mui.overlay('off')
145+
return cuteAlert({
171146
type: 'error',
172147
title: 'Update Failed',
173148
message: event.target.responseText
@@ -178,7 +153,8 @@ function abortHandler(event) {
178153
_('status').innerHTML = '';
179154
_('progressBar').value = 0;
180155
_('upload_btn').disabled = false
181-
cuteAlert({
156+
mui.overlay('off')
157+
return cuteAlert({
182158
type: 'info',
183159
title: 'Update Aborted',
184160
message: event.target.responseText

src/html/scan.js

Lines changed: 6 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -693,55 +693,25 @@ _('fileselect').addEventListener('change', (e) => {
693693

694694
// =========================================================
695695

696-
function callback(title, msg, url, getdata, success) {
697-
return function(e) {
698-
e.stopPropagation();
699-
e.preventDefault();
700-
xmlhttp = new XMLHttpRequest();
701-
xmlhttp.onreadystatechange = function() {
702-
if (this.readyState === 4) {
703-
if (this.status === 200) {
704-
if (success) success();
705-
cuteAlert({
706-
type: 'info',
707-
title: title,
708-
message: this.responseText
709-
});
710-
} else {
711-
cuteAlert({
712-
type: 'error',
713-
title: title,
714-
message: msg
715-
});
716-
}
717-
}
718-
};
719-
xmlhttp.open('POST', url, true);
720-
if (getdata) data = getdata(xmlhttp);
721-
else data = null;
722-
xmlhttp.send(data);
723-
};
724-
}
725-
726696
function setupNetwork(event) {
727697
if (_('nt0').checked) {
728-
callback('Set Home Network', 'An error occurred setting the home network', '/sethome?save', function() {
698+
postWithFeedback('Set Home Network', 'An error occurred setting the home network', '/sethome?save', function() {
729699
return new FormData(_('sethome'));
730700
}, function() {
731701
_('wifi-ssid').value = _('network').value;
732702
_('wifi-password').value = _('password').value;
733703
})(event);
734704
}
735705
if (_('nt1').checked) {
736-
callback('Connect To Network', 'An error occurred connecting to the network', '/sethome', function() {
706+
postWithFeedback('Connect To Network', 'An error occurred connecting to the network', '/sethome', function() {
737707
return new FormData(_('sethome'));
738708
})(event);
739709
}
740710
if (_('nt2').checked) {
741-
callback('Start Access Point', 'An error occurred starting the Access Point', '/access', null)(event);
711+
postWithFeedback('Start Access Point', 'An error occurred starting the Access Point', '/access', null)(event);
742712
}
743713
if (_('nt3').checked) {
744-
callback('Forget Home Network', 'An error occurred forgetting the home network', '/forget', null)(event);
714+
postWithFeedback('Forget Home Network', 'An error occurred forgetting the home network', '/forget', null)(event);
745715
}
746716
}
747717

@@ -751,9 +721,9 @@ _('reset-model').addEventListener('click', callback('Reset Model Settings', 'An
751721
_('reset-options').addEventListener('click', callback('Reset Runtime Options', 'An error occurred resetting runtime options', '/reset?options', null));
752722

753723
_('sethome').addEventListener('submit', setupNetwork);
754-
_('connect').addEventListener('click', callback('Connect to Home Network', 'An error occurred connecting to the Home network', '/connect', null));
724+
_('connect').addEventListener('click', postWithFeedback('Connect to Home Network', 'An error occurred connecting to the Home network', '/connect', null));
755725
if (_('config')) {
756-
_('config').addEventListener('submit', callback('Set Configuration', 'An error occurred updating the configuration', '/config',
726+
_('config').addEventListener('submit', postWithFeedback('Set Configuration', 'An error occurred updating the configuration', '/config',
757727
(xmlhttp) => {
758728
xmlhttp.setRequestHeader('Content-Type', 'application/json');
759729
return JSON.stringify({

src/include/target/Unified_ESP32_TX.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,25 @@
7979
#define WS2812_BOOT_LEDS hardware_i16_array(HARDWARE_ledidx_rgb_boot)
8080
#define WS2812_BOOT_LEDS_COUNT hardware_int(HARDWARE_ledidx_rgb_boot_count)
8181

82+
#if defined(PLATFORM_ESP32_C3)
83+
// No I2C for gyro, thermal or screen
84+
#define GPIO_PIN_SCL UNDEF_PIN
85+
#define GPIO_PIN_SDA UNDEF_PIN
86+
#define OPT_HAS_SCREEN false
87+
#define OPT_HAS_GSENSOR false
88+
#define OPT_HAS_THERMAL false
89+
// No backpack
90+
#define OPT_USE_TX_BACKPACK false
91+
#define GPIO_PIN_DEBUG_RX UNDEF_PIN
92+
#define GPIO_PIN_DEBUG_TX UNDEF_PIN
93+
#define GPIO_PIN_BACKPACK_EN UNDEF_PIN
94+
#define GPIO_PIN_BACKPACK_BOOT UNDEF_PIN
95+
#define BACKPACK_LOGGING_BAUD 0
96+
#define PASSTHROUGH_BAUD 0
97+
// No fan
98+
#define GPIO_PIN_FAN_EN UNDEF_PIN
99+
#define GPIO_PIN_FAN_PWM UNDEF_PIN
100+
#else
82101
// OLED/TFT
83102
#define OPT_HAS_SCREEN (hardware_int(HARDWARE_screen_type) > 0)
84103
#define OPT_HAS_OLED_I2C (hardware_int(HARDWARE_screen_type)==1)
@@ -121,6 +140,7 @@
121140

122141
#define OPT_HAS_THERMAL_LM75A hardware_flag(HARDWARE_thermal_lm75a)
123142
#define OPT_HAS_THERMAL OPT_HAS_THERMAL_LM75A // If any of the sensors are present
143+
#endif
124144

125145
#define OPT_HAS_VTX_SPI false
126146
#define GPIO_PIN_SPI_VTX_NSS UNDEF_PIN

src/lib/CONFIG/config.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1139,7 +1139,7 @@ RxConfig::SetDefaults(bool commit)
11391139
for (int ch=0; ch<PWM_MAX_CHANNELS; ++ch)
11401140
{
11411141
uint8_t mode = som50Hz;
1142-
// setup defaults for hardware defined I2C pins that are also IO pins
1142+
// setup defaults for hardware-defined I2C & Serial pins that are also IO pins
11431143
if (ch < GPIO_PIN_PWM_OUTPUTS_COUNT)
11441144
{
11451145
if (GPIO_PIN_PWM_OUTPUTS[ch] == GPIO_PIN_SCL)
@@ -1150,14 +1150,25 @@ RxConfig::SetDefaults(bool commit)
11501150
{
11511151
mode = somSDA;
11521152
}
1153-
else if (GPIO_PIN_PWM_OUTPUTS[ch] == U0RXD_GPIO_NUM || GPIO_PIN_PWM_OUTPUTS[ch] == U0TXD_GPIO_NUM)
1153+
else if ((GPIO_PIN_RCSIGNAL_RX == U0RXD_GPIO_NUM && GPIO_PIN_PWM_OUTPUTS[ch] == U0RXD_GPIO_NUM) ||
1154+
(GPIO_PIN_RCSIGNAL_TX == U0TXD_GPIO_NUM && GPIO_PIN_PWM_OUTPUTS[ch] == U0TXD_GPIO_NUM))
11541155
{
11551156
mode = somSerial;
11561157
}
1158+
#if defined(PLATFORM_ESP32)
1159+
else if (GPIO_PIN_PWM_OUTPUTS[ch] == GPIO_PIN_SERIAL1_RX)
1160+
{
1161+
mode = somSerial1RX;
1162+
}
1163+
else if (GPIO_PIN_PWM_OUTPUTS[ch] == GPIO_PIN_SERIAL1_TX)
1164+
{
1165+
mode = somSerial1TX;
1166+
}
1167+
#endif
11571168
}
1158-
SetPwmChannel(ch, 512, ch, false, mode, false);
1169+
const uint16_t failsafe = ch == 2 ? 0 : 512; // ch2 is throttle, failsafe it to 988
1170+
SetPwmChannel(ch, failsafe, ch, false, mode, false);
11591171
}
1160-
SetPwmChannel(2, 0, 2, false, 0, false); // ch2 is throttle, failsafe it to 988
11611172

11621173
m_config.teamraceChannel = AUX7; // CH11
11631174

src/lib/CrsfProtocol/crsf_protocol.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,8 @@ typedef struct elrsLinkStatistics_s : crsfLinkStatistics_t
382382

383383
static uint16_t ICACHE_RAM_ATTR fmap(uint16_t x, uint16_t in_min, uint16_t in_max, uint16_t out_min, uint16_t out_max)
384384
{
385-
return ((x - in_min) * (out_max - out_min) * 2 / (in_max - in_min) + out_min * 2 + 1) / 2;
385+
int32_t result = ((int32_t)(x - in_min) * (out_max - out_min) * 2 / (in_max - in_min) + out_min * 2 + 1)/2;
386+
return result < 0 ? 0 : (result > 65535 ? 65535 : result);
386387
}
387388

388389
// Scale a -100& to +100% crossfire value to 988-2012 (Taranis channel uS)

src/lib/FHSS/FHSS.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,13 @@ const fhss_config_t domains[] = {
2424

2525
#if defined(RADIO_LR1121)
2626
const fhss_config_t domainsDualBand[] = {
27-
{"ISM2G4", FREQ_HZ_TO_REG_VAL(2400400000), FREQ_HZ_TO_REG_VAL(2479400000), 80, 2440000000}
27+
{
28+
#if defined(Regulatory_Domain_EU_CE_2400)
29+
"CE_LBT",
30+
#else
31+
"ISM2G4",
32+
#endif
33+
FREQ_HZ_TO_REG_VAL(2400400000), FREQ_HZ_TO_REG_VAL(2479400000), 80, 2440000000}
2834
};
2935
#endif
3036

@@ -161,3 +167,8 @@ bool isDomain868()
161167
{
162168
return strcmp(FHSSconfig->domain, "EU868") == 0;
163169
}
170+
171+
bool isUsingPrimaryFreqBand()
172+
{
173+
return FHSSusePrimaryFreqBand;
174+
}

0 commit comments

Comments
 (0)