Subversion Repositories svn.mios32

Rev

Rev 1914 | Rev 1920 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1298 tk 1
// $Id: app.cpp 1919 2014-01-08 19:13:48Z tk $
2
/*
3
 * MIDIbox CV V2
4
 *
5
 * ==========================================================================
6
 *
7
 *  Copyright (C) 2011 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 <aout.h>
1887 tk 20
#include <glcd_font.h>
1334 tk 21
#include "tasks.h"
1298 tk 22
#include "app.h"
1334 tk 23
#include "MbCvEnvironment.h"
1298 tk 24
 
1334 tk 25
#include <file.h>
26
 
27
// include source of the SCS
28
#include <scs.h>
1887 tk 29
#include <scs_lcd.h>
1334 tk 30
#include "scs_config.h"
31
 
1492 tk 32
#include <midi_port.h>
33
#include <midi_router.h>
34
#include <midimon.h>
35
 
1895 tk 36
#include <app_lcd.h>
37
 
38
#include "terminal.h"
1912 tk 39
#include "mbcv_hwcfg.h"
1298 tk 40
#include "mbcv_sysex.h"
41
#include "mbcv_patch.h"
1299 tk 42
#include "mbcv_map.h"
1912 tk 43
#include "mbcv_button.h"
1901 tk 44
#include "mbcv_lre.h"
1298 tk 45
#include "mbcv_file.h"
46
#include "mbcv_file_p.h"
1453 tk 47
#include "mbcv_file_b.h"
1912 tk 48
#include "mbcv_file_hw.h"
1298 tk 49
#include "uip_task.h"
50
#include "osc_client.h"
51
 
1895 tk 52
 
1298 tk 53
/////////////////////////////////////////////////////////////////////////////
1334 tk 54
// for optional debugging messages via DEBUG_MSG (defined in mios32_config.h)
55
// should be at least 1 for sending error messages
1298 tk 56
/////////////////////////////////////////////////////////////////////////////
1334 tk 57
#define DEBUG_VERBOSE_LEVEL 2
1298 tk 58
 
1334 tk 59
// measure performance with the stopwatch
1903 tk 60
// 0: off
61
// 1: CV processing only
62
// 2: CV processing + mapping
1394 tk 63
//#define STOPWATCH_PERFORMANCE_MEASURING 2
1817 tk 64
#define STOPWATCH_PERFORMANCE_MEASURING 0
1298 tk 65
 
1903 tk 66
// output execution times at J5B:A4..A7
67
// 0: off
68
// 1: on -> J5.A4: CV processing (low-active)
69
//          J5.A5: CV processing + mapping (low-active)
70
//          J5.A6: Scope output (low-active)
1298 tk 71
 
1903 tk 72
#define J5_DEBUG_PINS 1
73
 
74
 
1298 tk 75
/////////////////////////////////////////////////////////////////////////////
76
// local variables
77
/////////////////////////////////////////////////////////////////////////////
1334 tk 78
static u32 stopwatch_value;
1903 tk 79
static u32 stopwatch_value_min;
1334 tk 80
static u32 stopwatch_value_max;
81
static u32 stopwatch_value_accumulated;
1903 tk 82
static u32 stopwatch_value_accumulated_ctr;
1298 tk 83
 
1914 tk 84
static u8  cv_se_speed_factor;
85
static u8  cv_se_overloaded;
86
static u32 cv_se_overload_check_ctr = 0;
87
static u32 cv_se_last_mios32_timestamp = 0;
1298 tk 88
 
1914 tk 89
 
1334 tk 90
/////////////////////////////////////////////////////////////////////////////
91
// C++ objects
92
/////////////////////////////////////////////////////////////////////////////
93
MbCvEnvironment mbCvEnvironment;
1298 tk 94
 
95
 
96
/////////////////////////////////////////////////////////////////////////////
97
// Local prototypes
98
/////////////////////////////////////////////////////////////////////////////
1334 tk 99
extern void CV_TIMER_SE_Update(void);
1298 tk 100
static s32 NOTIFY_MIDI_Rx(mios32_midi_port_t port, u8 byte);
1299 tk 101
static s32 NOTIFY_MIDI_Tx(mios32_midi_port_t port, mios32_midi_package_t package);
102
static s32 NOTIFY_MIDI_TimeOut(mios32_midi_port_t port);
1298 tk 103
 
104
 
105
/////////////////////////////////////////////////////////////////////////////
1334 tk 106
// returns pointer to MbCv objects
107
/////////////////////////////////////////////////////////////////////////////
108
MbCvEnvironment *APP_GetEnv()
109
{
110
  return &mbCvEnvironment;
111
}
112
 
113
 
114
/////////////////////////////////////////////////////////////////////////////
1298 tk 115
// This hook is called after startup to initialize the application
116
/////////////////////////////////////////////////////////////////////////////
1334 tk 117
extern "C" void APP_Init(void)
1298 tk 118
{
119
  // initialize all LEDs
120
  MIOS32_BOARD_LED_Init(0xffffffff);
121
 
1912 tk 122
  // init hardware config
123
  MBCV_HWCFG_Init(0);
1298 tk 124
 
1334 tk 125
  // init Stopwatch
126
  APP_StopwatchInit();
127
 
1903 tk 128
#if J5_DEBUG_PINS
129
  // initialize debug pins J5B:A4..A7
130
  {
131
    int i;
132
    for(int i=4; i<7; ++i) {
133
      MIOS32_BOARD_J5_PinInit(i, MIOS32_BOARD_PIN_MODE_OUTPUT_PP);
134
      MIOS32_BOARD_J5_PinSet(i, 1);
135
    }
136
  }
137
#endif
138
 
1298 tk 139
  // initialize all J10 pins as inputs with internal Pull-Up
140
  int pin;
141
  for(pin=0; pin<8; ++pin)
142
    MIOS32_BOARD_J10_PinInit(pin, MIOS32_BOARD_PIN_MODE_INPUT_PU);
143
 
1895 tk 144
  // initialize OLED pins at J5
145
  {
146
    APP_SelectScopeLCDs();
1298 tk 147
 
1895 tk 148
    APP_LCD_Init(0);
149
 
150
    int lcd;
151
    for(lcd=0; lcd<4; ++lcd) {
152
      MIOS32_LCD_DeviceSet(lcd);
153
      MIOS32_LCD_Clear();
154
    }
155
 
156
    APP_SelectMainLCD();
157
  }
158
 
1298 tk 159
  // install SysEx callback
160
  MIOS32_MIDI_SysExCallback_Init(APP_SYSEX_Parser);
161
 
1299 tk 162
  // install MIDI Rx/Tx callback functions
163
  MIOS32_MIDI_DirectRxCallback_Init(&NOTIFY_MIDI_Rx);
164
  MIOS32_MIDI_DirectTxCallback_Init(&NOTIFY_MIDI_Tx);
1298 tk 165
 
1299 tk 166
  // install timeout callback function
167
  MIOS32_MIDI_TimeOutCallback_Init(&NOTIFY_MIDI_TimeOut);
1298 tk 168
 
169
  // initialize AOUT module
170
  AOUT_Init(0);
171
 
172
  // configure interface (will be changed again once config file has been loaded from SD Card, or via SCS)
173
  aout_config_t config;
174
  config = AOUT_ConfigGet();
175
  config.if_type = AOUT_IF_MAX525;
176
  config.if_option = 0;
177
  config.num_channels = 8;
178
  config.chn_inverted = 0;
179
  AOUT_ConfigSet(config);
180
  AOUT_IF_Init(0);
181
 
1299 tk 182
  // initialize code modules
1492 tk 183
  MIDI_PORT_Init(0);
1299 tk 184
  MBCV_SYSEX_Init(0);
185
  MBCV_MAP_Init(0);
1492 tk 186
  MIDI_ROUTER_Init(0);
1299 tk 187
  MBCV_PATCH_Init(0);
1912 tk 188
  MBCV_BUTTON_Init(0);
1901 tk 189
  MBCV_LRE_Init(0);
1299 tk 190
  UIP_TASK_Init(0);
1887 tk 191
 
1299 tk 192
  SCS_Init(0);
193
  SCS_CONFIG_Init(0);
1887 tk 194
 
195
  if( mios32_lcd_parameters.lcd_type == MIOS32_LCD_TYPE_GLCD_SSD1306 )
196
    SCS_LCD_OffsetYSet(6);
197
 
1299 tk 198
  TERMINAL_Init(0);
199
  MIDIMON_Init(0);
200
  MBCV_FILE_Init(0);
201
 
1334 tk 202
  // initialize tasks
203
  TASKS_Init(0);
204
 
1914 tk 205
  // initialize MbCvEnvironment
206
  APP_CvUpdateRateFactorSet(5);
1901 tk 207
 
208
#if MIOS32_DONT_SERVICE_SRIO_SCAN
209
  //MIOS32_SRIO_ScanNumSet(4);
210
 
211
  // standard SRIO scan has been disabled in programming_models/traditional/main.c via MIOS32_DONT_SERVICE_SRIO_SCAN in mios32_config.h
212
  // start the scan here - and retrigger it whenever it's finished
213
  APP_SRIO_ServicePrepare();
214
  MIOS32_SRIO_ScanStart(APP_SRIO_ServiceFinish);
215
#endif
1298 tk 216
}
217
 
218
 
219
/////////////////////////////////////////////////////////////////////////////
220
// This task is running endless in background
221
/////////////////////////////////////////////////////////////////////////////
1334 tk 222
extern "C" void APP_Background(void)
1298 tk 223
{
224
}
225
 
226
 
227
/////////////////////////////////////////////////////////////////////////////
1919 tk 228
// This hook is called each mS from the main task which also handles DIN, ENC
229
// and AIN events. You could add more jobs here, but they shouldn't consume
230
// more than 300 uS to ensure the responsiveness of buttons, encoders, pots.
231
// Alternatively you could create a dedicated task for application specific
232
// jobs as explained in $MIOS32_PATH/apps/tutorials/006_rtos_tasks
233
/////////////////////////////////////////////////////////////////////////////
234
extern "C" void APP_Tick(void)
235
{
236
  // toggle the status LED (this is a sign of life)
237
  MIOS32_BOARD_LED_Set(0x0001, ~MIOS32_BOARD_LED_Get());
238
}
239
 
240
 
241
/////////////////////////////////////////////////////////////////////////////
242
// This hook is called each mS from the MIDI task which checks for incoming
243
// MIDI events. You could add more MIDI related jobs here, but they shouldn't
244
// consume more than 300 uS to ensure the responsiveness of incoming MIDI.
245
/////////////////////////////////////////////////////////////////////////////
246
extern "C" void APP_MIDI_Tick(void)
247
{
248
}
249
 
250
 
251
/////////////////////////////////////////////////////////////////////////////
1298 tk 252
// This hook is called when a MIDI package has been received
253
/////////////////////////////////////////////////////////////////////////////
1334 tk 254
extern "C" void APP_MIDI_NotifyPackage(mios32_midi_port_t port, mios32_midi_package_t midi_package)
1298 tk 255
{
1299 tk 256
  // -> CV MIDI handler
1334 tk 257
  mbCvEnvironment.midiReceive(port, midi_package);
1299 tk 258
 
1298 tk 259
  // -> MIDI Router
1492 tk 260
  MIDI_ROUTER_Receive(port, midi_package);
1298 tk 261
 
1299 tk 262
  // -> MIDI Port Handler (used for MIDI monitor function)
1492 tk 263
  MIDI_PORT_NotifyMIDIRx(port, midi_package);
1299 tk 264
 
1298 tk 265
  // forward to MIDI Monitor
266
  // SysEx messages have to be filtered for USB0 and UART0 to avoid data corruption
267
  // (the SysEx stream would interfere with monitor messages)
268
  u8 filter_sysex_message = (port == USB0) || (port == UART0);
1911 tk 269
  MIDIMON_Receive(port, midi_package, filter_sysex_message);
1298 tk 270
}
271
 
272
/////////////////////////////////////////////////////////////////////////////
273
// This function parses an incoming sysex stream for MIOS32 commands
274
/////////////////////////////////////////////////////////////////////////////
1334 tk 275
extern "C" s32 APP_SYSEX_Parser(mios32_midi_port_t port, u8 midi_in)
1298 tk 276
{
277
  // -> MBCV
278
  MBCV_SYSEX_Parser(port, midi_in);
279
 
280
  // -> MIDI Router
1492 tk 281
  MIDI_ROUTER_ReceiveSysEx(port, midi_in);
1298 tk 282
 
283
  return 0; // no error
284
}
285
 
286
/////////////////////////////////////////////////////////////////////////////
287
// This hook is called before the shift register chain is scanned
288
/////////////////////////////////////////////////////////////////////////////
1334 tk 289
extern "C" void APP_SRIO_ServicePrepare(void)
1298 tk 290
{
291
  // pass current pin state of J10
292
  // only available for LPC17xx, all others (like STM32) default to SRIO
293
  SCS_AllPinsSet(0xff00 | MIOS32_BOARD_J10_Get());
294
 
295
  // update encoders/buttons of SCS
296
  SCS_EncButtonUpdate_Tick();
297
}
298
 
299
 
300
/////////////////////////////////////////////////////////////////////////////
301
// This hook is called after the shift register chain has been scanned
302
/////////////////////////////////////////////////////////////////////////////
1334 tk 303
extern "C" void APP_SRIO_ServiceFinish(void)
1298 tk 304
{
1901 tk 305
#if MIOS32_DONT_SERVICE_SRIO_SCAN
306
  // update encoder states
307
  MIOS32_ENC_UpdateStates();
308
 
309
  // standard SRIO scan has been disabled in programming_models/traditional/main.c via MIOS32_DONT_SERVICE_SRIO_SCAN in mios32_config.h
310
  // start the scan here - and retrigger it whenever it's finished
311
  APP_SRIO_ServicePrepare();
312
  MIOS32_SRIO_ScanStart(APP_SRIO_ServiceFinish);
313
#endif
1298 tk 314
}
315
 
316
 
317
/////////////////////////////////////////////////////////////////////////////
318
// This hook is called when a button has been toggled
319
// pin_value is 1 when button released, and 0 when button pressed
320
/////////////////////////////////////////////////////////////////////////////
1334 tk 321
extern "C" void APP_DIN_NotifyToggle(u32 pin, u32 pin_value)
1298 tk 322
{
1912 tk 323
  // -> MBCV Button handler
324
  MBCV_BUTTON_Handler(pin, pin_value);
1298 tk 325
}
326
 
327
 
328
/////////////////////////////////////////////////////////////////////////////
329
// This hook is called when an encoder has been moved
330
// incrementer is positive when encoder has been turned clockwise, else
331
// it is negative
332
/////////////////////////////////////////////////////////////////////////////
1334 tk 333
extern "C" void APP_ENC_NotifyChange(u32 encoder, s32 incrementer)
1298 tk 334
{
335
  // pass encoder event to SCS handler
1901 tk 336
  if( encoder == SCS_ENC_MENU_ID ) // == 0 (assigned by SCS)
1298 tk 337
    SCS_ENC_MENU_NotifyChange(incrementer);
1901 tk 338
  else {
339
    // -> ENC Handler
1905 tk 340
    MBCV_LRE_NotifyChange(encoder-1, incrementer);
1901 tk 341
  }
1298 tk 342
}
343
 
344
 
345
/////////////////////////////////////////////////////////////////////////////
346
// This hook is called when a pot has been moved
347
/////////////////////////////////////////////////////////////////////////////
1334 tk 348
extern "C" void APP_AIN_NotifyChange(u32 pin, u32 pin_value)
1298 tk 349
{
350
}
351
 
352
 
353
 
1334 tk 354
/////////////////////////////////////////////////////////////////////////////
355
// This timer interrupt periodically calls the sound engine update
356
/////////////////////////////////////////////////////////////////////////////
357
extern void CV_TIMER_SE_Update(void)
358
{
1912 tk 359
  // ignore as long as hardware config hasn't been read
1914 tk 360
  if( !MBCV_FILE_HW_ConfigLocked() ) {
361
    cv_se_last_mios32_timestamp = MIOS32_TIMESTAMP_Get();
362
    return;
363
  }
1298 tk 364
 
1914 tk 365
  // check MIOS32 timestamp each second
366
  if( ++cv_se_overload_check_ctr >= (cv_se_speed_factor*500) ) {
367
    u32 timestamp = MIOS32_TIMESTAMP_Get();
368
    u32 delay = timestamp - cv_se_last_mios32_timestamp;
369
    cv_se_overload_check_ctr = 0;
370
    cv_se_last_mios32_timestamp = timestamp;
371
 
372
    // actually 1000, allow some margin
373
    cv_se_overloaded = (delay < 950 );
374
  }
375
 
376
  // don't process CV if engine overloaded
377
  if( cv_se_overloaded )
378
    return;
379
 
1903 tk 380
#if J5_DEBUG_PINS
1914 tk 381
  MIOS32_BOARD_J5_PinSet(4, 0);
382
  MIOS32_BOARD_J5_PinSet(5, 0);
1903 tk 383
#endif
384
 
385
#if STOPWATCH_PERFORMANCE_MEASURING == 1 || STOPWATCH_PERFORMANCE_MEASURING == 2
1334 tk 386
  APP_StopwatchReset();
387
#endif
388
 
1903 tk 389
  if( !mbCvEnvironment.tick() ) {
390
#if J5_DEBUG_PINS
391
    MIOS32_BOARD_J5_PinSet(4, 1);
392
    MIOS32_BOARD_J5_PinSet(5, 1);
393
#endif
1334 tk 394
    return; // no update required
1903 tk 395
  }
1334 tk 396
 
397
#if STOPWATCH_PERFORMANCE_MEASURING == 1
398
  APP_StopwatchCapture();
399
#endif
1903 tk 400
#if J5_DEBUG_PINS
401
    MIOS32_BOARD_J5_PinSet(4, 1);
402
#endif
1334 tk 403
 
404
  // update AOUTs
405
  MBCV_MAP_Update();
406
 
407
#if STOPWATCH_PERFORMANCE_MEASURING == 2
408
  APP_StopwatchCapture();
409
#endif
1903 tk 410
#if J5_DEBUG_PINS
411
    MIOS32_BOARD_J5_PinSet(5, 1);
412
#endif
1334 tk 413
}
414
 
415
 
416
 
417
 
1298 tk 418
/////////////////////////////////////////////////////////////////////////////
419
// This task handles the control surface
420
/////////////////////////////////////////////////////////////////////////////
1334 tk 421
void APP_TASK_Period_1mS_LP(void)
1298 tk 422
{
1887 tk 423
  static u8 clear_lcd = 1;
1911 tk 424
  static u32 performance_print_timestamp = 0;
1298 tk 425
 
1905 tk 426
  MUTEX_LCD_TAKE;
427
 
1887 tk 428
  if( clear_lcd ) {
429
    clear_lcd = 0;
1911 tk 430
    MIOS32_LCD_Clear();
1887 tk 431
  }
432
 
1334 tk 433
  // call SCS handler
434
  SCS_Tick();
1298 tk 435
 
1905 tk 436
  MUTEX_LCD_GIVE;
1885 tk 437
 
1334 tk 438
  // MIDI In/Out monitor
1492 tk 439
  MIDI_PORT_Period1mS();
1298 tk 440
 
1905 tk 441
  // LED rings
442
  MBCV_LRE_UpdateAllLedRings();
443
 
1334 tk 444
  // output and reset current stopwatch max value each second
1911 tk 445
  if( MIOS32_TIMESTAMP_GetDelay(performance_print_timestamp) > 1000 ) {
446
    performance_print_timestamp = MIOS32_TIMESTAMP_Get();
1334 tk 447
 
448
    MUTEX_MIDIOUT_TAKE;
449
    MIOS32_IRQ_Disable();
1903 tk 450
    u32 min_value = stopwatch_value_min;
451
    stopwatch_value_min = ~0;
1334 tk 452
    u32 max_value = stopwatch_value_max;
453
    stopwatch_value_max = 0;
454
    u32 acc_value = stopwatch_value_accumulated;
455
    stopwatch_value_accumulated = 0;
1903 tk 456
    u32 acc_ctr = stopwatch_value_accumulated_ctr;
457
    stopwatch_value_accumulated_ctr = 0;
1334 tk 458
    MIOS32_IRQ_Enable();
459
#if DEBUG_VERBOSE_LEVEL >= 2
460
    if( acc_value || max_value )
1903 tk 461
      DEBUG_MSG("%d uS (min: %d uS, max: %d uS)\n", acc_value / acc_ctr, min_value, max_value);
1334 tk 462
#endif
463
    MUTEX_MIDIOUT_GIVE;
1298 tk 464
  }
465
 
466
}
467
 
468
 
469
/////////////////////////////////////////////////////////////////////////////
1905 tk 470
// This task handles the scope displays with very low priority
471
/////////////////////////////////////////////////////////////////////////////
472
void APP_TASK_Period_1mS_LP2(void)
473
{
474
  {
475
#if J5_DEBUG_PINS
476
    MIOS32_BOARD_J5_PinSet(6, 0);
477
#endif
478
    // CV Scopes (note: mutex is taken inside function)
479
    mbCvEnvironment.tickScopes();
480
#if J5_DEBUG_PINS
481
    MIOS32_BOARD_J5_PinSet(6, 1);
482
#endif
483
  }
484
 
485
  // CV Bars (currently only for SSD1306)
486
  {
487
    MUTEX_LCD_TAKE;
488
 
489
    if( mios32_lcd_parameters.lcd_type == MIOS32_LCD_TYPE_GLCD_SSD1306 ) {
490
 
491
      MIOS32_LCD_DeviceSet(0);
492
      MIOS32_LCD_FontInit((u8 *)GLCD_FONT_METER_ICONS_V); // memo: 28 icons, 14 used, icon size: 8x32
493
 
494
      u16 *outMeter = mbCvEnvironment.cvOutMeter.first();
495
      for(int cv=0; cv<CV_SE_NUM; ++cv, ++outMeter) {
496
    MIOS32_LCD_CursorSet(0 + 2*cv, 4);
497
    MIOS32_LCD_PrintChar((*outMeter * 13) / 65535);
498
      }
499
 
500
      MIOS32_LCD_FontInit((u8 *)GLCD_FONT_NORMAL);    
501
    }
502
 
503
    MUTEX_LCD_GIVE;
504
  }
505
}
506
 
507
 
508
/////////////////////////////////////////////////////////////////////////////
1298 tk 509
// This task handles the SD Card
510
/////////////////////////////////////////////////////////////////////////////
1334 tk 511
void APP_TASK_Period_1mS_SD(void)
1298 tk 512
{
1334 tk 513
  static u16 sdcard_check_ctr = 0;
1298 tk 514
 
1334 tk 515
  // each second: check if SD Card (still) available
516
  if( ++sdcard_check_ctr >= 1000 ) {
517
    sdcard_check_ctr = 0;
1298 tk 518
 
1334 tk 519
    MUTEX_SDCARD_TAKE;
520
    s32 status = FILE_CheckSDCard();
1298 tk 521
 
1334 tk 522
    if( status == 1 ) {
523
      DEBUG_MSG("SD Card connected: %s\n", FILE_VolumeLabel());
524
      // load all file infos
525
      MBCV_FILE_LoadAllFiles(1); // including HW info
526
    } else if( status == 2 ) {
527
      DEBUG_MSG("SD Card disconnected\n");
528
      // invalidate all file infos
529
      MBCV_FILE_UnloadAllFiles();
1298 tk 530
 
1334 tk 531
      // change status
532
      MBCV_FILE_StatusMsgSet("No SD Card");
533
    } else if( status == 3 ) {
534
      if( !FILE_SDCardAvailable() ) {
535
    DEBUG_MSG("SD Card not found\n");
1912 tk 536
    MBCV_FILE_HW_LockConfig(); // lock configuration
1298 tk 537
    MBCV_FILE_StatusMsgSet("No SD Card");
1334 tk 538
      } else if( !FILE_VolumeAvailable() ) {
539
    DEBUG_MSG("ERROR: SD Card contains invalid FAT!\n");
1912 tk 540
    MBCV_FILE_HW_LockConfig(); // lock configuration
1334 tk 541
    MBCV_FILE_StatusMsgSet("No FAT");
542
      } else {
1653 tk 543
    // create the default files if they don't exist on SD Card
544
    MBCV_FILE_CreateDefaultFiles();
1298 tk 545
 
1334 tk 546
    // disable status message and print patch
547
    MBCV_FILE_StatusMsgSet(NULL);
1298 tk 548
      }
549
    }
1334 tk 550
 
551
    MUTEX_SDCARD_GIVE;
1298 tk 552
  }
553
}
554
 
555
 
556
/////////////////////////////////////////////////////////////////////////////
1452 tk 557
// This task is called periodically each mS
1298 tk 558
/////////////////////////////////////////////////////////////////////////////
1334 tk 559
void APP_TASK_Period_1mS(void)
1298 tk 560
{
1452 tk 561
  // e.g. for synched pattern changes
562
  mbCvEnvironment.tick_1mS();
1298 tk 563
}
564
 
565
 
566
/////////////////////////////////////////////////////////////////////////////
567
// Installed via MIOS32_MIDI_DirectRxCallback_Init
568
/////////////////////////////////////////////////////////////////////////////
569
static s32 NOTIFY_MIDI_Rx(mios32_midi_port_t port, u8 midi_byte)
570
{
1299 tk 571
  // filter MIDI In port which controls the MIDI clock
1895 tk 572
  if( MIDI_ROUTER_MIDIClockInGet(port) == 1 ) {
1408 tk 573
    if( midi_byte >= 0xf8 ) {
574
      mbCvEnvironment.midiReceiveRealTimeEvent(port, midi_byte);
575
    }
576
  }
577
 
1298 tk 578
  return 0; // no error, no filtering
579
}
580
 
1299 tk 581
/////////////////////////////////////////////////////////////////////////////
582
// Installed via MIOS32_MIDI_DirectTxCallback_Init
583
/////////////////////////////////////////////////////////////////////////////
584
static s32 NOTIFY_MIDI_Tx(mios32_midi_port_t port, mios32_midi_package_t package)
585
{
1492 tk 586
  return MIDI_PORT_NotifyMIDITx(port, package);
1299 tk 587
}
1298 tk 588
 
589
/////////////////////////////////////////////////////////////////////////////
1299 tk 590
// Installed via MIOS32_MIDI_TimeoutCallback_Init
591
/////////////////////////////////////////////////////////////////////////////
592
static s32 NOTIFY_MIDI_TimeOut(mios32_midi_port_t port)
593
{  
594
  // forward to SysEx parser
595
  MBCV_SYSEX_TimeOut(port);
596
 
597
  // print message on screen
598
  SCS_Msg(SCS_MSG_L, 2000, "MIDI Protocol", "TIMEOUT !!!");
599
 
600
  return 0;
601
}
602
 
603
 
604
/////////////////////////////////////////////////////////////////////////////
1895 tk 605
// Switches to the scope LCDs
606
/////////////////////////////////////////////////////////////////////////////
1905 tk 607
s32 APP_SelectScopeLCDs(void)
1895 tk 608
{
609
  // select the alternative pinning via J5A/J28
610
  APP_LCD_AltPinningSet(1);
611
 
612
  // select GLCD type and dimensions
613
  mios32_lcd_parameters.lcd_type = MIOS32_LCD_TYPE_GLCD_SSD1306; // TODO: get this from a configuration file
614
  mios32_lcd_parameters.num_x = 4;
615
  mios32_lcd_parameters.num_y = 1;
616
  mios32_lcd_parameters.width = 128;
617
  mios32_lcd_parameters.height = 64;
618
 
619
  return 0; // no error
620
}
621
 
622
/////////////////////////////////////////////////////////////////////////////
623
// Switches to the original LCD
624
/////////////////////////////////////////////////////////////////////////////
1905 tk 625
s32 APP_SelectMainLCD(void)
1895 tk 626
{
627
  // ensure that first LCD is selected
628
  MIOS32_LCD_DeviceSet(0);
629
 
630
  // select the original pinning
631
  APP_LCD_AltPinningSet(0);
632
 
633
  // retrieve original LCD parameters
634
  MIOS32_LCD_ParametersFetchFromBslInfoRange();
635
 
636
  return 0; // no error
637
}
638
 
639
 
640
/////////////////////////////////////////////////////////////////////////////
1914 tk 641
// Speed Factor (engine will be updated at factor * 500 Hz)
642
/////////////////////////////////////////////////////////////////////////////
643
s32 APP_CvUpdateRateFactorSet(u8 factor)
644
{
645
  if( factor < 1 || factor > APP_CV_UPDATE_RATE_FACTOR_MAX )
646
    return -1; // invalid factor
647
 
648
  MIOS32_IRQ_Disable();
649
 
650
  cv_se_speed_factor = factor;
651
  mbCvEnvironment.updateSpeedFactorSet(cv_se_speed_factor);
652
 
653
  // start timer
654
  MIOS32_TIMER_Init(2, 2000 / cv_se_speed_factor, CV_TIMER_SE_Update, MIOS32_IRQ_PRIO_MID);
655
 
656
  // clear overload indicators
657
  cv_se_overloaded = 0;
658
  cv_se_overload_check_ctr = 0;
659
  cv_se_last_mios32_timestamp = MIOS32_TIMESTAMP_Get();
660
 
661
  MIOS32_IRQ_Enable();
662
 
663
  return 0; // no error
664
}
665
 
666
s32 APP_CvUpdateRateFactorGet(void)
667
{
668
  return cv_se_speed_factor;
669
}
670
 
671
/////////////////////////////////////////////////////////////////////////////
672
// Returns 1 if engine overloaded
673
/////////////////////////////////////////////////////////////////////////////
674
s32 APP_CvUpdateOverloadStatusGet(void)
675
{
676
  return cv_se_overloaded;
677
}
678
 
679
 
680
/////////////////////////////////////////////////////////////////////////////
1334 tk 681
// For performance Measurements
1298 tk 682
/////////////////////////////////////////////////////////////////////////////
1334 tk 683
s32 APP_StopwatchInit(void)
1298 tk 684
{
1334 tk 685
  stopwatch_value = 0;
1903 tk 686
  stopwatch_value_min = ~0;
1334 tk 687
  stopwatch_value_max = 0;
688
  stopwatch_value_accumulated = 0;
1903 tk 689
  stopwatch_value_accumulated_ctr = 0;
1334 tk 690
  return MIOS32_STOPWATCH_Init(1); // 1 uS resolution
1298 tk 691
}
692
 
1334 tk 693
s32 APP_StopwatchReset(void)
1298 tk 694
{
1334 tk 695
  return MIOS32_STOPWATCH_Reset();
1298 tk 696
}
697
 
1334 tk 698
s32 APP_StopwatchCapture(void)
1298 tk 699
{
1334 tk 700
  u32 value = MIOS32_STOPWATCH_ValueGet();
701
  MIOS32_IRQ_Disable();
702
  stopwatch_value = value;
1903 tk 703
  if( value < stopwatch_value_min )
704
    stopwatch_value_min = value;
1334 tk 705
  if( value > stopwatch_value_max )
706
    stopwatch_value_max = value;
707
  stopwatch_value_accumulated += value;
1903 tk 708
  ++stopwatch_value_accumulated_ctr;
1334 tk 709
  MIOS32_IRQ_Enable();
1298 tk 710
 
711
  return 0; // no error
712
}
1895 tk 713