Subversion Repositories svn.mios32

Rev

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