Subversion Repositories svn.mios32

Rev

Rev 1919 | Rev 1937 | 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 1920 2014-01-08 19:29:35Z 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
{
1920 tk 236
  // PWM modulate the status LED (this is a sign of life)
237
  u32 timestamp = MIOS32_TIMESTAMP_Get();
238
  MIOS32_BOARD_LED_Set(1, (timestamp % 20) <= ((timestamp / 100) % 10));
1919 tk 239
}
240
 
241
 
242
/////////////////////////////////////////////////////////////////////////////
243
// This hook is called each mS from the MIDI task which checks for incoming
244
// MIDI events. You could add more MIDI related jobs here, but they shouldn't
245
// consume more than 300 uS to ensure the responsiveness of incoming MIDI.
246
/////////////////////////////////////////////////////////////////////////////
247
extern "C" void APP_MIDI_Tick(void)
248
{
249
}
250
 
251
 
252
/////////////////////////////////////////////////////////////////////////////
1298 tk 253
// This hook is called when a MIDI package has been received
254
/////////////////////////////////////////////////////////////////////////////
1334 tk 255
extern "C" void APP_MIDI_NotifyPackage(mios32_midi_port_t port, mios32_midi_package_t midi_package)
1298 tk 256
{
1299 tk 257
  // -> CV MIDI handler
1334 tk 258
  mbCvEnvironment.midiReceive(port, midi_package);
1299 tk 259
 
1298 tk 260
  // -> MIDI Router
1492 tk 261
  MIDI_ROUTER_Receive(port, midi_package);
1298 tk 262
 
1299 tk 263
  // -> MIDI Port Handler (used for MIDI monitor function)
1492 tk 264
  MIDI_PORT_NotifyMIDIRx(port, midi_package);
1299 tk 265
 
1298 tk 266
  // forward to MIDI Monitor
267
  // SysEx messages have to be filtered for USB0 and UART0 to avoid data corruption
268
  // (the SysEx stream would interfere with monitor messages)
269
  u8 filter_sysex_message = (port == USB0) || (port == UART0);
1911 tk 270
  MIDIMON_Receive(port, midi_package, filter_sysex_message);
1298 tk 271
}
272
 
273
/////////////////////////////////////////////////////////////////////////////
274
// This function parses an incoming sysex stream for MIOS32 commands
275
/////////////////////////////////////////////////////////////////////////////
1334 tk 276
extern "C" s32 APP_SYSEX_Parser(mios32_midi_port_t port, u8 midi_in)
1298 tk 277
{
278
  // -> MBCV
279
  MBCV_SYSEX_Parser(port, midi_in);
280
 
281
  // -> MIDI Router
1492 tk 282
  MIDI_ROUTER_ReceiveSysEx(port, midi_in);
1298 tk 283
 
284
  return 0; // no error
285
}
286
 
287
/////////////////////////////////////////////////////////////////////////////
288
// This hook is called before the shift register chain is scanned
289
/////////////////////////////////////////////////////////////////////////////
1334 tk 290
extern "C" void APP_SRIO_ServicePrepare(void)
1298 tk 291
{
292
  // pass current pin state of J10
293
  // only available for LPC17xx, all others (like STM32) default to SRIO
294
  SCS_AllPinsSet(0xff00 | MIOS32_BOARD_J10_Get());
295
 
296
  // update encoders/buttons of SCS
297
  SCS_EncButtonUpdate_Tick();
298
}
299
 
300
 
301
/////////////////////////////////////////////////////////////////////////////
302
// This hook is called after the shift register chain has been scanned
303
/////////////////////////////////////////////////////////////////////////////
1334 tk 304
extern "C" void APP_SRIO_ServiceFinish(void)
1298 tk 305
{
1901 tk 306
#if MIOS32_DONT_SERVICE_SRIO_SCAN
307
  // update encoder states
308
  MIOS32_ENC_UpdateStates();
309
 
310
  // standard SRIO scan has been disabled in programming_models/traditional/main.c via MIOS32_DONT_SERVICE_SRIO_SCAN in mios32_config.h
311
  // start the scan here - and retrigger it whenever it's finished
312
  APP_SRIO_ServicePrepare();
313
  MIOS32_SRIO_ScanStart(APP_SRIO_ServiceFinish);
314
#endif
1298 tk 315
}
316
 
317
 
318
/////////////////////////////////////////////////////////////////////////////
319
// This hook is called when a button has been toggled
320
// pin_value is 1 when button released, and 0 when button pressed
321
/////////////////////////////////////////////////////////////////////////////
1334 tk 322
extern "C" void APP_DIN_NotifyToggle(u32 pin, u32 pin_value)
1298 tk 323
{
1912 tk 324
  // -> MBCV Button handler
325
  MBCV_BUTTON_Handler(pin, pin_value);
1298 tk 326
}
327
 
328
 
329
/////////////////////////////////////////////////////////////////////////////
330
// This hook is called when an encoder has been moved
331
// incrementer is positive when encoder has been turned clockwise, else
332
// it is negative
333
/////////////////////////////////////////////////////////////////////////////
1334 tk 334
extern "C" void APP_ENC_NotifyChange(u32 encoder, s32 incrementer)
1298 tk 335
{
336
  // pass encoder event to SCS handler
1901 tk 337
  if( encoder == SCS_ENC_MENU_ID ) // == 0 (assigned by SCS)
1298 tk 338
    SCS_ENC_MENU_NotifyChange(incrementer);
1901 tk 339
  else {
340
    // -> ENC Handler
1905 tk 341
    MBCV_LRE_NotifyChange(encoder-1, incrementer);
1901 tk 342
  }
1298 tk 343
}
344
 
345
 
346
/////////////////////////////////////////////////////////////////////////////
347
// This hook is called when a pot has been moved
348
/////////////////////////////////////////////////////////////////////////////
1334 tk 349
extern "C" void APP_AIN_NotifyChange(u32 pin, u32 pin_value)
1298 tk 350
{
351
}
352
 
353
 
354
 
1334 tk 355
/////////////////////////////////////////////////////////////////////////////
356
// This timer interrupt periodically calls the sound engine update
357
/////////////////////////////////////////////////////////////////////////////
358
extern void CV_TIMER_SE_Update(void)
359
{
1912 tk 360
  // ignore as long as hardware config hasn't been read
1914 tk 361
  if( !MBCV_FILE_HW_ConfigLocked() ) {
362
    cv_se_last_mios32_timestamp = MIOS32_TIMESTAMP_Get();
363
    return;
364
  }
1298 tk 365
 
1914 tk 366
  // check MIOS32 timestamp each second
367
  if( ++cv_se_overload_check_ctr >= (cv_se_speed_factor*500) ) {
368
    u32 timestamp = MIOS32_TIMESTAMP_Get();
369
    u32 delay = timestamp - cv_se_last_mios32_timestamp;
370
    cv_se_overload_check_ctr = 0;
371
    cv_se_last_mios32_timestamp = timestamp;
372
 
373
    // actually 1000, allow some margin
374
    cv_se_overloaded = (delay < 950 );
375
  }
376
 
377
  // don't process CV if engine overloaded
378
  if( cv_se_overloaded )
379
    return;
380
 
1903 tk 381
#if J5_DEBUG_PINS
1914 tk 382
  MIOS32_BOARD_J5_PinSet(4, 0);
383
  MIOS32_BOARD_J5_PinSet(5, 0);
1903 tk 384
#endif
385
 
386
#if STOPWATCH_PERFORMANCE_MEASURING == 1 || STOPWATCH_PERFORMANCE_MEASURING == 2
1334 tk 387
  APP_StopwatchReset();
388
#endif
389
 
1903 tk 390
  if( !mbCvEnvironment.tick() ) {
391
#if J5_DEBUG_PINS
392
    MIOS32_BOARD_J5_PinSet(4, 1);
393
    MIOS32_BOARD_J5_PinSet(5, 1);
394
#endif
1334 tk 395
    return; // no update required
1903 tk 396
  }
1334 tk 397
 
398
#if STOPWATCH_PERFORMANCE_MEASURING == 1
399
  APP_StopwatchCapture();
400
#endif
1903 tk 401
#if J5_DEBUG_PINS
402
    MIOS32_BOARD_J5_PinSet(4, 1);
403
#endif
1334 tk 404
 
405
  // update AOUTs
406
  MBCV_MAP_Update();
407
 
408
#if STOPWATCH_PERFORMANCE_MEASURING == 2
409
  APP_StopwatchCapture();
410
#endif
1903 tk 411
#if J5_DEBUG_PINS
412
    MIOS32_BOARD_J5_PinSet(5, 1);
413
#endif
1334 tk 414
}
415
 
416
 
417
 
418
 
1298 tk 419
/////////////////////////////////////////////////////////////////////////////
420
// This task handles the control surface
421
/////////////////////////////////////////////////////////////////////////////
1334 tk 422
void APP_TASK_Period_1mS_LP(void)
1298 tk 423
{
1887 tk 424
  static u8 clear_lcd = 1;
1911 tk 425
  static u32 performance_print_timestamp = 0;
1298 tk 426
 
1905 tk 427
  MUTEX_LCD_TAKE;
428
 
1887 tk 429
  if( clear_lcd ) {
430
    clear_lcd = 0;
1911 tk 431
    MIOS32_LCD_Clear();
1887 tk 432
  }
433
 
1334 tk 434
  // call SCS handler
435
  SCS_Tick();
1298 tk 436
 
1905 tk 437
  MUTEX_LCD_GIVE;
1885 tk 438
 
1334 tk 439
  // MIDI In/Out monitor
1492 tk 440
  MIDI_PORT_Period1mS();
1298 tk 441
 
1905 tk 442
  // LED rings
443
  MBCV_LRE_UpdateAllLedRings();
444
 
1334 tk 445
  // output and reset current stopwatch max value each second
1911 tk 446
  if( MIOS32_TIMESTAMP_GetDelay(performance_print_timestamp) > 1000 ) {
447
    performance_print_timestamp = MIOS32_TIMESTAMP_Get();
1334 tk 448
 
449
    MUTEX_MIDIOUT_TAKE;
450
    MIOS32_IRQ_Disable();
1903 tk 451
    u32 min_value = stopwatch_value_min;
452
    stopwatch_value_min = ~0;
1334 tk 453
    u32 max_value = stopwatch_value_max;
454
    stopwatch_value_max = 0;
455
    u32 acc_value = stopwatch_value_accumulated;
456
    stopwatch_value_accumulated = 0;
1903 tk 457
    u32 acc_ctr = stopwatch_value_accumulated_ctr;
458
    stopwatch_value_accumulated_ctr = 0;
1334 tk 459
    MIOS32_IRQ_Enable();
460
#if DEBUG_VERBOSE_LEVEL >= 2
461
    if( acc_value || max_value )
1903 tk 462
      DEBUG_MSG("%d uS (min: %d uS, max: %d uS)\n", acc_value / acc_ctr, min_value, max_value);
1334 tk 463
#endif
464
    MUTEX_MIDIOUT_GIVE;
1298 tk 465
  }
466
 
467
}
468
 
469
 
470
/////////////////////////////////////////////////////////////////////////////
1905 tk 471
// This task handles the scope displays with very low priority
472
/////////////////////////////////////////////////////////////////////////////
473
void APP_TASK_Period_1mS_LP2(void)
474
{
475
  {
476
#if J5_DEBUG_PINS
477
    MIOS32_BOARD_J5_PinSet(6, 0);
478
#endif
479
    // CV Scopes (note: mutex is taken inside function)
480
    mbCvEnvironment.tickScopes();
481
#if J5_DEBUG_PINS
482
    MIOS32_BOARD_J5_PinSet(6, 1);
483
#endif
484
  }
485
 
486
  // CV Bars (currently only for SSD1306)
487
  {
488
    MUTEX_LCD_TAKE;
489
 
490
    if( mios32_lcd_parameters.lcd_type == MIOS32_LCD_TYPE_GLCD_SSD1306 ) {
491
 
492
      MIOS32_LCD_DeviceSet(0);
493
      MIOS32_LCD_FontInit((u8 *)GLCD_FONT_METER_ICONS_V); // memo: 28 icons, 14 used, icon size: 8x32
494
 
495
      u16 *outMeter = mbCvEnvironment.cvOutMeter.first();
496
      for(int cv=0; cv<CV_SE_NUM; ++cv, ++outMeter) {
497
    MIOS32_LCD_CursorSet(0 + 2*cv, 4);
498
    MIOS32_LCD_PrintChar((*outMeter * 13) / 65535);
499
      }
500
 
501
      MIOS32_LCD_FontInit((u8 *)GLCD_FONT_NORMAL);    
502
    }
503
 
504
    MUTEX_LCD_GIVE;
505
  }
506
}
507
 
508
 
509
/////////////////////////////////////////////////////////////////////////////
1298 tk 510
// This task handles the SD Card
511
/////////////////////////////////////////////////////////////////////////////
1334 tk 512
void APP_TASK_Period_1mS_SD(void)
1298 tk 513
{
1334 tk 514
  static u16 sdcard_check_ctr = 0;
1298 tk 515
 
1334 tk 516
  // each second: check if SD Card (still) available
517
  if( ++sdcard_check_ctr >= 1000 ) {
518
    sdcard_check_ctr = 0;
1298 tk 519
 
1334 tk 520
    MUTEX_SDCARD_TAKE;
521
    s32 status = FILE_CheckSDCard();
1298 tk 522
 
1334 tk 523
    if( status == 1 ) {
524
      DEBUG_MSG("SD Card connected: %s\n", FILE_VolumeLabel());
525
      // load all file infos
526
      MBCV_FILE_LoadAllFiles(1); // including HW info
527
    } else if( status == 2 ) {
528
      DEBUG_MSG("SD Card disconnected\n");
529
      // invalidate all file infos
530
      MBCV_FILE_UnloadAllFiles();
1298 tk 531
 
1334 tk 532
      // change status
533
      MBCV_FILE_StatusMsgSet("No SD Card");
534
    } else if( status == 3 ) {
535
      if( !FILE_SDCardAvailable() ) {
536
    DEBUG_MSG("SD Card not found\n");
1912 tk 537
    MBCV_FILE_HW_LockConfig(); // lock configuration
1298 tk 538
    MBCV_FILE_StatusMsgSet("No SD Card");
1334 tk 539
      } else if( !FILE_VolumeAvailable() ) {
540
    DEBUG_MSG("ERROR: SD Card contains invalid FAT!\n");
1912 tk 541
    MBCV_FILE_HW_LockConfig(); // lock configuration
1334 tk 542
    MBCV_FILE_StatusMsgSet("No FAT");
543
      } else {
1653 tk 544
    // create the default files if they don't exist on SD Card
545
    MBCV_FILE_CreateDefaultFiles();
1298 tk 546
 
1334 tk 547
    // disable status message and print patch
548
    MBCV_FILE_StatusMsgSet(NULL);
1298 tk 549
      }
550
    }
1334 tk 551
 
552
    MUTEX_SDCARD_GIVE;
1298 tk 553
  }
554
}
555
 
556
 
557
/////////////////////////////////////////////////////////////////////////////
1452 tk 558
// This task is called periodically each mS
1298 tk 559
/////////////////////////////////////////////////////////////////////////////
1334 tk 560
void APP_TASK_Period_1mS(void)
1298 tk 561
{
1452 tk 562
  // e.g. for synched pattern changes
563
  mbCvEnvironment.tick_1mS();
1298 tk 564
}
565
 
566
 
567
/////////////////////////////////////////////////////////////////////////////
568
// Installed via MIOS32_MIDI_DirectRxCallback_Init
569
/////////////////////////////////////////////////////////////////////////////
570
static s32 NOTIFY_MIDI_Rx(mios32_midi_port_t port, u8 midi_byte)
571
{
1299 tk 572
  // filter MIDI In port which controls the MIDI clock
1895 tk 573
  if( MIDI_ROUTER_MIDIClockInGet(port) == 1 ) {
1408 tk 574
    if( midi_byte >= 0xf8 ) {
575
      mbCvEnvironment.midiReceiveRealTimeEvent(port, midi_byte);
576
    }
577
  }
578
 
1298 tk 579
  return 0; // no error, no filtering
580
}
581
 
1299 tk 582
/////////////////////////////////////////////////////////////////////////////
583
// Installed via MIOS32_MIDI_DirectTxCallback_Init
584
/////////////////////////////////////////////////////////////////////////////
585
static s32 NOTIFY_MIDI_Tx(mios32_midi_port_t port, mios32_midi_package_t package)
586
{
1492 tk 587
  return MIDI_PORT_NotifyMIDITx(port, package);
1299 tk 588
}
1298 tk 589
 
590
/////////////////////////////////////////////////////////////////////////////
1299 tk 591
// Installed via MIOS32_MIDI_TimeoutCallback_Init
592
/////////////////////////////////////////////////////////////////////////////
593
static s32 NOTIFY_MIDI_TimeOut(mios32_midi_port_t port)
594
{  
595
  // forward to SysEx parser
596
  MBCV_SYSEX_TimeOut(port);
597
 
598
  // print message on screen
599
  SCS_Msg(SCS_MSG_L, 2000, "MIDI Protocol", "TIMEOUT !!!");
600
 
601
  return 0;
602
}
603
 
604
 
605
/////////////////////////////////////////////////////////////////////////////
1895 tk 606
// Switches to the scope LCDs
607
/////////////////////////////////////////////////////////////////////////////
1905 tk 608
s32 APP_SelectScopeLCDs(void)
1895 tk 609
{
610
  // select the alternative pinning via J5A/J28
611
  APP_LCD_AltPinningSet(1);
612
 
613
  // select GLCD type and dimensions
614
  mios32_lcd_parameters.lcd_type = MIOS32_LCD_TYPE_GLCD_SSD1306; // TODO: get this from a configuration file
615
  mios32_lcd_parameters.num_x = 4;
616
  mios32_lcd_parameters.num_y = 1;
617
  mios32_lcd_parameters.width = 128;
618
  mios32_lcd_parameters.height = 64;
619
 
620
  return 0; // no error
621
}
622
 
623
/////////////////////////////////////////////////////////////////////////////
624
// Switches to the original LCD
625
/////////////////////////////////////////////////////////////////////////////
1905 tk 626
s32 APP_SelectMainLCD(void)
1895 tk 627
{
628
  // ensure that first LCD is selected
629
  MIOS32_LCD_DeviceSet(0);
630
 
631
  // select the original pinning
632
  APP_LCD_AltPinningSet(0);
633
 
634
  // retrieve original LCD parameters
635
  MIOS32_LCD_ParametersFetchFromBslInfoRange();
636
 
637
  return 0; // no error
638
}
639
 
640
 
641
/////////////////////////////////////////////////////////////////////////////
1914 tk 642
// Speed Factor (engine will be updated at factor * 500 Hz)
643
/////////////////////////////////////////////////////////////////////////////
644
s32 APP_CvUpdateRateFactorSet(u8 factor)
645
{
646
  if( factor < 1 || factor > APP_CV_UPDATE_RATE_FACTOR_MAX )
647
    return -1; // invalid factor
648
 
649
  MIOS32_IRQ_Disable();
650
 
651
  cv_se_speed_factor = factor;
652
  mbCvEnvironment.updateSpeedFactorSet(cv_se_speed_factor);
653
 
654
  // start timer
655
  MIOS32_TIMER_Init(2, 2000 / cv_se_speed_factor, CV_TIMER_SE_Update, MIOS32_IRQ_PRIO_MID);
656
 
657
  // clear overload indicators
658
  cv_se_overloaded = 0;
659
  cv_se_overload_check_ctr = 0;
660
  cv_se_last_mios32_timestamp = MIOS32_TIMESTAMP_Get();
661
 
662
  MIOS32_IRQ_Enable();
663
 
664
  return 0; // no error
665
}
666
 
667
s32 APP_CvUpdateRateFactorGet(void)
668
{
669
  return cv_se_speed_factor;
670
}
671
 
672
/////////////////////////////////////////////////////////////////////////////
673
// Returns 1 if engine overloaded
674
/////////////////////////////////////////////////////////////////////////////
675
s32 APP_CvUpdateOverloadStatusGet(void)
676
{
677
  return cv_se_overloaded;
678
}
679
 
680
 
681
/////////////////////////////////////////////////////////////////////////////
1334 tk 682
// For performance Measurements
1298 tk 683
/////////////////////////////////////////////////////////////////////////////
1334 tk 684
s32 APP_StopwatchInit(void)
1298 tk 685
{
1334 tk 686
  stopwatch_value = 0;
1903 tk 687
  stopwatch_value_min = ~0;
1334 tk 688
  stopwatch_value_max = 0;
689
  stopwatch_value_accumulated = 0;
1903 tk 690
  stopwatch_value_accumulated_ctr = 0;
1334 tk 691
  return MIOS32_STOPWATCH_Init(1); // 1 uS resolution
1298 tk 692
}
693
 
1334 tk 694
s32 APP_StopwatchReset(void)
1298 tk 695
{
1334 tk 696
  return MIOS32_STOPWATCH_Reset();
1298 tk 697
}
698
 
1334 tk 699
s32 APP_StopwatchCapture(void)
1298 tk 700
{
1334 tk 701
  u32 value = MIOS32_STOPWATCH_ValueGet();
702
  MIOS32_IRQ_Disable();
703
  stopwatch_value = value;
1903 tk 704
  if( value < stopwatch_value_min )
705
    stopwatch_value_min = value;
1334 tk 706
  if( value > stopwatch_value_max )
707
    stopwatch_value_max = value;
708
  stopwatch_value_accumulated += value;
1903 tk 709
  ++stopwatch_value_accumulated_ctr;
1334 tk 710
  MIOS32_IRQ_Enable();
1298 tk 711
 
712
  return 0; // no error
713
}
1895 tk 714