Skip to content

Commit 4e4acf4

Browse files
authored
Daniel/duo/variable baud lifi adv modesharing (#298)
* big overhaul of modesharing and lifi protocol
1 parent 6098368 commit 4e4acf4

File tree

15 files changed

+363
-292
lines changed

15 files changed

+363
-292
lines changed

VortexEngine/src/Menus/MenuList/EditorConnection.cpp

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -258,20 +258,8 @@ void EditorConnection::handleState()
258258
case STATE_TRANSMIT_MODE_VL:
259259
#if VL_ENABLE_SENDER == 1
260260
// immediately load the mode and send it now
261-
VLSender::loadMode(&m_previewMode);
262-
VLSender::send();
261+
VLSender::send(&m_previewMode);
263262
#endif
264-
m_state = STATE_TRANSMIT_MODE_VL_TRANSMIT;
265-
break;
266-
case STATE_TRANSMIT_MODE_VL_TRANSMIT:
267-
#if VL_ENABLE_SENDER == 1
268-
// if still sending and the send command indicated more data
269-
if (VLSender::isSending() && VLSender::send()) {
270-
// then continue sending
271-
break;
272-
}
273-
#endif
274-
// othewrise, done, switch to the transmit done state
275263
m_state = STATE_TRANSMIT_MODE_VL_DONE;
276264
break;
277265
case STATE_TRANSMIT_MODE_VL_DONE:

VortexEngine/src/Menus/MenuList/EditorConnection.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ class EditorConnection : public Menu
7979

8080
// transmit the mode over visible light
8181
STATE_TRANSMIT_MODE_VL,
82-
STATE_TRANSMIT_MODE_VL_TRANSMIT,
8382
STATE_TRANSMIT_MODE_VL_DONE,
8483

8584
// editor pulls the modes from device (safer version)
Lines changed: 63 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "ModeSharing.h"
22

3+
#include "../../VortexEngine.h"
34
#include "../../Serial/ByteStream.h"
45
#include "../../Serial/Serial.h"
56
#include "../../Time/TimeControl.h"
@@ -15,28 +16,36 @@
1516

1617
ModeSharing::ModeSharing(const RGBColor &col, bool advanced) :
1718
Menu(col, advanced),
18-
m_sharingMode(ModeShareState::SHARE_RECEIVE),
19-
m_timeOutStartTime(0)
19+
m_sharingMode(ModeShareState::SHARE_SEND_RECEIVE),
20+
m_timeOutStartTime(0),
21+
m_lastPercentChange(0),
22+
m_lastPercent(0)
23+
2024
{
2125
}
2226

2327
ModeSharing::~ModeSharing()
2428
{
29+
VLReceiver::endReceiving();
30+
VortexEngine::toggleForceSleep(true);
2531
}
2632

2733
bool ModeSharing::init()
2834
{
2935
if (!Menu::init()) {
3036
return false;
3137
}
38+
// skip led selection
3239
if (!m_advanced) {
3340
// skip led selection
3441
m_ledSelected = true;
3542
}
3643
// start on receive because it's the more responsive of the two
3744
// the odds of opening receive and then accidentally receiving
3845
// a mode that is being broadcast nearby is completely unlikely
39-
beginReceiving();
46+
VLReceiver::beginReceiving();
47+
// turn off force sleep while using modesharing
48+
VortexEngine::toggleForceSleep(false);
4049
DEBUG_LOG("Entering Mode Sharing");
4150
return true;
4251
}
@@ -47,20 +56,24 @@ Menu::MenuAction ModeSharing::run()
4756
if (result != MENU_CONTINUE) {
4857
return result;
4958
}
50-
switch (m_sharingMode) {
51-
case ModeShareState::SHARE_SEND:
52-
// render the 'send mode' lights
53-
showSendMode();
54-
// continue sending any data as long as there is more to send
55-
continueSending();
56-
break;
57-
case ModeShareState::SHARE_RECEIVE:
58-
// render the 'receive mode' lights
59-
showReceiveMode();
60-
// load any modes that are received
61-
receiveMode();
62-
break;
59+
if (m_sharingMode == ModeShareState::SHARE_EXIT) {
60+
showExit();
61+
return MENU_CONTINUE;
62+
}
63+
// if the button is held for at least a long click, then continuously send
64+
if (g_pButton->isPressed() && g_pButton->holdDuration() >= CLICK_THRESHOLD) {
65+
// exit is handled above so the only two options are normal or legacy
66+
if (m_sharingMode == ModeShareState::SHARE_SEND_RECEIVE) {
67+
// send normal
68+
VLSender::send(&m_previewMode);
69+
} else {
70+
// send legacy
71+
VLSender::sendLegacy(&m_previewMode);
72+
}
6373
}
74+
// render the 'receive mode' lights whether legacy or not
75+
showReceiveMode();
76+
receiveMode();
6477
return MENU_CONTINUE;
6578
}
6679

@@ -78,12 +91,21 @@ void ModeSharing::onLedSelected()
7891
// handlers for clicks
7992
void ModeSharing::onShortClick()
8093
{
94+
if (g_pButton->holdDuration() >= CLICK_THRESHOLD) {
95+
return;
96+
}
8197
switch (m_sharingMode) {
82-
case ModeShareState::SHARE_RECEIVE:
83-
// click while on receive -> end receive, start sending
84-
VLReceiver::endReceiving();
85-
beginSending();
86-
DEBUG_LOG("Switched to send mode");
98+
case ModeShareState::SHARE_SEND_RECEIVE:
99+
// stop receiving, send the mode, go back to receiving
100+
VLReceiver::setLegacyReceiver(true);
101+
m_sharingMode = ModeShareState::SHARE_SEND_RECEIVE_LEGACY;
102+
break;
103+
case ModeShareState::SHARE_SEND_RECEIVE_LEGACY:
104+
VLReceiver::setLegacyReceiver(false);
105+
m_sharingMode = ModeShareState::SHARE_EXIT;
106+
break;
107+
case ModeShareState::SHARE_EXIT:
108+
m_sharingMode = ModeShareState::SHARE_SEND_RECEIVE;
87109
break;
88110
default:
89111
break;
@@ -93,57 +115,30 @@ void ModeSharing::onShortClick()
93115

94116
void ModeSharing::onLongClick()
95117
{
96-
leaveMenu();
97-
}
98-
99-
void ModeSharing::beginSending()
100-
{
101-
// if the sender is sending then cannot start again
102-
if (VLSender::isSending()) {
103-
ERROR_LOG("Cannot begin sending, sender is busy");
104-
return;
105-
}
106-
m_sharingMode = ModeShareState::SHARE_SEND;
107-
// initialize it with the current mode data
108-
VLSender::loadMode(&m_previewMode);
109-
// send the first chunk of data, leave if we're done
110-
if (!VLSender::send()) {
111-
// when send has completed, stores time that last action was completed to calculate interval between sends
112-
beginReceiving();
118+
if (m_sharingMode == ModeShareState::SHARE_EXIT) {
119+
leaveMenu();
113120
}
114121
}
115122

116-
void ModeSharing::continueSending()
117-
{
118-
// if the sender isn't sending then nothing to do
119-
if (!VLSender::isSending()) {
120-
return;
121-
}
122-
if (!VLSender::send()) {
123-
// when send has completed, stores time that last action was completed to calculate interval between sends
124-
beginReceiving();
125-
}
126-
}
127-
128-
void ModeSharing::beginReceiving()
129-
{
130-
m_sharingMode = ModeShareState::SHARE_RECEIVE;
131-
VLReceiver::beginReceiving();
132-
}
133-
134123
void ModeSharing::receiveMode()
135124
{
125+
uint32_t now = Time::getCurtime();
136126
// if reveiving new data set our last data time
137127
if (VLReceiver::onNewData()) {
138-
m_timeOutStartTime = Time::getCurtime();
128+
m_timeOutStartTime = now;
139129
// if our last data was more than time out duration reset the recveiver
140-
} else if (m_timeOutStartTime > 0 && (m_timeOutStartTime + MAX_TIMEOUT_DURATION) < Time::getCurtime()) {
130+
} else if (m_timeOutStartTime > 0 && (m_timeOutStartTime + MAX_TIMEOUT_DURATION) < now) {
141131
VLReceiver::resetVLState();
142132
m_timeOutStartTime = 0;
143133
return;
144134
}
145135
// check if the VLReceiver has a full packet available
146136
if (!VLReceiver::dataReady()) {
137+
uint8_t percent = VLReceiver::percentReceived();
138+
if (percent != m_lastPercent) {
139+
m_lastPercent = percent;
140+
m_lastPercentChange = now;
141+
}
147142
// nothing available yet
148143
return;
149144
}
@@ -170,21 +165,20 @@ void ModeSharing::receiveMode()
170165
leaveMenu(true);
171166
}
172167

173-
void ModeSharing::showSendMode()
174-
{
175-
// show a dim color when not sending
176-
if (!VLSender::isSending()) {
177-
Leds::setAll(RGBColor(0, 20, 20));
178-
}
179-
}
180-
181168
void ModeSharing::showReceiveMode()
182169
{
170+
// if the receiver is actively receiving right now then
183171
if (VLReceiver::isReceiving()) {
184-
// using uint32_t to avoid overflow, the result should be within 10 to 255
185-
Leds::setIndex(LED_0, RGBColor(0, VLReceiver::percentReceived(), 0));
172+
uint32_t diff = (Time::getCurtime() - m_lastPercentChange);
173+
// this generates the red flash when the receiver hasn't received something for
174+
// some amount of time, 100 is just arbitray idk if it could be a better value
175+
if (diff > 100) {
176+
Leds::setIndex(LED_0, RGB_RED3);
177+
} else {
178+
Leds::setIndex(LED_0, RGBColor(0, VLReceiver::percentReceived(), 0));
179+
}
186180
Leds::clearIndex(LED_1);
187181
} else {
188-
Leds::setAll(RGB_WHITE0);
182+
Leds::setAll((m_sharingMode == ModeShareState::SHARE_SEND_RECEIVE) ? 0x000F05 : RGB_WHITE0);
189183
}
190184
}

VortexEngine/src/Menus/MenuList/ModeSharing.h

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,25 @@ class ModeSharing : public Menu
2020
void onLongClick() override;
2121

2222
private:
23-
void beginSending();
24-
void continueSending();
25-
void beginReceiving();
2623
void receiveMode();
27-
28-
void showSendMode();
2924
void showReceiveMode();
3025

3126
enum class ModeShareState {
32-
SHARE_SEND, // send mode
33-
SHARE_RECEIVE, // receive mode
27+
// these three are the main options that can be iterated through
28+
// and if the button is held it will send, otherwise receive
29+
SHARE_SEND_RECEIVE, // send/receive mode
30+
SHARE_SEND_RECEIVE_LEGACY, // send/receive mode legacy
31+
SHARE_EXIT, // exit mode sharing
3432
};
3533

3634
ModeShareState m_sharingMode;
3735

3836
// the start time when checking for timing out
3937
uint32_t m_timeOutStartTime;
38+
39+
// used to track when the receive percentage changes for timeout purposes
40+
uint32_t m_lastPercentChange;
41+
uint8_t m_lastPercent;
4042
};
4143

4244
#endif

VortexEngine/src/Serial/BitStream.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ uint8_t BitStream::read1Bit()
8686
return rv;
8787
}
8888

89-
void BitStream::write1Bit(uint8_t bit)
89+
void BitStream::write1Bit(bool bit)
9090
{
9191
if (m_buf_eof) {
9292
return;
@@ -95,7 +95,8 @@ void BitStream::write1Bit(uint8_t bit)
9595
m_buf_eof = true;
9696
return;
9797
}
98-
m_buf[m_bit_pos / 8] |= (bit & 1) << (7 - (m_bit_pos % 8));
98+
uint8_t bitVal = (uint8_t)bit & 1;
99+
m_buf[m_bit_pos / 8] |= bitVal << (7 - (m_bit_pos % 8));
99100
m_bit_pos++;
100101
if (m_bit_pos >= (m_buf_size * 8)) {
101102
m_buf_eof = true;

VortexEngine/src/Serial/BitStream.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class BitStream
2424

2525
// read/write a single bit in LSB
2626
uint8_t read1Bit();
27-
void write1Bit(uint8_t bit);
27+
void write1Bit(bool bit);
2828
// read/write multiple bits from left to right at LSB
2929
uint8_t readBits(uint32_t numBits);
3030
void writeBits(uint32_t numBits, uint32_t val);
@@ -34,6 +34,7 @@ class BitStream
3434
bool allocated() const { return m_allocated; }
3535
uint16_t size() const { return m_buf_size; }
3636
const uint8_t *data() const { return m_buf; }
37+
uint8_t peekData(uint8_t pos) const { return m_buf[pos]; }
3738
const uint32_t *dwData() const { return (uint32_t *)m_buf; }
3839
uint16_t dwordpos() const { return m_bit_pos / 32; }
3940
uint16_t bytepos() const { return m_bit_pos / 8; }

VortexEngine/src/Serial/ByteStream.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ class ByteStream
117117
// return the members
118118
const uint8_t *data() const { return m_pData ? m_pData->buf : nullptr; }
119119
void *rawData() const { return m_pData; }
120-
uint32_t rawSize() const { return m_pData ? m_pData->size + sizeof(RawBuffer) : 0; }
120+
uint16_t rawSize() const { return m_pData ? (uint16_t)m_pData->size + sizeof(RawBuffer) : 0; }
121121
uint32_t size() const { return m_pData ? m_pData->size : 0; }
122122
uint32_t capacity() const { return m_capacity; }
123123
bool is_compressed() const;

VortexEngine/src/Storage/Storage.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ std::string Storage::m_storageFilename;
3737
#define STORAGE_FILENAME DEFAULT_STORAGE_FILENAME
3838
#endif
3939

40+
// size of each page of flash
41+
#define FLASH_PAGE_SIZE 128
4042
// The first half of the data goes into the eeprom and then the rest goes into
4143
// flash, the EEPROM is 256 and storage size is 512 so the flash storage is 256
4244
#define FLASH_STORAGE_SIZE (STORAGE_SIZE)
@@ -72,9 +74,6 @@ void Storage::cleanup()
7274
{
7375
}
7476

75-
#define FLASH_PAGE_SIZE 128
76-
77-
7877
// store a serial buffer to storage
7978
bool Storage::write(uint8_t slot, ByteStream &buffer)
8079
{

VortexEngine/src/VortexConfig.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@
290290
// This is the amount of time in ms for the IR receiver to wait
291291
// before reseting itself in the case that communication gets
292292
// interrupted.
293-
#define IR_RECEIVER_TIMEOUT_DURATION 2000
293+
#define IR_RECEIVER_TIMEOUT_DURATION 500
294294

295295
// IR Sender Wait Duration (ms)
296296
//

VortexEngine/src/Wireless/VLConfig.h

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,40 @@
2525
#define VL_THRES_UP (1 + VL_THRESHOLD)
2626
#define VL_THRES_DOWN (1 - VL_THRESHOLD)
2727

28-
#define VL_TIMING (uint32_t)3230
29-
#define VL_TIMING_MIN ((uint32_t)(VL_TIMING * VL_THRES_DOWN))
28+
// These are the modern constants for new sender/receiver in modesharing
29+
// new one is faster, more reliable, and better at error detection
30+
#define VL_TIMING (uint16_t)(2230)
3031

31-
#define VL_HEADER_MARK (uint32_t)(VL_TIMING * 16)
32-
#define VL_HEADER_SPACE (uint32_t)(VL_TIMING * 8)
32+
#define VL_HEADER_MARK (uint16_t)(VL_TIMING * 16)
33+
#define VL_HEADER_SPACE (uint16_t)(VL_TIMING * 8)
3334

34-
#define VL_HEADER_MARK_MIN ((uint32_t)(VL_HEADER_MARK * VL_THRES_DOWN))
35-
#define VL_HEADER_SPACE_MIN ((uint32_t)(VL_HEADER_SPACE * VL_THRES_DOWN))
35+
#define VL_HEADER_MARK_MIN ((uint16_t)(VL_HEADER_MARK * VL_THRES_DOWN))
36+
#define VL_HEADER_SPACE_MIN ((uint16_t)(VL_HEADER_SPACE * VL_THRES_DOWN))
3637

37-
#define VL_HEADER_MARK_MAX ((uint32_t)(VL_HEADER_MARK * VL_THRES_UP))
38-
#define VL_HEADER_SPACE_MAX ((uint32_t)(VL_HEADER_SPACE * VL_THRES_UP))
38+
#define VL_HEADER_MARK_MAX ((uint16_t)(VL_HEADER_MARK * VL_THRES_UP))
39+
#define VL_HEADER_SPACE_MAX ((uint16_t)(VL_HEADER_SPACE * VL_THRES_UP))
40+
41+
#define VL_TIMING_BIT_ONE (uint16_t)(VL_TIMING * 3)
42+
#define VL_TIMING_BIT_ZERO (uint16_t)(VL_TIMING)
43+
#define VL_TIMING_BIT(bit) (bit ? VL_TIMING_BIT_ONE : VL_TIMING_BIT_ZERO)
44+
45+
// legacy constants for old sender/receiver in modesharing, this one is
46+
// less reliable and much slower
47+
#define VL_TIMING_LEGACY (uint16_t)(3230)
48+
49+
#define VL_HEADER_MARK_LEGACY (uint16_t)(VL_TIMING_LEGACY * 16)
50+
#define VL_HEADER_SPACE_LEGACY (uint16_t)(VL_TIMING_LEGACY * 8)
51+
52+
#define VL_HEADER_MARK_MIN_LEGACY ((uint16_t)(VL_HEADER_MARK_LEGACY * VL_THRES_DOWN))
53+
#define VL_HEADER_SPACE_MIN_LEGACY ((uint16_t)(VL_HEADER_SPACE_LEGACY * VL_THRES_DOWN))
54+
55+
#define VL_HEADER_MARK_MAX_LEGACY ((uint16_t)(VL_HEADER_MARK_LEGACY * VL_THRES_UP))
56+
#define VL_HEADER_SPACE_MAX_LEGACY ((uint16_t)(VL_HEADER_SPACE_LEGACY * VL_THRES_UP))
57+
58+
#define VL_TIMING_BIT_ONE_LEGACY (uint16_t)(VL_TIMING_LEGACY * 3)
59+
#define VL_TIMING_BIT_ZERO_LEGACY (uint16_t)(VL_TIMING_LEGACY)
60+
#define VL_TIMING_BIT_LEGACY(bit) (bit ? VL_TIMING_BIT_ONE_LEGACY : VL_TIMING_BIT_ZERO_LEGACY)
3961

40-
#define VL_DIVIDER_SPACE VL_HEADER_MARK
41-
#define VL_DIVIDER_SPACE_MIN VL_HEADER_MARK_MIN
42-
#define VL_DIVIDER_SPACE_MAX VL_HEADER_MARK_MAX
4362

4463
#define VL_SEND_PWM_PIN 0
4564
#define VL_RECEIVER_PIN 0

0 commit comments

Comments
 (0)