Subversion Repositories svn.mios32

Rev

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

Rev Author Line No. Line
1573 tk 1
// $Id: terminal.c 2425 2016-11-03 00:44:22Z tk $
1654 tk 2
//! \defgroup TERMINAL
3
//! The MIOS Terminal Handler
4
//! \{
5
/* ==========================================================================
1573 tk 6
 *
7
 *  Copyright (C) 2012 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 <string.h>
1599 tk 20
#include <ff.h>
1573 tk 21
 
22
#include <midi_port.h>
23
#include <midi_router.h>
24
#include <midimon.h>
1667 tk 25
#include <keyboard.h>
1631 tk 26
#include <aout.h>
1573 tk 27
#include <file.h>
1633 tk 28
#include <app_lcd.h>
1573 tk 29
 
30
#include "app.h"
1653 tk 31
#include "terminal.h"
1573 tk 32
#include "mbng_patch.h"
33
#include "uip_terminal.h"
34
#include "tasks.h"
1575 tk 35
#include "mbng_event.h"
1699 tk 36
#include "mbng_lcd.h"
1573 tk 37
#include "mbng_file.h"
1587 tk 38
#include "mbng_file_c.h"
1730 tk 39
#include "mbng_file_r.h"
1573 tk 40
 
41
 
42
/////////////////////////////////////////////////////////////////////////////
1654 tk 43
//! Local defines
1573 tk 44
/////////////////////////////////////////////////////////////////////////////
45
 
46
#define STRING_MAX 100 // recommended size for file transfers via FILE_BrowserHandler()
47
 
48
 
49
/////////////////////////////////////////////////////////////////////////////
1654 tk 50
//! Local variables
1573 tk 51
/////////////////////////////////////////////////////////////////////////////
52
 
53
static char line_buffer[STRING_MAX];
54
static u16 line_ix;
55
 
1699 tk 56
static char autoload_ngc_file[9];
57
static u8 autoload_enabled;
1573 tk 58
 
1758 tk 59
static u8 ngr_section;
60
static s16 ngr_value;
1699 tk 61
 
1758 tk 62
 
1573 tk 63
/////////////////////////////////////////////////////////////////////////////
1654 tk 64
//! Local prototypes
1573 tk 65
/////////////////////////////////////////////////////////////////////////////
66
 
67
static s32 TERMINAL_ParseFilebrowser(mios32_midi_port_t port, char byte);
68
 
1699 tk 69
static s32 TERMINAL_BrowserUploadCallback(char *filename);
1573 tk 70
 
1699 tk 71
 
1573 tk 72
/////////////////////////////////////////////////////////////////////////////
1654 tk 73
//! Initialisation
1573 tk 74
/////////////////////////////////////////////////////////////////////////////
75
s32 TERMINAL_Init(u32 mode)
76
{
77
  // install the callback function which is called on incoming characters from MIOS Terminal
78
  MIOS32_MIDI_DebugCommandCallback_Init(TERMINAL_Parse);
79
 
80
  // install the callback function which is called on incoming characters from MIOS Filebrowser
81
  MIOS32_MIDI_FilebrowserCommandCallback_Init(TERMINAL_ParseFilebrowser);
82
 
83
  // clear line buffer
84
  line_buffer[0] = 0;
85
  line_ix = 0;
1699 tk 86
 
87
  // invalidate autoload file
88
  autoload_ngc_file[0] = 0;
2237 tk 89
 
1699 tk 90
  // enable autoload by default
91
  autoload_enabled = 1;
1573 tk 92
 
1758 tk 93
  // for .NGR file/command handling
94
  ngr_section = 0;
95
  ngr_value = 0;
96
 
1573 tk 97
  return 0; // no error
98
}
99
 
100
 
101
/////////////////////////////////////////////////////////////////////////////
1654 tk 102
//! help function which parses a decimal or hex value
103
//! \returns >= 0 if value is valid
104
//! \returns -1 if value is invalid
1573 tk 105
/////////////////////////////////////////////////////////////////////////////
106
static s32 get_dec(char *word)
107
{
108
  if( word == NULL )
109
    return -1;
110
 
111
  char *next;
112
  long l = strtol(word, &next, 0);
113
 
114
  if( word == next )
115
    return -1;
116
 
117
  return l; // value is valid
118
}
119
 
120
 
121
/////////////////////////////////////////////////////////////////////////////
1654 tk 122
//! help function which parses for on or off
123
//! \returns 0 if 'off', 1 if 'on', -1 if invalid
1573 tk 124
/////////////////////////////////////////////////////////////////////////////
125
static s32 get_on_off(char *word)
126
{
127
  if( strcmp(word, "on") == 0 )
128
    return 1;
129
 
130
  if( strcmp(word, "off") == 0 )
131
    return 0;
132
 
133
  return -1;
134
}
135
 
136
 
137
/////////////////////////////////////////////////////////////////////////////
1654 tk 138
//! Parser
1573 tk 139
/////////////////////////////////////////////////////////////////////////////
140
s32 TERMINAL_Parse(mios32_midi_port_t port, char byte)
141
{
142
  // temporary change debug port (will be restored at the end of this function)
143
  mios32_midi_port_t prev_debug_port = MIOS32_MIDI_DebugPortGet();
144
  MIOS32_MIDI_DebugPortSet(port);
145
 
146
  if( byte == '\r' ) {
147
    // ignore
148
  } else if( byte == '\n' ) {
149
    MUTEX_MIDIOUT_TAKE;
150
    TERMINAL_ParseLine(line_buffer, MIOS32_MIDI_SendDebugMessage);
151
    MUTEX_MIDIOUT_GIVE;
152
    line_ix = 0;
153
    line_buffer[line_ix] = 0;
154
  } else if( line_ix < (STRING_MAX-1) ) {
155
    line_buffer[line_ix++] = byte;
156
    line_buffer[line_ix] = 0;
157
  }
158
 
159
  // restore debug port
160
  MIOS32_MIDI_DebugPortSet(prev_debug_port);
161
 
162
  return 0; // no error
163
}
164
 
165
 
166
/////////////////////////////////////////////////////////////////////////////
1654 tk 167
//! Parser for Filebrowser
1573 tk 168
/////////////////////////////////////////////////////////////////////////////
169
s32 TERMINAL_ParseFilebrowser(mios32_midi_port_t port, char byte)
170
{
171
  if( byte == '\r' ) {
172
    // ignore
173
  } else if( byte == '\n' ) {
1699 tk 174
    // for the auto-load function
175
    FILE_BrowserUploadCallback_Init(TERMINAL_BrowserUploadCallback);
176
 
1573 tk 177
    MUTEX_MIDIOUT_TAKE;
178
    MUTEX_SDCARD_TAKE;
179
    FILE_BrowserHandler(port, line_buffer);
180
    MUTEX_SDCARD_GIVE;
181
    MUTEX_MIDIOUT_GIVE;
182
    line_ix = 0;
183
    line_buffer[line_ix] = 0;
184
  } else if( line_ix < (STRING_MAX-1) ) {
185
    line_buffer[line_ix++] = byte;
186
    line_buffer[line_ix] = 0;
187
  }
188
 
189
  return 0; // no error
190
}
191
 
1699 tk 192
/////////////////////////////////////////////////////////////////////////////
193
//! For the auto-load function
194
/////////////////////////////////////////////////////////////////////////////
195
static s32 TERMINAL_BrowserUploadCallback(char *filename)
196
{
197
  if( filename ) {
198
    // invalidate autoload file
199
    autoload_ngc_file[0] = 0;
1573 tk 200
 
1699 tk 201
    // check for .NGC file in root dir
202
 
203
    if( filename[0] == '/' )
204
      ++filename;
205
 
206
    int len = strlen(filename);
207
 
1720 tk 208
    if( len < 5 || len > 12 ||
209
    (strcasecmp((char *)&filename[len-4], ".ngc") != 0 &&
210
     strcasecmp((char *)&filename[len-4], ".ngl") != 0 &&
2237 tk 211
     strcasecmp((char *)&filename[len-4], ".ngk") != 0 &&
1720 tk 212
     strcasecmp((char *)&filename[len-4], ".ngr") != 0) )
1699 tk 213
      return 0; // no .NGC file
214
 
215
    int i;
216
    for(i=0; i<len; ++i) {
217
      if( filename[i] == '/' )
218
    return 0; // not in root dir
219
    }
220
 
221
    strncpy(autoload_ngc_file, filename, len-4);
222
    autoload_ngc_file[len-4] = 0;
223
  } else {
224
    if( autoload_enabled && autoload_ngc_file[0] ) {
225
      DEBUG_MSG("AUTOLOAD '%s'\n", autoload_ngc_file);
226
 
227
      s32 status = MBNG_PATCH_Load(autoload_ngc_file);
2257 tk 228
 
1699 tk 229
      if( status >= 0 ) {
230
    DEBUG_MSG("Patch '%s' loaded from SD Card!", autoload_ngc_file);
231
      } else {
232
    DEBUG_MSG("ERROR: failed to load patch '%s' on SD Card (status %d)!", autoload_ngc_file, status);
233
      }
234
    }
235
  }
236
 
237
  return 0; // no error
238
}
239
 
240
 
1573 tk 241
/////////////////////////////////////////////////////////////////////////////
1654 tk 242
//! Parser for a complete line - also used by shell.c for telnet
1573 tk 243
/////////////////////////////////////////////////////////////////////////////
244
s32 TERMINAL_ParseLine(char *input, void *_output_function)
245
{
246
  void (*out)(char *format, ...) = _output_function;
247
  char *separators = " \t";
248
  char *brkt;
249
  char *parameter;
250
 
251
  if( UIP_TERMINAL_ParseLine(input, _output_function) > 0 )
252
    return 0; // command parsed by UIP Terminal
253
 
1667 tk 254
  if( KEYBOARD_TerminalParseLine(input, _output_function) > 0 )
255
    return 0; // command parsed by Keyboard Terminal
256
 
1573 tk 257
  if( MIDIMON_TerminalParseLine(input, _output_function) > 0 )
258
    return 0; // command parsed
259
 
260
  if( MIDI_ROUTER_TerminalParseLine(input, _output_function) > 0 )
261
    return 0; // command parsed
262
 
1631 tk 263
#if !defined(MIOS32_FAMILY_EMULATION)
264
  if( AOUT_TerminalParseLine(input, _output_function) >= 1 )
265
    return 0; // command parsed
266
#endif
267
 
1633 tk 268
#ifdef MIOS32_LCD_universal
269
  if( APP_LCD_TerminalParseLine(input, _output_function) >= 1 )
270
    return 0; // command parsed
271
#endif
272
 
1573 tk 273
  if( (parameter = strtok_r(input, separators, &brkt)) ) {
274
    if( strcmp(parameter, "help") == 0 ) {
275
      out("Welcome to " MIOS32_LCD_BOOT_MSG_LINE1 "!");
276
      out("Following commands are available:");
277
      out("  system:                           print system info");
1599 tk 278
      out("  memory:                           print memory allocation info\n");
279
      out("  sdcard:                           print SD Card info\n");
1652 tk 280
      out("  sdcard_format:                    formats the SD Card (you will be asked for confirmation)\n");
1573 tk 281
      UIP_TERMINAL_Help(_output_function);
1667 tk 282
      KEYBOARD_TerminalHelp(_output_function);
1573 tk 283
      MIDIMON_TerminalHelp(_output_function);
284
      MIDI_ROUTER_TerminalHelp(_output_function);
1631 tk 285
      AOUT_TerminalHelp(_output_function);
1633 tk 286
#ifdef MIOS32_LCD_universal
287
      APP_LCD_TerminalHelp(_output_function);
288
#endif
1573 tk 289
      out("  set dout <pin> <0|1>:             directly sets DOUT (all or 0..%d) to given level (1 or 0)", MIOS32_SRIO_NUM_SR*8 - 1);
2208 tk 290
      out("  show douts:                       prints the current DOUT patterns");
1575 tk 291
      out("  set debug <on|off>:               enables debug messages (current: %s)", debug_verbose_level ? "on" : "off");
1699 tk 292
      out("  set autoload <on|off>:            enables autoload after filebrowser upload (current: %s)", autoload_enabled ? "on" : "off");
1573 tk 293
      out("  save <name>:                      stores current config on SD Card");
294
      out("  load <name>:                      restores config from SD Card");
1604 tk 295
      out("  show file:                        shows the current configuration file");
296
      out("  show pool:                        shows the items of the event pool");
297
      out("  show poolbin:                     shows the event pool in binary format");
1706 tk 298
      out("  show id <element>:<id>            shows informations about the given element id (e.g. BUTTON:1)");
299
      out("  show hw_id <element>:<hw_id>      shows informations about the given element hw_id (e.g. BUTTON:1)");
2210 tk 300
      out("  show ngr_tokens:                  shows .NGR token information");
1699 tk 301
      out("  lcd <string>:                     directly prints a string on LCD (can be formatted!)");
2100 tk 302
      out("  run [<section>] [<value>]:        executes the .NGR script with the optional section and value");
1758 tk 303
      out("  ngr_value:                        value used for 'run' (without parameter) and 'ngr' (is: %d)", ngr_value);
304
      out("  ngr_section:                      section used for 'run' (without parameter) and 'ngr' (is: %d)", ngr_section);
305
      out("  ngr <command>:                    directly executes a NGR command");
306
      out("  ngc <command>:                    directly executes a NGC command");
1573 tk 307
      out("  msd <on|off>:                     enables Mass Storage Device driver");
308
      out("  reset:                            resets the MIDIbox (!)\n");
309
      out("  help:                             this page");
310
      out("  exit:                             (telnet only) exits the terminal");
311
    } else if( strcmp(parameter, "system") == 0 ) {
312
      TERMINAL_PrintSystem(_output_function);
1599 tk 313
    } else if( strcmp(parameter, "memory") == 0 ) {
314
      TERMINAL_PrintMemoryInfo(out);
315
    } else if( strcmp(parameter, "sdcard") == 0 ) {
316
      TERMINAL_PrintSdCardInfo(out);
1652 tk 317
    } else if( strcmp(parameter, "sdcard_format") == 0 ) {
318
      if( !brkt || strcasecmp(brkt, "yes, I'm sure") != 0 ) {
319
    out("ATTENTION: this command will format your SD Card!!!");
320
    out("           ALL DATA WILL BE DELETED FOREVER!!!");
321
    out("           Check the current content with the 'sdcard' command");
322
    out("           Create a backup on your computer if necessary!");
323
    out("To start formatting, please enter: sdcard_format yes, I'm sure");
324
    if( brkt ) {
325
      out("('%s' wasn't the right \"password\")", brkt);
326
    }
327
      } else {
1653 tk 328
    MUTEX_SDCARD_TAKE;
1652 tk 329
    out("Formatting SD Card...");
330
    FRESULT res;
331
    if( (res=f_mkfs(0,0,0)) != FR_OK ) {
332
      out("Formatting failed with error code: %d!", res);
333
    } else {
334
      out("...with success!");
335
      MBNG_FILE_UnloadAllFiles();
336
      MBNG_FILE_CreateDefaultFiles();
337
    }
1653 tk 338
    MUTEX_SDCARD_GIVE;
1652 tk 339
      }
1573 tk 340
    } else if( strcmp(parameter, "msd") == 0 ) {
341
      char *arg = NULL;
342
      if( (arg = strtok_r(NULL, separators, &brkt)) ) {
343
    if( strcmp(arg, "on") == 0 ) {
344
      if( TASK_MSD_EnableGet() ) {
345
        out("Mass Storage Device Mode already activated!\n");
346
      } else {
347
        out("Mass Storage Device Mode activated - USB MIDI will be disabled!!!\n");
348
        // wait a second to ensure that this message is print in MIOS Terminal
349
        int d;
350
        for(d=0; d<1000; ++d)
351
          MIOS32_DELAY_Wait_uS(1000);
352
        // activate MSD mode
353
        TASK_MSD_EnableSet(1);
354
      }
355
    } else if( strcmp(arg, "off") == 0 ) {
356
      if( !TASK_MSD_EnableGet() ) {
357
        out("Mass Storage Device Mode already deactivated!\n");
358
      } else {
1699 tk 359
        out("Mass Storage Device Mode deactivated - USB MIDI will be available again\n");
1573 tk 360
        TASK_MSD_EnableSet(0);
361
      }
362
    } else
363
      arg = NULL;
364
      }
365
      if( arg == NULL ) {
366
    out("Please enter 'msd on' or 'msd off'\n");
367
      }      
1699 tk 368
    } else if( strcmp(parameter, "lcd") == 0 ) {
369
      if( !brkt || !strlen(brkt) ) {
370
    out("Please specify string (can be optionally formatted)");
371
      } else {
372
    out("Print '%s'", brkt);
373
 
374
    MUTEX_LCD_TAKE;
375
 
376
    // print from a dummy item
377
    mbng_event_item_t item;
378
    MBNG_EVENT_ItemInit(&item, MBNG_EVENT_CONTROLLER_DISABLED);
379
    item.label = brkt;
1732 tk 380
    MBNG_LCD_PrintItemLabel(&item, NULL, 0);
1699 tk 381
 
382
    MUTEX_LCD_GIVE;
383
      }
1730 tk 384
    } else if( strcmp(parameter, "run") == 0 ) {
385
      s32 section, value;
1758 tk 386
      if( (parameter = strtok_r(NULL, separators, &brkt)) ) {
387
    if( (section=get_dec(parameter)) < 0 || section >= 256 ) {
388
      out("Section number should be between 0..255!");
389
    } else {
390
      ngr_section = section;
391
    }
392
 
393
    if( (parameter = strtok_r(NULL, separators, &brkt)) ) {
394
      if( (value=get_dec(parameter)) < -16384 || value >= 16383 ) {
395
        out("Value should be between -16384..16383!");
396
      } else {
397
        ngr_value = value;
398
      }
399
    }
400
      }
401
 
402
      if( !MBNG_FILE_R_Valid() ) {
1730 tk 403
    out("ERROR: can't execute - missing %s.NGR file!", mbng_file_r_script_name);
404
      } else {
1758 tk 405
    out("Executing %s.NGR with ^section==%d ^value==%d", mbng_file_r_script_name, ngr_section, ngr_value);
406
    MBNG_FILE_R_ReadRequest(NULL, ngr_section, ngr_value, 1);
1730 tk 407
      }
1740 tk 408
    } else if( strcmp(parameter, "runstop") == 0 ) {
409
      if( MBNG_FILE_R_RunStop() > 0 ) {
410
    out("Stopped the execution of %s.NGR", mbng_file_r_script_name);
411
      } else {
412
    out("%s.NGR script not running.", mbng_file_r_script_name);
413
      }
1758 tk 414
    } else if( strcasecmp(parameter, "ngr_section") == 0 ) {
415
      s32 section;
416
      if( !(parameter = strtok_r(NULL, separators, &brkt)) ) {
417
    out("Please specify <ngr-section>! Current value: %d", ngr_section);
418
      } else if( (section=get_dec(parameter)) < 0 || section >= 256 ) {
419
    out("Section number should be between 0..255!");
420
      } else {
421
    ngr_section = section;
422
    out(".NGR section set to %d", ngr_section);
423
      }
424
    } else if( strcasecmp(parameter, "ngr_value") == 0 ) {
425
      s32 value;
426
 
427
      if( !(parameter = strtok_r(NULL, separators, &brkt)) ) {
428
    out("Please specify <ngr-value>! Current value: %d", ngr_value);
429
      } else if( (value=get_dec(parameter)) < -16384 || value >= 16383 ) {
430
    out("Value should be between -16384..16383!");
431
      } else {
432
    ngr_value = value;
433
    out(".NGR value set to %d", ngr_value);
434
      }
435
    } else if( strcasecmp(parameter, "ngr") == 0 ) {
1791 tk 436
      if( brkt == NULL ) {
437
    out("Please specify command!");
438
      } else {
2100 tk 439
    char load_filename[9];
440
    load_filename[0] = 0;
441
 
1791 tk 442
    MBNG_FILE_R_VarSectionSet(ngr_section);
443
    MBNG_FILE_R_VarValueSet(ngr_value);
2210 tk 444
    MBNG_FILE_R_Parser(0, brkt, NULL, NULL, load_filename, 0);
1791 tk 445
    out("Executed command with ^section==%d ^value==%d", ngr_section, ngr_value);
2100 tk 446
 
447
    if( load_filename[0] ) {
448
      s32 status = MBNG_PATCH_Load(parameter);
449
      if( status < 0 ) {
450
        out("ERROR: failed to load patch '%s' on SD Card (status %d)!", parameter, status);
451
      }
452
    }
1791 tk 453
      }
1758 tk 454
    } else if( strcasecmp(parameter, "ngc") == 0 ) {
1791 tk 455
      if( brkt == NULL ) {
456
    out("Please specify command!");
457
      } else {
458
    u8 got_first_event_item = 0;
459
    MBNG_FILE_C_Parser(0, brkt, &got_first_event_item);
460
    out("Executed command.");
461
      }
1573 tk 462
    } else if( strcmp(parameter, "save") == 0 ) {
463
      if( !(parameter = strtok_r(NULL, separators, &brkt)) ) {
464
    out("ERROR: please specify filename for patch (up to 8 characters)!");
465
      } else {
466
    if( strlen(parameter) > 8 ) {
467
      out("ERROR: 8 characters maximum!");
468
    } else {
469
      s32 status = MBNG_PATCH_Store(parameter);
470
      if( status >= 0 ) {
471
        out("Patch '%s' stored on SD Card!", parameter);
472
      } else {
473
        out("ERROR: failed to store patch '%s' on SD Card (status %d)!", parameter, status);
474
      }
475
    }
476
      }
477
    } else if( strcmp(parameter, "load") == 0 ) {
478
      if( !(parameter = strtok_r(NULL, separators, &brkt)) ) {
479
    out("ERROR: please specify filename for patch (up to 8 characters)!");
480
      } else {
481
    if( strlen(parameter) > 8 ) {
482
      out("ERROR: 8 characters maximum!");
483
    } else {
484
      s32 status = MBNG_PATCH_Load(parameter);
485
      if( status >= 0 ) {
486
        out("Patch '%s' loaded from SD Card!", parameter);
487
      } else {
488
        out("ERROR: failed to load patch '%s' on SD Card (status %d)!", parameter, status);
489
      }
490
    }
491
      }
492
    } else if( strcmp(parameter, "show") == 0 ) {
1604 tk 493
      if( !(parameter = strtok_r(NULL, separators, &brkt)) ) {
494
    out("ERROR: please specify the item which should be displayed!");
495
      } else {
1706 tk 496
    if( strcmp(parameter, "file") == 0 ) {
1604 tk 497
      MBNG_FILE_C_Debug();
2208 tk 498
    } else if( strcmp(parameter, "douts") == 0 ) {
499
      int page;
500
      for(page=0; page<MIOS32_SRIO_NUM_DOUT_PAGES; ++page) {
501
        char buffer[3*MIOS32_SRIO_NUM_SR + 20];
502
        sprintf(buffer, "Page %2d:", page+0);
503
        int i;
504
        for(i=0; i<MIOS32_SRIO_NUM_SR; ++i) {
505
          sprintf((char *)&buffer[8+i*3], " %02x", mios32_srio_dout[page][MIOS32_SRIO_NUM_SR-i-1]);
506
        }
507
        MIOS32_MIDI_SendDebugString(buffer);
508
      }
2210 tk 509
    } else if( strcmp(parameter, "ngr_tokens") == 0 || strcmp(parameter, "ngrtokens") == 0 ) {
510
      MBNG_FILE_R_TokenMemPrint();
1706 tk 511
    } else if( strcmp(parameter, "poolbin") == 0 ) {
1604 tk 512
      MBNG_EVENT_PoolPrint();
1706 tk 513
    } else if( strcmp(parameter, "pool") == 0 ) {
1604 tk 514
      MBNG_EVENT_PoolItemsPrint();
1629 tk 515
      MBNG_EVENT_PoolMapsPrint();
1706 tk 516
    } else if( strcmp(parameter, "id") == 0 || strcmp(parameter, "hw_id") == 0 ) {
517
      u8 search_hw_id = strcmp(parameter, "hw_id") == 0;
518
      const char *separator_colon = ":";
519
 
520
      char *id_str = brkt;
521
      if( id_str == NULL || !strlen(id_str) ) {
522
        out("Please specify <element>:<id> (e.g. LED:1)!");
523
      } else {
524
        char *values_str;
525
        mbng_event_item_id_t id;
526
        if( !(values_str = strtok_r(NULL, separator_colon, &brkt)) ||
527
        (id=MBNG_EVENT_ItemIdFromControllerStrGet(values_str)) == MBNG_EVENT_CONTROLLER_DISABLED ) {
528
          out("Invalid element name '%s'!", id_str);
529
        } else {
530
          char *id_lower_str = brkt;
531
          int id_lower = 0;
532
          if( !(values_str = strtok_r(NULL, separator_colon, &brkt)) ||
533
          (id_lower=get_dec(values_str)) < 1 || id_lower > 0xfff ) {
534
        out("Invalid element %s '%s:%s' (expecting %s:1 .. %s:4095)!", search_hw_id ? "hw_id" : "id", id_str, id_lower_str, id_str, id_str);
535
          } else {
536
        id = id | id_lower;
537
 
538
        if( search_hw_id ) {
539
          u8 num = MBNG_EVENT_ItemSearchByHwIdAndPrint(id);
540
          if( num < 1 ) {
541
            out("No items found which are assigned to this hw_id!");
542
          }
543
        } else {
544
          u8 num = MBNG_EVENT_ItemSearchByIdAndPrint(id);
545
          if( num < 1 ) {
546
            out("No items found which are assigned to this id!");
547
          }
548
        }
549
          }
550
        }
551
      }
1629 tk 552
    } else {
1721 tk 553
      out("ERROR: invalid item which should be showed - see 'show pool' for available items!");
1604 tk 554
    }
555
      }
1573 tk 556
    } else if( strcmp(parameter, "reset") == 0 ) {
557
      MIOS32_SYS_Reset();
558
    } else if( strcmp(parameter, "set") == 0 ) {
559
      if( (parameter = strtok_r(NULL, separators, &brkt)) ) {
560
    if( strcmp(parameter, "dout") == 0 ) {
561
      s32 pin = -1;
562
      if( (parameter = strtok_r(NULL, separators, &brkt)) ) {
563
        if( strcmp(parameter, "all") == 0 ) {
564
          pin = -42;
565
        } else {
566
          pin = get_dec(parameter);
567
        }
568
      }
569
 
570
      if( (pin < 0 && pin != -42) || pin >= (MIOS32_SRIO_NUM_SR*8) ) {
571
        out("Pin number should be between 0..%d", MIOS32_SRIO_NUM_SR*8 - 1);
572
      } else {
573
        s32 value = -1;
574
        if( (parameter = strtok_r(NULL, separators, &brkt)) )
575
          value = get_dec(parameter);
576
 
577
        if( value < 0 || value > 1 ) {
578
          out("Expecting value 1 or 0 for DOUT pin %d", pin);
579
        } else {
580
          if( pin == -42 ) {
581
        for(pin=0; pin<(MIOS32_SRIO_NUM_SR*8); ++pin)
582
          MIOS32_DOUT_PinSet(pin, value);
583
        out("All DOUT pins set to %d", value);
584
          } else {
585
        MIOS32_DOUT_PinSet(pin, value);
586
        out("DOUT Pin %d (SR#%d.D%d) set to %d", pin, (pin/8)+1, 7-(pin%8), value);
587
          }
588
        }
589
      }
1575 tk 590
 
591
    } else if( strcmp(parameter, "debug") == 0 ) {
592
      int on_off = -1;
593
      if( (parameter = strtok_r(NULL, separators, &brkt)) )
594
        on_off = get_on_off(parameter);
595
 
596
      if( on_off < 0 ) {
597
        out("Expecting 'on' or 'off'");
598
      } else {
599
        debug_verbose_level = on_off ? DEBUG_VERBOSE_LEVEL_INFO : DEBUG_VERBOSE_LEVEL_ERROR;
600
        out("Debug mode turned %s", on_off ? "on" : "off");
601
      }
1699 tk 602
 
603
    } else if( strcmp(parameter, "autoload") == 0 ) {
604
      int on_off = -1;
605
      if( (parameter = strtok_r(NULL, separators, &brkt)) )
606
        on_off = get_on_off(parameter);
607
 
608
      if( on_off < 0 ) {
609
        out("Expecting 'on' or 'off'");
610
      } else {
611
        autoload_enabled = on_off;
612
        out("Autoload of .NGC file after filebrowser upload %s", on_off ? "on" : "off");
613
      }
1573 tk 614
    } else {
615
      out("Unknown set parameter: '%s'!", parameter);
616
    }
617
      } else {
618
    out("Missing parameter after 'set'!");
619
      }
620
    } else {
621
      out("Unknown command - type 'help' to list available commands!");
622
    }
623
  }
624
 
625
  return 0; // no error
626
}
627
 
628
 
629
/////////////////////////////////////////////////////////////////////////////
1654 tk 630
//! System Informations
1573 tk 631
/////////////////////////////////////////////////////////////////////////////
1600 tk 632
s32 TERMINAL_PrintSystem(void *_output_function)
1573 tk 633
{
634
  void (*out)(char *format, ...) = _output_function;
635
 
636
  out("Application: " MIOS32_LCD_BOOT_MSG_LINE1);
637
 
638
  MIDIMON_TerminalPrintConfig(out);
639
 
1653 tk 640
  AOUT_TerminalPrintConfig(out);
641
 
1659 tk 642
  APP_LCD_TerminalPrintConfig(out);
643
 
1575 tk 644
  out("Event Pool Number of Items: %d", MBNG_EVENT_PoolNumItemsGet());
645
  u32 pool_size = MBNG_EVENT_PoolSizeGet();
646
  u32 pool_max_size = MBNG_EVENT_PoolMaxSizeGet();
647
  out("Event Pool Allocation: %d of %d bytes (%d%%)",
648
      pool_size, pool_max_size, (100*pool_size)/pool_max_size);
1599 tk 649
 
1744 tk 650
#if !defined(MIOS32_FAMILY_EMULATION) && (configGENERATE_RUN_TIME_STATS || configUSE_TRACE_FACILITY)
1599 tk 651
  // send Run Time Stats to MIOS terminal
652
  out("FreeRTOS Task RunTime Stats:\n");
653
  FREERTOS_UTILS_RunTimeStats();
654
#endif
1659 tk 655
 
1573 tk 656
  return 0; // no error
657
}
1599 tk 658
 
659
/////////////////////////////////////////////////////////////////////////////
1654 tk 660
//! Memory allocation Informations
1599 tk 661
/////////////////////////////////////////////////////////////////////////////
1600 tk 662
s32 TERMINAL_PrintMemoryInfo(void *_output_function)
1599 tk 663
{
2425 tk 664
  void (*out)(char *format, ...) = _output_function;
1599 tk 665
 
2425 tk 666
  out("Not supported yet");
1599 tk 667
 
668
  return 0; // no error
669
}
670
 
671
/////////////////////////////////////////////////////////////////////////////
1654 tk 672
//! SDCard Informations
1599 tk 673
/////////////////////////////////////////////////////////////////////////////
674
///////////////////////////////////////////////////////////////////
675
// These time and date functions and other bits of following code were adapted from 
676
// Rickey's world of Microelectronics under the creative commons 2.5 license.
677
// http://www.8051projects.net/mmc-sd-interface-fat16/final-code.php
678
static void ShowFatTime(u32 ThisTime, char* msg)
679
{
680
   u8 AM = 1;
681
 
682
   int Hour, Minute, Second;
683
 
684
   Hour = ThisTime >> 11;        // bits 15 through 11 hold Hour...
685
   Minute = ThisTime & 0x07E0;   // bits 10 through 5 hold Minute... 0000 0111 1110 0000
686
   Minute = Minute >> 5;
687
   Second = ThisTime & 0x001F;   //bits 4 through 0 hold Second...   0000 0000 0001 1111
688
 
689
   if( Hour > 11 )
690
   {
691
      AM = 0;
692
      if( Hour > 12 )
693
         Hour -= 12;
694
   }
695
 
696
   sprintf( msg, "%02d:%02d:%02d %s", Hour, Minute, Second*2,
697
         (AM)?"AM":"PM");
698
   return;
699
}
700
 
701
static void ShowFatDate(u32 ThisDate, char* msg)
702
{
703
 
704
   int Year, Month, Day;
705
 
706
   Year = ThisDate >> 9;         // bits 15 through 9 hold year...
707
   Month = ThisDate & 0x01E0;    // bits 8 through 5 hold month... 0000 0001 1110 0000
708
   Month = Month >> 5;
709
   Day = ThisDate & 0x001F;      //bits 4 through 0 hold day...    0000 0000 0001 1111
710
   sprintf( msg, "%02d/%02d/%02d", Month, Day, Year-20);
711
   return;
712
}
713
 
1600 tk 714
s32 TERMINAL_PrintSdCardInfo(void *_output_function)
1599 tk 715
{
716
  void (*out)(char *format, ...) = _output_function;
717
 
718
  FRESULT res;
719
  FILINFO fno;
720
  DIR dir;
721
  char *fn;
722
  char str_buffer[128];
723
 
724
  MUTEX_MIDIOUT_TAKE;
725
 
726
  out("SD Card Informations\n");
727
  out("====================\n");
728
 
729
#if !defined(MIOS32_FAMILY_EMULATION)
730
  // this yield ensures, that Debug Messages are sent before we continue the execution
731
  // Since MIOS Studio displays the time at which the messages arrived, this allows
732
  // us to measure the delay of following operations
733
  taskYIELD();
734
 
735
  MUTEX_SDCARD_TAKE;
736
  FILE_PrintSDCardInfos();
737
  MUTEX_SDCARD_GIVE;
738
#endif
739
 
740
  out("\n");
741
  out("Reading Root Directory\n");
742
  out("======================\n");
743
 
744
  taskYIELD();
745
 
746
  if( !FILE_SDCardAvailable() ) {
747
    sprintf(str_buffer, "not connected");
748
  } else if( !FILE_VolumeAvailable() ) {
749
    sprintf(str_buffer, "Invalid FAT");
750
  } else {
751
    out("Retrieving SD Card informations - please wait!\n");
752
    MUTEX_MIDIOUT_GIVE;
753
    MUTEX_SDCARD_TAKE;
754
    FILE_UpdateFreeBytes();
755
    MUTEX_SDCARD_GIVE;
756
    MUTEX_MIDIOUT_TAKE;
757
 
758
    sprintf(str_buffer, "'%s': %u of %u MB free",
759
        FILE_VolumeLabel(),
760
        (unsigned int)(FILE_VolumeBytesFree()/1000000),
761
        (unsigned int)(FILE_VolumeBytesTotal()/1000000));
762
  }
763
  out("SD Card: %s\n", str_buffer);
764
 
765
  taskYIELD();
766
 
767
#if _USE_LFN
768
  static char lfn[_MAX_LFN * (_DF1S ? 2 : 1) + 1];
769
  fno.lfname = lfn;
770
  fno.lfsize = sizeof(lfn);
771
#endif
772
 
773
  MUTEX_SDCARD_TAKE;
774
  if( (res=f_opendir(&dir, "/")) != FR_OK ) {
775
    out("Failed to open root directory - error status: %d\n", res);
776
  } else {
777
    while( (f_readdir(&dir, &fno) == FR_OK) && fno.fname[0] ) {
778
#if _USE_LFN
779
      fn = *fno.lfname ? fno.lfname : fno.fname;
780
#else
781
      fn = fno.fname;
782
#endif
783
      char date[10];
784
      ShowFatDate(fno.fdate,(char*)&date);
785
      char time[12];
786
      ShowFatTime(fno.ftime,(char*)&time);
787
      out("[%s%s%s%s%s%s%s] %s  %s   %s %u %s\n",
788
        (fno.fattrib & AM_RDO ) ? "r" : ".",
789
        (fno.fattrib & AM_HID ) ? "h" : ".",
790
        (fno.fattrib & AM_SYS ) ? "s" : ".",
791
        (fno.fattrib & AM_VOL ) ? "v" : ".",
792
        (fno.fattrib & AM_LFN ) ? "l" : ".",
793
        (fno.fattrib & AM_DIR ) ? "d" : ".",
794
        (fno.fattrib & AM_ARC ) ? "a" : ".",
795
        date,time,
796
        (fno.fattrib & AM_DIR) ? "<DIR>" : " ",
797
        fno.fsize,fn);
798
    }
799
  }
800
  MUTEX_SDCARD_GIVE;
801
 
802
  taskYIELD();
803
 
804
  out("done.\n");
805
  MUTEX_MIDIOUT_GIVE;
806
 
807
  return 0; // no error
808
}
1654 tk 809
 
810
 
811
//! \}