From 15f9f0697163b2b450acbdefb9db402094dcb12f Mon Sep 17 00:00:00 2001 From: scilor Date: Thu, 5 May 2022 20:02:05 +0200 Subject: [PATCH 01/16] add missing break to WiFi::loop() --- WrapperWiFi.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/WrapperWiFi.cpp b/WrapperWiFi.cpp index ea94f39..63c47bf 100755 --- a/WrapperWiFi.cpp +++ b/WrapperWiFi.cpp @@ -57,6 +57,7 @@ void WrapperWiFi::loop() { Events.handleWiFiEvent(_state); setInterval(5000); } + break; case ConnectionState::CONNECTED: if (WiFi.status() != WL_CONNECTED) { _state = ConnectionState::DISCONNECTED; From c5da3dd36e98eade6d34b345ee497cebf3e77242 Mon Sep 17 00:00:00 2001 From: scilor Date: Thu, 5 May 2022 20:06:43 +0200 Subject: [PATCH 02/16] Use new ADC value, remove adc factor for charger, adjust config values --- BoxBattery.cpp | 20 ++++++++++---------- BoxBattery.h | 4 +++- BoxConfig.cpp | 14 +++++++++----- ConfigStructures.h | 4 ++-- 4 files changed, 24 insertions(+), 18 deletions(-) diff --git a/BoxBattery.cpp b/BoxBattery.cpp index d9bc126..c4365b7 100644 --- a/BoxBattery.cpp +++ b/BoxBattery.cpp @@ -8,8 +8,7 @@ void BoxBattery::begin() { _wasLow = false; _wasCritical = false; - _batteryAdcRaw = analogRead(60); - _batteryAdcLowRaw = 9999; + _readBatteryAdc(); batteryTestThread.setInterval(10*60*1000); batteryTestThread.enabled = false; @@ -17,10 +16,10 @@ void BoxBattery::begin() { loop(); logBatteryStatus(); - setInterval(500); + setInterval(100); } void BoxBattery::loop() { - _batteryAdcRaw = analogRead(60); + _readBatteryAdc(); _charger.read(); if (_batteryAdcRaw < _batteryAdcLowRaw || isChargerConnected()) @@ -46,6 +45,11 @@ void BoxBattery::loop() { } } +void BoxBattery::_readBatteryAdc() { + uint16_t adcValue = analogReadAvg(BATTERY_VOLTAGE_PIN, 1); + _batteryAdcRaw = adcValue; +} + bool BoxBattery::isChargerConnected() { if (_charger.isPressed()) return true; @@ -55,10 +59,7 @@ uint16_t BoxBattery::getBatteryAdcRaw() { return _batteryAdcRaw; } uint16_t BoxBattery::getBatteryVoltage() { - if (isChargerConnected()) { - return 10000 * getBatteryAdcRaw() / _batteryVoltageChargerFactor; - } - return 10000 * getBatteryAdcRaw() / _batteryVoltageFactor; + return 1000 * getBatteryAdcRaw() / _batteryVoltageFactor; } bool BoxBattery::isBatteryLow() { if (getBatteryAdcRaw() < _batteryLowAdc) @@ -88,7 +89,6 @@ void BoxBattery::reloadConfig() { ConfigStruct* config = Config.get(); _batteryVoltageFactor = config->battery.voltageFactor; - _batteryVoltageChargerFactor = config->battery.voltageChargerFactor; _batteryLowAdc = config->battery.lowAdc; _batteryCriticalAdc = config->battery.criticalAdc; } @@ -144,7 +144,7 @@ void BoxBattery::startBatteryTest() { file.writeString("Comments"); file.writeString("\r\n"); file.writeString("0;;;;;;"); - sprintf(output, "vFactor=%lu, vChargerFactor=%lu;v2-wav", _batteryVoltageFactor, _batteryVoltageChargerFactor); + sprintf(output, "vFactor=%lu;v3-wav", _batteryVoltageFactor); file.writeString(output); file.writeString("\r\n"); file.close(); diff --git a/BoxBattery.h b/BoxBattery.h index 3df357c..d04a683 100644 --- a/BoxBattery.h +++ b/BoxBattery.h @@ -52,7 +52,6 @@ class BoxBattery : public EnhancedThread { private: uint32_t _batteryVoltageFactor; - uint32_t _batteryVoltageChargerFactor; uint16_t _batteryLowAdc; uint16_t _batteryCriticalAdc; @@ -64,6 +63,9 @@ class BoxBattery : public EnhancedThread { const char* _batteryTestFilename = "/revvox/batteryTest.csv"; uint64_t _batteryTestStartMillis; + + const static uint8_t BATTERY_VOLTAGE_PIN = 60; + void _readBatteryAdc(); }; #endif \ No newline at end of file diff --git a/BoxConfig.cpp b/BoxConfig.cpp index de9423b..90a0c7b 100644 --- a/BoxConfig.cpp +++ b/BoxConfig.cpp @@ -53,7 +53,6 @@ String BoxConfig::getAsJson() { JsonObject batteryDoc = doc.createNestedObject("battery"); ConfigBattery* batteryCfg = &_config.battery; batteryDoc["voltageFactor"] = batteryCfg->voltageFactor; - batteryDoc["voltageChargerFactor"] = batteryCfg->voltageChargerFactor; batteryDoc["lowAdc"] = batteryCfg->lowAdc; batteryDoc["criticalAdc"] = batteryCfg->criticalAdc; batteryDoc["sleepMinutes"] = batteryCfg->sleepMinutes; @@ -95,7 +94,6 @@ bool BoxConfig::setFromJson(String json) { JsonObject batteryDoc = doc["battery"]; ConfigBattery* batteryCfg = &_config.battery; batteryCfg->voltageFactor = batteryDoc["voltageFactor"].as(); - batteryCfg->voltageChargerFactor = batteryDoc["voltageChargerFactor"].as(); batteryCfg->lowAdc = batteryDoc["lowAdc"].as(); batteryCfg->criticalAdc = batteryDoc["criticalAdc"].as(); batteryCfg->sleepMinutes = batteryDoc["sleepMinutes"].as(); @@ -132,6 +130,11 @@ bool BoxConfig::setFromJson(String json) { case 4: miscCfg->swd = false; _config.version = 5; + case 5: + batteryCfg->lowAdc = 9658; + batteryCfg->criticalAdc = 8869; + batteryCfg->voltageFactor = 27850; + _config.version = 6; write(); break; default: @@ -147,11 +150,12 @@ bool BoxConfig::setFromJson(String json) { void BoxConfig::_initializeConfig() { _config.version = CONFIG_ACTIVE_VERSION; + //(4936,0258+0x59)/(10000/0x663d) = adc + //(10000/0x663d)×13152−0x59 = v-OFW ConfigBattery* battery = &_config.battery; battery->voltageFactor = 67690; - battery->voltageChargerFactor = 71907; - battery->lowAdc = 2500; - battery->criticalAdc = 2400; + battery->lowAdc = 9658; //OFW 0xE11 (9657,837) + battery->criticalAdc = 8869; //OFW 0xCE3/0xCE4 (8867,4124/8870,0297) battery->sleepMinutes = 15; ConfigButtonEars* buttons = &_config.buttonEars; diff --git a/ConfigStructures.h b/ConfigStructures.h index 1d31873..59e9590 100644 --- a/ConfigStructures.h +++ b/ConfigStructures.h @@ -1,11 +1,11 @@ #ifndef ConfigStructures_h #define ConfigStructures_h -#define CONFIG_ACTIVE_VERSION 5 +#define CONFIG_ACTIVE_VERSION 6 typedef struct { uint32_t voltageFactor; - uint32_t voltageChargerFactor; + uint32_t _deprecated_voltageChargerFactor; uint16_t lowAdc; uint16_t criticalAdc; uint8_t sleepMinutes; From d887ab1c614b2cc41a530cb93f2102f7a1774ddf Mon Sep 17 00:00:00 2001 From: scilor Date: Fri, 6 May 2022 21:57:35 +0200 Subject: [PATCH 03/16] Headphone detection (not startup) --- BoxDAC.cpp | 14 ++++++++++++++ BoxDAC.h | 7 +++++++ BoxEvents.cpp | 11 +++++++++++ BoxEvents.h | 4 +++- 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/BoxDAC.cpp b/BoxDAC.cpp index ba85bd7..cab005d 100644 --- a/BoxDAC.cpp +++ b/BoxDAC.cpp @@ -187,6 +187,7 @@ void BoxDAC::loop() { } } void BoxDAC::loop(uint16_t timeoutMs) { + checkHeadphoneState(); if (audioPlaying) { if (!audioGenerator || !audioSource) { audioPlaying = false; @@ -775,4 +776,17 @@ void BoxDAC::initDACI2C() { // Extract END send(ADDR::PAGE_CONTROL, PAGE::DAC_OUT_VOL); send(ADDR_P1_DAC_OUT::L_VOL_TO_SPK, 128); +} + +void BoxDAC::checkHeadphoneState() { + send(ADDR::PAGE_CONTROL, PAGE::SERIAL_IO); + uint8_t intrFlags = readByte(ADDR_P0_SERIAL::DAC_INTR_FLAGS); + if ((intrFlags & 0b00010000) == 0b00010000) { + intrFlags = readByte(ADDR_P0_SERIAL::INTR_FLAGS); + if ((intrFlags & 0b00010000) == 0b00010000) { + Events.handleHeadphoneEvent(HeadphoneEvent::INSERTED); + } else { + Events.handleHeadphoneEvent(HeadphoneEvent::REMOVED); + } + } } \ No newline at end of file diff --git a/BoxDAC.h b/BoxDAC.h index 886a0bf..61a73c7 100755 --- a/BoxDAC.h +++ b/BoxDAC.h @@ -20,6 +20,10 @@ class BoxDAC : public EnhancedThread { public: + enum class HeadphoneEvent { + INSERTED, + REMOVED + }; void begin(), loop(), @@ -149,6 +153,8 @@ class BoxDAC : public EnhancedThread { DAC_DOSR_VAL_LSB = 0x0E, CODEC_IF_CTRL1 = 0x1B, DAC_FLAG_REG = 0x26, + DAC_INTR_FLAGS = 0x2C, + INTR_FLAGS = 0x2E, INT1_CTRL_REG = 0x30, GPIO1_INOUT_CTRL = 0x33, DAC_PROC_BLOCK_SEL = 0x3C, @@ -202,6 +208,7 @@ class BoxDAC : public EnhancedThread { readByte(ADDR_P3_MCLK source_register); void initDACI2C(); + void checkHeadphoneState(); uint8_t getSampleRateIndex(); uint16_t ofwButtonFreqTable[5][4][2] = { diff --git a/BoxEvents.cpp b/BoxEvents.cpp index 425b719..7d0e0cd 100644 --- a/BoxEvents.cpp +++ b/BoxEvents.cpp @@ -306,4 +306,15 @@ void BoxEvents::handleTagEvent(BoxRFID::TAG_EVENT event) { break; } Box.boxPower.feedSleepTimer(); +} + +void BoxEvents::handleHeadphoneEvent(BoxDAC::HeadphoneEvent event) { + switch (event){ + case BoxDAC::HeadphoneEvent::INSERTED: + Log.info("Headphones connected"); + break; + case BoxDAC::HeadphoneEvent::REMOVED: + Log.info("Headphones disconnected"); + break; + } } \ No newline at end of file diff --git a/BoxEvents.h b/BoxEvents.h index 5d198c5..ed26969 100644 --- a/BoxEvents.h +++ b/BoxEvents.h @@ -17,7 +17,8 @@ class BoxEvents { WIFI, POWER, ACCELEROMETER, - TAG + TAG, + HEADPHONE }; void @@ -30,6 +31,7 @@ class BoxEvents { void handlePowerEvent(BoxPower::PowerEvent event); void handleAccelerometerOrientationEvent(BoxAccelerometer::Orientation orient); void handleTagEvent(BoxRFID::TAG_EVENT event); + void handleHeadphoneEvent(BoxDAC::HeadphoneEvent event); private: }; From f3c28613c537947aff5b47f483b4326b1b0f8133 Mon Sep 17 00:00:00 2001 From: scilor Date: Fri, 6 May 2022 22:03:38 +0200 Subject: [PATCH 04/16] Fix initial value for 27850 --- BoxConfig.cpp | 7 ++++++- ConfigStructures.h | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/BoxConfig.cpp b/BoxConfig.cpp index 90a0c7b..76efea7 100644 --- a/BoxConfig.cpp +++ b/BoxConfig.cpp @@ -135,6 +135,11 @@ bool BoxConfig::setFromJson(String json) { batteryCfg->criticalAdc = 8869; batteryCfg->voltageFactor = 27850; _config.version = 6; + case 6: + miscCfg->watchdogSeconds = 10; + if (batteryCfg->voltageFactor == 67690) //Fix for wrong value in previous CFW + batteryCfg->voltageFactor = 27850; + _config.version = 7; write(); break; default: @@ -153,7 +158,7 @@ void BoxConfig::_initializeConfig() { //(4936,0258+0x59)/(10000/0x663d) = adc //(10000/0x663d)×13152−0x59 = v-OFW ConfigBattery* battery = &_config.battery; - battery->voltageFactor = 67690; + battery->voltageFactor = 27850; battery->lowAdc = 9658; //OFW 0xE11 (9657,837) battery->criticalAdc = 8869; //OFW 0xCE3/0xCE4 (8867,4124/8870,0297) battery->sleepMinutes = 15; diff --git a/ConfigStructures.h b/ConfigStructures.h index 59e9590..2961e11 100644 --- a/ConfigStructures.h +++ b/ConfigStructures.h @@ -1,7 +1,7 @@ #ifndef ConfigStructures_h #define ConfigStructures_h -#define CONFIG_ACTIVE_VERSION 6 +#define CONFIG_ACTIVE_VERSION 7 typedef struct { uint32_t voltageFactor; From 40dd277470d4d9bd6787aa15939f6b0d0b586c21 Mon Sep 17 00:00:00 2001 From: scilor Date: Fri, 6 May 2022 22:04:16 +0200 Subject: [PATCH 05/16] Add watchdogSeconds config --- BoxConfig.cpp | 3 +++ BoxConfig.h | 4 ++-- ConfigStructures.h | 1 + Hackiebox.cpp | 36 ++++++++++++++++++++++++------------ Hackiebox.h | 3 ++- 5 files changed, 32 insertions(+), 15 deletions(-) diff --git a/BoxConfig.cpp b/BoxConfig.cpp index 76efea7..89815f5 100644 --- a/BoxConfig.cpp +++ b/BoxConfig.cpp @@ -75,6 +75,7 @@ String BoxConfig::getAsJson() { ConfigMisc* miscCfg = &_config.misc; miscDoc["autodump"] = miscCfg->autodump; miscDoc["swd"] = miscCfg->swd; + miscDoc["watchdogSeconds"] = miscCfg->watchdogSeconds; _json = ""; serializeJson(doc, _json); @@ -116,6 +117,7 @@ bool BoxConfig::setFromJson(String json) { ConfigMisc* miscCfg = &_config.misc; miscCfg->autodump = miscDoc["autodump"].as(); miscCfg->swd = miscDoc["swd"].as(); + miscCfg->watchdogSeconds = miscDoc["watchdogSeconds"].as(); // Convert old config version to latest one. if (_config.version != CONFIG_ACTIVE_VERSION) { @@ -182,4 +184,5 @@ void BoxConfig::_initializeConfig() { ConfigMisc* misc = &_config.misc; misc->autodump = false; misc->swd = false; + misc->watchdogSeconds = 10; } \ No newline at end of file diff --git a/BoxConfig.h b/BoxConfig.h index 7c51e16..7062084 100644 --- a/BoxConfig.h +++ b/BoxConfig.h @@ -6,8 +6,8 @@ #include "BoxSD.h" -#define BOXCONFIG_JSON_SIZE 528 -//{"version":255,"battery":{"voltageFactor":4294967295,"voltageChargerFactor":4294967295,"lowAdc":65535,"criticalAdc":65535,"sleepMinutes":255},"buttonEars":{"longPressMs":65535,"veryLongPressMs":65535},"wifi":{"ssid":"12345678901234567890123456789012","password":"1234567890123456789012345678901234567890123456789012345678901234"},"log":{"sdLog":false},"misc":{"autodump":false,"swd":false}} +#define BOXCONFIG_JSON_SIZE 560 +//{"version":255,"battery":{"voltageFactor":4294967295,"voltageChargerFactor":4294967295,"lowAdc":65535,"criticalAdc":65535,"sleepMinutes":255},"buttonEars":{"longPressMs":65535,"veryLongPressMs":65535},"wifi":{"ssid":"12345678901234567890123456789012","password":"1234567890123456789012345678901234567890123456789012345678901234"},"log":{"sdLog":false},"misc":{"autodump":false,"swd":false,"watchdogSeconds":255}} //Size from https://arduinojson.org/v6/assistant/ class BoxConfig { diff --git a/ConfigStructures.h b/ConfigStructures.h index 2961e11..1e3abea 100644 --- a/ConfigStructures.h +++ b/ConfigStructures.h @@ -42,6 +42,7 @@ typedef struct { typedef struct { bool autodump; bool swd; + uint8_t watchdogSeconds; } ConfigMisc; typedef struct { diff --git a/Hackiebox.cpp b/Hackiebox.cpp index d8eb9e8..5f1159f 100755 --- a/Hackiebox.cpp +++ b/Hackiebox.cpp @@ -47,7 +47,7 @@ void crash(crashSource source, uint32_t* sp) { Box.boxPower.hibernate(); } void Hackiebox::setup() { - if (!watchdog_start()) { + if (!watchdog_start(10)) { watchdog_stop(); //reset box?! } @@ -76,6 +76,8 @@ void Hackiebox::setup() { boxSD.begin(); Config.begin(); //SD Card needed! ConfigStruct* config = Config.get(); + + watchdog_start(config->misc.watchdogSeconds); boxPower.begin(); boxI2C.begin(); @@ -211,22 +213,30 @@ void Hackiebox::watchdog_unfeed() { _watchdog_fed = false; } void watchdog_handler() { - if (Box.watchdog_isFed()) { + if (Box.watchdog_isFed() || !Box.watchdog_enabled) { MAP_WatchdogIntClear(WDT_BASE); Box.watchdog_unfeed(); } } -bool Hackiebox::watchdog_start() { +bool Hackiebox::watchdog_start(uint8_t timeoutS) { watchdog_feed(); - - MAP_PRCMPeripheralClkEnable(PRCM_WDT, PRCM_RUN_MODE_CLK); - MAP_WatchdogUnlock(WDT_BASE); - MAP_IntPrioritySet(INT_WDT, INT_PRIORITY_LVL_1); - MAP_WatchdogStallEnable(WDT_BASE); //Allow Debugging - MAP_WatchdogIntRegister(WDT_BASE, watchdog_handler); - MAP_WatchdogReloadSet(WDT_BASE, 80000000*10); //10s - MAP_WatchdogEnable(WDT_BASE); - + if (timeoutS == 0) { + watchdog_start(53); + watchdog_stop(); + } else { + if (timeoutS > 53) + timeoutS = 53; //otherwise uint32_t of WatchdogReloadSet will overflow. + + MAP_PRCMPeripheralClkEnable(PRCM_WDT, PRCM_RUN_MODE_CLK); + MAP_WatchdogUnlock(WDT_BASE); + MAP_IntPrioritySet(INT_WDT, INT_PRIORITY_LVL_1); + MAP_WatchdogStallEnable(WDT_BASE); //Allow Debugging + MAP_WatchdogIntRegister(WDT_BASE, watchdog_handler); + MAP_WatchdogReloadSet(WDT_BASE, 80000000*timeoutS); + MAP_WatchdogEnable(WDT_BASE); + + watchdog_enabled = true; + } return MAP_WatchdogRunning(WDT_BASE); } void Hackiebox::watchdog_stop() { @@ -234,5 +244,7 @@ void Hackiebox::watchdog_stop() { MAP_WatchdogReloadSet(WDT_BASE, 0xFFFFFFFF); //set timer to high value MAP_WatchdogIntClear(WDT_BASE); MAP_WatchdogIntUnregister(WDT_BASE); + + watchdog_enabled = false; } diff --git a/Hackiebox.h b/Hackiebox.h index aa8b8cb..4106905 100644 --- a/Hackiebox.h +++ b/Hackiebox.h @@ -39,7 +39,7 @@ class Hackiebox { loop(); bool - watchdog_start(), + watchdog_start(uint8_t timeoutS), watchdog_isFed(); void watchdog_stop(), @@ -72,6 +72,7 @@ class Hackiebox { LogStreamSd logStreamSd; LogStreamSse logStreamSse; + bool watchdog_enabled; private:/* typedef void (*fAPPWDTDevCallbk)(); void From 071db4a59e6c25f192677d8a37759456e72c99ab Mon Sep 17 00:00:00 2001 From: scilor Date: Sat, 7 May 2022 09:48:01 +0200 Subject: [PATCH 06/16] single channel to L/R channel --- AudioOutputCC3200I2S.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/AudioOutputCC3200I2S.cpp b/AudioOutputCC3200I2S.cpp index 4586e1a..d4d6a63 100644 --- a/AudioOutputCC3200I2S.cpp +++ b/AudioOutputCC3200I2S.cpp @@ -93,10 +93,12 @@ bool AudioOutputCC3200I2S::ConsumeSample(int16_t sample[2]) ms[1] = sample[1]; MakeSampleStereo16( ms ); - if (this->mono) { + if (this->mono && this->channels == 2) { // Average the two samples and overwrite int32_t ttl = ms[LEFTCHANNEL] + ms[RIGHTCHANNEL]; ms[LEFTCHANNEL] = ms[RIGHTCHANNEL] = (ttl>>1) & 0xffff; + } else if (this->channels == 1) { + ms[LEFTCHANNEL] = ms[RIGHTCHANNEL]; } writeBuffer->buffer[writeBuffer->position++] = ms[LEFTCHANNEL]; From 2039324424f9549df0349981ab3e108b08ac0fe6 Mon Sep 17 00:00:00 2001 From: scilor Date: Sat, 7 May 2022 09:56:20 +0200 Subject: [PATCH 07/16] watchdog disable workaround --- Hackiebox.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Hackiebox.cpp b/Hackiebox.cpp index 5f1159f..f6ed052 100755 --- a/Hackiebox.cpp +++ b/Hackiebox.cpp @@ -222,7 +222,8 @@ bool Hackiebox::watchdog_start(uint8_t timeoutS) { watchdog_feed(); if (timeoutS == 0) { watchdog_start(53); - watchdog_stop(); + //watchdog_stop(); // Random watchdog triggers?! + watchdog_enabled = false; } else { if (timeoutS > 53) timeoutS = 53; //otherwise uint32_t of WatchdogReloadSet will overflow. From 4be9ccfc6c5bc4fb5adc02929c1fe62b058188fc Mon Sep 17 00:00:00 2001 From: scilor Date: Sat, 7 May 2022 09:58:11 +0200 Subject: [PATCH 08/16] Headset detection + disable speaker (except on startup!) --- BoxDAC.cpp | 37 +++++++++++++++++++++++++++++++++++++ BoxDAC.h | 3 +++ BoxEvents.cpp | 4 ++++ 3 files changed, 44 insertions(+) diff --git a/BoxDAC.cpp b/BoxDAC.cpp index cab005d..1cfa17f 100644 --- a/BoxDAC.cpp +++ b/BoxDAC.cpp @@ -119,6 +119,13 @@ void BoxDAC::begin() { Log.info("...done"); + uint8_t headsetDetect = readByte(ADDR_P0_SERIAL::HEADSET_DETECT); + Log.info("Headset detect=%B", headsetDetect); // Always no Headset detected?! TODO + if ((headsetDetect & 0b00100000) == 0b00100000) { + Events.handleHeadphoneEvent(HeadphoneEvent::INSERTED); + } else { + Events.handleHeadphoneEvent(HeadphoneEvent::REMOVED); + } //samSay("Hackiebox by Team Revvox!"); } void BoxDAC::opusTest() { @@ -778,6 +785,36 @@ void BoxDAC::initDACI2C() { send(ADDR_P1_DAC_OUT::L_VOL_TO_SPK, 128); } + +void BoxDAC::muteSpeaker(bool mute) { + send(ADDR::PAGE_CONTROL, PAGE::DAC_OUT_VOL); + uint8_t state = readByte(ADDR_P1_DAC_OUT::SPK_DRIVER); + + if (mute) { + state &= ~(0b00000100); + } else { + state |= 0b00000100; + } + + send(ADDR_P1_DAC_OUT::SPK_DRIVER, state); +} +void BoxDAC::muteHeadphones(bool mute) { + send(ADDR::PAGE_CONTROL, PAGE::DAC_OUT_VOL); + uint8_t stateL = readByte(ADDR_P1_DAC_OUT::HPL_DRIVER); + uint8_t stateR = readByte(ADDR_P1_DAC_OUT::HPR_DRIVER); + + if (mute) { + stateL &= ~(0b00000100); + stateR &= ~(0b00000100); + } else { + stateL |= 0b00000100; + stateR |= 0b00000100; + } + + send(ADDR_P1_DAC_OUT::HPL_DRIVER, stateL); + send(ADDR_P1_DAC_OUT::HPR_DRIVER, stateR); +} + void BoxDAC::checkHeadphoneState() { send(ADDR::PAGE_CONTROL, PAGE::SERIAL_IO); uint8_t intrFlags = readByte(ADDR_P0_SERIAL::DAC_INTR_FLAGS); diff --git a/BoxDAC.h b/BoxDAC.h index 61a73c7..b57efc8 100755 --- a/BoxDAC.h +++ b/BoxDAC.h @@ -117,6 +117,9 @@ class BoxDAC : public EnhancedThread { void logVolume(); void logBeepVolume(uint8_t volume); + void muteSpeaker(bool mute); + void muteHeadphones(bool mute); + void play(), pause(), diff --git a/BoxEvents.cpp b/BoxEvents.cpp index 7d0e0cd..91e620f 100644 --- a/BoxEvents.cpp +++ b/BoxEvents.cpp @@ -312,9 +312,13 @@ void BoxEvents::handleHeadphoneEvent(BoxDAC::HeadphoneEvent event) { switch (event){ case BoxDAC::HeadphoneEvent::INSERTED: Log.info("Headphones connected"); + Box.boxDAC.muteSpeaker(true); + Box.boxDAC.muteHeadphones(false); break; case BoxDAC::HeadphoneEvent::REMOVED: Log.info("Headphones disconnected"); + Box.boxDAC.muteHeadphones(true); + Box.boxDAC.muteSpeaker(false); break; } } \ No newline at end of file From 5f5f65ee169ddf5b86f582fbc6eeb527f1559dc4 Mon Sep 17 00:00:00 2001 From: scilor Date: Sat, 7 May 2022 09:58:31 +0200 Subject: [PATCH 09/16] Use L+R on headphones --- BoxDAC.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BoxDAC.cpp b/BoxDAC.cpp index 1cfa17f..d2cb6dc 100644 --- a/BoxDAC.cpp +++ b/BoxDAC.cpp @@ -775,8 +775,8 @@ void BoxDAC::initDACI2C() { send(ADDR::PAGE_CONTROL, PAGE::SERIAL_IO); - //send(ADDR_P0_SERIAL::DAC_DATA_PATH_SETUP, 0xD5); // DAC power on, Left=left, Right=Right, DAC Softstep HP STEREO - send(ADDR_P0_SERIAL::DAC_DATA_PATH_SETUP, 0xF1); // DAC power on, Left=left, Right=Right, DAC Softstep SPEAKER MONO + send(ADDR_P0_SERIAL::DAC_DATA_PATH_SETUP, 0xD5); // DAC power on, Left=left, Right=Right, DAC Softstep HP STEREO + //send(ADDR_P0_SERIAL::DAC_DATA_PATH_SETUP, 0xF1); // DAC power on, Left=left, Right=Right, DAC Softstep SPEAKER MONO send(ADDR_P0_SERIAL::DAC_VOL_L_CTRL, 0xDC); send(ADDR_P0_SERIAL::DAC_VOL_R_CTRL, 0xDC); //Excel 219 From ec0961d6399e105871c2d50370ff81fccd367a28 Mon Sep 17 00:00:00 2001 From: scilor Date: Mon, 9 May 2022 20:14:11 +0200 Subject: [PATCH 10/16] Remove unnecessary flush --- LogStreamSse.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/LogStreamSse.cpp b/LogStreamSse.cpp index 8a7c7dd..f429620 100644 --- a/LogStreamSse.cpp +++ b/LogStreamSse.cpp @@ -18,8 +18,7 @@ size_t LogStreamSse::write(uint8_t character) { if (_tagIsOpen) { client->print("\" }\n\n"); // Extra newline required by SSE standard tagIsOpen = false; - } - client->flush(); + } } else { if (!_tagIsOpen) { client->print("data: { \"type\":\""); From 8454d0371fdb0530ad807ad56ce183f684267ca0 Mon Sep 17 00:00:00 2001 From: scilor Date: Mon, 9 May 2022 20:16:10 +0200 Subject: [PATCH 11/16] Flush SSE Logging data after every \n --- LogStreamMulti.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/LogStreamMulti.cpp b/LogStreamMulti.cpp index 153cf1d..f9831fa 100644 --- a/LogStreamMulti.cpp +++ b/LogStreamMulti.cpp @@ -27,6 +27,13 @@ size_t LogStreamMulti::write(const uint8_t *buffer, size_t size) { } memcpy(&_buffer[_getBufferPosition()], buffer+position, size-position); + for (uint8_t i=position; i Date: Sun, 15 May 2022 09:56:02 +0200 Subject: [PATCH 12/16] Silent watchdog feed --- WrapperWebServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WrapperWebServer.cpp b/WrapperWebServer.cpp index f2c6769..f40b26e 100755 --- a/WrapperWebServer.cpp +++ b/WrapperWebServer.cpp @@ -538,7 +538,7 @@ void WrapperWebServer::sendEvent(const char* eventname, const char* content) { } } if (clientConnected) - Box.boxPower.feedSleepTimer(); + Box.boxPower.feedSleepTimerSilent(); } void WrapperWebServer::sseKeepAlive() { sendEvent("keep-alive", ""); From ff26d9fd1695d4760cff5aff53eef8838d885e19 Mon Sep 17 00:00:00 2001 From: scilor Date: Sun, 15 May 2022 09:56:31 +0200 Subject: [PATCH 13/16] Flush SD log on crash --- Hackiebox.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Hackiebox.cpp b/Hackiebox.cpp index f6ed052..89ac260 100755 --- a/Hackiebox.cpp +++ b/Hackiebox.cpp @@ -41,6 +41,8 @@ void crash(crashSource source, uint32_t* sp) { _file.close(); } Log.info("...done"); + + Box.logStreamMulti.flush(); //Write all buffered logs to SD/SSE __asm__ volatile("bkpt"); From 77c5d05925d3ca98b1464b5808bbda8e1351c190 Mon Sep 17 00:00:00 2001 From: scilor Date: Sun, 15 May 2022 09:58:18 +0200 Subject: [PATCH 14/16] Escape paramater sseEvents and flush before every event. --- WrapperWebServer.cpp | 15 +++++++++++---- WrapperWebServer.h | 8 +++++--- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/WrapperWebServer.cpp b/WrapperWebServer.cpp index f40b26e..79fdc09 100755 --- a/WrapperWebServer.cpp +++ b/WrapperWebServer.cpp @@ -513,20 +513,27 @@ void WrapperWebServer::handleUploadFlashFile() { handleNotFound(); } -void WrapperWebServer::sendEvent(const char* eventname, const char* content) { +void WrapperWebServer::sendEvent(const char* eventname, const char* content, bool escapeData) { bool clientConnected = false; for (uint8_t i = 0; i < SSE_MAX_CHANNELS; i++) { if (!(subscription[i].clientIP)) continue; + Box.logStreamMulti.flush(); sampleMemory(4); if (subscription[i].client.connected()) { clientConnected = true; subscription[i].client.print("data: { \"type\":\""); subscription[i].client.print(eventname); - subscription[i].client.print("\", \"data\":\""); - subscription[i].client.print(content); - subscription[i].client.print("\" }"); + if (escapeData) { + subscription[i].client.print("\", \"data\":\""); + subscription[i].client.print(content); + subscription[i].client.print("\" }"); + } else { + subscription[i].client.print("\", \"data\":"); + subscription[i].client.print(content); + subscription[i].client.print("}"); + } subscription[i].client.println("\n"); // Extra newline required by SSE standard } else { Log.info("Client not listening on channel %i, remove subscription", i); diff --git a/WrapperWebServer.h b/WrapperWebServer.h index 20b8f89..3b40c42 100755 --- a/WrapperWebServer.h +++ b/WrapperWebServer.h @@ -20,6 +20,10 @@ class WrapperWebServer : public EnhancedThread { void begin(), loop(); + + void + sendEvent(const char* eventname, const char* content, bool escapeData = true); + //sendEventJSON(char* eventname, xyzjsondoc jsonContent) private: void @@ -37,9 +41,7 @@ class WrapperWebServer : public EnhancedThread { void sseHandler(uint8_t channel), - sseKeepAlive(), - sendEvent(const char* eventname, const char* content); - //sendEventJSON(char* eventname, xyzjsondoc jsonContent); + sseKeepAlive(); bool From 655c3e3ee1afd3aafe1c55ced32c205192582abb Mon Sep 17 00:00:00 2001 From: scilor Date: Sun, 15 May 2022 09:59:21 +0200 Subject: [PATCH 15/16] Log events to sse --- BoxEvents.cpp | 42 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/BoxEvents.cpp b/BoxEvents.cpp index 91e620f..f818235 100644 --- a/BoxEvents.cpp +++ b/BoxEvents.cpp @@ -10,7 +10,7 @@ void BoxEvents::loop() { void BoxEvents::handleEarEvent(BoxButtonEars::EarButton earId, BoxButtonEars::PressedType pressType, BoxButtonEars::PressedTime pressLength) { const char* nameEar; const char* nameType; - const char* nameLength; + const char* nameDuration; switch (earId) { case BoxButtonEars::EarButton::SMALL: @@ -41,22 +41,27 @@ void BoxEvents::handleEarEvent(BoxButtonEars::EarButton earId, BoxButtonEars::Pr switch (pressLength) { case BoxButtonEars::PressedTime::SHORT: - nameLength = "short"; + nameDuration = "short"; break; case BoxButtonEars::PressedTime::LONG: - nameLength = "long"; + nameDuration = "long"; break; case BoxButtonEars::PressedTime::VERY_LONG: - nameLength = "very long"; + nameDuration = "very long"; break; default: - nameLength = "unknown length"; + nameDuration = "unknown length"; break; } - Log.info("%s %s-%s", nameEar, nameLength, nameType); + + Log.info("%s %s-%s", nameEar, nameDuration, nameType); Box.boxPower.feedSleepTimer(); + char earEvent[34]; + snprintf(earEvent, 34, "{\"id\":%i,\"type\":%i,\"duration\":%i}", earId, pressType, pressLength); + Box.webServer.sendEvent("Ear", earEvent, false); + if (pressType == BoxButtonEars::PressedType::PRESS) { if (pressLength == BoxButtonEars::PressedTime::SHORT) { if (earId == BoxButtonEars::EarButton::BIG) { @@ -126,6 +131,10 @@ void BoxEvents::handleEarEvent(BoxButtonEars::EarButton earId, BoxButtonEars::Pr } void BoxEvents::handleBatteryEvent(BoxBattery::BatteryEvent state) { + char batteryEvent[12]; + snprintf(batteryEvent, 12, "{\"state\":%i}", state); + Box.webServer.sendEvent("Battery", batteryEvent, false); + switch (state) { case BoxBattery::BatteryEvent::BAT_CRITICAL: Log.info("Battery is critical, connect the charger, hibernating!"); @@ -167,10 +176,9 @@ void BoxEvents::handleWiFiEvent(WrapperWiFi::ConnectionState state) { Box.boxWiFi.mDnsAdvertiseSetup(); break; case WrapperWiFi::ConnectionState::DISCONNECTED: - //Box.boxLEDs.setActiveAnimationByIteration(BoxLEDs::ANIMATION_TYPE::BLINK, BoxLEDs::CRGB::Cyan, 3); + Box.boxLEDs.setActiveAnimationByIteration(BoxLEDs::ANIMATION_TYPE::BLINK, BoxLEDs::CRGB::Red, 3); Log.info("WiFi lost"); break; - default: break; } @@ -235,15 +243,24 @@ void BoxEvents::handleAccelerometerOrientationEvent(BoxAccelerometer::Orientatio break; } Log.info("Box' orientation changed to %s", orientText); + + char orientEvent[9]; + snprintf(orientEvent, 9, "{\"id\":%i}", orient); + Box.webServer.sendEvent("Orientation", orientEvent, false); + Box.boxPower.feedSleepTimer(); } void BoxEvents::handleTagEvent(BoxRFID::TAG_EVENT event) { + uint8_t uid[24]; + uid[0] = '\0'; + switch (event) { case BoxRFID::TAG_EVENT::TAG_PLACED: Log.info("Tag placed", event); Box.boxLEDs.setIdleAnimation(BoxLEDs::ANIMATION_TYPE::PARTY, BoxLEDs::CRGB::White); Box.boxRFID.logUID(); + Box.boxRFID.getUID(uid); if (!Box.boxDAC.hasStopped() && (memcmp(Box.boxRFID.tagUid, Box.boxTonie.currentUid, 8) == 0)) { Log.info("Continue playing last file"); @@ -305,6 +322,12 @@ void BoxEvents::handleTagEvent(BoxRFID::TAG_EVENT event) { Log.error("Unknown TAG_EVENT=%X", event); break; } + + + char tagEvent[44]; + snprintf(tagEvent, 44, "{\"event\":%i,\"uid\":\"%s\"}", event, uid, false); + Box.webServer.sendEvent("Tag", tagEvent, false); + Box.boxPower.feedSleepTimer(); } @@ -321,4 +344,7 @@ void BoxEvents::handleHeadphoneEvent(BoxDAC::HeadphoneEvent event) { Box.boxDAC.muteSpeaker(false); break; } + char hpEvent[12]; + snprintf(hpEvent, 12, "{\"event\":%i}", hpEvent); + Box.webServer.sendEvent("Headphones", hpEvent, false); } \ No newline at end of file From 1c6cabd65d0c8be8453433695b3470f814ae890a Mon Sep 17 00:00:00 2001 From: scilor Date: Sun, 15 May 2022 10:00:38 +0200 Subject: [PATCH 16/16] try to implement taps (failed) --- BoxAccelerometer.cpp | 111 +++++++++++++++++++++++++++++++++---------- BoxAccelerometer.h | 19 +++++--- 2 files changed, 99 insertions(+), 31 deletions(-) diff --git a/BoxAccelerometer.cpp b/BoxAccelerometer.cpp index 4c5fea6..3262305 100644 --- a/BoxAccelerometer.cpp +++ b/BoxAccelerometer.cpp @@ -14,21 +14,21 @@ void BoxAccelerometer::begin() { _accel.setupPL(); - _accel.writeRegister(CTRL_REG1, 0x02); //Original 0x02 - _accel.writeRegister(XYZ_DATA_CFG, 0x02); //Original 0x02 - _accel.writeRegister(CTRL_REG2, 0x00); //Original 0x00 + _accel.writeRegister(CTRL_REG1, 0x02); //Original 0x02 //F_READ + _accel.writeRegister(XYZ_DATA_CFG, 0x02); //Original 0x02 //FS1 + _accel.writeRegister(CTRL_REG2, 0x00); //Original 0x00 //Standby _accel.writeRegister(F_SETUP, 0x00); //Original 0x00 - _accel.writeRegister(TRIG_CFG, 0x08); //Original 0x08 - _accel.writeRegister(PULSE_CFG, 0x54); //Original 0x54 + _accel.writeRegister(TRIG_CFG, 0x08); //Original 0x08 //Trig_PULSE/ZSPEFE/ELE + _accel.writeRegister(PULSE_CFG, 0x54); //Original 0x54 //YSPEFE _accel.setupTap(0x1B, 0x3F, 0x3F); //Original 0x1B, 0x3F, 0x3F - _accel.writeRegister(PULSE_TMLT, 0x28); //Original 0x28 - _accel.writeRegister(PULSE_LTCY, 0x7F); //Original 0x7F - _accel.writeRegister(HP_FILTER_CUTOFF, 0x10); //Original 0x10 + _accel.writeRegister(PULSE_TMLT, 0x28); //Original 0x28 //TMLT3/TMLT5 + _accel.writeRegister(PULSE_LTCY, 0x7F); //Original 0x7F //LTCY6/LTCY5/LTCY4/LTCY3/LTCY2/LTCY1/LTCY0 + _accel.writeRegister(HP_FILTER_CUTOFF, 0x10); //Original 0x10 //Pulse_LPF_EN - _accel.writeRegister(CTRL_REG3, 0x12); //Original 0x12 - _accel.writeRegister(CTRL_REG4, 0x40); //Original 0x40 - _accel.writeRegister(CTRL_REG5, 0x40); //Original 0x40 - _accel.writeRegister(CTRL_REG1, 0x03); //Original 0x03 + _accel.writeRegister(CTRL_REG3, 0x12); //Original 0x12 //WAKE_PULSE/IPOL + _accel.writeRegister(CTRL_REG4, 0x40); //Original 0x40 //INT_EN_FIFO + _accel.writeRegister(CTRL_REG5, 0x40); //Original 0x40 //INT_CFG_FIFO INT1 + _accel.writeRegister(CTRL_REG1, 0x03); //Original 0x03 //F_READ/ACTIVE Log.info("...done"); } @@ -51,13 +51,13 @@ void BoxAccelerometer::loop() { uint8_t tap = _accel.readTap(); if (tap) { - bool AxZ = tap&0b1000000; //event on axis - bool AxY = tap&0b0100000; - bool AxX = tap&0b0010000; - //bool DPE = tap&0b0001000; //double - bool PolZ = tap&0b0000100; //0=positive 1=negative - bool PolY = tap&0b0000010; - bool PolX = tap&0b0000001; + bool AxZ = (tap&0b1000000)>0; //event on axis + bool AxY = (tap&0b0100000)>0; + bool AxX = (tap&0b0010000)>0; + //bool DPE = (tap&0b0001000)>0; //double + bool PolZ = !((tap&0b0000100)>0); //0=positive 1=negative + bool PolY = !((tap&0b0000010)>0); + bool PolX = !((tap&0b0000001)>0); //X+ = box bottom //X- = box top @@ -80,22 +80,85 @@ void BoxAccelerometer::loop() { if (AxY && AxZ) { if (PolY && PolZ) { tapOn = TapOn::BACK; - Box.boxLEDs.setActiveAnimationByIteration(BoxLEDs::ANIMATION_TYPE::BLINK, BoxLEDs::CRGB::Blue, 2); + Box.boxLEDs.setActiveAnimationByIteration(BoxLEDs::ANIMATION_TYPE::BLINK, BoxLEDs::CRGB::Blue, 3); } else if (!PolY && !PolZ) { tapOn = TapOn::FRONT; - Box.boxLEDs.setActiveAnimationByIteration(BoxLEDs::ANIMATION_TYPE::BLINK, BoxLEDs::CRGB::Violet, 2); + Box.boxLEDs.setActiveAnimationByIteration(BoxLEDs::ANIMATION_TYPE::BLINK, BoxLEDs::CRGB::Violet, 3); } else if (PolY && !PolZ) { tapOn = TapOn::LEFT; - Box.boxLEDs.setActiveAnimationByIteration(BoxLEDs::ANIMATION_TYPE::BLINK, BoxLEDs::CRGB::Green, 2); + Box.boxLEDs.setActiveAnimationByIteration(BoxLEDs::ANIMATION_TYPE::BLINK, BoxLEDs::CRGB::Green, 3); } else if (!PolY && PolZ) { tapOn = TapOn::RIGHT; - Box.boxLEDs.setActiveAnimationByIteration(BoxLEDs::ANIMATION_TYPE::BLINK, BoxLEDs::CRGB::GreenYellow, 2); + Box.boxLEDs.setActiveAnimationByIteration(BoxLEDs::ANIMATION_TYPE::BLINK, BoxLEDs::CRGB::GreenYellow, 3); + } + } else if (AxY) { + if (PolY) { + tapOn = TapOn::LEFT_BACK; + Box.boxLEDs.setActiveAnimationByIteration(BoxLEDs::ANIMATION_TYPE::BLINK, BoxLEDs::CRGB::Blue, 3); + } else { + tapOn = TapOn::LEFT_FRONT; + Box.boxLEDs.setActiveAnimationByIteration(BoxLEDs::ANIMATION_TYPE::BLINK, BoxLEDs::CRGB::Violet, 3); + } + } else if (AxZ) { + if (PolZ) { + tapOn = TapOn::RIGHT_BACK; + Box.boxLEDs.setActiveAnimationByIteration(BoxLEDs::ANIMATION_TYPE::BLINK, BoxLEDs::CRGB::Green, 3); + } else { + tapOn = TapOn::RIGHT_FRONT; + Box.boxLEDs.setActiveAnimationByIteration(BoxLEDs::ANIMATION_TYPE::BLINK, BoxLEDs::CRGB::GreenYellow, 3); } } - Log.verbose("Tap recieved %B, direction %X", tap, tapOn); + Log.disableNewline(true); + Log.verbose("Tap recieved %B, direction=%X, ", tap, tapOn); + Log.disableNewline(false); + switch (tapOn) + { + case TapOn::LEFT: + Log.printfln("LEFT"); + break; + + case TapOn::RIGHT: + Log.printfln("RIGHT"); + break; + + case TapOn::FRONT: + Log.printfln("FRONT"); + break; + + case TapOn::BACK: + Log.printfln("BACK"); + break; + + case TapOn::TOP: + Log.printfln("TOP"); + break; + + case TapOn::BOTTOM: + Log.printfln("BOTTOM"); + break; + case TapOn::LEFT_FRONT: + Log.printfln("LEFT_FRONT"); + break; + + case TapOn::RIGHT_FRONT: + Log.printfln("RIGHT_FRONT"); + break; + + case TapOn::LEFT_BACK: + Log.printfln("LEFT_BACK"); + break; + case TapOn::RIGHT_BACK: + Log.printfln("RIGHT_BACK"); + break; + + default: + break; + Log.printfln("OTHER"); + } + } } diff --git a/BoxAccelerometer.h b/BoxAccelerometer.h index 2ce0d3a..da4a017 100644 --- a/BoxAccelerometer.h +++ b/BoxAccelerometer.h @@ -21,13 +21,18 @@ class BoxAccelerometer : public EnhancedThread { EARS_DOWN2 = 0x4 }; enum class TapOn { - NONE = 0x0, - LEFT = 0x1, - RIGHT = 0x2, //17,34,68 - 34 - FRONT = 0x3, //16, 17 - BACK = 0x4, - TOP = 0x5, //16,32,64,68,24 - 16 - BOTTOM = 0x6 //17 + NONE = 0x00, + LEFT = 0x01, + RIGHT = 0x02, //17,34,68 - 34 + FRONT = 0x04, //16, 17 + BACK = 0x08, + TOP = 0x10, //16,32,64,68,24 - 16 + BOTTOM = 0x20, //17 + + LEFT_FRONT = LEFT + FRONT, + RIGHT_FRONT = RIGHT + FRONT, + LEFT_BACK = LEFT + BACK, + RIGHT_BACK = RIGHT + BACK }; void