Subversion Repositories svn.mios32

Rev

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