Subversion Repositories svn.mios32

Rev

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