Subversion Repositories svn.mios32

Rev

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

Rev Author Line No. Line
1083 tk 1
// $Id: seq_ui_cv.c 2098 2014-12-07 19:25:03Z tk $
2
/*
3
 * CV configuration page
4
 *
5
 * ==========================================================================
6
 *
7
 *  Copyright (C) 2008 Thorsten Klose (tk@midibox.org)
8
 *  Licensed for personal non-commercial use only.
9
 *  All other rights reserved.
10
 *
11
 * ==========================================================================
12
 */
13
 
14
/////////////////////////////////////////////////////////////////////////////
15
// Include files
16
/////////////////////////////////////////////////////////////////////////////
17
 
18
#include <mios32.h>
19
#include <aout.h>
20
#include "tasks.h"
21
 
22
#include "seq_lcd.h"
23
#include "seq_ui.h"
24
 
25
#include "seq_file_c.h"
26
#include "seq_file_gc.h"
27
 
28
#include "seq_cv.h"
29
 
30
 
31
/////////////////////////////////////////////////////////////////////////////
32
// Local definitions
33
/////////////////////////////////////////////////////////////////////////////
34
 
2098 tk 35
#define NUM_OF_ITEMS       10
1083 tk 36
#define ITEM_CV            0
37
#define ITEM_CURVE         1
38
#define ITEM_SLEWRATE      2
39
#define ITEM_PITCHRANGE    3
40
#define ITEM_GATE          4
41
#define ITEM_CALIBRATION   5
2098 tk 42
#define ITEM_CLK_SEL       6
43
#define ITEM_CLK_PPQN      7
44
#define ITEM_CLK_WIDTH     8
45
#define ITEM_MODULE        9
1083 tk 46
 
47
/////////////////////////////////////////////////////////////////////////////
48
// Local variables
49
/////////////////////////////////////////////////////////////////////////////
50
 
51
static u8 store_file_required;
52
static u8 selected_cv;
2098 tk 53
static u8 selected_clkout;
1083 tk 54
 
55
const u16 din_sync_div_presets[] =
2098 tk 56
  // 1    2    3    4   6   8  12  16  24  32  48  96  192  384 ppqn, StartStop(=0)
57
  { 384, 192, 128, 96, 64, 48, 32, 24, 16, 12,  8,  4,   2,  1, 0 };
1083 tk 58
 
59
 
60
 
61
/////////////////////////////////////////////////////////////////////////////
62
// Local LED handler function
63
/////////////////////////////////////////////////////////////////////////////
64
static s32 LED_Handler(u16 *gp_leds)
65
{
66
  if( ui_cursor_flash ) // if flashing flag active: no LED flag set
67
    return 0;
68
 
69
  switch( ui_selected_item ) {
70
    case ITEM_CV:          *gp_leds = 0x0001; break;
71
    case ITEM_CURVE:       *gp_leds = 0x0002; break;
72
    case ITEM_SLEWRATE:    *gp_leds = 0x000c; break;
73
    case ITEM_PITCHRANGE:  *gp_leds = 0x0010; break;
74
    case ITEM_GATE:        *gp_leds = 0x0020; break;
75
    case ITEM_CALIBRATION: *gp_leds = 0x00c0; break;
2098 tk 76
    case ITEM_CLK_SEL:     *gp_leds = 0x0100; break;
77
    case ITEM_CLK_PPQN:    *gp_leds = 0x0600; break;
78
    case ITEM_CLK_WIDTH:   *gp_leds = 0x0800; break;
1083 tk 79
    case ITEM_MODULE:      *gp_leds = 0xc000; break;
80
  }
81
 
82
  return 0; // no error
83
}
84
 
85
 
86
 
87
/////////////////////////////////////////////////////////////////////////////
88
// Local encoder callback function
89
// Should return:
90
//   1 if value has been changed
91
//   0 if value hasn't been changed
92
//  -1 if invalid or unsupported encoder
93
/////////////////////////////////////////////////////////////////////////////
94
static s32 Encoder_Handler(seq_ui_encoder_t encoder, s32 incrementer)
95
{
96
  switch( encoder ) {
97
    case SEQ_UI_ENCODER_GP1:
98
      ui_selected_item = ITEM_CV;
99
      break;
100
 
101
    case SEQ_UI_ENCODER_GP2:
102
      ui_selected_item = ITEM_CURVE;
103
      break;
104
 
105
    case SEQ_UI_ENCODER_GP3:
106
    case SEQ_UI_ENCODER_GP4:
107
      ui_selected_item = ITEM_SLEWRATE;
108
      break;
109
 
110
    case SEQ_UI_ENCODER_GP5:
111
      ui_selected_item = ITEM_PITCHRANGE;
112
      break;
113
 
114
    case SEQ_UI_ENCODER_GP6:
115
      ui_selected_item = ITEM_GATE;
116
      break;
117
 
118
    case SEQ_UI_ENCODER_GP7:
119
    case SEQ_UI_ENCODER_GP8:
120
      ui_selected_item = ITEM_CALIBRATION;
121
      break;
122
 
123
    case SEQ_UI_ENCODER_GP9:
2098 tk 124
      ui_selected_item = ITEM_CLK_SEL;
125
      break;
126
 
1083 tk 127
    case SEQ_UI_ENCODER_GP10:
2098 tk 128
    case SEQ_UI_ENCODER_GP11:
129
      ui_selected_item = ITEM_CLK_PPQN;
1083 tk 130
      break;
131
 
132
    case SEQ_UI_ENCODER_GP12:
2098 tk 133
      ui_selected_item = ITEM_CLK_WIDTH;
1083 tk 134
      break;
135
 
2098 tk 136
    case SEQ_UI_ENCODER_GP13:
1083 tk 137
    case SEQ_UI_ENCODER_GP14:
138
      return -1; // not mapped
139
 
140
    case SEQ_UI_ENCODER_GP15:
141
    case SEQ_UI_ENCODER_GP16:
142
      ui_selected_item = ITEM_MODULE;
143
      break;
144
  }
145
 
146
  // for GP encoders and Datawheel
147
  switch( ui_selected_item ) {
148
    case ITEM_CV:
149
      if( SEQ_UI_Var8_Inc(&selected_cv, 0, SEQ_CV_NUM-1, incrementer) >= 0 ) {
150
    SEQ_CV_CaliModeSet(selected_cv, SEQ_CV_CaliModeGet()); // change calibration mode to new pin
151
    return 1;
152
      }
153
      return 0;
154
 
155
    case ITEM_CURVE: {
156
    u8 curve = SEQ_CV_CurveGet(selected_cv);
157
      if( SEQ_UI_Var8_Inc(&curve, 0, SEQ_CV_NUM_CURVES-1, incrementer) >= 0 ) {
158
    SEQ_CV_CurveSet(selected_cv, curve);
159
    store_file_required = 1;
160
    return 1;
161
      }
162
      return 0;
163
    }
164
 
165
    case ITEM_SLEWRATE: {
166
      u8 rate = SEQ_CV_SlewRateGet(selected_cv);
167
      if( SEQ_UI_Var8_Inc(&rate, 0, 255, incrementer) >= 0 ) {
168
    SEQ_CV_SlewRateSet(selected_cv, rate);
169
    store_file_required = 1;
170
    return 1;
171
      }
172
      return 0;
173
    }
174
 
175
    case ITEM_PITCHRANGE: {
176
      u8 range = SEQ_CV_PitchRangeGet(selected_cv);
177
      if( SEQ_UI_Var8_Inc(&range, 0, 127, incrementer) >= 0 ) {
178
    SEQ_CV_PitchRangeSet(selected_cv, range);
179
    store_file_required = 1;
180
    return 1;
181
      }
182
      return 0;
183
    }
184
 
185
    case ITEM_GATE: {
186
      u8 inv = SEQ_CV_GateInversionGet(selected_cv);
187
      if( SEQ_UI_Var8_Inc(&inv, 0, 1, incrementer) >= 0 ) {
188
    SEQ_CV_GateInversionSet(selected_cv, inv);
189
    store_file_required = 1;
190
    return 1;
191
      }
192
      return 0;
193
    }
194
 
195
    case ITEM_CALIBRATION: {
196
      u8 mode = SEQ_CV_CaliModeGet();
197
      if( SEQ_UI_Var8_Inc(&mode, 0, SEQ_CV_NUM_CALI_MODES-1, incrementer) >= 0 ) {
198
    SEQ_CV_CaliModeSet(selected_cv, mode);
199
    store_file_required = 1;
200
    return 1;
201
      }
202
      return 0;
203
    }
204
 
2098 tk 205
    case ITEM_CLK_SEL:
206
      if( SEQ_UI_Var8_Inc(&selected_clkout, 0, SEQ_CV_NUM_CLKOUT-1, incrementer) >= 0 ) {
207
    return 1;
208
      }
209
      return 0;
210
 
211
    case ITEM_CLK_PPQN: {
1083 tk 212
      int i;
213
      u8 din_sync_div_ix = 0;
2098 tk 214
      u16 div = SEQ_CV_ClkDividerGet(selected_clkout);
1083 tk 215
 
216
      for(i=0; i<sizeof(din_sync_div_presets)/sizeof(u16); ++i)
217
    if( div == din_sync_div_presets[i] ) {
218
      din_sync_div_ix = i;
219
      break;
220
    }
221
 
222
      if( SEQ_UI_Var8_Inc(&din_sync_div_ix, 0, (sizeof(din_sync_div_presets)/sizeof(u16))-1, incrementer) ) {
2098 tk 223
    SEQ_CV_ClkDividerSet(selected_clkout, din_sync_div_presets[din_sync_div_ix]);
1083 tk 224
    store_file_required = 1;
225
    return 1; // value has been changed
226
      } else
227
    return 0; // value hasn't been changed
228
    } break;
229
 
2098 tk 230
    case ITEM_CLK_WIDTH: {
231
      u8 width = SEQ_CV_ClkPulseWidthGet(selected_clkout);
1083 tk 232
      if( SEQ_UI_Var8_Inc(&width, 1, 255, incrementer) >= 0 ) {
2098 tk 233
    SEQ_CV_ClkPulseWidthSet(selected_clkout, width);
1083 tk 234
    store_file_required = 1;
235
    return 1;
236
      }
237
      return 0;
238
    } break;
239
 
240
    case ITEM_MODULE: {
241
      u8 if_type = SEQ_CV_IfGet();
242
      if( SEQ_UI_Var8_Inc(&if_type, 0, SEQ_CV_NUM_IF-1, incrementer) >= 0 ) {
243
    SEQ_CV_IfSet(if_type);
244
    store_file_required = 1;
245
    return 1;
246
      }
247
      return 0;
248
    }
249
  }
250
 
251
  return -1; // invalid or unsupported encoder
252
}
253
 
254
 
255
/////////////////////////////////////////////////////////////////////////////
256
// Local button callback function
257
// Should return:
258
//   1 if value has been changed
259
//   0 if value hasn't been changed
260
//  -1 if invalid or unsupported button
261
/////////////////////////////////////////////////////////////////////////////
262
static s32 Button_Handler(seq_ui_button_t button, s32 depressed)
263
{
264
  if( depressed ) return 0; // ignore when button depressed
265
 
266
#if 0
267
  // leads to: comparison is always true due to limited range of data type
268
  if( button >= SEQ_UI_BUTTON_GP1 && button <= SEQ_UI_BUTTON_GP16 ) {
269
#else
270
  if( button <= SEQ_UI_BUTTON_GP16 ) {
271
#endif
272
    // re-use encoder handler - only select UI item, don't increment, flags will be toggled
273
    return Encoder_Handler((int)button, 0);
274
  }
275
 
276
  // remaining buttons:
277
  switch( button ) {
278
    case SEQ_UI_BUTTON_Select:
279
    case SEQ_UI_BUTTON_Right:
280
      if( depressed ) return -1;
281
      if( ++ui_selected_item >= NUM_OF_ITEMS )
282
    ui_selected_item = 0;
283
      return 1; // value always changed
284
 
285
    case SEQ_UI_BUTTON_Left:
286
      if( depressed ) return -1;
287
      if( ui_selected_item == 0 )
288
    ui_selected_item = NUM_OF_ITEMS-1;
1142 tk 289
      else
290
    --ui_selected_item;
1083 tk 291
      return 1; // value always changed
292
 
293
    case SEQ_UI_BUTTON_Up:
294
      if( depressed ) return -1;
295
      return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, 1);
296
 
297
    case SEQ_UI_BUTTON_Down:
298
      if( depressed ) return -1;
299
      return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, -1);
300
  }
301
 
302
  return -1; // invalid or unsupported button
303
}
304
 
305
 
306
/////////////////////////////////////////////////////////////////////////////
307
// Local Display Handler function
308
// IN: <high_prio>: if set, a high-priority LCD update is requested
309
/////////////////////////////////////////////////////////////////////////////
310
static s32 LCD_Handler(u8 high_prio)
311
{
312
  if( high_prio )
313
    return 0; // there are no high-priority updates
314
 
315
  // layout:
316
  // 00000000001111111111222222222233333333330000000000111111111122222222223333333333
317
  // 01234567890123456789012345678901234567890123456789012345678901234567890123456789
318
  // <--------------------------------------><-------------------------------------->
2098 tk 319
  //  CV  Curve SlewRate PRng  Gate  Calibr.  Clk   Rate    Width             Module 
320
  //   1  V/Oct    0 mS    2   Pos.    off     1   24 PPQN   1 mS             AOUT_NG
1083 tk 321
 
322
 
323
  ///////////////////////////////////////////////////////////////////////////
324
  SEQ_LCD_CursorSet(0, 0);
2098 tk 325
  SEQ_LCD_PrintString(" CV  Curve SlewRate PRng  Gate  Calibr.  Clk   Rate    Width             Module ");
1083 tk 326
 
327
  ///////////////////////////////////////////////////////////////////////////
328
  SEQ_LCD_CursorSet(0, 1);
329
 
330
  ///////////////////////////////////////////////////////////////////////////
331
  if( ui_selected_item == ITEM_CV && ui_cursor_flash ) {
332
    SEQ_LCD_PrintSpaces(5);
333
  } else {
334
    SEQ_LCD_PrintFormattedString(" %2d  ", selected_cv+1);
335
  }
336
 
337
  ///////////////////////////////////////////////////////////////////////////
338
  if( ui_selected_item == ITEM_CURVE && ui_cursor_flash ) {
339
    SEQ_LCD_PrintSpaces(6);
340
  } else {
341
    SEQ_LCD_PrintString((char *)SEQ_CV_CurveNameGet(selected_cv));
342
  }
343
 
344
  ///////////////////////////////////////////////////////////////////////////
345
  if( ui_selected_item == ITEM_SLEWRATE && ui_cursor_flash ) {
346
    SEQ_LCD_PrintSpaces(9);
347
  } else {
348
    SEQ_LCD_PrintFormattedString(" %3d mS  ", SEQ_CV_SlewRateGet(selected_cv));
349
  }
350
 
351
  ///////////////////////////////////////////////////////////////////////////
352
  if( ui_selected_item == ITEM_PITCHRANGE && ui_cursor_flash ) {
353
    SEQ_LCD_PrintSpaces(6);
354
  } else {
355
    SEQ_LCD_PrintFormattedString("%3d   ", SEQ_CV_PitchRangeGet(selected_cv));
356
  }
357
 
358
  ///////////////////////////////////////////////////////////////////////////
359
  if( ui_selected_item == ITEM_GATE && ui_cursor_flash ) {
360
    SEQ_LCD_PrintSpaces(6);
361
  } else {
362
    SEQ_LCD_PrintFormattedString(SEQ_CV_GateInversionGet(selected_cv) ? "Neg.  " : "Pos.  ");
363
  }
364
 
365
  ///////////////////////////////////////////////////////////////////////////
366
  if( ui_selected_item == ITEM_CALIBRATION && ui_cursor_flash ) {
367
    SEQ_LCD_PrintSpaces(8);
368
  } else {
369
    SEQ_LCD_PrintFormattedString(" %s ", SEQ_CV_CaliNameGet());
370
  }
371
 
372
  ///////////////////////////////////////////////////////////////////////////
2098 tk 373
  if( ui_selected_item == ITEM_CLK_SEL && ui_cursor_flash ) {
1083 tk 374
    SEQ_LCD_PrintSpaces(4);
375
  } else {
2098 tk 376
    SEQ_LCD_PrintFormattedString("%3d ", selected_clkout + 1);
1083 tk 377
  }
2098 tk 378
  SEQ_LCD_PrintSpaces(2);
1083 tk 379
 
380
  ///////////////////////////////////////////////////////////////////////////
2098 tk 381
  if( ui_selected_item == ITEM_CLK_PPQN && ui_cursor_flash ) {
382
    SEQ_LCD_PrintSpaces(9);
1083 tk 383
  } else {
2098 tk 384
    u16 divider = SEQ_CV_ClkDividerGet(selected_clkout);
385
    if( !divider ) {
386
      SEQ_LCD_PrintFormattedString("StartStop", 384 / divider);
387
    } else {
388
      SEQ_LCD_PrintFormattedString("%3d PPQN ", 384 / divider);
389
    }
1083 tk 390
  }
391
 
2098 tk 392
  ///////////////////////////////////////////////////////////////////////////
393
  if( ui_selected_item == ITEM_CLK_WIDTH && ui_cursor_flash ) {
394
    SEQ_LCD_PrintSpaces(6);
395
  } else {
396
    SEQ_LCD_PrintFormattedString("%3d mS", SEQ_CV_ClkPulseWidthGet(selected_clkout));
397
  }
1083 tk 398
 
2098 tk 399
  SEQ_LCD_PrintSpaces(12);
400
 
1083 tk 401
  ///////////////////////////////////////////////////////////////////////////
402
  if( ui_selected_item == ITEM_MODULE && ui_cursor_flash ) {
403
    SEQ_LCD_PrintSpaces(8);
404
  } else {
1312 tk 405
    SEQ_LCD_PrintString((char *)SEQ_CV_IfNameGet(SEQ_CV_IfGet()));
1083 tk 406
  }
407
 
408
 
409
  return 0; // no error
410
}
411
 
412
 
413
/////////////////////////////////////////////////////////////////////////////
414
// Local exit function
415
/////////////////////////////////////////////////////////////////////////////
416
static s32 EXIT_Handler(void)
417
{
418
  s32 status = 0;
419
 
420
  // ensure that calibration mode disabled
421
  SEQ_CV_CaliModeSet(selected_cv, AOUT_CALI_MODE_OFF);
422
 
423
  if( store_file_required ) {
424
    // write config file
425
    MUTEX_SDCARD_TAKE;
426
    if( (status=SEQ_FILE_GC_Write()) < 0 )
427
      SEQ_UI_SDCardErrMsg(2000, status);
428
    MUTEX_SDCARD_GIVE;
429
 
430
    store_file_required = 0;
431
  }
432
 
433
  return status;
434
}
435
 
436
 
437
/////////////////////////////////////////////////////////////////////////////
438
// Initialisation
439
/////////////////////////////////////////////////////////////////////////////
440
s32 SEQ_UI_CV_Init(u32 mode)
441
{
442
  // install callback routines
443
  SEQ_UI_InstallButtonCallback(Button_Handler);
444
  SEQ_UI_InstallEncoderCallback(Encoder_Handler);
445
  SEQ_UI_InstallLEDCallback(LED_Handler);
446
  SEQ_UI_InstallLCDCallback(LCD_Handler);
447
  SEQ_UI_InstallExitCallback(EXIT_Handler);
448
 
449
  store_file_required = 0;
450
 
451
  return 0; // no error
452
}