Subversion Repositories svn.mios32

Rev

Rev 316 | Rev 319 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
134 tk 1
// $Id: seq_ui.c 318 2009-01-25 22:12:19Z tk $
2
/*
3
 * User Interface Routines
4
 *
5
 * ==========================================================================
6
 *
7
 *  Copyright (C) 2008 Thorsten Klose (tk@midibox.org)
8
 *  Licensed for personal non-commercial use only.
9
 *  All other rights reserved.
10
 *
11
 * ==========================================================================
12
 */
13
 
14
/////////////////////////////////////////////////////////////////////////////
15
// Include files
16
/////////////////////////////////////////////////////////////////////////////
17
 
272 tk 18
// with this switch, seq_ui.h/seq_ui_pages.inc will create local variables
19
#define SEQ_UI_PAGES_INC_LOCAL_VARS 1
20
 
134 tk 21
#include <mios32.h>
299 tk 22
#include <string.h>
134 tk 23
#include <blm8x8.h>
190 tk 24
#include <seq_midi_out.h>
25
#include <seq_bpm.h>
134 tk 26
 
290 tk 27
#include "tasks.h"
134 tk 28
#include "seq_ui.h"
29
#include "seq_lcd.h"
30
#include "seq_led.h"
186 tk 31
#include "seq_midply.h"
134 tk 32
#include "seq_core.h"
178 tk 33
#include "seq_layer.h"
184 tk 34
#include "seq_cc.h"
299 tk 35
#include "seq_file.h"
248 tk 36
#include "seq_file_b.h"
280 tk 37
#include "seq_file_m.h"
134 tk 38
 
39
 
40
/////////////////////////////////////////////////////////////////////////////
41
// Local types
42
/////////////////////////////////////////////////////////////////////////////
43
 
44
 
45
/////////////////////////////////////////////////////////////////////////////
46
// Local prototypes
47
/////////////////////////////////////////////////////////////////////////////
48
 
49
 
50
/////////////////////////////////////////////////////////////////////////////
51
// Global variables
52
/////////////////////////////////////////////////////////////////////////////
53
 
159 tk 54
u8 seq_ui_display_update_req;
55
u8 seq_ui_display_init_req;
134 tk 56
 
167 tk 57
seq_ui_button_state_t seq_ui_button_state;
58
 
134 tk 59
u8 ui_selected_group;
60
u8 ui_selected_tracks;
61
u8 ui_selected_par_layer;
62
u8 ui_selected_trg_layer;
63
u8 ui_selected_step_view;
64
u8 ui_selected_step;
168 tk 65
u8 ui_selected_item;
134 tk 66
 
168 tk 67
u8 ui_selected_item;
134 tk 68
 
240 tk 69
u16 ui_hold_msg_ctr;
70
 
206 tk 71
seq_ui_page_t ui_page;
272 tk 72
seq_ui_page_t ui_selected_page;
303 tk 73
seq_ui_page_t ui_stepview_prev_page;
206 tk 74
 
173 tk 75
volatile u8 ui_cursor_flash;
76
u16 ui_cursor_flash_ctr;
134 tk 77
 
316 tk 78
char ui_edit_name[21];
79
u8 ui_edit_name_cursor;
80
u8 ui_edit_preset_num_category;
81
u8 ui_edit_preset_num_label;
82
 
193 tk 83
u8 ui_seq_pause;
84
 
85
 
134 tk 86
/////////////////////////////////////////////////////////////////////////////
87
// Local variables
88
/////////////////////////////////////////////////////////////////////////////
89
 
168 tk 90
static s32 (*ui_button_callback)(seq_ui_button_t button, s32 depressed);
91
static s32 (*ui_encoder_callback)(seq_ui_encoder_t encoder, s32 incrementer);
173 tk 92
static s32 (*ui_led_callback)(u16 *gp_leds);
167 tk 93
static s32 (*ui_lcd_callback)(u8 high_prio);
94
 
168 tk 95
static u16 ui_gp_leds;
167 tk 96
 
168 tk 97
 
299 tk 98
#define SDCARD_MSG_MAX_CHAR 21
99
static char sdcard_msg[2][SDCARD_MSG_MAX_CHAR];
100
static u16 sdcard_msg_ctr;
101
 
102
 
103
 
134 tk 104
/////////////////////////////////////////////////////////////////////////////
105
// Initialisation
106
/////////////////////////////////////////////////////////////////////////////
107
s32 SEQ_UI_Init(u32 mode)
108
{
109
  // init selection variables
110
  ui_selected_group = 0;
111
  ui_selected_tracks = (1 << 0);
112
  ui_selected_par_layer = 0;
113
  ui_selected_trg_layer = 0;
114
  ui_selected_step_view = 0;
115
  ui_selected_step = 0;
168 tk 116
  ui_selected_item = 0;
134 tk 117
 
240 tk 118
  ui_hold_msg_ctr = 0;
299 tk 119
  sdcard_msg_ctr = 0;
240 tk 120
 
168 tk 121
  ui_cursor_flash_ctr = 0;
173 tk 122
  ui_cursor_flash = 0;
168 tk 123
 
167 tk 124
  seq_ui_button_state.ALL = 0;
125
 
193 tk 126
  ui_seq_pause = 0;
127
 
134 tk 128
  // visible GP pattern
129
  ui_gp_leds = 0x0000;
130
 
167 tk 131
  // change to edit page
132
  ui_page = SEQ_UI_PAGE_NONE;
133
  SEQ_UI_PageSet(SEQ_UI_PAGE_EDIT);
134 tk 134
 
135
  return 0; // no error
136
}
137
 
138
 
139
/////////////////////////////////////////////////////////////////////////////
178 tk 140
// Inits the speed mode of all encoders
141
// Auto mode should be used whenever:
142
//    - the edit screen is entered
143
//    - the group is changed
144
//    - a track is changed
145
//    - a layer is changed
146
/////////////////////////////////////////////////////////////////////////////
147
s32 SEQ_UI_InitEncSpeed(u32 auto_config)
148
{
149
  mios32_enc_config_t enc_config;
150
 
151
  if( auto_config ) {
152
#if DEFAULT_AUTO_FAST_BUTTON
153
    switch( SEQ_LAYER_GetVControlType(SEQ_UI_VisibleTrackGet(), ui_selected_par_layer) ) {
154
      case SEQ_LAYER_ControlType_Velocity:
155
      case SEQ_LAYER_ControlType_Chord1_Velocity:
156
      case SEQ_LAYER_ControlType_Chord2_Velocity:
157
      case SEQ_LAYER_ControlType_CC:
158
    seq_ui_button_state.FAST_ENCODERS = 1;
159
    break;
160
 
161
      default:
162
    seq_ui_button_state.FAST_ENCODERS = 0;
163
    }
164
#else
165
    // auto mode not enabled - ignore auto reconfiguration request
166
    return 0;
167
#endif
168
  }
169
 
170
  // change for datawheel and GP encoders
171
  int enc;
172
  for(enc=0; enc<17; ++enc) {
173
    enc_config = MIOS32_ENC_ConfigGet(enc);
174
    enc_config.cfg.speed = seq_ui_button_state.FAST_ENCODERS ? FAST : NORMAL;
175
    enc_config.cfg.speed_par = (enc == 0) ? DEFAULT_DATAWHEEL_SPEED_VALUE : DEFAULT_ENC_SPEED_VALUE;
176
    MIOS32_ENC_ConfigSet(enc, enc_config);
177
  }
178
 
179
  return 0; // no error
180
}
181
 
182
 
183
/////////////////////////////////////////////////////////////////////////////
167 tk 184
// Various installation routines for menu page LCD handlers
185
/////////////////////////////////////////////////////////////////////////////
168 tk 186
s32 SEQ_UI_InstallButtonCallback(void *callback)
167 tk 187
{
168 tk 188
  ui_button_callback = callback;
167 tk 189
  return 0; // no error
190
}
191
 
168 tk 192
s32 SEQ_UI_InstallEncoderCallback(void *callback)
167 tk 193
{
168 tk 194
  ui_encoder_callback = callback;
167 tk 195
  return 0; // no error
196
}
197
 
168 tk 198
s32 SEQ_UI_InstallLEDCallback(void *callback)
167 tk 199
{
168 tk 200
  ui_led_callback = callback;
167 tk 201
  return 0; // no error
202
}
203
 
168 tk 204
s32 SEQ_UI_InstallLCDCallback(void *callback)
167 tk 205
{
206
  ui_lcd_callback = callback;
207
  return 0; // no error
208
}
209
 
210
 
211
/////////////////////////////////////////////////////////////////////////////
212
// Change the menu page
213
/////////////////////////////////////////////////////////////////////////////
214
s32 SEQ_UI_PageSet(seq_ui_page_t page)
215
{
216
  if( page != ui_page ) {
217
    // disable hooks of previous page and request re-initialisation
318 tk 218
    portENTER_CRITICAL();
167 tk 219
    ui_page = page;
168 tk 220
    ui_button_callback = NULL;
221
    ui_encoder_callback = NULL;
222
    ui_led_callback = NULL;
167 tk 223
    ui_lcd_callback = NULL;
318 tk 224
    portEXIT_CRITICAL();
167 tk 225
 
178 tk 226
#if DEFAULT_BEHAVIOUR_BUTTON_MENU
168 tk 227
    seq_ui_button_state.MENU_PRESSED = 0; // MENU page selection finished
167 tk 228
#endif
229
 
230
    // request display initialisation
231
    seq_ui_display_init_req = 1;
232
  }
173 tk 233
 
306 tk 234
  // for MENU button:
235
  // first page has been selected - display new screen
236
  seq_ui_button_state.MENU_FIRST_PAGE_SELECTED = 1;
237
 
272 tk 238
  // for SEQ_UI_MENU which is accessible with EXIT button
239
  // remember the current selectable page
240
  if( ui_page >= SEQ_UI_FIRST_MENU_SELECTION_PAGE )
241
    ui_selected_page = ui_page;
242
 
184 tk 243
  return 0; // no error
167 tk 244
}
245
 
246
 
247
/////////////////////////////////////////////////////////////////////////////
272 tk 248
// Returns name of menu page (18 characters)
249
/////////////////////////////////////////////////////////////////////////////
250
char *SEQ_UI_PageNameGet(seq_ui_page_t page)
251
{
252
  return ui_menu_pages[page].name;
253
}
254
 
255
 
256
/////////////////////////////////////////////////////////////////////////////
134 tk 257
// Dedicated button functions
258
// Mapped to physical buttons in SEQ_UI_Button_Handler()
259
// Will also be mapped to MIDI keys later (for MIDI remote function)
260
/////////////////////////////////////////////////////////////////////////////
261
static s32 SEQ_UI_Button_GP(s32 depressed, u32 gp)
262
{
306 tk 263
  // in MENU page: overrule GP buttons so long MENU button is pressed/active
264
  if( seq_ui_button_state.MENU_PRESSED ) {
265
    if( depressed ) return -1;
266
    SEQ_UI_PageSet(ui_shortcut_menu_pages[gp]);
267
  } else {
268
    // forward to menu page
269
    if( ui_button_callback != NULL )
270
      ui_button_callback(gp, depressed);
271
    ui_cursor_flash_ctr = 0;
272
  }
134 tk 273
 
274
  return 0; // no error
275
}
276
 
277
static s32 SEQ_UI_Button_Left(s32 depressed)
278
{
168 tk 279
  // forward to menu page
306 tk 280
  if( !seq_ui_button_state.MENU_PRESSED && ui_button_callback != NULL )
168 tk 281
    ui_button_callback(SEQ_UI_BUTTON_Left, depressed);
173 tk 282
  ui_cursor_flash_ctr = 0;
134 tk 283
 
284
  return 0; // no error
285
}
286
 
287
static s32 SEQ_UI_Button_Right(s32 depressed)
288
{
168 tk 289
  // forward to menu page
306 tk 290
  if( !seq_ui_button_state.MENU_PRESSED && ui_button_callback != NULL )
168 tk 291
    ui_button_callback(SEQ_UI_BUTTON_Right, depressed);
173 tk 292
  ui_cursor_flash_ctr = 0;
134 tk 293
 
294
  return 0; // no error
295
}
296
 
168 tk 297
static s32 SEQ_UI_Button_Down(s32 depressed)
298
{
240 tk 299
  seq_ui_button_state.DOWN = depressed ? 0 : 1;
300
 
168 tk 301
  // forward to menu page
306 tk 302
  if( !seq_ui_button_state.MENU_PRESSED && ui_button_callback != NULL )
168 tk 303
    ui_button_callback(SEQ_UI_BUTTON_Down, depressed);
173 tk 304
  ui_cursor_flash_ctr = 0;
168 tk 305
 
306
  return 0; // no error
307
}
308
 
309
static s32 SEQ_UI_Button_Up(s32 depressed)
310
{
240 tk 311
  seq_ui_button_state.UP = depressed ? 0 : 1;
312
 
168 tk 313
  // forward to menu page
306 tk 314
  if( !seq_ui_button_state.MENU_PRESSED && ui_button_callback != NULL )
168 tk 315
    ui_button_callback(SEQ_UI_BUTTON_Up, depressed);
173 tk 316
  ui_cursor_flash_ctr = 0;
168 tk 317
 
318
  return 0; // no error
319
}
320
 
134 tk 321
static s32 SEQ_UI_Button_Scrub(s32 depressed)
322
{
178 tk 323
#if DEFAULT_BEHAVIOUR_BUTTON_SCRUB
324
  // toggle mode
134 tk 325
  if( depressed ) return -1; // ignore when button depressed
178 tk 326
  seq_ui_button_state.SCRUB ^= 1;
137 tk 327
#else
178 tk 328
  // set mode
329
  seq_ui_button_state.SCRUB = depressed ? 0 : 1;
137 tk 330
#endif
331
 
134 tk 332
  return 0; // no error
333
}
334
 
335
static s32 SEQ_UI_Button_Metronome(s32 depressed)
336
{
178 tk 337
#if DEFAULT_BEHAVIOUR_BUTTON_METRON
338
  // toggle mode
134 tk 339
  if( depressed ) return -1; // ignore when button depressed
178 tk 340
  seq_ui_button_state.METRONOME ^= 1;
290 tk 341
 
248 tk 342
#if 1
290 tk 343
  MUTEX_SDCARD_TAKE;
280 tk 344
 
318 tk 345
#if 1
249 tk 346
  u8 bank;
347
  for(bank=0; bank<SEQ_FILE_B_NUM_BANKS; ++bank) {
348
    SEQ_FILE_B_Create(bank);
349
    SEQ_FILE_B_Open(bank);
350
  }
280 tk 351
#else
352
    SEQ_FILE_M_Create();
353
    SEQ_FILE_M_Open();
354
#endif
355
 
290 tk 356
  MUTEX_SDCARD_GIVE;
248 tk 357
#endif
358
 
137 tk 359
#else
178 tk 360
  // set mode
361
  seq_ui_button_state.METRONOME = depressed ? 0 : 1;
137 tk 362
#endif
134 tk 363
 
364
  return 0; // no error
365
}
366
 
367
static s32 SEQ_UI_Button_Stop(s32 depressed)
368
{
369
  if( depressed ) return -1; // ignore when button depressed
370
 
159 tk 371
  // if sequencer running: stop it
372
  // if sequencer already stopped: reset song position
186 tk 373
#if MID_PLAYER_TEST
193 tk 374
  if( SEQ_BPM_IsRunning() )
375
    SEQ_BPM_Stop();
186 tk 376
  else
377
    SEQ_MIDPLY_Reset();
378
#else
193 tk 379
  if( SEQ_BPM_IsRunning() )
380
    SEQ_BPM_Stop();
159 tk 381
  else
382
    SEQ_CORE_Reset();
186 tk 383
#endif
159 tk 384
 
134 tk 385
  return 0; // no error
386
}
387
 
388
static s32 SEQ_UI_Button_Pause(s32 depressed)
389
{
390
  if( depressed ) return -1; // ignore when button depressed
391
 
193 tk 392
  // if in auto mode and BPM generator is clocked in slave mode:
393
  // change to master mode
394
  SEQ_BPM_CheckAutoMaster();
159 tk 395
 
193 tk 396
  // toggle pause mode
397
  ui_seq_pause ^= 1;
398
 
399
  // execute stop/continue depending on new mode
400
  if( ui_seq_pause )
401
    SEQ_BPM_Stop();
402
  else
403
    SEQ_BPM_Cont();
404
 
134 tk 405
  return 0; // no error
406
}
407
 
408
static s32 SEQ_UI_Button_Play(s32 depressed)
409
{
410
  if( depressed ) return -1; // ignore when button depressed
411
 
186 tk 412
  // if in auto mode and BPM generator is clocked in slave mode:
413
  // change to master mode
414
  SEQ_BPM_CheckAutoMaster();
415
 
193 tk 416
#if 0
417
  // if sequencer running: restart it
418
  // if sequencer stopped: continue at last song position
419
  if( SEQ_BPM_IsRunning() )
420
    SEQ_BPM_Start();
421
  else
422
    SEQ_BPM_Cont();
186 tk 423
#else
193 tk 424
  // always restart sequencer
425
  SEQ_BPM_Start();
186 tk 426
#endif
159 tk 427
 
134 tk 428
  return 0; // no error
429
}
430
 
431
static s32 SEQ_UI_Button_Rew(s32 depressed)
432
{
240 tk 433
  seq_ui_button_state.REW = depressed ? 0 : 1;
434
 
134 tk 435
  if( depressed ) return -1; // ignore when button depressed
436
 
437
  return 0; // no error
438
}
439
 
440
static s32 SEQ_UI_Button_Fwd(s32 depressed)
441
{
240 tk 442
  seq_ui_button_state.FWD = depressed ? 0 : 1;
443
 
134 tk 444
  if( depressed ) return -1; // ignore when button depressed
445
 
446
  return 0; // no error
447
}
448
 
449
static s32 SEQ_UI_Button_F1(s32 depressed)
450
{
240 tk 451
  seq_ui_button_state.F1 = depressed ? 0 : 1;
452
 
134 tk 453
  if( depressed ) return -1; // ignore when button depressed
454
 
240 tk 455
  // change to utility page
456
  SEQ_UI_PageSet(SEQ_UI_PAGE_UTIL);
457
 
134 tk 458
  return 0; // no error
459
}
460
 
461
static s32 SEQ_UI_Button_F2(s32 depressed)
462
{
240 tk 463
  seq_ui_button_state.F2 = depressed ? 0 : 1;
464
 
134 tk 465
  if( depressed ) return -1; // ignore when button depressed
466
 
467
  return 0; // no error
468
}
469
 
470
static s32 SEQ_UI_Button_F3(s32 depressed)
471
{
240 tk 472
  seq_ui_button_state.F3 = depressed ? 0 : 1;
473
 
134 tk 474
  if( depressed ) return -1; // ignore when button depressed
475
 
476
  return 0; // no error
477
}
478
 
479
static s32 SEQ_UI_Button_F4(s32 depressed)
480
{
240 tk 481
  seq_ui_button_state.F4 = depressed ? 0 : 1;
482
 
134 tk 483
  if( depressed ) return -1; // ignore when button depressed
484
 
485
  return 0; // no error
486
}
487
 
488
static s32 SEQ_UI_Button_Utility(s32 depressed)
489
{
490
  if( depressed ) return -1; // ignore when button depressed
491
 
240 tk 492
  // change to utility page
493
  SEQ_UI_PageSet(SEQ_UI_PAGE_UTIL);
494
 
134 tk 495
  return 0; // no error
496
}
497
 
498
static s32 SEQ_UI_Button_Copy(s32 depressed)
499
{
240 tk 500
  static seq_ui_page_t prev_page = SEQ_UI_PAGE_NONE;
134 tk 501
 
240 tk 502
  seq_ui_button_state.COPY = depressed ? 0 : 1;
503
 
280 tk 504
  if( ui_page == SEQ_UI_PAGE_MIXER ) {
505
    if( depressed ) return -1;
506
    SEQ_UI_MIXER_Copy();
507
    return 1;
508
  } else {
509
    if( !depressed ) {
510
      prev_page = ui_page;
511
      SEQ_UI_PageSet(SEQ_UI_PAGE_UTIL);
512
    }
240 tk 513
 
280 tk 514
    s32 status = SEQ_UI_UTIL_CopyButton(depressed);
240 tk 515
 
280 tk 516
    if( depressed )
517
      SEQ_UI_PageSet(prev_page);
240 tk 518
 
280 tk 519
    return status;
520
  }
134 tk 521
}
522
 
523
static s32 SEQ_UI_Button_Paste(s32 depressed)
524
{
240 tk 525
  static seq_ui_page_t prev_page = SEQ_UI_PAGE_NONE;
134 tk 526
 
240 tk 527
  seq_ui_button_state.PASTE = depressed ? 0 : 1;
528
 
280 tk 529
  if( ui_page == SEQ_UI_PAGE_MIXER ) {
530
    if( depressed ) return -1;
531
    SEQ_UI_MIXER_Paste();
532
    return 1;
533
  } else {
534
    if( !depressed ) {
535
      prev_page = ui_page;
536
      SEQ_UI_PageSet(SEQ_UI_PAGE_UTIL);
537
    }
240 tk 538
 
280 tk 539
    s32 status = SEQ_UI_UTIL_PasteButton(depressed);
240 tk 540
 
280 tk 541
    if( depressed )
542
      SEQ_UI_PageSet(prev_page);
240 tk 543
 
280 tk 544
    return status;
545
  }
134 tk 546
}
547
 
548
static s32 SEQ_UI_Button_Clear(s32 depressed)
549
{
240 tk 550
  seq_ui_button_state.CLEAR = depressed ? 0 : 1;
280 tk 551
 
552
  if( ui_page == SEQ_UI_PAGE_MIXER ) {
553
    if( depressed ) return -1;
554
    SEQ_UI_MIXER_Clear();
555
    return 1;
556
  } else {
557
    return SEQ_UI_UTIL_ClearButton(depressed);
558
  }
134 tk 559
}
560
 
561
static s32 SEQ_UI_Button_Menu(s32 depressed)
562
{
167 tk 563
  // TODO: define generic #define for this button behaviour
178 tk 564
#if DEFAULT_BEHAVIOUR_BUTTON_MENU
565
  // toggle mode
134 tk 566
  if( depressed ) return -1; // ignore when button depressed
306 tk 567
  seq_ui_button_state.MENU_FIRST_PAGE_SELECTED = 0;
167 tk 568
  seq_ui_button_state.MENU_PRESSED ^= 1; // toggle MENU pressed (will also be released once GP button has been pressed)
569
#else
178 tk 570
  // set mode
306 tk 571
  seq_ui_button_state.MENU_FIRST_PAGE_SELECTED = 0;
167 tk 572
  seq_ui_button_state.MENU_PRESSED = depressed ? 0 : 1;
573
#endif
134 tk 574
 
575
  return 0; // no error
576
}
577
 
578
static s32 SEQ_UI_Button_Select(s32 depressed)
579
{
168 tk 580
  // forward to menu page
306 tk 581
  if( !seq_ui_button_state.MENU_PRESSED && ui_button_callback != NULL )
168 tk 582
    ui_button_callback(SEQ_UI_BUTTON_Select, depressed);
173 tk 583
  ui_cursor_flash_ctr = 0;
134 tk 584
 
585
  return 0; // no error
586
}
587
 
588
static s32 SEQ_UI_Button_Exit(s32 depressed)
589
{
272 tk 590
  if( depressed ) return -1; // ignore when button depressed
591
 
592
  u8 prev_ui_page = ui_page;
593
 
168 tk 594
  // forward to menu page
306 tk 595
  if( !seq_ui_button_state.MENU_PRESSED && ui_button_callback != NULL )
168 tk 596
    ui_button_callback(SEQ_UI_BUTTON_Exit, depressed);
173 tk 597
  ui_cursor_flash_ctr = 0;
134 tk 598
 
167 tk 599
  // release all button states
600
  seq_ui_button_state.ALL = 0;
601
 
272 tk 602
  // enter menu page if we were not there before
603
  if( prev_ui_page != SEQ_UI_PAGE_MENU )
604
    SEQ_UI_PageSet(SEQ_UI_PAGE_MENU);
605
 
134 tk 606
  return 0; // no error
607
}
608
 
609
static s32 SEQ_UI_Button_Edit(s32 depressed)
610
{
611
  if( depressed ) return -1; // ignore when button depressed
612
 
167 tk 613
  // change to edit page
614
  SEQ_UI_PageSet(SEQ_UI_PAGE_EDIT);
615
 
178 tk 616
  // set/clear encoder fast function if required
617
  SEQ_UI_InitEncSpeed(1); // auto config
618
 
134 tk 619
  return 0; // no error
620
}
621
 
622
static s32 SEQ_UI_Button_Mute(s32 depressed)
623
{
624
  if( depressed ) return -1; // ignore when button depressed
625
 
184 tk 626
  SEQ_UI_PageSet(SEQ_UI_PAGE_MUTE);
627
 
134 tk 628
  return 0; // no error
629
}
630
 
631
static s32 SEQ_UI_Button_Pattern(s32 depressed)
632
{
633
  if( depressed ) return -1; // ignore when button depressed
634
 
184 tk 635
  SEQ_UI_PageSet(SEQ_UI_PAGE_PATTERN);
636
 
134 tk 637
  return 0; // no error
638
}
639
 
640
static s32 SEQ_UI_Button_Song(s32 depressed)
641
{
642
  if( depressed ) return -1; // ignore when button depressed
643
 
644
  return 0; // no error
645
}
646
 
647
static s32 SEQ_UI_Button_Solo(s32 depressed)
648
{
178 tk 649
#if DEFAULT_BEHAVIOUR_BUTTON_ALL
650
  // toggle mode
134 tk 651
  if( depressed ) return -1; // ignore when button depressed
178 tk 652
  seq_ui_button_state.SOLO ^= 1;
653
#else
654
  // set mode
655
  seq_ui_button_state.SOLO = depressed ? 0 : 1;
656
#endif
134 tk 657
 
658
  return 0; // no error
659
}
660
 
661
static s32 SEQ_UI_Button_Fast(s32 depressed)
662
{
178 tk 663
#if DEFAULT_BEHAVIOUR_BUTTON_FAST
664
  // toggle mode
134 tk 665
  if( depressed ) return -1; // ignore when button depressed
178 tk 666
  seq_ui_button_state.FAST_ENCODERS ^= 1;
667
#else
668
  // set mode
669
  seq_ui_button_state.FAST_ENCODERS = depressed ? 0 : 1;
670
#endif
134 tk 671
 
178 tk 672
  SEQ_UI_InitEncSpeed(0); // no auto config
673
 
134 tk 674
  return 0; // no error
675
}
676
 
677
static s32 SEQ_UI_Button_All(s32 depressed)
678
{
178 tk 679
  seq_ui_button_state.CHANGE_ALL_STEPS_SAME_VALUE = depressed ? 0 : 1;
134 tk 680
 
178 tk 681
#if DEFAULT_BEHAVIOUR_BUTTON_ALL
682
  // toggle mode
683
  if( depressed ) return -1;
684
  seq_ui_button_state.CHANGE_ALL_STEPS ^= 1;
685
#else
686
  // set mode
687
  seq_ui_button_state.CHANGE_ALL_STEPS = depressed ? 0 : 1;
688
#endif
689
 
134 tk 690
  return 0; // no error
691
}
692
 
693
static s32 SEQ_UI_Button_StepView(s32 depressed)
694
{
303 tk 695
#if DEFAULT_BEHAVIOUR_BUTTON_STEPVIEW
134 tk 696
  if( depressed ) return -1; // ignore when button depressed
303 tk 697
  seq_ui_button_state.STEPVIEW ^= 1; // toggle STEPVIEW pressed (will also be released once GP button has been pressed)
698
#else
699
  // set mode
700
  seq_ui_button_state.STEPVIEW = depressed ? 0 : 1;
701
#endif
134 tk 702
 
303 tk 703
  if( seq_ui_button_state.STEPVIEW ) {
704
    ui_stepview_prev_page = ui_page;
705
    SEQ_UI_PageSet(SEQ_UI_PAGE_STEPSEL);
706
  } else {
707
    SEQ_UI_PageSet(ui_stepview_prev_page);
708
  }
134 tk 709
 
710
  return 0; // no error
711
}
712
 
713
static s32 SEQ_UI_Button_TapTempo(s32 depressed)
714
{
715
  if( depressed ) return -1; // ignore when button depressed
716
 
717
  return 0; // no error
718
}
719
 
720
static s32 SEQ_UI_Button_Track(s32 depressed, u32 track)
721
{
722
  if( depressed ) return -1; // ignore when button depressed
723
 
724
  if( track >= 4 ) return -2; // max. 4 track buttons
725
 
726
  ui_selected_tracks = (1 << track); // TODO: multi-selections!
727
 
178 tk 728
  // set/clear encoder fast function if required
729
  SEQ_UI_InitEncSpeed(1); // auto config
730
 
134 tk 731
  return 0; // no error
732
}
733
 
734
static s32 SEQ_UI_Button_Group(s32 depressed, u32 group)
735
{
736
  if( depressed ) return -1; // ignore when button depressed
737
 
738
  if( group >= 4 ) return -2; // max. 4 group buttons
739
 
740
  ui_selected_group = group;
741
 
178 tk 742
  // set/clear encoder fast function if required
743
  SEQ_UI_InitEncSpeed(1); // auto config
744
 
134 tk 745
  return 0; // no error
746
}
747
 
748
static s32 SEQ_UI_Button_ParLayer(s32 depressed, u32 par_layer)
749
{
750
  if( depressed ) return -1; // ignore when button depressed
751
 
752
  if( par_layer >= 3 ) return -2; // max. 3 parlayer buttons
753
 
754
  ui_selected_par_layer = par_layer;
755
 
178 tk 756
  // set/clear encoder fast function if required
757
  SEQ_UI_InitEncSpeed(1); // auto config
758
 
134 tk 759
  return 0; // no error
760
}
761
 
762
static s32 SEQ_UI_Button_TrgLayer(s32 depressed, u32 trg_layer)
763
{
764
  if( depressed ) return -1; // ignore when button depressed
765
 
766
  if( trg_layer >= 3 ) return -2; // max. 3 trglayer buttons
767
 
768
  ui_selected_trg_layer = trg_layer;
769
 
770
  return 0; // no error
771
}
772
 
773
 
774
 
775
/////////////////////////////////////////////////////////////////////////////
776
// Button handler
777
/////////////////////////////////////////////////////////////////////////////
778
s32 SEQ_UI_Button_Handler(u32 pin, u32 pin_value)
779
{
780
  switch( pin ) {
168 tk 781
#if BUTTON_GP1 != BUTTON_DISABLED
134 tk 782
    case BUTTON_GP1:   SEQ_UI_Button_GP(pin_value, 0); break;
783
#endif
168 tk 784
#if BUTTON_GP2 != BUTTON_DISABLED
134 tk 785
    case BUTTON_GP2:   SEQ_UI_Button_GP(pin_value, 1); break;
786
#endif
168 tk 787
#if BUTTON_GP3 != BUTTON_DISABLED
134 tk 788
    case BUTTON_GP3:   SEQ_UI_Button_GP(pin_value, 2); break;
789
#endif
168 tk 790
#if BUTTON_GP4 != BUTTON_DISABLED
134 tk 791
    case BUTTON_GP4:   SEQ_UI_Button_GP(pin_value, 3); break;
792
#endif
168 tk 793
#if BUTTON_GP5 != BUTTON_DISABLED
134 tk 794
    case BUTTON_GP5:   SEQ_UI_Button_GP(pin_value, 4); break;
795
#endif
168 tk 796
#if BUTTON_GP6 != BUTTON_DISABLED
134 tk 797
    case BUTTON_GP6:   SEQ_UI_Button_GP(pin_value, 5); break;
798
#endif
168 tk 799
#if BUTTON_GP7 != BUTTON_DISABLED
134 tk 800
    case BUTTON_GP7:   SEQ_UI_Button_GP(pin_value, 6); break;
801
#endif
168 tk 802
#if BUTTON_GP8 != BUTTON_DISABLED
134 tk 803
    case BUTTON_GP8:   SEQ_UI_Button_GP(pin_value, 7); break;
804
#endif
168 tk 805
#if BUTTON_GP9 != BUTTON_DISABLED
134 tk 806
    case BUTTON_GP9:   SEQ_UI_Button_GP(pin_value, 8); break;
807
#endif
168 tk 808
#if BUTTON_GP10 != BUTTON_DISABLED
134 tk 809
    case BUTTON_GP10:  SEQ_UI_Button_GP(pin_value, 9); break;
810
#endif
168 tk 811
#if BUTTON_GP11 != BUTTON_DISABLED
134 tk 812
    case BUTTON_GP11:  SEQ_UI_Button_GP(pin_value, 10); break;
813
#endif
168 tk 814
#if BUTTON_GP12 != BUTTON_DISABLED
134 tk 815
    case BUTTON_GP12:  SEQ_UI_Button_GP(pin_value, 11); break;
816
#endif
168 tk 817
#if BUTTON_GP13 != BUTTON_DISABLED
134 tk 818
    case BUTTON_GP13:  SEQ_UI_Button_GP(pin_value, 12); break;
819
#endif
168 tk 820
#if BUTTON_GP14 != BUTTON_DISABLED
134 tk 821
    case BUTTON_GP14:  SEQ_UI_Button_GP(pin_value, 13); break;
822
#endif
168 tk 823
#if BUTTON_GP15 != BUTTON_DISABLED
134 tk 824
    case BUTTON_GP15:  SEQ_UI_Button_GP(pin_value, 14); break;
825
#endif
168 tk 826
#if BUTTON_GP16 != BUTTON_DISABLED
134 tk 827
    case BUTTON_GP16:  SEQ_UI_Button_GP(pin_value, 15); break;
828
#endif
829
 
168 tk 830
#if BUTTON_LEFT != BUTTON_DISABLED
134 tk 831
    case BUTTON_LEFT:  SEQ_UI_Button_Left(pin_value); break;
832
#endif
168 tk 833
#if BUTTON_RIGHT != BUTTON_DISABLED
134 tk 834
    case BUTTON_RIGHT: SEQ_UI_Button_Right(pin_value); break;
835
#endif
836
 
168 tk 837
#if BUTTON_DOWN != BUTTON_DISABLED
838
    case BUTTON_DOWN:  SEQ_UI_Button_Down(pin_value); break;
839
#endif
840
#if BUTTON_UP != BUTTON_DISABLED
841
    case BUTTON_UP:    SEQ_UI_Button_Up(pin_value); break;
842
#endif
843
 
844
#if BUTTON_SCRUB != BUTTON_DISABLED
134 tk 845
    case BUTTON_SCRUB: SEQ_UI_Button_Scrub(pin_value); break;
846
#endif
168 tk 847
#if BUTTON_METRONOME != BUTTON_DISABLED
134 tk 848
    case BUTTON_METRONOME: SEQ_UI_Button_Metronome(pin_value); break;
849
#endif
850
 
168 tk 851
#if BUTTON_STOP != BUTTON_DISABLED
134 tk 852
    case BUTTON_STOP:  SEQ_UI_Button_Stop(pin_value); break;
853
#endif
168 tk 854
#if BUTTON_PAUSE != BUTTON_DISABLED
134 tk 855
    case BUTTON_PAUSE: SEQ_UI_Button_Pause(pin_value); break;
856
#endif
168 tk 857
#if BUTTON_PLAY != BUTTON_DISABLED
134 tk 858
    case BUTTON_PLAY:  SEQ_UI_Button_Play(pin_value); break;
859
#endif
168 tk 860
#if BUTTON_REW != BUTTON_DISABLED
134 tk 861
    case BUTTON_REW:   SEQ_UI_Button_Rew(pin_value); break;
862
#endif
168 tk 863
#if BUTTON_FWD != BUTTON_DISABLED
134 tk 864
    case BUTTON_FWD:   SEQ_UI_Button_Fwd(pin_value); break;
865
#endif
866
 
168 tk 867
#if BUTTON_F1 != BUTTON_DISABLED
134 tk 868
    case BUTTON_F1:    SEQ_UI_Button_F1(pin_value); break;
869
#endif
168 tk 870
#if BUTTON_F2 != BUTTON_DISABLED
134 tk 871
    case BUTTON_F2:    SEQ_UI_Button_F2(pin_value); break;
872
#endif
168 tk 873
#if BUTTON_F3 != BUTTON_DISABLED
134 tk 874
    case BUTTON_F3:    SEQ_UI_Button_F3(pin_value); break;
875
#endif
168 tk 876
#if BUTTON_F4 != BUTTON_DISABLED
134 tk 877
    case BUTTON_F4:    SEQ_UI_Button_F4(pin_value); break;
878
#endif
879
 
168 tk 880
#if BUTTON_UTILITY != BUTTON_DISABLED
134 tk 881
    case BUTTON_UTILITY: SEQ_UI_Button_Utility(pin_value); break;
882
#endif
168 tk 883
#if BUTTON_COPY != BUTTON_DISABLED
134 tk 884
    case BUTTON_COPY:  SEQ_UI_Button_Copy(pin_value); break;
885
#endif
168 tk 886
#if BUTTON_PASTE != BUTTON_DISABLED
134 tk 887
    case BUTTON_PASTE: SEQ_UI_Button_Paste(pin_value); break;
888
#endif
168 tk 889
#if BUTTON_CLEAR != BUTTON_DISABLED
134 tk 890
    case BUTTON_CLEAR: SEQ_UI_Button_Clear(pin_value); break;
891
#endif
892
 
168 tk 893
#if BUTTON_MENU != BUTTON_DISABLED
134 tk 894
    case BUTTON_MENU:  SEQ_UI_Button_Menu(pin_value); break;
895
#endif
168 tk 896
#if BUTTON_SELECT != BUTTON_DISABLED
134 tk 897
    case BUTTON_SELECT:SEQ_UI_Button_Select(pin_value); break;
898
#endif
168 tk 899
#if BUTTON_EXIT != BUTTON_DISABLED
134 tk 900
    case BUTTON_EXIT:  SEQ_UI_Button_Exit(pin_value); break;
901
#endif
902
 
168 tk 903
#if BUTTON_TRACK1 != BUTTON_DISABLED
134 tk 904
    case BUTTON_TRACK1: SEQ_UI_Button_Track(pin_value, 0); break;
905
#endif
168 tk 906
#if BUTTON_TRACK2 != BUTTON_DISABLED
134 tk 907
    case BUTTON_TRACK2: SEQ_UI_Button_Track(pin_value, 1); break;
908
#endif
168 tk 909
#if BUTTON_TRACK3 != BUTTON_DISABLED
134 tk 910
    case BUTTON_TRACK3: SEQ_UI_Button_Track(pin_value, 2); break;
911
#endif
168 tk 912
#if BUTTON_TRACK4 != BUTTON_DISABLED
134 tk 913
    case BUTTON_TRACK4: SEQ_UI_Button_Track(pin_value, 3); break;
914
#endif
915
 
168 tk 916
#if BUTTON_PAR_LAYER_A != BUTTON_DISABLED
134 tk 917
    case BUTTON_PAR_LAYER_A: SEQ_UI_Button_ParLayer(pin_value, 0); break;
918
#endif
168 tk 919
#if BUTTON_PAR_LAYER_B != BUTTON_DISABLED
134 tk 920
    case BUTTON_PAR_LAYER_B: SEQ_UI_Button_ParLayer(pin_value, 1); break;
921
#endif
168 tk 922
#if BUTTON_PAR_LAYER_C != BUTTON_DISABLED
134 tk 923
    case BUTTON_PAR_LAYER_C: SEQ_UI_Button_ParLayer(pin_value, 2); break;
924
#endif
925
 
168 tk 926
#if BUTTON_EDIT != BUTTON_DISABLED
134 tk 927
    case BUTTON_EDIT:   SEQ_UI_Button_Edit(pin_value); break;
928
#endif
168 tk 929
#if BUTTON_MUTE != BUTTON_DISABLED
134 tk 930
    case BUTTON_MUTE:   SEQ_UI_Button_Mute(pin_value); break;
931
#endif
168 tk 932
#if BUTTON_PATTERN != BUTTON_DISABLED
134 tk 933
    case BUTTON_PATTERN:SEQ_UI_Button_Pattern(pin_value); break;
934
#endif
168 tk 935
#if BUTTON_SONG != BUTTON_DISABLED
134 tk 936
    case BUTTON_SONG:   SEQ_UI_Button_Song(pin_value); break;
937
#endif
938
 
168 tk 939
#if BUTTON_SOLO != BUTTON_DISABLED
134 tk 940
    case BUTTON_SOLO:   SEQ_UI_Button_Solo(pin_value); break;
941
#endif
168 tk 942
#if BUTTON_FAST != BUTTON_DISABLED
134 tk 943
    case BUTTON_FAST:   SEQ_UI_Button_Fast(pin_value); break;
944
#endif
168 tk 945
#if BUTTON_ALL != BUTTON_DISABLED
134 tk 946
    case BUTTON_ALL:    SEQ_UI_Button_All(pin_value); break;
947
#endif
948
 
168 tk 949
#if BUTTON_GROUP1 != BUTTON_DISABLED
134 tk 950
    case BUTTON_GROUP1: SEQ_UI_Button_Group(pin_value, 0); break;
951
#endif
168 tk 952
#if BUTTON_GROUP2 != BUTTON_DISABLED
134 tk 953
    case BUTTON_GROUP2: SEQ_UI_Button_Group(pin_value, 1); break;
954
#endif
168 tk 955
#if BUTTON_GROUP3 != BUTTON_DISABLED
134 tk 956
    case BUTTON_GROUP3: SEQ_UI_Button_Group(pin_value, 2); break;
957
#endif
168 tk 958
#if BUTTON_GROUP4 != BUTTON_DISABLED
134 tk 959
    case BUTTON_GROUP4: SEQ_UI_Button_Group(pin_value, 3); break;
960
#endif
961
 
168 tk 962
#if BUTTON_TRG_LAYER_A != BUTTON_DISABLED
134 tk 963
    case BUTTON_TRG_LAYER_A: SEQ_UI_Button_TrgLayer(pin_value, 0); break;
964
#endif
168 tk 965
#if BUTTON_TRG_LAYER_B != BUTTON_DISABLED
134 tk 966
    case BUTTON_TRG_LAYER_B: SEQ_UI_Button_TrgLayer(pin_value, 1); break;
967
#endif
168 tk 968
#if BUTTON_TRG_LAYER_C != BUTTON_DISABLED
134 tk 969
    case BUTTON_TRG_LAYER_C: SEQ_UI_Button_TrgLayer(pin_value, 2); break;
970
#endif
971
 
168 tk 972
#if BUTTON_STEP_VIEW != BUTTON_DISABLED
134 tk 973
    case BUTTON_STEP_VIEW: SEQ_UI_Button_StepView(pin_value); break;
974
#endif
975
 
168 tk 976
#if BUTTON_TAP_TEMPO != BUTTON_DISABLED
134 tk 977
    case BUTTON_TAP_TEMPO:   SEQ_UI_Button_TapTempo(pin_value); break;
978
#endif
979
 
980
    default:
981
      return -1; // button function not mapped to physical button
982
  }
983
 
984
  // request display update
159 tk 985
  seq_ui_display_update_req = 1;
134 tk 986
 
987
  return 0; // no error
988
}
989
 
990
 
991
/////////////////////////////////////////////////////////////////////////////
992
// Encoder handler
993
/////////////////////////////////////////////////////////////////////////////
994
s32 SEQ_UI_Encoder_Handler(u32 encoder, s32 incrementer)
995
{
996
  if( encoder > 16 )
997
    return -1; // encoder doesn't exist
998
 
999
  // limit incrementer
1000
  if( incrementer > 3 )
1001
    incrementer = 3;
1002
  else if( incrementer < -3 )
1003
    incrementer = -3;
1004
 
306 tk 1005
  if( !seq_ui_button_state.MENU_PRESSED && ui_encoder_callback != NULL ) {
173 tk 1006
    ui_encoder_callback((encoder == 0) ? SEQ_UI_ENCODER_Datawheel : (encoder-1), incrementer);
1007
    ui_cursor_flash_ctr = 0; // ensure that value is visible when it has been changed
134 tk 1008
  }
1009
 
1010
  // request display update
159 tk 1011
  seq_ui_display_update_req = 1;
134 tk 1012
 
1013
  return 0; // no error
1014
}
1015
 
1016
 
1017
/////////////////////////////////////////////////////////////////////////////
1018
// Update LCD messages
1019
// Usually called from background task
1020
/////////////////////////////////////////////////////////////////////////////
1021
s32 SEQ_UI_LCD_Handler(void)
1022
{
159 tk 1023
  if( seq_ui_display_init_req ) {
1024
    seq_ui_display_init_req = 0; // clear request
134 tk 1025
 
278 tk 1026
    // clear force update of LCD
1027
    SEQ_LCD_Clear();
1028
    SEQ_LCD_Update(1);
134 tk 1029
 
168 tk 1030
    // select first menu item
1031
    ui_selected_item = 0;
1032
 
167 tk 1033
    // call init function of current page
272 tk 1034
    if( ui_menu_pages[ui_page].init_callback != NULL )
1035
      ui_menu_pages[ui_page].init_callback(0); // mode
134 tk 1036
 
1037
    // request display update
159 tk 1038
    seq_ui_display_update_req = 1;
134 tk 1039
  }
1040
 
306 tk 1041
  // in MENU page: overrule LCD output so long MENU button is pressed/active
1042
  if( seq_ui_button_state.MENU_PRESSED && !seq_ui_button_state.MENU_FIRST_PAGE_SELECTED ) {
1043
    SEQ_LCD_CursorSet(0, 0);
1044
    //                      <-------------------------------------->
1045
    //                      0123456789012345678901234567890123456789
1046
    SEQ_LCD_PrintString("Menu Shortcuts:");
1047
    SEQ_LCD_PrintSpaces(25 + 40);
1048
    SEQ_LCD_CursorSet(0, 1);
1049
    SEQ_LCD_PrintString(UI_SHORTCUT_STR); // defined in seq_ui_pages.inc
1050
  } else {
1051
    // perform high priority LCD update request
1052
    if( ui_lcd_callback != NULL )
1053
      ui_lcd_callback(1); // high_prio
167 tk 1054
 
306 tk 1055
    // perform low priority LCD update request if requested
1056
    if( seq_ui_display_update_req ) {
1057
      seq_ui_display_update_req = 0; // clear request
1058
 
1059
      if( ui_lcd_callback != NULL )
1060
    ui_lcd_callback(0); // no high_prio
1061
    }
134 tk 1062
  }
1063
 
299 tk 1064
  // if SD card message active: copy over the text
1065
  if( sdcard_msg_ctr ) {
1066
    const char animation_l[4][3] = {
1067
      "  ", " >", ">>", "> " };
1068
    const char animation_r[4][3] = {
1069
      "  ", "< ", "<<", " <" };
1070
    int anum = (sdcard_msg_ctr % 1000) / 250;
1071
 
1072
    int line;
1073
    for(line=0; line<2; ++line) {
1074
      SEQ_LCD_CursorSet(40, line);
1075
      SEQ_LCD_PrintFormattedString(" %s| %-20s |%s ",
1076
                   (char *)animation_l[anum],
1077
                   (char *)sdcard_msg[line],
1078
                   (char *)animation_r[anum]);
1079
    }
1080
  }
1081
 
278 tk 1082
  // transfer all changed characters to LCD
1083
  SEQ_LCD_Update(0);
159 tk 1084
 
134 tk 1085
  return 0; // no error
1086
}
1087
 
1088
 
1089
 
1090
/////////////////////////////////////////////////////////////////////////////
1091
// Update all LEDs
1092
// Usually called from background task
1093
/////////////////////////////////////////////////////////////////////////////
1094
s32 SEQ_UI_LED_Handler(void)
1095
{
1096
  // track LEDs
167 tk 1097
  SEQ_LED_PinSet(LED_TRACK1, (ui_selected_tracks & (1 << 0)));
1098
  SEQ_LED_PinSet(LED_TRACK2, (ui_selected_tracks & (1 << 1)));
1099
  SEQ_LED_PinSet(LED_TRACK3, (ui_selected_tracks & (1 << 2)));
1100
  SEQ_LED_PinSet(LED_TRACK4, (ui_selected_tracks & (1 << 3)));
134 tk 1101
 
1102
  // parameter layer LEDs
167 tk 1103
  SEQ_LED_PinSet(LED_PAR_LAYER_A, (ui_selected_par_layer == 0));
1104
  SEQ_LED_PinSet(LED_PAR_LAYER_B, (ui_selected_par_layer == 1));
1105
  SEQ_LED_PinSet(LED_PAR_LAYER_C, (ui_selected_par_layer == 2));
134 tk 1106
 
1107
  // group LEDs
167 tk 1108
  SEQ_LED_PinSet(LED_GROUP1, (ui_selected_group == 0));
1109
  SEQ_LED_PinSet(LED_GROUP2, (ui_selected_group == 1));
1110
  SEQ_LED_PinSet(LED_GROUP3, (ui_selected_group == 2));
1111
  SEQ_LED_PinSet(LED_GROUP4, (ui_selected_group == 3));
134 tk 1112
 
1113
  // trigger layer LEDs
167 tk 1114
  SEQ_LED_PinSet(LED_TRG_LAYER_A, (ui_selected_trg_layer == 0));
1115
  SEQ_LED_PinSet(LED_TRG_LAYER_B, (ui_selected_trg_layer == 1));
1116
  SEQ_LED_PinSet(LED_TRG_LAYER_C, (ui_selected_trg_layer == 2));
134 tk 1117
 
1118
  // remaining LEDs
167 tk 1119
  SEQ_LED_PinSet(LED_EDIT, ui_page == SEQ_UI_PAGE_EDIT);
184 tk 1120
  SEQ_LED_PinSet(LED_MUTE, ui_page == SEQ_UI_PAGE_MUTE);
1121
  SEQ_LED_PinSet(LED_PATTERN, ui_page == SEQ_UI_PAGE_PATTERN);
134 tk 1122
  SEQ_LED_PinSet(LED_SONG, 0);
1123
 
178 tk 1124
  SEQ_LED_PinSet(LED_SOLO, seq_ui_button_state.SOLO);
1125
  SEQ_LED_PinSet(LED_FAST, seq_ui_button_state.FAST_ENCODERS);
1126
  SEQ_LED_PinSet(LED_ALL, seq_ui_button_state.CHANGE_ALL_STEPS);
134 tk 1127
 
193 tk 1128
  SEQ_LED_PinSet(LED_PLAY, SEQ_BPM_IsRunning());
1129
  SEQ_LED_PinSet(LED_STOP, !SEQ_BPM_IsRunning() && !ui_seq_pause);
1130
  SEQ_LED_PinSet(LED_PAUSE, ui_seq_pause);
240 tk 1131
 
1132
  SEQ_LED_PinSet(LED_REW, seq_ui_button_state.REW);
1133
  SEQ_LED_PinSet(LED_FWD, seq_ui_button_state.FWD);
134 tk 1134
 
303 tk 1135
  SEQ_LED_PinSet(LED_STEPVIEW, seq_ui_button_state.STEPVIEW);
134 tk 1136
 
167 tk 1137
  SEQ_LED_PinSet(LED_MENU, seq_ui_button_state.MENU_PRESSED);
178 tk 1138
  SEQ_LED_PinSet(LED_SCRUB, seq_ui_button_state.SCRUB);
1139
  SEQ_LED_PinSet(LED_METRONOME, seq_ui_button_state.METRONOME);
134 tk 1140
 
240 tk 1141
  SEQ_LED_PinSet(LED_UTILITY, ui_page == SEQ_UI_PAGE_UTIL);
1142
  SEQ_LED_PinSet(LED_COPY, seq_ui_button_state.COPY);
1143
  SEQ_LED_PinSet(LED_PASTE, seq_ui_button_state.PASTE);
1144
  SEQ_LED_PinSet(LED_CLEAR, seq_ui_button_state.CLEAR);
1145
 
1146
  SEQ_LED_PinSet(LED_F1, seq_ui_button_state.F1);
1147
  SEQ_LED_PinSet(LED_F2, seq_ui_button_state.F2);
1148
  SEQ_LED_PinSet(LED_F3, seq_ui_button_state.F3);
1149
  SEQ_LED_PinSet(LED_F4, seq_ui_button_state.F4);
1150
 
1151
  SEQ_LED_PinSet(LED_DOWN, seq_ui_button_state.DOWN);
1152
  SEQ_LED_PinSet(LED_UP, seq_ui_button_state.UP);
1153
 
167 tk 1154
 
306 tk 1155
  // in MENU page: overrule GP LEDs so long MENU button is pressed/active
1156
  if( seq_ui_button_state.MENU_PRESSED ) {
1157
    if( ui_cursor_flash ) // if flashing flag active: no LED flag set
1158
      ui_gp_leds = 0x0000;
1159
    else {
1160
      int i;
1161
      u16 new_ui_gp_leds = 0x0000;
1162
      for(i=0; i<16; ++i)
1163
    if( ui_page == ui_shortcut_menu_pages[i] )
1164
      new_ui_gp_leds |= (1 << i);
1165
      ui_gp_leds = new_ui_gp_leds;
1166
    }
1167
  } else {
1168
    // note: the background function is permanently interrupted - therefore we write the GP pattern
1169
    // into a temporary variable, and take it over once completed
1170
    u16 new_ui_gp_leds = 0x0000;
1171
    // request GP LED values from current menu page
1172
    // will be transfered to DOUT registers in SEQ_UI_LED_Handler_Periodic
1173
    new_ui_gp_leds = 0x0000;
206 tk 1174
 
306 tk 1175
    if( ui_led_callback != NULL )
1176
      ui_led_callback(&new_ui_gp_leds);
167 tk 1177
 
306 tk 1178
    ui_gp_leds = new_ui_gp_leds;
1179
  }
1180
 
134 tk 1181
  return 0; // no error
1182
}
1183
 
1184
 
1185
/////////////////////////////////////////////////////////////////////////////
1186
// updates high-prio LED functions (GP LEDs and Beat LED)
168 tk 1187
// called each mS
134 tk 1188
/////////////////////////////////////////////////////////////////////////////
1189
s32 SEQ_UI_LED_Handler_Periodic()
1190
{
1191
  // GP LEDs are only updated when ui_gp_leds or pos_marker_mask has changed
1192
  static u16 prev_ui_gp_leds = 0x0000;
1193
  static u16 prev_pos_marker_mask = 0x0000;
1194
 
1195
  // beat LED: tmp. for demo w/o real sequencer
193 tk 1196
  u8 sequencer_running = SEQ_BPM_IsRunning();
1197
  SEQ_LED_PinSet(LED_BEAT, (sequencer_running && (seq_core_state.ref_step & 3) == 0));
134 tk 1198
 
1199
  // for song position marker (supports 16 LEDs, check for selected step view)
1200
  u16 pos_marker_mask = 0x0000;
166 tk 1201
  u8 played_step = seq_core_trk[SEQ_UI_VisibleTrackGet()].step;
193 tk 1202
  if( sequencer_running && (played_step >> 4) == ui_selected_step_view )
134 tk 1203
    pos_marker_mask = 1 << (played_step & 0xf);
1204
 
1205
  // exit of pattern hasn't changed
173 tk 1206
  if( prev_ui_gp_leds == ui_gp_leds && prev_pos_marker_mask == pos_marker_mask )
134 tk 1207
    return 0;
173 tk 1208
  prev_ui_gp_leds = ui_gp_leds;
134 tk 1209
  prev_pos_marker_mask = pos_marker_mask;
1210
 
1211
  // transfer to GP LEDs
1212
 
1213
#ifdef DEFAULT_GP_DOUT_SR_L
1214
# ifdef DEFAULT_GP_DOUT_SR_L2
173 tk 1215
  SEQ_LED_SRSet(DEFAULT_GP_DOUT_SR_L-1, (ui_gp_leds >> 0) & 0xff);
134 tk 1216
# else
173 tk 1217
  SEQ_LED_SRSet(DEFAULT_GP_DOUT_SR_L-1, ((ui_gp_leds ^ pos_marker_mask) >> 0) & 0xff);
134 tk 1218
# endif
1219
#endif
1220
#ifdef DEFAULT_GP_DOUT_SR_R
1221
# ifdef DEFAULT_GP_DOUT_SR_R2
173 tk 1222
  SEQ_LED_SRSet(DEFAULT_GP_DOUT_SR_R-1, (ui_gp_leds >> 8) & 0xff);
134 tk 1223
#else
173 tk 1224
  SEQ_LED_SRSet(DEFAULT_GP_DOUT_SR_R-1, ((ui_gp_leds ^ pos_marker_mask) >> 8) & 0xff);
134 tk 1225
#endif
1226
#endif
1227
 
1228
#ifdef DEFAULT_GP_DOUT_SR_L2
1229
  SEQ_LED_SRSet(DEFAULT_GP_DOUT_SR_L2-1, (pos_marker_mask >> 0) & 0xff);
1230
#endif
1231
#ifdef DEFAULT_GP_DOUT_SR_R2
1232
  SEQ_LED_SRSet(DEFAULT_GP_DOUT_SR_R2-1, (pos_marker_mask >> 8) & 0xff);
1233
#endif
1234
 
1235
#if DEFAULT_SRM_ENABLED && DEFAULT_SRM_DOUT_M_MAPPING == 1
1236
  // for wilba's frontpanel
1237
 
1238
  // BLM8X8 DOUT -> GP LED mapping
1239
  // 0 = 15,16  1 = 13,14   2 = 11,12   3 = 9,10
1240
  // 4 = 1,2    5 = 3,4     6 = 5,6     7 = 7,8
1241
 
1242
  // bit 7: first green (i.e. GP1-G)
1243
  // bit 6: first red (i.e. GP1-R)
1244
  // bit 5: second green (i.e. GP2-G)
1245
  // bit 4: second red (i.e. GP2-R)
1246
 
1247
  // this mapping routine takes ca. 5 uS
173 tk 1248
  // since it's only executed when ui_gp_leds or gp_mask has changed, it doesn't really hurt
134 tk 1249
 
173 tk 1250
  u16 modified_gp_leds = ui_gp_leds;
134 tk 1251
#if 1
1252
  // extra: red LED is lit exclusively for higher contrast
1253
  modified_gp_leds &= ~pos_marker_mask;
1254
#endif
1255
 
1256
  int sr;
1257
  const u8 blm8x8_sr_map[8] = {4, 5, 6, 7, 3, 2, 1, 0};
1258
  u16 gp_mask = 1 << 0;
1259
  for(sr=0; sr<8; ++sr) {
1260
    u8 pattern = 0;
1261
 
1262
    if( modified_gp_leds & gp_mask )
1263
      pattern |= 0x80;
1264
    if( pos_marker_mask & gp_mask )
1265
      pattern |= 0x40;
1266
    gp_mask <<= 1;
1267
    if( modified_gp_leds & gp_mask )
1268
      pattern |= 0x20;
1269
    if( pos_marker_mask & gp_mask )
1270
      pattern |= 0x10;
1271
    gp_mask <<= 1;
1272
 
1273
    u8 mapped_sr = blm8x8_sr_map[sr];
1274
    blm8x8_led_row[mapped_sr] = (blm8x8_led_row[mapped_sr] & 0x0f) | pattern;
1275
  }
1276
#endif
1277
 
184 tk 1278
  return 0; // no error
134 tk 1279
}
1280
 
1281
 
1282
/////////////////////////////////////////////////////////////////////////////
168 tk 1283
// for menu handling (e.g. flashing cursor, doubleclick counter, etc...)
1284
// called each mS
1285
/////////////////////////////////////////////////////////////////////////////
1286
s32 SEQ_UI_MENU_Handler_Periodic()
1287
{
1288
  if( ++ui_cursor_flash_ctr >= SEQ_UI_CURSOR_FLASH_CTR_MAX ) {
1289
    ui_cursor_flash_ctr = 0;
1290
    seq_ui_display_update_req = 1;
173 tk 1291
  } else if( ui_cursor_flash_ctr == SEQ_UI_CURSOR_FLASH_CTR_LED_OFF ) {
168 tk 1292
    seq_ui_display_update_req = 1;
173 tk 1293
  }
1294
  // important: flash flag has to be recalculated on each invocation of this
1295
  // handler, since counter could also be reseted outside this function
1296
  ui_cursor_flash = ui_cursor_flash_ctr >= SEQ_UI_CURSOR_FLASH_CTR_LED_OFF;
168 tk 1297
 
184 tk 1298
 
240 tk 1299
  // used in some pages for temporary messages
1300
  if( ui_hold_msg_ctr )
1301
    --ui_hold_msg_ctr;
1302
 
299 tk 1303
  // used for temporary SD Card messages
1304
  if( sdcard_msg_ctr )
1305
    --sdcard_msg_ctr;
1306
 
184 tk 1307
  // VU meters (used in MUTE menu, could also be available as LED matrix...)
1308
  static u8 vu_meter_prediv = 0; // predivider for VU meters
1309
 
1310
  if( ++vu_meter_prediv >= 4 ) {
1311
    vu_meter_prediv = 0;
1312
 
1313
    u8 track;
1314
    seq_core_trk_t *t = &seq_core_trk[0];
318 tk 1315
    portENTER_CRITICAL();
184 tk 1316
    for(track=0; track<SEQ_CORE_NUM_TRACKS; ++t, ++track)
1317
      if( t->vu_meter )
1318
    --t->vu_meter;
318 tk 1319
    portEXIT_CRITICAL();
184 tk 1320
  }
1321
 
168 tk 1322
  return 0;
1323
}
1324
 
1325
 
1326
/////////////////////////////////////////////////////////////////////////////
134 tk 1327
// Returns the currently visible track
1328
/////////////////////////////////////////////////////////////////////////////
1329
u8 SEQ_UI_VisibleTrackGet(void)
1330
{
1331
  u8 offset = 0;
1332
 
1333
  if( ui_selected_tracks & (1 << 3) )
1334
    offset = 3;
1335
  if( ui_selected_tracks & (1 << 2) )
1336
    offset = 2;
1337
  if( ui_selected_tracks & (1 << 1) )
1338
    offset = 1;
1339
  if( ui_selected_tracks & (1 << 0) )
1340
    offset = 0;
1341
 
1342
  return 4*ui_selected_group + offset;
1343
}
1344
 
168 tk 1345
 
1346
/////////////////////////////////////////////////////////////////////////////
178 tk 1347
// Returns 1 if 'track' is selected
1348
/////////////////////////////////////////////////////////////////////////////
1349
s32 SEQ_UI_IsSelectedTrack(u8 track)
1350
{
1351
  if( (track>>2) != ui_selected_group )
1352
    return 0;
1353
  return (ui_selected_tracks & (1 << (track&3))) ? 1 : 0;
1354
}
1355
 
1356
 
1357
/////////////////////////////////////////////////////////////////////////////
240 tk 1358
// Sets a new selected step and updates the step view
1359
/////////////////////////////////////////////////////////////////////////////
1360
s32 SEQ_UI_SelectedStepSet(u8 step)
1361
{
1362
  ui_selected_step = step;
1363
  ui_selected_step_view = (ui_selected_step >= 16) ? 1 : 0;
1364
  return 0; // no error
1365
}
1366
 
1367
 
1368
/////////////////////////////////////////////////////////////////////////////
168 tk 1369
// Increments the selected tracks/groups
1370
// OUT: 1 if value has been changed, otherwise 0
1371
/////////////////////////////////////////////////////////////////////////////
1372
s32 SEQ_UI_GxTyInc(s32 incrementer)
1373
{
1374
  int gxty = SEQ_UI_VisibleTrackGet();
1375
  int prev_gxty = gxty;
1376
 
1377
  if( incrementer >= 0 ) {
1378
    if( (gxty += incrementer) >= SEQ_CORE_NUM_TRACKS )
1379
      gxty = SEQ_CORE_NUM_TRACKS-1;
1380
  } else {
1381
    if( (gxty += incrementer) < 0 )
1382
      gxty = 0;
1383
  }
1384
 
1385
  if( gxty == prev_gxty )
1386
    return 0; // no change
1387
 
1388
  ui_selected_tracks = 1 << (gxty % 4);
1389
  ui_selected_group = gxty / 4;
1390
 
1391
  return 1; // value changed
1392
}
1393
 
1394
 
1395
/////////////////////////////////////////////////////////////////////////////
236 tk 1396
// Increments a 16bit variable within given min/max range
1397
// OUT: 1 if value has been changed, otherwise 0
1398
/////////////////////////////////////////////////////////////////////////////
240 tk 1399
s32 SEQ_UI_Var16_Inc(u16 *value, u16 min, u16 max, s32 incrementer)
236 tk 1400
{
1401
  int new_value = *value;
1402
  int prev_value = new_value;
1403
 
1404
  if( incrementer >= 0 ) {
1405
    if( (new_value += incrementer) >= max )
1406
      new_value = max;
1407
  } else {
1408
    if( (new_value += incrementer) < min )
1409
      new_value = min;
1410
  }
1411
 
1412
  if( new_value == prev_value )
1413
    return 0; // no change
1414
 
1415
  *value = new_value;
1416
 
1417
  return 1; // value changed
1418
}
1419
 
240 tk 1420
/////////////////////////////////////////////////////////////////////////////
1421
// Increments an 8bit variable within given min/max range
1422
// OUT: 1 if value has been changed, otherwise 0
1423
/////////////////////////////////////////////////////////////////////////////
1424
s32 SEQ_UI_Var8_Inc(u8 *value, u16 min, u16 max, s32 incrementer)
1425
{
1426
  u16 tmp = *value;
1427
  if( SEQ_UI_Var16_Inc(&tmp, min, max, incrementer) ) {
1428
    *value = tmp;
1429
    return 1; // value changed
1430
  }
236 tk 1431
 
240 tk 1432
  return 0; // value hasn't been changed
1433
}
1434
 
1435
 
236 tk 1436
/////////////////////////////////////////////////////////////////////////////
168 tk 1437
// Increments a CC within given min/max range
1438
// OUT: 1 if value has been changed, otherwise 0
1439
/////////////////////////////////////////////////////////////////////////////
248 tk 1440
s32 SEQ_UI_CC_Inc(u8 cc, u8 min, u8 max, s32 incrementer)
168 tk 1441
{
1442
  u8 visible_track = SEQ_UI_VisibleTrackGet();
173 tk 1443
  int new_value = SEQ_CC_Get(visible_track, cc);
1444
  int prev_value = new_value;
168 tk 1445
 
1446
  if( incrementer >= 0 ) {
173 tk 1447
    if( (new_value += incrementer) >= max )
1448
      new_value = max;
168 tk 1449
  } else {
173 tk 1450
    if( (new_value += incrementer) < min )
1451
      new_value = min;
168 tk 1452
  }
1453
 
173 tk 1454
  if( new_value == prev_value )
168 tk 1455
    return 0; // no change
1456
 
173 tk 1457
  SEQ_CC_Set(visible_track, cc, new_value);
168 tk 1458
 
179 tk 1459
  // set same value for all selected tracks
1460
  u8 track;
1461
  for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track)
1462
    if( track != visible_track && SEQ_UI_IsSelectedTrack(track) )
1463
      SEQ_CC_Set(track, cc, new_value);
1464
 
168 tk 1465
  return 1; // value changed
1466
}
1467
 
173 tk 1468
 
1469
/////////////////////////////////////////////////////////////////////////////
179 tk 1470
// Sets a CC value on all selected tracks
1471
// OUT: 1 if value has been changed, otherwise 0
1472
/////////////////////////////////////////////////////////////////////////////
248 tk 1473
s32 SEQ_UI_CC_Set(u8 cc, u8 value)
179 tk 1474
{
1475
  u8 visible_track = SEQ_UI_VisibleTrackGet();
1476
  int prev_value = SEQ_CC_Get(visible_track, cc);
1477
 
1478
  if( value == prev_value )
1479
    return 0; // no change
1480
 
1481
  SEQ_CC_Set(visible_track, cc, value);
1482
 
1483
  // set same value for all selected tracks
1484
  u8 track;
1485
  for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track)
1486
    if( track != visible_track && SEQ_UI_IsSelectedTrack(track) )
1487
      SEQ_CC_Set(track, cc, value);
1488
 
1489
  return 1; // value changed
1490
}
1491
 
1492
/////////////////////////////////////////////////////////////////////////////
173 tk 1493
// Modifies a bitfield in a CC value to a given value
1494
// OUT: 1 if value has been changed, otherwise 0
1495
/////////////////////////////////////////////////////////////////////////////
248 tk 1496
s32 SEQ_UI_CC_SetFlags(u8 cc, u8 flag_mask, u8 value)
173 tk 1497
{
1498
  u8 visible_track = SEQ_UI_VisibleTrackGet();
1499
  int new_value = SEQ_CC_Get(visible_track, cc);
1500
  int prev_value = new_value;
1501
 
1502
  new_value = (new_value & ~flag_mask) | value;
1503
 
1504
  if( new_value == prev_value )
1505
    return 0; // no change
1506
 
1507
  SEQ_CC_Set(visible_track, cc, new_value);
1508
 
179 tk 1509
  // do same modification for all selected tracks
1510
  u8 track;
1511
  for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track)
1512
    if( track != visible_track && SEQ_UI_IsSelectedTrack(track) ) {
1513
      int new_value = SEQ_CC_Get(track, cc);
1514
      new_value = (new_value & ~flag_mask) | value;
1515
      SEQ_CC_Set(track, cc, new_value);
1516
    }
1517
 
173 tk 1518
  return 1; // value changed
1519
}
1520
 
1521
 
299 tk 1522
/////////////////////////////////////////////////////////////////////////////
1523
// Print temporary messages after file operations
1524
// expects mS delay and two lines, each up to 20 characters
1525
/////////////////////////////////////////////////////////////////////////////
1526
s32 SEQ_UI_SDCardMsg(u16 delay, char *line1, char *line2)
1527
{
1528
  sdcard_msg_ctr = delay;
1529
  strncpy((char *)sdcard_msg[0], line1, SDCARD_MSG_MAX_CHAR);
1530
  strncpy((char *)sdcard_msg[1], line2, SDCARD_MSG_MAX_CHAR);
1531
 
1532
  return 0; // no error
1533
}
1534
 
1535
/////////////////////////////////////////////////////////////////////////////
1536
// Prints a temporary error messages after file operation
1537
// Expects error status number (as defined in seq_file.h)
1538
/////////////////////////////////////////////////////////////////////////////
1539
s32 SEQ_UI_SDCardErrMsg(u16 delay, s32 status)
1540
{
1541
  // TODO: add more verbose error messages, they are clearly defined in seq_file.h)
1542
  char str[21];
1543
  sprintf(str, "E%3d (DOSFS: D%3d)", -status, seq_file_dfs_errno < 1000 ? seq_file_dfs_errno : 999);
1544
  return SEQ_UI_SDCardMsg(delay, "!! SD Card Error !!!", str);
1545
}