Subversion Repositories svn.mios32

Rev

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

Rev Author Line No. Line
1260 tk 1
// $Id: app.c 1653 2013-01-09 23:08:59Z tk $
2
/*
3
 * MIDIO 128 V3
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>
1297 tk 19
#include <msd.h>
1260 tk 20
#include "app.h"
21
#include "tasks.h"
22
 
1536 tk 23
#include <ainser.h>
1492 tk 24
#include <midi_port.h>
25
#include <midi_router.h>
26
#include <midimon.h>
27
 
1260 tk 28
#include "midio_sysex.h"
29
#include "midio_patch.h"
30
#include "midio_din.h"
31
#include "midio_dout.h"
1303 tk 32
#include "midio_ain.h"
1292 tk 33
#include "midio_matrix.h"
1260 tk 34
 
35
// include source of the SCS
36
#include <scs.h>
37
#include "scs_config.h"
38
 
1261 tk 39
#include "file.h"
1260 tk 40
#include "midio_file.h"
41
#include "midio_file_p.h"
42
 
1261 tk 43
#include <seq_bpm.h>
44
#include <seq_midi_out.h>
45
#include "seq.h"
46
#include "mid_file.h"
47
 
1260 tk 48
#include "terminal.h"
49
 
50
#include "uip_task.h"
51
#include "osc_client.h"
52
 
53
 
1261 tk 54
// define priority level for sequencer
55
// use same priority as MIOS32 specific tasks
56
#define PRIORITY_TASK_PERIOD_1mS ( tskIDLE_PRIORITY + 3 )
57
 
58
// local prototype of the task function
59
static void TASK_Period_1mS(void *pvParameters);
60
 
1260 tk 61
// define priority level for control surface handler
62
// use lower priority as MIOS32 specific tasks (2), so that slow LCDs don't affect overall performance
63
#define PRIORITY_TASK_PERIOD_1mS_LP ( tskIDLE_PRIORITY + 2 )
64
 
1297 tk 65
// SD Card with lower priority
66
#define PRIORITY_TASK_PERIOD_1mS_SD ( tskIDLE_PRIORITY + 2 )
67
 
1260 tk 68
// local prototype of the task function
69
static void TASK_Period_1mS_LP(void *pvParameters);
1297 tk 70
static void TASK_Period_1mS_SD(void *pvParameters);
1260 tk 71
 
1480 tk 72
 
73
// Extra hack: optionally map 16 encoders to the first DINX4 module (SR1..4)
74
// they send relative events CC16..CC23 over MIDI channel #2
75
#define ENABLE_ROTARY_ENCODERS 0
76
#define NUM_ROTARY_ENCODERS 16
77
 
78
 
1297 tk 79
/////////////////////////////////////////////////////////////////////////////
80
// Local types
81
/////////////////////////////////////////////////////////////////////////////
1260 tk 82
 
1297 tk 83
typedef enum {
84
  MSD_DISABLED,
85
  MSD_INIT,
86
  MSD_READY,
87
  MSD_SHUTDOWN
88
} msd_state_t;
89
 
90
 
1260 tk 91
/////////////////////////////////////////////////////////////////////////////
92
// local variables
93
/////////////////////////////////////////////////////////////////////////////
1298 tk 94
static u8 hw_enabled;
1260 tk 95
 
96
// for mutual exclusive SD Card access between different tasks
97
// The mutex is handled with MUTEX_SDCARD_TAKE and MUTEX_SDCARD_GIVE
98
// macros inside the application, which contain a different implementation 
99
// for emulation
100
xSemaphoreHandle xSDCardSemaphore;
101
 
102
// Mutex for MIDI IN/OUT handler
103
xSemaphoreHandle xMIDIINSemaphore;
104
xSemaphoreHandle xMIDIOUTSemaphore;
105
 
106
 
107
static u32 ms_counter;
108
 
1299 tk 109
static volatile msd_state_t msd_state;
1260 tk 110
 
1297 tk 111
 
1260 tk 112
/////////////////////////////////////////////////////////////////////////////
113
// Local prototypes
114
/////////////////////////////////////////////////////////////////////////////
1261 tk 115
static s32 NOTIFY_MIDI_Rx(mios32_midi_port_t port, u8 byte);
1299 tk 116
static s32 NOTIFY_MIDI_Tx(mios32_midi_port_t port, mios32_midi_package_t package);
117
static s32 NOTIFY_MIDI_TimeOut(mios32_midi_port_t port);
1260 tk 118
 
119
 
120
 
121
/////////////////////////////////////////////////////////////////////////////
122
// This hook is called after startup to initialize the application
123
/////////////////////////////////////////////////////////////////////////////
124
void APP_Init(void)
125
{
126
  // initialize all LEDs
127
  MIOS32_BOARD_LED_Init(0xffffffff);
128
 
1299 tk 129
  // disable MSD by default (has to be enabled in SHIFT menu)
1297 tk 130
  msd_state = MSD_DISABLED;
131
 
1298 tk 132
  // hardware will be enabled once configuration has been loaded from SD Card
1260 tk 133
  // (resp. no SD Card is available)
1298 tk 134
  hw_enabled = 0;
1260 tk 135
 
136
  // initialize all J10 pins as inputs with internal Pull-Up
137
  int pin;
138
  for(pin=0; pin<8; ++pin)
139
    MIOS32_BOARD_J10_PinInit(pin, MIOS32_BOARD_PIN_MODE_INPUT_PU);
140
 
1441 tk 141
  // initialize the AINSER module(s)
142
  AINSER_Init(0);
1260 tk 143
 
144
  // create semaphores
145
  xSDCardSemaphore = xSemaphoreCreateRecursiveMutex();
146
  xMIDIINSemaphore = xSemaphoreCreateRecursiveMutex();
147
  xMIDIOUTSemaphore = xSemaphoreCreateRecursiveMutex();
148
 
149
  // install SysEx callback
150
  MIOS32_MIDI_SysExCallback_Init(APP_SYSEX_Parser);
151
 
1299 tk 152
  // install MIDI Rx/Tx callback functions
153
  MIOS32_MIDI_DirectRxCallback_Init(&NOTIFY_MIDI_Rx);
154
  MIOS32_MIDI_DirectTxCallback_Init(&NOTIFY_MIDI_Tx);
1261 tk 155
 
1299 tk 156
  // install timeout callback function
157
  MIOS32_MIDI_TimeOutCallback_Init(&NOTIFY_MIDI_TimeOut);
158
 
1260 tk 159
  // initialize code modules
1492 tk 160
  MIDI_PORT_Init(0);
1260 tk 161
  MIDIO_SYSEX_Init(0);
1492 tk 162
  MIDI_ROUTER_Init(0);
1260 tk 163
  MIDIO_PATCH_Init(0);
164
  MIDIO_DIN_Init(0);
165
  MIDIO_DOUT_Init(0);
1303 tk 166
  MIDIO_AIN_Init(0);
1292 tk 167
  MIDIO_MATRIX_Init(0);
1260 tk 168
  UIP_TASK_Init(0);
169
  SCS_Init(0);
170
  SCS_CONFIG_Init(0);
171
  TERMINAL_Init(0);
172
  MIDIMON_Init(0);
173
  MIDIO_FILE_Init(0);
1261 tk 174
  SEQ_MIDI_OUT_Init(0);
175
  SEQ_Init(0);
1260 tk 176
 
1480 tk 177
#if ENABLE_ROTARY_ENCODERS
178
  // optionally enable rotary encoders
179
  int enc;
180
  for(enc=0; enc<NUM_ROTARY_ENCODERS; ++enc) {
181
    u8 pin_sr = enc >> 2; // each DIN SR has 4 encoders connected
182
    u8 pin_pos = (enc & 0x3) << 1; // Pin position of first ENC channel: either 0, 2, 4 or 6
183
 
184
    mios32_enc_config_t enc_config = MIOS32_ENC_ConfigGet(enc);
185
    enc_config.cfg.type = DETENTED3; // see mios32_enc.h for available types
186
    enc_config.cfg.sr = pin_sr;
187
    enc_config.cfg.pos = pin_pos;
188
    enc_config.cfg.speed = NORMAL;
189
    enc_config.cfg.speed_par = 0;
190
 
191
    // EXTRA: assign encoder to +1, since the first encoder entry is allocated by the SCS!
192
    MIOS32_ENC_ConfigSet(enc+1, enc_config);
193
  }
194
#endif
195
 
1261 tk 196
  // start tasks
197
  xTaskCreate(TASK_Period_1mS, (signed portCHAR *)"1mS", configMINIMAL_STACK_SIZE, NULL, PRIORITY_TASK_PERIOD_1mS, NULL);
1268 tk 198
  xTaskCreate(TASK_Period_1mS_LP, (signed portCHAR *)"1mS_LP", 2*configMINIMAL_STACK_SIZE, NULL, PRIORITY_TASK_PERIOD_1mS_LP, NULL);
1297 tk 199
  xTaskCreate(TASK_Period_1mS_SD, (signed portCHAR *)"1mS_SD", 2*configMINIMAL_STACK_SIZE, NULL, PRIORITY_TASK_PERIOD_1mS_SD, NULL);
1260 tk 200
 
201
}
202
 
203
 
204
/////////////////////////////////////////////////////////////////////////////
205
// This task is running endless in background
206
/////////////////////////////////////////////////////////////////////////////
207
void APP_Background(void)
208
{
209
  // endless loop
210
  while( 1 ) {
211
    // toggle the state of all LEDs (allows to measure the execution speed with a scope)
212
    MIOS32_BOARD_LED_Set(0xffffffff, ~MIOS32_BOARD_LED_Get());
213
  }
214
}
215
 
216
 
217
/////////////////////////////////////////////////////////////////////////////
218
// This hook is called when a MIDI package has been received
219
/////////////////////////////////////////////////////////////////////////////
220
void APP_MIDI_NotifyPackage(mios32_midi_port_t port, mios32_midi_package_t midi_package)
221
{
222
  // -> DOUT
223
  MIDIO_DOUT_MIDI_NotifyPackage(port, midi_package);
224
 
1293 tk 225
  // -> MIDI Router
1492 tk 226
  MIDI_ROUTER_Receive(port, midi_package);
1260 tk 227
 
1299 tk 228
  // -> MIDI Port Handler (used for MIDI monitor function)
1492 tk 229
  MIDI_PORT_NotifyMIDIRx(port, midi_package);
1299 tk 230
 
1536 tk 231
  // -> MIDI file recorder
1538 tk 232
  MID_FILE_Receive(port, midi_package);
1536 tk 233
 
1260 tk 234
  // forward to MIDI Monitor
235
  // SysEx messages have to be filtered for USB0 and UART0 to avoid data corruption
236
  // (the SysEx stream would interfere with monitor messages)
237
  u8 filter_sysex_message = (port == USB0) || (port == UART0);
238
  MIDIMON_Receive(port, midi_package, ms_counter, filter_sysex_message);
239
}
240
 
241
/////////////////////////////////////////////////////////////////////////////
242
// This function parses an incoming sysex stream for MIOS32 commands
243
/////////////////////////////////////////////////////////////////////////////
244
s32 APP_SYSEX_Parser(mios32_midi_port_t port, u8 midi_in)
245
{
246
  // -> MIDIO
247
  MIDIO_SYSEX_Parser(port, midi_in);
248
 
1293 tk 249
  // -> MIDI Router
1492 tk 250
  MIDI_ROUTER_ReceiveSysEx(port, midi_in);
1260 tk 251
 
252
  return 0; // no error
253
}
254
 
255
/////////////////////////////////////////////////////////////////////////////
256
// This hook is called before the shift register chain is scanned
257
/////////////////////////////////////////////////////////////////////////////
258
void APP_SRIO_ServicePrepare(void)
259
{
260
  // pass current pin state of J10
261
  // only available for LPC17xx, all others (like STM32) default to SRIO
262
  SCS_AllPinsSet(0xff00 | MIOS32_BOARD_J10_Get());
263
 
264
  // update encoders/buttons of SCS
265
  SCS_EncButtonUpdate_Tick();
1292 tk 266
 
267
  // Matrix handler
268
  MIDIO_MATRIX_PrepareCol();
1260 tk 269
}
270
 
271
 
272
/////////////////////////////////////////////////////////////////////////////
273
// This hook is called after the shift register chain has been scanned
274
/////////////////////////////////////////////////////////////////////////////
275
void APP_SRIO_ServiceFinish(void)
276
{
1292 tk 277
  // Matrix handler
278
  MIDIO_MATRIX_GetRow();
1260 tk 279
}
280
 
281
 
282
/////////////////////////////////////////////////////////////////////////////
283
// This hook is called when a button has been toggled
284
// pin_value is 1 when button released, and 0 when button pressed
285
/////////////////////////////////////////////////////////////////////////////
286
void APP_DIN_NotifyToggle(u32 pin, u32 pin_value)
287
{
288
  // -> MIDIO_DIN once enabled
1298 tk 289
  if( hw_enabled )
1260 tk 290
    MIDIO_DIN_NotifyToggle(pin, pin_value);
291
}
292
 
293
 
294
/////////////////////////////////////////////////////////////////////////////
295
// This hook is called when an encoder has been moved
296
// incrementer is positive when encoder has been turned clockwise, else
297
// it is negative
298
/////////////////////////////////////////////////////////////////////////////
299
void APP_ENC_NotifyChange(u32 encoder, s32 incrementer)
300
{
301
  // pass encoder event to SCS handler
302
  if( encoder == SCS_ENC_MENU_ID )
303
    SCS_ENC_MENU_NotifyChange(incrementer);
1480 tk 304
  else {
305
#if ENABLE_ROTARY_ENCODERS
306
    // determine relative value: 64 +/- <incrementer>
307
    int value = 64 + incrementer;
308
 
309
    // ensure that value is in range of 0..127
310
    if( value < 0 )
311
      value = 0;
312
    else if( value > 127 )
313
      value = 127;
314
 
315
    // send event
316
    MIOS32_MIDI_SendCC(DEFAULT, Chn2, 0x10 + encoder - 1, value);
317
#endif
318
  }
1260 tk 319
}
320
 
321
 
322
/////////////////////////////////////////////////////////////////////////////
323
// This hook is called when a pot has been moved
324
/////////////////////////////////////////////////////////////////////////////
325
void APP_AIN_NotifyChange(u32 pin, u32 pin_value)
326
{
1303 tk 327
  // -> MIDIO_AIN once enabled
328
  if( hw_enabled )
329
    MIDIO_AIN_NotifyChange(pin, pin_value);
1260 tk 330
}
331
 
332
 
1441 tk 333
/////////////////////////////////////////////////////////////////////////////
334
// This hook is called when an AINSER pot has been moved
335
/////////////////////////////////////////////////////////////////////////////
336
static void APP_AINSER_NotifyChange(u32 module, u32 pin, u32 pin_value)
337
{
338
  // -> MIDIO_AIN once enabled
339
  if( hw_enabled )
340
    MIDIO_AIN_NotifyChange_SER64(module, pin, pin_value);
341
}
1261 tk 342
 
343
 
1260 tk 344
/////////////////////////////////////////////////////////////////////////////
345
// This task handles the control surface
346
/////////////////////////////////////////////////////////////////////////////
347
static void TASK_Period_1mS_LP(void *pvParameters)
348
{
349
  MIOS32_LCD_Clear();
350
 
351
  while( 1 ) {
352
    vTaskDelay(1 / portTICK_RATE_MS);
353
 
354
    // call SCS handler
355
    SCS_Tick();
1299 tk 356
 
357
    // MIDI In/Out monitor
1492 tk 358
    MIDI_PORT_Period1mS();
1261 tk 359
  }
1260 tk 360
 
1261 tk 361
}
362
 
363
 
364
/////////////////////////////////////////////////////////////////////////////
1297 tk 365
// This task handles the SD Card
366
/////////////////////////////////////////////////////////////////////////////
367
static void TASK_Period_1mS_SD(void *pvParameters)
368
{
1540 tk 369
  const u16 sdcard_check_delay = 1000;
1297 tk 370
  u16 sdcard_check_ctr = 0;
371
  u8 lun_available = 0;
372
 
373
  while( 1 ) {
374
    vTaskDelay(1 / portTICK_RATE_MS);
375
 
376
    // each second: check if SD Card (still) available
1540 tk 377
    if( msd_state == MSD_DISABLED && ++sdcard_check_ctr >= sdcard_check_delay ) {
1297 tk 378
      sdcard_check_ctr = 0;
379
 
380
      MUTEX_SDCARD_TAKE;
381
      s32 status = FILE_CheckSDCard();
382
 
383
      if( status == 1 ) {
384
    DEBUG_MSG("SD Card connected: %s\n", FILE_VolumeLabel());
1540 tk 385
 
386
    // stop sequencer
387
    SEQ_BPM_Stop();
388
 
1297 tk 389
    // load all file infos
390
    MIDIO_FILE_LoadAllFiles(1); // including HW info
1540 tk 391
 
392
    // immediately go to next step
393
    sdcard_check_ctr = sdcard_check_delay;
1297 tk 394
      } else if( status == 2 ) {
395
    DEBUG_MSG("SD Card disconnected\n");
396
    // invalidate all file infos
397
    MIDIO_FILE_UnloadAllFiles();
398
 
399
    // stop sequencer
400
    SEQ_BPM_Stop();
401
 
1298 tk 402
    // change status
403
    MIDIO_FILE_StatusMsgSet("No SD Card");
1297 tk 404
      } else if( status == 3 ) {
405
    if( !FILE_SDCardAvailable() ) {
406
      DEBUG_MSG("SD Card not found\n");
1298 tk 407
      MIDIO_FILE_StatusMsgSet("No SD Card");
1297 tk 408
    } else if( !FILE_VolumeAvailable() ) {
409
      DEBUG_MSG("ERROR: SD Card contains invalid FAT!\n");
1298 tk 410
      MIDIO_FILE_StatusMsgSet("No FAT");
1297 tk 411
    } else {
1653 tk 412
      // create the default files if they don't exist on SD Card
413
      MIDIO_FILE_CreateDefaultFiles();
1297 tk 414
 
1540 tk 415
      // load first MIDI file
416
      MID_FILE_UI_NameClear();
417
      SEQ_SetPauseMode(1);
418
      SEQ_PlayFileReq(0, 1);
1297 tk 419
    }
1585 tk 420
 
421
    hw_enabled = 1; // enable hardware after first read...
1297 tk 422
      }
423
 
424
      MUTEX_SDCARD_GIVE;
425
    }
426
 
427
    // MSD driver
428
    if( msd_state != MSD_DISABLED ) {
429
      MUTEX_SDCARD_TAKE;
430
 
431
      switch( msd_state ) {
432
      case MSD_SHUTDOWN:
433
    // switch back to USB MIDI
434
    MIOS32_USB_Init(1);
435
    msd_state = MSD_DISABLED;
436
    break;
437
 
438
      case MSD_INIT:
439
    // LUN not mounted yet
440
    lun_available = 0;
441
 
442
    // enable MSD USB driver
443
    //MUTEX_J16_TAKE;
444
    if( MSD_Init(0) >= 0 )
445
      msd_state = MSD_READY;
446
    else
447
      msd_state = MSD_SHUTDOWN;
448
    //MUTEX_J16_GIVE;
449
    break;
450
 
451
      case MSD_READY:
452
    // service MSD USB driver
453
    MSD_Periodic_mS();
454
 
455
    // this mechanism shuts down the MSD driver if SD card has been unmounted by OS
456
    if( lun_available && !MSD_LUN_AvailableGet(0) )
457
      msd_state = MSD_SHUTDOWN;
458
    else if( !lun_available && MSD_LUN_AvailableGet(0) )
459
      lun_available = 1;
460
    break;
461
      }
462
 
463
      MUTEX_SDCARD_GIVE;
464
    }
465
  }
466
 
467
}
468
 
469
 
470
/////////////////////////////////////////////////////////////////////////////
1261 tk 471
// This task is called periodically each mS to handle sequencer requests
472
/////////////////////////////////////////////////////////////////////////////
473
static void TASK_Period_1mS(void *pvParameters)
474
{
475
  portTickType xLastExecutionTime;
476
 
477
  // Initialise the xLastExecutionTime variable on task entry
478
  xLastExecutionTime = xTaskGetTickCount();
479
 
480
  while( 1 ) {
481
    vTaskDelayUntil(&xLastExecutionTime, 1 / portTICK_RATE_MS);
482
 
1297 tk 483
    // skip delay gap if we had to wait for more than 5 ticks to avoid 
484
    // unnecessary repeats until xLastExecutionTime reached xTaskGetTickCount() again
485
    portTickType xCurrentTickCount = xTaskGetTickCount();
486
    if( xLastExecutionTime < (xCurrentTickCount-5) )
487
      xLastExecutionTime = xCurrentTickCount;
488
 
1610 tk 489
 
490
    // increment timestamp
491
    ++ms_counter;
492
 
1261 tk 493
    // execute sequencer handler
494
    MUTEX_SDCARD_TAKE;
495
    SEQ_Handler();
1260 tk 496
    MUTEX_SDCARD_GIVE;
1261 tk 497
 
498
    // send timestamped MIDI events
499
    MUTEX_MIDIOUT_TAKE;
500
    SEQ_MIDI_OUT_Handler();
501
    MUTEX_MIDIOUT_GIVE;
1292 tk 502
 
503
    // Scan Matrix button handler
504
    MIDIO_MATRIX_ButtonHandler();
1441 tk 505
 
506
    // scan AINSER pins
507
    AINSER_Handler(APP_AINSER_NotifyChange);
1260 tk 508
  }
509
}
510
 
511
 
512
/////////////////////////////////////////////////////////////////////////////
1261 tk 513
// Installed via MIOS32_MIDI_DirectRxCallback_Init
514
/////////////////////////////////////////////////////////////////////////////
515
static s32 NOTIFY_MIDI_Rx(mios32_midi_port_t port, u8 midi_byte)
516
{
1299 tk 517
  // filter MIDI In port which controls the MIDI clock
1492 tk 518
  if( MIDI_ROUTER_MIDIClockInGet(port) == 1 )
1299 tk 519
    SEQ_BPM_NotifyMIDIRx(midi_byte);
1261 tk 520
 
521
  return 0; // no error, no filtering
522
}
1297 tk 523
 
1299 tk 524
/////////////////////////////////////////////////////////////////////////////
525
// Installed via MIOS32_MIDI_DirectTxCallback_Init
526
/////////////////////////////////////////////////////////////////////////////
527
static s32 NOTIFY_MIDI_Tx(mios32_midi_port_t port, mios32_midi_package_t package)
528
{
1492 tk 529
  return MIDI_PORT_NotifyMIDITx(port, package);
1299 tk 530
}
1297 tk 531
 
532
/////////////////////////////////////////////////////////////////////////////
1299 tk 533
// Installed via MIOS32_MIDI_TimeoutCallback_Init
534
/////////////////////////////////////////////////////////////////////////////
535
static s32 NOTIFY_MIDI_TimeOut(mios32_midi_port_t port)
536
{  
537
  // forward to SysEx parser
538
  MIDIO_SYSEX_TimeOut(port);
539
 
540
  // print message on screen
541
  SCS_Msg(SCS_MSG_L, 2000, "MIDI Protocol", "TIMEOUT !!!");
542
 
543
  return 0;
544
}
545
 
546
 
547
/////////////////////////////////////////////////////////////////////////////
1297 tk 548
// MSD access functions
549
/////////////////////////////////////////////////////////////////////////////
550
s32 TASK_MSD_EnableSet(u8 enable)
551
{
552
  MIOS32_IRQ_Disable();
553
  if( msd_state == MSD_DISABLED && enable ) {
554
    msd_state = MSD_INIT;
555
  } else if( msd_state == MSD_READY && !enable )
556
    msd_state = MSD_SHUTDOWN;
557
  MIOS32_IRQ_Enable();
558
 
559
  return 0; // no error
560
}
561
 
562
s32 TASK_MSD_EnableGet()
563
{
564
  return (msd_state == MSD_READY) ? 1 : 0;
565
}
566
 
567
s32 TASK_MSD_FlagStrGet(char str[5])
568
{
569
  str[0] = MSD_CheckAvailable() ? 'U' : '-';
570
  str[1] = MSD_LUN_AvailableGet(0) ? 'M' : '-';
571
  str[2] = MSD_RdLEDGet(250) ? 'R' : '-';
572
  str[3] = MSD_WrLEDGet(250) ? 'W' : '-';
573
  str[4] = 0;
574
 
575
  return 0; // no error
576
}
1610 tk 577
 
578
/////////////////////////////////////////////////////////////////////////////
579
// functions to access MIDI IN/Out Mutex
580
// see also mios32_config.h
581
/////////////////////////////////////////////////////////////////////////////
582
void APP_MUTEX_MIDIOUT_Take(void) { MUTEX_MIDIOUT_TAKE; }
583
void APP_MUTEX_MIDIOUT_Give(void) { MUTEX_MIDIOUT_GIVE; }
584
void APP_MUTEX_MIDIIN_Take(void) { MUTEX_MIDIIN_TAKE; }
585
void APP_MUTEX_MIDIIN_Give(void) { MUTEX_MIDIIN_GIVE; }