Subversion Repositories svn.mios32

Rev

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