From ae0a2262c43da057904968df5c7bd64627bd40fa Mon Sep 17 00:00:00 2001 From: Rene Stange Date: Tue, 1 Mar 2022 15:56:20 +0100 Subject: [PATCH] Add class CUserInterface The user interface should be implemented here. As a start it supports showing the program number and name on the LCD display. The LCD output is buffered, so that LCD writes from an IRQ handler are possible. --- src/Makefile | 3 +- src/minidexed.cpp | 48 +++++++------------ src/minidexed.h | 19 ++------ src/userinterface.cpp | 107 ++++++++++++++++++++++++++++++++++++++++++ src/userinterface.h | 52 ++++++++++++++++++++ 5 files changed, 181 insertions(+), 48 deletions(-) create mode 100644 src/userinterface.cpp create mode 100644 src/userinterface.h diff --git a/src/Makefile b/src/Makefile index 49e3361..26a9067 100644 --- a/src/Makefile +++ b/src/Makefile @@ -5,7 +5,8 @@ CIRCLE_STDLIB_DIR = ../circle-stdlib SYNTH_DEXED_DIR = ../Synth_Dexed/src -OBJS = main.o kernel.o minidexed.o config.o pckeyboard.o sysexfileloader.o perftimer.o \ +OBJS = main.o kernel.o minidexed.o config.o userinterface.o pckeyboard.o \ + sysexfileloader.o perftimer.o \ $(SYNTH_DEXED_DIR)/synth_dexed.o INCLUDE += -I $(SYNTH_DEXED_DIR) diff --git a/src/minidexed.cpp b/src/minidexed.cpp index 12a9cb8..bbb34e2 100644 --- a/src/minidexed.cpp +++ b/src/minidexed.cpp @@ -18,19 +18,16 @@ CMiniDexed *CMiniDexed::s_pThis = 0; bool CMiniDexed::Initialize (void) { - m_SysExFileLoader.Load (); - - if (!m_Serial.Initialize(m_pConfig->GetMIDIBaudRate ())) + if (!m_UI.Initialize ()) { return false; } - if (m_pLCD) + m_SysExFileLoader.Load (); + + if (!m_Serial.Initialize(m_pConfig->GetMIDIBaudRate ())) { - if (!m_pLCD->Initialize ()) - { - return FALSE; - } + return false; } m_bUseSerial = true; @@ -50,6 +47,8 @@ void CMiniDexed::Process(boolean bPlugAndPlayUpdated) m_GetChunkTimer.Dump (); } + m_UI.Process (); + if (m_pMIDIDevice != 0) { return; @@ -203,22 +202,15 @@ void CMiniDexed::MIDIPacketHandler (unsigned nCable, u8 *pPacket, unsigned nLeng } void CMiniDexed::ChangeProgram(unsigned program) { - if(program > 31) { - return; - } - printf ("Loading voice %u\n", (unsigned) program+1); // MIDI numbering starts with 0, user interface with 1 - uint8_t Buffer[156]; - s_pThis->m_SysExFileLoader.GetVoice (program, Buffer); - s_pThis->loadVoiceParameters(Buffer); - char buf_name[11]; - memset(buf_name, 0, 11); // Initialize with 0x00 chars - s_pThis->setName(buf_name); - printf ("%s\n", buf_name); - // Print to optional HD44780 display - s_pThis->LCDWrite("\x1B[?25l"); // cursor off - CString String; - String.Format ("\n\r%i\n\r%s", program+1, buf_name); // MIDI numbering starts with 0, user interface with 1 - s_pThis->LCDWrite ((const char *) String); + if(program > 31) { + return; + } + + uint8_t Buffer[156]; + m_SysExFileLoader.GetVoice (program, Buffer); + loadVoiceParameters (Buffer); + + m_UI.ProgramChanged (program); } void CMiniDexed::USBDeviceRemovedHandler (CDevice *pDevice, void *pContext) @@ -338,11 +330,3 @@ unsigned CMiniDexedHDMI::GetChunk(u32 *pBuffer, unsigned nChunkSize) return(nResult); }; - -void CMiniDexed::LCDWrite (const char *pString) -{ - if (m_pLCD) - { - m_pLCD->Write (pString, strlen (pString)); - } -} diff --git a/src/minidexed.h b/src/minidexed.h index e4d15aa..dc0626b 100644 --- a/src/minidexed.h +++ b/src/minidexed.h @@ -19,7 +19,7 @@ #include "sysexfileloader.h" #include "pckeyboard.h" #include "perftimer.h" -#include +#include "userinterface.h" class CMiniDexed : public CDexedAdapter { @@ -33,28 +33,17 @@ class CMiniDexed : public CDexedAdapter m_nSerialState (0), m_GetChunkTimer ("GetChunk", 1000000U * pConfig->GetChunkSize ()/2 / pConfig->GetSampleRate ()), m_pConfig (pConfig), - m_pLCD (0) + m_UI (this, pConfig) { s_pThis = this; - - if (pConfig->GetLCDEnabled ()) - { - m_pLCD = new CHD44780Device (CConfig::LCDColumns, CConfig::LCDRows, - pConfig->GetLCDPinData4 (), pConfig->GetLCDPinData5 (), - pConfig->GetLCDPinData6 (), pConfig->GetLCDPinData7 (), - pConfig->GetLCDPinEnable (), pConfig->GetLCDPinRegisterSelect (), - pConfig->GetLCDPinReadWrite ()); - } }; virtual bool Initialize (void); void Process(boolean bPlugAndPlayUpdated); - private: - void LCDWrite (const char *pString); protected: static void MIDIPacketHandler (unsigned nCable, u8 *pPacket, unsigned nLength); static void KeyStatusHandlerRaw (unsigned char ucModifiers, const unsigned char RawKeys[6]); - static void ChangeProgram(unsigned program); + void ChangeProgram(unsigned program); static void USBDeviceRemovedHandler (CDevice *pDevice, void *pContext); CUSBMIDIDevice * volatile m_pMIDIDevice; CPCKeyboard m_PCKeyboard; @@ -66,7 +55,7 @@ class CMiniDexed : public CDexedAdapter CPerformanceTimer m_GetChunkTimer; private: CConfig *m_pConfig; - CHD44780Device *m_pLCD; + CUserInterface m_UI; static CMiniDexed *s_pThis; }; diff --git a/src/userinterface.cpp b/src/userinterface.cpp new file mode 100644 index 0000000..7281118 --- /dev/null +++ b/src/userinterface.cpp @@ -0,0 +1,107 @@ +// +// userinterface.cpp +// +// MiniDexed - Dexed FM synthesizer for bare metal Raspberry Pi +// Copyright (C) 2022 The MiniDexed Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +#include "userinterface.h" +#include "minidexed.h" +#include +#include +#include +#include +#include + +LOGMODULE ("ui"); + +CUserInterface::CUserInterface (CMiniDexed *pMiniDexed, CConfig *pConfig) +: m_pMiniDexed (pMiniDexed), + m_pConfig (pConfig), + m_pLCD (0), + m_pLCDBuffered (0) +{ +} + +CUserInterface::~CUserInterface (void) +{ + delete m_pLCDBuffered; + delete m_pLCD; +} + +bool CUserInterface::Initialize (void) +{ + assert (m_pConfig); + + if (m_pConfig->GetLCDEnabled ()) + { + m_pLCD = new CHD44780Device (CConfig::LCDColumns, CConfig::LCDRows, + m_pConfig->GetLCDPinData4 (), + m_pConfig->GetLCDPinData5 (), + m_pConfig->GetLCDPinData6 (), + m_pConfig->GetLCDPinData7 (), + m_pConfig->GetLCDPinEnable (), + m_pConfig->GetLCDPinRegisterSelect (), + m_pConfig->GetLCDPinReadWrite ()); + assert (m_pLCD); + + if (!m_pLCD->Initialize ()) + { + return false; + } + + m_pLCDBuffered = new CWriteBufferDevice (m_pLCD); + assert (m_pLCDBuffered); + + LCDWrite ("\x1B[?25l"); // cursor off + + LOGDBG ("LCD initialized"); + } + + return true; +} + +void CUserInterface::Process (void) +{ + if (m_pLCDBuffered) + { + m_pLCDBuffered->Update (); + } +} + +void CUserInterface::ProgramChanged (unsigned nProgram) +{ + nProgram++; // MIDI numbering starts with 0, user interface with 1 + + // fetch program name from Dexed instance + char ProgramName[11]; + memset (ProgramName, 0, sizeof ProgramName); + assert (m_pMiniDexed); + m_pMiniDexed->setName (ProgramName); + + printf ("Loading voice %u: \"%s\"\n", nProgram, ProgramName); + + CString String; + String.Format ("\n\r%u\n\r%s", nProgram, ProgramName); + LCDWrite (String); +} + +void CUserInterface::LCDWrite (const char *pString) +{ + if (m_pLCDBuffered) + { + m_pLCDBuffered->Write (pString, strlen (pString)); + } +} diff --git a/src/userinterface.h b/src/userinterface.h new file mode 100644 index 0000000..5bb24f0 --- /dev/null +++ b/src/userinterface.h @@ -0,0 +1,52 @@ +// +// userinterface.h +// +// MiniDexed - Dexed FM synthesizer for bare metal Raspberry Pi +// Copyright (C) 2022 The MiniDexed Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +#ifndef _userinterface_h +#define _userinterface_h + +#include "config.h" +#include +#include + +class CMiniDexed; + +class CUserInterface +{ +public: + CUserInterface (CMiniDexed *pMiniDexed, CConfig *pConfig); + ~CUserInterface (void); + + bool Initialize (void); + + void Process (void); + + void ProgramChanged (unsigned nProgram); // 0 .. 127 + +private: + void LCDWrite (const char *pString); // Print to optional HD44780 display + +private: + CMiniDexed *m_pMiniDexed; + CConfig *m_pConfig; + + CHD44780Device *m_pLCD; + CWriteBufferDevice *m_pLCDBuffered; +}; + +#endif