This is a part of the Kinetiszer project.
Diff: user_interface.c
- Revision:
- 0:cb80470434eb
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/user_interface.c Tue Oct 28 12:19:42 2014 +0000 @@ -0,0 +1,412 @@ +/* + * @brief User interface + * + * @note + * Copyright (C) Elektor, 2014 + * All rights reserved. + * + * @par + * This software is supplied "AS IS" without any warranties of any kind, + * and Elektor and its licensor disclaim any and all warranties, express + * or implied, including all implied warranties of merchantability, + * fitness for a particular purpose and non-infringement of intellectual + * property rights. Elektor assumes no responsibility or liability for + * the use of the software, conveys no license or rights under any patent, + * copyright, mask work right, or any other intellectual property rights in + * or to any products. Elektor reserves the right to make changes in the + * software without notification. Elektor also makes no representation or + * warranty that such application will be suitable for the specified use + * without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under Elektor's and its licensor's + * relevant copyrights in the software, without fee. This copyright, + * permission, and disclaimer notice must appear in all copies of this code. + */ + +#include "lcd.h" +#include "atmegatron.h" +#include "board.h" + + +#define FUNCTION_VALUE_OFFSET (13) + + +uint8_t display_page = (uint8_t)-1; +boolean display_page_changed = false; + + +const char *functions_str[FUNC_MAX][2] = +{ + { "Waveform bank ", "" }, + { "Filter ", "(norming)" }, + { "Env1 attack", "Inverted" }, + { "Env1 dec/rel", "Inverted" }, + { "Env1 sustain", "Inverted" }, + { "Env2 attack", "SysEx write" }, + { "Env2 decay", "SysEx read" }, + { "Env2 sustain", "User wave" }, + { "Env2 release", "SysEx bank" }, + { "LFO shape ", "(inv)" }, + { "LFO rate ", "" }, + { "Arpeggio ", "(pp)" }, + { "Arpeggio rate", "" }, + { "Portamento", "Proportional" }, + { "Crusher ", "pre-filter" }, + { "Patch number", "Empty" }, +}; + + +const char *wave_str[FUNC_MAX][2] = +{ + { "Pure square", "Metallic 1" }, + { "Octave square", "Metallic 2" }, + { "Square fifths", "Metallic 3" }, + { "RP2A07 square ", "Metallic 4" }, + { "Pure saw", "Vocal 1" }, + { "Buzz saw", "Vocal 2" }, + { "Saw fifths", "Vocal 3" }, + { "Octave saw", "Brass" }, + { "Subsine + square", "Reed organ" }, + { "Pure sine", "Electric piano" }, + { "PPG sine", "Reed" }, + { "Warped sine ", "Resonant saw" }, + { "CZ101 pulse", "Bell" }, + { "Bassoon", "Chord" }, + { "Bass", "Overtones" }, + { "Noise", "Saw thirds" }, +}; + + +const char *filter_str[FUNC_MAX] = +{ + "Bypassed", + "Low pass", + "High pass", + "Band pass", + "Notch", + "Param EQ 10 dB", + "Param EQ 30 dB", + "Param EQ 100 dB", + "LO shelf 10 dB", + "LO shelf 30 dB", + "HI shelf 10 dB", + "HI shelf 30 dB", + "Butter LP (no Q)", + "Butter HP (no Q)", + "Bessel LP (no Q)", + "Bessel HP (no Q)", +}; + + +const char *lfo_str[FUNC_MAX] = +{ + "Sine", + "Triangle", + "Ramp down (lin)", + "Ramp up (exp)", + "Sine + 3rd", + "Pulse 5%", + "Pulse 25%", + "Pulse 50%", + "Pulse 75%", + "Pulse 95%", + "Ramp up & hold", + "Hold & ramp down", + "Duh dugga", + "Dugga duh", + "Noise-like", + "DC", +}; + + +const char *arp_str[FUNC_MAX] = +{ + "Off", + "Up", + "Down", + "Octave", + "Fifths", + "Skip one up", + "Skip one down", + "I feel love", + "Horton", + "Etheridge", + "Meads", + "Palmer", + "gwEm 1", + "gwEm 2", + "Triplet up", + "Robyn", +}; + +const char *rate_str[FUNC_MAX] = +{ + "4", + "2", + "1", + "3/4", + "2/3", + "1/2", + "3/8", + "1/3", + "1/4", + "3/16", + "1/8", + "3/32", + "1/16", + "3/64", + "1/32", + "1/64", +}; + + +const char *crusher_str[FUNC_MAX] = +{ + "Off", + "3 bit", + "2 bit", + "1 bit", + "4 bit, SR/2", + "3 bit, SR/2", + "2 bit, SR/2", + "1 bit, SR/2", + "4 bit, SR/4", + "3 bit, SR/4", + "2 bit, SR/4", + "1 bit, SR/4", + "4 bit, SR/8", + "3 bit, SR/8", + "2 bit, SR/8", + "1 bit, SR/8", +}; + + +/*const char *controls_str[CTRL_MAX][2] = +{ + // Digital controls (potentiometers) + { "Filt cutoff", "Filt cutoff" }, + { "Filter Q", "Filter Q" }, + { "Filter env", "Pitch env" }, + { "Filter LFO", "Pitch LFO" }, + { "Amp LFO", "PW LFO" }, + { "Distortion", "Phase LFO" }, +};*/ + + +void display_init(void) +{ + // Setup LCD. + lcd_init(); + display_page_set(PAGE_SPLASH); +} + + +void display_print_value(uint8_t line, uint8_t position, int value, boolean ignore_sign) +{ + int scale = 100; + + lcd_clear_to_eol(line,position); + if (ignore_sign==false) + { + if (value<0) + { + lcd_putc('-'); + value = -value; + } + else lcd_putc(' '); + } + + if (value<100) + { + lcd_putc(' '); + scale = 10; + } + if (value<10) + { + lcd_putc(' '); + scale = 1; + } + + do + { + int temp = value/scale; + lcd_putc(temp+'0'); + value -= temp*scale; + scale /= 10; + } + while (scale>0); +} + + +void display_page_splash(void) +{ + lcd_clear(); + lcd_font(ST7032_FUNC_HEIGHT_DOUBLE); + lcd_puts("J2B Synthesizer"); + SysTick_Delay(1500); + lcd_font(ST7032_FUNC_HEIGHT_NORMAL); + display_page_set(PAGE_FUNCTION); +} + + +void display_page_function(void) +{ + uint8_t function = Hardware_Get_Function(); + boolean shift = Hard_Get_Shift(function); + uint8_t value = Hardware_Get_Value(function); + + lcd_clear(); + if (function>=FUNC_MAX) + { + lcd_puts((char*)"undefined"); + } + else + { + lcd_puts((char*)functions_str[function][0]); + switch (function) + { + case FUNC_WAVE: + if (shift==GREEN) lcd_putc('2'); + else lcd_putc('1'); + lcd_cursor(1,0); + lcd_puts((char*)wave_str[value][shift]); + break; + + case FUNC_FILT: + if (shift==GREEN) lcd_puts((char*)functions_str[function][1]); + lcd_cursor(1,0); + lcd_puts((char*)filter_str[value]); + break; + + case FUNC_LFOTYPE: + if (shift==GREEN) lcd_puts((char*)functions_str[function][1]); + lcd_cursor(1,0); + lcd_puts((char*)lfo_str[value]); + break; + + case FUNC_LFOSPEED: + case FUNC_ARPSPEED: + if (shift==GREEN) lcd_puts((char*)functions_str[function][1]); + lcd_cursor(1,0); + lcd_puts((char*)rate_str[value]); + break; + + case FUNC_ARPTYPE: + if (shift==GREEN) lcd_puts((char*)functions_str[function][1]); + lcd_cursor(1,0); + lcd_puts((char*)arp_str[value]); + break; + + case FUNC_BITCRUSH: + if (shift==GREEN) lcd_puts("(pre)"); + else lcd_puts("(post)"); + lcd_cursor(1,0); + lcd_puts((char*)crusher_str[value]); + break; + + case FUNC_MEM: + { + uint8_t buffer[MEM_PATCHSIZE]; + display_print_value(0,FUNCTION_VALUE_OFFSET,value+1,true); + if (Memory_Load_Patch(buffer,value*MEM_PATCHSIZE)==false) + { + lcd_cursor(1,0); + lcd_puts((char*)functions_str[function][1]); + } + break; + } + + default: + display_print_value(0,FUNCTION_VALUE_OFFSET,value,true); + if (shift==GREEN) + { + lcd_cursor(1,0); + lcd_puts((char*)functions_str[function][1]); + } + } + } +} + + +extern uint8_t encoder_to_ctrl[8]; + +void display_page_ctrl(void) +{ + uint8_t i, column, value, dec; + uint8_t shift = Hardware_Get_Ctrl_Shift(); + + lcd_clear(); + + for (i=0; i<6; i++) + { + column = 3*(encoder_to_ctrl[i+2]-2); + value = Hardware_Get_Ctrl(shift,i); + if ((i==CTRL_AMP || i==CTRL_FX) && shift!=0) + { + lcd_cursor(1,column-1); + value >>= 3; + dec = value/10; + if (dec>0) + { + value -= 10*dec; + lcd_putc(dec+'0'); + } + else lcd_putc(' '); + lcd_putc(value+'0'); + } + else if (i==CTRL_FX && shift==0) + { + lcd_cursor(1,column); + lcd_putc((value>>5)+'0'); + } + else + { + lcd_bar_graph(column,value,255); + } + } +} + + +boolean display_page_set(uint8_t page) +{ + display_page_changed = display_page!=page? true : false; + display_page = page; + return display_page_changed; +} + + +uint8_t display_page_get(void) +{ + return display_page; +} + + +void display_invalidate(void) +{ + display_page_changed = true; +} + + +void display_draw(boolean force_redraw) +{ + if (display_page_changed==true || force_redraw==true) + { + display_page_changed = false; + switch (display_page) + { + case PAGE_SPLASH: + display_page_splash(); + break; + + case PAGE_FUNCTION: + display_page_function(); + break; + + case PAGE_CTRL: + display_page_ctrl(); + break; + } + } +}