Subversion Repositories svn.mios32

Rev

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