Subversion Repositories svn.mios32

Rev

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