/* ANALOG INPUT EXPANDER */
/*
-Copyright 2021 Balthasar Szczepański
+Copyright 2021, 2025 Balthasar Szczepański
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
data = AIX_RX__SDR; // get byte
- if((aix_buffer_w + 1 == aix_buffer_r) || (aix_buffer_w + 1 == aix_buffer_r + N_AIX_BUFFER)) // buffer overflow
+ if(FULL_BP(aix_buffer_w, aix_buffer_r, N_AIX_BUFFER)) // buffer overflow
{}
else
{
aix_buffer[aix_buffer_w] = data;
// advance the pointer
- if (aix_buffer_w >= N_AIX_BUFFER - 1)
- aix_buffer_w = 0;
- else
- ++aix_buffer_w;
+ ADVANCE_BP(aix_buffer_w, N_AIX_BUFFER);
}
}
uint8_t data;
int16_t diff;
- if (aix_buffer_r != aix_buffer_w) // data waiting in buffer
+ if (NOT_EMPTY_BP(aix_buffer_w, aix_buffer_r, N_AIX_BUFFER)) // data waiting in buffer
{
// get data; advance pointer
data = aix_buffer[aix_buffer_r];
- if(aix_buffer_r >= N_AIX_BUFFER - 1)
- aix_buffer_r = 0;
- else
- ++aix_buffer_r;
+ ADVANCE_BP(aix_buffer_r, N_AIX_BUFFER);
if (data == '\n') //end of frame
{
/* COMMUNICATING WITH MAIN CONTROLLER */
/*
-Copyright 2021, 2024 Balthasar Szczepański
+Copyright 2021, 2024, 2025 Balthasar Szczepański
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
data = CTRL_RX__SDR; // get byte
- if((ctrl_rxbuffer_w + 1 == ctrl_rxbuffer_r) || (ctrl_rxbuffer_w + 1 == ctrl_rxbuffer_r + N_CTRL_RXBUFFER)) // buffer overflow
+ if (FULL_BP(ctrl_rxbuffer_w, ctrl_rxbuffer_r, N_CTRL_RXBUFFER)) // buffer overflow
ctrl_error |= ERR_OVERFLOW;
else
{
ctrl_rxbuffer[ctrl_rxbuffer_w] = data;
- // advance the pointer
- if (ctrl_rxbuffer_w >= N_CTRL_RXBUFFER - 1)
- ctrl_rxbuffer_w = 0;
- else
- ++ctrl_rxbuffer_w;
+ ADVANCE_BP(ctrl_rxbuffer_w, N_CTRL_RXBUFFER);
}
}
while (ctrl_state == CTRL_SEND) // send the command
{
- if((ctrl_txbuffer_w + 1 == ctrl_txbuffer_r) || (ctrl_txbuffer_w + 1 == ctrl_txbuffer_r + N_CTRL_TXBUFFER)) // no place in buffer
+ if (FULL_BP(ctrl_txbuffer_w, ctrl_txbuffer_r, N_CTRL_TXBUFFER)) // no place in buffer
break;
if (ctrl_index < 0) // start of frame, command id
{
io = '\n';
ctrl_state = CTRL_SWITCH; // GOTO next state
- ctrl_rxbuffer_r = ctrl_rxbuffer_w;
+ CLEAR_BP(ctrl_rxbuffer_w, ctrl_rxbuffer_r, N_CTRL_RXBUFFER);
}
else // data byte
{
// put to buffer, adnvance the pointer
ctrl_txbuffer[ctrl_txbuffer_w] = io;
- if (ctrl_txbuffer_w >= N_CTRL_TXBUFFER - 1)
- ctrl_txbuffer_w = 0;
- else
- ++ctrl_txbuffer_w;
+ ADVANCE_BP(ctrl_txbuffer_w, N_CTRL_TXBUFFER);
}
- if (ctrl_txbuffer_r != ctrl_txbuffer_w) // data in output buffer
+ if (NOT_EMPTY_BP(ctrl_txbuffer_w, ctrl_txbuffer_r, N_CTRL_TXBUFFER)) // data in output buffer
{
if(!(CTRL_TX__SSR & 0b01000000)) // uart is ready
{
CTRL_TX__IF = 0;
CTRL_TX__SDR = ctrl_txbuffer[ctrl_txbuffer_r]; // send the byte
-
- // advance the pointer
- if (ctrl_txbuffer_r >= N_CTRL_RXBUFFER - 1)
- ctrl_txbuffer_r = 0;
- else
- ++ctrl_txbuffer_r;
+ ADVANCE_BP(ctrl_txbuffer_r, N_CTRL_RXBUFFER); // advance the pointer
}
}
ctrl_resp = CMD_NOP;
}
- while (ctrl_rxbuffer_r != ctrl_rxbuffer_w) // data in input buffer
+ while (NOT_EMPTY_BP(ctrl_rxbuffer_w, ctrl_rxbuffer_r, N_CTRL_RXBUFFER)) // data in input buffer
{
// get the byte, advance the pointer
io = ctrl_rxbuffer[ctrl_rxbuffer_r];
- if(ctrl_rxbuffer_r >= N_CTRL_RXBUFFER -1 )
- ctrl_rxbuffer_r = 0;
- else
- ++ctrl_rxbuffer_r;
+ ADVANCE_BP(ctrl_rxbuffer_r, N_CTRL_RXBUFFER);
if (io == CMD_ERR) // received a complain from CTRL
{
// drop any action, immediately switch to listen
ctrl_state = CTRL_RECEIVE;
- ctrl_txbuffer_r = ctrl_txbuffer_w;
+ CLEAR_BP(ctrl_txbuffer_w, ctrl_txbuffer_r, N_CTRL_TXBUFFER);
}
if (ctrl_state == CTRL_RECEIVE) // actually expecting to receive
/* DEBUG SERIAL OUTPUT */
/*
-Copyright 2021 Balthasar Szczepański
+Copyright 2021, 2025 Balthasar Szczepański
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
{
uint8_t byte;
- if(debug_buffer_r != debug_buffer_w) // data waiting in buffer
+ if (NOT_EMPTY_BP(debug_buffer_w, debug_buffer_r, N_DEBUG_BUFFER)) // data waiting in buffer
{
byte = debug_buffer[debug_buffer_r]; // get the byte
}
else
return;
- // advance the pointer
- if(debug_buffer_r >= N_DEBUG_BUFFER - 1)
- debug_buffer_r = 0;
- else
- ++debug_buffer_r;
+ ADVANCE_BP(debug_buffer_r, N_DEBUG_BUFFER); // advance the pointer
}
}
const uint8_t blocking
)
{
- while((debug_buffer_w + 1 == debug_buffer_r) || (debug_buffer_w + 1 == debug_buffer_r + N_DEBUG_BUFFER))
+ while (FULL_BP(debug_buffer_w, debug_buffer_r, N_DEBUG_BUFFER))
{
if (blocking)
handle_debug();
return;
}
debug_buffer[debug_buffer_w] = value;
- if(debug_buffer_w >= N_DEBUG_BUFFER - 1)
- debug_buffer_w = 0;
- else
- ++debug_buffer_w;
+ ADVANCE_BP(debug_buffer_w, N_DEBUG_BUFFER);
}
void debug_string ( // send a string to debug output
/* GUI */
/*
-Copyright 2021, 2022, 2024 Balthasar Szczepański
+Copyright 2021, 2022, 2024, 2025 Balthasar Szczepański
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
uint8_t gui_return_state = GUI_WAVE;
uint8_t gui_errors = 0;
uint8_t gui_accepted_errors = GUI_ERRF_ALL;
+ int8_t gui_choice = GUI_NOCHOICE;
+ int16_t gui_used_voice_page = -1;
+ int16_t gui_used_voice_id = -1;
uint8_t gui_page=0;
uint8_t gui_name[N_NAME+1] = {[0 ... (N_NAME)] = '\0'};
inline void add_gui_event(const uint16_t event)
{
- if((gui_event_w + 1 == gui_event_r) || (gui_event_w + 1 == gui_event_r + N_GUI_EVENT)) // event buffer is full
+ if (FULL_BP(gui_event_w, gui_event_r, N_GUI_EVENT)) // event buffer is full
return;
else
{
// add event, advance pointer
gui_event[gui_event_w] = event;
- if (gui_event_w >= N_GUI_EVENT - 1)
- gui_event_w = 0;
- else
- ++gui_event_w;
+ ADVANCE_BP(gui_event_w, N_GUI_EVENT);
}
}
{
button_valid = 0; // reject any already pressed buttons
button_hold_count = 0; // to not get a long hold in new state
- gui_event_r = gui_event_w;
+ CLEAR_BP(gui_event_w, gui_event_r, N_GUI_EVENT);
}
inline void gui_trigger_error (const uint8_t error)
else if (event & (BUTTON_A | BUTTON_B))
{
gui_switch_wave();
+ gui_used_voice_page = -1;
+ gui_used_voice_id = -1;
}
else if (event & (BUTTON_C | BUTTON_D | BUTTON_E ))
{
gui_switch_adsr();
+ gui_used_voice_page = -1;
+ gui_used_voice_id = -1;
}
else if (event & BUTTON_F)
{
gui_lock_wave();
gui_lock_adsr();
}
+ gui_used_voice_page = -1;
+ gui_used_voice_id = -1;
}
break;
}
inline void gui_gotostate_select (void)
{
gui_state = GUI_SELECT;
+ // gui_choice = GUI_NOCHOICE;
draw_select();
reject_gui_events();
}
if (event & EVENT_LONG)
{
fs_delete_voice(id);
- lcd_update_button(id, "");
+ lcd_update_button(id, "", gui_choice == id);
reject_gui_events();
}
else
- lcd_update_button(id, GUI_BUTTONTEXT_CONFIRM_REMOVE);
+ lcd_update_button(id, GUI_BUTTONTEXT_CONFIRM_REMOVE, gui_choice == id);
}
}
else if (event & BUTTON_Y) // no need to check long hold
if (fs_is_voice_stored(id))
{
if (event & EVENT_WAS_HOLD)
- lcd_update_button(id, fs_page_names[id]);
+ lcd_update_button(id, fs_page_names[id], gui_choice == id);
else
{
gui_lock_adsr();
ctrl_update_adsr();
gui_update_adsr();
gui_update_wave();
+ if (gui_choice != id)
+ lcd_select_button(gui_choice, 0);
+ lcd_select_button(id, 1);
+ gui_used_voice_page = fs_page;
+ gui_used_voice_id = id;
+ gui_choice = id;
}
else
{
gui_unlock_adsr();
gui_unlock_wave();
+ gui_used_voice_page = -1;
+ gui_used_voice_id = -1;
+ if ((gui_choice >= 0) && (gui_choice <= 5))
+ lcd_select_button(gui_choice, 0);
+ gui_choice = GUI_NOCHOICE;
}
}
}
{
gui_unlock_adsr();
gui_unlock_wave();
+ gui_used_voice_page = -1;
+ gui_used_voice_id = -1;
+ if ((gui_choice >= 0) && (gui_choice <= 5))
+ lcd_select_button(gui_choice, 0);
+ gui_choice = GUI_NOCHOICE;
}
}
else if (event & BUTTON_X)
gui_name_pos = 0;
}
gui_state = GUI_NAME;
+ gui_choice = 2;
gui_name_list = gui_list_ABC;
gui_name_maxcursor = N_ABC-1;
GUI_BUTTONTEXT_ABC,
GUI_BUTTONTEXT_abc,
GUI_BUTTONTEXT_123,
- GUI_BUTTONTEXT_OK
+ GUI_BUTTONTEXT_OK,
+ gui_choice
);
reject_gui_events();
gui_ignore_event = new;
}
else
gui_name[gui_name_pos] = '\0';
- lcd_update_button(-1,gui_name);
+ lcd_update_button(-1, gui_name, 0);
}
else if (event & ( BUTTON_C | BUTTON_D | BUTTON_E ))
{
{
gui_name_list = gui_list_ABC;
gui_name_maxcursor = N_ABC-1;
+ if (gui_choice != 2)
+ lcd_select_button(gui_choice, 0);
+ gui_choice = 2;
+ lcd_select_button(2, 1);
}
else if (event & BUTTON_D)
{
gui_name_list = gui_list_abc;
gui_name_maxcursor = N_abc-1;
+ if (gui_choice != 3)
+ lcd_select_button(gui_choice, 0);
+ gui_choice = 3;
+ lcd_select_button(3, 1);
}
else if (event & BUTTON_E)
{
gui_name_list = gui_list_123;
gui_name_maxcursor = N_123-1;
+ if (gui_choice != 4)
+ lcd_select_button(gui_choice, 0);
+ gui_choice = 4;
+ lcd_select_button(4, 1);
}
lcd_draw_name_list(gui_name_list);
if (gui_name_cursor > gui_name_maxcursor)
if ((gui_name_pos < N_NAME) && (gui_name[gui_name_pos] != cursor))
{
gui_name[gui_name_pos] = cursor;
- lcd_update_button(-1, gui_name);
+ lcd_update_button(-1, gui_name, 0);
}
}
{
// gui_return_state = gui_state;
gui_state = GUI_SELECT_SAVE;
+ // gui_choice = GUI_NOCHOICE;
draw_select_save();
reject_gui_events();
}
if (event & (BUTTON_ABCDEF))
{
if (fs_is_voice_stored(id))
- lcd_update_button(id, GUI_BUTTONTEXT_CONFIRM_REPLACE);
+ lcd_update_button(id, GUI_BUTTONTEXT_CONFIRM_REPLACE, gui_choice==id);
}
break;
case EVENT_HOLD:
if (event & (BUTTON_ABCDEF))
{
if (fs_is_voice_stored(id))
- lcd_update_button(id, fs_page_names[id]);
+ lcd_update_button(id, fs_page_names[id], gui_choice==id);
else
{
fs_store_voice(
}
// OPTIONS: menu with some settings
+// TUNING: change tuning of instrument
+// TRANSPOSE: shift by -12 to 12 semitones
+// MIDI ID IN: choose MIDI channel ID for input
+// MIDI ID OUT: choose MIDI channel ID for output
+// MIDI PEDAL: allow / block MIDI pedal input
+// TOTAL RESET remove all stored voices from flash memory
inline void gui_gotostate_options (void)
{
make_text_midi_out ();
gui_state = GUI_OPTIONS;
+ gui_choice = GUI_NOCHOICE;
lcd_draw_menu (6,
GUI_TITLE_OPTIONS,"",
text_tuning,
text_midi_in,
text_midi_out,
midi_pedal_en ? GUI_BUTTONTEXT_MIDI_PEDAL : GUI_BUTTONTEXT_MIDI_NOPEDAL,
- GUI_BUTTONTEXT_RESET
+ GUI_BUTTONTEXT_RESET,
+ gui_choice
);
reject_gui_events();
}
switch (event & EVENT_BITS)
{
case EVENT_PRESS:
- if (event & BUTTON_F)
- lcd_update_button(5, GUI_BUTTONTEXT_CONFIRM_RESET);
+ if (event & BUTTON_A)
+ {
+ if (gui_choice != 0)
+ lcd_select_button(gui_choice, 0);
+ gui_choice = 0;
+ lcd_select_button(0, 1);
+ lcd_update_title(GUI_TITLE_OPTION_TUNING);
+ }
+ else if (event & BUTTON_B)
+ {
+ if (gui_choice != 1)
+ lcd_select_button(gui_choice, 0);
+ gui_choice = 1;
+ lcd_select_button(1, 1);
+ lcd_update_title(GUI_TITLE_OPTION_TRANSPOSE);
+ }
+ else if (event & BUTTON_C)
+ {
+ if (gui_choice != 2)
+ lcd_select_button(gui_choice, 0);
+ gui_choice = 2;
+ lcd_select_button(2, 1);
+ lcd_update_title(GUI_TITLE_OPTION_MIDI_ID);
+ }
+ else if (event & BUTTON_D)
+ {
+ if (gui_choice != 3)
+ lcd_select_button(gui_choice, 0);
+ gui_choice = 3;
+ lcd_select_button(3, 1);
+ lcd_update_title(GUI_TITLE_OPTION_MIDI_OUT_ID);
+ }
+ else if (event & BUTTON_E)
+ {
+ if (gui_choice != 4)
+ lcd_select_button(gui_choice, 0);
+ gui_choice = 4;
+ lcd_select_button(4, 1);
+ lcd_update_title(GUI_TITLE_OPTION_MIDI_PEDAL);
+ }
+ else if (event & BUTTON_F)
+ {
+ if (gui_choice != 5)
+ lcd_select_button(gui_choice, 0);
+ gui_choice = 5;
+ lcd_update_button(5, GUI_BUTTONTEXT_CONFIRM_RESET, 1);
+ lcd_update_title(GUI_TITLE_OPTION_TRANSPOSE);
+ }
break;
case EVENT_HOLD:
if (event & BUTTON_A)
{
set_tuning(DEFAULT_TUNING);
make_text_tuning();
- lcd_update_button(0, text_tuning);
+ lcd_update_button(0, text_tuning, 1);
reject_gui_events();
}
else if (event & BUTTON_B)
{
set_transp(0);
make_text_transpose();
- lcd_update_button(1, text_transpose);
+ lcd_update_button(1, text_transpose, 1);
reject_gui_events();
}
else if (event & BUTTON_C)
midi_id = N_MIDI_ID;
ctrl_update_midi();
make_text_midi_in();
- lcd_update_button(2, text_midi_in);
+ lcd_update_button(2, text_midi_in, 1);
reject_gui_events();
}
else if (event & BUTTON_D)
midi_id_out = 0;
ctrl_update_midi();
make_text_midi_out();
- lcd_update_button(3, text_midi_out);
+ lcd_update_button(3, text_midi_out, 1);
reject_gui_events();
}
// no long press on button E
gui_gotostate_wave();
else if (event & BUTTON_Y)
gui_gotostate_select();
- else if (event & BUTTON_A)
- gui_gotostate_tuning();
- else if (event & BUTTON_B)
- gui_gotostate_transpose();
- else if (event & BUTTON_C)
- gui_gotostate_midi_id();
- else if (event & BUTTON_D)
- gui_gotostate_midi_id_out();
else if (event & BUTTON_E)
{
if (midi_pedal_en)
{
midi_pedal_en = 0;
- lcd_update_button(4, GUI_BUTTONTEXT_MIDI_NOPEDAL);
+ lcd_update_button(4, GUI_BUTTONTEXT_MIDI_NOPEDAL, 1);
}
else
{
midi_pedal_en = 1;
- lcd_update_button(4, GUI_BUTTONTEXT_MIDI_PEDAL);
+ lcd_update_button(4, GUI_BUTTONTEXT_MIDI_PEDAL, 1);
}
ctrl_update_midi();
}
else if (event & BUTTON_F)
- lcd_update_button(5, GUI_BUTTONTEXT_RESET);
- break;
- }
-}
-
-// TUNING: change tuning of instrument
-
-inline void gui_gotostate_tuning (void)
-{
- make_text_tuning();
-
- gui_state = GUI_TUNING;
- lcd_draw_menu (6,
- GUI_TITLE_TUNING,"",
- text_tuning, "", "", "", "", ""
- );
- reject_gui_events();
-}
-
-inline void gui_event_tuning (const uint16_t event)
-{
- switch (event & EVENT_BITS)
- {
- case EVENT_HOLD:
- if (event & BUTTON_A)
- {
- set_tuning(DEFAULT_TUNING);
- make_text_tuning();
- lcd_update_button(0, text_tuning);
- reject_gui_events();
- }
- break;
- case EVENT_RELEASE:
- if (event & (BUTTON_A | BUTTON_X | BUTTON_Y))
- gui_gotostate_options();
+ lcd_update_button(5, GUI_BUTTONTEXT_RESET, 1);
break;
case EVENT_JOG:
- if ((event & JOG_BITS) == JOG_PLUS)
+ switch (gui_choice)
{
- set_tuning(tuning + gui_jog_boost(event & JOG_TIME_BITS));
- }
- else
- {
- set_tuning(tuning - gui_jog_boost(event & JOG_TIME_BITS));
- }
-
- make_text_tuning();
- lcd_update_button(0, text_tuning);
- break;
- }
-}
-
-// TRANSPOSE: shift by -12 to 12 semitones
-
-inline void gui_gotostate_transpose (void)
-{
- make_text_transpose();
-
- gui_state = GUI_TRANSPOSE;
- lcd_draw_menu (6,
- GUI_TITLE_TRANSPOSE,"",
- "",text_transpose, "", "", "", ""
- );
- reject_gui_events();
-}
-
-inline void gui_event_transpose (const uint16_t event)
-{
- switch (event & EVENT_BITS)
- {
- case EVENT_HOLD:
- if (event & BUTTON_B)
- {
- set_transp(0);
+ case 0:
+ if ((event & JOG_BITS) == JOG_PLUS)
+ {
+ set_tuning(tuning + gui_jog_boost(event & JOG_TIME_BITS));
+ }
+ else
+ {
+ set_tuning(tuning - gui_jog_boost(event & JOG_TIME_BITS));
+ }
+ make_text_tuning();
+ lcd_update_button(0, text_tuning, 1);
+ break;
+ case 1:
+ if ((event & JOG_BITS) == JOG_PLUS)
+ {
+ if (transp<12)
+ set_transp(transp + 1);
+ }
+ else
+ {
+ if (transp>-12)
+ set_transp(transp - 1);
+ }
make_text_transpose();
- lcd_update_button(1, text_transpose);
- reject_gui_events();
- }
- break;
- case EVENT_RELEASE:
- if (event & (BUTTON_B | BUTTON_X | BUTTON_Y))
- gui_gotostate_options();
- break;
- case EVENT_JOG:
- if ((event & JOG_BITS) == JOG_PLUS)
- {
- if (transp<12)
- set_transp(transp + 1);
- }
- else
- {
- if (transp>-12)
- set_transp(transp - 1);
- }
-
- make_text_transpose();
- lcd_update_button(1, text_transpose);
- break;
- }
-}
-
-// MIDI_ID: choose MIDI channel ID for input
-
-inline void gui_gotostate_midi_id (void)
-{
- make_text_midi_in();
-
- gui_state = GUI_MIDI_ID;
- lcd_draw_menu (6,
- GUI_TITLE_MIDI_ID,"",
- "","",text_midi_in, "", "", ""
- );
- reject_gui_events();
-}
-
-inline void gui_event_midi_id (const uint16_t event)
-{
- switch (event & EVENT_BITS)
- {
- case EVENT_HOLD:
- if (event & BUTTON_C)
- {
- midi_id = N_MIDI_ID;
+ lcd_update_button(1, text_transpose, 1);
+ break;
+ case 2:
+ if ((event & JOG_BITS) == JOG_PLUS)
+ {
+ if (midi_id < N_MIDI_ID)
+ ++midi_id;
+ else
+ midi_id = 0;
+ }
+ else
+ {
+ if (midi_id != 0)
+ --midi_id;
+ else
+ midi_id = N_MIDI_ID;
+ }
ctrl_update_midi();
make_text_midi_in();
- lcd_update_button(2, text_midi_in);
- reject_gui_events();
- }
- break;
- case EVENT_RELEASE:
- if (event & (BUTTON_C | BUTTON_X | BUTTON_Y))
- gui_gotostate_options();
- break;
- case EVENT_JOG:
- if ((event & JOG_BITS) == JOG_PLUS)
- {
- if (midi_id < N_MIDI_ID)
- ++midi_id;
- else
- midi_id = 0;
- }
- else
- {
- if (midi_id != 0)
- --midi_id;
+ lcd_update_button(2, text_midi_in, 1);
+ break;
+ case 3:
+ if ((event & JOG_BITS) == JOG_PLUS)
+ {
+ if (midi_id_out < N_MIDI_ID-1)
+ ++midi_id_out;
+ else
+ midi_id_out = 0;
+ }
else
- midi_id = N_MIDI_ID;
- }
-
- ctrl_update_midi();
- make_text_midi_in();
- lcd_update_button(2, text_midi_in);
- break;
- }
-}
-
-// MIDI_ID_OUT: choose MIDI channel ID for output
-
-inline void gui_gotostate_midi_id_out (void)
-{
- make_text_midi_out();
-
- gui_state = GUI_MIDI_ID_OUT;
- lcd_draw_menu (6,
- GUI_TITLE_MIDI_ID_OUT,"",
- "","","",text_midi_out, "", ""
- );
- reject_gui_events();
-}
-
-inline void gui_event_midi_id_out (const uint16_t event)
-{
- switch (event & EVENT_BITS)
- {
- case EVENT_HOLD:
- if (event & BUTTON_D)
- {
- midi_id_out = 0;
+ {
+ if (midi_id_out != 0)
+ --midi_id_out;
+ else
+ midi_id_out = N_MIDI_ID-1;
+ }
+
ctrl_update_midi();
make_text_midi_out();
- lcd_update_button(3, text_midi_out);
- reject_gui_events();
- }
- break;
- case EVENT_RELEASE:
- if (event & (BUTTON_D | BUTTON_X | BUTTON_Y))
- gui_gotostate_options();
- break;
- case EVENT_JOG:
- if ((event & JOG_BITS) == JOG_PLUS)
- {
- if (midi_id_out < N_MIDI_ID-1)
- ++midi_id_out;
- else
- midi_id_out = 0;
- }
- else
- {
- if (midi_id_out != 0)
- --midi_id_out;
- else
- midi_id_out = N_MIDI_ID-1;
+ lcd_update_button(3, text_midi_out, 1);
+ break;
}
-
- ctrl_update_midi();
- make_text_midi_out();
- lcd_update_button(3, text_midi_out);
- break;
}
}
gui_state = GUI_ERR_AIX;
lcd_draw_menu(1,
GUI_TITLE_ERR_AIX,"",
- "","","","","",GUI_BUTTONTEXT_IGNORE
+ "","","","","",GUI_BUTTONTEXT_IGNORE,
+ GUI_NOCHOICE
);
reject_gui_events();
}
gui_state = GUI_ERR_CTRL;
lcd_draw_menu(1,
GUI_TITLE_ERR_CTRL,"",
- "","","","","",GUI_BUTTONTEXT_IGNORE
+ "","","","","",GUI_BUTTONTEXT_IGNORE,
+ GUI_NOCHOICE
);
reject_gui_events();
}
"","","",
GUI_BUTTONTEXT_FORMAT,
GUI_BUTTONTEXT_RECOVER,
- GUI_BUTTONTEXT_IGNORE
+ GUI_BUTTONTEXT_IGNORE,
+ GUI_NOCHOICE
);
reject_gui_events();
}
gui_state = GUI_TOTAL_RESET;
lcd_draw_menu(0,
GUI_TITLE_RESET,"",
- "","","","","",""
+ "","","","","","",
+ GUI_NOCHOICE
);
fs_format();
RESET_UI();
{
uint16_t event;
- if (gui_event_r != gui_event_w) // event received
+ if (NOT_EMPTY_BP(gui_event_w, gui_event_r, N_GUI_EVENT)) // event received
{
// get event, advance pointer
event = gui_event[gui_event_r];
- if(gui_event_r >= N_GUI_EVENT - 1)
- gui_event_r = 0;
- else
- ++gui_event_r;
+ ADVANCE_BP(gui_event_r, N_GUI_EVENT);
// if ((event & EVENT_BITS) == EVENT_JOG)
// {
case GUI_OPTIONS:
gui_event_options(event);
break;
- case GUI_TUNING:
- gui_event_tuning(event);
- break;
- case GUI_TRANSPOSE:
- gui_event_transpose(event);
- break;
- case GUI_MIDI_ID:
- gui_event_midi_id(event);
- break;
- case GUI_MIDI_ID_OUT:
- gui_event_midi_id_out(event);
- break;
case GUI_ERR_AIX:
gui_event_err_aix(event);
break;
case GUI_SELECT:
case GUI_SELECT_SAVE:
case GUI_OPTIONS:
- case GUI_TUNING:
- case GUI_TRANSPOSE:
- case GUI_MIDI_ID:
- case GUI_MIDI_ID_OUT:
case GUI_ERR_AIX:
case GUI_ERR_CTRL:
case GUI_ERR_FS:
void draw_select (void) // voice settings selection
{
fs_load_page(gui_page);
+ if ((fs_page == gui_used_voice_page) && (gui_used_voice_id >= 0))
+ gui_choice = gui_used_voice_id;
+ else
+ gui_choice = GUI_NOCHOICE;
+
make_text_select();
lcd_draw_menu(6,
fs_page_names[2],
fs_page_names[3],
fs_page_names[4],
- fs_page_names[5]
+ fs_page_names[5],
+ gui_choice
);
}
void draw_select_save (void) // voice setting save location selection
{
fs_load_page(gui_page);
+ if ((fs_page == gui_used_voice_page) && (gui_used_voice_id >= 0))
+ gui_choice = gui_used_voice_id;
+ else
+ gui_choice = GUI_NOCHOICE;
+
make_text_save();
lcd_draw_menu(7,
fs_page_names[2],
fs_page_names[3],
fs_page_names[4],
- fs_page_names[5]
+ fs_page_names[5],
+ gui_choice
);
}
/* GUI */
/*
-Copyright 2021, 2022, 2024 Balthasar Szczepański
+Copyright 2021, 2022, 2024, 2025 Balthasar Szczepański
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
#define EVENT_WAS_HOLD 0x1000
#define EVENT_LONG 0x0800
+
+#define GUI_NOCHOICE (-128)
+
+
#define GUI_INIT 0x00
#define GUI_WAVE 0x01
#define GUI_SELECT 0x02
#define GUI_SELECT_SAVE 0x03
#define GUI_NAME 0x04
#define GUI_OPTIONS 0x10
-#define GUI_TUNING 0x11
-#define GUI_TRANSPOSE 0x12
-#define GUI_MIDI_ID 0x13
-#define GUI_MIDI_ID_OUT 0x14
#define GUI_ERROR 0x80
#define GUI_ERR_AIX 0x81
#define N_abc 35
#define N_123 42
-#define GUI_TITLE_NAME "Save as:"
-#define GUI_TITLE_OPTIONS "Options:"
-#define GUI_TITLE_TUNING "Tuning:"
-#define GUI_TITLE_TRANSPOSE "Transpose:"
-#define GUI_TITLE_MIDI_ID "MIDI in ID:"
-#define GUI_TITLE_MIDI_ID_OUT "MIDI out ID:"
-#define GUI_TITLE_ERR_AIX "AIX communication fail!"
-#define GUI_TITLE_ERR_CTRL "CTRL communication fail!"
-#define GUI_TITLE_ERR_FS "File system unformatted or damaged!"
-#define GUI_TITLE_RESET "TERAS BENDZIE INNY $WIAT"
+#define GUI_TITLE_NAME "Save as:"
+#define GUI_TITLE_TUNING "Tuning:"
+#define GUI_TITLE_ERR_AIX "AIX communication fail!"
+#define GUI_TITLE_ERR_CTRL "CTRL communication fail!"
+#define GUI_TITLE_ERR_FS "File system unformatted or damaged!"
+#define GUI_TITLE_RESET "TERAS BENDZIE INNY $WIAT"
+
+#define GUI_TITLE_OPTIONS "Options: "
+#define GUI_TITLE_OPTION_TUNING "Options: (tuning)"
+#define GUI_TITLE_OPTION_TRANSPOSE "Options: (transpose)"
+#define GUI_TITLE_OPTION_MIDI_ID "Options: (MIDI in ID)"
+#define GUI_TITLE_OPTION_MIDI_OUT_ID "Options: (MIDI out ID)"
+#define GUI_TITLE_OPTION_MIDI_PEDAL "Options: (MIDI pedal)"
+#define GUI_TITLE_OPTION_RESET "Options: (TOTAL RESET)"
+
#define GUI_BUTTONTEXT_DEL " <xx"
#define GUI_BUTTONTEXT_SPACE ""
inline void gui_gotostate_name (const uint8_t new);
inline void gui_gotostate_select_save (void);
inline void gui_gotostate_options (void);
-inline void gui_gotostate_tuning (void);
-inline void gui_gotostate_transpose (void);
-inline void gui_gotostate_midi_id (void);
-inline void gui_gotostate_midi_id_out (void);
inline void gui_gotostate_err_aix (void);
inline void gui_gotostate_err_ctrl (void);
inline void gui_gotostate_err_fs (void);
inline void gui_event_name (const uint16_t event);
inline void gui_event_select_save (const uint16_t event);
inline void gui_event_options (const uint16_t event);
-inline void gui_event_tuning (const uint16_t event);
-inline void gui_event_transp (const uint16_t event);
-inline void gui_event_midi_id (const uint16_t event);
-inline void gui_event_midi_id_out (const uint16_t event);
inline void gui_event_err_aix (const uint16_t event);
inline void gui_event_err_ctrl (const uint16_t event);
inline void gui_event_err_fs (const uint16_t event);
/*
-Copyright 2021 Balthasar Szczepański
+Copyright 2021, 2025 Balthasar Szczepański
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
asm("br !!0xEF00;"); \
}
+// common actions on buffer pointers
+// W write pointer
+// R read pointer
+// P any pointer
+// N buffer size
+#define ADVANCE_BP(P, N) ((P<(N-1)) ? (++P) : (P=0))
+#define DIFF_BP(W, R, N) ((W<R) ? (N + W - R) : W - R)
+#define FULL_BP(W, R, N) (DIFF_BP(W, R, N) == (N-1))
+#define NOT_FULL_BP(W, R, N) (DIFF_BP(W, R, N) != (N-1))
+#define EMPTY_BP(W, R, N) (R == W)
+#define NOT_EMPTY_BP(W, R, N) (R != W)
+#define CLEAR_BP(W, R, N) (R = W)
#endif
/* LCD */
/*
-Copyright 2021 Balthasar Szczepański
+Copyright 2021, 2025 Balthasar Szczepański
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
lcd_write(LCD_MASTER, LCD_DATA, x >> LCD_Vop_HIGHSHIFT);
}
-
-
inline void setup_lcd (void)
{
PER1 |= 0b00000001; //enable timer RJ
void lcd_subdraw_button (
uint16_t * const x,
const uint8_t type,
- const uint8_t * const text
+ const uint8_t * const text,
+ const uint8_t selected
)
{
uint16_t line1, line2, line3, line4, margin_l, margin_r;
uint16_t len, N;
uint16_t i, i0, i1, i2, i3, j0, j1, j2, j3;
uint8_t chip = LCD_SLAVE;
+ uint8_t underline;
+
+ underline = selected ? 0x3C : 00;
line1 = button_chars[type];
margin_l = button_lmargin[type];
lcd_write(chip, LCD_DATA, font16[j0]);
++j0;
lcd_write(chip, LCD_DATA, 0x00);
- lcd_write(chip, LCD_DATA, 0x00);
+ lcd_write(chip, LCD_DATA, underline);
++(*x);
}
}
++j1;
lcd_write(chip, LCD_DATA, font16[j1]);
++j1;
- lcd_write(chip, LCD_DATA, 0x00);
+ lcd_write(chip, LCD_DATA, underline);
++(*x);
}
}
++j1;
lcd_write(chip, LCD_DATA, font8[j2]);
++j2;
- lcd_write(chip, LCD_DATA, 0x00);
+ lcd_write(chip, LCD_DATA, underline);
++(*x);
}
}
++j2;
lcd_write(chip, LCD_DATA, font8[j3]);
++j3;
- lcd_write(chip, LCD_DATA, 0x00);
+ lcd_write(chip, LCD_DATA, underline);
++(*x);
}
}
lcd_write(chip, LCD_DATA, 0x00);
lcd_write(chip, LCD_DATA, 0x00);
lcd_write(chip, LCD_DATA, 0x00);
- lcd_write(chip, LCD_DATA, 0x00);
+ lcd_write(chip, LCD_DATA, 0x80);
++(*x);
}
}
void lcd_subdraw_lowbutton8 (
uint16_t * const x,
const uint8_t type,
- const uint8_t * const text
+ const uint8_t * const text,
+ const uint8_t selected
)
{
uint16_t line1, margin_l, margin_r;
uint16_t len, N;
uint16_t i, i0, j0, j3;
uint8_t chip = LCD_SLAVE;
+ uint8_t underline;
+
+ underline = selected ? 0x3C : 00;
line1 = button_chars[type];
margin_l = button_lmargin[type];
}
lcd_write(chip, LCD_DATA, font8[j0]);
++j0;
- lcd_write(chip, LCD_DATA, 0x00);
+ lcd_write(chip, LCD_DATA, underline);
++(*x);
}
const uint8_t * const button_C,
const uint8_t * const button_D,
const uint8_t * const button_E,
- const uint8_t * const button_F
+ const uint8_t * const button_F,
+ const int8_t selected
){
uint16_t x=0;
lcd_setup_drawing(LCD_MONO, 0, 511, 0, 4);
- lcd_subdraw_button (&x, FULLTEXT - buttons, title);
+ lcd_subdraw_button (&x, FULLTEXT - buttons, title, 0);
switch (buttons)
{
case 7:
lcd_subdraw_divider(&x);
- lcd_subdraw_button (&x, BUTTON_1X, button_0);
+ lcd_subdraw_button (&x, BUTTON_1X, button_0, selected == -1);
case 6:
lcd_subdraw_divider(&x);
- lcd_subdraw_button (&x, BUTTON_1X, button_A);
+ lcd_subdraw_button (&x, BUTTON_1X, button_A, selected == 0);
case 5:
lcd_subdraw_divider(&x);
- lcd_subdraw_button (&x, BUTTON_1X, button_B);
+ lcd_subdraw_button (&x, BUTTON_1X, button_B, selected == 1);
case 4:
lcd_subdraw_divider(&x);
- lcd_subdraw_button (&x, BUTTON_1X, button_C);
+ lcd_subdraw_button (&x, BUTTON_1X, button_C, selected == 2);
case 3:
lcd_subdraw_divider(&x);
- lcd_subdraw_button (&x, BUTTON_1X, button_D);
+ lcd_subdraw_button (&x, BUTTON_1X, button_D, selected == 3);
case 2:
lcd_subdraw_divider(&x);
- lcd_subdraw_button (&x, BUTTON_1X, button_E);
+ lcd_subdraw_button (&x, BUTTON_1X, button_E, selected == 4);
case 1:
lcd_subdraw_divider(&x);
- lcd_subdraw_button (&x, BUTTON_1X, button_F);
+ lcd_subdraw_button (&x, BUTTON_1X, button_F, selected == 5);
case 0:
default:
break;
}
}
+void lcd_update_title (const uint8_t * const text)
+{
+ uint16_t x = 0;
+
+ lcd_setup_drawing(LCD_MONO, 0, TITLE_6B_PIXELS-1, 0, 4);
+
+ lcd_subdraw_button (&x, TITLE_6B, text, 0);
+}
+
+
void lcd_update_button (
const int8_t id,
- const uint8_t * const text
+ const uint8_t * const text,
+ const uint8_t selected
)
{
uint16_t x;
lcd_setup_drawing(LCD_MONO, x, x+BUTTON_1X_PIXELS-1, 0, 4);
- lcd_subdraw_button (&x, 0, text);
+ lcd_subdraw_button (&x, BUTTON_1X, text, selected);
+}
+
+void lcd_select_button (
+ const int8_t id,
+ const uint8_t selected
+)
+{
+ uint16_t x;
+ uint16_t N;
+ uint16_t margin_l, margin_r;
+ uint16_t i;
+ uint8_t chip = LCD_SLAVE;
+ uint8_t underline;
+
+ if ((id < -1) || (id > 5))
+ return;
+
+ x = TITLE_6B_PIXELS + 1 + id * (BUTTON_1X_PIXELS + 1);
+
+ lcd_setup_drawing(LCD_MONO, x, x+BUTTON_1X_PIXELS-1, 4, 4);
+
+ underline = selected ? 0x3C : 00;
+
+ margin_l = button_lmargin[BUTTON_1X];
+ margin_r = button_rmargin[BUTTON_1X];
+ N = button_chars[BUTTON_1X] <<3;
+
+ for(i=0; i<margin_l; ++i) // left margin
+ {
+ if (x >= 256)
+ chip = LCD_MASTER;
+ lcd_write(chip, LCD_DATA, 0x00);
+ ++x;
+ }
+
+ for (i=0; i<N; ++i) // underline
+ {
+ if (x >= 256)
+ chip = LCD_MASTER;
+ lcd_write(chip, LCD_DATA, underline);
+ ++x;
+ }
+
+ for(i=0; i<margin_r; ++i) // right margin
+ {
+ if (x >= 256)
+ chip = LCD_MASTER;
+ lcd_write(chip, LCD_DATA, 0x00);
+ ++x;
+ }
}
void lcd_draw_name_cursor (const uint8_t pos)
const uint8_t * const button_C,
const uint8_t * const button_D,
const uint8_t * const button_E,
- const uint8_t * const button_F
+ const uint8_t * const button_F,
+ const int8_t selected
)
{
uint16_t x = 0;
lcd_clear_screen(LCD_MONO);
lcd_setup_drawing(LCD_MONO, 0, TITLE_6B_PIXELS, 0, 4);
- lcd_subdraw_button (&x, TITLE_7B, title);
+ lcd_subdraw_button (&x, TITLE_7B, title, 0);
lcd_subdraw_divider(&x);
- lcd_subdraw_button (&x, BUTTON_1X, name);
+ lcd_subdraw_button (&x, BUTTON_1X, name, 0);
lcd_subdraw_divider(&x);
lcd_setup_drawing(LCD_MONO, x, 511, 3, 4);
- lcd_subdraw_lowbutton8(&x, BUTTON_1X, button_A);
+ lcd_subdraw_lowbutton8(&x, BUTTON_1X, button_A, selected == 0);
lcd_subdraw_lowdivider(&x);
- lcd_subdraw_lowbutton8(&x, BUTTON_1X, button_B);
+ lcd_subdraw_lowbutton8(&x, BUTTON_1X, button_B, selected == 1);
lcd_subdraw_lowdivider(&x);
- lcd_subdraw_lowbutton8(&x, BUTTON_1X, button_C);
+ lcd_subdraw_lowbutton8(&x, BUTTON_1X, button_C, selected == 2);
lcd_subdraw_lowdivider(&x);
- lcd_subdraw_lowbutton8(&x, BUTTON_1X, button_D);
+ lcd_subdraw_lowbutton8(&x, BUTTON_1X, button_D, selected == 3);
lcd_subdraw_lowdivider(&x);
- lcd_subdraw_lowbutton8(&x, BUTTON_1X, button_E);
+ lcd_subdraw_lowbutton8(&x, BUTTON_1X, button_E, selected == 4);
lcd_subdraw_lowdivider(&x);
- lcd_subdraw_lowbutton8(&x, BUTTON_1X, button_F);
+ lcd_subdraw_lowbutton8(&x, BUTTON_1X, button_F, selected == 5);
lcd_draw_name_list(list);
/* LCD */
/*
-Copyright 2021 Balthasar Szczepański
+Copyright 2021, 2025 Balthasar Szczepański
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
void lcd_subdraw_button (
uint16_t * const x,
const uint8_t type,
- const uint8_t * const text
+ const uint8_t * const text,
+ const uint8_t selected
);
void lcd_subdraw_lowbutton8 (
uint16_t * const x,
const uint8_t type,
- const uint8_t * const text
+ const uint8_t * const text,
+ const uint8_t selected
);
void lcd_subdraw_lowbutton16 (
uint16_t * const x,
const uint8_t * const button_C,
const uint8_t * const button_D,
const uint8_t * const button_E,
- const uint8_t * const button_F
+ const uint8_t * const button_F,
+ const int8_t selected
);
+void lcd_update_title (const uint8_t * const text);
void lcd_update_button (
const int8_t id,
- const uint8_t * const text
+ const uint8_t * const text,
+ const uint8_t selected
+);
+void lcd_select_button (
+ const int8_t id,
+ const uint8_t selected
);
void lcd_draw_name_cursor(const uint8_t pos);
void lcd_erase_name_cursor(const uint8_t pos);
const uint8_t * const button_C,
const uint8_t * const button_D,
const uint8_t * const button_E,
- const uint8_t * const button_F
+ const uint8_t * const button_F,
+ const int8_t selected
);