Subversion Repositories svn.mios32

Rev

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