Subversion Repositories svn.mios32

Rev

Rev 166 | Rev 168 | 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 167 2008-12-07 02:58:05Z 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
 
20
#if DEFAULT_SRM_ENABLED
21
#include <blm8x8.h>
22
#endif
23
 
24
#include "seq_ui.h"
25
#include "seq_lcd.h"
26
#include "seq_led.h"
27
#include "seq_midi.h"
159 tk 28
#include "seq_bpm.h"
134 tk 29
#include "seq_core.h"
30
#include "seq_par.h"
31
#include "seq_trg.h"
32
 
33
 
34
/////////////////////////////////////////////////////////////////////////////
35
// Local types
36
/////////////////////////////////////////////////////////////////////////////
37
 
38
 
39
/////////////////////////////////////////////////////////////////////////////
40
// Local prototypes
41
/////////////////////////////////////////////////////////////////////////////
42
 
43
 
44
/////////////////////////////////////////////////////////////////////////////
45
// Global variables
46
/////////////////////////////////////////////////////////////////////////////
47
 
159 tk 48
u8 seq_ui_display_update_req;
49
u8 seq_ui_display_init_req;
134 tk 50
 
167 tk 51
seq_ui_button_state_t seq_ui_button_state;
52
 
134 tk 53
u8 ui_selected_group;
54
u8 ui_selected_tracks;
55
u8 ui_selected_par_layer;
56
u8 ui_selected_trg_layer;
57
u8 ui_selected_step_view;
58
u8 ui_selected_step;
59
 
60
u16 ui_gp_leds;
167 tk 61
u16 ui_gp_leds_flashing;
134 tk 62
 
63
 
64
/////////////////////////////////////////////////////////////////////////////
65
// Local variables
66
/////////////////////////////////////////////////////////////////////////////
67
 
167 tk 68
// Note: must be kept in sync with SEQ_UI_PAGE_xxx definitions in seq_ui.h!
69
static const s32 (*ui_init_callback[SEQ_UI_PAGES])(u32 mode) = {
70
  (void *)&SEQ_UI_TODO_Init,    // 0
71
  (void *)&SEQ_UI_EDIT_Init,    // 1
72
  (void *)&SEQ_UI_TRKDIR_Init   // 2
73
};
134 tk 74
 
167 tk 75
static s32 (*ui_gp_button_callback)(u32 pin, s32 depressed);
76
static s32 (*ui_gp_encoder_callback)(u32 encoder, s32 incrementer);
77
static s32 (*ui_gp_led_callback)(u16 *gp_leds, u16 *gp_leds_flashing);
78
static s32 (*ui_lcd_callback)(u8 high_prio);
79
 
80
static seq_ui_page_t ui_page;
81
 
82
 
83
// following pages are directly accessible with the GP buttons when MENU button is pressed
84
static const seq_ui_page_t ui_direct_access_menu_pages[16] = {
85
  SEQ_UI_PAGE_NONE,        // GP1
86
  SEQ_UI_PAGE_NONE,        // GP2
87
  SEQ_UI_PAGE_NONE,        // GP3
88
  SEQ_UI_PAGE_TRKDIR,      // GP4
89
  SEQ_UI_PAGE_NONE,        // GP5
90
  SEQ_UI_PAGE_NONE,        // GP6
91
  SEQ_UI_PAGE_NONE,        // GP7
92
  SEQ_UI_PAGE_NONE,        // GP8
93
  SEQ_UI_PAGE_NONE,        // GP9
94
  SEQ_UI_PAGE_NONE,        // GP10
95
  SEQ_UI_PAGE_NONE,        // GP11
96
  SEQ_UI_PAGE_NONE,        // GP12
97
  SEQ_UI_PAGE_NONE,        // GP13
98
  SEQ_UI_PAGE_NONE,        // GP14
99
  SEQ_UI_PAGE_NONE,        // GP15
100
  SEQ_UI_PAGE_NONE         // GP16
101
};
102
 
103
 
134 tk 104
/////////////////////////////////////////////////////////////////////////////
105
// Initialisation
106
/////////////////////////////////////////////////////////////////////////////
107
s32 SEQ_UI_Init(u32 mode)
108
{
109
  // init selection variables
110
  ui_selected_group = 0;
111
  ui_selected_tracks = (1 << 0);
112
  ui_selected_par_layer = 0;
113
  ui_selected_trg_layer = 0;
114
  ui_selected_step_view = 0;
115
  ui_selected_step = 0;
116
 
167 tk 117
  seq_ui_button_state.ALL = 0;
118
 
134 tk 119
  // visible GP pattern
120
  ui_gp_leds = 0x0000;
167 tk 121
  ui_gp_leds_flashing = 0x0000;
134 tk 122
 
167 tk 123
  // change to edit page
124
  ui_page = SEQ_UI_PAGE_NONE;
125
  SEQ_UI_PageSet(SEQ_UI_PAGE_EDIT);
134 tk 126
 
127
  return 0; // no error
128
}
129
 
130
 
131
/////////////////////////////////////////////////////////////////////////////
167 tk 132
// Various installation routines for menu page LCD handlers
133
/////////////////////////////////////////////////////////////////////////////
134
s32 SEQ_UI_InstallGPButtonCallback(void *callback)
135
{
136
  ui_gp_button_callback = callback;
137
  return 0; // no error
138
}
139
 
140
s32 SEQ_UI_InstallGPEncoderCallback(void *callback)
141
{
142
  ui_gp_encoder_callback = callback;
143
  return 0; // no error
144
}
145
 
146
s32 SEQ_UI_InstallGPLEDCallback(void *callback)
147
{
148
  ui_gp_led_callback = callback;
149
  return 0; // no error
150
}
151
 
152
s32 SEQ_UI_InstallGPLCDCallback(void *callback)
153
{
154
  ui_lcd_callback = callback;
155
  return 0; // no error
156
}
157
 
158
 
159
/////////////////////////////////////////////////////////////////////////////
160
// Change the menu page
161
/////////////////////////////////////////////////////////////////////////////
162
s32 SEQ_UI_PageSet(seq_ui_page_t page)
163
{
164
  if( page != ui_page ) {
165
    // disable hooks of previous page and request re-initialisation
166
    MIOS32_IRQ_Disable();
167
    ui_page = page;
168
    ui_gp_button_callback = NULL;
169
    ui_gp_encoder_callback = NULL;
170
    ui_gp_led_callback = NULL;
171
    ui_lcd_callback = NULL;
172
    MIOS32_IRQ_Enable();
173
 
174
  // TODO: define generic #define for this button behaviour
175
#if defined(MIOS32_FAMILY_EMULATION)
176
  seq_ui_button_state.MENU_PRESSED = 0; // MENU page selection finished
177
#endif
178
 
179
    // request display initialisation
180
    seq_ui_display_init_req = 1;
181
  }
182
}
183
 
184
 
185
/////////////////////////////////////////////////////////////////////////////
134 tk 186
// Dedicated button functions
187
// Mapped to physical buttons in SEQ_UI_Button_Handler()
188
// Will also be mapped to MIDI keys later (for MIDI remote function)
189
/////////////////////////////////////////////////////////////////////////////
190
static s32 SEQ_UI_Button_GP(s32 depressed, u32 gp)
191
{
192
  if( depressed ) return -1; // ignore when button depressed
193
 
167 tk 194
  if( seq_ui_button_state.MENU_PRESSED ) {
195
    // MENU button overruling - select menu page
196
    SEQ_UI_PageSet(ui_direct_access_menu_pages[gp]);
197
  } else {
198
    // forward to menu page
199
    if( ui_gp_button_callback != NULL )
200
      ui_gp_button_callback(gp, depressed);
201
  }
134 tk 202
 
203
  return 0; // no error
204
}
205
 
206
static s32 SEQ_UI_Button_Left(s32 depressed)
207
{
208
  if( depressed ) return -1; // ignore when button depressed
209
 
210
  return 0; // no error
211
}
212
 
213
static s32 SEQ_UI_Button_Right(s32 depressed)
214
{
215
  if( depressed ) return -1; // ignore when button depressed
216
 
217
  return 0; // no error
218
}
219
 
220
static s32 SEQ_UI_Button_Scrub(s32 depressed)
221
{
137 tk 222
#if 0
134 tk 223
  if( depressed ) return -1; // ignore when button depressed
137 tk 224
#else
225
  // Sending SysEx Stream test
226
  u8 buffer[7] = { 0xf0, 0x11, 0x22, 0x33, 0x44, depressed ? 0x00 : 0x55, 0xf7 };
134 tk 227
 
137 tk 228
  MIOS32_MIDI_SendSysEx(DEFAULT, buffer, 7);
229
#endif
230
 
134 tk 231
  return 0; // no error
232
}
233
 
234
static s32 SEQ_UI_Button_Metronome(s32 depressed)
235
{
137 tk 236
#if 0
134 tk 237
  if( depressed ) return -1; // ignore when button depressed
137 tk 238
#else
239
  // Sending MIDI Note test
240
  if( depressed )
241
    MIOS32_MIDI_SendNoteOff(DEFAULT, 0x90, 0x3c, 0x00);
242
  else
243
    MIOS32_MIDI_SendNoteOn(DEFAULT, 0x90, 0x3c, 0x7f);
244
#endif
134 tk 245
 
246
  return 0; // no error
247
}
248
 
249
static s32 SEQ_UI_Button_Stop(s32 depressed)
250
{
251
  if( depressed ) return -1; // ignore when button depressed
252
 
159 tk 253
  // if sequencer running: stop it
254
  // if sequencer already stopped: reset song position
166 tk 255
  if( seq_core_state.RUN )
159 tk 256
    SEQ_CORE_Stop(0);
257
  else
258
    SEQ_CORE_Reset();
259
 
134 tk 260
  return 0; // no error
261
}
262
 
263
static s32 SEQ_UI_Button_Pause(s32 depressed)
264
{
265
  if( depressed ) return -1; // ignore when button depressed
266
 
159 tk 267
  // pause sequencer
268
  SEQ_CORE_Pause(0);
269
 
134 tk 270
  return 0; // no error
271
}
272
 
273
static s32 SEQ_UI_Button_Play(s32 depressed)
274
{
275
  if( depressed ) return -1; // ignore when button depressed
276
 
159 tk 277
  // start sequencer
278
  SEQ_CORE_Start(0);
279
 
134 tk 280
  return 0; // no error
281
}
282
 
283
static s32 SEQ_UI_Button_Rew(s32 depressed)
284
{
285
  if( depressed ) return -1; // ignore when button depressed
286
 
287
  return 0; // no error
288
}
289
 
290
static s32 SEQ_UI_Button_Fwd(s32 depressed)
291
{
292
  if( depressed ) return -1; // ignore when button depressed
293
 
294
  return 0; // no error
295
}
296
 
297
static s32 SEQ_UI_Button_F1(s32 depressed)
298
{
299
  if( depressed ) return -1; // ignore when button depressed
300
 
301
  return 0; // no error
302
}
303
 
304
static s32 SEQ_UI_Button_F2(s32 depressed)
305
{
306
  if( depressed ) return -1; // ignore when button depressed
307
 
308
  return 0; // no error
309
}
310
 
311
static s32 SEQ_UI_Button_F3(s32 depressed)
312
{
313
  if( depressed ) return -1; // ignore when button depressed
314
 
315
  return 0; // no error
316
}
317
 
318
static s32 SEQ_UI_Button_F4(s32 depressed)
319
{
320
  if( depressed ) return -1; // ignore when button depressed
321
 
322
  return 0; // no error
323
}
324
 
325
static s32 SEQ_UI_Button_Utility(s32 depressed)
326
{
327
  if( depressed ) return -1; // ignore when button depressed
328
 
329
  return 0; // no error
330
}
331
 
332
static s32 SEQ_UI_Button_Copy(s32 depressed)
333
{
334
  if( depressed ) return -1; // ignore when button depressed
335
 
336
  return 0; // no error
337
}
338
 
339
static s32 SEQ_UI_Button_Paste(s32 depressed)
340
{
341
  if( depressed ) return -1; // ignore when button depressed
342
 
343
  return 0; // no error
344
}
345
 
346
static s32 SEQ_UI_Button_Clear(s32 depressed)
347
{
348
  if( depressed ) return -1; // ignore when button depressed
349
 
350
  return 0; // no error
351
}
352
 
353
static s32 SEQ_UI_Button_Menu(s32 depressed)
354
{
167 tk 355
  // TODO: define generic #define for this button behaviour
356
#if defined(MIOS32_FAMILY_EMULATION)
134 tk 357
  if( depressed ) return -1; // ignore when button depressed
167 tk 358
  seq_ui_button_state.MENU_PRESSED ^= 1; // toggle MENU pressed (will also be released once GP button has been pressed)
359
#else
360
  seq_ui_button_state.MENU_PRESSED = depressed ? 0 : 1;
361
#endif
134 tk 362
 
363
  return 0; // no error
364
}
365
 
366
static s32 SEQ_UI_Button_Select(s32 depressed)
367
{
368
  if( depressed ) return -1; // ignore when button depressed
369
 
370
  return 0; // no error
371
}
372
 
373
static s32 SEQ_UI_Button_Exit(s32 depressed)
374
{
375
  if( depressed ) return -1; // ignore when button depressed
376
 
167 tk 377
  // release all button states
378
  seq_ui_button_state.ALL = 0;
379
 
134 tk 380
  return 0; // no error
381
}
382
 
383
static s32 SEQ_UI_Button_Edit(s32 depressed)
384
{
385
  if( depressed ) return -1; // ignore when button depressed
386
 
167 tk 387
  // change to edit page
388
  SEQ_UI_PageSet(SEQ_UI_PAGE_EDIT);
389
 
134 tk 390
  return 0; // no error
391
}
392
 
393
static s32 SEQ_UI_Button_Mute(s32 depressed)
394
{
395
  if( depressed ) return -1; // ignore when button depressed
396
 
397
  return 0; // no error
398
}
399
 
400
static s32 SEQ_UI_Button_Pattern(s32 depressed)
401
{
402
  if( depressed ) return -1; // ignore when button depressed
403
 
404
  return 0; // no error
405
}
406
 
407
static s32 SEQ_UI_Button_Song(s32 depressed)
408
{
409
  if( depressed ) return -1; // ignore when button depressed
410
 
411
  return 0; // no error
412
}
413
 
414
static s32 SEQ_UI_Button_Solo(s32 depressed)
415
{
416
  if( depressed ) return -1; // ignore when button depressed
417
 
418
  return 0; // no error
419
}
420
 
421
static s32 SEQ_UI_Button_Fast(s32 depressed)
422
{
423
  if( depressed ) return -1; // ignore when button depressed
424
 
425
  return 0; // no error
426
}
427
 
428
static s32 SEQ_UI_Button_All(s32 depressed)
429
{
430
  if( depressed ) return -1; // ignore when button depressed
431
 
432
  return 0; // no error
433
}
434
 
435
static s32 SEQ_UI_Button_StepView(s32 depressed)
436
{
437
  if( depressed ) return -1; // ignore when button depressed
438
 
439
  ui_selected_step_view = ui_selected_step_view ? 0 : 1;
440
 
441
  return 0; // no error
442
}
443
 
444
static s32 SEQ_UI_Button_TapTempo(s32 depressed)
445
{
446
  if( depressed ) return -1; // ignore when button depressed
447
 
448
  return 0; // no error
449
}
450
 
451
static s32 SEQ_UI_Button_Track(s32 depressed, u32 track)
452
{
453
  if( depressed ) return -1; // ignore when button depressed
454
 
455
  if( track >= 4 ) return -2; // max. 4 track buttons
456
 
457
  ui_selected_tracks = (1 << track); // TODO: multi-selections!
458
 
459
  return 0; // no error
460
}
461
 
462
static s32 SEQ_UI_Button_Group(s32 depressed, u32 group)
463
{
464
  if( depressed ) return -1; // ignore when button depressed
465
 
466
  if( group >= 4 ) return -2; // max. 4 group buttons
467
 
468
  ui_selected_group = group;
469
 
470
  return 0; // no error
471
}
472
 
473
static s32 SEQ_UI_Button_ParLayer(s32 depressed, u32 par_layer)
474
{
475
  if( depressed ) return -1; // ignore when button depressed
476
 
477
  if( par_layer >= 3 ) return -2; // max. 3 parlayer buttons
478
 
479
  ui_selected_par_layer = par_layer;
480
 
481
  return 0; // no error
482
}
483
 
484
static s32 SEQ_UI_Button_TrgLayer(s32 depressed, u32 trg_layer)
485
{
486
  if( depressed ) return -1; // ignore when button depressed
487
 
488
  if( trg_layer >= 3 ) return -2; // max. 3 trglayer buttons
489
 
490
  ui_selected_trg_layer = trg_layer;
491
 
492
  return 0; // no error
493
}
494
 
495
 
496
 
497
/////////////////////////////////////////////////////////////////////////////
498
// Button handler
499
/////////////////////////////////////////////////////////////////////////////
500
s32 SEQ_UI_Button_Handler(u32 pin, u32 pin_value)
501
{
502
  switch( pin ) {
503
#if BUTTON_GP1
504
    case BUTTON_GP1:   SEQ_UI_Button_GP(pin_value, 0); break;
505
#endif
506
#if BUTTON_GP2
507
    case BUTTON_GP2:   SEQ_UI_Button_GP(pin_value, 1); break;
508
#endif
509
#if BUTTON_GP3
510
    case BUTTON_GP3:   SEQ_UI_Button_GP(pin_value, 2); break;
511
#endif
512
#if BUTTON_GP4
513
    case BUTTON_GP4:   SEQ_UI_Button_GP(pin_value, 3); break;
514
#endif
515
#if BUTTON_GP5
516
    case BUTTON_GP5:   SEQ_UI_Button_GP(pin_value, 4); break;
517
#endif
518
#if BUTTON_GP6
519
    case BUTTON_GP6:   SEQ_UI_Button_GP(pin_value, 5); break;
520
#endif
521
#if BUTTON_GP7
522
    case BUTTON_GP7:   SEQ_UI_Button_GP(pin_value, 6); break;
523
#endif
524
#if BUTTON_GP8
525
    case BUTTON_GP8:   SEQ_UI_Button_GP(pin_value, 7); break;
526
#endif
527
#if BUTTON_GP9
528
    case BUTTON_GP9:   SEQ_UI_Button_GP(pin_value, 8); break;
529
#endif
530
#if BUTTON_GP10
531
    case BUTTON_GP10:  SEQ_UI_Button_GP(pin_value, 9); break;
532
#endif
533
#if BUTTON_GP11
534
    case BUTTON_GP11:  SEQ_UI_Button_GP(pin_value, 10); break;
535
#endif
536
#if BUTTON_GP12
537
    case BUTTON_GP12:  SEQ_UI_Button_GP(pin_value, 11); break;
538
#endif
539
#if BUTTON_GP13
540
    case BUTTON_GP13:  SEQ_UI_Button_GP(pin_value, 12); break;
541
#endif
542
#if BUTTON_GP14
543
    case BUTTON_GP14:  SEQ_UI_Button_GP(pin_value, 13); break;
544
#endif
545
#if BUTTON_GP15
546
    case BUTTON_GP15:  SEQ_UI_Button_GP(pin_value, 14); break;
547
#endif
548
#if BUTTON_GP16
549
    case BUTTON_GP16:  SEQ_UI_Button_GP(pin_value, 15); break;
550
#endif
551
 
552
#if BUTTON_LEFT
553
    case BUTTON_LEFT:  SEQ_UI_Button_Left(pin_value); break;
554
#endif
555
#if BUTTON_RIGHT
556
    case BUTTON_RIGHT: SEQ_UI_Button_Right(pin_value); break;
557
#endif
558
 
559
#if BUTTON_SCRUB
560
    case BUTTON_SCRUB: SEQ_UI_Button_Scrub(pin_value); break;
561
#endif
562
#if BUTTON_METRONOME
563
    case BUTTON_METRONOME: SEQ_UI_Button_Metronome(pin_value); break;
564
#endif
565
 
566
#if BUTTON_STOP
567
    case BUTTON_STOP:  SEQ_UI_Button_Stop(pin_value); break;
568
#endif
569
#if BUTTON_PAUSE
570
    case BUTTON_PAUSE: SEQ_UI_Button_Pause(pin_value); break;
571
#endif
572
#if BUTTON_PLAY
573
    case BUTTON_PLAY:  SEQ_UI_Button_Play(pin_value); break;
574
#endif
575
#if BUTTON_REW
576
    case BUTTON_REW:   SEQ_UI_Button_Rew(pin_value); break;
577
#endif
578
#if BUTTON_FWD
579
    case BUTTON_FWD:   SEQ_UI_Button_Fwd(pin_value); break;
580
#endif
581
 
582
#if BUTTON_F1
583
    case BUTTON_F1:    SEQ_UI_Button_F1(pin_value); break;
584
#endif
585
#if BUTTON_F2
586
    case BUTTON_F2:    SEQ_UI_Button_F2(pin_value); break;
587
#endif
588
#if BUTTON_F3
589
    case BUTTON_F3:    SEQ_UI_Button_F3(pin_value); break;
590
#endif
591
#if BUTTON_F4
592
    case BUTTON_F4:    SEQ_UI_Button_F4(pin_value); break;
593
#endif
594
 
595
#if BUTTON_UTILITY
596
    case BUTTON_UTILITY: SEQ_UI_Button_Utility(pin_value); break;
597
#endif
598
#if BUTTON_COPY
599
    case BUTTON_COPY:  SEQ_UI_Button_Copy(pin_value); break;
600
#endif
601
#if BUTTON_PASTE
602
    case BUTTON_PASTE: SEQ_UI_Button_Paste(pin_value); break;
603
#endif
604
#if BUTTON_CLEAR
605
    case BUTTON_CLEAR: SEQ_UI_Button_Clear(pin_value); break;
606
#endif
607
 
608
#if BUTTON_MENU
609
    case BUTTON_MENU:  SEQ_UI_Button_Menu(pin_value); break;
610
#endif
611
#if BUTTON_SELECT
612
    case BUTTON_SELECT:SEQ_UI_Button_Select(pin_value); break;
613
#endif
614
#if BUTTON_EXIT
615
    case BUTTON_EXIT:  SEQ_UI_Button_Exit(pin_value); break;
616
#endif
617
 
618
#if BUTTON_TRACK1
619
    case BUTTON_TRACK1: SEQ_UI_Button_Track(pin_value, 0); break;
620
#endif
621
#if BUTTON_TRACK2
622
    case BUTTON_TRACK2: SEQ_UI_Button_Track(pin_value, 1); break;
623
#endif
624
#if BUTTON_TRACK3
625
    case BUTTON_TRACK3: SEQ_UI_Button_Track(pin_value, 2); break;
626
#endif
627
#if BUTTON_TRACK4
628
    case BUTTON_TRACK4: SEQ_UI_Button_Track(pin_value, 3); break;
629
#endif
630
 
631
#if BUTTON_PAR_LAYER_A
632
    case BUTTON_PAR_LAYER_A: SEQ_UI_Button_ParLayer(pin_value, 0); break;
633
#endif
634
#if BUTTON_PAR_LAYER_B
635
    case BUTTON_PAR_LAYER_B: SEQ_UI_Button_ParLayer(pin_value, 1); break;
636
#endif
637
#if BUTTON_PAR_LAYER_C
638
    case BUTTON_PAR_LAYER_C: SEQ_UI_Button_ParLayer(pin_value, 2); break;
639
#endif
640
 
641
#if BUTTON_EDIT
642
    case BUTTON_EDIT:   SEQ_UI_Button_Edit(pin_value); break;
643
#endif
644
#if BUTTON_MUTE
645
    case BUTTON_MUTE:   SEQ_UI_Button_Mute(pin_value); break;
646
#endif
647
#if BUTTON_PATTERN
648
    case BUTTON_PATTERN:SEQ_UI_Button_Pattern(pin_value); break;
649
#endif
650
#if BUTTON_SONG
651
    case BUTTON_SONG:   SEQ_UI_Button_Song(pin_value); break;
652
#endif
653
 
654
#if BUTTON_SOLO
655
    case BUTTON_SOLO:   SEQ_UI_Button_Solo(pin_value); break;
656
#endif
657
#if BUTTON_FAST
658
    case BUTTON_FAST:   SEQ_UI_Button_Fast(pin_value); break;
659
#endif
660
#if BUTTON_ALL
661
    case BUTTON_ALL:    SEQ_UI_Button_All(pin_value); break;
662
#endif
663
 
664
#if BUTTON_GROUP1
665
    case BUTTON_GROUP1: SEQ_UI_Button_Group(pin_value, 0); break;
666
#endif
667
#if BUTTON_GROUP2
668
    case BUTTON_GROUP2: SEQ_UI_Button_Group(pin_value, 1); break;
669
#endif
670
#if BUTTON_GROUP3
671
    case BUTTON_GROUP3: SEQ_UI_Button_Group(pin_value, 2); break;
672
#endif
673
#if BUTTON_GROUP4
674
    case BUTTON_GROUP4: SEQ_UI_Button_Group(pin_value, 3); break;
675
#endif
676
 
677
#if BUTTON_TRG_LAYER_A
678
    case BUTTON_TRG_LAYER_A: SEQ_UI_Button_TrgLayer(pin_value, 0); break;
679
#endif
680
#if BUTTON_TRG_LAYER_B
681
    case BUTTON_TRG_LAYER_B: SEQ_UI_Button_TrgLayer(pin_value, 1); break;
682
#endif
683
#if BUTTON_TRG_LAYER_C
684
    case BUTTON_TRG_LAYER_C: SEQ_UI_Button_TrgLayer(pin_value, 2); break;
685
#endif
686
 
687
#if BUTTON_STEP_VIEW
688
    case BUTTON_STEP_VIEW: SEQ_UI_Button_StepView(pin_value); break;
689
#endif
690
 
691
#if BUTTON_TAP_TEMPO
692
    case BUTTON_TAP_TEMPO:   SEQ_UI_Button_TapTempo(pin_value); break;
693
#endif
694
 
695
    default:
696
      return -1; // button function not mapped to physical button
697
  }
698
 
699
  // request display update
159 tk 700
  seq_ui_display_update_req = 1;
134 tk 701
 
702
  return 0; // no error
703
}
704
 
705
 
706
/////////////////////////////////////////////////////////////////////////////
707
// Encoder handler
708
/////////////////////////////////////////////////////////////////////////////
709
s32 SEQ_UI_Encoder_Handler(u32 encoder, s32 incrementer)
710
{
711
  if( encoder > 16 )
712
    return -1; // encoder doesn't exist
713
 
714
  // limit incrementer
715
  if( incrementer > 3 )
716
    incrementer = 3;
717
  else if( incrementer < -3 )
718
    incrementer = -3;
719
 
720
  if( encoder == 0 ) {
166 tk 721
    // TODO
134 tk 722
  } else {
167 tk 723
    // forward to menu page
724
    if( ui_gp_encoder_callback != NULL )
725
      ui_gp_encoder_callback(encoder, incrementer);
134 tk 726
  }
727
 
728
  // request display update
159 tk 729
  seq_ui_display_update_req = 1;
134 tk 730
 
731
  return 0; // no error
732
}
733
 
734
 
735
/////////////////////////////////////////////////////////////////////////////
736
// Update LCD messages
737
// Usually called from background task
738
/////////////////////////////////////////////////////////////////////////////
739
s32 SEQ_UI_LCD_Handler(void)
740
{
159 tk 741
  if( seq_ui_display_init_req ) {
742
    seq_ui_display_init_req = 0; // clear request
134 tk 743
 
744
    // clear both LCDs
745
    int i;
746
    for(i=0; i<2; ++i) {
747
      MIOS32_LCD_DeviceSet(i);
748
      SEQ_LCD_Clear();
749
    }
750
 
167 tk 751
    // call init function of current page
752
    if( ui_init_callback[ui_page] != NULL )
753
      ui_init_callback[ui_page](0); // mode
134 tk 754
 
755
    // request display update
159 tk 756
    seq_ui_display_update_req = 1;
134 tk 757
  }
758
 
167 tk 759
  // perform high priority LCD update request
760
  if( ui_lcd_callback != NULL )
761
    ui_lcd_callback(1); // high_prio
762
 
763
  // perform low priority LCD update request if requested
159 tk 764
  if( seq_ui_display_update_req ) {
765
    seq_ui_display_update_req = 0; // clear request
134 tk 766
 
167 tk 767
#if 0
768
  // print available menu pages
769
  MIOS32_LCD_DeviceSet(0);
770
  MIOS32_LCD_CursorSet(0, 0);
771
  //                      <-------------------------------------->
772
  //                      0123456789012345678901234567890123456789
773
  MIOS32_LCD_PrintString("                                        ");
774
  MIOS32_LCD_CursorSet(0, 1);
775
  MIOS32_LCD_PrintString("Mix  Evnt Mode Dir. Div. Len. Trn. Grv. ");
134 tk 776
 
167 tk 777
  MIOS32_LCD_DeviceSet(1);
778
  MIOS32_LCD_CursorSet(0, 0);
779
  //                      <-------------------------------------->
780
  //                      0123456789012345678901234567890123456789
781
  MIOS32_LCD_PrintString("                                        ");
782
  MIOS32_LCD_CursorSet(0, 1);
783
  MIOS32_LCD_PrintString("Trg.  Fx  Man. Mrp. BPM  Save MIDI SysEx");
784
#endif
785
 
786
    if( ui_lcd_callback != NULL )
787
      ui_lcd_callback(0); // no high_prio
134 tk 788
  }
789
 
159 tk 790
  // for debugging
791
#if 0
792
  MIOS32_LCD_DeviceSet(0);
793
  MIOS32_LCD_CursorSet(0, 0);
794
  MIOS32_LCD_PrintFormattedString("%5d  ", seq_midi_queue_size);
795
#endif
796
 
167 tk 797
#if 0
166 tk 798
  u32 bpm_tick = SEQ_BPM_TickGet();
799
  u32 bpm_sub = bpm_tick % SEQ_BPM_RESOLUTION_PPQN;
800
  u32 bpm_16th = (bpm_tick / (SEQ_BPM_RESOLUTION_PPQN/4)) % 16;
801
  u32 bpm_qn = (bpm_tick / SEQ_BPM_RESOLUTION_PPQN) % 4;
802
  u32 bpm_n = bpm_tick / (4*SEQ_BPM_RESOLUTION_PPQN);
803
  MIOS32_LCD_DeviceSet(0);
804
  MIOS32_LCD_CursorSet(0, 0);
805
  MIOS32_LCD_PrintFormattedString("%3d.%2d.%2d.%3d  ", bpm_n, bpm_qn, bpm_16th, bpm_sub);
806
#endif
807
 
134 tk 808
  return 0; // no error
809
}
810
 
811
 
812
 
813
/////////////////////////////////////////////////////////////////////////////
814
// Update all LEDs
815
// Usually called from background task
816
/////////////////////////////////////////////////////////////////////////////
817
s32 SEQ_UI_LED_Handler(void)
818
{
819
  u8 visible_track = SEQ_UI_VisibleTrackGet();
820
 
821
  // track LEDs
167 tk 822
  SEQ_LED_PinSet(LED_TRACK1, (ui_selected_tracks & (1 << 0)));
823
  SEQ_LED_PinSet(LED_TRACK2, (ui_selected_tracks & (1 << 1)));
824
  SEQ_LED_PinSet(LED_TRACK3, (ui_selected_tracks & (1 << 2)));
825
  SEQ_LED_PinSet(LED_TRACK4, (ui_selected_tracks & (1 << 3)));
134 tk 826
 
827
  // parameter layer LEDs
167 tk 828
  SEQ_LED_PinSet(LED_PAR_LAYER_A, (ui_selected_par_layer == 0));
829
  SEQ_LED_PinSet(LED_PAR_LAYER_B, (ui_selected_par_layer == 1));
830
  SEQ_LED_PinSet(LED_PAR_LAYER_C, (ui_selected_par_layer == 2));
134 tk 831
 
832
  // group LEDs
167 tk 833
  SEQ_LED_PinSet(LED_GROUP1, (ui_selected_group == 0));
834
  SEQ_LED_PinSet(LED_GROUP2, (ui_selected_group == 1));
835
  SEQ_LED_PinSet(LED_GROUP3, (ui_selected_group == 2));
836
  SEQ_LED_PinSet(LED_GROUP4, (ui_selected_group == 3));
134 tk 837
 
838
  // trigger layer LEDs
167 tk 839
  SEQ_LED_PinSet(LED_TRG_LAYER_A, (ui_selected_trg_layer == 0));
840
  SEQ_LED_PinSet(LED_TRG_LAYER_B, (ui_selected_trg_layer == 1));
841
  SEQ_LED_PinSet(LED_TRG_LAYER_C, (ui_selected_trg_layer == 2));
134 tk 842
 
843
  // remaining LEDs
167 tk 844
  SEQ_LED_PinSet(LED_EDIT, ui_page == SEQ_UI_PAGE_EDIT);
134 tk 845
  SEQ_LED_PinSet(LED_MUTE, 0);
846
  SEQ_LED_PinSet(LED_PATTERN, 0);
847
  SEQ_LED_PinSet(LED_SONG, 0);
848
 
849
  SEQ_LED_PinSet(LED_SOLO, 0);
850
  SEQ_LED_PinSet(LED_FAST, 0);
851
  SEQ_LED_PinSet(LED_ALL, 0);
852
 
166 tk 853
  SEQ_LED_PinSet(LED_PLAY, seq_core_state.RUN);
854
  SEQ_LED_PinSet(LED_STOP, !seq_core_state.RUN);
855
  SEQ_LED_PinSet(LED_PAUSE, seq_core_state.PAUSE);
134 tk 856
 
167 tk 857
  SEQ_LED_PinSet(LED_STEP_1_16, (ui_selected_step_view == 0));
858
  SEQ_LED_PinSet(LED_STEP_17_32, (ui_selected_step_view == 1)); // will be obsolete in MBSEQ V4
134 tk 859
 
167 tk 860
  SEQ_LED_PinSet(LED_MENU, seq_ui_button_state.MENU_PRESSED);
861
  SEQ_LED_PinSet(LED_SCRUB, 0);
862
  SEQ_LED_PinSet(LED_METRONOME, 0);
134 tk 863
 
167 tk 864
  // note: the background function is permanently interrupted - therefore we write the GP pattern
865
  // into a temporary variable, and take it over once completed
866
  u16 new_ui_gp_leds = 0x0000;
867
  u16 new_ui_gp_leds_flashing = 0x0000;  
868
  if( seq_ui_button_state.MENU_PRESSED ) {
869
    // MENU button overruling - find out the selected menu (if accessible via MENU button)
870
    int i;
871
    for(i=0; i<16; ++i)
872
      if(ui_page == ui_direct_access_menu_pages[i])
873
    new_ui_gp_leds |= (1 << i);
874
  } else {
875
    // request GP LED values from current menu page
876
    // will be transfered to DOUT registers in SEQ_UI_LED_Handler_Periodic
877
    new_ui_gp_leds = 0x0000;
878
    new_ui_gp_leds_flashing = 0x0000;
879
 
880
    if( ui_gp_led_callback != NULL )
881
      ui_gp_led_callback(&new_ui_gp_leds, &new_ui_gp_leds_flashing);
882
  }
883
  ui_gp_leds = new_ui_gp_leds;
884
  ui_gp_leds_flashing = new_ui_gp_leds_flashing;
885
 
134 tk 886
  return 0; // no error
887
}
888
 
889
 
890
/////////////////////////////////////////////////////////////////////////////
891
// updates high-prio LED functions (GP LEDs and Beat LED)
892
// Called before SRIO update
893
/////////////////////////////////////////////////////////////////////////////
894
s32 SEQ_UI_LED_Handler_Periodic()
895
{
896
  // GP LEDs are only updated when ui_gp_leds or pos_marker_mask has changed
897
  static u16 prev_ui_gp_leds = 0x0000;
898
  static u16 prev_pos_marker_mask = 0x0000;
899
 
900
  // beat LED: tmp. for demo w/o real sequencer
167 tk 901
  SEQ_LED_PinSet(LED_BEAT, (seq_core_state.RUN && (seq_core_state.ref_step & 3) == 0));
134 tk 902
 
903
  // for song position marker (supports 16 LEDs, check for selected step view)
904
  u16 pos_marker_mask = 0x0000;
166 tk 905
  u8 played_step = seq_core_trk[SEQ_UI_VisibleTrackGet()].step;
906
  if( seq_core_state.RUN && (played_step >> 4) == ui_selected_step_view )
134 tk 907
    pos_marker_mask = 1 << (played_step & 0xf);
908
 
909
  // exit of pattern hasn't changed
910
  if( prev_ui_gp_leds == ui_gp_leds && prev_pos_marker_mask == pos_marker_mask )
911
    return 0;
912
  prev_ui_gp_leds = ui_gp_leds;
913
  prev_pos_marker_mask = pos_marker_mask;
914
 
915
  // transfer to GP LEDs
916
 
917
#ifdef DEFAULT_GP_DOUT_SR_L
918
# ifdef DEFAULT_GP_DOUT_SR_L2
919
  SEQ_LED_SRSet(DEFAULT_GP_DOUT_SR_L-1, (ui_gp_leds >> 0) & 0xff);
920
# else
921
  SEQ_LED_SRSet(DEFAULT_GP_DOUT_SR_L-1, ((ui_gp_leds ^ pos_marker_mask) >> 0) & 0xff);
922
# endif
923
#endif
924
#ifdef DEFAULT_GP_DOUT_SR_R
925
# ifdef DEFAULT_GP_DOUT_SR_R2
926
  SEQ_LED_SRSet(DEFAULT_GP_DOUT_SR_R-1, (ui_gp_leds >> 8) & 0xff);
927
#else
928
  SEQ_LED_SRSet(DEFAULT_GP_DOUT_SR_R-1, ((ui_gp_leds ^ pos_marker_mask) >> 8) & 0xff);
929
#endif
930
#endif
931
 
932
#ifdef DEFAULT_GP_DOUT_SR_L2
933
  SEQ_LED_SRSet(DEFAULT_GP_DOUT_SR_L2-1, (pos_marker_mask >> 0) & 0xff);
934
#endif
935
#ifdef DEFAULT_GP_DOUT_SR_R2
936
  SEQ_LED_SRSet(DEFAULT_GP_DOUT_SR_R2-1, (pos_marker_mask >> 8) & 0xff);
937
#endif
938
 
939
#if DEFAULT_SRM_ENABLED && DEFAULT_SRM_DOUT_M_MAPPING == 1
940
  // for wilba's frontpanel
941
 
942
  // BLM8X8 DOUT -> GP LED mapping
943
  // 0 = 15,16  1 = 13,14   2 = 11,12   3 = 9,10
944
  // 4 = 1,2    5 = 3,4     6 = 5,6     7 = 7,8
945
 
946
  // bit 7: first green (i.e. GP1-G)
947
  // bit 6: first red (i.e. GP1-R)
948
  // bit 5: second green (i.e. GP2-G)
949
  // bit 4: second red (i.e. GP2-R)
950
 
951
  // this mapping routine takes ca. 5 uS
952
  // since it's only executed when ui_gp_leds or gp_mask has changed, it doesn't really hurt
953
 
954
  u16 modified_gp_leds = ui_gp_leds;
955
#if 1
956
  // extra: red LED is lit exclusively for higher contrast
957
  modified_gp_leds &= ~pos_marker_mask;
958
#endif
959
 
960
  int sr;
961
  const u8 blm8x8_sr_map[8] = {4, 5, 6, 7, 3, 2, 1, 0};
962
  u16 gp_mask = 1 << 0;
963
  for(sr=0; sr<8; ++sr) {
964
    u8 pattern = 0;
965
 
966
    if( modified_gp_leds & gp_mask )
967
      pattern |= 0x80;
968
    if( pos_marker_mask & gp_mask )
969
      pattern |= 0x40;
970
    gp_mask <<= 1;
971
    if( modified_gp_leds & gp_mask )
972
      pattern |= 0x20;
973
    if( pos_marker_mask & gp_mask )
974
      pattern |= 0x10;
975
    gp_mask <<= 1;
976
 
977
    u8 mapped_sr = blm8x8_sr_map[sr];
978
    blm8x8_led_row[mapped_sr] = (blm8x8_led_row[mapped_sr] & 0x0f) | pattern;
979
  }
980
#endif
981
 
982
}
983
 
984
 
985
/////////////////////////////////////////////////////////////////////////////
986
// Returns the currently visible track
987
/////////////////////////////////////////////////////////////////////////////
988
u8 SEQ_UI_VisibleTrackGet(void)
989
{
990
  u8 offset = 0;
991
 
992
  if( ui_selected_tracks & (1 << 3) )
993
    offset = 3;
994
  if( ui_selected_tracks & (1 << 2) )
995
    offset = 2;
996
  if( ui_selected_tracks & (1 << 1) )
997
    offset = 1;
998
  if( ui_selected_tracks & (1 << 0) )
999
    offset = 0;
1000
 
1001
  return 4*ui_selected_group + offset;
1002
}
1003