Initial commit of SSD1322/u8x8 support

pull/3/head
Dirk Niggemann 5 years ago
parent 0581978f70
commit aabcb40f23
  1. 86
      MicroDexed.ino
  2. 98
      SSD1322_Plus.h
  3. 107
      UI.hpp

@ -42,7 +42,8 @@ AudioPlayQueue dexed1;
AudioAnalyzePeak peak1; AudioAnalyzePeak peak1;
AudioEffectDelay delay_r; AudioEffectDelay delay_r;
AudioEffectDelay delay_l; AudioEffectDelay delay_l;
AudioEffectFreeverbStereo freeverbs1; AudioEffectFreeverb freeverb_r;
AudioEffectFreeverb freeverb_l;
AudioEffectModulatedDelay modchorus_r; AudioEffectModulatedDelay modchorus_r;
AudioEffectModulatedDelay modchorus_l; AudioEffectModulatedDelay modchorus_l;
#if MOD_FILTER_OUTPUT != MOD_NO_FILTER_OUTPUT #if MOD_FILTER_OUTPUT != MOD_NO_FILTER_OUTPUT
@ -61,7 +62,7 @@ AudioMixer4 reverb_mixer_r;
AudioMixer4 reverb_mixer_l; AudioMixer4 reverb_mixer_l;
AudioAmplifier volume_r; AudioAmplifier volume_r;
AudioAmplifier volume_l; AudioAmplifier volume_l;
#ifdef MIDI_DEVICE_USB #if defined(AUDIO_DEVICE_USB)
AudioOutputUSB usb1; AudioOutputUSB usb1;
#endif #endif
AudioConnection patchCord0(dexed1, peak1); AudioConnection patchCord0(dexed1, peak1);
@ -97,30 +98,30 @@ AudioConnection patchCord24(delay_r, 0, delay_mixer_r, 2);
AudioConnection patchCord25(delay_l, 0, delay_mixer_l, 2); AudioConnection patchCord25(delay_l, 0, delay_mixer_l, 2);
AudioConnection patchCord26(delay_fb_mixer_r, delay_r); AudioConnection patchCord26(delay_fb_mixer_r, delay_r);
AudioConnection patchCord27(delay_fb_mixer_l, delay_l); AudioConnection patchCord27(delay_fb_mixer_l, delay_l);
AudioConnection patchCord28(delay_mixer_r, 0, freeverbs1, 1); AudioConnection patchCord28(freeverb_r, 0, reverb_mixer_r, 1);
AudioConnection patchCord29(delay_mixer_l, 0, freeverbs1, 1); AudioConnection patchCord29(freeverb_l, 0, reverb_mixer_l, 1);
AudioConnection patchCord30(freeverbs1, 0, reverb_mixer_r, 1); AudioConnection patchCord30(reverb_mixer_r, volume_r);
AudioConnection patchCord31(freeverbs1, 1, reverb_mixer_l, 1); AudioConnection patchCord31(reverb_mixer_l, volume_l);
AudioConnection patchCord32(reverb_mixer_r, volume_r); #if defined(AUDIO_DEVICE_USB)
AudioConnection patchCord33(reverb_mixer_l, volume_l); AudioConnection patchCord32(volume_r, 0, usb1, 0);
#ifdef MIDI_DEVICE_USB AudioConnection patchCord33(volume_l, 0, usb1, 1);
AudioConnection patchCord34(volume_r, 0, usb1, 0);
AudioConnection patchCord35(volume_l, 0, usb1, 1);
#endif #endif
#if defined(TEENSY_AUDIO_BOARD) #if defined(TEENSY_AUDIO_BOARD) || defined (I2S_AUDIO_ONLY)
AudioOutputI2S i2s1; AudioOutputI2S i2s1;
AudioConnection patchCord36(volume_r, 0, i2s1, 0); AudioConnection patchCord34(volume_r, 0, i2s1, 0);
AudioConnection patchCord37(volume_l, 0, i2s1, 1); AudioConnection patchCord35(volume_l, 0, i2s1, 1);
#endif
#if defined(TEENSY_AUDIO_BOARD)
AudioControlSGTL5000 sgtl5000_1; AudioControlSGTL5000 sgtl5000_1;
#elif defined(TGA_AUDIO_BOARD) #elif defined(TGA_AUDIO_BOARD)
AudioOutputI2S i2s1; AudioOutputI2S i2s1;
AudioConnection patchCord36(volume_r, 0, i2s1, 0); AudioConnection patchCord34(volume_r, 0, i2s1, 0);
AudioConnection patchCord37(volume_l, 0, i2s1, 1); AudioConnection patchCord35(volume_l, 0, i2s1, 1);
AudioControlWM8731master wm8731_1; AudioControlWM8731master wm8731_1;
#else #elif !defined(I2S_AUDIO_ONLY)
AudioOutputPT8211 pt8211_1; AudioOutputPT8211 pt8211_1;
AudioConnection patchCord36(volume_r, 0, pt8211_1, 0); AudioConnection patchCord34(volume_r, 0, pt8211_1, 0);
AudioConnection patchCord37(volume_l, 0, pt8211_1, 1); AudioConnection patchCord35(volume_l, 0, pt8211_1, 1);
#endif #endif
Dexed* dexed = new Dexed(SAMPLE_RATE); Dexed* dexed = new Dexed(SAMPLE_RATE);
@ -165,42 +166,25 @@ short r_delayline[MOD_DELAY_SAMPLE_BUFFER];
/*********************************************************************** /***********************************************************************
LCDMenuLib2 LCDMenuLib2
***********************************************************************/ ***********************************************************************/
extern LiquidCrystalPlus_I2C lcd;
extern LCDMenuLib2 LCDML; extern LCDMenuLib2 LCDML;
extern uint8_t menu_state; extern uint8_t menu_state;
#endif #endif
void change_disp_sd(bool disp)
{
digitalWrite(SDCARD_CS_PIN, disp);
digitalWrite(U8X8_CS_PIN, !disp);
}
void setup() void setup()
{ {
//while (!Serial) ; // wait for Arduino Serial Monitor //while (!Serial) ; // wait for Arduino Serial Monitor
Serial.begin(SERIAL_SPEED); Serial.begin(SERIAL_SPEED);
pinMode(SDCARD_CS_PIN, OUTPUT);
pinMode(U8X8_CS_PIN, OUTPUT);
#ifdef ENABLE_LCD_UI #ifdef ENABLE_LCD_UI
// LCD Begin setup_ui();
lcd.init();
lcd.backlight();
lcd.clear();
lcd.blink_off();
lcd.cursor_off();
lcd.backlight();
lcd.setCursor(1, 0);
lcd.print("MicroDexed");
lcd.setCursor(0, 1);
lcd.print("(c)parasiTstudio");
// set special chars for scrollbar
lcd.createChar(0, (uint8_t*)scroll_bar[0]);
lcd.createChar(1, (uint8_t*)scroll_bar[1]);
lcd.createChar(2, (uint8_t*)scroll_bar[2]);
lcd.createChar(3, (uint8_t*)scroll_bar[3]);
lcd.createChar(4, (uint8_t*)scroll_bar[4]);
// LCDMenuLib Setup
LCDML_setup(_LCDML_DISP_cnt);
// Enable Menu Rollover
//LCDML.MENU_enRollover();
// Enable Screensaver (screensaver menu function, time to activate in ms)
//LCDML.SCREEN_enable(UI_func_voice_selection, VOICE_SELECTION_MS); // set to 10 seconds
#else #else
Serial.println(F("NO LCD DISPLAY ENABLED!")); Serial.println(F("NO LCD DISPLAY ENABLED!"));
#endif #endif
@ -255,13 +239,18 @@ void setup()
wm8731_1.enable(); wm8731_1.enable();
wm8731_1.volume(1.0); wm8731_1.volume(1.0);
Serial.println(F("TGA board enabled.")); Serial.println(F("TGA board enabled."));
#elif defined(I2S_AUDIO_ONLY)
Serial.println(F("I2S enabled."));
#else #else
Serial.println(F("PT8211 enabled.")); Serial.println(F("PT8211 enabled."));
#endif #endif
// start SD card // start SD card
#ifndef __IMXRT1062__
SPI.setMOSI(SDCARD_MOSI_PIN); SPI.setMOSI(SDCARD_MOSI_PIN);
SPI.setSCK(SDCARD_SCK_PIN); SPI.setSCK(SDCARD_SCK_PIN);
#endif
change_disp_sd(false);
if (!SD.begin(SDCARD_CS_PIN)) if (!SD.begin(SDCARD_CS_PIN))
{ {
Serial.println(F("SD card not accessable.")); Serial.println(F("SD card not accessable."));
@ -300,7 +289,7 @@ void setup()
// load default SYSEX data // load default SYSEX data
load_sysex(configuration.bank, configuration.voice); load_sysex(configuration.bank, configuration.voice);
} }
change_disp_sd(true);
// Init effects // Init effects
if (!modchorus_r.begin(r_delayline, MOD_DELAY_SAMPLE_BUFFER)) { if (!modchorus_r.begin(r_delayline, MOD_DELAY_SAMPLE_BUFFER)) {
Serial.println(F("AudioEffectModulatedDelay - right channel begin failed")); Serial.println(F("AudioEffectModulatedDelay - right channel begin failed"));
@ -443,6 +432,7 @@ void loop()
{ {
#ifdef ENABLE_LCD_UI #ifdef ENABLE_LCD_UI
// LCD Menu // LCD Menu
delay(1);
LCDML.loop(); LCDML.loop();
// initial starts voice selection menu as default // initial starts voice selection menu as default
@ -637,7 +627,9 @@ void handleProgramChange(byte inChannel, byte inProgram)
{ {
if (inProgram < MAX_VOICES) if (inProgram < MAX_VOICES)
{ {
change_disp_sd(false);
load_sysex(configuration.bank, inProgram); load_sysex(configuration.bank, inProgram);
change_disp_sd(true);
} }
} }

@ -0,0 +1,98 @@
/*
MicroDexed
MicroDexed is a port of the Dexed sound engine
(https://github.com/asb2m10/dexed) for the Teensy-3.5/3.6 with audio shield.
Dexed ist heavily based on https://github.com/google/music-synthesizer-for-android
(c)2018 H. Wirtz <wirtz@parasitstudio.de>
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, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <U8x8lib.h>
#ifndef SSD1322_PLUS_H_INCLUDED
#define SSD1322_PLUS_H_INCLUDED
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
#define STRING_BUF_SIZE 21
class SSD1322_Plus : public U8X8_SSD1322_NHD_256X64_4W_HW_SPI
{
public:
using U8X8_SSD1322_NHD_256X64_4W_HW_SPI::U8X8_SSD1322_NHD_256X64_4W_HW_SPI;
void show(uint8_t y, uint8_t x, uint8_t fs, char *str)
{
_show(y, x, fs, str, false, false);
}
void show(uint8_t y, uint8_t x, uint8_t fs, long num)
{
char _buf10[STRING_BUF_SIZE];
_show(y, x, fs, itoa(num, _buf10, 10), true, true);
}
private:
void _show(uint8_t pos_y, uint8_t pos_x, uint8_t field_size, char *str, bool justify_right, bool fill_zero)
{
{
char tmp[STRING_BUF_SIZE];
char *s = tmp;
uint8_t l = strlen(str);
memset(tmp, 0, sizeof(tmp));
if (fill_zero == true)
memset(tmp, '0', field_size);
else
memset(tmp, 0x20, field_size - 1); // blank
if (l > field_size)
l = field_size;
if (justify_right == true)
s += field_size - l;
strncpy(s, str, l);
//setCursor(pos_x * getMaxCharWidth(), pos_y * getMaxCharHeight());
setCursor(pos_x, pos_y );
print(tmp);
#ifdef DEBUG
Serial.print(pos_y, DEC);
Serial.print(F("/"));
Serial.print(pos_x, DEC);
Serial.print(F(": ["));
Serial.print(tmp);
Serial.println(F("]"));
#endif
}
}
};
#endif

107
UI.hpp

@ -27,14 +27,23 @@
#define _UI_HPP_ #define _UI_HPP_
#include "config.h" #include "config.h"
#ifdef I2C_DISPLAY
#include "LiquidCrystalPlus_I2C.h" #include "LiquidCrystalPlus_I2C.h"
#endif
#ifdef U8X8_DISPLAY
#include "SSD1322_Plus.h"
#endif
#include <LCDMenuLib2.h> #include <LCDMenuLib2.h>
#include <Encoder.h> #include <Encoder.h>
#define _LCDML_DISP_cols LCD_cols #define _LCDML_DISP_cols LCD_cols
#define _LCDML_DISP_rows LCD_rows #define _LCDML_DISP_rows LCD_rows
#ifdef I2C_DISPLAY
#define _LCDML_DISP_cfg_cursor 0x7E // cursor Symbol #define _LCDML_DISP_cfg_cursor 0x7E // cursor Symbol
#else
#define _LCDML_DISP_cfg_cursor 0x8d // cursor Symbol
#endif
#define _LCDML_DISP_cfg_scrollbar 1 // enable a scrollbar #define _LCDML_DISP_cfg_scrollbar 1 // enable a scrollbar
extern config_t configuration; extern config_t configuration;
@ -47,6 +56,7 @@ extern void strip_extension(char* s, char *target);
extern void eeprom_write(void); extern void eeprom_write(void);
extern bool get_voice_names_from_bank(uint8_t b); extern bool get_voice_names_from_bank(uint8_t b);
extern bool load_sysex(uint8_t b, uint8_t v); extern bool load_sysex(uint8_t b, uint8_t v);
extern void change_disp_sd(bool d);
extern value_change_t soften_volume; extern value_change_t soften_volume;
extern value_change_t soften_filter_res; extern value_change_t soften_filter_res;
extern value_change_t soften_filter_cut; extern value_change_t soften_filter_cut;
@ -56,7 +66,13 @@ extern value_change_t soften_filter_cut;
************************************************************************/ ************************************************************************/
elapsedMillis back_from_volume; elapsedMillis back_from_volume;
#ifdef I2C_DISPLAY
LiquidCrystalPlus_I2C lcd(LCD_I2C_ADDRESS, _LCDML_DISP_cols, _LCDML_DISP_rows); LiquidCrystalPlus_I2C lcd(LCD_I2C_ADDRESS, _LCDML_DISP_cols, _LCDML_DISP_rows);
#endif
#ifdef U8X8_DISPLAY
SSD1322_Plus lcd(/* cs=*/ U8X8_CS_PIN, /* dc=*/ U8X8_DC_PIN, /* reset=*/ U8X8_RESET_PIN);
#endif
const uint8_t scroll_bar[5][8] = { const uint8_t scroll_bar[5][8] = {
{B10001, B10001, B10001, B10001, B10001, B10001, B10001, B10001}, // scrollbar top {B10001, B10001, B10001, B10001, B10001, B10001, B10001, B10001}, // scrollbar top
@ -109,6 +125,7 @@ void UI_func_volume(uint8_t param);
void UI_func_back(uint8_t param); void UI_func_back(uint8_t param);
void UI_func_goToRootMenu(uint8_t param); void UI_func_goToRootMenu(uint8_t param);
// normal menu // normal menu
LCDMenuLib2_menu LCDML_0(255, 0, 0, NULL, NULL); // normal root menu element (do not change) LCDMenuLib2_menu LCDML_0(255, 0, 0, NULL, NULL); // normal root menu element (do not change)
LCDMenuLib2 LCDML(LCDML_0, _LCDML_DISP_rows, _LCDML_DISP_cols, lcdml_menu_display, lcdml_menu_clear, lcdml_menu_control); LCDMenuLib2 LCDML(LCDML_0, _LCDML_DISP_rows, _LCDML_DISP_cols, lcdml_menu_display, lcdml_menu_clear, lcdml_menu_control);
@ -158,6 +175,63 @@ long g_LCDML_CONTROL_button_press_time[NUM_ENCODER] = {0, 0};
bool g_LCDML_CONTROL_button_prev[NUM_ENCODER] = {HIGH, HIGH}; bool g_LCDML_CONTROL_button_prev[NUM_ENCODER] = {HIGH, HIGH};
uint8_t g_LCDML_CONTROL_prev[NUM_ENCODER] = {0, 0}; uint8_t g_LCDML_CONTROL_prev[NUM_ENCODER] = {0, 0};
#ifdef U8X8_DISPLAY
const uint8_t * flipped_scroll_bar[5];
uint8_t * rotTile(const uint8_t * tile) {
uint8_t * newt = new uint8_t[8];
for (int x = 0; x < 8; x++) {
uint8_t newb = 0;
for (int y = 0 ; y < 8; y++){
newb |= (tile[y] << x) & 0x80;
newb >>= 1;
}
newt[x] = newb;
}
return newt;
}
#endif
void setup_ui(void){
// LCD Begin
#ifdef I2C_DISPLAY
lcd.init();
lcd.backlight();
lcd.clear();
lcd.blink_off();
lcd.cursor_off();
lcd.backlight();
#else
lcd.begin();
lcd.clear();
lcd.setFont(u8x8_font_amstrad_cpc_extended_f);
#endif
lcd.setCursor(1, 0);
lcd.print("MicroDexed");
lcd.setCursor(0, 1);
lcd.print("(c)parasiTstudio");
#ifdef I2C_DISPLAY
// set special chars for scrollbar
lcd.createChar(0, (uint8_t*)scroll_bar[0]);
lcd.createChar(1, (uint8_t*)scroll_bar[1]);
lcd.createChar(2, (uint8_t*)scroll_bar[2]);
lcd.createChar(3, (uint8_t*)scroll_bar[3]);
lcd.createChar(4, (uint8_t*)scroll_bar[4]);
#else
for (int x=0; x < 5; x++) {
flipped_scroll_bar[x] = rotTile(scroll_bar[x]);
}
#endif
// LCDMenuLib Setup
LCDML_setup(_LCDML_DISP_cnt);
// Enable Menu Rollover
//LCDML.MENU_enRollover();
// Enable Screensaver (screensaver menu function, time to activate in ms)
//LCDML.SCREEN_enable(UI_func_voice_selection, VOICE_SELECTION_MS); // set to 10 seconds
}
void lcdml_menu_control(void) void lcdml_menu_control(void)
{ {
// If something must init, put in in the setup condition // If something must init, put in in the setup condition
@ -326,8 +400,11 @@ void encoder_right_up(void)
if (configuration.bank < MAX_BANKS) if (configuration.bank < MAX_BANKS)
{ {
configuration.bank++; configuration.bank++;
change_disp_sd(false);
load_sysex(configuration.bank, configuration.voice); load_sysex(configuration.bank, configuration.voice);
get_voice_names_from_bank(configuration.bank); get_voice_names_from_bank(configuration.bank);
change_disp_sd(true);
} }
break; break;
case MENU_VOICE_SOUND: case MENU_VOICE_SOUND:
@ -341,9 +418,12 @@ void encoder_right_up(void)
configuration.voice = 0; configuration.voice = 0;
} }
} }
change_disp_sd(false);
load_sysex(configuration.bank, configuration.voice); load_sysex(configuration.bank, configuration.voice);
get_voice_names_from_bank(configuration.bank); get_voice_names_from_bank(configuration.bank);
change_disp_sd(true);
eeprom_write(); eeprom_write();
} }
UI_func_voice_selection(0); UI_func_voice_selection(0);
break; break;
@ -369,8 +449,12 @@ void encoder_right_down(void)
if (configuration.bank > 0) if (configuration.bank > 0)
{ {
configuration.bank--; configuration.bank--;
change_disp_sd(false);
load_sysex(configuration.bank, configuration.voice); load_sysex(configuration.bank, configuration.voice);
get_voice_names_from_bank(configuration.bank); get_voice_names_from_bank(configuration.bank);
change_disp_sd(true);
} }
break; break;
case MENU_VOICE_SOUND: case MENU_VOICE_SOUND:
@ -384,8 +468,11 @@ void encoder_right_down(void)
configuration.voice = 31; configuration.voice = 31;
} }
} }
change_disp_sd(false);
load_sysex(configuration.bank, configuration.voice); load_sysex(configuration.bank, configuration.voice);
get_voice_names_from_bank(configuration.bank); get_voice_names_from_bank(configuration.bank);
change_disp_sd(true);
eeprom_write(); eeprom_write();
} }
UI_func_voice_selection(0); UI_func_voice_selection(0);
@ -567,8 +654,13 @@ void lcdml_menu_display(void)
// delete or reset scrollbar // delete or reset scrollbar
if (_LCDML_DISP_cfg_scrollbar == 1) { if (_LCDML_DISP_cfg_scrollbar == 1) {
if (scrollbar_max > n_max) { if (scrollbar_max > n_max) {
#ifdef I2C_DISPLAY
lcd.setCursor((_LCDML_DISP_cols - 1), n); lcd.setCursor((_LCDML_DISP_cols - 1), n);
lcd.write((uint8_t)0); lcd.write((uint8_t)0);
#else
lcd.drawTile((_LCDML_DISP_cols - 1), n, 1, flipped_scroll_bar[0]);
lcd.setCursor((_LCDML_DISP_cols), n+1);
#endif
} }
else { else {
lcd.setCursor((_LCDML_DISP_cols - 1), n); lcd.setCursor((_LCDML_DISP_cols - 1), n);
@ -583,16 +675,31 @@ void lcdml_menu_display(void)
//set scroll position //set scroll position
if (scrollbar_cur_pos == scrollbar_min) { if (scrollbar_cur_pos == scrollbar_min) {
// min pos // min pos
#ifdef I2C_DISPLAY
lcd.setCursor((_LCDML_DISP_cols - 1), 0); lcd.setCursor((_LCDML_DISP_cols - 1), 0);
lcd.write((uint8_t)1); lcd.write((uint8_t)1);
#else
lcd.drawTile((_LCDML_DISP_cols - 1), 0, 1, flipped_scroll_bar[1]);
lcd.setCursor((_LCDML_DISP_cols), 1);
#endif
} else if (scrollbar_cur_pos == (scrollbar_max - 1)) { } else if (scrollbar_cur_pos == (scrollbar_max - 1)) {
// max pos // max pos
#ifdef I2C_DISPLAY
lcd.setCursor((_LCDML_DISP_cols - 1), (n_max - 1)); lcd.setCursor((_LCDML_DISP_cols - 1), (n_max - 1));
lcd.write((uint8_t)4); lcd.write((uint8_t)4);
#else
lcd.drawTile((_LCDML_DISP_cols - 1), (n_max - 1), 1, flipped_scroll_bar[4]);
lcd.setCursor((_LCDML_DISP_cols), (n_max));
#endif
} else { } else {
// between // between
#ifdef I2C_DISPLAY
lcd.setCursor((_LCDML_DISP_cols - 1), scroll_pos / n_max); lcd.setCursor((_LCDML_DISP_cols - 1), scroll_pos / n_max);
lcd.write((uint8_t)(scroll_pos % n_max) + 1); lcd.write((uint8_t)(scroll_pos % n_max) + 1);
#else
lcd.drawTile((_LCDML_DISP_cols - 1), scroll_pos / n_max, 1, flipped_scroll_bar[(scroll_pos % n_max) + 1]);
lcd.setCursor((_LCDML_DISP_cols), (scroll_pos / n_max)+1);
#endif
} }
} }
} }

Loading…
Cancel
Save