Subversion Repositories svn.mios32

Rev

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

Rev Author Line No. Line
1260 tk 1
// $Id: midio_file_p.c 1268 2011-07-22 22:40:03Z tk $
2
/*
1264 tk 3
 * Patch File access functions
1260 tk 4
 *
5
 * NOTE: before accessing the SD Card, the upper level function should
6
 * synchronize with the SD Card semaphore!
7
 *   MUTEX_SDCARD_TAKE; // to take the semaphore
8
 *   MUTEX_SDCARD_GIVE; // to release the semaphore
9
 *
10
 * ==========================================================================
11
 *
1261 tk 12
 *  Copyright (C) 2011 Thorsten Klose (tk@midibox.org)
1260 tk 13
 *  Licensed for personal non-commercial use only.
14
 *  All other rights reserved.
15
 *
16
 * ==========================================================================
17
 */
18
 
19
/////////////////////////////////////////////////////////////////////////////
20
// Include files
21
/////////////////////////////////////////////////////////////////////////////
22
 
23
#include <mios32.h>
24
#include "tasks.h"
25
 
26
#include <string.h>
27
 
1261 tk 28
#include "file.h"
1260 tk 29
#include "midio_file.h"
30
#include "midio_file_p.h"
31
#include "midio_patch.h"
32
 
33
#if !defined(MIOS32_FAMILY_EMULATION)
34
#include "uip.h"
35
#include "uip_task.h"
36
#include "osc_server.h"
37
#endif
38
 
39
 
40
/////////////////////////////////////////////////////////////////////////////
41
// for optional debugging messages via DEBUG_MSG (defined in mios32_config.h)
42
/////////////////////////////////////////////////////////////////////////////
43
 
44
// Note: verbose level 1 is default - it prints error messages!
45
#define DEBUG_VERBOSE_LEVEL 1
46
 
47
 
48
/////////////////////////////////////////////////////////////////////////////
49
// Local definitions
50
/////////////////////////////////////////////////////////////////////////////
51
 
52
// in which subdirectory of the SD card are the files located?
53
// use "/" for root
54
// use "/<dir>/" for a subdirectory in root
55
// use "/<dir>/<subdir>/" to reach a subdirectory in <dir>, etc..
56
 
57
#define MIDIO_FILES_PATH "/"
58
//#define MIDIO_FILES_PATH "/MySongs/"
59
 
60
 
61
/////////////////////////////////////////////////////////////////////////////
62
// Local types
63
/////////////////////////////////////////////////////////////////////////////
64
 
65
// file informations stored in RAM
66
typedef struct {
67
  unsigned valid: 1;   // file is accessible
68
} midio_file_p_info_t;
69
 
70
 
71
/////////////////////////////////////////////////////////////////////////////
72
// Local prototypes
73
/////////////////////////////////////////////////////////////////////////////
74
 
75
 
76
/////////////////////////////////////////////////////////////////////////////
77
// Local variables
78
/////////////////////////////////////////////////////////////////////////////
79
 
80
static midio_file_p_info_t midio_file_p_info;
81
 
82
 
83
/////////////////////////////////////////////////////////////////////////////
1264 tk 84
// Global variables
85
/////////////////////////////////////////////////////////////////////////////
86
char midio_file_p_patch_name[MIDIO_FILE_P_FILENAME_LEN+1];
87
 
88
 
89
/////////////////////////////////////////////////////////////////////////////
1260 tk 90
// Initialisation
91
/////////////////////////////////////////////////////////////////////////////
92
s32 MIDIO_FILE_P_Init(u32 mode)
93
{
94
  // invalidate file info
95
  MIDIO_FILE_P_Unload();
96
 
97
  return 0; // no error
98
}
99
 
100
 
101
/////////////////////////////////////////////////////////////////////////////
1264 tk 102
// Loads patch file
103
// Called from MIDIO_FILE_CheckSDCard() when the SD card has been connected
1260 tk 104
// returns < 0 on errors
105
/////////////////////////////////////////////////////////////////////////////
1264 tk 106
s32 MIDIO_FILE_P_Load(char *filename)
1260 tk 107
{
108
  s32 error;
1264 tk 109
  error = MIDIO_FILE_P_Read(filename);
1260 tk 110
#if DEBUG_VERBOSE_LEVEL >= 2
1264 tk 111
  DEBUG_MSG("[MIDIO_FILE_P] Tried to open patch %s, status: %d\n", filename, error);
1260 tk 112
#endif
113
 
114
  return error;
115
}
116
 
117
 
118
/////////////////////////////////////////////////////////////////////////////
1264 tk 119
// Unloads patch file
120
// Called from MIDIO_FILE_CheckSDCard() when the SD card has been disconnected
1260 tk 121
// returns < 0 on errors
122
/////////////////////////////////////////////////////////////////////////////
123
s32 MIDIO_FILE_P_Unload(void)
124
{
125
  midio_file_p_info.valid = 0;
126
 
127
  return 0; // no error
128
}
129
 
130
 
131
 
132
/////////////////////////////////////////////////////////////////////////////
1264 tk 133
// Returns 1 if current patch file valid
134
// Returns 0 if current patch file not valid
1260 tk 135
/////////////////////////////////////////////////////////////////////////////
136
s32 MIDIO_FILE_P_Valid(void)
137
{
138
  return midio_file_p_info.valid;
139
}
140
 
141
 
142
/////////////////////////////////////////////////////////////////////////////
143
// help function which parses a decimal or hex value
144
// returns >= 0 if value is valid
145
// returns -1 if value is invalid
146
/////////////////////////////////////////////////////////////////////////////
147
static s32 get_dec(char *word)
148
{
149
  if( word == NULL )
150
    return -1;
151
 
152
  char *next;
153
  long l = strtol(word, &next, 0);
154
 
155
  if( word == next )
156
    return -1;
157
 
158
  return l; // value is valid
159
}
160
 
161
/////////////////////////////////////////////////////////////////////////////
162
// help function which parses an IP value
163
// returns > 0 if value is valid
164
// returns 0 if value is invalid
165
/////////////////////////////////////////////////////////////////////////////
166
static u32 get_ip(char *brkt)
167
{
168
  u8 ip[4];
169
  char *word;
170
 
171
  int i;
172
  for(i=0; i<4; ++i) {
173
    if( (word=strtok_r(NULL, ".", &brkt)) ) {
174
      s32 value = get_dec(word);
175
      if( value >= 0 && value <= 255 )
176
    ip[i] = value;
177
      else
178
    return 0;
179
    }
180
  }
181
 
182
  if( i == 4 )
183
    return (ip[0]<<24)|(ip[1]<<16)|(ip[2]<<8)|(ip[3]<<0);
184
  else
185
    return 0; // invalid IP
186
}
187
 
1268 tk 188
/////////////////////////////////////////////////////////////////////////////
189
// help function which parses a SR definition (<dec>.D<dec>)
190
// returns >= 0 if value is valid
191
// returns -1 if value is invalid
192
// returns -2 if SR number 0 has been passed (could disable a SR definition)
193
/////////////////////////////////////////////////////////////////////////////
194
static s32 get_sr(char *word)
195
{
196
  if( word == NULL )
197
    return -1;
1260 tk 198
 
1268 tk 199
  // check for '.D' separator
200
  char *word2 = word;
201
  while( *word2 != '.' )
202
    if( *word2++ == 0 )
203
      return -1;
204
  word2++;
205
  if( *word2++ != 'D' )
206
    return -1;
207
 
208
  s32 srNum = get_dec(word);
209
  if( srNum < 0 )
210
    return -1;
211
 
212
  if( srNum == 0 )
213
    return -2; // SR has been disabled...
214
 
215
  s32 pinNum = get_dec(word2);
216
  if( pinNum < 0 )
217
    return -1;
218
 
219
  if( pinNum >= 8 )
220
    return -1;
221
 
222
  return 8*(srNum-1) + pinNum;
223
}
224
 
1260 tk 225
/////////////////////////////////////////////////////////////////////////////
1268 tk 226
// help function which parses a binary value
227
// returns >= 0 if value is valid
228
// returns -1 if value is invalid
229
/////////////////////////////////////////////////////////////////////////////
230
static s32 get_bin(char *word, int numBits)
231
{
232
  if( word == NULL )
233
    return -1;
234
 
235
  s32 value = 0;
236
  int bit = 0;
237
  while( 1 ) {
238
    if( *word == '1' ) {
239
      value |= 1 << bit;
240
    } else if( *word != '0' ) {
241
      break;
242
    }
243
    ++word;
244
    ++bit;
245
  }
246
 
247
  if( bit != numBits )
248
    return -1; // invalid number of bits
249
 
250
  return value;
251
}
252
 
253
 
254
/////////////////////////////////////////////////////////////////////////////
1264 tk 255
// reads the patch file content (again)
1260 tk 256
// returns < 0 on errors (error codes are documented in midio_file.h)
257
/////////////////////////////////////////////////////////////////////////////
1264 tk 258
s32 MIDIO_FILE_P_Read(char *filename)
1260 tk 259
{
260
  s32 status = 0;
261
  midio_file_p_info_t *info = &midio_file_p_info;
1261 tk 262
  file_t file;
1260 tk 263
 
264
  info->valid = 0; // will be set to valid if file content has been read successfully
265
 
1264 tk 266
  // store current file name in global variable for UI
267
  memcpy(midio_file_p_patch_name, filename, MIDIO_FILE_P_FILENAME_LEN+1);
268
 
1260 tk 269
  char filepath[MAX_PATH];
1264 tk 270
  sprintf(filepath, "%s%s.MIO", MIDIO_FILES_PATH, midio_file_p_patch_name);
1260 tk 271
 
272
#if DEBUG_VERBOSE_LEVEL >= 2
1264 tk 273
  DEBUG_MSG("[MIDIO_FILE_P] Open patch '%s'\n", filepath);
1260 tk 274
#endif
275
 
1261 tk 276
  if( (status=FILE_ReadOpen(&file, filepath)) < 0 ) {
1260 tk 277
#if DEBUG_VERBOSE_LEVEL >= 2
278
    DEBUG_MSG("[MIDIO_FILE_P] failed to open file, status: %d\n", status);
279
#endif
280
    return status;
281
  }
282
 
1264 tk 283
  // read patch values
1260 tk 284
  char line_buffer[128];
285
  do {
1261 tk 286
    status=FILE_ReadLine((u8 *)line_buffer, 128);
1260 tk 287
 
288
    if( status > 1 ) {
289
#if DEBUG_VERBOSE_LEVEL >= 3
290
      DEBUG_MSG("[MIDIO_FILE_P] read: %s", line_buffer);
291
#endif
292
 
293
      // sscanf consumes too much memory, therefore we parse directly
294
      char *separators = " \t";
295
      char *brkt;
296
      char *parameter;
297
 
298
      if( (parameter = strtok_r(line_buffer, separators, &brkt)) ) {
299
 
300
    if( *parameter == '#' ) {
301
      // ignore comments
1268 tk 302
    } else if( strcmp(parameter, "DIN") == 0 ) {
303
      s32 sr;
304
      char *word = strtok_r(NULL, separators, &brkt);
305
      if( (sr=get_sr(word)) < 0 || sr >= MIDIO_PATCH_NUM_DIN  ) {
306
#if DEBUG_VERBOSE_LEVEL >= 1
307
        DEBUG_MSG("[MIDIO_FILE_P] ERROR invalid SR.Pin format for parameter '%s'\n", parameter);
308
#endif
309
      } else {
310
        s32 enabled_ports;
311
        char *word = strtok_r(NULL, separators, &brkt);
312
        if( (enabled_ports=get_bin(word, 16)) < 0 ) {
313
#if DEBUG_VERBOSE_LEVEL >= 1
314
          DEBUG_MSG("[MIDIO_FILE_P] ERROR invalid MIDI port format for parameter '%s %2d.D%d'\n", parameter, (sr/8)+1, sr%8);
315
#endif
316
        } else {
317
          s32 mode;
318
          char *word = strtok_r(NULL, separators, &brkt);
319
          if( (mode=get_dec(word)) < 0 ) {
320
#if DEBUG_VERBOSE_LEVEL >= 1
321
        DEBUG_MSG("[MIDIO_FILE_P] ERROR invalid Mode format for parameter '%s %2d.D%d'\n", parameter, (sr/8)+1, sr%8);
322
#endif
323
          } else {
324
        u8 events[6];
325
        int i;
326
        for(i=0; i<6; ++i) {
327
          char *word = strtok_r(NULL, separators, &brkt);
328
          if( (events[i]=get_dec(word)) < 0 ) {
329
#if DEBUG_VERBOSE_LEVEL >= 1
330
            DEBUG_MSG("[MIDIO_FILE_P] ERROR invalid Event format for parameter '%s %2d.D%d'\n", parameter, (sr/8)+1, sr%8);
331
#endif
332
            break;
333
          } else {
334
            events[i] &= 0x7f;
335
          }
336
        }
337
 
338
        if( i == 6 ) {
339
          // finally a valid line!
340
          midio_patch_din_entry_t *din_cfg = (midio_patch_din_entry_t *)&midio_patch_din[sr];
341
          din_cfg->enabled_ports = enabled_ports;
342
          din_cfg->mode = mode;
343
          din_cfg->evnt0_on = events[0];
344
          din_cfg->evnt1_on = events[1];
345
          din_cfg->evnt2_on = events[2];
346
          din_cfg->evnt0_off = events[3];
347
          din_cfg->evnt1_off = events[4];
348
          din_cfg->evnt2_off = events[5];
349
        }
350
          }
351
        }
352
 
353
      }  
354
    } else if( strcmp(parameter, "DOUT") == 0 ) {
355
      s32 sr;
356
      char *word = strtok_r(NULL, separators, &brkt);
357
      if( (sr=get_sr(word)) < 0 || sr >= MIDIO_PATCH_NUM_DIN  ) {
358
#if DEBUG_VERBOSE_LEVEL >= 1
359
        DEBUG_MSG("[MIDIO_FILE_P] ERROR invalid SR.Pin format for parameter '%s'\n", parameter);
360
#endif
361
      } else {
362
        s32 enabled_ports;
363
        char *word = strtok_r(NULL, separators, &brkt);
364
        if( (enabled_ports=get_bin(word, 16)) < 0 ) {
365
#if DEBUG_VERBOSE_LEVEL >= 1
366
          DEBUG_MSG("[MIDIO_FILE_P] ERROR invalid MIDI port format for parameter '%s %2d.D%d'\n", parameter, (sr/8)+1, 7-(sr%8));
367
#endif
368
        } else {
369
          u8 events[2];
370
          int i;
371
          for(i=0; i<2; ++i) {
372
        char *word = strtok_r(NULL, separators, &brkt);
373
        if( (events[i]=get_dec(word)) < 0 ) {
374
#if DEBUG_VERBOSE_LEVEL >= 1
375
          DEBUG_MSG("[MIDIO_FILE_P] ERROR invalid Event format for parameter '%s %2d.D%d'\n", parameter, (sr/8)+1, (7-sr%8));
376
#endif
377
          break;
378
        } else {
379
          events[i] &= 0x7f;
380
        }
381
          }
382
 
383
          if( i == 2 ) {
384
        // finally a valid line!
385
        sr ^= 7; // DOUT SR pins are mirrored
386
        midio_patch_dout_entry_t *dout_cfg = (midio_patch_dout_entry_t *)&midio_patch_dout[sr];
387
        dout_cfg->enabled_ports = enabled_ports;
388
        dout_cfg->evnt0 = events[0];
389
        dout_cfg->evnt1 = events[1];
390
          }
391
        }
392
 
393
      }  
394
    } else if( strcmp(parameter, "MergerMode") == 0 ) {
395
      u32 value;
396
      if( (value=get_dec(brkt)) < 0 ) {
397
#if DEBUG_VERBOSE_LEVEL >= 1
398
        DEBUG_MSG("[MIDIO_FILE_P] ERROR invalid format for parameter '%s'\n", parameter);
399
#endif
400
      } else {
401
        midio_patch_cfg.flags.MERGER_MODE = value;
402
      }
403
    } else if( strcmp(parameter, "ForwardIO") == 0 ) {
404
      u32 value;
405
      if( (value=get_dec(brkt)) < 0 ) {
406
#if DEBUG_VERBOSE_LEVEL >= 1
407
        DEBUG_MSG("[MIDIO_FILE_P] ERROR invalid format for parameter '%s'\n", parameter);
408
#endif
409
      } else {
410
        midio_patch_cfg.flags.FORWARD_IO = value;
411
      }
412
    } else if( strcmp(parameter, "InverseDIN") == 0 ) {
413
      u32 value;
414
      if( (value=get_dec(brkt)) < 0 ) {
415
#if DEBUG_VERBOSE_LEVEL >= 1
416
        DEBUG_MSG("[MIDIO_FILE_P] ERROR invalid format for parameter '%s'\n", parameter);
417
#endif
418
      } else {
419
        midio_patch_cfg.flags.INVERSE_DIN = value;
420
      }
421
    } else if( strcmp(parameter, "InverseDOUT") == 0 ) {
422
      u32 value;
423
      if( (value=get_dec(brkt)) < 0 ) {
424
#if DEBUG_VERBOSE_LEVEL >= 1
425
        DEBUG_MSG("[MIDIO_FILE_P] ERROR invalid format for parameter '%s'\n", parameter);
426
#endif
427
      } else {
428
        midio_patch_cfg.flags.INVERSE_DOUT = value;
429
      }
430
    } else if( strcmp(parameter, "AltProgramChange") == 0 ) {
431
      u32 value;
432
      if( (value=get_dec(brkt)) < 0 ) {
433
#if DEBUG_VERBOSE_LEVEL >= 1
434
        DEBUG_MSG("[MIDIO_FILE_P] ERROR invalid format for parameter '%s'\n", parameter);
435
#endif
436
      } else {
437
        midio_patch_cfg.flags.ALT_PROGCHNG = value;
438
      }
439
    } else if( strcmp(parameter, "DebounceCtr") == 0 ) {
440
      u32 value;
441
      if( (value=get_dec(brkt)) < 0 ) {
442
#if DEBUG_VERBOSE_LEVEL >= 1
443
        DEBUG_MSG("[MIDIO_FILE_P] ERROR invalid format for parameter '%s'\n", parameter);
444
#endif
445
      } else {
446
        midio_patch_cfg.debounce_ctr = value;
447
      }
448
    } else if( strcmp(parameter, "GlobalChannel") == 0 ) {
449
      u32 value;
450
      if( (value=get_dec(brkt)) < 0 ) {
451
#if DEBUG_VERBOSE_LEVEL >= 1
452
        DEBUG_MSG("[MIDIO_FILE_P] ERROR invalid format for parameter '%s'\n", parameter);
453
#endif
454
      } else {
455
        midio_patch_cfg.global_chn = value;
456
      }
457
    } else if( strcmp(parameter, "AllNotesOffChannel") == 0 ) {
458
      u32 value;
459
      if( (value=get_dec(brkt)) < 0 ) {
460
#if DEBUG_VERBOSE_LEVEL >= 1
461
        DEBUG_MSG("[MIDIO_FILE_P] ERROR invalid format for parameter '%s'\n", parameter);
462
#endif
463
      } else {
464
        midio_patch_cfg.all_notes_off_chn = value;
465
      }
466
 
1260 tk 467
#if !defined(MIOS32_FAMILY_EMULATION)
468
    } else if( strcmp(parameter, "ETH_LocalIp") == 0 ) {
469
      u32 value;
470
      if( !(value=get_ip(brkt)) ) {
471
#if DEBUG_VERBOSE_LEVEL >= 1
472
        DEBUG_MSG("[MIDIO_FILE_P] ERROR invalid IP format for parameter '%s'\n", parameter);
473
#endif
474
      } else {
475
        UIP_TASK_IP_AddressSet(value);
476
      }
477
    } else if( strcmp(parameter, "ETH_Netmask") == 0 ) {
478
      u32 value;
479
      if( !(value=get_ip(brkt)) ) {
480
#if DEBUG_VERBOSE_LEVEL >= 1
481
        DEBUG_MSG("[MIDIO_FILE_P] ERROR invalid IP format for parameter '%s'\n", parameter);
482
#endif
483
      } else {
484
        UIP_TASK_NetmaskSet(value);
485
      }
486
    } else if( strcmp(parameter, "ETH_Gateway") == 0 ) {
487
      u32 value;
488
      if( !(value=get_ip(brkt)) ) {
489
#if DEBUG_VERBOSE_LEVEL >= 1
490
        DEBUG_MSG("[MIDIO_FILE_P] ERROR invalid IP format for parameter '%s'\n", parameter);
491
#endif
492
      } else {
493
        UIP_TASK_GatewaySet(value);
494
      }
495
    } else {
496
      char *word = strtok_r(NULL, separators, &brkt);
497
      s32 value = get_dec(word);
498
 
499
      if( value < 0 ) {
500
#if DEBUG_VERBOSE_LEVEL >= 1
501
        DEBUG_MSG("[MIDIO_FILE_P] ERROR invalid value for parameter '%s'\n", parameter);
502
#endif
503
      } else if( strcmp(parameter, "ETH_Dhcp") == 0 ) {
504
        UIP_TASK_DHCP_EnableSet((value >= 1) ? 1 : 0);
505
      } else if( strcmp(parameter, "OSC_RemoteIp") == 0 ) {
506
        if( value > OSC_SERVER_NUM_CONNECTIONS ) {
507
          DEBUG_MSG("[MIDIO_FILE_P] ERROR invalid connection number for parameter '%s'\n", parameter);
508
        } else {
509
          u8 con = value;
510
          u32 ip;
511
          if( !(ip=get_ip(brkt)) ) {
512
#if DEBUG_VERBOSE_LEVEL >= 1
513
        DEBUG_MSG("[MIDIO_FILE_P] ERROR invalid IP format for parameter '%s'\n", parameter);
514
#endif
515
          } else {
516
        OSC_SERVER_RemoteIP_Set(con, ip);
517
          }
518
        }
519
      } else if( strcmp(parameter, "OSC_RemotePort") == 0 ) {
520
        if( value > OSC_SERVER_NUM_CONNECTIONS ) {
521
          DEBUG_MSG("[MIDIO_FILE_P] ERROR invalid connection number for parameter '%s'\n", parameter);
522
        } else {
523
          u8 con = value;
524
          word = strtok_r(NULL, separators, &brkt);
525
          if( (value=get_dec(word)) < 0 ) {
526
        DEBUG_MSG("[MIDIO_FILE_P] ERROR invalid port number for parameter '%s'\n", parameter);
527
          } else {
528
        OSC_SERVER_RemotePortSet(con, value);
529
          }
530
        }
531
      } else if( strcmp(parameter, "OSC_LocalPort") == 0 ) {
532
        if( value > OSC_SERVER_NUM_CONNECTIONS ) {
533
          DEBUG_MSG("[MIDIO_FILE_P] ERROR invalid connection number for parameter '%s'\n", parameter);
534
        } else {
535
          u8 con = value;
536
          word = strtok_r(NULL, separators, &brkt);
537
          if( (value=get_dec(word)) < 0 ) {
538
        DEBUG_MSG("[MIDIO_FILE_P] ERROR invalid port number for parameter '%s'\n", parameter);
539
          } else {
540
        OSC_SERVER_LocalPortSet(con, value);
541
          }
542
        }
543
#if 0
544
      } else if( strcmp(parameter, "OSC_TransferMode") == 0 ) {
545
        if( value > OSC_SERVER_NUM_CONNECTIONS ) {
546
          DEBUG_MSG("[MIDIO_FILE_P] ERROR invalid connection number for parameter '%s'\n", parameter);
547
        } else {
548
          u8 con = value;
549
          word = strtok_r(NULL, separators, &brkt);
550
          if( (value=get_dec(word)) < 0 ) {
551
        DEBUG_MSG("[MIDIO_FILE_P] ERROR invalid transfer mode number for parameter '%s'\n", parameter);
552
          } else {
553
        SEQ_MIDI_OSC_TransferModeSet(con, value);
554
          }
555
        }
556
#endif
557
#endif /* !defined(MIOS32_FAMILY_EMULATION) */
558
      } else {
559
#if DEBUG_VERBOSE_LEVEL >= 2
560
        // changed error level from 1 to 2 here, since people are sometimes confused about these messages
561
        // on file format changes
562
        DEBUG_MSG("[MIDIO_FILE_P] ERROR: unknown parameter: %s", line_buffer);
563
#endif
564
      }
565
    }
566
      } else {
567
#if DEBUG_VERBOSE_LEVEL >= 1
568
    DEBUG_MSG("[MIDIO_FILE_P] ERROR no space separator in following line: %s", line_buffer);
569
#endif
570
      }
571
    }
572
 
573
  } while( status >= 1 );
574
 
575
  // close file
1261 tk 576
  status |= FILE_ReadClose(&file);
1260 tk 577
 
578
#if !defined(MIOS32_FAMILY_EMULATION)
579
  // OSC_SERVER_Init(0) has to be called after all settings have been done!
580
  OSC_SERVER_Init(0);
581
#endif
582
 
583
  if( status < 0 ) {
584
#if DEBUG_VERBOSE_LEVEL >= 1
585
    DEBUG_MSG("[MIDIO_FILE_P] ERROR while reading file, status: %d\n", status);
586
#endif
587
    return MIDIO_FILE_P_ERR_READ;
588
  }
589
 
590
  // file is valid! :)
591
  info->valid = 1;
592
 
593
  return 0; // no error
594
}
595
 
596
 
597
/////////////////////////////////////////////////////////////////////////////
598
// help function to write data into file or send to debug terminal
599
// returns < 0 on errors (error codes are documented in seq_file.h)
600
/////////////////////////////////////////////////////////////////////////////
601
static s32 MIDIO_FILE_P_Write_Hlp(u8 write_to_file)
602
{
603
  s32 status = 0;
604
  char line_buffer[128];
605
 
1261 tk 606
#define FLUSH_BUFFER if( !write_to_file ) { DEBUG_MSG(line_buffer); } else { status |= FILE_WriteBuffer((u8 *)line_buffer, strlen(line_buffer)); }
1260 tk 607
 
1268 tk 608
  {
609
    //    SR/Pin MIDI OUT ports   mode     ON Event        OFF event
610
    // DIN  1.D0 1111111111111111   0   0x90 0x30 0x7F  0x90 0x30 0x00
611
    sprintf(line_buffer, "\n\n#  SR/Pin MIDI OUT ports   mode     ON Event        OFF event\n");
612
    FLUSH_BUFFER;
613
 
614
    int din;
615
    midio_patch_din_entry_t *din_cfg = (midio_patch_din_entry_t *)&midio_patch_din[0];
616
    for(din=0; din<MIDIO_PATCH_NUM_DIN; ++din, ++din_cfg) {
617
      char ports_bin[17];
618
      int bit;
619
      for(bit=0; bit<16; ++bit)
620
    ports_bin[bit] = (din_cfg->enabled_ports & (1 << bit)) ? '1' : '0';
621
      ports_bin[16] = 0;
622
 
623
      sprintf(line_buffer, "DIN %2d.D%d %s  %2d   0x%02X 0x%02X 0x%02X  0x%02x 0x%02x 0x%02x\n",
624
          (din / 8) + 1,
625
          din % 8,
626
          ports_bin,
627
          din_cfg->mode,
628
          din_cfg->evnt0_on | 0x80, din_cfg->evnt1_on, din_cfg->evnt2_on,
629
          din_cfg->evnt0_off | 0x80, din_cfg->evnt1_off, din_cfg->evnt2_off);
630
      FLUSH_BUFFER;
631
    }
632
  }
633
 
634
  {
635
    //     SR/Pin MIDI IN ports       Event
636
    // DOUT  1.D7 1111111111111111  0x90 0x30
637
    sprintf(line_buffer, "\n\n#   SR/Pin MIDI IN ports       Event\n");
638
    FLUSH_BUFFER;
639
 
640
    int dout;
641
    midio_patch_dout_entry_t *dout_cfg = (midio_patch_dout_entry_t *)&midio_patch_dout[0];
642
    for(dout=0; dout<MIDIO_PATCH_NUM_DOUT; ++dout, ++dout_cfg) {
643
      char ports_bin[17];
644
      int bit;
645
      for(bit=0; bit<16; ++bit)
646
    ports_bin[bit] = (dout_cfg->enabled_ports & (1 << bit)) ? '1' : '0';
647
      ports_bin[16] = 0;
648
 
649
      sprintf(line_buffer, "DOUT %2d.D%d %s  0x%02X 0x%02X\n",
650
          (dout / 8) + 1,
651
          7 - (dout % 8),
652
          ports_bin,
653
          dout_cfg->evnt0 | 0x80, dout_cfg->evnt1);
654
      FLUSH_BUFFER;
655
    }
656
  }
657
 
1260 tk 658
#if !defined(MIOS32_FAMILY_EMULATION)
1268 tk 659
  sprintf(line_buffer, "\n\n# Ethernet Setup\n");
660
  FLUSH_BUFFER;
1260 tk 661
  {
662
    u32 value = UIP_TASK_IP_AddressGet();
663
    sprintf(line_buffer, "ETH_LocalIp %d.%d.%d.%d\n",
664
        (value >> 24) & 0xff,
665
        (value >> 16) & 0xff,
666
        (value >>  8) & 0xff,
667
        (value >>  0) & 0xff);
668
    FLUSH_BUFFER;
669
  }
670
 
671
  {
672
    u32 value = UIP_TASK_NetmaskGet();
673
    sprintf(line_buffer, "ETH_Netmask %d.%d.%d.%d\n",
674
        (value >> 24) & 0xff,
675
        (value >> 16) & 0xff,
676
        (value >>  8) & 0xff,
677
        (value >>  0) & 0xff);
678
    FLUSH_BUFFER;
679
  }
680
 
681
  {
682
    u32 value = UIP_TASK_GatewayGet();
683
    sprintf(line_buffer, "ETH_Gateway %d.%d.%d.%d\n",
684
        (value >> 24) & 0xff,
685
        (value >> 16) & 0xff,
686
        (value >>  8) & 0xff,
687
        (value >>  0) & 0xff);
688
    FLUSH_BUFFER;
689
  }
690
 
691
  sprintf(line_buffer, "ETH_Dhcp %d\n", UIP_TASK_DHCP_EnableGet());
692
  FLUSH_BUFFER;
693
 
694
  int con;
695
  for(con=0; con<OSC_SERVER_NUM_CONNECTIONS; ++con) {
696
    u32 value = OSC_SERVER_RemoteIP_Get(con);
697
    sprintf(line_buffer, "OSC_RemoteIp %d %d.%d.%d.%d\n",
698
        con,
699
        (value >> 24) & 0xff,
700
        (value >> 16) & 0xff,
701
        (value >>  8) & 0xff,
702
        (value >>  0) & 0xff);
703
    FLUSH_BUFFER;
704
 
705
    sprintf(line_buffer, "OSC_RemotePort %d %d\n", con, OSC_SERVER_RemotePortGet(con));
706
    FLUSH_BUFFER;
707
 
708
    sprintf(line_buffer, "OSC_LocalPort %d %d\n", con, OSC_SERVER_LocalPortGet(con));
709
    FLUSH_BUFFER;
710
 
711
#if 0
712
    sprintf(line_buffer, "OSC_TransferMode %d %d\n", con, MIDIO_MIDI_OSC_TransferModeGet(con));
713
    FLUSH_BUFFER;
714
#endif
715
  }
716
#endif
717
 
1268 tk 718
  sprintf(line_buffer, "\n\n# Misc. Configuration\n");
719
  FLUSH_BUFFER;
720
 
721
  sprintf(line_buffer, "MergerMode %d\n", midio_patch_cfg.flags.MERGER_MODE);
722
  FLUSH_BUFFER;
723
  sprintf(line_buffer, "ForwardIO %d\n", midio_patch_cfg.flags.FORWARD_IO);
724
  FLUSH_BUFFER;
725
  sprintf(line_buffer, "InverseDIN %d\n", midio_patch_cfg.flags.INVERSE_DIN);
726
  FLUSH_BUFFER;
727
  sprintf(line_buffer, "InverseDOUT %d\n", midio_patch_cfg.flags.INVERSE_DOUT);
728
  FLUSH_BUFFER;
729
  sprintf(line_buffer, "AltProgramChange %d\n", midio_patch_cfg.flags.ALT_PROGCHNG);
730
  FLUSH_BUFFER;
731
  sprintf(line_buffer, "DebounceCtr %d\n", midio_patch_cfg.debounce_ctr);
732
  FLUSH_BUFFER;
733
  sprintf(line_buffer, "GlobalChannel %d\n", midio_patch_cfg.global_chn);
734
  FLUSH_BUFFER;
735
  sprintf(line_buffer, "AllNotesOffChannel %d\n", midio_patch_cfg.all_notes_off_chn);
736
  FLUSH_BUFFER;
737
 
738
 
1260 tk 739
  return status;
740
}
741
 
742
 
743
/////////////////////////////////////////////////////////////////////////////
1264 tk 744
// writes data into patch file
1260 tk 745
// returns < 0 on errors (error codes are documented in seq_file.h)
746
/////////////////////////////////////////////////////////////////////////////
1264 tk 747
s32 MIDIO_FILE_P_Write(char *filename)
1260 tk 748
{
749
  midio_file_p_info_t *info = &midio_file_p_info;
750
 
1264 tk 751
  // store current file name in global variable for UI
752
  memcpy(midio_file_p_patch_name, filename, MIDIO_FILE_P_FILENAME_LEN+1);
753
 
1260 tk 754
  char filepath[MAX_PATH];
1264 tk 755
  sprintf(filepath, "%s%s.MIO", MIDIO_FILES_PATH, midio_file_p_patch_name);
1260 tk 756
 
757
#if DEBUG_VERBOSE_LEVEL >= 2
1264 tk 758
  DEBUG_MSG("[MIDIO_FILE_P] Open patch '%s' for writing\n", filepath);
1260 tk 759
#endif
760
 
761
  s32 status = 0;
1261 tk 762
  if( (status=FILE_WriteOpen(filepath, 1)) < 0 ) {
1260 tk 763
#if DEBUG_VERBOSE_LEVEL >= 1
1264 tk 764
    DEBUG_MSG("[MIDIO_FILE_P] Failed to open/create patch file, status: %d\n", status);
1260 tk 765
#endif
1261 tk 766
    FILE_WriteClose(); // important to free memory given by malloc
1260 tk 767
    info->valid = 0;
768
    return status;
769
  }
770
 
771
  // write file
772
  status |= MIDIO_FILE_P_Write_Hlp(1);
773
 
774
  // close file
1261 tk 775
  status |= FILE_WriteClose();
1260 tk 776
 
777
 
778
  // check if file is valid
779
  if( status >= 0 )
780
    info->valid = 1;
781
 
782
#if DEBUG_VERBOSE_LEVEL >= 2
1264 tk 783
  DEBUG_MSG("[MIDIO_FILE_P] patch file written with status %d\n", status);
1260 tk 784
#endif
785
 
786
  return (status < 0) ? MIDIO_FILE_P_ERR_WRITE : 0;
787
 
788
}
789
 
790
/////////////////////////////////////////////////////////////////////////////
1264 tk 791
// sends patch data to debug terminal
1260 tk 792
// returns < 0 on errors
793
/////////////////////////////////////////////////////////////////////////////
794
s32 MIDIO_FILE_P_Debug(void)
795
{
796
  return MIDIO_FILE_P_Write_Hlp(0); // send to debug terminal
797
}