Subversion Repositories svn.mios32

Rev

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