From 86d7860d8642300c503af6425ac9ce55554d30d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 13 Dec 2022 17:31:01 +0100 Subject: [PATCH] made a nice PTT/RECV screen for audio module. And cleaned up screen graphics a bit. --- src/graphics/Screen.cpp | 7 +++- src/graphics/images.h | 30 --------------- src/graphics/img/compass.xbm | 28 -------------- src/graphics/img/pin.xbm | 6 --- src/modules/esp32/AudioModule.cpp | 62 +++++++++++++++++++++++++++++-- src/modules/esp32/AudioModule.h | 15 +++++++- 6 files changed, 78 insertions(+), 70 deletions(-) delete mode 100644 src/graphics/img/compass.xbm delete mode 100644 src/graphics/img/pin.xbm diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 6f4c1fb58..f1c3fdccc 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -1419,17 +1419,22 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL); display->setColor(BLACK); - display->setColor(WHITE); if (WiFi.status() != WL_CONNECTED) { display->drawString(x, y, String("WiFi: Not Connected")); + display->drawString(x + 1, y, String("WiFi: Not Connected")); } else { display->drawString(x, y, String("WiFi: Connected")); + display->drawString(x + 1, y, String("WiFi: Connected")); display->drawString(x + SCREEN_WIDTH - display->getStringWidth("RSSI " + String(WiFi.RSSI())), y, "RSSI " + String(WiFi.RSSI())); + display->drawString(x + SCREEN_WIDTH - display->getStringWidth("RSSI " + String(WiFi.RSSI())) - 1, y, + "RSSI " + String(WiFi.RSSI())); } + display->setColor(WHITE); + /* - WL_CONNECTED: assigned when connected to a WiFi network; - WL_NO_SSID_AVAIL: assigned when no SSID are available; diff --git a/src/graphics/images.h b/src/graphics/images.h index 41b390eaf..4680b9475 100644 --- a/src/graphics/images.h +++ b/src/graphics/images.h @@ -15,33 +15,3 @@ const uint8_t imgPositionSolid[] PROGMEM = { 0x20, 0x30, 0x38, 0x3C, 0x7E, 0xFF const uint8_t imgInfo[] PROGMEM = { 0xFF, 0x81, 0x81, 0xB5, 0xB5, 0x81, 0x81, 0xFF }; #include "img/icon.xbm" - -// We now programmatically draw our compass -#if 0 -const -#include "img/compass.xbm" -#endif - -#if 0 -const uint8_t activeSymbol[] PROGMEM = { - B00000000, - B00000000, - B00011000, - B00100100, - B01000010, - B01000010, - B00100100, - B00011000 -}; - -const uint8_t inactiveSymbol[] PROGMEM = { - B00000000, - B00000000, - B00000000, - B00000000, - B00011000, - B00011000, - B00000000, - B00000000 -}; -#endif \ No newline at end of file diff --git a/src/graphics/img/compass.xbm b/src/graphics/img/compass.xbm deleted file mode 100644 index 115a7a1d4..000000000 --- a/src/graphics/img/compass.xbm +++ /dev/null @@ -1,28 +0,0 @@ -#define compass_width 48 -#define compass_height 48 -static char compass_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, - 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, - 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0x01, 0x00, - 0x00, 0xC0, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0xF0, 0xFF, 0xFF, 0x0F, 0x00, - 0x00, 0xF8, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0xFC, 0x07, 0xE0, 0x3F, 0x00, - 0x00, 0xFE, 0x01, 0x80, 0x7F, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x7F, 0x00, - 0x00, 0x7F, 0x00, 0x00, 0xFE, 0x00, 0x80, 0x3F, 0x00, 0x00, 0xFC, 0x01, - 0x80, 0x1F, 0x00, 0x00, 0xF8, 0x01, 0x80, 0x0F, 0x00, 0x00, 0xF0, 0x01, - 0xC0, 0x0F, 0x00, 0x00, 0xF0, 0x03, 0xC0, 0x07, 0x00, 0x00, 0xE0, 0x03, - 0xC0, 0x07, 0x00, 0x00, 0xE0, 0x03, 0xC0, 0x07, 0x00, 0x00, 0xE0, 0x03, - 0xFC, 0x07, 0x00, 0x00, 0xE0, 0x3F, 0xFC, 0x07, 0x00, 0x00, 0xE0, 0x3F, - 0xFC, 0x07, 0x00, 0x00, 0xE0, 0x3F, 0xFC, 0x07, 0x00, 0x00, 0xE0, 0x3F, - 0xC0, 0x07, 0x00, 0x00, 0xE0, 0x03, 0xC0, 0x07, 0x00, 0x00, 0xE0, 0x03, - 0xC0, 0x07, 0x00, 0x00, 0xE0, 0x03, 0xC0, 0x0F, 0x00, 0x00, 0xF0, 0x03, - 0x80, 0x0F, 0x00, 0x00, 0xF0, 0x01, 0x80, 0x1F, 0x00, 0x00, 0xF8, 0x01, - 0x80, 0x3F, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x7F, 0x00, 0x00, 0xFE, 0x00, - 0x00, 0xFE, 0x00, 0x00, 0x7F, 0x00, 0x00, 0xFE, 0x01, 0x80, 0x7F, 0x00, - 0x00, 0xFC, 0x07, 0xE0, 0x3F, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x1F, 0x00, - 0x00, 0xF0, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0x03, 0x00, - 0x00, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, - 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, - 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - }; diff --git a/src/graphics/img/pin.xbm b/src/graphics/img/pin.xbm deleted file mode 100644 index e8c8f8930..000000000 --- a/src/graphics/img/pin.xbm +++ /dev/null @@ -1,6 +0,0 @@ -#define pin_width 13 -#define pin_height 13 -static char pin_bits[] = { - 0x00, 0x00, 0xF0, 0x01, 0xF8, 0x03, 0xFC, 0x07, 0xBC, 0x07, 0xBC, 0x07, - 0xFC, 0x07, 0xF8, 0x03, 0xF8, 0x03, 0xF0, 0x01, 0xE0, 0x00, 0xE0, 0x00, - 0x00, 0x00, }; diff --git a/src/modules/esp32/AudioModule.cpp b/src/modules/esp32/AudioModule.cpp index f29c11056..75e329ce5 100644 --- a/src/modules/esp32/AudioModule.cpp +++ b/src/modules/esp32/AudioModule.cpp @@ -41,9 +41,26 @@ AudioModule *audioModule; #define YIELD_FROM_ISR(x) portYIELD_FROM_ISR(x) #endif -//int16_t 1KHz sine test tone -int16_t Sine1KHz[8] = { -21210 , -30000, -21210, 0 , 21210 , 30000 , 21210, 0 }; -int Sine1KHz_index = 0; +#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) +// The screen is bigger so use bigger fonts +#define FONT_SMALL ArialMT_Plain_16 +#define FONT_MEDIUM ArialMT_Plain_24 +#define FONT_LARGE ArialMT_Plain_24 +#else +#ifdef OLED_RU +#define FONT_SMALL ArialMT_Plain_10_RU +#else +#define FONT_SMALL ArialMT_Plain_10 +#endif +#define FONT_MEDIUM ArialMT_Plain_16 +#define FONT_LARGE ArialMT_Plain_24 +#endif + +#define fontHeight(font) ((font)[1] + 1) // height is position 1 + +#define FONT_HEIGHT_SMALL fontHeight(FONT_SMALL) +#define FONT_HEIGHT_MEDIUM fontHeight(FONT_MEDIUM) +#define FONT_HEIGHT_LARGE fontHeight(FONT_LARGE) void run_codec2(void* parameter) { @@ -124,6 +141,30 @@ AudioModule::AudioModule() : SinglePortModule("AudioModule", PortNum_AUDIO_APP), } } +void AudioModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) +{ + displayedNodeNum = 0; // Not currently showing a node pane + + char buffer[50]; + + display->setTextAlignment(TEXT_ALIGN_LEFT); + display->setFont(FONT_SMALL); + display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL); + display->setColor(BLACK); + display->drawStringf(0 + x, 0 + y, buffer, "Codec2 Mode %d Audio", (moduleConfig.audio.bitrate ? moduleConfig.audio.bitrate : AUDIO_MODULE_MODE) - 1); + display->setColor(WHITE); + display->setFont(FONT_LARGE); + display->setTextAlignment(TEXT_ALIGN_CENTER); + switch (radio_state) { + case RadioState::tx: + display->drawString(display->getWidth() / 2 + x, (display->getHeight() - FONT_HEIGHT_SMALL) / 2 + y, "PTT"); + break; + default: + display->drawString(display->getWidth() / 2 + x, (display->getHeight() - FONT_HEIGHT_SMALL) / 2 + y, "Receive"); + break; + } +} + int32_t AudioModule::runOnce() { if ((moduleConfig.audio.codec2_enabled) && (myRegion->audioPermitted)) { @@ -170,11 +211,14 @@ int32_t AudioModule::runOnce() firstTime = false; } else { + UIFrameEvent e = {false, true}; // Check if PTT is pressed. TODO hook that into Onebutton/Interrupt drive. if (digitalRead(moduleConfig.audio.ptt_pin ? moduleConfig.audio.ptt_pin : PTT_PIN) == HIGH) { if (radio_state == RadioState::rx) { DEBUG_MSG("♪♫♪ PTT pressed, switching to TX\n"); radio_state = RadioState::tx; + e.frameChanged = true; + this->notifyObservers(&e); } } else { if (radio_state == RadioState::tx) { @@ -183,9 +227,11 @@ int32_t AudioModule::runOnce() DEBUG_MSG("♪♫♪ Sending %d codec2 bytes (incomplete)\n", tx_encode_frame_index); sendPayload(); } - DEBUG_MSG("♪♫♪ PTT released, switching to RX\n"); + DEBUG_MSG("♪♫♪ PTT released, switching to RX\n"); tx_encode_frame_index = sizeof(tx_header); radio_state = RadioState::rx; + e.frameChanged = true; + this->notifyObservers(&e); } } if (radio_state == RadioState::tx) { @@ -222,6 +268,14 @@ MeshPacket *AudioModule::allocReply() return reply; } +bool AudioModule::shouldDraw() +{ + if (!moduleConfig.audio.codec2_enabled) { + return false; + } + return (radio_state == RadioState::tx); +} + void AudioModule::sendPayload(NodeNum dest, bool wantReplies) { MeshPacket *p = allocReply(); diff --git a/src/modules/esp32/AudioModule.h b/src/modules/esp32/AudioModule.h index 8e813ad1e..1a41ab6c4 100644 --- a/src/modules/esp32/AudioModule.h +++ b/src/modules/esp32/AudioModule.h @@ -10,6 +10,8 @@ #include #include #include +#include +#include enum RadioState { standby, rx, tx }; @@ -28,7 +30,7 @@ struct c2_header { #define AUDIO_MODULE_RX_BUFFER 128 #define AUDIO_MODULE_MODE ModuleConfig_AudioConfig_Audio_Baud_CODEC2_700 -class AudioModule : public SinglePortModule, private concurrency::OSThread +class AudioModule : public SinglePortModule, public Observable, private concurrency::OSThread { public: unsigned char rx_encode_frame[Constants_DATA_PAYLOAD_LEN] = {}; @@ -50,6 +52,8 @@ class AudioModule : public SinglePortModule, private concurrency::OSThread AudioModule(); + bool shouldDraw(); + /** * Send our payload into the mesh */ @@ -63,6 +67,15 @@ class AudioModule : public SinglePortModule, private concurrency::OSThread virtual MeshPacket *allocReply() override; + virtual bool wantUIFrame() override { return this->shouldDraw(); } + virtual Observable* getUIFrameObservable() override { return this; } +#if !HAS_SCREEN + void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y); +#else + virtual void drawFrame( + OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) override; +#endif + /** Called to handle a particular incoming message * @return ProcessMessage::STOP if you've guaranteed you've handled this message and no other handlers should be considered for it */