diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 294a86e..1bd04dd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,11 +20,11 @@ jobs: run: | set -ex git submodule update --init --recursive - - name: Use Circle develop branch for WM8960 support until it is merged upstream + - name: Use Circle develop branch for WM8960 and i2c display support until it is merged upstream run: | set -ex cd circle-stdlib/libs/circle - git checkout ae22928 # develop + git checkout c9a4815 # develop cd - - name: Install toolchains run: | diff --git a/README.md b/README.md index b7b8304..8070e57 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Video about this project by [Floyd Steinberg](https://www.youtube.com/watch?v=Z3 * Raspberry Pi 1, 2, 3, 4, or 400 (Zero and Zero 2 can be used but need HDMI or a supported i2s DAC for audio out). On Raspberry Pi 1 and on Raspberry Pi Zero there will be severely limited functionality (only one tone generator instead of 8) * A [PCM5102A or PCM5122 based DAC](https://github.com/probonopd/MiniDexed/wiki/Hardware#i2c-dac), HDMI display or [audio extractor](https://github.com/probonopd/MiniDexed/wiki/Hardware#hdmi-to-audio) for good sound quality. If you don't have this, you can use the headphone jack on the Raspberry Pi but on anything but the Raspberry 4 the sound quality will be seriously limited -* Optionally (but highly recommended), an [LCDC1602 Display](https://www.berrybase.de/en/sensors-modules/displays/alphanumeric-displays/alphanumerisches-lcd-16x2-gr-252-n/gelb) (not i2c) and a [KY-040 rotary encoder](https://www.berrybase.de/en/components/passive-components/potentiometer/rotary-encoder/drehregler/rotary-encoder-mit-breakoutboard-ohne-gewinde-und-mutter) +* Optionally (but highly recommended), an [LCDC1602 Display](https://www.berrybase.de/en/sensors-modules/displays/alphanumeric-displays/alphanumerisches-lcd-16x2-gr-252-n/gelb) (with or without i2c "backpack" board) and a [KY-040 rotary encoder](https://www.berrybase.de/en/components/passive-components/potentiometer/rotary-encoder/drehregler/rotary-encoder-mit-breakoutboard-ohne-gewinde-und-mutter) ## Usage @@ -43,6 +43,7 @@ Video about this project by [Floyd Steinberg](https://www.youtube.com/watch?v=Z3 * Alternatively, attach a PCM5102A or PCM5122 based DAC and select i2c sound output using `SoundDevice=i2s` in `minidexed.ini` (best audio quality) * Alternatively, attach a HDMI display with sound and select HDMI sound output using `SoundDevice=hdmi` in `minidexed.ini` (this may introduce slight latency) * Attach a MIDI keyboard via USB (alternatively you can build a circuit that allows you to attach a "traditional" MIDI keyboard using a DIN connector, or use a DIN-MIDI-to-USB adapter) +* If you are using a LCDC1602 with an i2c "backpack" board, then you need to set `LCDI2CAddress=0x27` (or another address your i2c "backpack" board is set to) in `minidexed.ini` * Boot * Start playing * If the system seems to become unresponsive after a few seconds, remove `usbspeed=full` from `cmdline.txt` and repeat ([details](https://github.com/probonopd/MiniDexed/issues/39)) diff --git a/src/config.cpp b/src/config.cpp index d5f4e96..3433b73 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -79,6 +79,7 @@ void CConfig::Load (void) m_nLCDPinData5 = m_Properties.GetNumber ("LCDPinData5", 23); m_nLCDPinData6 = m_Properties.GetNumber ("LCDPinData6", 24); m_nLCDPinData7 = m_Properties.GetNumber ("LCDPinData7", 25); + m_nLCDI2CAddress = m_Properties.GetNumber ("LCDI2CAddress", 0); m_bEncoderEnabled = m_Properties.GetNumber ("EncoderEnabled", 0) != 0; m_nEncoderPinClock = m_Properties.GetNumber ("EncoderPinClock", 10); @@ -174,6 +175,11 @@ unsigned CConfig::GetLCDPinData7 (void) const return m_nLCDPinData7; } +unsigned CConfig::GetLCDI2CAddress (void) const +{ + return m_nLCDI2CAddress; +} + bool CConfig::GetEncoderEnabled (void) const { return m_bEncoderEnabled; diff --git a/src/config.h b/src/config.h index 5c4ada6..cf51755 100644 --- a/src/config.h +++ b/src/config.h @@ -86,6 +86,7 @@ public: unsigned GetLCDPinData5 (void) const; unsigned GetLCDPinData6 (void) const; unsigned GetLCDPinData7 (void) const; + unsigned GetLCDI2CAddress (void) const; // KY-040 Rotary Encoder // GPIO pin numbers are chip numbers, not header positions @@ -120,6 +121,7 @@ private: unsigned m_nLCDPinData5; unsigned m_nLCDPinData6; unsigned m_nLCDPinData7; + unsigned m_nLCDI2CAddress; bool m_bEncoderEnabled; unsigned m_nEncoderPinClock; diff --git a/src/minidexed.cpp b/src/minidexed.cpp index c4f4b40..21e79f1 100644 --- a/src/minidexed.cpp +++ b/src/minidexed.cpp @@ -37,7 +37,7 @@ CMiniDexed::CMiniDexed (CConfig *pConfig, CInterruptSystem *pInterrupt, CMultiCoreSupport (CMemorySystem::Get ()), #endif m_pConfig (pConfig), - m_UI (this, pGPIOManager, pConfig), + m_UI (this, pGPIOManager, pI2CMaster, pConfig), m_PerformanceConfig (pFileSystem), m_PCKeyboard (this, pConfig), m_SerialMIDI (this, pInterrupt, pConfig), diff --git a/src/minidexed.ini b/src/minidexed.ini index 47aefc2..c3724a8 100644 --- a/src/minidexed.ini +++ b/src/minidexed.ini @@ -25,6 +25,7 @@ LCDPinData4=22 LCDPinData5=23 LCDPinData6=24 LCDPinData7=25 +LCDI2CAddress=0x00 # KY-040 Rotary Encoder EncoderEnabled=1 diff --git a/src/userinterface.cpp b/src/userinterface.cpp index 0fbf440..c7c746f 100644 --- a/src/userinterface.cpp +++ b/src/userinterface.cpp @@ -27,9 +27,10 @@ LOGMODULE ("ui"); -CUserInterface::CUserInterface (CMiniDexed *pMiniDexed, CGPIOManager *pGPIOManager, CConfig *pConfig) +CUserInterface::CUserInterface (CMiniDexed *pMiniDexed, CGPIOManager *pGPIOManager, CI2CMaster *pI2CMaster, CConfig *pConfig) : m_pMiniDexed (pMiniDexed), m_pGPIOManager (pGPIOManager), + m_pI2CMaster (pI2CMaster), m_pConfig (pConfig), m_pLCD (0), m_pLCDBuffered (0), @@ -52,14 +53,23 @@ bool CUserInterface::Initialize (void) 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 ()); + unsigned i2caddr = m_pConfig->GetLCDI2CAddress (); + if (i2caddr == 0) + { + 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 ()); + } + else + { + m_pLCD = new CHD44780Device (m_pI2CMaster, i2caddr, + CConfig::LCDColumns, CConfig::LCDRows); + } assert (m_pLCD); if (!m_pLCD->Initialize ()) diff --git a/src/userinterface.h b/src/userinterface.h index 437993a..726abbd 100644 --- a/src/userinterface.h +++ b/src/userinterface.h @@ -26,13 +26,14 @@ #include #include #include +#include class CMiniDexed; class CUserInterface { public: - CUserInterface (CMiniDexed *pMiniDexed, CGPIOManager *pGPIOManager, CConfig *pConfig); + CUserInterface (CMiniDexed *pMiniDexed, CGPIOManager *pGPIOManager, CI2CMaster *pI2CMaster, CConfig *pConfig); ~CUserInterface (void); bool Initialize (void); @@ -58,6 +59,7 @@ private: private: CMiniDexed *m_pMiniDexed; CGPIOManager *m_pGPIOManager; + CI2CMaster *m_pI2CMaster; CConfig *m_pConfig; CHD44780Device *m_pLCD;