Subversion Repositories svn.mios32

Rev

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