Subversion Repositories svn.mios32

Rev

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