Subversion Repositories svn.mios32

Rev

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