Subversion Repositories svn.mios32

Rev

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