diff --git a/VortexEngine/src/Menus/MenuList/ModeSharing.cpp b/VortexEngine/src/Menus/MenuList/ModeSharing.cpp index e3391c1df2..1906e4c573 100644 --- a/VortexEngine/src/Menus/MenuList/ModeSharing.cpp +++ b/VortexEngine/src/Menus/MenuList/ModeSharing.cpp @@ -4,8 +4,9 @@ #include "../../Serial/Serial.h" #include "../../Time/TimeControl.h" #include "../../Time/Timings.h" -#include "../../Wireless/IRReceiver.h" +#include "../../Wireless/VLReceiver.h" #include "../../Wireless/VLSender.h" +#include "../../Wireless/IRReceiver.h" #include "../../Wireless/IRSender.h" #include "../../Buttons/Button.h" #include "../../Modes/Modes.h" @@ -15,8 +16,10 @@ ModeSharing::ModeSharing(const RGBColor &col, bool advanced) : Menu(col, advanced), - m_sharingMode(ModeShareState::SHARE_RECEIVE), - m_timeOutStartTime(0) + m_sharingMode(ModeShareState::SHARE_RECEIVE_VL), + m_timeOutStartTime(0), + m_lastSendTime(0), + m_shouldEndSend(false) { } @@ -34,7 +37,7 @@ bool ModeSharing::init() // 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 - beginReceivingIR(); + beginReceivingVL(); DEBUG_LOG("Entering Mode Sharing"); return true; } @@ -46,11 +49,11 @@ Menu::MenuAction ModeSharing::run() return result; } switch (m_sharingMode) { - case ModeShareState::SHARE_SEND_IR: - // render the 'send mode' lights - showSendModeIR(); - // continue sending any data as long as there is more to send - continueSendingIR(); + case ModeShareState::SHARE_RECEIVE_VL: + // render the 'receive mode' lights + showReceiveModeVL(); + // load any modes that are received + receiveModeVL(); break; case ModeShareState::SHARE_SEND_VL: // render the 'send mode' lights @@ -58,25 +61,42 @@ Menu::MenuAction ModeSharing::run() // continue sending any data as long as there is more to send continueSendingVL(); break; - case ModeShareState::SHARE_RECEIVE: + case ModeShareState::SHARE_RECEIVE_IR: // render the 'receive mode' lights - showReceiveMode(); + showReceiveModeIR(); // load any modes that are received receiveModeIR(); break; + case ModeShareState::SHARE_SEND_IR: + // render the 'send mode' lights + showSendModeIR(); + // continue sending any data as long as there is more to send + continueSendingIR(); + break; } return MENU_CONTINUE; } // handlers for clicks -void ModeSharing::onShortClick() +void ModeSharing::onShortClickM() { switch (m_sharingMode) { - case ModeShareState::SHARE_RECEIVE: + case ModeShareState::SHARE_RECEIVE_VL: // click while on receive -> end receive, start sending - IRReceiver::endReceiving(); - beginSendingIR(); - DEBUG_LOG("Switched to send mode"); + VLReceiver::endReceiving(); + beginSendingVL(); + DEBUG_LOG("Switched to send VL"); + break; + case ModeShareState::SHARE_RECEIVE_IR: + if (!IRSender::isSending()) { + beginSendingIR(); + DEBUG_LOG("Switched to send IR"); + } else { + m_shouldEndSend = true; + } + break; + case ModeShareState::SHARE_SEND_IR: + m_shouldEndSend = true; break; default: break; @@ -84,27 +104,38 @@ void ModeSharing::onShortClick() Leds::clearAll(); } -void ModeSharing::onLongClick() +// handlers for clicks +void ModeSharing::onShortClickL() { - Modes::updateCurMode(&m_previewMode); - leaveMenu(true); + switchVLIR(); } -void ModeSharing::beginSendingVL() +void ModeSharing::onShortClickR() { - // 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_VL; - // initialize it with the current mode data - VLSender::loadMode(Modes::curMode()); - // 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 + switchVLIR(); +} + +void ModeSharing::switchVLIR() +{ + switch (m_sharingMode) { + case ModeShareState::SHARE_RECEIVE_VL: + VLReceiver::endReceiving(); beginReceivingIR(); + break; + case ModeShareState::SHARE_RECEIVE_IR: + IRReceiver::endReceiving(); + beginReceivingVL(); + break; + default: + break; } + Leds::clearAll(); +} + +void ModeSharing::onLongClickM() +{ + Modes::updateCurMode(&m_previewMode); + leaveMenu(true); } void ModeSharing::beginSendingIR() @@ -115,47 +146,47 @@ void ModeSharing::beginSendingIR() return; } m_sharingMode = ModeShareState::SHARE_SEND_IR; + Leds::clearAll(); + Leds::update(); // initialize it with the current mode data IRSender::loadMode(Modes::curMode()); // send the first chunk of data, leave if we're done if (!IRSender::send()) { - // when send has completed, stores time that last action was completed to calculate interval between sends - beginReceivingIR(); - } -} - -void ModeSharing::continueSendingVL() -{ - // 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 - beginReceivingIR(); + // just set the last time and wait + m_lastSendTime = Time::getCurtime(); } + DEBUG_LOG("Switched to sending IR"); } void ModeSharing::continueSendingIR() { // if the sender isn't sending then nothing to do if (!IRSender::isSending()) { + if (m_lastSendTime && m_lastSendTime < (Time::getCurtime() + MS_TO_TICKS(350))) { + if (m_shouldEndSend) { + beginReceivingIR(); + m_shouldEndSend = false; + } else { + beginSendingIR(); + } + } return; } if (!IRSender::send()) { - // when send has completed, stores time that last action was completed to calculate interval between sends - beginReceivingIR(); + // just set the last time and wait + m_lastSendTime = Time::getCurtime(); } } void ModeSharing::beginReceivingIR() { - m_sharingMode = ModeShareState::SHARE_RECEIVE; + m_sharingMode = ModeShareState::SHARE_RECEIVE_IR; IRReceiver::beginReceiving(); + DEBUG_LOG("Switched to receiving IR"); } void ModeSharing::receiveModeIR() -{ + { // if reveiving new data set our last data time if (IRReceiver::onNewData()) { m_timeOutStartTime = Time::getCurtime(); @@ -184,6 +215,73 @@ void ModeSharing::receiveModeIR() } } +void ModeSharing::beginSendingVL() +{ + // 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_VL; + // initialize it with the current mode data + VLSender::loadMode(Modes::curMode()); + // 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 + beginReceivingVL(); + } + DEBUG_LOG("Switched to sending VL"); +} + +void ModeSharing::continueSendingVL() +{ + // 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 + beginReceivingVL(); + } +} + +void ModeSharing::beginReceivingVL() +{ + m_sharingMode = ModeShareState::SHARE_RECEIVE_VL; + VLReceiver::beginReceiving(); + DEBUG_LOG("Switched to receiving VL"); +} + +void ModeSharing::receiveModeVL() +{ + // if reveiving new data set our last data time + if (VLReceiver::onNewData()) { + m_timeOutStartTime = Time::getCurtime(); + // 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()) { + VLReceiver::resetVLState(); + m_timeOutStartTime = 0; + return; + } + // check if the VLReceiver has a full packet available + if (!VLReceiver::dataReady()) { + // nothing available yet + return; + } + DEBUG_LOG("Mode ready to receive! Receiving..."); + // receive the VL mode into the current mode + if (!VLReceiver::receiveMode(&m_previewMode)) { + ERROR_LOG("Failed to receive mode"); + return; + } + DEBUG_LOGF("Success receiving mode: %u", m_previewMode.getPatternID()); + if (!m_advanced) { + Modes::updateCurMode(&m_previewMode); + // leave menu and save settings, even if the mode was the same whatever + leaveMenu(true); + } +} + void ModeSharing::showSendModeVL() { // show a dim color when not sending @@ -193,19 +291,36 @@ void ModeSharing::showSendModeVL() void ModeSharing::showSendModeIR() { // show a dim color when not sending - Leds::clearAll(); + Leds::setAll(RGB_CYAN5); + Leds::setAllEvens(RGB_CYAN0); +} + +void ModeSharing::showReceiveModeVL() +{ + if (VLReceiver::isReceiving()) { + // using uint32_t to avoid overflow, the result should be within 10 to 255 + Leds::clearAll(); + Leds::setRange(LED_FIRST, (LedPos)(VLReceiver::percentReceived() / 10), RGBColor(0, 1, 0)); + } else { + if (m_advanced) { + m_previewMode.play(); + } else { + Leds::setAll(0x010101); + } + } } -void ModeSharing::showReceiveMode() +void ModeSharing::showReceiveModeIR() { - if (IRReceiver::isReceiving()) { + if (VLReceiver::isReceiving()) { // using uint32_t to avoid overflow, the result should be within 10 to 255 - Leds::setAll(RGBColor(0, IRReceiver::percentReceived(), 0)); + Leds::clearAll(); + Leds::setRange(LED_FIRST, (LedPos)(VLReceiver::percentReceived() / 10), RGBColor(0, 1, 0)); } else { if (m_advanced) { m_previewMode.play(); } else { - Leds::setAll(RGB_WHITE0); + Leds::setAll(RGB_CYAN0); } } } diff --git a/VortexEngine/src/Menus/MenuList/ModeSharing.h b/VortexEngine/src/Menus/MenuList/ModeSharing.h index dc5adf2357..ed15e7c8af 100644 --- a/VortexEngine/src/Menus/MenuList/ModeSharing.h +++ b/VortexEngine/src/Menus/MenuList/ModeSharing.h @@ -13,31 +13,44 @@ class ModeSharing : public Menu MenuAction run() override; // handlers for clicks - void onShortClick() override; - void onLongClick() override; + void onShortClickM() override; + void onShortClickL() override; + void onShortClickR() override; + void onLongClickM() override; private: void beginSendingVL(); - void beginSendingIR(); void continueSendingVL(); + void beginReceivingVL(); + void receiveModeVL(); + + void beginSendingIR(); void continueSendingIR(); void beginReceivingIR(); void receiveModeIR(); void showSendModeVL(); void showSendModeIR(); - void showReceiveMode(); + void showReceiveModeVL(); + void showReceiveModeIR(); + + void switchVLIR(); enum class ModeShareState { - SHARE_SEND_IR, // send mode over ir - SHARE_SEND_VL, // send mode over vl - SHARE_RECEIVE, // receive mode + SHARE_RECEIVE_VL, + SHARE_SEND_VL, + SHARE_RECEIVE_IR, + SHARE_SEND_IR, }; ModeShareState m_sharingMode; // the start time when checking for timing out uint32_t m_timeOutStartTime; + uint32_t m_lastSendTime; + + // whether to end the next send and go back to receive + bool m_shouldEndSend; }; #endif diff --git a/VortexEngine/src/Wireless/IRReceiver.cpp b/VortexEngine/src/Wireless/IRReceiver.cpp index 47ec50ef4d..0190d52e8a 100644 --- a/VortexEngine/src/Wireless/IRReceiver.cpp +++ b/VortexEngine/src/Wireless/IRReceiver.cpp @@ -9,6 +9,10 @@ #include "../Modes/Mode.h" #include "../Log/Log.h" +#ifdef VORTEX_EMBEDDED +#include +#endif + BitStream IRReceiver::m_irData; IRReceiver::RecvState IRReceiver::m_recvState = WAITING_HEADER_MARK; uint32_t IRReceiver::m_prevTime = 0; @@ -17,6 +21,9 @@ uint32_t IRReceiver::m_previousBytes = 0; bool IRReceiver::init() { +#ifdef VORTEX_EMBEDDED + pinMode(IR_RECEIVER_PIN, INPUT_PULLUP); +#endif m_irData.init(IR_RECV_BUF_SIZE); return true; } @@ -83,12 +90,18 @@ bool IRReceiver::receiveMode(Mode *pMode) bool IRReceiver::beginReceiving() { +#ifdef VORTEX_EMBEDDED + attachInterrupt(digitalPinToInterrupt(IR_RECEIVER_PIN), IRReceiver::recvPCIHandler, CHANGE); +#endif resetIRState(); return true; } bool IRReceiver::endReceiving() { +#ifdef VORTEX_EMBEDDED + detachInterrupt(digitalPinToInterrupt(IR_RECEIVER_PIN)); +#endif resetIRState(); return true; } @@ -138,7 +151,7 @@ void IRReceiver::recvPCIHandler() // check previous time for validity if (!m_prevTime || m_prevTime > now) { m_prevTime = now; - DEBUG_LOG("Bad first time diff, resetting..."); + //DEBUG_LOG("Bad first time diff, resetting..."); resetIRState(); return; } @@ -155,7 +168,7 @@ void IRReceiver::handleIRTiming(uint32_t diff) { // if the diff is too long or too short then it's not useful if ((diff > IR_HEADER_MARK_MAX && m_recvState < READING_DATA_MARK) || diff < IR_TIMING_MIN) { - DEBUG_LOGF("bad delay: %u, resetting...", diff); + //DEBUG_LOGF("bad delay: %u, resetting...", diff); resetIRState(); return; } @@ -164,7 +177,7 @@ void IRReceiver::handleIRTiming(uint32_t diff) if (diff >= IR_HEADER_MARK_MIN && diff <= IR_HEADER_MARK_MAX) { m_recvState = WAITING_HEADER_SPACE; } else { - DEBUG_LOGF("Bad header mark %u, resetting...", diff); + //DEBUG_LOGF("Bad header mark %u, resetting...", diff); resetIRState(); } break; @@ -172,7 +185,7 @@ void IRReceiver::handleIRTiming(uint32_t diff) if (diff >= IR_HEADER_SPACE_MIN && diff <= IR_HEADER_SPACE_MAX) { m_recvState = READING_DATA_MARK; } else { - DEBUG_LOGF("Bad header space %u, resetting...", diff); + //DEBUG_LOGF("Bad header space %u, resetting...", diff); resetIRState(); } break; @@ -186,7 +199,7 @@ void IRReceiver::handleIRTiming(uint32_t diff) m_recvState = READING_DATA_MARK; break; default: // ?? - DEBUG_LOGF("Bad receive state: %u", m_recvState); + //DEBUG_LOGF("Bad receive state: %u", m_recvState); break; } } @@ -197,7 +210,7 @@ void IRReceiver::resetIRState() m_recvState = WAITING_HEADER_MARK; // zero out the receive buffer and reset bit receiver position m_irData.reset(); - DEBUG_LOG("IR State Reset"); + //DEBUG_LOG("IR State Reset"); } #endif diff --git a/VortexEngine/src/Wireless/IRSender.cpp b/VortexEngine/src/Wireless/IRSender.cpp index 1d127a1978..b211680d4a 100644 --- a/VortexEngine/src/Wireless/IRSender.cpp +++ b/VortexEngine/src/Wireless/IRSender.cpp @@ -11,6 +11,10 @@ #include "VortexLib.h" #endif +#ifdef VORTEX_EMBEDDED +#include +#endif + // the serial buffer for the data ByteStream IRSender::m_serialBuf; // a bit walker for the serial data @@ -32,6 +36,9 @@ uint32_t IRSender::m_writeCounter = 0; bool IRSender::init() { +#ifdef VORTEX_EMBEDDED + initPWM(); +#endif return true; } @@ -144,6 +151,9 @@ void IRSender::sendMark(uint16_t time) #ifdef VORTEX_LIB // send mark timing over socket Vortex::vcallbacks()->infraredWrite(true, time); +#else + startPWM(); + Time::delayMicroseconds(time); #endif } @@ -152,7 +162,34 @@ void IRSender::sendSpace(uint16_t time) #ifdef VORTEX_LIB // send space timing over socket Vortex::vcallbacks()->infraredWrite(false, time); +#else + stopPWM(); + Time::delayMicroseconds(time); #endif } +#ifdef VORTEX_EMBEDDED +const uint32_t pwmFrequency = 39062; // Actual frequency with divider = 8 +const uint8_t pwmResolution = 8; +const uint32_t pwmDutyCycle = 85; + +void IRSender::initPWM() +{ + // Configure the PWM on the specified pin with initial duty cycle of 0 + ledcAttach(IR_SEND_PWM_PIN, pwmFrequency, pwmResolution); +} + +void IRSender::startPWM() +{ + // Start PWM with the specified duty cycle + ledcWrite(IR_SEND_PWM_PIN, pwmDutyCycle); +} + +void IRSender::stopPWM() +{ + // Stop PWM by setting the duty cycle to 0 + ledcWrite(IR_SEND_PWM_PIN, 0); +} +#endif + #endif diff --git a/VortexEngine/src/Wireless/IRSender.h b/VortexEngine/src/Wireless/IRSender.h index 8f65fa7048..2b2048ffad 100644 --- a/VortexEngine/src/Wireless/IRSender.h +++ b/VortexEngine/src/Wireless/IRSender.h @@ -27,6 +27,12 @@ class IRSender static uint32_t percentDone() { return (uint32_t)(((float)m_writeCounter / (float)m_size) * 100.0); } private: +#ifdef VORTEX_EMBEDDED + static void initPWM(); + static void startPWM(); + static void stopPWM(); +#endif + // sender functions static void beginSend(); // send a full 8 bits in a tight loop diff --git a/VortexEngine/src/Wireless/VLReceiver.cpp b/VortexEngine/src/Wireless/VLReceiver.cpp index 8d2f12a9a1..aa6c9cab2d 100644 --- a/VortexEngine/src/Wireless/VLReceiver.cpp +++ b/VortexEngine/src/Wireless/VLReceiver.cpp @@ -16,8 +16,57 @@ uint32_t VLReceiver::m_prevTime = 0; uint8_t VLReceiver::m_pinState = 0; uint32_t VLReceiver::m_previousBytes = 0; +#ifdef VORTEX_EMBEDDED +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "driver/adc.h" +#include "esp_adc_cal.h" +#include "esp_log.h" +#include "esp_timer.h" + +#include "../Serial/Serial.h" + +// ADC and timer configuration +#define ADC_CHANNEL ADC1_CHANNEL_1 // Update this based on the actual ADC channel used +#define ADC_ATTEN ADC_ATTEN_DB_0 +#define ADC_WIDTH ADC_WIDTH_BIT_12 +#define TIMER_INTERVAL_MICRO_SEC 1000 // Check every 10ms, adjust as needed for your application + +// Timer handle as a global variable for control in beginReceiving and endReceiving +esp_timer_handle_t periodic_timer = nullptr; +esp_adc_cal_characteristics_t adc_chars; + +#define MIN_THRESHOLD 200 +#define BASE_OFFSET 100 +#define THRESHOLD_BEGIN (MIN_THRESHOLD + BASE_OFFSET) +// the threshold needs to start high then it will be automatically pulled down +uint32_t threshold = THRESHOLD_BEGIN; +void VLReceiver::adcCheckTimerCallback(void *arg) +{ + static bool wasAboveThreshold = false; + uint32_t raw = adc1_get_raw(ADC_CHANNEL); + uint32_t val = esp_adc_cal_raw_to_voltage(raw, &adc_chars); + + if (val > MIN_THRESHOLD && val < (threshold + BASE_OFFSET)) { + threshold = val + BASE_OFFSET; + } + bool isAboveThreshold = (val > threshold); + if (wasAboveThreshold != isAboveThreshold) { + wasAboveThreshold = isAboveThreshold; + VLReceiver::recvPCIHandler(); + } +} +#endif + bool VLReceiver::init() { +#ifdef VORTEX_EMBEDDED + // Initialize ADC for GPIO1 (or appropriate pin connected to your light sensor) + adc1_config_width(ADC_WIDTH); + adc1_config_channel_atten(ADC_CHANNEL, ADC_ATTEN); + memset(&adc_chars, 0, sizeof(adc_chars)); + esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN, ADC_WIDTH, 0, &adc_chars); +#endif return m_vlData.init(VL_RECV_BUF_SIZE); } @@ -83,12 +132,36 @@ bool VLReceiver::receiveMode(Mode *pMode) bool VLReceiver::beginReceiving() { +#ifdef VORTEX_EMBEDDED + if (periodic_timer) { + DEBUG_LOG("VL Reception already running."); + return false; // Timer is already running + } + // Initialize timer for periodic ADC checks + const esp_timer_create_args_t periodic_timer_args = { + .callback = &VLReceiver::adcCheckTimerCallback, + .name = "adc_check_timer", + }; + ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &periodic_timer)); + ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, TIMER_INTERVAL_MICRO_SEC)); +#endif resetVLState(); return true; } bool VLReceiver::endReceiving() { +#ifdef VORTEX_EMBEDDED + if (periodic_timer == nullptr) { + DEBUG_LOG("VL Reception was not running."); + return false; // Timer was not running + } + // Stop and delete the timer + ESP_ERROR_CHECK(esp_timer_stop(periodic_timer)); + ESP_ERROR_CHECK(esp_timer_delete(periodic_timer)); + periodic_timer = nullptr; + DEBUG_LOG("VL Reception stopped."); +#endif resetVLState(); return true; } @@ -138,10 +211,11 @@ void VLReceiver::recvPCIHandler() // check previous time for validity if (!m_prevTime || m_prevTime > now) { m_prevTime = now; - DEBUG_LOG("Bad first time diff, resetting..."); + //DEBUG_LOG("Bad first time diff, resetting..."); resetVLState(); return; } + //DEBUG_LOGF("Received: %u", m_pinState); // calc time difference between previous change and now uint32_t diff = (uint32_t)(now - m_prevTime); // and update the previous changetime for next loop @@ -155,7 +229,7 @@ void VLReceiver::handleVLTiming(uint32_t diff) { // if the diff is too long or too short then it's not useful if ((diff > VL_HEADER_MARK_MAX && m_recvState < READING_DATA_MARK) || diff < VL_TIMING_MIN) { - DEBUG_LOGF("bad delay: %u, resetting...", diff); + //DEBUG_LOGF("bad delay: %u, resetting...", diff); resetVLState(); return; } @@ -164,7 +238,7 @@ void VLReceiver::handleVLTiming(uint32_t diff) if (diff >= VL_HEADER_SPACE_MIN && diff <= VL_HEADER_MARK_MAX) { m_recvState = WAITING_HEADER_SPACE; } else { - DEBUG_LOGF("Bad header mark %u, resetting...", diff); + //DEBUG_LOGF("Bad header mark %u, resetting...", diff); resetVLState(); } break; @@ -172,7 +246,7 @@ void VLReceiver::handleVLTiming(uint32_t diff) if (diff >= VL_HEADER_SPACE_MIN && diff <= VL_HEADER_MARK_MAX) { m_recvState = READING_DATA_MARK; } else { - DEBUG_LOGF("Bad header space %u, resetting...", diff); + //DEBUG_LOGF("Bad header space %u, resetting...", diff); resetVLState(); } break; @@ -186,7 +260,7 @@ void VLReceiver::handleVLTiming(uint32_t diff) m_recvState = READING_DATA_MARK; break; default: // ?? - DEBUG_LOGF("Bad receive state: %u", m_recvState); + //DEBUG_LOGF("Bad receive state: %u", m_recvState); break; } } @@ -197,7 +271,7 @@ void VLReceiver::resetVLState() m_recvState = WAITING_HEADER_MARK; // zero out the receive buffer and reset bit receiver position m_vlData.reset(); - DEBUG_LOG("VL State Reset"); + //DEBUG_LOG("VL State Reset"); } #endif diff --git a/VortexEngine/src/Wireless/VLReceiver.h b/VortexEngine/src/Wireless/VLReceiver.h index be4b0a68b5..1d7d35628b 100644 --- a/VortexEngine/src/Wireless/VLReceiver.h +++ b/VortexEngine/src/Wireless/VLReceiver.h @@ -9,6 +9,10 @@ #if VL_ENABLE_RECEIVER == 1 +#ifdef VORTEX_EMBEDDED +#include +#endif + class ByteStream; class Mode; @@ -73,6 +77,10 @@ class VLReceiver // used to compare if received data has changed since last checking static uint32_t m_previousBytes; +#ifdef VORTEX_EMBEDDED + static void adcCheckTimerCallback(void *arg); +#endif + #ifdef VORTEX_LIB friend class Vortex; #endif