Subversion Repositories svn.mios32

Rev

Rev 2308 | Rev 2324 | 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 2322 2016-03-15 19:08:38Z 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;
2322 tk 399
      } else if( strcasecmp(parameter, "JAM_LIVE") == 0 ) {
400
        seq_hwcfg_button.jam_live = din_value;
401
      } else if( strcasecmp(parameter, "JAM_STEP") == 0 ) {
402
        seq_hwcfg_button.jam_live = din_value;
2039 tk 403
      } else if( strcasecmp(parameter, "LIVE") == 0 ) {
1219 tk 404
        seq_hwcfg_button.live = din_value;
2039 tk 405
      } else if( strcasecmp(parameter, "STOP") == 0 ) {
492 tk 406
        seq_hwcfg_button.stop = din_value;
2039 tk 407
      } else if( strcasecmp(parameter, "PAUSE") == 0 ) {
492 tk 408
        seq_hwcfg_button.pause = din_value;
2039 tk 409
      } else if( strcasecmp(parameter, "PLAY") == 0 ) {
492 tk 410
        seq_hwcfg_button.play = din_value;
2039 tk 411
      } else if( strcasecmp(parameter, "REW") == 0 ) {
492 tk 412
        seq_hwcfg_button.rew = din_value;
2039 tk 413
      } else if( strcasecmp(parameter, "FWD") == 0 ) {
492 tk 414
        seq_hwcfg_button.fwd = din_value;
2039 tk 415
      } else if( strcasecmp(parameter, "MENU") == 0 ) {
492 tk 416
        seq_hwcfg_button.menu = din_value;
2039 tk 417
      } else if( strcasecmp(parameter, "BOOKMARK") == 0 ) {
1203 tk 418
        seq_hwcfg_button.bookmark = din_value;
2039 tk 419
      } else if( strcasecmp(parameter, "SELECT") == 0 ) {
492 tk 420
        seq_hwcfg_button.select = din_value;
2039 tk 421
      } else if( strcasecmp(parameter, "EXIT") == 0 ) {
492 tk 422
        seq_hwcfg_button.exit = din_value;
2039 tk 423
      } else if( strncasecmp(parameter, "TRACK", 5) == 0 && // TRACK[1234]
496 tk 424
             (hlp=parameter[5]-'1') >= 0 && hlp < 4 ) {
425
        seq_hwcfg_button.track[hlp] = din_value;
2039 tk 426
      } else if( strncasecmp(parameter, "PAR_LAYER_", 10) == 0 && // PAR_LAYER_[ABC]
496 tk 427
             (hlp=parameter[10]-'A') >= 0 && hlp < 3 ) {
428
        seq_hwcfg_button.par_layer[hlp] = din_value;
2039 tk 429
      } else if( strcasecmp(parameter, "EDIT") == 0 ) {
492 tk 430
        seq_hwcfg_button.edit = din_value;
2039 tk 431
      } else if( strcasecmp(parameter, "MUTE") == 0 ) {
492 tk 432
        seq_hwcfg_button.mute = din_value;
2039 tk 433
      } else if( strcasecmp(parameter, "PATTERN") == 0 ) {
492 tk 434
        seq_hwcfg_button.pattern = din_value;
2039 tk 435
      } else if( strcasecmp(parameter, "SONG") == 0 ) {
492 tk 436
        seq_hwcfg_button.song = din_value;
2039 tk 437
      } else if( strcasecmp(parameter, "SOLO") == 0 ) {
492 tk 438
        seq_hwcfg_button.solo = din_value;
2039 tk 439
      } else if( strcasecmp(parameter, "FAST2") == 0 ) {
1121 tk 440
        seq_hwcfg_button.fast2 = din_value;
2039 tk 441
      } else if( strcasecmp(parameter, "FAST") == 0 ) {
492 tk 442
        seq_hwcfg_button.fast = din_value;
2039 tk 443
      } else if( strcasecmp(parameter, "ALL") == 0 ) {
492 tk 444
        seq_hwcfg_button.all = din_value;
2039 tk 445
      } else if( strncasecmp(parameter, "GP", 2) == 0 && // GP%d
496 tk 446
             (hlp=atoi(parameter+2)) >= 1 && hlp <= 16 ) {
447
        seq_hwcfg_button.gp[hlp-1] = din_value;
2039 tk 448
      } else if( strncasecmp(parameter, "GROUP", 5) == 0 && // GROUP[1234]
496 tk 449
             (hlp=parameter[5]-'1') >= 0 && hlp < 4 ) {
450
        seq_hwcfg_button.group[hlp] = din_value;
2039 tk 451
      } else if( strncasecmp(parameter, "TRG_LAYER_", 10) == 0 && // TRG_LAYER_[ABC]
496 tk 452
             (hlp=parameter[10]-'A') >= 0 && hlp < 3 ) {
453
        seq_hwcfg_button.trg_layer[hlp] = din_value;
2039 tk 454
      } else if( strcasecmp(parameter, "STEP_VIEW") == 0 ) {
492 tk 455
        seq_hwcfg_button.step_view = din_value;
2039 tk 456
      } else if( strcasecmp(parameter, "TRG_LAYER_SEL") == 0 ) {
513 tk 457
        seq_hwcfg_button.trg_layer_sel = din_value;
2039 tk 458
      } else if( strcasecmp(parameter, "PAR_LAYER_SEL") == 0 ) {
513 tk 459
        seq_hwcfg_button.par_layer_sel = din_value;
2039 tk 460
      } else if( strcasecmp(parameter, "TRACK_SEL") == 0 ) {
513 tk 461
        seq_hwcfg_button.track_sel = din_value;
2039 tk 462
      } else if( strcasecmp(parameter, "TAP_TEMPO") == 0 ) {
492 tk 463
        seq_hwcfg_button.tap_tempo = din_value;
2039 tk 464
      } else if( strcasecmp(parameter, "TEMPO_PRESET") == 0 ) {
513 tk 465
        seq_hwcfg_button.tempo_preset = din_value;
2039 tk 466
      } else if( strcasecmp(parameter, "EXT_RESTART") == 0 ) {
524 tk 467
        seq_hwcfg_button.ext_restart = din_value;
2039 tk 468
      } else if( strcasecmp(parameter, "UTILITY") == 0 ) {
492 tk 469
        seq_hwcfg_button.utility = din_value;
2039 tk 470
      } else if( strcasecmp(parameter, "COPY") == 0 ) {
492 tk 471
        seq_hwcfg_button.copy = din_value;
2039 tk 472
      } else if( strcasecmp(parameter, "PASTE") == 0 ) {
492 tk 473
        seq_hwcfg_button.paste = din_value;
2039 tk 474
      } else if( strcasecmp(parameter, "CLEAR") == 0 ) {
492 tk 475
        seq_hwcfg_button.clear = din_value;
2039 tk 476
      } else if( strcasecmp(parameter, "UNDO") == 0 ) {
1014 tk 477
        seq_hwcfg_button.undo = din_value;
2308 tk 478
      } else if( strcasecmp(parameter, "MOVE") == 0 ) {
479
        seq_hwcfg_button.move = din_value;
480
      } else if( strcasecmp(parameter, "SCROLL") == 0 ) {
481
        seq_hwcfg_button.scroll = din_value;
2039 tk 482
      } else if( strcasecmp(parameter, "MIXER") == 0 ) {
544 tk 483
        seq_hwcfg_button.mixer = din_value;
2039 tk 484
      } else if( strcasecmp(parameter, "SAVE") == 0 ) {
1787 tk 485
        seq_hwcfg_button.save = din_value;
2039 tk 486
      } else if( strcasecmp(parameter, "SAVE_ALL") == 0 ) {
1787 tk 487
        seq_hwcfg_button.save_all = din_value;
2039 tk 488
      } else if( strcasecmp(parameter, "TRACK_MODE") == 0 ) {
1119 tk 489
        seq_hwcfg_button.track_mode = din_value;
2039 tk 490
      } else if( strcasecmp(parameter, "TRACK_GROOVE") == 0 ) {
1119 tk 491
        seq_hwcfg_button.track_groove = din_value;
2039 tk 492
      } else if( strcasecmp(parameter, "TRACK_LENGTH") == 0 ) {
1119 tk 493
        seq_hwcfg_button.track_length = din_value;
2039 tk 494
      } else if( strcasecmp(parameter, "TRACK_DIRECTION") == 0 ) {
1119 tk 495
        seq_hwcfg_button.track_direction = din_value;
2039 tk 496
      } else if( strcasecmp(parameter, "MORPH") == 0 || strcasecmp(parameter, "TRACK_MORPH") == 0 ) {
1119 tk 497
        seq_hwcfg_button.track_morph = din_value;
2039 tk 498
      } else if( strcasecmp(parameter, "TRANSPOSE") == 0 || strcasecmp(parameter, "TRACK_TRANSPOSE") == 0 ) {
1119 tk 499
        seq_hwcfg_button.track_transpose = din_value;
2294 tk 500
      } else if( strcasecmp(parameter, "FX") == 0 ) {
501
        seq_hwcfg_button.fx = din_value;
2039 tk 502
      } else if( strcasecmp(parameter, "FOOTSWITCH") == 0 ) {
1349 tk 503
        seq_hwcfg_button.footswitch = din_value;
2039 tk 504
          } else if( strcasecmp(parameter, "PATTERN_RMX") == 0 ) {
1454 midilab 505
            seq_hwcfg_button.pattern_remix = din_value;
2039 tk 506
          } else if( strcasecmp(parameter, "MUTE_ALL_TRACKS") == 0 ) {
1811 tk 507
            seq_hwcfg_button.mute_all_tracks = din_value;
2039 tk 508
          } else if( strcasecmp(parameter, "MUTE_TRACK_LAYERS") == 0 ) {
1811 tk 509
            seq_hwcfg_button.mute_track_layers = din_value;
2039 tk 510
          } else if( strcasecmp(parameter, "MUTE_ALL_TRACKS_AND_LAYERS") == 0 ) {
1811 tk 511
            seq_hwcfg_button.mute_all_tracks_and_layers = din_value;
2039 tk 512
          } else if( strcasecmp(parameter, "UNMUTE_ALL_TRACKS") == 0 ) {
1811 tk 513
            seq_hwcfg_button.unmute_all_tracks = din_value;
2039 tk 514
          } else if( strcasecmp(parameter, "UNMUTE_TRACK_LAYERS") == 0 ) {
1811 tk 515
            seq_hwcfg_button.unmute_track_layers = din_value;
2039 tk 516
          } else if( strcasecmp(parameter, "UNMUTE_ALL_TRACKS_AND_LAYERS") == 0 ) {
1811 tk 517
            seq_hwcfg_button.unmute_all_tracks_and_layers = din_value;
2039 tk 518
      } else if( strncasecmp(parameter, "DIRECT_BOOKMARK", 15) == 0 ) {
1205 tk 519
        parameter += 15;
520
 
521
        s32 bookmark = get_dec(parameter);
522
        if( bookmark < 1 || bookmark > SEQ_HWCFG_NUM_DIRECT_BOOKMARK ) {
523
#if DEBUG_VERBOSE_LEVEL >= 1
524
          DEBUG_MSG("[SEQ_FILE_HW] ERROR in BUTTON_DIRECT_BOOKMARK%s definition: invalid track number '%s'!", parameter, parameter);
525
#endif
526
          continue;
527
        }
528
        seq_hwcfg_button.direct_bookmark[bookmark-1] = din_value;
2039 tk 529
      } else if( strncasecmp(parameter, "DIRECT_TRACK", 12) == 0 ) {
1164 tk 530
        parameter += 12;
531
 
532
        s32 track = get_dec(parameter);
1205 tk 533
        if( track < 1 || track > SEQ_HWCFG_NUM_DIRECT_TRACK ) {
1164 tk 534
#if DEBUG_VERBOSE_LEVEL >= 1
535
          DEBUG_MSG("[SEQ_FILE_HW] ERROR in BUTTON_DIRECT_TRACK%s definition: invalid track number '%s'!", parameter, parameter);
536
#endif
537
          continue;
538
        }
1173 tk 539
        seq_hwcfg_button.direct_track[track-1] = din_value;
492 tk 540
      } else {
541
#if DEBUG_VERBOSE_LEVEL >= 1
496 tk 542
        DEBUG_MSG("[SEQ_FILE_HW] ERROR: unknown button function 'BUTTON_%s'!", parameter);
492 tk 543
#endif
544
      }
545
 
496 tk 546
    ////////////////////////////////////////////////////////////////////////////////////////////
547
    // LED_
548
    ////////////////////////////////////////////////////////////////////////////////////////////
2039 tk 549
    } else if( strncasecmp(parameter, "LED_", 4) == 0 ) {
496 tk 550
      parameter += 4;
492 tk 551
 
496 tk 552
      char *word = strtok_r(NULL, separators, &brkt);
1864 tk 553
 
554
      // M1..M8 -> SR 24..31
555
      s32 sr = -1;
556
      u8 blm8x8_selected = 0;
557
      if( word[0] == 'M' ) {
558
        blm8x8_selected = 1;
559
        ++word;
560
        s32 m = get_dec(word);
561
 
562
        if( m < 1 || m > 8 ) {
492 tk 563
#if DEBUG_VERBOSE_LEVEL >= 1
1864 tk 564
          DEBUG_MSG("[SEQ_FILE_HW] ERROR in LED_%s definition: invalid SR value 'M%s'!", parameter, word);
492 tk 565
#endif
1864 tk 566
          continue;
567
        }
568
        sr = 24 + m-1;
569
      } else {
570
        sr = get_dec(word);
571
        if( sr < 0 || sr > 32 ) {
572
#if DEBUG_VERBOSE_LEVEL >= 1
573
          DEBUG_MSG("[SEQ_FILE_HW] ERROR in LED_%s definition: invalid SR value '%s'!", parameter, word);
574
#endif
575
          continue;
576
        }
492 tk 577
      }
578
 
496 tk 579
      word = strtok_r(NULL, separators, &brkt);
580
      s32 pin = get_dec(word);
581
      if( pin < 0 || pin >= 8 ) {
492 tk 582
#if DEBUG_VERBOSE_LEVEL >= 1
513 tk 583
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in LED_%s definition: invalid pin value '%s'!", parameter, word);
492 tk 584
#endif
585
        continue;
586
      }
587
 
588
      u8 dout_value = ((sr-1)<<3) | pin;
1864 tk 589
 
590
      // compatibility with old configurations: if SRIO_NUM_SR hasn't been set to 23 (so that it's still 16)
591
      // then map DOUT SR 17..24 to 24..31
592
      if( !blm8x8_selected && MIOS32_SRIO_ScanNumGet() <= 16 && dout_value >= 128 && dout_value < 192 ) {
593
        dout_value += 56;
594
      }
595
 
492 tk 596
#if DEBUG_VERBOSE_LEVEL >= 3
496 tk 597
      DEBUG_MSG("[SEQ_FILE_HW] LED %s: SR %d Pin %d (DOUT: 0x%02x)", parameter, sr, pin, dout_value);
492 tk 598
#endif
599
 
2039 tk 600
      if( strncasecmp(parameter, "TRACK", 5) == 0 && // TRACK[1234]
496 tk 601
             (hlp=parameter[5]-'1') >= 0 && hlp < 4 ) {
602
        seq_hwcfg_led.track[hlp] = dout_value;
2039 tk 603
      } else if( strncasecmp(parameter, "PAR_LAYER_", 10) == 0 && // PAR_LAYER_[ABC]
496 tk 604
             (hlp=parameter[10]-'A') >= 0 && hlp < 3 ) {
605
        seq_hwcfg_led.par_layer[hlp] = dout_value;
2039 tk 606
      } else if( strcasecmp(parameter, "BEAT") == 0 ) {
492 tk 607
        seq_hwcfg_led.beat = dout_value;
2301 tk 608
      } else if( strcasecmp(parameter, "MEASURE") == 0 ) {
609
        seq_hwcfg_led.measure = dout_value;
2039 tk 610
      } else if( strcasecmp(parameter, "MIDI_IN_COMBINED") == 0 ) {
1336 tk 611
        seq_hwcfg_led.midi_in_combined = dout_value;
2039 tk 612
      } else if( strcasecmp(parameter, "MIDI_OUT_COMBINED") == 0 ) {
1336 tk 613
        seq_hwcfg_led.midi_out_combined = dout_value;
2039 tk 614
      } else if( strcasecmp(parameter, "EDIT") == 0 ) {
492 tk 615
        seq_hwcfg_led.edit = dout_value;
2039 tk 616
      } else if( strcasecmp(parameter, "MUTE") == 0 ) {
492 tk 617
        seq_hwcfg_led.mute = dout_value;
2039 tk 618
      } else if( strcasecmp(parameter, "PATTERN") == 0 ) {
492 tk 619
        seq_hwcfg_led.pattern = dout_value;
2039 tk 620
      } else if( strcasecmp(parameter, "SONG") == 0 ) {
492 tk 621
        seq_hwcfg_led.song = dout_value;
2039 tk 622
      } else if( strcasecmp(parameter, "SOLO") == 0 ) {
492 tk 623
        seq_hwcfg_led.solo = dout_value;
2039 tk 624
      } else if( strcasecmp(parameter, "FAST2") == 0 ) {
1121 tk 625
        seq_hwcfg_led.fast2 = dout_value;
2039 tk 626
      } else if( strcasecmp(parameter, "FAST") == 0 ) {
492 tk 627
        seq_hwcfg_led.fast = dout_value;
2039 tk 628
      } else if( strcasecmp(parameter, "ALL") == 0 ) {
492 tk 629
        seq_hwcfg_led.all = dout_value;
2039 tk 630
      } else if( strncasecmp(parameter, "GROUP", 5) == 0 && // GROUP[1234]
496 tk 631
             (hlp=parameter[5]-'1') >= 0 && hlp < 4 ) {
632
        seq_hwcfg_led.group[hlp] = dout_value;
2039 tk 633
      } else if( strncasecmp(parameter, "TRG_LAYER_", 10) == 0 && // TRG_LAYER_[ABC]
496 tk 634
             (hlp=parameter[10]-'A') >= 0 && hlp < 3 ) {
635
        seq_hwcfg_led.trg_layer[hlp] = dout_value;
2039 tk 636
      } else if( strcasecmp(parameter, "PLAY") == 0 ) {
492 tk 637
        seq_hwcfg_led.play = dout_value;
2039 tk 638
      } else if( strcasecmp(parameter, "STOP") == 0 ) {
492 tk 639
        seq_hwcfg_led.stop = dout_value;
2039 tk 640
      } else if( strcasecmp(parameter, "PAUSE") == 0 ) {
492 tk 641
        seq_hwcfg_led.pause = dout_value;
2039 tk 642
      } else if( strcasecmp(parameter, "REW") == 0 ) {
492 tk 643
        seq_hwcfg_led.rew = dout_value;
2039 tk 644
      } else if( strcasecmp(parameter, "FWD") == 0 ) {
492 tk 645
        seq_hwcfg_led.fwd = dout_value;
2039 tk 646
      } else if( strcasecmp(parameter, "EXIT") == 0 ) {
591 tk 647
        seq_hwcfg_led.exit = dout_value;
2039 tk 648
      } else if( strcasecmp(parameter, "SELECT") == 0 ) {
591 tk 649
        seq_hwcfg_led.select = dout_value;
2039 tk 650
      } else if( strcasecmp(parameter, "MENU") == 0 ) {
492 tk 651
        seq_hwcfg_led.menu = dout_value;
2039 tk 652
      } else if( strcasecmp(parameter, "BOOKMARK") == 0 ) {
1203 tk 653
        seq_hwcfg_led.bookmark = dout_value;
2039 tk 654
      } else if( strcasecmp(parameter, "SCRUB") == 0 ) {
492 tk 655
        seq_hwcfg_led.scrub = dout_value;
2039 tk 656
      } else if( strcasecmp(parameter, "LOOP") == 0 ) {
599 tk 657
        seq_hwcfg_led.loop = dout_value;
2039 tk 658
      } else if( strcasecmp(parameter, "FOLLOW") == 0 ) {
951 tk 659
        seq_hwcfg_led.follow = dout_value;
2039 tk 660
      } else if( strcasecmp(parameter, "METRONOME") == 0 ) {
492 tk 661
        seq_hwcfg_led.metronome = dout_value;
2039 tk 662
      } else if( strcasecmp(parameter, "RECORD") == 0 ) {
630 tk 663
        seq_hwcfg_led.record = dout_value;
2322 tk 664
      } else if( strcasecmp(parameter, "JAM_LIVE") == 0 ) {
665
        seq_hwcfg_led.jam_live = dout_value;
666
      } else if( strcasecmp(parameter, "JAM_STEP") == 0 ) {
667
        seq_hwcfg_led.jam_step = dout_value;
2039 tk 668
      } else if( strcasecmp(parameter, "LIVE") == 0 ) {
1219 tk 669
        seq_hwcfg_led.live = dout_value;
2039 tk 670
      } else if( strcasecmp(parameter, "UTILITY") == 0 ) {
492 tk 671
        seq_hwcfg_led.utility = dout_value;
2039 tk 672
      } else if( strcasecmp(parameter, "COPY") == 0 ) {
492 tk 673
        seq_hwcfg_led.copy = dout_value;
2039 tk 674
      } else if( strcasecmp(parameter, "PASTE") == 0 ) {
492 tk 675
        seq_hwcfg_led.paste = dout_value;
2039 tk 676
      } else if( strcasecmp(parameter, "CLEAR") == 0 ) {
492 tk 677
        seq_hwcfg_led.clear = dout_value;
2039 tk 678
      } else if( strcasecmp(parameter, "UNDO") == 0 ) {
1014 tk 679
        seq_hwcfg_led.undo = dout_value;
2308 tk 680
      } else if( strcasecmp(parameter, "MOVE") == 0 ) {
681
        seq_hwcfg_led.move = dout_value;
682
      } else if( strcasecmp(parameter, "SCROLL") == 0 ) {
683
        seq_hwcfg_led.scroll = dout_value;
2039 tk 684
      } else if( strcasecmp(parameter, "STEP_VIEW") == 0 ) {
492 tk 685
        seq_hwcfg_led.step_view = dout_value;
2039 tk 686
      } else if( strcasecmp(parameter, "TRG_LAYER_SEL") == 0 ) {
513 tk 687
        seq_hwcfg_led.trg_layer_sel = dout_value;
2039 tk 688
      } else if( strcasecmp(parameter, "PAR_LAYER_SEL") == 0 ) {
513 tk 689
        seq_hwcfg_led.par_layer_sel = dout_value;
2039 tk 690
      } else if( strcasecmp(parameter, "TRACK_SEL") == 0 ) {
513 tk 691
        seq_hwcfg_led.track_sel = dout_value;
2039 tk 692
      } else if( strcasecmp(parameter, "TAP_TEMPO") == 0 ) {
513 tk 693
        seq_hwcfg_led.tap_tempo = dout_value;
2039 tk 694
      } else if( strcasecmp(parameter, "TEMPO_PRESET") == 0 ) {
513 tk 695
        seq_hwcfg_led.tempo_preset = dout_value;
2039 tk 696
      } else if( strcasecmp(parameter, "EXT_RESTART") == 0 ) {
524 tk 697
        seq_hwcfg_led.ext_restart = dout_value;
2039 tk 698
      } else if( strcasecmp(parameter, "DOWN") == 0 ) {
492 tk 699
        seq_hwcfg_led.down = dout_value;
2039 tk 700
      } else if( strcasecmp(parameter, "UP") == 0 ) {
492 tk 701
        seq_hwcfg_led.up = dout_value;
2039 tk 702
      } else if( strcasecmp(parameter, "MIXER") == 0 ) {
743 tk 703
        seq_hwcfg_led.mixer = dout_value;
2039 tk 704
      } else if( strcasecmp(parameter, "TRACK_MODE") == 0 ) {
1119 tk 705
        seq_hwcfg_led.track_mode = dout_value;
2039 tk 706
      } else if( strcasecmp(parameter, "TRACK_GROOVE") == 0 ) {
1119 tk 707
        seq_hwcfg_led.track_groove = dout_value;
2039 tk 708
      } else if( strcasecmp(parameter, "TRACK_LENGTH") == 0 ) {
1119 tk 709
        seq_hwcfg_led.track_length = dout_value;
2039 tk 710
      } else if( strcasecmp(parameter, "TRACK_DIRECTION") == 0 ) {
1119 tk 711
        seq_hwcfg_led.track_direction = dout_value;
2039 tk 712
      } else if( strcasecmp(parameter, "MORPH") == 0 || strcasecmp(parameter, "TRACK_MORPH") == 0 ) {
1119 tk 713
        seq_hwcfg_led.track_morph = dout_value;
2039 tk 714
      } else if( strcasecmp(parameter, "TRANSPOSE") == 0 || strcasecmp(parameter, "TRACK_TRANSPOSE") == 0 ) {
1119 tk 715
        seq_hwcfg_led.track_transpose = dout_value;
2294 tk 716
      } else if( strcasecmp(parameter, "FX") == 0 ) {
717
        seq_hwcfg_led.fx = dout_value;
2039 tk 718
          } else if( strcasecmp(parameter, "MUTE_ALL_TRACKS") == 0 ) {
1811 tk 719
            seq_hwcfg_led.mute_all_tracks = dout_value;
2039 tk 720
          } else if( strcasecmp(parameter, "MUTE_TRACK_LAYERS") == 0 ) {
1811 tk 721
            seq_hwcfg_led.mute_track_layers = dout_value;
2039 tk 722
          } else if( strcasecmp(parameter, "MUTE_ALL_TRACKS_AND_LAYERS") == 0 ) {
1811 tk 723
            seq_hwcfg_led.mute_all_tracks_and_layers = dout_value;
2039 tk 724
          } else if( strcasecmp(parameter, "UNMUTE_ALL_TRACKS") == 0 ) {
1811 tk 725
            seq_hwcfg_led.unmute_all_tracks = dout_value;
2039 tk 726
          } else if( strcasecmp(parameter, "UNMUTE_TRACK_LAYERS") == 0 ) {
1811 tk 727
            seq_hwcfg_led.unmute_track_layers = dout_value;
2039 tk 728
          } else if( strcasecmp(parameter, "UNMUTE_ALL_TRACKS_AND_LAYERS") == 0 ) {
1811 tk 729
            seq_hwcfg_led.unmute_all_tracks_and_layers = dout_value;
492 tk 730
      } else {
731
#if DEBUG_VERBOSE_LEVEL >= 1
496 tk 732
        DEBUG_MSG("[SEQ_FILE_HW] ERROR: unknown LED function 'LED_%s'!", parameter);
492 tk 733
#endif
734
      }
735
 
736
 
496 tk 737
    ////////////////////////////////////////////////////////////////////////////////////////////
738
    // ENC_
739
    ////////////////////////////////////////////////////////////////////////////////////////////
2039 tk 740
    } else if( strncasecmp(parameter, "ENC_", 4) == 0 ) {
496 tk 741
      parameter += 4;
742
 
743
      char *word = strtok_r(NULL, separators, &brkt);
744
      s32 sr = get_dec(word);
1864 tk 745
      if( sr < 0 || sr > MIOS32_SRIO_NUM_SR ) {
492 tk 746
#if DEBUG_VERBOSE_LEVEL >= 1
513 tk 747
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in ENC_%s definition: invalid first value '%s'!", parameter, word);
492 tk 748
#endif
749
        continue;
750
      }
751
 
2039 tk 752
      if( strcasecmp(parameter, "DATAWHEEL_FAST_SPEED") == 0 ) {
513 tk 753
        seq_hwcfg_enc.datawheel_fast_speed = sr;
754
        continue;
755
      }
2039 tk 756
      if( strcasecmp(parameter, "BPM_FAST_SPEED") == 0 ) {
1341 tk 757
        seq_hwcfg_enc.bpm_fast_speed = sr;
758
        continue;
759
      }
2039 tk 760
      if( strcasecmp(parameter, "GP_FAST_SPEED") == 0 ) {
513 tk 761
        seq_hwcfg_enc.gp_fast_speed = sr;
762
        continue;
763
      }
2039 tk 764
      if( strcasecmp(parameter, "AUTO_FAST") == 0 ) {
513 tk 765
        seq_hwcfg_enc.auto_fast = sr;
766
        continue;
767
      }
768
 
496 tk 769
      word = strtok_r(NULL, separators, &brkt);
770
      s32 pin = get_dec(word);
771
      if( pin < 0 || pin >= 8 ) { // should we check for odd pin values (1/3/5/7) as well?
492 tk 772
#if DEBUG_VERBOSE_LEVEL >= 1
513 tk 773
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in ENC_%s definition: invalid pin value '%s'!", parameter, word);
492 tk 774
#endif
775
        continue;
776
      }
777
 
496 tk 778
      word = strtok_r(NULL, separators, &brkt);
492 tk 779
      mios32_enc_type_t enc_type = DISABLED;
496 tk 780
      if( word == NULL ) {
492 tk 781
#if DEBUG_VERBOSE_LEVEL >= 1
496 tk 782
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in ENC_%s definition: missing encoder type!", parameter);
492 tk 783
#endif
784
        continue;
2039 tk 785
      } else if( strcasecmp(word, "NON_DETENTED") == 0 ) {
492 tk 786
        enc_type = NON_DETENTED;
2039 tk 787
      } else if( strcasecmp(word, "DETENTED1") == 0 ) {
492 tk 788
        enc_type = DETENTED1;
2039 tk 789
      } else if( strcasecmp(word, "DETENTED2") == 0 ) {
492 tk 790
        enc_type = DETENTED2;
2039 tk 791
      } else if( strcasecmp(word, "DETENTED3") == 0 ) {
492 tk 792
        enc_type = DETENTED3;
2135 tk 793
      } else if( strcasecmp(word, "DETENTED4") == 0 ) {
794
        enc_type = DETENTED4;
795
      } else if( strcasecmp(word, "DETENTED5") == 0 ) {
796
        enc_type = DETENTED5;
492 tk 797
      } else {
798
#if DEBUG_VERBOSE_LEVEL >= 1
496 tk 799
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in ENC_%s definition: invalid type '%s'!", parameter, word);
492 tk 800
#endif
801
        continue;
802
      }
803
 
804
#if DEBUG_VERBOSE_LEVEL >= 3
496 tk 805
      DEBUG_MSG("[SEQ_FILE_HW] ENC %s: SR %d Pin %d Type %d", parameter, sr, pin, enc_type);
492 tk 806
#endif
807
 
808
      mios32_enc_config_t enc_config = { .cfg.type=enc_type, .cfg.speed=NORMAL, .cfg.speed_par=0, .cfg.sr=sr, .cfg.pos=pin };
809
 
2039 tk 810
      if( strcasecmp(parameter, "DATAWHEEL") == 0 ) {
492 tk 811
        MIOS32_ENC_ConfigSet(0, enc_config);
2039 tk 812
      } else if( strcasecmp(parameter, "BPM") == 0 ) {
1341 tk 813
        MIOS32_ENC_ConfigSet(17, enc_config);
2039 tk 814
      } else if( strncasecmp(parameter, "GP", 2) == 0 ) {
496 tk 815
        parameter += 2;
492 tk 816
 
496 tk 817
        int gp = atoi(parameter);
492 tk 818
        if( gp < 1 || gp > 16 ) {
819
#if DEBUG_VERBOSE_LEVEL >= 1
496 tk 820
          DEBUG_MSG("[SEQ_FILE_HW] ERROR: invalid ENC_GP number 'ENC_GP%s'!", parameter);
492 tk 821
#endif
822
        } else {
823
          MIOS32_ENC_ConfigSet(gp, enc_config);
824
        }
825
 
826
      } else {
827
#if DEBUG_VERBOSE_LEVEL >= 1
496 tk 828
        DEBUG_MSG("[SEQ_FILE_HW] ERROR: unknown ENC name 'ENC_%s'!", parameter);
492 tk 829
#endif
830
      }
831
 
496 tk 832
 
833
    ////////////////////////////////////////////////////////////////////////////////////////////
1164 tk 834
    // TRACKS_DOUT_[LR]_SR
835
    ////////////////////////////////////////////////////////////////////////////////////////////
2039 tk 836
    } else if( strcasecmp(parameter, "TRACKS_DOUT_L_SR") == 0 || strcasecmp(parameter, "TRACKS_DOUT_R_SR") == 0 ) {
1164 tk 837
      char *word = strtok_r(NULL, separators, &brkt);
838
      s32 sr = get_dec(word);
1864 tk 839
      if( sr < 0 || sr > MIOS32_SRIO_NUM_SR ) {
1164 tk 840
#if DEBUG_VERBOSE_LEVEL >= 1
841
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in %s definition: invalid SR value '%s'!", parameter, word);
842
#endif
843
        continue;
844
      }
2039 tk 845
      if( strcasecmp(parameter, "TRACKS_DOUT_L_SR") == 0 ) {
1164 tk 846
        seq_hwcfg_led.tracks_dout_l_sr = sr;
847
      } else {
848
        seq_hwcfg_led.tracks_dout_r_sr = sr;
849
      }
850
 
851
    ////////////////////////////////////////////////////////////////////////////////////////////
1864 tk 852
    // SRIO_NUM_SR
853
    ////////////////////////////////////////////////////////////////////////////////////////////
2039 tk 854
    } else if( strcasecmp(parameter, "SRIO_NUM_SR") == 0 ) {
1864 tk 855
      char *word = strtok_r(NULL, separators, &brkt);
856
      s32 num_sr = get_dec(word);
857
      if( num_sr < 1 || num_sr > MIOS32_SRIO_NUM_SR ) {
858
#if DEBUG_VERBOSE_LEVEL >= 1
859
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in SRIO_NUM_SR definition: invalid value '%s'!", word);
860
#endif
861
        continue;
862
      }
863
 
864
#if DEBUG_VERBOSE_LEVEL >= 3
865
      DEBUG_MSG("[SEQ_FILE_HW] SRIO_NUM_SR %d", num_sr);
866
#endif
867
 
868
      MIOS32_SRIO_ScanNumSet(num_sr);
869
 
870
      // clear all DOUTs (for the case that the number has been decreased)
871
      int i;
872
      for(i=0; i<MIOS32_SRIO_NUM_SR; ++i)
873
        MIOS32_DOUT_SRSet(i, 0x00);
874
 
875
    ////////////////////////////////////////////////////////////////////////////////////////////
514 tk 876
    // GP_DOUT_
496 tk 877
    ////////////////////////////////////////////////////////////////////////////////////////////
2039 tk 878
    } else if( strncasecmp(parameter, "GP_DOUT_", 8) == 0 ) {
514 tk 879
      parameter += 8;
496 tk 880
 
881
      char *word = strtok_r(NULL, separators, &brkt);
882
      s32 sr = get_dec(word);
1864 tk 883
      if( sr < 0 || sr > MIOS32_SRIO_NUM_SR ) {
496 tk 884
#if DEBUG_VERBOSE_LEVEL >= 1
514 tk 885
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in GP_DOUT_%s definition: invalid SR value '%s'!", parameter, word);
496 tk 886
#endif
887
        continue;
888
      }
889
 
890
#if DEBUG_VERBOSE_LEVEL >= 3
514 tk 891
      DEBUG_MSG("[SEQ_FILE_HW] GP_DOUT_%s: SR %d", parameter, sr);
496 tk 892
#endif
893
 
2039 tk 894
      if( strcasecmp(parameter, "L_SR") == 0 ) {
514 tk 895
        seq_hwcfg_led.gp_dout_l_sr = sr;
2039 tk 896
      } else if( strcasecmp(parameter, "R_SR") == 0 ) {
514 tk 897
        seq_hwcfg_led.gp_dout_r_sr = sr;
2039 tk 898
      } else if( strcasecmp(parameter, "L2_SR") == 0 ) {
514 tk 899
        seq_hwcfg_led.gp_dout_l2_sr = sr;
2039 tk 900
      } else if( strcasecmp(parameter, "R2_SR") == 0 ) {
514 tk 901
        seq_hwcfg_led.gp_dout_r2_sr = sr;
496 tk 902
      } else {
903
#if DEBUG_VERBOSE_LEVEL >= 1
514 tk 904
        DEBUG_MSG("[SEQ_FILE_HW] ERROR: unknown GP_DOUT_* name '%s'!", parameter);
496 tk 905
#endif
906
      }
907
 
908
 
909
    ////////////////////////////////////////////////////////////////////////////////////////////
514 tk 910
    // BLM_
496 tk 911
    ////////////////////////////////////////////////////////////////////////////////////////////
2039 tk 912
    } else if( strncasecmp(parameter, "BLM_", 4) == 0 ) {
496 tk 913
      parameter += 4;
914
 
915
      char *word = strtok_r(NULL, separators, &brkt);
916
      s32 value = get_dec(word);
917
      if( value < 0 ) {
918
#if DEBUG_VERBOSE_LEVEL >= 1
514 tk 919
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in BLM_%s definition: invalid value '%s'!", parameter, word);
496 tk 920
#endif
921
        continue;
922
      }
923
 
924
#if DEBUG_VERBOSE_LEVEL >= 3
514 tk 925
      DEBUG_MSG("[SEQ_FILE_HW] BLM_%s: %d", parameter, value);
496 tk 926
#endif
927
 
2039 tk 928
      if( strcasecmp(parameter, "ENABLED") == 0 ) {
514 tk 929
        seq_hwcfg_blm.enabled = value;
2039 tk 930
      } else if( strcasecmp(parameter, "DOUT_L1_SR") == 0 ) {
524 tk 931
        blm_config_t config = BLM_ConfigGet();
932
        config.dout_l1_sr = value;
933
        BLM_ConfigSet(config);
2039 tk 934
      } else if( strcasecmp(parameter, "DOUT_R1_SR") == 0 ) {
524 tk 935
        blm_config_t config = BLM_ConfigGet();
936
        config.dout_r1_sr = value;
937
        BLM_ConfigSet(config);
2039 tk 938
      } else if( strcasecmp(parameter, "DOUT_CATHODES_SR1") == 0 ) {
524 tk 939
        blm_config_t config = BLM_ConfigGet();
940
        config.dout_cathodes_sr1 = value;
941
        BLM_ConfigSet(config);
2039 tk 942
      } else if( strcasecmp(parameter, "DOUT_CATHODES_SR2") == 0 ) {
524 tk 943
        blm_config_t config = BLM_ConfigGet();
944
        config.dout_cathodes_sr2 = value;
945
        BLM_ConfigSet(config);
2039 tk 946
      } else if( strcasecmp(parameter, "DOUT_CATHODES_INV_MASK") == 0 ) {
524 tk 947
        blm_config_t config = BLM_ConfigGet();
948
        config.cathodes_inv_mask = value;
949
        BLM_ConfigSet(config);
2039 tk 950
      } else if( strcasecmp(parameter, "DOUT_DUOCOLOUR") == 0 ) {
514 tk 951
        seq_hwcfg_blm.dout_duocolour = value;
2039 tk 952
      } else if( strcasecmp(parameter, "DOUT_L2_SR") == 0 ) {
524 tk 953
        blm_config_t config = BLM_ConfigGet();
954
        config.dout_l2_sr = value;
955
        BLM_ConfigSet(config);
2039 tk 956
      } else if( strcasecmp(parameter, "DOUT_R2_SR") == 0 ) {
524 tk 957
        blm_config_t config = BLM_ConfigGet();
958
        config.dout_r2_sr = value;
959
        BLM_ConfigSet(config);
2039 tk 960
      } else if( strcasecmp(parameter, "BUTTONS_ENABLED") == 0 ) {
514 tk 961
        seq_hwcfg_blm.buttons_enabled = value;
2039 tk 962
      } else if( strcasecmp(parameter, "BUTTONS_NO_UI") == 0 ) {
514 tk 963
        seq_hwcfg_blm.buttons_no_ui = value;
2039 tk 964
      } else if( strcasecmp(parameter, "GP_ALWAYS_SELECT_MENU_PAGE") == 0 ) {
1675 tk 965
        seq_hwcfg_blm.gp_always_select_menu_page = value;
2039 tk 966
      } else if( strcasecmp(parameter, "DIN_L_SR") == 0 ) {
524 tk 967
        blm_config_t config = BLM_ConfigGet();
968
        config.din_l_sr = value;
969
        BLM_ConfigSet(config);
2039 tk 970
      } else if( strcasecmp(parameter, "DIN_R_SR") == 0 ) {
524 tk 971
        blm_config_t config = BLM_ConfigGet();
972
        config.din_r_sr = value;
973
        BLM_ConfigSet(config);
784 tk 974
 
514 tk 975
      } else {
976
#if DEBUG_VERBOSE_LEVEL >= 1
977
        DEBUG_MSG("[SEQ_FILE_HW] ERROR: unknown BLM_* name '%s'!", parameter);
978
#endif
979
      }
980
 
981
 
982
    ////////////////////////////////////////////////////////////////////////////////////////////
983
    // BLM8X8_
984
    ////////////////////////////////////////////////////////////////////////////////////////////
2039 tk 985
    } else if( strncasecmp(parameter, "BLM8X8_", 7) == 0 ) {
514 tk 986
      parameter += 7;
987
 
988
      char *word = strtok_r(NULL, separators, &brkt);
989
      s32 value = get_dec(word);
990
      if( value < 0 ) {
991
#if DEBUG_VERBOSE_LEVEL >= 1
992
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in BLM8X8_%s definition: invalid value '%s'!", parameter, word);
993
#endif
994
        continue;
995
      }
996
 
997
#if DEBUG_VERBOSE_LEVEL >= 3
998
      DEBUG_MSG("[SEQ_FILE_HW] BLM8X8_%s: %d", parameter, value);
999
#endif
1000
 
2039 tk 1001
      if( strcasecmp(parameter, "ENABLED") == 0 ) {
514 tk 1002
        seq_hwcfg_blm8x8.enabled = value;
2039 tk 1003
      } else if( strcasecmp(parameter, "DOUT_CATHODES_SR") == 0 ) {
513 tk 1004
        blm_x_config_t config = BLM_X_ConfigGet();
1005
        config.rowsel_dout_sr = value;
1006
        BLM_X_ConfigSet(config);
2039 tk 1007
      } else if( strcasecmp(parameter, "DOUT_CATHODES_INV_MASK") == 0 ) {
513 tk 1008
        blm_x_config_t config = BLM_X_ConfigGet();
1009
        config.rowsel_inv_mask = value;
1010
        BLM_X_ConfigSet(config);
2039 tk 1011
      } else if( strcasecmp(parameter, "DOUT_LED_SR") == 0 ) {
513 tk 1012
        blm_x_config_t config = BLM_X_ConfigGet();
514 tk 1013
        config.led_first_dout_sr = value;
1014
        BLM_X_ConfigSet(config);
2039 tk 1015
      } else if( strcasecmp(parameter, "DOUT_GP_MAPPING") == 0 ) {
514 tk 1016
        seq_hwcfg_blm8x8.dout_gp_mapping = value;
2039 tk 1017
      } else if( strcasecmp(parameter, "DIN_SR") == 0 ) {
514 tk 1018
        blm_x_config_t config = BLM_X_ConfigGet();
513 tk 1019
        config.btn_first_din_sr = value;
1020
        BLM_X_ConfigSet(config);
496 tk 1021
      } else {
1022
#if DEBUG_VERBOSE_LEVEL >= 1
514 tk 1023
        DEBUG_MSG("[SEQ_FILE_HW] ERROR: unknown BLM8X8_* name '%s'!", parameter);
496 tk 1024
#endif
1025
      }
1026
 
1027
    ////////////////////////////////////////////////////////////////////////////////////////////
1336 tk 1028
    // BPM_DIGITS_
1029
    ////////////////////////////////////////////////////////////////////////////////////////////
2039 tk 1030
    } else if( strncasecmp(parameter, "BPM_DIGITS_", 11) == 0 ) {
1336 tk 1031
      parameter += 11;
1032
 
1033
      char *word = strtok_r(NULL, separators, &brkt);
1034
      s32 value = get_dec(word);
1035
      if( value < 0 ) {
1036
#if DEBUG_VERBOSE_LEVEL >= 1
1037
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in BPM_DIGITS_%s definition: invalid value '%s'!", parameter, word);
1038
#endif
1039
        continue;
1040
      }
1041
 
1042
#if DEBUG_VERBOSE_LEVEL >= 3
1043
      DEBUG_MSG("[SEQ_FILE_HW] BPM_DIGITS_%s: %d", parameter, value);
1044
#endif
1045
 
2039 tk 1046
      if( strcasecmp(parameter, "ENABLED") == 0 ) {
1336 tk 1047
        seq_hwcfg_bpm_digits.enabled = value;
2039 tk 1048
      } else if( strcasecmp(parameter, "SEGMENTS_SR") == 0 ) {
1336 tk 1049
        seq_hwcfg_bpm_digits.segments_sr = value;
2039 tk 1050
      } else if( strcasecmp(parameter, "COMMON1_PIN") == 0 ||
1051
             strcasecmp(parameter, "COMMON2_PIN") == 0 ||
1052
             strcasecmp(parameter, "COMMON3_PIN") == 0 ||
1053
             strcasecmp(parameter, "COMMON4_PIN") == 0 ) {
1336 tk 1054
 
1055
        word = strtok_r(NULL, separators, &brkt);
1056
        s32 pin = get_dec(word);
1057
        if( pin < 0 || pin >= 8 ) {
1058
#if DEBUG_VERBOSE_LEVEL >= 1
1341 tk 1059
          DEBUG_MSG("[SEQ_FILE_HW] ERROR in BPM_DIGITS_%s definition: invalid pin value '%s'!", parameter, word);
1336 tk 1060
#endif
1061
          continue;
1062
        }
1063
        u8 dout_value = ((value-1)<<3) | pin;
1064
 
2039 tk 1065
        if( strcasecmp(parameter, "COMMON1_PIN") == 0 ) {
1336 tk 1066
          seq_hwcfg_bpm_digits.common1_pin = dout_value;
2039 tk 1067
        } else if( strcasecmp(parameter, "COMMON2_PIN") == 0 ) {
1336 tk 1068
          seq_hwcfg_bpm_digits.common2_pin = dout_value;
2039 tk 1069
        } else if( strcasecmp(parameter, "COMMON3_PIN") == 0 ) {
1336 tk 1070
          seq_hwcfg_bpm_digits.common3_pin = dout_value;
2039 tk 1071
        } else if( strcasecmp(parameter, "COMMON4_PIN") == 0 ) {
1341 tk 1072
          seq_hwcfg_bpm_digits.common4_pin = dout_value;
1336 tk 1073
        }
1074
      } else {
1075
#if DEBUG_VERBOSE_LEVEL >= 1
1341 tk 1076
        DEBUG_MSG("[SEQ_FILE_HW] ERROR: unknown BPM_DIGITS_* name '%s'!", parameter);
1336 tk 1077
#endif
1078
      }
1079
 
1080
    ////////////////////////////////////////////////////////////////////////////////////////////
1341 tk 1081
    // STEP_DIGITS_
1082
    ////////////////////////////////////////////////////////////////////////////////////////////
2039 tk 1083
    } else if( strncasecmp(parameter, "STEP_DIGITS_", 12) == 0 ) {
1341 tk 1084
      parameter += 12;
1085
 
1086
      char *word = strtok_r(NULL, separators, &brkt);
1087
      s32 value = get_dec(word);
1088
      if( value < 0 ) {
1089
#if DEBUG_VERBOSE_LEVEL >= 1
1090
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in STEP_DIGITS_%s definition: invalid value '%s'!", parameter, word);
1091
#endif
1092
        continue;
1093
      }
1094
 
1095
#if DEBUG_VERBOSE_LEVEL >= 3
1096
      DEBUG_MSG("[SEQ_FILE_HW] STEP_DIGITS_%s: %d", parameter, value);
1097
#endif
1098
 
2039 tk 1099
      if( strcasecmp(parameter, "ENABLED") == 0 ) {
1341 tk 1100
        seq_hwcfg_step_digits.enabled = value;
2039 tk 1101
      } else if( strcasecmp(parameter, "SEGMENTS_SR") == 0 ) {
1341 tk 1102
        seq_hwcfg_step_digits.segments_sr = value;
2039 tk 1103
      } else if( strcasecmp(parameter, "COMMON1_PIN") == 0 ||
1104
             strcasecmp(parameter, "COMMON2_PIN") == 0 ||
1105
             strcasecmp(parameter, "COMMON3_PIN") == 0 ) {
1341 tk 1106
 
1107
        word = strtok_r(NULL, separators, &brkt);
1108
        s32 pin = get_dec(word);
1109
        if( pin < 0 || pin >= 8 ) {
1110
#if DEBUG_VERBOSE_LEVEL >= 1
1111
          DEBUG_MSG("[SEQ_FILE_HW] ERROR in STEP_DIGITS_%s definition: invalid pin value '%s'!", parameter, word);
1112
#endif
1113
          continue;
1114
        }
1115
        u8 dout_value = ((value-1)<<3) | pin;
1116
 
2039 tk 1117
        if( strcasecmp(parameter, "COMMON1_PIN") == 0 ) {
1341 tk 1118
          seq_hwcfg_step_digits.common1_pin = dout_value;
2039 tk 1119
        } else if( strcasecmp(parameter, "COMMON2_PIN") == 0 ) {
1341 tk 1120
          seq_hwcfg_step_digits.common2_pin = dout_value;
2039 tk 1121
        } else if( strcasecmp(parameter, "COMMON3_PIN") == 0 ) {
1341 tk 1122
          seq_hwcfg_step_digits.common3_pin = dout_value;
1123
        }
1124
      } else {
1125
#if DEBUG_VERBOSE_LEVEL >= 1
1126
        DEBUG_MSG("[SEQ_FILE_HW] ERROR: unknown STEP_DIGITS_* name '%s'!", parameter);
1127
#endif
1128
      }
1345 tk 1129
    ////////////////////////////////////////////////////////////////////////////////////////////
1130
    // TPD_
1131
    ////////////////////////////////////////////////////////////////////////////////////////////
2039 tk 1132
    } else if( strncasecmp(parameter, "TPD_", 4) == 0 ) {
1345 tk 1133
      parameter += 4;
1341 tk 1134
 
1345 tk 1135
      char *word = strtok_r(NULL, separators, &brkt);
1136
      s32 value = get_dec(word);
1137
      if( value < 0 ) {
1138
#if DEBUG_VERBOSE_LEVEL >= 1
1139
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in TPD_%s definition: invalid value '%s'!", parameter, word);
1140
#endif
1141
        continue;
1142
      }
1143
 
1144
#if DEBUG_VERBOSE_LEVEL >= 3
1145
      DEBUG_MSG("[SEQ_FILE_HW] TPD_%s: %d", parameter, value);
1146
#endif
1147
 
2039 tk 1148
      if( strcasecmp(parameter, "ENABLED") == 0 ) {
1345 tk 1149
        seq_hwcfg_tpd.enabled = value;
2039 tk 1150
      } else if( strcasecmp(parameter, "COLUMNS_SR") == 0 || strcasecmp(parameter, "COLUMNS_SR_L") == 0 ) {
1864 tk 1151
        seq_hwcfg_tpd.columns_sr[0] = value;
2039 tk 1152
      } else if( strcasecmp(parameter, "COLUMNS_SR_R") == 0 ) {
1864 tk 1153
        seq_hwcfg_tpd.columns_sr[1] = value;
2039 tk 1154
      } else if( strcasecmp(parameter, "ROWS_SR") == 0 || strcasecmp(parameter, "ROWS_SR_GREEN_L") == 0 ) {
1864 tk 1155
        seq_hwcfg_tpd.rows_sr_green[0] = value;
2039 tk 1156
      } else if( strcasecmp(parameter, "ROWS_SR_GREEN_R") == 0 ) {
1864 tk 1157
        seq_hwcfg_tpd.rows_sr_green[1] = value;
2039 tk 1158
      } else if( strcasecmp(parameter, "ROWS_SR_RED_L") == 0 ) {
1864 tk 1159
        seq_hwcfg_tpd.rows_sr_red[0] = value;
2039 tk 1160
      } else if( strcasecmp(parameter, "ROWS_SR_RED_R") == 0 ) {
1864 tk 1161
        seq_hwcfg_tpd.rows_sr_red[1] = value;
1345 tk 1162
      } else {
1163
#if DEBUG_VERBOSE_LEVEL >= 1
1164
        DEBUG_MSG("[SEQ_FILE_HW] ERROR: unknown STEP_TPM_* name '%s'!", parameter);
1165
#endif
1166
      }  
1167
 
1341 tk 1168
    ////////////////////////////////////////////////////////////////////////////////////////////
507 tk 1169
    // misc
1170
    ////////////////////////////////////////////////////////////////////////////////////////////
2039 tk 1171
    } else if( strcasecmp(parameter, "MIDI_REMOTE_KEY") == 0 ) {
741 tk 1172
      char *word = strtok_r(NULL, separators, &brkt);
1173
      s32 key = get_dec(word);
1174
      if( key < 0 || key >= 128 ) {
1175
#if DEBUG_VERBOSE_LEVEL >= 1
1176
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in %s definition: invalid remote key '%s'!", parameter, word);
1177
#endif
1178
        continue;
1179
      }
1180
 
1181
      seq_hwcfg_midi_remote.key = key;
1182
 
2039 tk 1183
    } else if( strcasecmp(parameter, "MIDI_REMOTE_CC") == 0 ) {
741 tk 1184
      char *word = strtok_r(NULL, separators, &brkt);
1185
      s32 cc = get_dec(word);
1186
      if( cc < 0 || cc >= 128 ) {
1187
#if DEBUG_VERBOSE_LEVEL >= 1
1188
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in %s definition: invalid remote CC '%s'!", parameter, word);
1189
#endif
1190
        continue;
1191
      }
1192
 
1193
      seq_hwcfg_midi_remote.cc = cc;
1194
 
2039 tk 1195
    } else if( strcasecmp(parameter, "TRACK_CC_MODE") == 0 ) {
1713 tk 1196
      char *word = strtok_r(NULL, separators, &brkt);
1197
      s32 mode = get_dec(word);
1198
      if( mode < 0 || mode > 2 ) {
1199
#if DEBUG_VERBOSE_LEVEL >= 1
1200
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in %s definition: invalid Track CC mode '%s'!", parameter, word);
1201
#endif
1202
        continue;
1203
      }
1204
 
1205
      seq_hwcfg_track_cc.mode = mode;
1206
 
2039 tk 1207
    } else if( strcasecmp(parameter, "TRACK_CC_PORT") == 0 ) {
1713 tk 1208
      char *word = strtok_r(NULL, separators, &brkt);
2039 tk 1209
      s32 port = SEQ_MIDI_PORT_OutPortFromNameGet(word);
1713 tk 1210
 
1211
      if( port < 0 || port >= 0x100 ) {
1212
#if DEBUG_VERBOSE_LEVEL >= 1
1213
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in %s definition: invalid port number '%s'!", parameter, word);
1214
#endif
1215
        continue;
1216
      }
1217
 
1218
      seq_hwcfg_track_cc.port = port;
1219
 
2039 tk 1220
    } else if( strcasecmp(parameter, "TRACK_CC_CHANNEL") == 0 ) {
1713 tk 1221
      char *word = strtok_r(NULL, separators, &brkt);
1222
      s32 chn = get_dec(word);
1223
      if( chn < 1 || chn > 16 ) {
1224
#if DEBUG_VERBOSE_LEVEL >= 1
1225
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in %s definition: invalid Track CC channel '%s'!", parameter, word);
1226
#endif
1227
        continue;
1228
      }
1229
 
1230
      seq_hwcfg_track_cc.chn = chn-1; // counting from 1 for user, from 0 for app
1231
 
2039 tk 1232
    } else if( strcasecmp(parameter, "TRACK_CC_NUMBER") == 0 ) {
1713 tk 1233
      char *word = strtok_r(NULL, separators, &brkt);
1234
      s32 cc = get_dec(word);
1235
      if( cc < 0 || cc >= 128 ) {
1236
#if DEBUG_VERBOSE_LEVEL >= 1
1237
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in %s definition: invalid Track CC number '%s'!", parameter, word);
1238
#endif
1239
        continue;
1240
      }
1241
 
1242
      seq_hwcfg_track_cc.cc = cc;
1243
 
2039 tk 1244
    } else if( strcasecmp(parameter, "RS_OPTIMISATION") == 0 ) {
1025 tk 1245
      char *word = strtok_r(NULL, separators, &brkt);
2039 tk 1246
      s32 port = SEQ_MIDI_PORT_OutPortFromNameGet(word);
1025 tk 1247
 
1248
      if( port < 0 || port >= 0x100 ) {
1249
#if DEBUG_VERBOSE_LEVEL >= 1
1250
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in %s definition: invalid port number '%s'!", parameter, word);
1251
#endif
1252
        continue;
1253
      }
1254
 
1255
      word = strtok_r(NULL, separators, &brkt);
1256
      s32 enable = get_dec(word);
1257
      if( enable != 0 && enable != 1 ) {
1258
#if DEBUG_VERBOSE_LEVEL >= 1
1259
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in %s definition: invalid enable flag '%s', expecting 1 or 0!", parameter, word);
1260
#endif
1261
        continue;
1262
      }
1263
 
1264
      s32 status;
1265
      if( (status=MIOS32_MIDI_RS_OptimisationSet(port, enable)) < 0 ) {
1266
#if DEBUG_VERBOSE_LEVEL >= 1
1346 tk 1267
        if( port != 0x23 ) // this port is only available for LPC17, not for STM32
1268
          DEBUG_MSG("[SEQ_FILE_HW] RS_OPTIMISATION 0x%02x %d failed with status %d!", port, enable, status);
1025 tk 1269
#endif
1270
      }
1271
 
2039 tk 1272
    } else if( strcasecmp(parameter, "DEBOUNCE_DELAY") == 0 ) {
1126 tk 1273
      char *word = strtok_r(NULL, separators, &brkt);
1274
      s32 delay = get_dec(word);
1275
      if( delay < 0 || delay >= 128 ) {
1276
#if DEBUG_VERBOSE_LEVEL >= 1
1277
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in %s definition: invalid delay value '%s'!", parameter, word);
1278
#endif
1279
        continue;
1280
      }
1281
 
1531 tk 1282
      // common DINs
1126 tk 1283
      MIOS32_SRIO_DebounceSet(delay);
1284
 
1531 tk 1285
      // BLM_X based DINs
1286
      blm_x_config_t config = BLM_X_ConfigGet();
1287
      config.debounce_delay = delay;
1288
      BLM_X_ConfigSet(config);
1289
 
2039 tk 1290
    } else if( strcasecmp(parameter, "AOUT_INTERFACE_TYPE") == 0 ) {
1083 tk 1291
      // only for compatibility reasons - AOUT interface is stored in MBSEQ_GC.V4 now!
1292
      // can be removed once most users switched to beta28 and later!
1293
 
507 tk 1294
      char *word = strtok_r(NULL, separators, &brkt);
1295
      s32 aout_type = get_dec(word);
1296
      if( aout_type < 0 || aout_type >= 4 ) {
1297
#if DEBUG_VERBOSE_LEVEL >= 1
1298
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in %s definition: invalid AOUT interface type '%s'!", parameter, word);
1299
#endif
1300
        continue;
1301
      }
1302
 
1303
      aout_config_t config;
1304
      config = AOUT_ConfigGet();
1305
      config.if_type = aout_type;
1306
      config.if_option = (config.if_type == AOUT_IF_74HC595) ? 0xffffffff : 0x00000000; // AOUT_LC: select 8/8 bit configuration
1307
      config.num_channels = 8;
1308
      config.chn_inverted = 0;
1309
      AOUT_ConfigSet(config);
1310
      AOUT_IF_Init(0);
1311
 
2088 tk 1312
    } else if( strncasecmp(parameter, "CV_GATE_SR", 10) == 0 && // CV_GATE_SR%d
1313
             (hlp=atoi(parameter+10)) >= 1 && hlp <= SEQ_HWCFG_NUM_SR_CV_GATES ) {
1314
 
1315
      char *word = strtok_r(NULL, separators, &brkt);
1316
      s32 sr = get_dec(word);
1317
      if( sr < 0 || sr > MIOS32_SRIO_NUM_SR ) {
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_cv_gate_sr[hlp-1] = sr;
1325
 
1326
    } else if( strcasecmp(parameter, "CLK_SR") == 0 ) {
1327
      char *word = strtok_r(NULL, separators, &brkt);
1328
      s32 sr = get_dec(word);
1329
      if( sr < 0 || sr > MIOS32_SRIO_NUM_SR ) {
1330
#if DEBUG_VERBOSE_LEVEL >= 1
1331
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in %s definition: invalid SR value '%s'!", parameter, word);
1332
#endif
1333
        continue;
1334
      }
1335
 
1336
        seq_hwcfg_clk_sr = sr;
1337
 
2039 tk 1338
    } else if( strncasecmp(parameter, "DOUT_GATE_SR", 12) == 0 && // DOUT_GATE_SR%d
507 tk 1339
             (hlp=atoi(parameter+12)) >= 1 && hlp <= SEQ_HWCFG_NUM_SR_DOUT_GATES ) {
1340
 
1341
      char *word = strtok_r(NULL, separators, &brkt);
1342
      s32 sr = get_dec(word);
1864 tk 1343
      if( sr < 0 || sr > MIOS32_SRIO_NUM_SR ) {
507 tk 1344
#if DEBUG_VERBOSE_LEVEL >= 1
1345
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in %s definition: invalid SR value '%s'!", parameter, word);
1346
#endif
1347
        continue;
1348
      }
1349
 
1350
        seq_hwcfg_dout_gate_sr[hlp-1] = sr;
1351
 
2039 tk 1352
    } else if( strcasecmp(parameter, "J5_ENABLED") == 0 ) {
507 tk 1353
      char *word = strtok_r(NULL, separators, &brkt);
1354
      s32 j5_enabled = get_dec(word);
1355
      if( j5_enabled < 0 || j5_enabled > 2 ) {
1356
#if DEBUG_VERBOSE_LEVEL >= 1
1357
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in %s definition: expecting 0, 1 or 2!", parameter);
1358
#endif
1359
        continue;
1360
      }
1361
 
2268 tk 1362
      // copy to global variable (used in seq_cv)
1363
      seq_hwcfg_j5_enabled = j5_enabled;
507 tk 1364
 
2268 tk 1365
      if( j5_enabled ) {
1366
        int i;
1367
        mios32_board_pin_mode_t pin_mode = MIOS32_BOARD_PIN_MODE_INPUT_PD;
1368
        if( j5_enabled == 1 )
1369
          pin_mode = MIOS32_BOARD_PIN_MODE_OUTPUT_PP;
1370
        if( j5_enabled == 2 )
1371
          pin_mode = MIOS32_BOARD_PIN_MODE_OUTPUT_OD;
507 tk 1372
 
2268 tk 1373
        for(i=0; i<6; ++i) {
1374
          MIOS32_BOARD_J5_PinInit(i, pin_mode);
1375
          MIOS32_BOARD_J5_PinSet(i, 0);
1376
        }
1377
 
2088 tk 1378
#if defined(MIOS32_FAMILY_STM32F10x)
2268 tk 1379
        // pin J5.A6 and J5.A7 used for UART2 (-> MIDI OUT3)
1380
        for(i=8; i<12; ++i) {
1381
          MIOS32_BOARD_J5_PinInit(i, pin_mode);
1382
          MIOS32_BOARD_J5_PinSet(i, 0);
1383
        }
2088 tk 1384
#elif defined(MIOS32_FAMILY_STM32F4xx)
2268 tk 1385
        // pin J5.A6 and J5.A7 used as gates
1386
        for(i=6; i<8; ++i) {
1387
          MIOS32_BOARD_J5_PinInit(i, pin_mode);
1388
          MIOS32_BOARD_J5_PinSet(i, 0);
1389
        }
1390
        // and J10B for additional outputs
1391
        for(i=8; i<16; ++i) {
1392
          MIOS32_BOARD_J10_PinInit(i, pin_mode);
1393
          MIOS32_BOARD_J10_PinSet(i, 0);
1394
        }
1311 tk 1395
#elif defined(MIOS32_FAMILY_LPC17xx)
2268 tk 1396
        // and pin J28 for additional outputs
1397
        for(i=0; i<4; ++i) {
1398
          MIOS32_BOARD_J28_PinInit(i, pin_mode);
1399
          MIOS32_BOARD_J28_PinSet(i, 0);
1400
        }
1311 tk 1401
#else
1402
# warning "please adapt for this MIOS32_FAMILY"
1403
#endif
2268 tk 1404
      }
1071 tk 1405
 
2039 tk 1406
    } else if( strcasecmp(parameter, "DIN_SYNC_CLK_PULSEWIDTH") == 0 ) {
1083 tk 1407
      // only for compatibility reasons - AOUT interface is stored in MBSEQ_GC.V4 now!
1408
      // can be removed once most users switched to beta28 and later!
1409
 
784 tk 1410
      char *word = strtok_r(NULL, separators, &brkt);
1411
      s32 pulsewidth = get_dec(word);
1412
      if( pulsewidth < 1 || pulsewidth > 250 ) {
1413
#if DEBUG_VERBOSE_LEVEL >= 1
1414
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in %s definition: expecting pulsewidth of 1..250!", parameter);
1415
#endif
1416
        continue;
1417
      }
1418
 
2098 tk 1419
      SEQ_CV_ClkPulseWidthSet(0, pulsewidth);
784 tk 1420
 
2039 tk 1421
    } else if( strcasecmp(parameter, "DOUT_1MS_TRIGGER") == 0 ) {
507 tk 1422
 
1423
      char *word = strtok_r(NULL, separators, &brkt);
1424
      s32 trg_enabled = get_dec(word);
1425
      if( trg_enabled < 0 || trg_enabled > 1 ) {
1426
#if DEBUG_VERBOSE_LEVEL >= 1
1427
        DEBUG_MSG("[SEQ_FILE_HW] ERROR in %s definition: expecting 0 or 1!", parameter);
1428
#endif
1429
        continue;
1430
      }
1431
 
1432
      seq_hwcfg_dout_gate_1ms = trg_enabled;
1433
 
1434
 
1435
    ////////////////////////////////////////////////////////////////////////////////////////////
496 tk 1436
    // unknown
1437
    ////////////////////////////////////////////////////////////////////////////////////////////
492 tk 1438
    } else {
1439
#if DEBUG_VERBOSE_LEVEL >= 1
496 tk 1440
      DEBUG_MSG("[SEQ_FILE_HW] ERROR: unknown parameter: %s", line_buffer);
492 tk 1441
#endif
1442
    }
1443
      } else {
1444
#if DEBUG_VERBOSE_LEVEL >= 1
1445
    DEBUG_MSG("[SEQ_FILE_HW] ERROR: no space separator in following line: %s", line_buffer);
1446
#endif
1447
      }
1448
    }
1449
 
1450
  } while( status >= 1 );
1451
 
1261 tk 1452
  FILE_ReadClose(&file);
492 tk 1453
 
1454
  if( status < 0 ) {
1455
#if DEBUG_VERBOSE_LEVEL >= 1
1456
    DEBUG_MSG("[SEQ_FILE_HW] ERROR while reading file, status: %d\n", status);
1457
#endif
1458
    return SEQ_FILE_HW_ERR_READ;
1459
  }
1460
 
1461
  // file is valid! :)
1462
  info->valid = 1;
1463
 
1464
  return 0; // no error
1465
}