Subversion Repositories svn.mios32

Rev

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

Rev Author Line No. Line
492 tk 1
// $Id: seq_file_hw.c 2098 2014-12-07 19:25:03Z tk $
2
/*
3
 * Hardware Soft-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
 
956 tk 25
#include <ff.h>
492 tk 26
#include <string.h>
507 tk 27
#include <aout.h>
1117 tk 28
#include <seq_cv.h>
524 tk 29
#include <blm.h>
513 tk 30
#include <blm_x.h>
492 tk 31
 
1261 tk 32
#include "file.h"
492 tk 33
#include "seq_file.h"
34
#include "seq_file_hw.h"
35
 
36
#include "seq_hwcfg.h"
37
 
784 tk 38
#include "seq_ui.h"
2039 tk 39
#include "seq_ui_pages.h"
1713 tk 40
#include "seq_midi_port.h"
492 tk 41
 
784 tk 42
 
492 tk 43
/////////////////////////////////////////////////////////////////////////////
44
// for optional debugging messages via DEBUG_MSG (defined in mios32_config.h)
45
/////////////////////////////////////////////////////////////////////////////
46
 
47
// Note: verbose level 1 is default - it prints error messages!
48
#define DEBUG_VERBOSE_LEVEL 1
49
 
50
 
51
/////////////////////////////////////////////////////////////////////////////
52
// Local definitions
53
/////////////////////////////////////////////////////////////////////////////
54
 
55
// in which subdirectory of the SD card are the MBSEQ files located?
956 tk 56
// use "/" for root
57
// use "/<dir>/" for a subdirectory in root
58
// use "/<dir>/<subdir>/" to reach a subdirectory in <dir>, etc..
492 tk 59
 
956 tk 60
#define SEQ_FILES_PATH "/"
61
//#define SEQ_FILES_PATH "/MySongs/"
492 tk 62
 
63
 
64
/////////////////////////////////////////////////////////////////////////////
65
// Local types
66
/////////////////////////////////////////////////////////////////////////////
67
 
68
// file informations stored in RAM
69
typedef struct {
70
  unsigned valid:1;
496 tk 71
  unsigned config_locked: 1;   // file is only loaded after startup
492 tk 72
} seq_file_hw_info_t;
73
 
74
 
75
/////////////////////////////////////////////////////////////////////////////
76
// Local prototypes
77
/////////////////////////////////////////////////////////////////////////////
78
 
79
 
80
/////////////////////////////////////////////////////////////////////////////
81
// Local variables
82
/////////////////////////////////////////////////////////////////////////////
83
 
84
static seq_file_hw_info_t seq_file_hw_info;
85
 
86
 
87
/////////////////////////////////////////////////////////////////////////////
88
// Initialisation
89
/////////////////////////////////////////////////////////////////////////////
90
s32 SEQ_FILE_HW_Init(u32 mode)
91
{
92
  SEQ_FILE_HW_Unload();
93
 
496 tk 94
  seq_file_hw_info.config_locked = 0;
492 tk 95
 
96
  return 0; // no error
97
}
98
 
99
/////////////////////////////////////////////////////////////////////////////
100
// Loads hardware config file
101
// Called from SEQ_FILE_HWheckSDCard() when the SD card has been connected
102
// returns < 0 on errors
103
/////////////////////////////////////////////////////////////////////////////
104
s32 SEQ_FILE_HW_Load(void)
105
{
106
  s32 error = 0;
107
 
496 tk 108
  if( seq_file_hw_info.config_locked ) {
492 tk 109
#if DEBUG_VERBOSE_LEVEL >= 2
110
    DEBUG_MSG("[SEQ_FILE_HW] HW config file not loaded again\n");
111
#endif
112
  } else {
113
    error = SEQ_FILE_HW_Read();
114
#if DEBUG_VERBOSE_LEVEL >= 2
115
    DEBUG_MSG("[SEQ_FILE_HW] Tried to open HW config file, status: %d\n", error);
116
#endif
496 tk 117
    seq_file_hw_info.config_locked = 1;
492 tk 118
  }
119
 
120
  return error;
121
}
122
 
123
 
124
/////////////////////////////////////////////////////////////////////////////
125
// Unloads config file
126
// Called from SEQ_FILE_HWheckSDCard() when the SD card has been disconnected
127
// returns < 0 on errors
128
/////////////////////////////////////////////////////////////////////////////
129
s32 SEQ_FILE_HW_Unload(void)
130
{
131
  seq_file_hw_info.valid = 0;
132
 
133
  return 0; // no error
134
}
135
 
136
 
137
 
138
/////////////////////////////////////////////////////////////////////////////
139
// Returns 1 if config file valid
140
// Returns 0 if config file not valid
141
/////////////////////////////////////////////////////////////////////////////
142
s32 SEQ_FILE_HW_Valid(void)
143
{
144
  return seq_file_hw_info.valid;
145
}
146
 
147
 
496 tk 148
/////////////////////////////////////////////////////////////////////////////
149
// Returns 1 if config has been read and is locked (no change anymore)
150
// Returns 0 if config hasn't been read yet (Button/Encoder/LED functions should be disabled)
151
/////////////////////////////////////////////////////////////////////////////
152
s32 SEQ_FILE_HW_ConfigLocked(void)
153
{
154
  return seq_file_hw_info.config_locked;
155
}
492 tk 156
 
496 tk 157
 
492 tk 158
/////////////////////////////////////////////////////////////////////////////
496 tk 159
// Returns 1 if config has been read and is locked (no change anymore)
160
// Returns 0 if config hasn't been read yet (Button/Encoder/LED functions should be disabled)
161
/////////////////////////////////////////////////////////////////////////////
162
s32 SEQ_FILE_HW_LockConfig(void)
163
{
164
  seq_file_hw_info.config_locked = 1;
690 tk 165
 
166
  return 0; // no error
496 tk 167
}
168
 
169
 
170
 
171
 
172
/////////////////////////////////////////////////////////////////////////////
173
// help function which parses a decimal or hex value
174
// returns >= 0 if value is valid
175
// returns -1 if value is invalid
176
/////////////////////////////////////////////////////////////////////////////
177
static s32 get_dec(char *word)
178
{
179
  if( word == NULL )
180
    return -1;
181
 
182
  char *next;
183
  long l = strtol(word, &next, 0);
184
 
185
  if( word == next )
186
    return -1;
187
 
188
  return l; // value is valid
189
}
190
 
191
 
192
/////////////////////////////////////////////////////////////////////////////
492 tk 193
// reads the hardware config file content
194
// returns < 0 on errors (error codes are documented in seq_file.h)
195
/////////////////////////////////////////////////////////////////////////////
196
s32 SEQ_FILE_HW_Read(void)
197
{
198
  s32 status = 0;
199
  seq_file_hw_info_t *info = &seq_file_hw_info;
1261 tk 200
  file_t file;
492 tk 201
 
202
  info->valid = 0; // will be set to valid if file content has been read successfully
203
 
204
  char filepath[MAX_PATH];
205
  sprintf(filepath, "%sMBSEQ_HW.V4", SEQ_FILES_PATH);
206
 
207
#if DEBUG_VERBOSE_LEVEL >= 2
208
  DEBUG_MSG("[SEQ_FILE_HW] Open config file '%s'\n", filepath);
209
#endif
210
 
1261 tk 211
  if( (status=FILE_ReadOpen(&file, filepath)) < 0 ) {
492 tk 212
#if DEBUG_VERBOSE_LEVEL >= 2
213
    DEBUG_MSG("[SEQ_FILE_HW] failed to open file, status: %d\n", status);
214
#endif
215
    return status;
216
  }
217
 
218
  // read config values
766 tk 219
  char line_buffer[128];
492 tk 220
  do {
1261 tk 221
    status=FILE_ReadLine((u8 *)line_buffer, 80);
492 tk 222
 
223
    if( status > 1 ) {
224
#if DEBUG_VERBOSE_LEVEL >= 3
225
      DEBUG_MSG("[SEQ_FILE_HW] read: %s", line_buffer);
226
#endif
227
 
228
      // sscanf consumes too much memory, therefore we parse directly
496 tk 229
      char *separators = " \t";
230
      char *brkt;
231
      char *parameter;
507 tk 232
      int hlp;
492 tk 233
 
690 tk 234
      if( (parameter = strtok_r(line_buffer, separators, &brkt)) ) {
492 tk 235
 
496 tk 236
    ////////////////////////////////////////////////////////////////////////////////////////////
237
    // ignore comments
238
    ////////////////////////////////////////////////////////////////////////////////////////////
239
    if( *parameter == '#' ) {
492 tk 240
 
496 tk 241
 
242
    ////////////////////////////////////////////////////////////////////////////////////////////
2039 tk 243
    // MENU_SHORTCUT
244
    ////////////////////////////////////////////////////////////////////////////////////////////
245
    } else if( strcasecmp(parameter, "MENU_SHORTCUT") == 0 ) {
246
      char *word = strtok_r(NULL, separators, &brkt);
247
      s32 pos = get_dec(word);
248
      if( pos < 1 || pos > 16 ) {
249
#if DEBUG_VERBOSE_LEVEL >= 1
250
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in MENU_SHORTCUT definition: invalid value '%s'!", word);
251
#endif
252
        continue;
253
      }
254
 
255
      word = strtok_r(NULL, separators, &brkt);
256
      if( word == NULL ) {
257
#if DEBUG_VERBOSE_LEVEL >= 1
258
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in MENU_SHORTCUT definition: expecting page name for GP%d!", pos);
259
#endif
260
        continue;
261
      }
262
 
263
      seq_ui_page_t page = SEQ_UI_PAGES_CfgNameSearch(word);
264
      if( page == SEQ_UI_PAGE_NONE ) {
265
#if DEBUG_VERBOSE_LEVEL >= 1
266
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in MENU_SHORTCUT definition: page name '%s' defined for GP%d doesn't exist!", word, pos);
267
#endif
268
        continue;
269
      }
270
 
271
      SEQ_UI_PAGES_MenuShortcutPageSet(pos-1, page);
272
 
273
    ////////////////////////////////////////////////////////////////////////////////////////////
513 tk 274
    // BUTTON_BEH
275
    ////////////////////////////////////////////////////////////////////////////////////////////
2039 tk 276
    } else if( strncasecmp(parameter, "BUTTON_BEH_", 11) == 0 ) {
513 tk 277
      parameter += 11;
278
 
279
      char *word = strtok_r(NULL, separators, &brkt);
280
      s32 flag = get_dec(word);
281
      if( flag < 0 || flag > 1 ) {
282
#if DEBUG_VERBOSE_LEVEL >= 1
283
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in BUTTON_BEH_%s definition: expecting 0 or 1, got '%s'!", parameter, word);
284
#endif
285
        continue;
286
      }
287
 
2039 tk 288
      if( strcasecmp(parameter, "FAST2") == 0 ) {
1121 tk 289
        seq_hwcfg_button_beh.fast2 = flag;
2039 tk 290
      } else if( strcasecmp(parameter, "FAST") == 0 ) {
513 tk 291
        seq_hwcfg_button_beh.fast = flag;
2039 tk 292
      } else if( strcasecmp(parameter, "ALL") == 0 ) {
513 tk 293
        seq_hwcfg_button_beh.all = flag;
2039 tk 294
      } else if( strcasecmp(parameter, "SOLO") == 0 ) {
513 tk 295
        seq_hwcfg_button_beh.solo = flag;
2039 tk 296
      } else if( strcasecmp(parameter, "METRONOME") == 0 ) {
513 tk 297
        seq_hwcfg_button_beh.metronome = flag;
2039 tk 298
      } else if( strcasecmp(parameter, "SCRUB") == 0 ) {
513 tk 299
        seq_hwcfg_button_beh.scrub = flag;
2039 tk 300
      } else if( strcasecmp(parameter, "LOOP") == 0 ) {
599 tk 301
        seq_hwcfg_button_beh.loop = flag;
2039 tk 302
      } else if( strcasecmp(parameter, "FOLLOW") == 0 ) {
951 tk 303
        seq_hwcfg_button_beh.follow = flag;
2039 tk 304
      } else if( strcasecmp(parameter, "MENU") == 0 ) {
513 tk 305
        seq_hwcfg_button_beh.menu = flag;
2039 tk 306
      } else if( strcasecmp(parameter, "BOOKMARK") == 0 ) {
1203 tk 307
        seq_hwcfg_button_beh.bookmark = flag;
2039 tk 308
      } else if( strcasecmp(parameter, "STEP_VIEW") == 0 ) {
513 tk 309
        seq_hwcfg_button_beh.step_view = flag;
2039 tk 310
      } else if( strcasecmp(parameter, "TRG_LAYER") == 0 ) {
513 tk 311
        seq_hwcfg_button_beh.trg_layer = flag;
2039 tk 312
      } else if( strcasecmp(parameter, "PAR_LAYER") == 0 ) {
513 tk 313
        seq_hwcfg_button_beh.par_layer = flag;
2039 tk 314
      } else if( strcasecmp(parameter, "TRACK_SEL") == 0 ) {
513 tk 315
        seq_hwcfg_button_beh.track_sel = flag;
2039 tk 316
      } else if( strcasecmp(parameter, "TEMPO_PRESET") == 0 ) {
513 tk 317
        seq_hwcfg_button_beh.tempo_preset = flag;
2039 tk 318
      } else if( strcasecmp(parameter, "ALL_WITH_TRIGGERS") == 0 ) {
607 tk 319
        seq_hwcfg_button_beh.all_with_triggers = flag;
513 tk 320
      } else {
321
#if DEBUG_VERBOSE_LEVEL >= 1
322
        DEBUG_MSG("[SEQ_FILE_HW] ERROR: unknown button behaviour function 'BUTTON_BEH_%s'!", parameter);
323
#endif
324
      }
325
 
326
 
327
    ////////////////////////////////////////////////////////////////////////////////////////////
496 tk 328
    // BUTTON_
329
    ////////////////////////////////////////////////////////////////////////////////////////////
2039 tk 330
    } else if( strncasecmp(parameter, "BUTTON_", 7) == 0 ) {
496 tk 331
      parameter += 7;
332
 
333
      char *word = strtok_r(NULL, separators, &brkt);
1864 tk 334
 
335
      // M1..M8 -> SR 24..31
336
      s32 sr = -1;
337
      u8 blm8x8_selected = 0;
338
      if( word[0] == 'M' ) {
339
        blm8x8_selected = 1;
340
        ++word;
341
        s32 m = get_dec(word);
342
 
343
        if( m < 1 || m > 8 ) {
492 tk 344
#if DEBUG_VERBOSE_LEVEL >= 1
1864 tk 345
          DEBUG_MSG("[SEQ_FILE_HW] ERROR in BUTTON_%s definition: invalid SR value 'M%s'!", parameter, word);
492 tk 346
#endif
1864 tk 347
          continue;
348
        }
349
        sr = 24 + m-1;
350
      } else {
351
        sr = get_dec(word);
352
        if( sr < 0 || sr > 32 ) {
353
#if DEBUG_VERBOSE_LEVEL >= 1
354
          DEBUG_MSG("[SEQ_FILE_HW] ERROR in BUTTON_%s definition: invalid SR value '%s'!", parameter, word);
355
#endif
356
          continue;
357
        }
492 tk 358
      }
359
 
496 tk 360
      word = strtok_r(NULL, separators, &brkt);
361
      s32 pin = get_dec(word);
362
      if( pin < 0 || pin >= 8 ) {
492 tk 363
#if DEBUG_VERBOSE_LEVEL >= 1
513 tk 364
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in BUTTON_%s definition: invalid pin value '%s'!", parameter, word);
492 tk 365
#endif
366
        continue;
367
      }
368
 
369
      u8 din_value = ((sr-1)<<3) | pin;
496 tk 370
 
1864 tk 371
      // compatibility with old configurations: if SRIO_NUM_SR hasn't been set to 23 (so that it's still 16)
372
      // then map DIN SR 17..24 to 24..31
373
      if( !blm8x8_selected && MIOS32_SRIO_ScanNumGet() <= 16 && din_value >= 128 && din_value < 192 ) {
374
        din_value += 56;
375
      }
376
 
492 tk 377
#if DEBUG_VERBOSE_LEVEL >= 3
378
      DEBUG_MSG("[SEQ_FILE_HW] Button %s: SR %d Pin %d (DIN: 0x%02x)", line_buffer, sr, pin, din_value);
379
#endif
380
 
2039 tk 381
      if( strcasecmp(parameter, "DOWN") == 0 ) {
492 tk 382
        seq_hwcfg_button.down = din_value;
2039 tk 383
      } else if( strcasecmp(parameter, "UP") == 0 ) {
492 tk 384
        seq_hwcfg_button.up = din_value;
2039 tk 385
      } else if( strcasecmp(parameter, "LEFT") == 0 ) {
492 tk 386
        seq_hwcfg_button.left = din_value;
2039 tk 387
      } else if( strcasecmp(parameter, "RIGHT") == 0 ) {
492 tk 388
        seq_hwcfg_button.right = din_value;
2039 tk 389
      } else if( strcasecmp(parameter, "SCRUB") == 0 ) {
492 tk 390
        seq_hwcfg_button.scrub = din_value;
2039 tk 391
      } else if( strcasecmp(parameter, "LOOP") == 0 ) {
599 tk 392
        seq_hwcfg_button.loop = din_value;
2039 tk 393
      } else if( strcasecmp(parameter, "FOLLOW") == 0 ) {
951 tk 394
        seq_hwcfg_button.follow = din_value;
2039 tk 395
      } else if( strcasecmp(parameter, "METRONOME") == 0 ) {
492 tk 396
        seq_hwcfg_button.metronome = din_value;
2039 tk 397
      } else if( strcasecmp(parameter, "RECORD") == 0 ) {
630 tk 398
        seq_hwcfg_button.record = din_value;
2039 tk 399
      } else if( strcasecmp(parameter, "LIVE") == 0 ) {
1219 tk 400
        seq_hwcfg_button.live = din_value;
2039 tk 401
      } else if( strcasecmp(parameter, "STOP") == 0 ) {
492 tk 402
        seq_hwcfg_button.stop = din_value;
2039 tk 403
      } else if( strcasecmp(parameter, "PAUSE") == 0 ) {
492 tk 404
        seq_hwcfg_button.pause = din_value;
2039 tk 405
      } else if( strcasecmp(parameter, "PLAY") == 0 ) {
492 tk 406
        seq_hwcfg_button.play = din_value;
2039 tk 407
      } else if( strcasecmp(parameter, "REW") == 0 ) {
492 tk 408
        seq_hwcfg_button.rew = din_value;
2039 tk 409
      } else if( strcasecmp(parameter, "FWD") == 0 ) {
492 tk 410
        seq_hwcfg_button.fwd = din_value;
2039 tk 411
      } else if( strcasecmp(parameter, "MENU") == 0 ) {
492 tk 412
        seq_hwcfg_button.menu = din_value;
2039 tk 413
      } else if( strcasecmp(parameter, "BOOKMARK") == 0 ) {
1203 tk 414
        seq_hwcfg_button.bookmark = din_value;
2039 tk 415
      } else if( strcasecmp(parameter, "SELECT") == 0 ) {
492 tk 416
        seq_hwcfg_button.select = din_value;
2039 tk 417
      } else if( strcasecmp(parameter, "EXIT") == 0 ) {
492 tk 418
        seq_hwcfg_button.exit = din_value;
2039 tk 419
      } else if( strncasecmp(parameter, "TRACK", 5) == 0 && // TRACK[1234]
496 tk 420
             (hlp=parameter[5]-'1') >= 0 && hlp < 4 ) {
421
        seq_hwcfg_button.track[hlp] = din_value;
2039 tk 422
      } else if( strncasecmp(parameter, "PAR_LAYER_", 10) == 0 && // PAR_LAYER_[ABC]
496 tk 423
             (hlp=parameter[10]-'A') >= 0 && hlp < 3 ) {
424
        seq_hwcfg_button.par_layer[hlp] = din_value;
2039 tk 425
      } else if( strcasecmp(parameter, "EDIT") == 0 ) {
492 tk 426
        seq_hwcfg_button.edit = din_value;
2039 tk 427
      } else if( strcasecmp(parameter, "MUTE") == 0 ) {
492 tk 428
        seq_hwcfg_button.mute = din_value;
2039 tk 429
      } else if( strcasecmp(parameter, "PATTERN") == 0 ) {
492 tk 430
        seq_hwcfg_button.pattern = din_value;
2039 tk 431
      } else if( strcasecmp(parameter, "SONG") == 0 ) {
492 tk 432
        seq_hwcfg_button.song = din_value;
2039 tk 433
      } else if( strcasecmp(parameter, "SOLO") == 0 ) {
492 tk 434
        seq_hwcfg_button.solo = din_value;
2039 tk 435
      } else if( strcasecmp(parameter, "FAST2") == 0 ) {
1121 tk 436
        seq_hwcfg_button.fast2 = din_value;
2039 tk 437
      } else if( strcasecmp(parameter, "FAST") == 0 ) {
492 tk 438
        seq_hwcfg_button.fast = din_value;
2039 tk 439
      } else if( strcasecmp(parameter, "ALL") == 0 ) {
492 tk 440
        seq_hwcfg_button.all = din_value;
2039 tk 441
      } else if( strncasecmp(parameter, "GP", 2) == 0 && // GP%d
496 tk 442
             (hlp=atoi(parameter+2)) >= 1 && hlp <= 16 ) {
443
        seq_hwcfg_button.gp[hlp-1] = din_value;
2039 tk 444
      } else if( strncasecmp(parameter, "GROUP", 5) == 0 && // GROUP[1234]
496 tk 445
             (hlp=parameter[5]-'1') >= 0 && hlp < 4 ) {
446
        seq_hwcfg_button.group[hlp] = din_value;
2039 tk 447
      } else if( strncasecmp(parameter, "TRG_LAYER_", 10) == 0 && // TRG_LAYER_[ABC]
496 tk 448
             (hlp=parameter[10]-'A') >= 0 && hlp < 3 ) {
449
        seq_hwcfg_button.trg_layer[hlp] = din_value;
2039 tk 450
      } else if( strcasecmp(parameter, "STEP_VIEW") == 0 ) {
492 tk 451
        seq_hwcfg_button.step_view = din_value;
2039 tk 452
      } else if( strcasecmp(parameter, "TRG_LAYER_SEL") == 0 ) {
513 tk 453
        seq_hwcfg_button.trg_layer_sel = din_value;
2039 tk 454
      } else if( strcasecmp(parameter, "PAR_LAYER_SEL") == 0 ) {
513 tk 455
        seq_hwcfg_button.par_layer_sel = din_value;
2039 tk 456
      } else if( strcasecmp(parameter, "TRACK_SEL") == 0 ) {
513 tk 457
        seq_hwcfg_button.track_sel = din_value;
2039 tk 458
      } else if( strcasecmp(parameter, "TAP_TEMPO") == 0 ) {
492 tk 459
        seq_hwcfg_button.tap_tempo = din_value;
2039 tk 460
      } else if( strcasecmp(parameter, "TEMPO_PRESET") == 0 ) {
513 tk 461
        seq_hwcfg_button.tempo_preset = din_value;
2039 tk 462
      } else if( strcasecmp(parameter, "EXT_RESTART") == 0 ) {
524 tk 463
        seq_hwcfg_button.ext_restart = din_value;
2039 tk 464
      } else if( strcasecmp(parameter, "UTILITY") == 0 ) {
492 tk 465
        seq_hwcfg_button.utility = din_value;
2039 tk 466
      } else if( strcasecmp(parameter, "COPY") == 0 ) {
492 tk 467
        seq_hwcfg_button.copy = din_value;
2039 tk 468
      } else if( strcasecmp(parameter, "PASTE") == 0 ) {
492 tk 469
        seq_hwcfg_button.paste = din_value;
2039 tk 470
      } else if( strcasecmp(parameter, "CLEAR") == 0 ) {
492 tk 471
        seq_hwcfg_button.clear = din_value;
2039 tk 472
      } else if( strcasecmp(parameter, "UNDO") == 0 ) {
1014 tk 473
        seq_hwcfg_button.undo = din_value;
2039 tk 474
      } else if( strcasecmp(parameter, "MIXER") == 0 ) {
544 tk 475
        seq_hwcfg_button.mixer = din_value;
2039 tk 476
      } else if( strcasecmp(parameter, "SAVE") == 0 ) {
1787 tk 477
        seq_hwcfg_button.save = din_value;
2039 tk 478
      } else if( strcasecmp(parameter, "SAVE_ALL") == 0 ) {
1787 tk 479
        seq_hwcfg_button.save_all = din_value;
2039 tk 480
      } else if( strcasecmp(parameter, "TRACK_MODE") == 0 ) {
1119 tk 481
        seq_hwcfg_button.track_mode = din_value;
2039 tk 482
      } else if( strcasecmp(parameter, "TRACK_GROOVE") == 0 ) {
1119 tk 483
        seq_hwcfg_button.track_groove = din_value;
2039 tk 484
      } else if( strcasecmp(parameter, "TRACK_LENGTH") == 0 ) {
1119 tk 485
        seq_hwcfg_button.track_length = din_value;
2039 tk 486
      } else if( strcasecmp(parameter, "TRACK_DIRECTION") == 0 ) {
1119 tk 487
        seq_hwcfg_button.track_direction = din_value;
2039 tk 488
      } else if( strcasecmp(parameter, "MORPH") == 0 || strcasecmp(parameter, "TRACK_MORPH") == 0 ) {
1119 tk 489
        seq_hwcfg_button.track_morph = din_value;
2039 tk 490
      } else if( strcasecmp(parameter, "TRANSPOSE") == 0 || strcasecmp(parameter, "TRACK_TRANSPOSE") == 0 ) {
1119 tk 491
        seq_hwcfg_button.track_transpose = din_value;
2039 tk 492
      } else if( strcasecmp(parameter, "FOOTSWITCH") == 0 ) {
1349 tk 493
        seq_hwcfg_button.footswitch = din_value;
2039 tk 494
          } else if( strcasecmp(parameter, "PATTERN_RMX") == 0 ) {
1454 midilab 495
            seq_hwcfg_button.pattern_remix = din_value;
2039 tk 496
          } else if( strcasecmp(parameter, "MUTE_ALL_TRACKS") == 0 ) {
1811 tk 497
            seq_hwcfg_button.mute_all_tracks = din_value;
2039 tk 498
          } else if( strcasecmp(parameter, "MUTE_TRACK_LAYERS") == 0 ) {
1811 tk 499
            seq_hwcfg_button.mute_track_layers = din_value;
2039 tk 500
          } else if( strcasecmp(parameter, "MUTE_ALL_TRACKS_AND_LAYERS") == 0 ) {
1811 tk 501
            seq_hwcfg_button.mute_all_tracks_and_layers = din_value;
2039 tk 502
          } else if( strcasecmp(parameter, "UNMUTE_ALL_TRACKS") == 0 ) {
1811 tk 503
            seq_hwcfg_button.unmute_all_tracks = din_value;
2039 tk 504
          } else if( strcasecmp(parameter, "UNMUTE_TRACK_LAYERS") == 0 ) {
1811 tk 505
            seq_hwcfg_button.unmute_track_layers = din_value;
2039 tk 506
          } else if( strcasecmp(parameter, "UNMUTE_ALL_TRACKS_AND_LAYERS") == 0 ) {
1811 tk 507
            seq_hwcfg_button.unmute_all_tracks_and_layers = din_value;
2039 tk 508
      } else if( strncasecmp(parameter, "DIRECT_BOOKMARK", 15) == 0 ) {
1205 tk 509
        parameter += 15;
510
 
511
        s32 bookmark = get_dec(parameter);
512
        if( bookmark < 1 || bookmark > SEQ_HWCFG_NUM_DIRECT_BOOKMARK ) {
513
#if DEBUG_VERBOSE_LEVEL >= 1
514
          DEBUG_MSG("[SEQ_FILE_HW] ERROR in BUTTON_DIRECT_BOOKMARK%s definition: invalid track number '%s'!", parameter, parameter);
515
#endif
516
          continue;
517
        }
518
        seq_hwcfg_button.direct_bookmark[bookmark-1] = din_value;
2039 tk 519
      } else if( strncasecmp(parameter, "DIRECT_TRACK", 12) == 0 ) {
1164 tk 520
        parameter += 12;
521
 
522
        s32 track = get_dec(parameter);
1205 tk 523
        if( track < 1 || track > SEQ_HWCFG_NUM_DIRECT_TRACK ) {
1164 tk 524
#if DEBUG_VERBOSE_LEVEL >= 1
525
          DEBUG_MSG("[SEQ_FILE_HW] ERROR in BUTTON_DIRECT_TRACK%s definition: invalid track number '%s'!", parameter, parameter);
526
#endif
527
          continue;
528
        }
1173 tk 529
        seq_hwcfg_button.direct_track[track-1] = din_value;
492 tk 530
      } else {
531
#if DEBUG_VERBOSE_LEVEL >= 1
496 tk 532
        DEBUG_MSG("[SEQ_FILE_HW] ERROR: unknown button function 'BUTTON_%s'!", parameter);
492 tk 533
#endif
534
      }
535
 
496 tk 536
    ////////////////////////////////////////////////////////////////////////////////////////////
537
    // LED_
538
    ////////////////////////////////////////////////////////////////////////////////////////////
2039 tk 539
    } else if( strncasecmp(parameter, "LED_", 4) == 0 ) {
496 tk 540
      parameter += 4;
492 tk 541
 
496 tk 542
      char *word = strtok_r(NULL, separators, &brkt);
1864 tk 543
 
544
      // M1..M8 -> SR 24..31
545
      s32 sr = -1;
546
      u8 blm8x8_selected = 0;
547
      if( word[0] == 'M' ) {
548
        blm8x8_selected = 1;
549
        ++word;
550
        s32 m = get_dec(word);
551
 
552
        if( m < 1 || m > 8 ) {
492 tk 553
#if DEBUG_VERBOSE_LEVEL >= 1
1864 tk 554
          DEBUG_MSG("[SEQ_FILE_HW] ERROR in LED_%s definition: invalid SR value 'M%s'!", parameter, word);
492 tk 555
#endif
1864 tk 556
          continue;
557
        }
558
        sr = 24 + m-1;
559
      } else {
560
        sr = get_dec(word);
561
        if( sr < 0 || sr > 32 ) {
562
#if DEBUG_VERBOSE_LEVEL >= 1
563
          DEBUG_MSG("[SEQ_FILE_HW] ERROR in LED_%s definition: invalid SR value '%s'!", parameter, word);
564
#endif
565
          continue;
566
        }
492 tk 567
      }
568
 
496 tk 569
      word = strtok_r(NULL, separators, &brkt);
570
      s32 pin = get_dec(word);
571
      if( pin < 0 || pin >= 8 ) {
492 tk 572
#if DEBUG_VERBOSE_LEVEL >= 1
513 tk 573
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in LED_%s definition: invalid pin value '%s'!", parameter, word);
492 tk 574
#endif
575
        continue;
576
      }
577
 
578
      u8 dout_value = ((sr-1)<<3) | pin;
1864 tk 579
 
580
      // compatibility with old configurations: if SRIO_NUM_SR hasn't been set to 23 (so that it's still 16)
581
      // then map DOUT SR 17..24 to 24..31
582
      if( !blm8x8_selected && MIOS32_SRIO_ScanNumGet() <= 16 && dout_value >= 128 && dout_value < 192 ) {
583
        dout_value += 56;
584
      }
585
 
492 tk 586
#if DEBUG_VERBOSE_LEVEL >= 3
496 tk 587
      DEBUG_MSG("[SEQ_FILE_HW] LED %s: SR %d Pin %d (DOUT: 0x%02x)", parameter, sr, pin, dout_value);
492 tk 588
#endif
589
 
2039 tk 590
      if( strncasecmp(parameter, "TRACK", 5) == 0 && // TRACK[1234]
496 tk 591
             (hlp=parameter[5]-'1') >= 0 && hlp < 4 ) {
592
        seq_hwcfg_led.track[hlp] = dout_value;
2039 tk 593
      } else if( strncasecmp(parameter, "PAR_LAYER_", 10) == 0 && // PAR_LAYER_[ABC]
496 tk 594
             (hlp=parameter[10]-'A') >= 0 && hlp < 3 ) {
595
        seq_hwcfg_led.par_layer[hlp] = dout_value;
2039 tk 596
      } else if( strcasecmp(parameter, "BEAT") == 0 ) {
492 tk 597
        seq_hwcfg_led.beat = dout_value;
2039 tk 598
      } else if( strcasecmp(parameter, "MIDI_IN_COMBINED") == 0 ) {
1336 tk 599
        seq_hwcfg_led.midi_in_combined = dout_value;
2039 tk 600
      } else if( strcasecmp(parameter, "MIDI_OUT_COMBINED") == 0 ) {
1336 tk 601
        seq_hwcfg_led.midi_out_combined = dout_value;
2039 tk 602
      } else if( strcasecmp(parameter, "EDIT") == 0 ) {
492 tk 603
        seq_hwcfg_led.edit = dout_value;
2039 tk 604
      } else if( strcasecmp(parameter, "MUTE") == 0 ) {
492 tk 605
        seq_hwcfg_led.mute = dout_value;
2039 tk 606
      } else if( strcasecmp(parameter, "PATTERN") == 0 ) {
492 tk 607
        seq_hwcfg_led.pattern = dout_value;
2039 tk 608
      } else if( strcasecmp(parameter, "SONG") == 0 ) {
492 tk 609
        seq_hwcfg_led.song = dout_value;
2039 tk 610
      } else if( strcasecmp(parameter, "SOLO") == 0 ) {
492 tk 611
        seq_hwcfg_led.solo = dout_value;
2039 tk 612
      } else if( strcasecmp(parameter, "FAST2") == 0 ) {
1121 tk 613
        seq_hwcfg_led.fast2 = dout_value;
2039 tk 614
      } else if( strcasecmp(parameter, "FAST") == 0 ) {
492 tk 615
        seq_hwcfg_led.fast = dout_value;
2039 tk 616
      } else if( strcasecmp(parameter, "ALL") == 0 ) {
492 tk 617
        seq_hwcfg_led.all = dout_value;
2039 tk 618
      } else if( strncasecmp(parameter, "GROUP", 5) == 0 && // GROUP[1234]
496 tk 619
             (hlp=parameter[5]-'1') >= 0 && hlp < 4 ) {
620
        seq_hwcfg_led.group[hlp] = dout_value;
2039 tk 621
      } else if( strncasecmp(parameter, "TRG_LAYER_", 10) == 0 && // TRG_LAYER_[ABC]
496 tk 622
             (hlp=parameter[10]-'A') >= 0 && hlp < 3 ) {
623
        seq_hwcfg_led.trg_layer[hlp] = dout_value;
2039 tk 624
      } else if( strcasecmp(parameter, "PLAY") == 0 ) {
492 tk 625
        seq_hwcfg_led.play = dout_value;
2039 tk 626
      } else if( strcasecmp(parameter, "STOP") == 0 ) {
492 tk 627
        seq_hwcfg_led.stop = dout_value;
2039 tk 628
      } else if( strcasecmp(parameter, "PAUSE") == 0 ) {
492 tk 629
        seq_hwcfg_led.pause = dout_value;
2039 tk 630
      } else if( strcasecmp(parameter, "REW") == 0 ) {
492 tk 631
        seq_hwcfg_led.rew = dout_value;
2039 tk 632
      } else if( strcasecmp(parameter, "FWD") == 0 ) {
492 tk 633
        seq_hwcfg_led.fwd = dout_value;
2039 tk 634
      } else if( strcasecmp(parameter, "EXIT") == 0 ) {
591 tk 635
        seq_hwcfg_led.exit = dout_value;
2039 tk 636
      } else if( strcasecmp(parameter, "SELECT") == 0 ) {
591 tk 637
        seq_hwcfg_led.select = dout_value;
2039 tk 638
      } else if( strcasecmp(parameter, "MENU") == 0 ) {
492 tk 639
        seq_hwcfg_led.menu = dout_value;
2039 tk 640
      } else if( strcasecmp(parameter, "BOOKMARK") == 0 ) {
1203 tk 641
        seq_hwcfg_led.bookmark = dout_value;
2039 tk 642
      } else if( strcasecmp(parameter, "SCRUB") == 0 ) {
492 tk 643
        seq_hwcfg_led.scrub = dout_value;
2039 tk 644
      } else if( strcasecmp(parameter, "LOOP") == 0 ) {
599 tk 645
        seq_hwcfg_led.loop = dout_value;
2039 tk 646
      } else if( strcasecmp(parameter, "FOLLOW") == 0 ) {
951 tk 647
        seq_hwcfg_led.follow = dout_value;
2039 tk 648
      } else if( strcasecmp(parameter, "METRONOME") == 0 ) {
492 tk 649
        seq_hwcfg_led.metronome = dout_value;
2039 tk 650
      } else if( strcasecmp(parameter, "RECORD") == 0 ) {
630 tk 651
        seq_hwcfg_led.record = dout_value;
2039 tk 652
      } else if( strcasecmp(parameter, "LIVE") == 0 ) {
1219 tk 653
        seq_hwcfg_led.live = dout_value;
2039 tk 654
      } else if( strcasecmp(parameter, "UTILITY") == 0 ) {
492 tk 655
        seq_hwcfg_led.utility = dout_value;
2039 tk 656
      } else if( strcasecmp(parameter, "COPY") == 0 ) {
492 tk 657
        seq_hwcfg_led.copy = dout_value;
2039 tk 658
      } else if( strcasecmp(parameter, "PASTE") == 0 ) {
492 tk 659
        seq_hwcfg_led.paste = dout_value;
2039 tk 660
      } else if( strcasecmp(parameter, "CLEAR") == 0 ) {
492 tk 661
        seq_hwcfg_led.clear = dout_value;
2039 tk 662
      } else if( strcasecmp(parameter, "UNDO") == 0 ) {
1014 tk 663
        seq_hwcfg_led.undo = dout_value;
2039 tk 664
      } else if( strcasecmp(parameter, "STEP_VIEW") == 0 ) {
492 tk 665
        seq_hwcfg_led.step_view = dout_value;
2039 tk 666
      } else if( strcasecmp(parameter, "TRG_LAYER_SEL") == 0 ) {
513 tk 667
        seq_hwcfg_led.trg_layer_sel = dout_value;
2039 tk 668
      } else if( strcasecmp(parameter, "PAR_LAYER_SEL") == 0 ) {
513 tk 669
        seq_hwcfg_led.par_layer_sel = dout_value;
2039 tk 670
      } else if( strcasecmp(parameter, "TRACK_SEL") == 0 ) {
513 tk 671
        seq_hwcfg_led.track_sel = dout_value;
2039 tk 672
      } else if( strcasecmp(parameter, "TAP_TEMPO") == 0 ) {
513 tk 673
        seq_hwcfg_led.tap_tempo = dout_value;
2039 tk 674
      } else if( strcasecmp(parameter, "TEMPO_PRESET") == 0 ) {
513 tk 675
        seq_hwcfg_led.tempo_preset = dout_value;
2039 tk 676
      } else if( strcasecmp(parameter, "EXT_RESTART") == 0 ) {
524 tk 677
        seq_hwcfg_led.ext_restart = dout_value;
2039 tk 678
      } else if( strcasecmp(parameter, "DOWN") == 0 ) {
492 tk 679
        seq_hwcfg_led.down = dout_value;
2039 tk 680
      } else if( strcasecmp(parameter, "UP") == 0 ) {
492 tk 681
        seq_hwcfg_led.up = dout_value;
2039 tk 682
      } else if( strcasecmp(parameter, "MIXER") == 0 ) {
743 tk 683
        seq_hwcfg_led.mixer = dout_value;
2039 tk 684
      } else if( strcasecmp(parameter, "TRACK_MODE") == 0 ) {
1119 tk 685
        seq_hwcfg_led.track_mode = dout_value;
2039 tk 686
      } else if( strcasecmp(parameter, "TRACK_GROOVE") == 0 ) {
1119 tk 687
        seq_hwcfg_led.track_groove = dout_value;
2039 tk 688
      } else if( strcasecmp(parameter, "TRACK_LENGTH") == 0 ) {
1119 tk 689
        seq_hwcfg_led.track_length = dout_value;
2039 tk 690
      } else if( strcasecmp(parameter, "TRACK_DIRECTION") == 0 ) {
1119 tk 691
        seq_hwcfg_led.track_direction = dout_value;
2039 tk 692
      } else if( strcasecmp(parameter, "MORPH") == 0 || strcasecmp(parameter, "TRACK_MORPH") == 0 ) {
1119 tk 693
        seq_hwcfg_led.track_morph = dout_value;
2039 tk 694
      } else if( strcasecmp(parameter, "TRANSPOSE") == 0 || strcasecmp(parameter, "TRACK_TRANSPOSE") == 0 ) {
1119 tk 695
        seq_hwcfg_led.track_transpose = dout_value;
2039 tk 696
          } else if( strcasecmp(parameter, "MUTE_ALL_TRACKS") == 0 ) {
1811 tk 697
            seq_hwcfg_led.mute_all_tracks = dout_value;
2039 tk 698
          } else if( strcasecmp(parameter, "MUTE_TRACK_LAYERS") == 0 ) {
1811 tk 699
            seq_hwcfg_led.mute_track_layers = dout_value;
2039 tk 700
          } else if( strcasecmp(parameter, "MUTE_ALL_TRACKS_AND_LAYERS") == 0 ) {
1811 tk 701
            seq_hwcfg_led.mute_all_tracks_and_layers = dout_value;
2039 tk 702
          } else if( strcasecmp(parameter, "UNMUTE_ALL_TRACKS") == 0 ) {
1811 tk 703
            seq_hwcfg_led.unmute_all_tracks = dout_value;
2039 tk 704
          } else if( strcasecmp(parameter, "UNMUTE_TRACK_LAYERS") == 0 ) {
1811 tk 705
            seq_hwcfg_led.unmute_track_layers = dout_value;
2039 tk 706
          } else if( strcasecmp(parameter, "UNMUTE_ALL_TRACKS_AND_LAYERS") == 0 ) {
1811 tk 707
            seq_hwcfg_led.unmute_all_tracks_and_layers = dout_value;
492 tk 708
      } else {
709
#if DEBUG_VERBOSE_LEVEL >= 1
496 tk 710
        DEBUG_MSG("[SEQ_FILE_HW] ERROR: unknown LED function 'LED_%s'!", parameter);
492 tk 711
#endif
712
      }
713
 
714
 
496 tk 715
    ////////////////////////////////////////////////////////////////////////////////////////////
716
    // ENC_
717
    ////////////////////////////////////////////////////////////////////////////////////////////
2039 tk 718
    } else if( strncasecmp(parameter, "ENC_", 4) == 0 ) {
496 tk 719
      parameter += 4;
720
 
721
      char *word = strtok_r(NULL, separators, &brkt);
722
      s32 sr = get_dec(word);
1864 tk 723
      if( sr < 0 || sr > MIOS32_SRIO_NUM_SR ) {
492 tk 724
#if DEBUG_VERBOSE_LEVEL >= 1
513 tk 725
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in ENC_%s definition: invalid first value '%s'!", parameter, word);
492 tk 726
#endif
727
        continue;
728
      }
729
 
2039 tk 730
      if( strcasecmp(parameter, "DATAWHEEL_FAST_SPEED") == 0 ) {
513 tk 731
        seq_hwcfg_enc.datawheel_fast_speed = sr;
732
        continue;
733
      }
2039 tk 734
      if( strcasecmp(parameter, "BPM_FAST_SPEED") == 0 ) {
1341 tk 735
        seq_hwcfg_enc.bpm_fast_speed = sr;
736
        continue;
737
      }
2039 tk 738
      if( strcasecmp(parameter, "GP_FAST_SPEED") == 0 ) {
513 tk 739
        seq_hwcfg_enc.gp_fast_speed = sr;
740
        continue;
741
      }
2039 tk 742
      if( strcasecmp(parameter, "AUTO_FAST") == 0 ) {
513 tk 743
        seq_hwcfg_enc.auto_fast = sr;
744
        continue;
745
      }
746
 
496 tk 747
      word = strtok_r(NULL, separators, &brkt);
748
      s32 pin = get_dec(word);
749
      if( pin < 0 || pin >= 8 ) { // should we check for odd pin values (1/3/5/7) as well?
492 tk 750
#if DEBUG_VERBOSE_LEVEL >= 1
513 tk 751
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in ENC_%s definition: invalid pin value '%s'!", parameter, word);
492 tk 752
#endif
753
        continue;
754
      }
755
 
496 tk 756
      word = strtok_r(NULL, separators, &brkt);
492 tk 757
      mios32_enc_type_t enc_type = DISABLED;
496 tk 758
      if( word == NULL ) {
492 tk 759
#if DEBUG_VERBOSE_LEVEL >= 1
496 tk 760
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in ENC_%s definition: missing encoder type!", parameter);
492 tk 761
#endif
762
        continue;
2039 tk 763
      } else if( strcasecmp(word, "NON_DETENTED") == 0 ) {
492 tk 764
        enc_type = NON_DETENTED;
2039 tk 765
      } else if( strcasecmp(word, "DETENTED1") == 0 ) {
492 tk 766
        enc_type = DETENTED1;
2039 tk 767
      } else if( strcasecmp(word, "DETENTED2") == 0 ) {
492 tk 768
        enc_type = DETENTED2;
2039 tk 769
      } else if( strcasecmp(word, "DETENTED3") == 0 ) {
492 tk 770
        enc_type = DETENTED3;
771
      } else {
772
#if DEBUG_VERBOSE_LEVEL >= 1
496 tk 773
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in ENC_%s definition: invalid type '%s'!", parameter, word);
492 tk 774
#endif
775
        continue;
776
      }
777
 
778
#if DEBUG_VERBOSE_LEVEL >= 3
496 tk 779
      DEBUG_MSG("[SEQ_FILE_HW] ENC %s: SR %d Pin %d Type %d", parameter, sr, pin, enc_type);
492 tk 780
#endif
781
 
782
      mios32_enc_config_t enc_config = { .cfg.type=enc_type, .cfg.speed=NORMAL, .cfg.speed_par=0, .cfg.sr=sr, .cfg.pos=pin };
783
 
2039 tk 784
      if( strcasecmp(parameter, "DATAWHEEL") == 0 ) {
492 tk 785
        MIOS32_ENC_ConfigSet(0, enc_config);
2039 tk 786
      } else if( strcasecmp(parameter, "BPM") == 0 ) {
1341 tk 787
        MIOS32_ENC_ConfigSet(17, enc_config);
2039 tk 788
      } else if( strncasecmp(parameter, "GP", 2) == 0 ) {
496 tk 789
        parameter += 2;
492 tk 790
 
496 tk 791
        int gp = atoi(parameter);
492 tk 792
        if( gp < 1 || gp > 16 ) {
793
#if DEBUG_VERBOSE_LEVEL >= 1
496 tk 794
          DEBUG_MSG("[SEQ_FILE_HW] ERROR: invalid ENC_GP number 'ENC_GP%s'!", parameter);
492 tk 795
#endif
796
        } else {
797
          MIOS32_ENC_ConfigSet(gp, enc_config);
798
        }
799
 
800
      } else {
801
#if DEBUG_VERBOSE_LEVEL >= 1
496 tk 802
        DEBUG_MSG("[SEQ_FILE_HW] ERROR: unknown ENC name 'ENC_%s'!", parameter);
492 tk 803
#endif
804
      }
805
 
496 tk 806
 
807
    ////////////////////////////////////////////////////////////////////////////////////////////
1164 tk 808
    // TRACKS_DOUT_[LR]_SR
809
    ////////////////////////////////////////////////////////////////////////////////////////////
2039 tk 810
    } else if( strcasecmp(parameter, "TRACKS_DOUT_L_SR") == 0 || strcasecmp(parameter, "TRACKS_DOUT_R_SR") == 0 ) {
1164 tk 811
      char *word = strtok_r(NULL, separators, &brkt);
812
      s32 sr = get_dec(word);
1864 tk 813
      if( sr < 0 || sr > MIOS32_SRIO_NUM_SR ) {
1164 tk 814
#if DEBUG_VERBOSE_LEVEL >= 1
815
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in %s definition: invalid SR value '%s'!", parameter, word);
816
#endif
817
        continue;
818
      }
2039 tk 819
      if( strcasecmp(parameter, "TRACKS_DOUT_L_SR") == 0 ) {
1164 tk 820
        seq_hwcfg_led.tracks_dout_l_sr = sr;
821
      } else {
822
        seq_hwcfg_led.tracks_dout_r_sr = sr;
823
      }
824
 
825
    ////////////////////////////////////////////////////////////////////////////////////////////
1864 tk 826
    // SRIO_NUM_SR
827
    ////////////////////////////////////////////////////////////////////////////////////////////
2039 tk 828
    } else if( strcasecmp(parameter, "SRIO_NUM_SR") == 0 ) {
1864 tk 829
      char *word = strtok_r(NULL, separators, &brkt);
830
      s32 num_sr = get_dec(word);
831
      if( num_sr < 1 || num_sr > MIOS32_SRIO_NUM_SR ) {
832
#if DEBUG_VERBOSE_LEVEL >= 1
833
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in SRIO_NUM_SR definition: invalid value '%s'!", word);
834
#endif
835
        continue;
836
      }
837
 
838
#if DEBUG_VERBOSE_LEVEL >= 3
839
      DEBUG_MSG("[SEQ_FILE_HW] SRIO_NUM_SR %d", num_sr);
840
#endif
841
 
842
      MIOS32_SRIO_ScanNumSet(num_sr);
843
 
844
      // clear all DOUTs (for the case that the number has been decreased)
845
      int i;
846
      for(i=0; i<MIOS32_SRIO_NUM_SR; ++i)
847
        MIOS32_DOUT_SRSet(i, 0x00);
848
 
849
    ////////////////////////////////////////////////////////////////////////////////////////////
514 tk 850
    // GP_DOUT_
496 tk 851
    ////////////////////////////////////////////////////////////////////////////////////////////
2039 tk 852
    } else if( strncasecmp(parameter, "GP_DOUT_", 8) == 0 ) {
514 tk 853
      parameter += 8;
496 tk 854
 
855
      char *word = strtok_r(NULL, separators, &brkt);
856
      s32 sr = get_dec(word);
1864 tk 857
      if( sr < 0 || sr > MIOS32_SRIO_NUM_SR ) {
496 tk 858
#if DEBUG_VERBOSE_LEVEL >= 1
514 tk 859
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in GP_DOUT_%s definition: invalid SR value '%s'!", parameter, word);
496 tk 860
#endif
861
        continue;
862
      }
863
 
864
#if DEBUG_VERBOSE_LEVEL >= 3
514 tk 865
      DEBUG_MSG("[SEQ_FILE_HW] GP_DOUT_%s: SR %d", parameter, sr);
496 tk 866
#endif
867
 
2039 tk 868
      if( strcasecmp(parameter, "L_SR") == 0 ) {
514 tk 869
        seq_hwcfg_led.gp_dout_l_sr = sr;
2039 tk 870
      } else if( strcasecmp(parameter, "R_SR") == 0 ) {
514 tk 871
        seq_hwcfg_led.gp_dout_r_sr = sr;
2039 tk 872
      } else if( strcasecmp(parameter, "L2_SR") == 0 ) {
514 tk 873
        seq_hwcfg_led.gp_dout_l2_sr = sr;
2039 tk 874
      } else if( strcasecmp(parameter, "R2_SR") == 0 ) {
514 tk 875
        seq_hwcfg_led.gp_dout_r2_sr = sr;
496 tk 876
      } else {
877
#if DEBUG_VERBOSE_LEVEL >= 1
514 tk 878
        DEBUG_MSG("[SEQ_FILE_HW] ERROR: unknown GP_DOUT_* name '%s'!", parameter);
496 tk 879
#endif
880
      }
881
 
882
 
883
    ////////////////////////////////////////////////////////////////////////////////////////////
514 tk 884
    // BLM_
496 tk 885
    ////////////////////////////////////////////////////////////////////////////////////////////
2039 tk 886
    } else if( strncasecmp(parameter, "BLM_", 4) == 0 ) {
496 tk 887
      parameter += 4;
888
 
889
      char *word = strtok_r(NULL, separators, &brkt);
890
      s32 value = get_dec(word);
891
      if( value < 0 ) {
892
#if DEBUG_VERBOSE_LEVEL >= 1
514 tk 893
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in BLM_%s definition: invalid value '%s'!", parameter, word);
496 tk 894
#endif
895
        continue;
896
      }
897
 
898
#if DEBUG_VERBOSE_LEVEL >= 3
514 tk 899
      DEBUG_MSG("[SEQ_FILE_HW] BLM_%s: %d", parameter, value);
496 tk 900
#endif
901
 
2039 tk 902
      if( strcasecmp(parameter, "ENABLED") == 0 ) {
514 tk 903
        seq_hwcfg_blm.enabled = value;
2039 tk 904
      } else if( strcasecmp(parameter, "DOUT_L1_SR") == 0 ) {
524 tk 905
        blm_config_t config = BLM_ConfigGet();
906
        config.dout_l1_sr = value;
907
        BLM_ConfigSet(config);
2039 tk 908
      } else if( strcasecmp(parameter, "DOUT_R1_SR") == 0 ) {
524 tk 909
        blm_config_t config = BLM_ConfigGet();
910
        config.dout_r1_sr = value;
911
        BLM_ConfigSet(config);
2039 tk 912
      } else if( strcasecmp(parameter, "DOUT_CATHODES_SR1") == 0 ) {
524 tk 913
        blm_config_t config = BLM_ConfigGet();
914
        config.dout_cathodes_sr1 = value;
915
        BLM_ConfigSet(config);
2039 tk 916
      } else if( strcasecmp(parameter, "DOUT_CATHODES_SR2") == 0 ) {
524 tk 917
        blm_config_t config = BLM_ConfigGet();
918
        config.dout_cathodes_sr2 = value;
919
        BLM_ConfigSet(config);
2039 tk 920
      } else if( strcasecmp(parameter, "DOUT_CATHODES_INV_MASK") == 0 ) {
524 tk 921
        blm_config_t config = BLM_ConfigGet();
922
        config.cathodes_inv_mask = value;
923
        BLM_ConfigSet(config);
2039 tk 924
      } else if( strcasecmp(parameter, "DOUT_DUOCOLOUR") == 0 ) {
514 tk 925
        seq_hwcfg_blm.dout_duocolour = value;
2039 tk 926
      } else if( strcasecmp(parameter, "DOUT_L2_SR") == 0 ) {
524 tk 927
        blm_config_t config = BLM_ConfigGet();
928
        config.dout_l2_sr = value;
929
        BLM_ConfigSet(config);
2039 tk 930
      } else if( strcasecmp(parameter, "DOUT_R2_SR") == 0 ) {
524 tk 931
        blm_config_t config = BLM_ConfigGet();
932
        config.dout_r2_sr = value;
933
        BLM_ConfigSet(config);
2039 tk 934
      } else if( strcasecmp(parameter, "BUTTONS_ENABLED") == 0 ) {
514 tk 935
        seq_hwcfg_blm.buttons_enabled = value;
2039 tk 936
      } else if( strcasecmp(parameter, "BUTTONS_NO_UI") == 0 ) {
514 tk 937
        seq_hwcfg_blm.buttons_no_ui = value;
2039 tk 938
      } else if( strcasecmp(parameter, "GP_ALWAYS_SELECT_MENU_PAGE") == 0 ) {
1675 tk 939
        seq_hwcfg_blm.gp_always_select_menu_page = value;
2039 tk 940
      } else if( strcasecmp(parameter, "DIN_L_SR") == 0 ) {
524 tk 941
        blm_config_t config = BLM_ConfigGet();
942
        config.din_l_sr = value;
943
        BLM_ConfigSet(config);
2039 tk 944
      } else if( strcasecmp(parameter, "DIN_R_SR") == 0 ) {
524 tk 945
        blm_config_t config = BLM_ConfigGet();
946
        config.din_r_sr = value;
947
        BLM_ConfigSet(config);
784 tk 948
 
514 tk 949
      } else {
950
#if DEBUG_VERBOSE_LEVEL >= 1
951
        DEBUG_MSG("[SEQ_FILE_HW] ERROR: unknown BLM_* name '%s'!", parameter);
952
#endif
953
      }
954
 
955
 
956
    ////////////////////////////////////////////////////////////////////////////////////////////
957
    // BLM8X8_
958
    ////////////////////////////////////////////////////////////////////////////////////////////
2039 tk 959
    } else if( strncasecmp(parameter, "BLM8X8_", 7) == 0 ) {
514 tk 960
      parameter += 7;
961
 
962
      char *word = strtok_r(NULL, separators, &brkt);
963
      s32 value = get_dec(word);
964
      if( value < 0 ) {
965
#if DEBUG_VERBOSE_LEVEL >= 1
966
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in BLM8X8_%s definition: invalid value '%s'!", parameter, word);
967
#endif
968
        continue;
969
      }
970
 
971
#if DEBUG_VERBOSE_LEVEL >= 3
972
      DEBUG_MSG("[SEQ_FILE_HW] BLM8X8_%s: %d", parameter, value);
973
#endif
974
 
2039 tk 975
      if( strcasecmp(parameter, "ENABLED") == 0 ) {
514 tk 976
        seq_hwcfg_blm8x8.enabled = value;
2039 tk 977
      } else if( strcasecmp(parameter, "DOUT_CATHODES_SR") == 0 ) {
513 tk 978
        blm_x_config_t config = BLM_X_ConfigGet();
979
        config.rowsel_dout_sr = value;
980
        BLM_X_ConfigSet(config);
2039 tk 981
      } else if( strcasecmp(parameter, "DOUT_CATHODES_INV_MASK") == 0 ) {
513 tk 982
        blm_x_config_t config = BLM_X_ConfigGet();
983
        config.rowsel_inv_mask = value;
984
        BLM_X_ConfigSet(config);
2039 tk 985
      } else if( strcasecmp(parameter, "DOUT_LED_SR") == 0 ) {
513 tk 986
        blm_x_config_t config = BLM_X_ConfigGet();
514 tk 987
        config.led_first_dout_sr = value;
988
        BLM_X_ConfigSet(config);
2039 tk 989
      } else if( strcasecmp(parameter, "DOUT_GP_MAPPING") == 0 ) {
514 tk 990
        seq_hwcfg_blm8x8.dout_gp_mapping = value;
2039 tk 991
      } else if( strcasecmp(parameter, "DIN_SR") == 0 ) {
514 tk 992
        blm_x_config_t config = BLM_X_ConfigGet();
513 tk 993
        config.btn_first_din_sr = value;
994
        BLM_X_ConfigSet(config);
496 tk 995
      } else {
996
#if DEBUG_VERBOSE_LEVEL >= 1
514 tk 997
        DEBUG_MSG("[SEQ_FILE_HW] ERROR: unknown BLM8X8_* name '%s'!", parameter);
496 tk 998
#endif
999
      }
1000
 
1001
    ////////////////////////////////////////////////////////////////////////////////////////////
1336 tk 1002
    // BPM_DIGITS_
1003
    ////////////////////////////////////////////////////////////////////////////////////////////
2039 tk 1004
    } else if( strncasecmp(parameter, "BPM_DIGITS_", 11) == 0 ) {
1336 tk 1005
      parameter += 11;
1006
 
1007
      char *word = strtok_r(NULL, separators, &brkt);
1008
      s32 value = get_dec(word);
1009
      if( value < 0 ) {
1010
#if DEBUG_VERBOSE_LEVEL >= 1
1011
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in BPM_DIGITS_%s definition: invalid value '%s'!", parameter, word);
1012
#endif
1013
        continue;
1014
      }
1015
 
1016
#if DEBUG_VERBOSE_LEVEL >= 3
1017
      DEBUG_MSG("[SEQ_FILE_HW] BPM_DIGITS_%s: %d", parameter, value);
1018
#endif
1019
 
2039 tk 1020
      if( strcasecmp(parameter, "ENABLED") == 0 ) {
1336 tk 1021
        seq_hwcfg_bpm_digits.enabled = value;
2039 tk 1022
      } else if( strcasecmp(parameter, "SEGMENTS_SR") == 0 ) {
1336 tk 1023
        seq_hwcfg_bpm_digits.segments_sr = value;
2039 tk 1024
      } else if( strcasecmp(parameter, "COMMON1_PIN") == 0 ||
1025
             strcasecmp(parameter, "COMMON2_PIN") == 0 ||
1026
             strcasecmp(parameter, "COMMON3_PIN") == 0 ||
1027
             strcasecmp(parameter, "COMMON4_PIN") == 0 ) {
1336 tk 1028
 
1029
        word = strtok_r(NULL, separators, &brkt);
1030
        s32 pin = get_dec(word);
1031
        if( pin < 0 || pin >= 8 ) {
1032
#if DEBUG_VERBOSE_LEVEL >= 1
1341 tk 1033
          DEBUG_MSG("[SEQ_FILE_HW] ERROR in BPM_DIGITS_%s definition: invalid pin value '%s'!", parameter, word);
1336 tk 1034
#endif
1035
          continue;
1036
        }
1037
        u8 dout_value = ((value-1)<<3) | pin;
1038
 
2039 tk 1039
        if( strcasecmp(parameter, "COMMON1_PIN") == 0 ) {
1336 tk 1040
          seq_hwcfg_bpm_digits.common1_pin = dout_value;
2039 tk 1041
        } else if( strcasecmp(parameter, "COMMON2_PIN") == 0 ) {
1336 tk 1042
          seq_hwcfg_bpm_digits.common2_pin = dout_value;
2039 tk 1043
        } else if( strcasecmp(parameter, "COMMON3_PIN") == 0 ) {
1336 tk 1044
          seq_hwcfg_bpm_digits.common3_pin = dout_value;
2039 tk 1045
        } else if( strcasecmp(parameter, "COMMON4_PIN") == 0 ) {
1341 tk 1046
          seq_hwcfg_bpm_digits.common4_pin = dout_value;
1336 tk 1047
        }
1048
      } else {
1049
#if DEBUG_VERBOSE_LEVEL >= 1
1341 tk 1050
        DEBUG_MSG("[SEQ_FILE_HW] ERROR: unknown BPM_DIGITS_* name '%s'!", parameter);
1336 tk 1051
#endif
1052
      }
1053
 
1054
    ////////////////////////////////////////////////////////////////////////////////////////////
1341 tk 1055
    // STEP_DIGITS_
1056
    ////////////////////////////////////////////////////////////////////////////////////////////
2039 tk 1057
    } else if( strncasecmp(parameter, "STEP_DIGITS_", 12) == 0 ) {
1341 tk 1058
      parameter += 12;
1059
 
1060
      char *word = strtok_r(NULL, separators, &brkt);
1061
      s32 value = get_dec(word);
1062
      if( value < 0 ) {
1063
#if DEBUG_VERBOSE_LEVEL >= 1
1064
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in STEP_DIGITS_%s definition: invalid value '%s'!", parameter, word);
1065
#endif
1066
        continue;
1067
      }
1068
 
1069
#if DEBUG_VERBOSE_LEVEL >= 3
1070
      DEBUG_MSG("[SEQ_FILE_HW] STEP_DIGITS_%s: %d", parameter, value);
1071
#endif
1072
 
2039 tk 1073
      if( strcasecmp(parameter, "ENABLED") == 0 ) {
1341 tk 1074
        seq_hwcfg_step_digits.enabled = value;
2039 tk 1075
      } else if( strcasecmp(parameter, "SEGMENTS_SR") == 0 ) {
1341 tk 1076
        seq_hwcfg_step_digits.segments_sr = value;
2039 tk 1077
      } else if( strcasecmp(parameter, "COMMON1_PIN") == 0 ||
1078
             strcasecmp(parameter, "COMMON2_PIN") == 0 ||
1079
             strcasecmp(parameter, "COMMON3_PIN") == 0 ) {
1341 tk 1080
 
1081
        word = strtok_r(NULL, separators, &brkt);
1082
        s32 pin = get_dec(word);
1083
        if( pin < 0 || pin >= 8 ) {
1084
#if DEBUG_VERBOSE_LEVEL >= 1
1085
          DEBUG_MSG("[SEQ_FILE_HW] ERROR in STEP_DIGITS_%s definition: invalid pin value '%s'!", parameter, word);
1086
#endif
1087
          continue;
1088
        }
1089
        u8 dout_value = ((value-1)<<3) | pin;
1090
 
2039 tk 1091
        if( strcasecmp(parameter, "COMMON1_PIN") == 0 ) {
1341 tk 1092
          seq_hwcfg_step_digits.common1_pin = dout_value;
2039 tk 1093
        } else if( strcasecmp(parameter, "COMMON2_PIN") == 0 ) {
1341 tk 1094
          seq_hwcfg_step_digits.common2_pin = dout_value;
2039 tk 1095
        } else if( strcasecmp(parameter, "COMMON3_PIN") == 0 ) {
1341 tk 1096
          seq_hwcfg_step_digits.common3_pin = dout_value;
1097
        }
1098
      } else {
1099
#if DEBUG_VERBOSE_LEVEL >= 1
1100
        DEBUG_MSG("[SEQ_FILE_HW] ERROR: unknown STEP_DIGITS_* name '%s'!", parameter);
1101
#endif
1102
      }
1345 tk 1103
    ////////////////////////////////////////////////////////////////////////////////////////////
1104
    // TPD_
1105
    ////////////////////////////////////////////////////////////////////////////////////////////
2039 tk 1106
    } else if( strncasecmp(parameter, "TPD_", 4) == 0 ) {
1345 tk 1107
      parameter += 4;
1341 tk 1108
 
1345 tk 1109
      char *word = strtok_r(NULL, separators, &brkt);
1110
      s32 value = get_dec(word);
1111
      if( value < 0 ) {
1112
#if DEBUG_VERBOSE_LEVEL >= 1
1113
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in TPD_%s definition: invalid value '%s'!", parameter, word);
1114
#endif
1115
        continue;
1116
      }
1117
 
1118
#if DEBUG_VERBOSE_LEVEL >= 3
1119
      DEBUG_MSG("[SEQ_FILE_HW] TPD_%s: %d", parameter, value);
1120
#endif
1121
 
2039 tk 1122
      if( strcasecmp(parameter, "ENABLED") == 0 ) {
1345 tk 1123
        seq_hwcfg_tpd.enabled = value;
2039 tk 1124
      } else if( strcasecmp(parameter, "COLUMNS_SR") == 0 || strcasecmp(parameter, "COLUMNS_SR_L") == 0 ) {
1864 tk 1125
        seq_hwcfg_tpd.columns_sr[0] = value;
2039 tk 1126
      } else if( strcasecmp(parameter, "COLUMNS_SR_R") == 0 ) {
1864 tk 1127
        seq_hwcfg_tpd.columns_sr[1] = value;
2039 tk 1128
      } else if( strcasecmp(parameter, "ROWS_SR") == 0 || strcasecmp(parameter, "ROWS_SR_GREEN_L") == 0 ) {
1864 tk 1129
        seq_hwcfg_tpd.rows_sr_green[0] = value;
2039 tk 1130
      } else if( strcasecmp(parameter, "ROWS_SR_GREEN_R") == 0 ) {
1864 tk 1131
        seq_hwcfg_tpd.rows_sr_green[1] = value;
2039 tk 1132
      } else if( strcasecmp(parameter, "ROWS_SR_RED_L") == 0 ) {
1864 tk 1133
        seq_hwcfg_tpd.rows_sr_red[0] = value;
2039 tk 1134
      } else if( strcasecmp(parameter, "ROWS_SR_RED_R") == 0 ) {
1864 tk 1135
        seq_hwcfg_tpd.rows_sr_red[1] = value;
1345 tk 1136
      } else {
1137
#if DEBUG_VERBOSE_LEVEL >= 1
1138
        DEBUG_MSG("[SEQ_FILE_HW] ERROR: unknown STEP_TPM_* name '%s'!", parameter);
1139
#endif
1140
      }  
1141
 
1341 tk 1142
    ////////////////////////////////////////////////////////////////////////////////////////////
507 tk 1143
    // misc
1144
    ////////////////////////////////////////////////////////////////////////////////////////////
2039 tk 1145
    } else if( strcasecmp(parameter, "MIDI_REMOTE_KEY") == 0 ) {
741 tk 1146
      char *word = strtok_r(NULL, separators, &brkt);
1147
      s32 key = get_dec(word);
1148
      if( key < 0 || key >= 128 ) {
1149
#if DEBUG_VERBOSE_LEVEL >= 1
1150
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in %s definition: invalid remote key '%s'!", parameter, word);
1151
#endif
1152
        continue;
1153
      }
1154
 
1155
      seq_hwcfg_midi_remote.key = key;
1156
 
2039 tk 1157
    } else if( strcasecmp(parameter, "MIDI_REMOTE_CC") == 0 ) {
741 tk 1158
      char *word = strtok_r(NULL, separators, &brkt);
1159
      s32 cc = get_dec(word);
1160
      if( cc < 0 || cc >= 128 ) {
1161
#if DEBUG_VERBOSE_LEVEL >= 1
1162
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in %s definition: invalid remote CC '%s'!", parameter, word);
1163
#endif
1164
        continue;
1165
      }
1166
 
1167
      seq_hwcfg_midi_remote.cc = cc;
1168
 
2039 tk 1169
    } else if( strcasecmp(parameter, "TRACK_CC_MODE") == 0 ) {
1713 tk 1170
      char *word = strtok_r(NULL, separators, &brkt);
1171
      s32 mode = get_dec(word);
1172
      if( mode < 0 || mode > 2 ) {
1173
#if DEBUG_VERBOSE_LEVEL >= 1
1174
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in %s definition: invalid Track CC mode '%s'!", parameter, word);
1175
#endif
1176
        continue;
1177
      }
1178
 
1179
      seq_hwcfg_track_cc.mode = mode;
1180
 
2039 tk 1181
    } else if( strcasecmp(parameter, "TRACK_CC_PORT") == 0 ) {
1713 tk 1182
      char *word = strtok_r(NULL, separators, &brkt);
2039 tk 1183
      s32 port = SEQ_MIDI_PORT_OutPortFromNameGet(word);
1713 tk 1184
 
1185
      if( port < 0 || port >= 0x100 ) {
1186
#if DEBUG_VERBOSE_LEVEL >= 1
1187
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in %s definition: invalid port number '%s'!", parameter, word);
1188
#endif
1189
        continue;
1190
      }
1191
 
1192
      seq_hwcfg_track_cc.port = port;
1193
 
2039 tk 1194
    } else if( strcasecmp(parameter, "TRACK_CC_CHANNEL") == 0 ) {
1713 tk 1195
      char *word = strtok_r(NULL, separators, &brkt);
1196
      s32 chn = get_dec(word);
1197
      if( chn < 1 || chn > 16 ) {
1198
#if DEBUG_VERBOSE_LEVEL >= 1
1199
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in %s definition: invalid Track CC channel '%s'!", parameter, word);
1200
#endif
1201
        continue;
1202
      }
1203
 
1204
      seq_hwcfg_track_cc.chn = chn-1; // counting from 1 for user, from 0 for app
1205
 
2039 tk 1206
    } else if( strcasecmp(parameter, "TRACK_CC_NUMBER") == 0 ) {
1713 tk 1207
      char *word = strtok_r(NULL, separators, &brkt);
1208
      s32 cc = get_dec(word);
1209
      if( cc < 0 || cc >= 128 ) {
1210
#if DEBUG_VERBOSE_LEVEL >= 1
1211
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in %s definition: invalid Track CC number '%s'!", parameter, word);
1212
#endif
1213
        continue;
1214
      }
1215
 
1216
      seq_hwcfg_track_cc.cc = cc;
1217
 
2039 tk 1218
    } else if( strcasecmp(parameter, "RS_OPTIMISATION") == 0 ) {
1025 tk 1219
      char *word = strtok_r(NULL, separators, &brkt);
2039 tk 1220
      s32 port = SEQ_MIDI_PORT_OutPortFromNameGet(word);
1025 tk 1221
 
1222
      if( port < 0 || port >= 0x100 ) {
1223
#if DEBUG_VERBOSE_LEVEL >= 1
1224
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in %s definition: invalid port number '%s'!", parameter, word);
1225
#endif
1226
        continue;
1227
      }
1228
 
1229
      word = strtok_r(NULL, separators, &brkt);
1230
      s32 enable = get_dec(word);
1231
      if( enable != 0 && enable != 1 ) {
1232
#if DEBUG_VERBOSE_LEVEL >= 1
1233
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in %s definition: invalid enable flag '%s', expecting 1 or 0!", parameter, word);
1234
#endif
1235
        continue;
1236
      }
1237
 
1238
      s32 status;
1239
      if( (status=MIOS32_MIDI_RS_OptimisationSet(port, enable)) < 0 ) {
1240
#if DEBUG_VERBOSE_LEVEL >= 1
1346 tk 1241
        if( port != 0x23 ) // this port is only available for LPC17, not for STM32
1242
          DEBUG_MSG("[SEQ_FILE_HW] RS_OPTIMISATION 0x%02x %d failed with status %d!", port, enable, status);
1025 tk 1243
#endif
1244
      }
1245
 
2039 tk 1246
    } else if( strcasecmp(parameter, "DEBOUNCE_DELAY") == 0 ) {
1126 tk 1247
      char *word = strtok_r(NULL, separators, &brkt);
1248
      s32 delay = get_dec(word);
1249
      if( delay < 0 || delay >= 128 ) {
1250
#if DEBUG_VERBOSE_LEVEL >= 1
1251
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in %s definition: invalid delay value '%s'!", parameter, word);
1252
#endif
1253
        continue;
1254
      }
1255
 
1531 tk 1256
      // common DINs
1126 tk 1257
      MIOS32_SRIO_DebounceSet(delay);
1258
 
1531 tk 1259
      // BLM_X based DINs
1260
      blm_x_config_t config = BLM_X_ConfigGet();
1261
      config.debounce_delay = delay;
1262
      BLM_X_ConfigSet(config);
1263
 
2039 tk 1264
    } else if( strcasecmp(parameter, "AOUT_INTERFACE_TYPE") == 0 ) {
1083 tk 1265
      // only for compatibility reasons - AOUT interface is stored in MBSEQ_GC.V4 now!
1266
      // can be removed once most users switched to beta28 and later!
1267
 
507 tk 1268
      char *word = strtok_r(NULL, separators, &brkt);
1269
      s32 aout_type = get_dec(word);
1270
      if( aout_type < 0 || aout_type >= 4 ) {
1271
#if DEBUG_VERBOSE_LEVEL >= 1
1272
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in %s definition: invalid AOUT interface type '%s'!", parameter, word);
1273
#endif
1274
        continue;
1275
      }
1276
 
1277
      aout_config_t config;
1278
      config = AOUT_ConfigGet();
1279
      config.if_type = aout_type;
1280
      config.if_option = (config.if_type == AOUT_IF_74HC595) ? 0xffffffff : 0x00000000; // AOUT_LC: select 8/8 bit configuration
1281
      config.num_channels = 8;
1282
      config.chn_inverted = 0;
1283
      AOUT_ConfigSet(config);
1284
      AOUT_IF_Init(0);
1285
 
2088 tk 1286
    } else if( strncasecmp(parameter, "CV_GATE_SR", 10) == 0 && // CV_GATE_SR%d
1287
             (hlp=atoi(parameter+10)) >= 1 && hlp <= SEQ_HWCFG_NUM_SR_CV_GATES ) {
1288
 
1289
      char *word = strtok_r(NULL, separators, &brkt);
1290
      s32 sr = get_dec(word);
1291
      if( sr < 0 || sr > MIOS32_SRIO_NUM_SR ) {
1292
#if DEBUG_VERBOSE_LEVEL >= 1
1293
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in %s definition: invalid SR value '%s'!", parameter, word);
1294
#endif
1295
        continue;
1296
      }
1297
 
1298
        seq_hwcfg_cv_gate_sr[hlp-1] = sr;
1299
 
1300
    } else if( strcasecmp(parameter, "CLK_SR") == 0 ) {
1301
      char *word = strtok_r(NULL, separators, &brkt);
1302
      s32 sr = get_dec(word);
1303
      if( sr < 0 || sr > MIOS32_SRIO_NUM_SR ) {
1304
#if DEBUG_VERBOSE_LEVEL >= 1
1305
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in %s definition: invalid SR value '%s'!", parameter, word);
1306
#endif
1307
        continue;
1308
      }
1309
 
1310
        seq_hwcfg_clk_sr = sr;
1311
 
2039 tk 1312
    } else if( strncasecmp(parameter, "DOUT_GATE_SR", 12) == 0 && // DOUT_GATE_SR%d
507 tk 1313
             (hlp=atoi(parameter+12)) >= 1 && hlp <= SEQ_HWCFG_NUM_SR_DOUT_GATES ) {
1314
 
1315
      char *word = strtok_r(NULL, separators, &brkt);
1316
      s32 sr = get_dec(word);
1864 tk 1317
      if( sr < 0 || sr > MIOS32_SRIO_NUM_SR ) {
507 tk 1318
#if DEBUG_VERBOSE_LEVEL >= 1
1319
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in %s definition: invalid SR value '%s'!", parameter, word);
1320
#endif
1321
        continue;
1322
      }
1323
 
1324
        seq_hwcfg_dout_gate_sr[hlp-1] = sr;
1325
 
2039 tk 1326
    } else if( strcasecmp(parameter, "J5_ENABLED") == 0 ) {
507 tk 1327
      char *word = strtok_r(NULL, separators, &brkt);
1328
      s32 j5_enabled = get_dec(word);
1329
      if( j5_enabled < 0 || j5_enabled > 2 ) {
1330
#if DEBUG_VERBOSE_LEVEL >= 1
1331
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in %s definition: expecting 0, 1 or 2!", parameter);
1332
#endif
1333
        continue;
1334
      }
1335
 
1336
      int i;
1337
      mios32_board_pin_mode_t pin_mode = MIOS32_BOARD_PIN_MODE_INPUT_PD;
1338
      if( j5_enabled == 1 )
1339
        pin_mode = MIOS32_BOARD_PIN_MODE_OUTPUT_PP;
1340
      if( j5_enabled == 2 )
1341
        pin_mode = MIOS32_BOARD_PIN_MODE_OUTPUT_OD;
1342
 
1071 tk 1343
      for(i=0; i<6; ++i) {
1073 tk 1344
        MIOS32_BOARD_J5_PinInit(i, pin_mode);
1071 tk 1345
        MIOS32_BOARD_J5_PinSet(i, 0);
1346
      }
507 tk 1347
 
2088 tk 1348
#if defined(MIOS32_FAMILY_STM32F10x)
1071 tk 1349
      // pin J5.A6 and J5.A7 used for UART2 (-> MIDI OUT3)
1350
      for(i=8; i<12; ++i) {
1073 tk 1351
        MIOS32_BOARD_J5_PinInit(i, pin_mode);
1071 tk 1352
        MIOS32_BOARD_J5_PinSet(i, 0);
1353
      }
2088 tk 1354
#elif defined(MIOS32_FAMILY_STM32F4xx)
1355
      // pin J5.A6 and J5.A7 used as gates
1356
      for(i=6; i<8; ++i) {
1357
        MIOS32_BOARD_J5_PinInit(i, pin_mode);
1358
        MIOS32_BOARD_J5_PinSet(i, 0);
1359
      }
1360
      // and J10B for additional outputs
1361
      for(i=8; i<16; ++i) {
1362
        MIOS32_BOARD_J10_PinInit(i, pin_mode);
1363
        MIOS32_BOARD_J10_PinSet(i, 0);
1364
      }
1311 tk 1365
#elif defined(MIOS32_FAMILY_LPC17xx)
2088 tk 1366
      // and pin J28 for additional outputs
1311 tk 1367
      for(i=0; i<4; ++i) {
1368
        MIOS32_BOARD_J28_PinInit(i, pin_mode);
1369
        MIOS32_BOARD_J28_PinSet(i, 0);
1370
      }
1371
#else
1372
# warning "please adapt for this MIOS32_FAMILY"
1373
#endif
1071 tk 1374
 
2039 tk 1375
    } else if( strcasecmp(parameter, "DIN_SYNC_CLK_PULSEWIDTH") == 0 ) {
1083 tk 1376
      // only for compatibility reasons - AOUT interface is stored in MBSEQ_GC.V4 now!
1377
      // can be removed once most users switched to beta28 and later!
1378
 
784 tk 1379
      char *word = strtok_r(NULL, separators, &brkt);
1380
      s32 pulsewidth = get_dec(word);
1381
      if( pulsewidth < 1 || pulsewidth > 250 ) {
1382
#if DEBUG_VERBOSE_LEVEL >= 1
1383
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in %s definition: expecting pulsewidth of 1..250!", parameter);
1384
#endif
1385
        continue;
1386
      }
1387
 
2098 tk 1388
      SEQ_CV_ClkPulseWidthSet(0, pulsewidth);
784 tk 1389
 
2039 tk 1390
    } else if( strcasecmp(parameter, "DOUT_1MS_TRIGGER") == 0 ) {
507 tk 1391
 
1392
      char *word = strtok_r(NULL, separators, &brkt);
1393
      s32 trg_enabled = get_dec(word);
1394
      if( trg_enabled < 0 || trg_enabled > 1 ) {
1395
#if DEBUG_VERBOSE_LEVEL >= 1
1396
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in %s definition: expecting 0 or 1!", parameter);
1397
#endif
1398
        continue;
1399
      }
1400
 
1401
      seq_hwcfg_dout_gate_1ms = trg_enabled;
1402
 
1403
 
1404
    ////////////////////////////////////////////////////////////////////////////////////////////
496 tk 1405
    // unknown
1406
    ////////////////////////////////////////////////////////////////////////////////////////////
492 tk 1407
    } else {
1408
#if DEBUG_VERBOSE_LEVEL >= 1
496 tk 1409
      DEBUG_MSG("[SEQ_FILE_HW] ERROR: unknown parameter: %s", line_buffer);
492 tk 1410
#endif
1411
    }
1412
      } else {
1413
#if DEBUG_VERBOSE_LEVEL >= 1
1414
    DEBUG_MSG("[SEQ_FILE_HW] ERROR: no space separator in following line: %s", line_buffer);
1415
#endif
1416
      }
1417
    }
1418
 
1419
  } while( status >= 1 );
1420
 
1261 tk 1421
  FILE_ReadClose(&file);
492 tk 1422
 
1423
  if( status < 0 ) {
1424
#if DEBUG_VERBOSE_LEVEL >= 1
1425
    DEBUG_MSG("[SEQ_FILE_HW] ERROR while reading file, status: %d\n", status);
1426
#endif
1427
    return SEQ_FILE_HW_ERR_READ;
1428
  }
1429
 
1430
  // file is valid! :)
1431
  info->valid = 1;
1432
 
1433
  return 0; // no error
1434
}