Subversion Repositories svn.mios32

Rev

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

Rev Author Line No. Line
1052 tk 1
// $Id: seq_file_gc.c 2098 2014-12-07 19:25:03Z tk $
2
/*
3
 * Global Config File access functions
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
 *
12
 *  Copyright (C) 2008 Thorsten Klose (tk@midibox.org)
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
 
1311 tk 28
#include <osc_client.h>
29
 
1261 tk 30
#include "file.h"
1052 tk 31
#include "seq_file.h"
32
#include "seq_file_gc.h"
33
#include "seq_file_b.h"
34
 
35
 
36
#include "seq_ui.h"
37
#include "seq_bpm.h"
38
#include "seq_song.h"
39
#include "seq_mixer.h"
40
#include "seq_midi_in.h"
1323 tk 41
#include "seq_midi_port.h"
1052 tk 42
#include "seq_midi_router.h"
1316 tk 43
#include "seq_midi_sysex.h"
1052 tk 44
#include "seq_pattern.h"
1754 tk 45
#include "seq_record.h"
1052 tk 46
#include "seq_core.h"
1083 tk 47
#include "seq_cv.h"
1316 tk 48
#include "seq_blm.h"
1864 tk 49
#include "seq_tpd.h"
1316 tk 50
 
1052 tk 51
#if !defined(MIOS32_FAMILY_EMULATION)
52
#include "uip.h"
53
#include "uip_task.h"
54
#include "osc_server.h"
55
#endif
56
 
57
 
58
/////////////////////////////////////////////////////////////////////////////
59
// for optional debugging messages via DEBUG_MSG (defined in mios32_config.h)
60
/////////////////////////////////////////////////////////////////////////////
61
 
62
// Note: verbose level 1 is default - it prints error messages!
63
#define DEBUG_VERBOSE_LEVEL 1
64
 
65
 
66
/////////////////////////////////////////////////////////////////////////////
67
// Local definitions
68
/////////////////////////////////////////////////////////////////////////////
69
 
70
// in which subdirectory of the SD card are the MBSEQ files located?
71
// use "/" for root
72
// use "/<dir>/" for a subdirectory in root
73
// use "/<dir>/<subdir>/" to reach a subdirectory in <dir>, etc..
74
 
75
#define SEQ_FILES_PATH "/"
76
//#define SEQ_FILES_PATH "/MySongs/"
77
 
78
 
79
/////////////////////////////////////////////////////////////////////////////
80
// Local types
81
/////////////////////////////////////////////////////////////////////////////
82
 
83
// file informations stored in RAM
84
typedef struct {
85
  unsigned valid: 1;   // file is accessible
86
} seq_file_gc_info_t;
87
 
88
 
89
/////////////////////////////////////////////////////////////////////////////
90
// Local prototypes
91
/////////////////////////////////////////////////////////////////////////////
92
 
93
 
94
/////////////////////////////////////////////////////////////////////////////
95
// Local variables
96
/////////////////////////////////////////////////////////////////////////////
97
 
98
static seq_file_gc_info_t seq_file_gc_info;
99
 
100
 
101
/////////////////////////////////////////////////////////////////////////////
102
// Initialisation
103
/////////////////////////////////////////////////////////////////////////////
104
s32 SEQ_FILE_GC_Init(u32 mode)
105
{
106
  // invalidate file info
107
  SEQ_FILE_GC_Unload();
108
 
109
  return 0; // no error
110
}
111
 
112
 
113
/////////////////////////////////////////////////////////////////////////////
114
// Loads global config file
115
// Called from SEQ_FILE_GCheckSDCard() when the SD card has been connected
116
// returns < 0 on errors
117
/////////////////////////////////////////////////////////////////////////////
118
s32 SEQ_FILE_GC_Load(void)
119
{
120
  s32 error;
121
  error = SEQ_FILE_GC_Read();
122
#if DEBUG_VERBOSE_LEVEL >= 2
123
  DEBUG_MSG("[SEQ_FILE_GC] Tried to open global config file, status: %d\n", error);
124
#endif
125
 
126
  return error;
127
}
128
 
129
 
130
/////////////////////////////////////////////////////////////////////////////
131
// Unloads global config file
132
// Called from SEQ_FILE_GCheckSDCard() when the SD card has been disconnected
133
// returns < 0 on errors
134
/////////////////////////////////////////////////////////////////////////////
135
s32 SEQ_FILE_GC_Unload(void)
136
{
137
  seq_file_gc_info.valid = 0;
138
 
139
  return 0; // no error
140
}
141
 
142
 
143
 
144
/////////////////////////////////////////////////////////////////////////////
145
// Returns 1 if global config file valid
146
// Returns 0 if global config file not valid
147
/////////////////////////////////////////////////////////////////////////////
148
s32 SEQ_FILE_GC_Valid(void)
149
{
150
  return seq_file_gc_info.valid;
151
}
152
 
153
 
154
/////////////////////////////////////////////////////////////////////////////
155
// help function which parses a decimal or hex value
156
// returns >= 0 if value is valid
157
// returns -1 if value is invalid
158
/////////////////////////////////////////////////////////////////////////////
159
static s32 get_dec(char *word)
160
{
161
  if( word == NULL )
162
    return -1;
163
 
164
  char *next;
165
  long l = strtol(word, &next, 0);
166
 
167
  if( word == next )
168
    return -1;
169
 
170
  return l; // value is valid
171
}
172
 
173
/////////////////////////////////////////////////////////////////////////////
174
// help function which parses an IP value
175
// returns > 0 if value is valid
176
// returns 0 if value is invalid
177
/////////////////////////////////////////////////////////////////////////////
178
static u32 get_ip(char *brkt)
179
{
180
  u8 ip[4];
181
  char *word;
182
 
183
  int i;
184
  for(i=0; i<4; ++i) {
1117 tk 185
    if( (word=strtok_r(NULL, ".", &brkt)) ) {
1052 tk 186
      s32 value = get_dec(word);
187
      if( value >= 0 && value <= 255 )
188
    ip[i] = value;
189
      else
190
    return 0;
191
    }
192
  }
193
 
194
  if( i == 4 )
195
    return (ip[0]<<24)|(ip[1]<<16)|(ip[2]<<8)|(ip[3]<<0);
196
  else
197
    return 0; // invalid IP
198
}
199
 
200
 
201
/////////////////////////////////////////////////////////////////////////////
202
// reads the global config file content (again)
203
// returns < 0 on errors (error codes are documented in seq_file.h)
204
/////////////////////////////////////////////////////////////////////////////
205
s32 SEQ_FILE_GC_Read(void)
206
{
207
  s32 status = 0;
208
  seq_file_gc_info_t *info = &seq_file_gc_info;
1261 tk 209
  file_t file;
1052 tk 210
 
211
  info->valid = 0; // will be set to valid if file content has been read successfully
212
 
213
  char filepath[MAX_PATH];
214
  sprintf(filepath, "%sMBSEQ_GC.V4", SEQ_FILES_PATH);
215
 
216
#if DEBUG_VERBOSE_LEVEL >= 2
217
  DEBUG_MSG("[SEQ_FILE_GC] Open global config file '%s'\n", filepath);
218
#endif
219
 
1261 tk 220
  if( (status=FILE_ReadOpen(&file, filepath)) < 0 ) {
1052 tk 221
#if DEBUG_VERBOSE_LEVEL >= 2
222
    DEBUG_MSG("[SEQ_FILE_GC] failed to open file, status: %d\n", status);
223
#endif
224
    return status;
225
  }
226
 
227
  // read global config values
228
  char line_buffer[128];
229
  do {
1261 tk 230
    status=FILE_ReadLine((u8 *)line_buffer, 128);
1052 tk 231
 
232
    if( status > 1 ) {
233
#if DEBUG_VERBOSE_LEVEL >= 3
234
      DEBUG_MSG("[SEQ_FILE_GC] read: %s", line_buffer);
235
#endif
236
 
237
      // sscanf consumes too much memory, therefore we parse directly
238
      char *separators = " \t";
239
      char *brkt;
240
      char *parameter;
241
 
242
      if( (parameter = strtok_r(line_buffer, separators, &brkt)) ) {
243
 
244
    if( *parameter == '#' ) {
245
      // ignore comments
246
#if !defined(MIOS32_FAMILY_EMULATION)
247
    } else if( strcmp(parameter, "ETH_LocalIp") == 0 ) {
248
      u32 value;
249
      if( !(value=get_ip(brkt)) ) {
250
#if DEBUG_VERBOSE_LEVEL >= 1
251
        DEBUG_MSG("[SEQ_FILE_GC] ERROR invalid IP format for parameter '%s'\n", parameter);
252
#endif
253
      } else {
254
        UIP_TASK_IP_AddressSet(value);
255
      }
256
    } else if( strcmp(parameter, "ETH_Netmask") == 0 ) {
257
      u32 value;
258
      if( !(value=get_ip(brkt)) ) {
259
#if DEBUG_VERBOSE_LEVEL >= 1
260
        DEBUG_MSG("[SEQ_FILE_GC] ERROR invalid IP format for parameter '%s'\n", parameter);
261
#endif
262
      } else {
263
        UIP_TASK_NetmaskSet(value);
264
      }
265
    } else if( strcmp(parameter, "ETH_Gateway") == 0 ) {
266
      u32 value;
267
      if( !(value=get_ip(brkt)) ) {
268
#if DEBUG_VERBOSE_LEVEL >= 1
269
        DEBUG_MSG("[SEQ_FILE_GC] ERROR invalid IP format for parameter '%s'\n", parameter);
270
#endif
271
      } else {
272
        UIP_TASK_GatewaySet(value);
273
      }
1083 tk 274
#endif /* !defined(MIOS32_FAMILY_EMULATION) */
1052 tk 275
    } else {
276
      char *word = strtok_r(NULL, separators, &brkt);
277
      s32 value = get_dec(word);
278
 
279
      if( value < 0 ) {
280
#if DEBUG_VERBOSE_LEVEL >= 1
281
        DEBUG_MSG("[SEQ_FILE_GC] ERROR invalid value for parameter '%s'\n", parameter);
282
#endif
283
      } else if( strcmp(parameter, "MetronomePort") == 0 ) {
284
        seq_core_metronome_port = (mios32_midi_port_t)value;
285
      } else if( strcmp(parameter, "MetronomeChannel") == 0 ) {
286
        seq_core_metronome_chn = value;
287
      } else if( strcmp(parameter, "MetronomeNoteM") == 0 ) {
288
        seq_core_metronome_note_m = value;
289
      } else if( strcmp(parameter, "MetronomeNoteB") == 0 ) {
290
        seq_core_metronome_note_b = value;
1754 tk 291
      } else if( strcmp(parameter, "RecQuantisation") == 0 ) {
292
        seq_record_quantize = value;
1075 tk 293
      } else if( strcmp(parameter, "PasteClrAll") == 0 ) {
294
        seq_core_options.PASTE_CLR_ALL = value;
1794 tk 295
      } else if( strcmp(parameter, "InitCC") == 0 ) {
296
        seq_core_options.INIT_CC = value;
1810 tk 297
      } else if( strcmp(parameter, "LiveLayerMuteSteps") == 0 ) {
298
        seq_core_options.LIVE_LAYER_MUTE_STEPS = value;
1794 tk 299
      } else if( strcmp(parameter, "PatternMixerMapCoupling") == 0 ) {
300
        seq_core_options.PATTERN_MIXER_MAP_COUPLING = value;
1323 tk 301
      } else if( strcmp(parameter, "MultiPortEnableFlags") == 0 ) {
302
        seq_midi_port_multi_enable_flags = value;
1052 tk 303
      } else if( strcmp(parameter, "RemoteMode") == 0 ) {
1316 tk 304
        seq_midi_sysex_remote_mode = (value > 2) ? 0 : value;
1052 tk 305
      } else if( strcmp(parameter, "RemotePort") == 0 ) {
1316 tk 306
        seq_midi_sysex_remote_port = value;
1052 tk 307
      } else if( strcmp(parameter, "RemoteID") == 0 ) {
1316 tk 308
        seq_midi_sysex_remote_id = (value > 128) ? 0 : value;
1083 tk 309
      } else if( strcmp(parameter, "CV_AOUT_Type") == 0 ) {
310
        SEQ_CV_IfSet(value);
311
      } else if( strcmp(parameter, "CV_PinMode") == 0 ) {
312
        u32 cv = value;
313
        if( cv >= SEQ_CV_NUM ) {
314
          DEBUG_MSG("[SEQ_FILE_GC] ERROR wrong CV channel %u for parameter '%s'\n", value);
315
        } else {
316
          word = strtok_r(NULL, separators, &brkt);
317
          u32 curve = get_dec(word);
318
          if( curve >= SEQ_CV_NUM_CURVES ) {
319
        DEBUG_MSG("[SEQ_FILE_GC] ERROR wrong curve %u for parameter '%s', CV channel %u\n", curve, cv);
320
          } else {
321
        word = strtok_r(NULL, separators, &brkt);
322
        u32 slewrate = get_dec(word);
323
        if( slewrate >= 256 ) // saturate
324
          slewrate = 255;
1052 tk 325
 
1083 tk 326
        word = strtok_r(NULL, separators, &brkt);
327
        u32 range = get_dec(word);
328
        if( range >= 127 ) // saturate
329
          range = 2; // default value
330
 
331
        SEQ_CV_CurveSet(cv, curve);
332
        SEQ_CV_SlewRateSet(cv, slewrate);
333
        SEQ_CV_PitchRangeSet(cv, range);
334
          }
335
        }
336
      } else if( strcmp(parameter, "CV_GateInv") == 0 ) {
337
        SEQ_CV_GateInversionAllSet(value);
338
      } else if( strcmp(parameter, "CV_ClkPulsewidth") == 0 ) {
2098 tk 339
        SEQ_CV_ClkPulseWidthSet(0, value); // Legacy Value - replaced by CV_ExtClk
1083 tk 340
      } else if( strcmp(parameter, "CV_ClkDivider") == 0 ) {
2098 tk 341
        SEQ_CV_ClkDividerSet(0, value); // Legacy Value - replaced by CV_ExtClk
342
      } else if( strcmp(parameter, "CV_ExtClk") == 0 ) {
343
        u32 clkout = value;
344
        if( clkout >= SEQ_CV_NUM_CLKOUT ) {
345
          DEBUG_MSG("[SEQ_FILE_GC] ERROR wrong clock output %u for parameter '%s'\n", value);
346
        } else {
347
          word = strtok_r(NULL, separators, &brkt);
348
          u32 divider = get_dec(word);
349
          if( divider >= 65536 ) {
350
        DEBUG_MSG("[SEQ_FILE_GC] ERROR wrong divider value %u for parameter '%s', clock output %u\n", divider, clkout);
351
          } else {
352
        word = strtok_r(NULL, separators, &brkt);
353
        u32 pulsewidth = get_dec(word);
354
        if( pulsewidth >= 256 ) // saturate
355
          pulsewidth = 255;
356
 
357
        SEQ_CV_ClkDividerSet(clkout, divider);
358
        SEQ_CV_ClkPulseWidthSet(clkout, pulsewidth);
359
          }
360
        }
1864 tk 361
      } else if( strcmp(parameter, "TpdMode") == 0 ) {
362
        SEQ_TPD_ModeSet(value);
1052 tk 363
      } else if( strcmp(parameter, "BLM_SCALAR_Port") == 0 ) {
364
        seq_blm_port = value;
365
 
366
        MUTEX_MIDIOUT_TAKE;
367
        SEQ_BLM_SYSEX_SendRequest(0x00); // request layout from BLM_SCALAR
368
        MUTEX_MIDIOUT_GIVE;
2020 tk 369
        seq_blm_timeout_ctr = 0; // fake timeout (so that "BLM not found" message will be displayed)
1052 tk 370
 
371
#if !defined(MIOS32_FAMILY_EMULATION)
2020 tk 372
      } else if( strcmp(parameter, "BLM_SCALAR_AlwaysUseFts") == 0 ) {
373
        seq_blm_options.ALWAYS_USE_FTS = value;
1052 tk 374
      } else if( strcmp(parameter, "ETH_Dhcp") == 0 ) {
375
        UIP_TASK_DHCP_EnableSet((value >= 1) ? 1 : 0);
1058 tk 376
      } else if( strcmp(parameter, "OSC_RemoteIp") == 0 ) {
377
        if( value > OSC_SERVER_NUM_CONNECTIONS ) {
378
          DEBUG_MSG("[SEQ_FILE_GC] ERROR invalid connection number for parameter '%s'\n", parameter);
379
        } else {
380
          u8 con = value;
381
          u32 ip;
382
          if( !(ip=get_ip(brkt)) ) {
383
#if DEBUG_VERBOSE_LEVEL >= 1
384
        DEBUG_MSG("[SEQ_FILE_GC] ERROR invalid IP format for parameter '%s'\n", parameter);
385
#endif
386
          } else {
387
        OSC_SERVER_RemoteIP_Set(con, ip);
388
          }
389
        }
1052 tk 390
      } else if( strcmp(parameter, "OSC_RemotePort") == 0 ) {
1058 tk 391
        if( value > OSC_SERVER_NUM_CONNECTIONS ) {
392
          DEBUG_MSG("[SEQ_FILE_GC] ERROR invalid connection number for parameter '%s'\n", parameter);
393
        } else {
394
          u8 con = value;
395
          word = strtok_r(NULL, separators, &brkt);
396
          if( (value=get_dec(word)) < 0 ) {
397
        DEBUG_MSG("[SEQ_FILE_GC] ERROR invalid port number for parameter '%s'\n", parameter);
398
          } else {
399
        OSC_SERVER_RemotePortSet(con, value);
400
          }
401
        }
1052 tk 402
      } else if( strcmp(parameter, "OSC_LocalPort") == 0 ) {
1058 tk 403
        if( value > OSC_SERVER_NUM_CONNECTIONS ) {
404
          DEBUG_MSG("[SEQ_FILE_GC] ERROR invalid connection number for parameter '%s'\n", parameter);
405
        } else {
406
          u8 con = value;
407
          word = strtok_r(NULL, separators, &brkt);
408
          if( (value=get_dec(word)) < 0 ) {
409
        DEBUG_MSG("[SEQ_FILE_GC] ERROR invalid port number for parameter '%s'\n", parameter);
410
          } else {
411
        OSC_SERVER_LocalPortSet(con, value);
412
          }
413
        }
414
      } else if( strcmp(parameter, "OSC_TransferMode") == 0 ) {
415
        if( value > OSC_SERVER_NUM_CONNECTIONS ) {
416
          DEBUG_MSG("[SEQ_FILE_GC] ERROR invalid connection number for parameter '%s'\n", parameter);
417
        } else {
418
          u8 con = value;
419
          word = strtok_r(NULL, separators, &brkt);
420
          if( (value=get_dec(word)) < 0 ) {
421
        DEBUG_MSG("[SEQ_FILE_GC] ERROR invalid transfer mode number for parameter '%s'\n", parameter);
422
          } else {
1311 tk 423
        OSC_CLIENT_TransferModeSet(con, value);
1058 tk 424
          }
425
        }
1052 tk 426
#endif
427
      } else {
428
#if DEBUG_VERBOSE_LEVEL >= 2
429
        // changed error level from 1 to 2 here, since people are sometimes confused about these messages
430
        // on file format changes
431
        DEBUG_MSG("[SEQ_FILE_GC] ERROR: unknown parameter: %s", line_buffer);
432
#endif
433
      }
434
    }
435
      } else {
436
#if DEBUG_VERBOSE_LEVEL >= 1
437
    DEBUG_MSG("[SEQ_FILE_GC] ERROR no space separator in following line: %s", line_buffer);
438
#endif
439
      }
440
    }
441
 
442
  } while( status >= 1 );
443
 
444
  // close file
1261 tk 445
  status |= FILE_ReadClose(&file);
1052 tk 446
 
1058 tk 447
#if !defined(MIOS32_FAMILY_EMULATION)
448
  // OSC_SERVER_Init(0) has to be called after all settings have been done!
449
  OSC_SERVER_Init(0);
450
#endif
451
 
1052 tk 452
  if( status < 0 ) {
453
#if DEBUG_VERBOSE_LEVEL >= 1
454
    DEBUG_MSG("[SEQ_FILE_GC] ERROR while reading file, status: %d\n", status);
455
#endif
456
    return SEQ_FILE_GC_ERR_READ;
457
  }
458
 
459
  // file is valid! :)
460
  info->valid = 1;
461
 
462
  // change tempo to given preset
463
  SEQ_CORE_BPM_Update(seq_core_bpm_preset_tempo[seq_core_bpm_preset_num], seq_core_bpm_preset_ramp[seq_core_bpm_preset_num]);
464
 
465
  return 0; // no error
466
}
467
 
468
 
469
/////////////////////////////////////////////////////////////////////////////
470
// help function to write data into file or send to debug terminal
471
// returns < 0 on errors (error codes are documented in seq_file.h)
472
/////////////////////////////////////////////////////////////////////////////
473
static s32 SEQ_FILE_GC_Write_Hlp(u8 write_to_file)
474
{
475
  s32 status = 0;
476
  char line_buffer[128];
477
 
1261 tk 478
#define FLUSH_BUFFER if( !write_to_file ) { DEBUG_MSG(line_buffer); } else { status |= FILE_WriteBuffer((u8 *)line_buffer, strlen(line_buffer)); }
1052 tk 479
 
480
  // write global config values
481
  sprintf(line_buffer, "MetronomePort %d\n", (u8)seq_core_metronome_port);
482
  FLUSH_BUFFER;
483
 
484
  sprintf(line_buffer, "MetronomeChannel %d\n", (u8)seq_core_metronome_chn);
485
  FLUSH_BUFFER;
486
 
487
  sprintf(line_buffer, "MetronomeNoteM %d\n", (u8)seq_core_metronome_note_m);
488
  FLUSH_BUFFER;
489
 
490
  sprintf(line_buffer, "MetronomeNoteB %d\n", (u8)seq_core_metronome_note_b);
491
  FLUSH_BUFFER;
492
 
1754 tk 493
  sprintf(line_buffer, "RecQuantisation %d\n", (u8)seq_record_quantize);
494
  FLUSH_BUFFER;
495
 
1075 tk 496
  sprintf(line_buffer, "PasteClrAll %d\n", seq_core_options.PASTE_CLR_ALL);
497
  FLUSH_BUFFER;
498
 
1794 tk 499
  sprintf(line_buffer, "InitCC %d\n", seq_core_options.INIT_CC);
500
  FLUSH_BUFFER;
501
 
1810 tk 502
  sprintf(line_buffer, "LiveLayerMuteSteps %d\n", seq_core_options.LIVE_LAYER_MUTE_STEPS);
503
  FLUSH_BUFFER;
504
 
1794 tk 505
  sprintf(line_buffer, "PatternMixerMapCoupling %d\n", seq_core_options.PATTERN_MIXER_MAP_COUPLING);
506
  FLUSH_BUFFER;
507
 
1323 tk 508
  sprintf(line_buffer, "MultiPortEnableFlags 0x%06x\n", seq_midi_port_multi_enable_flags);
509
  FLUSH_BUFFER;
510
 
1316 tk 511
  sprintf(line_buffer, "RemoteMode %d\n", (u8)seq_midi_sysex_remote_mode);
1052 tk 512
  FLUSH_BUFFER;
513
 
1316 tk 514
  sprintf(line_buffer, "RemotePort %d\n", (u8)seq_midi_sysex_remote_port);
1052 tk 515
  FLUSH_BUFFER;
516
 
1316 tk 517
  sprintf(line_buffer, "RemoteID %d\n", (u8)seq_midi_sysex_remote_id);
1052 tk 518
  FLUSH_BUFFER;
519
 
1083 tk 520
  sprintf(line_buffer, "CV_AOUT_Type %d\n", (u8)SEQ_CV_IfGet());
521
  FLUSH_BUFFER;
522
 
2098 tk 523
  {
524
    int cv;
525
    for(cv=0; cv<SEQ_CV_NUM; ++cv) {
526
      sprintf(line_buffer, "CV_PinMode %d %d %d %d\n", cv, SEQ_CV_CurveGet(cv), (int)SEQ_CV_SlewRateGet(cv), (int)SEQ_CV_PitchRangeGet(cv));
527
      FLUSH_BUFFER;
528
    }
1083 tk 529
  }
530
 
531
  sprintf(line_buffer, "CV_GateInv 0x%02x\n", (u8)SEQ_CV_GateInversionAllGet());
532
  FLUSH_BUFFER;
533
 
2098 tk 534
  {
535
    int clkout;
1083 tk 536
 
2098 tk 537
    for(clkout=0; clkout<SEQ_CV_NUM_CLKOUT; ++clkout) {
538
      sprintf(line_buffer, "CV_ExtClk %d %d %d\n", clkout, SEQ_CV_ClkDividerGet(clkout), SEQ_CV_ClkPulseWidthGet(clkout));
539
      FLUSH_BUFFER;
540
    }
541
  }
1083 tk 542
 
1864 tk 543
  sprintf(line_buffer, "TpdMode %d\n", SEQ_TPD_ModeGet());
544
  FLUSH_BUFFER;
545
 
1052 tk 546
  sprintf(line_buffer, "BLM_SCALAR_Port %d\n", (u8)seq_blm_port);
547
  FLUSH_BUFFER;
548
 
2020 tk 549
  sprintf(line_buffer, "BLM_SCALAR_AlwaysUseFts %d\n", (u8)seq_blm_options.ALWAYS_USE_FTS);
550
  FLUSH_BUFFER;
551
 
1052 tk 552
#if !defined(MIOS32_FAMILY_EMULATION)
553
  {
554
    u32 value = UIP_TASK_IP_AddressGet();
555
    sprintf(line_buffer, "ETH_LocalIp %d.%d.%d.%d\n",
556
        (value >> 24) & 0xff,
557
        (value >> 16) & 0xff,
558
        (value >>  8) & 0xff,
559
        (value >>  0) & 0xff);
560
    FLUSH_BUFFER;
561
  }
562
 
563
  {
564
    u32 value = UIP_TASK_NetmaskGet();
565
    sprintf(line_buffer, "ETH_Netmask %d.%d.%d.%d\n",
566
        (value >> 24) & 0xff,
567
        (value >> 16) & 0xff,
568
        (value >>  8) & 0xff,
569
        (value >>  0) & 0xff);
570
    FLUSH_BUFFER;
571
  }
572
 
573
  {
574
    u32 value = UIP_TASK_GatewayGet();
575
    sprintf(line_buffer, "ETH_Gateway %d.%d.%d.%d\n",
576
        (value >> 24) & 0xff,
577
        (value >> 16) & 0xff,
578
        (value >>  8) & 0xff,
579
        (value >>  0) & 0xff);
580
    FLUSH_BUFFER;
581
  }
582
 
583
  sprintf(line_buffer, "ETH_Dhcp %d\n", UIP_TASK_DHCP_EnableGet());
584
  FLUSH_BUFFER;
585
 
1058 tk 586
  int con;
587
  for(con=0; con<OSC_SERVER_NUM_CONNECTIONS; ++con) {
588
    u32 value = OSC_SERVER_RemoteIP_Get(con);
589
    sprintf(line_buffer, "OSC_RemoteIp %d %d.%d.%d.%d\n",
590
        con,
1052 tk 591
        (value >> 24) & 0xff,
592
        (value >> 16) & 0xff,
593
        (value >>  8) & 0xff,
594
        (value >>  0) & 0xff);
595
    FLUSH_BUFFER;
596
 
1058 tk 597
    sprintf(line_buffer, "OSC_RemotePort %d %d\n", con, OSC_SERVER_RemotePortGet(con));
598
    FLUSH_BUFFER;
1052 tk 599
 
1058 tk 600
    sprintf(line_buffer, "OSC_LocalPort %d %d\n", con, OSC_SERVER_LocalPortGet(con));
601
    FLUSH_BUFFER;
1052 tk 602
 
1311 tk 603
    sprintf(line_buffer, "OSC_TransferMode %d %d\n", con, OSC_CLIENT_TransferModeGet(con));
1058 tk 604
    FLUSH_BUFFER;
605
  }
606
 
1052 tk 607
#endif
608
 
609
  return status;
610
}
611
 
612
 
613
/////////////////////////////////////////////////////////////////////////////
614
// writes data into global config file
615
// returns < 0 on errors (error codes are documented in seq_file.h)
616
/////////////////////////////////////////////////////////////////////////////
617
s32 SEQ_FILE_GC_Write(void)
618
{
619
  seq_file_gc_info_t *info = &seq_file_gc_info;
620
 
621
  char filepath[MAX_PATH];
622
  sprintf(filepath, "%sMBSEQ_GC.V4", SEQ_FILES_PATH);
623
 
624
#if DEBUG_VERBOSE_LEVEL >= 2
625
  DEBUG_MSG("[SEQ_FILE_GC] Open global config file '%s' for writing\n", filepath);
626
#endif
627
 
628
  s32 status = 0;
1261 tk 629
  if( (status=FILE_WriteOpen(filepath, 1)) < 0 ) {
1052 tk 630
#if DEBUG_VERBOSE_LEVEL >= 1
631
    DEBUG_MSG("[SEQ_FILE_GC] Failed to open/create global config file, status: %d\n", status);
632
#endif
1261 tk 633
    FILE_WriteClose(); // important to free memory given by malloc
1052 tk 634
    info->valid = 0;
635
    return status;
636
  }
637
 
638
  // write file
639
  status |= SEQ_FILE_GC_Write_Hlp(1);
640
 
641
  // close file
1261 tk 642
  status |= FILE_WriteClose();
1052 tk 643
 
644
 
645
  // check if file is valid
646
  if( status >= 0 )
647
    info->valid = 1;
648
 
649
#if DEBUG_VERBOSE_LEVEL >= 2
650
  DEBUG_MSG("[SEQ_FILE_GC] global config file written with status %d\n", status);
651
#endif
652
 
653
  return (status < 0) ? SEQ_FILE_GC_ERR_WRITE : 0;
654
 
655
}
656
 
657
/////////////////////////////////////////////////////////////////////////////
658
// sends global config data to debug terminal
659
// returns < 0 on errors
660
/////////////////////////////////////////////////////////////////////////////
661
s32 SEQ_FILE_GC_Debug(void)
662
{
663
  return SEQ_FILE_GC_Write_Hlp(0); // send to debug terminal
664
}