Skip to content
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
14 changes: 1 addition & 13 deletions VortexEngine/src/Menus/MenuList/EditorConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,20 +258,8 @@ void EditorConnection::handleState()
case STATE_TRANSMIT_MODE_VL:
#if VL_ENABLE_SENDER == 1
// immediately load the mode and send it now
VLSender::loadMode(&m_previewMode);
VLSender::send();
VLSender::send(&m_previewMode);
#endif
m_state = STATE_TRANSMIT_MODE_VL_TRANSMIT;
break;
case STATE_TRANSMIT_MODE_VL_TRANSMIT:
#if VL_ENABLE_SENDER == 1
// if still sending and the send command indicated more data
if (VLSender::isSending() && VLSender::send()) {
// then continue sending
break;
}
#endif
// othewrise, done, switch to the transmit done state
m_state = STATE_TRANSMIT_MODE_VL_DONE;
break;
case STATE_TRANSMIT_MODE_VL_DONE:
Expand Down
1 change: 0 additions & 1 deletion VortexEngine/src/Menus/MenuList/EditorConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ class EditorConnection : public Menu

// transmit the mode over visible light
STATE_TRANSMIT_MODE_VL,
STATE_TRANSMIT_MODE_VL_TRANSMIT,
STATE_TRANSMIT_MODE_VL_DONE,

// editor pulls the modes from device (safer version)
Expand Down
132 changes: 63 additions & 69 deletions VortexEngine/src/Menus/MenuList/ModeSharing.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "ModeSharing.h"

#include "../../VortexEngine.h"
#include "../../Serial/ByteStream.h"
#include "../../Serial/Serial.h"
#include "../../Time/TimeControl.h"
Expand All @@ -15,28 +16,36 @@

ModeSharing::ModeSharing(const RGBColor &col, bool advanced) :
Menu(col, advanced),
m_sharingMode(ModeShareState::SHARE_RECEIVE),
m_timeOutStartTime(0)
m_sharingMode(ModeShareState::SHARE_SEND_RECEIVE),
m_timeOutStartTime(0),
m_lastPercentChange(0),
m_lastPercent(0)

{
}

ModeSharing::~ModeSharing()
{
VLReceiver::endReceiving();
VortexEngine::toggleForceSleep(true);
}

bool ModeSharing::init()
{
if (!Menu::init()) {
return false;
}
// skip led selection
if (!m_advanced) {
// skip led selection
m_ledSelected = true;
}
// start on receive because it's the more responsive of the two
// the odds of opening receive and then accidentally receiving
// a mode that is being broadcast nearby is completely unlikely
beginReceiving();
VLReceiver::beginReceiving();
// turn off force sleep while using modesharing
VortexEngine::toggleForceSleep(false);
DEBUG_LOG("Entering Mode Sharing");
return true;
}
Expand All @@ -47,20 +56,24 @@ Menu::MenuAction ModeSharing::run()
if (result != MENU_CONTINUE) {
return result;
}
switch (m_sharingMode) {
case ModeShareState::SHARE_SEND:
// render the 'send mode' lights
showSendMode();
// continue sending any data as long as there is more to send
continueSending();
break;
case ModeShareState::SHARE_RECEIVE:
// render the 'receive mode' lights
showReceiveMode();
// load any modes that are received
receiveMode();
break;
if (m_sharingMode == ModeShareState::SHARE_EXIT) {
showExit();
return MENU_CONTINUE;
}
// if the button is held for at least a long click, then continuously send
if (g_pButton->isPressed() && g_pButton->holdDuration() >= CLICK_THRESHOLD) {
// exit is handled above so the only two options are normal or legacy
if (m_sharingMode == ModeShareState::SHARE_SEND_RECEIVE) {
// send normal
VLSender::send(&m_previewMode);
} else {
// send legacy
VLSender::sendLegacy(&m_previewMode);
}
}
// render the 'receive mode' lights whether legacy or not
showReceiveMode();
receiveMode();
return MENU_CONTINUE;
}

Expand All @@ -78,12 +91,21 @@ void ModeSharing::onLedSelected()
// handlers for clicks
void ModeSharing::onShortClick()
{
if (g_pButton->holdDuration() >= CLICK_THRESHOLD) {
return;
}
switch (m_sharingMode) {
case ModeShareState::SHARE_RECEIVE:
// click while on receive -> end receive, start sending
VLReceiver::endReceiving();
beginSending();
DEBUG_LOG("Switched to send mode");
case ModeShareState::SHARE_SEND_RECEIVE:
// stop receiving, send the mode, go back to receiving
VLReceiver::setLegacyReceiver(true);
m_sharingMode = ModeShareState::SHARE_SEND_RECEIVE_LEGACY;
break;
case ModeShareState::SHARE_SEND_RECEIVE_LEGACY:
VLReceiver::setLegacyReceiver(false);
m_sharingMode = ModeShareState::SHARE_EXIT;
break;
case ModeShareState::SHARE_EXIT:
m_sharingMode = ModeShareState::SHARE_SEND_RECEIVE;
break;
default:
break;
Expand All @@ -93,57 +115,30 @@ void ModeSharing::onShortClick()

void ModeSharing::onLongClick()
{
leaveMenu();
}

void ModeSharing::beginSending()
{
// if the sender is sending then cannot start again
if (VLSender::isSending()) {
ERROR_LOG("Cannot begin sending, sender is busy");
return;
}
m_sharingMode = ModeShareState::SHARE_SEND;
// initialize it with the current mode data
VLSender::loadMode(&m_previewMode);
// send the first chunk of data, leave if we're done
if (!VLSender::send()) {
// when send has completed, stores time that last action was completed to calculate interval between sends
beginReceiving();
if (m_sharingMode == ModeShareState::SHARE_EXIT) {
leaveMenu();
}
}

void ModeSharing::continueSending()
{
// if the sender isn't sending then nothing to do
if (!VLSender::isSending()) {
return;
}
if (!VLSender::send()) {
// when send has completed, stores time that last action was completed to calculate interval between sends
beginReceiving();
}
}

void ModeSharing::beginReceiving()
{
m_sharingMode = ModeShareState::SHARE_RECEIVE;
VLReceiver::beginReceiving();
}

void ModeSharing::receiveMode()
{
uint32_t now = Time::getCurtime();
// if reveiving new data set our last data time
if (VLReceiver::onNewData()) {
m_timeOutStartTime = Time::getCurtime();
m_timeOutStartTime = now;
// if our last data was more than time out duration reset the recveiver
} else if (m_timeOutStartTime > 0 && (m_timeOutStartTime + MAX_TIMEOUT_DURATION) < Time::getCurtime()) {
} else if (m_timeOutStartTime > 0 && (m_timeOutStartTime + MAX_TIMEOUT_DURATION) < now) {
VLReceiver::resetVLState();
m_timeOutStartTime = 0;
return;
}
// check if the VLReceiver has a full packet available
if (!VLReceiver::dataReady()) {
uint8_t percent = VLReceiver::percentReceived();
if (percent != m_lastPercent) {
m_lastPercent = percent;
m_lastPercentChange = now;
}
// nothing available yet
return;
}
Expand All @@ -170,21 +165,20 @@ void ModeSharing::receiveMode()
leaveMenu(true);
}

void ModeSharing::showSendMode()
{
// show a dim color when not sending
if (!VLSender::isSending()) {
Leds::setAll(RGBColor(0, 20, 20));
}
}

void ModeSharing::showReceiveMode()
{
// if the receiver is actively receiving right now then
if (VLReceiver::isReceiving()) {
// using uint32_t to avoid overflow, the result should be within 10 to 255
Leds::setIndex(LED_0, RGBColor(0, VLReceiver::percentReceived(), 0));
uint32_t diff = (Time::getCurtime() - m_lastPercentChange);
// this generates the red flash when the receiver hasn't received something for
// some amount of time, 100 is just arbitray idk if it could be a better value
if (diff > 100) {
Leds::setIndex(LED_0, RGB_RED3);
} else {
Leds::setIndex(LED_0, RGBColor(0, VLReceiver::percentReceived(), 0));
}
Leds::clearIndex(LED_1);
} else {
Leds::setAll(RGB_WHITE0);
Leds::setAll((m_sharingMode == ModeShareState::SHARE_SEND_RECEIVE) ? 0x000F05 : RGB_WHITE0);
}
}
16 changes: 9 additions & 7 deletions VortexEngine/src/Menus/MenuList/ModeSharing.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,25 @@ class ModeSharing : public Menu
void onLongClick() override;

private:
void beginSending();
void continueSending();
void beginReceiving();
void receiveMode();

void showSendMode();
void showReceiveMode();

enum class ModeShareState {
SHARE_SEND, // send mode
SHARE_RECEIVE, // receive mode
// these three are the main options that can be iterated through
// and if the button is held it will send, otherwise receive
SHARE_SEND_RECEIVE, // send/receive mode
SHARE_SEND_RECEIVE_LEGACY, // send/receive mode legacy
SHARE_EXIT, // exit mode sharing
};

ModeShareState m_sharingMode;

// the start time when checking for timing out
uint32_t m_timeOutStartTime;

// used to track when the receive percentage changes for timeout purposes
uint32_t m_lastPercentChange;
uint8_t m_lastPercent;
};

#endif
5 changes: 3 additions & 2 deletions VortexEngine/src/Serial/BitStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ uint8_t BitStream::read1Bit()
return rv;
}

void BitStream::write1Bit(uint8_t bit)
void BitStream::write1Bit(bool bit)
{
if (m_buf_eof) {
return;
Expand All @@ -95,7 +95,8 @@ void BitStream::write1Bit(uint8_t bit)
m_buf_eof = true;
return;
}
m_buf[m_bit_pos / 8] |= (bit & 1) << (7 - (m_bit_pos % 8));
uint8_t bitVal = (uint8_t)bit & 1;
m_buf[m_bit_pos / 8] |= bitVal << (7 - (m_bit_pos % 8));
m_bit_pos++;
if (m_bit_pos >= (m_buf_size * 8)) {
m_buf_eof = true;
Expand Down
3 changes: 2 additions & 1 deletion VortexEngine/src/Serial/BitStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class BitStream

// read/write a single bit in LSB
uint8_t read1Bit();
void write1Bit(uint8_t bit);
void write1Bit(bool bit);
// read/write multiple bits from left to right at LSB
uint8_t readBits(uint32_t numBits);
void writeBits(uint32_t numBits, uint32_t val);
Expand All @@ -34,6 +34,7 @@ class BitStream
bool allocated() const { return m_allocated; }
uint16_t size() const { return m_buf_size; }
const uint8_t *data() const { return m_buf; }
uint8_t peekData(uint8_t pos) const { return m_buf[pos]; }
const uint32_t *dwData() const { return (uint32_t *)m_buf; }
uint16_t dwordpos() const { return m_bit_pos / 32; }
uint16_t bytepos() const { return m_bit_pos / 8; }
Expand Down
2 changes: 1 addition & 1 deletion VortexEngine/src/Serial/ByteStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ class ByteStream
// return the members
const uint8_t *data() const { return m_pData ? m_pData->buf : nullptr; }
void *rawData() const { return m_pData; }
uint32_t rawSize() const { return m_pData ? m_pData->size + sizeof(RawBuffer) : 0; }
uint16_t rawSize() const { return m_pData ? (uint16_t)m_pData->size + sizeof(RawBuffer) : 0; }
uint32_t size() const { return m_pData ? m_pData->size : 0; }
uint32_t capacity() const { return m_capacity; }
bool is_compressed() const;
Expand Down
5 changes: 2 additions & 3 deletions VortexEngine/src/Storage/Storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ std::string Storage::m_storageFilename;
#define STORAGE_FILENAME DEFAULT_STORAGE_FILENAME
#endif

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

#define FLASH_PAGE_SIZE 128


// store a serial buffer to storage
bool Storage::write(uint8_t slot, ByteStream &buffer)
{
Expand Down
2 changes: 1 addition & 1 deletion VortexEngine/src/VortexConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@
// This is the amount of time in ms for the IR receiver to wait
// before reseting itself in the case that communication gets
// interrupted.
#define IR_RECEIVER_TIMEOUT_DURATION 2000
#define IR_RECEIVER_TIMEOUT_DURATION 500

// IR Sender Wait Duration (ms)
//
Expand Down
41 changes: 30 additions & 11 deletions VortexEngine/src/Wireless/VLConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,40 @@
#define VL_THRES_UP (1 + VL_THRESHOLD)
#define VL_THRES_DOWN (1 - VL_THRESHOLD)

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

#define VL_HEADER_MARK (uint32_t)(VL_TIMING * 16)
#define VL_HEADER_SPACE (uint32_t)(VL_TIMING * 8)
#define VL_HEADER_MARK (uint16_t)(VL_TIMING * 16)
#define VL_HEADER_SPACE (uint16_t)(VL_TIMING * 8)

#define VL_HEADER_MARK_MIN ((uint32_t)(VL_HEADER_MARK * VL_THRES_DOWN))
#define VL_HEADER_SPACE_MIN ((uint32_t)(VL_HEADER_SPACE * VL_THRES_DOWN))
#define VL_HEADER_MARK_MIN ((uint16_t)(VL_HEADER_MARK * VL_THRES_DOWN))
#define VL_HEADER_SPACE_MIN ((uint16_t)(VL_HEADER_SPACE * VL_THRES_DOWN))

#define VL_HEADER_MARK_MAX ((uint32_t)(VL_HEADER_MARK * VL_THRES_UP))
#define VL_HEADER_SPACE_MAX ((uint32_t)(VL_HEADER_SPACE * VL_THRES_UP))
#define VL_HEADER_MARK_MAX ((uint16_t)(VL_HEADER_MARK * VL_THRES_UP))
#define VL_HEADER_SPACE_MAX ((uint16_t)(VL_HEADER_SPACE * VL_THRES_UP))

#define VL_TIMING_BIT_ONE (uint16_t)(VL_TIMING * 3)
#define VL_TIMING_BIT_ZERO (uint16_t)(VL_TIMING)
#define VL_TIMING_BIT(bit) (bit ? VL_TIMING_BIT_ONE : VL_TIMING_BIT_ZERO)

// legacy constants for old sender/receiver in modesharing, this one is
// less reliable and much slower
#define VL_TIMING_LEGACY (uint16_t)(3230)

#define VL_HEADER_MARK_LEGACY (uint16_t)(VL_TIMING_LEGACY * 16)
#define VL_HEADER_SPACE_LEGACY (uint16_t)(VL_TIMING_LEGACY * 8)

#define VL_HEADER_MARK_MIN_LEGACY ((uint16_t)(VL_HEADER_MARK_LEGACY * VL_THRES_DOWN))
#define VL_HEADER_SPACE_MIN_LEGACY ((uint16_t)(VL_HEADER_SPACE_LEGACY * VL_THRES_DOWN))

#define VL_HEADER_MARK_MAX_LEGACY ((uint16_t)(VL_HEADER_MARK_LEGACY * VL_THRES_UP))
#define VL_HEADER_SPACE_MAX_LEGACY ((uint16_t)(VL_HEADER_SPACE_LEGACY * VL_THRES_UP))

#define VL_TIMING_BIT_ONE_LEGACY (uint16_t)(VL_TIMING_LEGACY * 3)
#define VL_TIMING_BIT_ZERO_LEGACY (uint16_t)(VL_TIMING_LEGACY)
#define VL_TIMING_BIT_LEGACY(bit) (bit ? VL_TIMING_BIT_ONE_LEGACY : VL_TIMING_BIT_ZERO_LEGACY)

#define VL_DIVIDER_SPACE VL_HEADER_MARK
#define VL_DIVIDER_SPACE_MIN VL_HEADER_MARK_MIN
#define VL_DIVIDER_SPACE_MAX VL_HEADER_MARK_MAX

#define VL_SEND_PWM_PIN 0
#define VL_RECEIVER_PIN 0
Expand Down
Loading