Subversion Repositories svn.mios32

Rev

Rev 1010 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1009 ilmenator 1
// $Id: app.c 690 2009-08-04 22:49:33Z tk $
2
/*
3
 * MIOS32 Application Template
4
 *
5
 * ==========================================================================
6
 *
7
 *  Copyright (C) 2010 ilmenator (ilmenator@web.de)
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
 
20
#include <string.h>
1010 tk 21
 
22
extern "C" {
1009 ilmenator 23
#include <ff.h>
1010 tk 24
#include <diskio.h>
25
}
1009 ilmenator 26
 
27
#include "app.h"
28
#include <FreeRTOS.h>
29
#include <semphr.h>
30
 
1013 ilmenator 31
#include <tinyxml.h>
32
//#include <tinystr.h>
33
 
1009 ilmenator 34
/////////////////////////////////////////////////////////////////////////////
35
// for optional debugging messages via MIDI
36
// should be enabled for this application!
37
/////////////////////////////////////////////////////////////////////////////
38
#define DEBUG_VERBOSE_LEVEL 1
39
#define DEBUG_MSG MIOS32_MIDI_SendDebugMessage
40
#define MAX_PATH 100
41
 
42
/////////////////////////////////////////////////////////////////////////////
43
// Local variables
44
/////////////////////////////////////////////////////////////////////////////
45
 
46
// FatFs variables
47
static FATFS fs; // Work area (file system object) for logical drives
1010 tk 48
static char line_buffer[100];
49
static char dir_path[MAX_PATH];
1009 ilmenator 50
static u8 tmp_buffer[_MAX_SS]; //_MAX_SS
51
static u16 line_ix;
1010 tk 52
static char disk_label[12];
1009 ilmenator 53
static FIL fsrc, fdst; // File handles for copy routine.
54
 
55
xSemaphoreHandle xSDCardSemaphore;
56
# define MUTEX_SDCARD_TAKE { while( xSemaphoreTakeRecursive(xSDCardSemaphore, (portTickType)1) != pdTRUE ); }
57
# define MUTEX_SDCARD_GIVE { xSemaphoreGiveRecursive(xSDCardSemaphore); }
58
 
59
 
60
 
61
/////////////////////////////////////////////////////////////////////////////
62
// This hook is called after startup to initialize the application
63
/////////////////////////////////////////////////////////////////////////////
64
void APP_Init(void)
65
{
1013 ilmenator 66
  // initialize +all LEDs
1009 ilmenator 67
  MIOS32_BOARD_LED_Init(0xffffffff);
68
 
69
  // send boot message to Mackie C4 Pro display
70
  // MIOS32_MIDI_SendSysEx(mios32_midi_port_t port, u8 *stream, u32 63);
71
 
72
  // init the semaphore for SD Card access
73
  xSDCardSemaphore = xSemaphoreCreateRecursiveMutex();
74
 
75
  // init the SD Card
76
  MIOS32_SDCARD_Init(0);
77
 
78
  // install the callback function which is called on incoming characters
79
  // from MIOS Terminal
1010 tk 80
  MIOS32_MIDI_DebugCommandCallback_Init((void *)&APP_TERMINAL_Parse);
1009 ilmenator 81
 
82
  // clear line buffer
83
  line_buffer[0] = 0;
84
  line_ix = 0;
85
 
86
#if DEBUG_VERBOSE_LEVEL >= 1
87
  // print welcome message on MIOS terminal
88
  DEBUG_MSG("\n");
89
  DEBUG_MSG("====================\n");
90
  DEBUG_MSG("%s\n", MIOS32_LCD_BOOT_MSG_LINE1);
91
  DEBUG_MSG("====================\n");
92
  DEBUG_MSG("\n");
93
#endif
94
 
95
}
96
 
97
 
98
/////////////////////////////////////////////////////////////////////////////
99
// This function prints some useful SD card informations
100
/////////////////////////////////////////////////////////////////////////////
101
s32 SDCARD_Mount(void)
102
{
103
  int status = 0;
104
  // mount SD Card
105
  FRESULT res;
106
  DIR dir;
107
  DEBUG_MSG("Mounting SD Card...\n");
108
  if( (res=f_mount(0, &fs)) != FR_OK ) {
109
    DEBUG_MSG("Failed to mount SD Card - error status: %d\n", res);
110
    return -1; // error
111
  }
112
 
113
    // Set dir_path to / as we have a new card.
114
  strcpy(dir_path, "/");
115
  if( (res=f_opendir(&dir, dir_path)) != FR_OK ) {
116
    DEBUG_MSG("Failed to open directory %s - error status: %d\n",dir_path, res);
117
    return -1; // error
118
  }
119
 
120
  // Get volume label from base sector  
1010 tk 121
  if(disk_read(0, (BYTE *)&dir.fs->win, dir.fs->dirbase,  1) != 0){
1009 ilmenator 122
    DEBUG_MSG("Couldn't read directory sector...\n");
123
    return -1;  
124
  }  
1010 tk 125
  strncpy( disk_label, (char *)dir.fs->win, 11 );
1009 ilmenator 126
 
127
  return 0;
128
}  
129
 
130
 
131
/////////////////////////////////////////////////////////////////////////////
132
// This task is running endless in background
133
/////////////////////////////////////////////////////////////////////////////
134
void APP_Background(void)
135
{
136
  static u8 sdcard_available = 0;
137
 
138
  // endless loop
139
  while( 1 ) {
140
    // check if SD card is available
141
    // High-speed access if SD card was previously available
142
    u8 prev_sdcard_available = sdcard_available;
143
        MUTEX_SDCARD_TAKE
144
    sdcard_available = MIOS32_SDCARD_CheckAvailable(prev_sdcard_available);
145
        MUTEX_SDCARD_GIVE
146
    if( sdcard_available && !prev_sdcard_available ) {
147
      MIOS32_BOARD_LED_Set(0x1, 0x1); // turn on LED
148
 
149
#if DEBUG_VERBOSE_LEVEL >= 0
150
      // always print...
151
      DEBUG_MSG("SD Card has been connected!\n");
152
#endif
153
 
154
      MIOS32_LCD_Clear();
155
      MIOS32_LCD_CursorSet(0, 0);
156
      MIOS32_LCD_PrintString("SD Card         ");
157
      MIOS32_LCD_CursorSet(0, 1);
158
      MIOS32_LCD_PrintString("connected       ");
159
 
160
#if DEBUG_VERBOSE_LEVEL >= 1
161
      if( SDCARD_Mount() < 0 ) {
162
        DEBUG_MSG("ERROR while mounting SD Card!\n");
163
      } else {
164
        DEBUG_MSG("SUCCESS: SD Card mounted!\n");
165
      }
166
#endif
167
 
168
    } else if( !sdcard_available && prev_sdcard_available ) {
169
      MIOS32_BOARD_LED_Set(0x1, 0x0); // turn off LED
170
 
171
#if DEBUG_VERBOSE_LEVEL >= 0
172
      // always print...
173
      DEBUG_MSG("SD Card disconnected!\n");
174
#endif
175
 
176
      MIOS32_LCD_Clear();
177
      MIOS32_LCD_CursorSet(0, 0);
178
      MIOS32_LCD_PrintString("SD Card         ");
179
      MIOS32_LCD_CursorSet(0, 1);
180
      MIOS32_LCD_PrintString("disconnected    ");
181
    }
182
  }
183
}
184
 
185
 
186
 
187
/////////////////////////////////////////////////////////////////////////////
188
// This hook is called when a MIDI package has been received
189
/////////////////////////////////////////////////////////////////////////////
190
void APP_MIDI_NotifyPackage(mios32_midi_port_t port, mios32_midi_package_t midi_package)
191
{
192
  // toggle Status LED on each incoming MIDI package
193
  MIOS32_BOARD_LED_Set(1, ~MIOS32_BOARD_LED_Get());
194
 
195
  char *message_type;
196
  char *C4_turn_dir="right";
197
  char *C4_element;
198
 
199
  // forward USB0 (Terminal)  <--> UART0 (Mackie C4 Pro)
200
  switch( port ) {
201
    // MIDI messages coming from terminal
202
    case USB0:  MIOS32_MIDI_SendPackage(UART0, midi_package);
203
      // send received MIDI package to MIOS Terminal
204
      MIOS32_MIDI_SendDebugMessage("Port:%02X  Type:%X  Evnt0:%02X  Evnt1:%02X  Evnt2:%02X\n",
205
                   port,
206
                   midi_package.type,
207
                   midi_package.evnt0, midi_package.evnt1, midi_package.evnt2);
208
  break;
209
    // MIDI messages coming from Mackie C4 Pro
210
    case UART0: MIOS32_MIDI_SendPackage(USB0,  midi_package);
211
      // verbose MIDI message type
212
      switch( midi_package.type ) {
213
        case 0x09: message_type = "Button ";
214
          switch( midi_package.evnt2 ) {
215
            case 0x00: C4_turn_dir = "release"; break;
216
            case 0x7f: C4_turn_dir = "press  "; break;
217
          }
218
          switch( midi_package.evnt1 ) {
219
            case 0x00: C4_element = "SPLIT"; break;
220
            case 0x03: C4_element = "LOCK"; break;
221
            case 0x04: C4_element = "SPOT ERASE"; break;
222
            case 0x05: C4_element = "MARKER"; break;
223
            case 0x06: C4_element = "TRACK"; break;
224
            case 0x07: C4_element = "CHAN STRIP"; break;
225
            case 0x08: C4_element = "FUNCTION"; break;
226
            case 0x09: C4_element = "BANK <"; break;
227
            case 0x0a: C4_element = "BANK >"; break;
228
            case 0x0b: C4_element = "SINGLE <"; break;
229
            case 0x0c: C4_element = "SINGLE >"; break;
230
            case 0x0d: C4_element = "SHIFT"; break;
231
            case 0x0e: C4_element = "OPTION"; break;
232
            case 0x0f: C4_element = "CONTROL"; break;
233
            case 0x10: C4_element = "X/ALT"; break;
234
            case 0x11: C4_element = "SLOT UP"; break;
235
            case 0x12: C4_element = "SLOT DOWN"; break;
236
            case 0x13: C4_element = "TRACK L"; break;
237
            case 0x14: C4_element = "TRACK R"; break;
238
            case 0x20: C4_element = "1 / 1"; break;
239
            case 0x21: C4_element = "1 / 2"; break;
240
            case 0x22: C4_element = "1 / 3"; break;
241
            case 0x23: C4_element = "1 / 4"; break;
242
            case 0x24: C4_element = "1 / 5"; break;
243
            case 0x25: C4_element = "1 / 6"; break;
244
            case 0x26: C4_element = "1 / 7"; break;
245
            case 0x27: C4_element = "1 / 8"; break;
246
            case 0x28: C4_element = "2 / 1"; break;
247
            case 0x29: C4_element = "2 / 2"; break;
248
            case 0x2a: C4_element = "2 / 3"; break;
249
            case 0x2b: C4_element = "2 / 4"; break;
250
            case 0x2c: C4_element = "2 / 5"; break;
251
            case 0x2d: C4_element = "2 / 6"; break;
252
            case 0x2e: C4_element = "2 / 7"; break;
253
            case 0x2f: C4_element = "2 / 8"; break;
254
            case 0x30: C4_element = "3 / 1"; break;
255
            case 0x31: C4_element = "3 / 2"; break;
256
            case 0x32: C4_element = "3 / 3"; break;
257
            case 0x33: C4_element = "3 / 4"; break;
258
            case 0x34: C4_element = "3 / 5"; break;
259
            case 0x35: C4_element = "3 / 6"; break;
260
            case 0x36: C4_element = "3 / 7"; break;
261
            case 0x37: C4_element = "3 / 8"; break;
262
            case 0x38: C4_element = "4 / 1"; break;
263
            case 0x39: C4_element = "4 / 2"; break;
264
            case 0x3a: C4_element = "4 / 3"; break;
265
            case 0x3b: C4_element = "4 / 4"; break;
266
            case 0x3c: C4_element = "4 / 5"; break;
267
            case 0x3d: C4_element = "4 / 6"; break;
268
            case 0x3e: C4_element = "4 / 7"; break;
269
            case 0x3f: C4_element = "4 / 8"; break;
270
          }
271
      break;
272
        case 0x0b: message_type = "Encoder";
273
          if( midi_package.evnt2 > 0x40 )
274
            C4_turn_dir = "left ";
275
          switch( midi_package.evnt1 ) {
276
            case 0x00: C4_element = "1 / 1"; break;
277
            case 0x01: C4_element = "1 / 2"; break;
278
            case 0x02: C4_element = "1 / 3"; break;
279
            case 0x03: C4_element = "1 / 4"; break;
280
            case 0x04: C4_element = "1 / 5"; break;
281
            case 0x05: C4_element = "1 / 6"; break;
282
            case 0x06: C4_element = "1 / 7"; break;
283
            case 0x07: C4_element = "1 / 8"; break;
284
            case 0x08: C4_element = "2 / 1"; break;
285
            case 0x09: C4_element = "2 / 2"; break;
286
            case 0x0a: C4_element = "2 / 3"; break;
287
            case 0x0b: C4_element = "2 / 4"; break;
288
            case 0x0c: C4_element = "2 / 5"; break;
289
            case 0x0d: C4_element = "2 / 6"; break;
290
            case 0x0e: C4_element = "2 / 7"; break;
291
            case 0x0f: C4_element = "2 / 8"; break;
292
            case 0x10: C4_element = "3 / 1"; break;
293
            case 0x11: C4_element = "3 / 2"; break;
294
            case 0x12: C4_element = "3 / 3"; break;
295
            case 0x13: C4_element = "3 / 4"; break;
296
            case 0x14: C4_element = "3 / 5"; break;
297
            case 0x15: C4_element = "3 / 6"; break;
298
            case 0x16: C4_element = "3 / 7"; break;
299
            case 0x17: C4_element = "3 / 8"; break;
300
            case 0x18: C4_element = "4 / 1"; break;
301
            case 0x19: C4_element = "4 / 2"; break;
302
            case 0x1a: C4_element = "4 / 3"; break;
303
            case 0x1b: C4_element = "4 / 4"; break;
304
            case 0x1c: C4_element = "4 / 5"; break;
305
            case 0x1d: C4_element = "4 / 6"; break;
306
            case 0x1e: C4_element = "4 / 7"; break;
307
            case 0x1f: C4_element = "4 / 8"; break;
308
          }
309
        break;  
310
      break;
311
      }
312
      // send received MIDI package to MIOS Terminal
313
      MIOS32_MIDI_SendDebugMessage("C4 %s  %s  %s\n",
314
                   message_type,
315
                   C4_element,
316
                   C4_turn_dir);
317
 
318
      // print messages on LCD
319
      MIOS32_LCD_CursorSet(0, 0); // X, Y
1010 tk 320
      MIOS32_LCD_PrintFormattedString("C4 %s  %s  %s\\       ",
1009 ilmenator 321
                   message_type,
322
                   C4_element,
323
                   C4_turn_dir);
324
 
325
 
326
  break;
327
  }
328
 
329
}
330
 
331
 
332
/////////////////////////////////////////////////////////////////////////////
333
// This hook is called before the shift register chain is scanned
334
/////////////////////////////////////////////////////////////////////////////
335
void APP_SRIO_ServicePrepare(void)
336
{
337
}
338
 
339
 
340
/////////////////////////////////////////////////////////////////////////////
341
// This hook is called after the shift register chain has been scanned
342
/////////////////////////////////////////////////////////////////////////////
343
void APP_SRIO_ServiceFinish(void)
344
{
345
}
346
 
347
 
348
/////////////////////////////////////////////////////////////////////////////
349
// This hook is called when a button has been toggled
350
// pin_value is 1 when button released, and 0 when button pressed
351
/////////////////////////////////////////////////////////////////////////////
352
void APP_DIN_NotifyToggle(u32 pin, u32 pin_value)
353
{
354
}
355
 
356
 
357
/////////////////////////////////////////////////////////////////////////////
358
// This hook is called when an encoder has been moved
359
// incrementer is positive when encoder has been turned clockwise, else
360
// it is negative
361
/////////////////////////////////////////////////////////////////////////////
362
void APP_ENC_NotifyChange(u32 encoder, s32 incrementer)
363
{
364
}
365
 
366
 
367
/////////////////////////////////////////////////////////////////////////////
368
// This hook is called when a pot has been moved
369
/////////////////////////////////////////////////////////////////////////////
370
void APP_AIN_NotifyChange(u32 pin, u32 pin_value)
371
{
372
}
373
 
1013 ilmenator 374
 
375
// ----------------------------------------------------------------------
376
// STDOUT dump and indenting utility functions
377
// ----------------------------------------------------------------------
378
const unsigned int NUM_INDENTS_PER_SPACE=2;
379
 
380
const char * getIndent( unsigned int numIndents )
381
{
382
    static const char * pINDENT="                                      + ";
383
    static const unsigned int LENGTH=strlen( pINDENT );
384
    unsigned int n=numIndents*NUM_INDENTS_PER_SPACE;
385
    if ( n > LENGTH ) n = LENGTH;
386
 
387
    return &pINDENT[ LENGTH-n ];
388
}
389
 
390
// same as getIndent but no "+" at the end
391
const char * getIndentAlt( unsigned int numIndents )
392
{
393
    static const char * pINDENT="                                        ";
394
    static const unsigned int LENGTH=strlen( pINDENT );
395
    unsigned int n=numIndents*NUM_INDENTS_PER_SPACE;
396
    if ( n > LENGTH ) n = LENGTH;
397
 
398
    return &pINDENT[ LENGTH-n ];
399
}
400
 
401
int dump_attribs_to_stdout(TiXmlElement* pElement, unsigned int indent)
402
{
403
    if ( !pElement ) return 0;
404
 
405
    TiXmlAttribute* pAttrib=pElement->FirstAttribute();
406
    int i=0;
407
    int ival;
408
    double dval;
409
    const char* pIndent=getIndent(indent);
410
    printf("\n");
411
    while (pAttrib)
412
    {
413
        printf( "%s%s: value=[%s]", pIndent, pAttrib->Name(), pAttrib->Value());
414
 
415
        if (pAttrib->QueryIntValue(&ival)==TIXML_SUCCESS)    printf( " int=%d", ival);
416
        if (pAttrib->QueryDoubleValue(&dval)==TIXML_SUCCESS) printf( " d=%1.1f", dval);
417
        printf( "\n" );
418
        i++;
419
        pAttrib=pAttrib->Next();
420
    }
421
    return i;  
422
}
423
 
424
void dump_to_stdout( TiXmlNode* pParent, unsigned int indent = 0 )
425
{
426
    if ( !pParent ) return;
427
 
428
    TiXmlNode* pChild;
429
    TiXmlText* pText;
430
    int t = pParent->Type();
431
    printf( "%s", getIndent(indent));
432
    int num;
433
 
434
    switch ( t )
435
    {
436
    case TiXmlNode::TINYXML_DOCUMENT:
437
        printf( "Document" );
438
        break;
439
 
440
    case TiXmlNode::TINYXML_ELEMENT:
441
        printf( "Element [%s]", pParent->Value() );
442
        num=dump_attribs_to_stdout(pParent->ToElement(), indent+1);
443
        switch(num)
444
        {
445
            case 0:  printf( " (No attributes)"); break;
446
            case 1:  printf( "%s1 attribute", getIndentAlt(indent)); break;
447
            default: printf( "%s%d attributes", getIndentAlt(indent), num); break;
448
        }
449
        break;
450
 
451
    case TiXmlNode::TINYXML_COMMENT:
452
        printf( "Comment: [%s]", pParent->Value());
453
        break;
454
 
455
    case TiXmlNode::TINYXML_UNKNOWN:
456
        printf( "Unknown" );
457
        break;
458
 
459
    case TiXmlNode::TINYXML_TEXT:
460
        pText = pParent->ToText();
461
        printf( "Text: [%s]", pText->Value() );
462
        break;
463
 
464
    case TiXmlNode::TINYXML_DECLARATION:
465
        printf( "Declaration" );
466
        break;
467
    default:
468
        break;
469
    }
470
    printf( "\n" );
471
    for ( pChild = pParent->FirstChild(); pChild != 0; pChild = pChild->NextSibling())
472
    {
473
        dump_to_stdout( pChild, indent+1 );
474
    }
475
}
476
 
477
 
478
// load the named file and dump its structure to STDOUT
479
void dump_to_stdout(const char* pFilename)
480
{
481
    TiXmlDocument doc(pFilename);
482
    bool loadOkay = doc.LoadFile();
483
    if (loadOkay)
484
    {
485
        printf("\n%s:\n", pFilename);
486
        dump_to_stdout( &doc ); // defined later in the tutorial
487
    }
488
    else
489
    {
490
        printf("Failed to load file \"%s\"\n", pFilename);
491
    }
492
}
493
 
494
 
495
 
496
 
1009 ilmenator 497
void SDCARD_Read_CID(void)
498
{
499
  int status = 0;
500
  // read CID data
501
  mios32_sdcard_cid_t cid;
502
  if( (status=MIOS32_SDCARD_CIDRead(&cid)) < 0 ) {
503
    DEBUG_MSG("ERROR: Reading CID failed with status %d!\n", status);
504
  } else {
505
    DEBUG_MSG("--------------------\n");
506
    DEBUG_MSG("CID:\n");
507
    DEBUG_MSG("- ManufacturerID:\n", cid.ManufacturerID);
508
    DEBUG_MSG("- OEM AppliID:\n", cid.OEM_AppliID);
509
    DEBUG_MSG("- ProdName: %s\n", cid.ProdName);
510
    DEBUG_MSG("- ProdRev: %u\n", cid.ProdRev);
511
    DEBUG_MSG("- ProdSN: 0x%08x\n", cid.ProdSN);
512
    DEBUG_MSG("- Reserved1: %u\n", cid.Reserved1);
513
    DEBUG_MSG("- ManufactDate: %u\n", cid.ManufactDate);
514
    DEBUG_MSG("- msd_CRC: 0x%02x\n", cid.msd_CRC);
515
    DEBUG_MSG("- Reserved2: %u\n", cid.Reserved2);
516
    DEBUG_MSG("--------------------\n");
517
  }
518
}
519
 
520
 
521
void SDCARD_Read_CSD(void)
522
{
523
  int status = 0;
524
  // read CSD data
525
  mios32_sdcard_csd_t csd;
526
  if( (status=MIOS32_SDCARD_CSDRead(&csd)) < 0 ) {
527
    DEBUG_MSG("ERROR: Reading CSD failed with status %d!\n", status);
528
  } else {
529
    DEBUG_MSG("--------------------\n");
530
    DEBUG_MSG("- CSDStruct: %u\n", csd.CSDStruct);
531
    DEBUG_MSG("- SysSpecVersion: %u\n", csd.SysSpecVersion);
532
    DEBUG_MSG("- Reserved1: %u\n", csd.Reserved1);
533
    DEBUG_MSG("- TAAC: %u\n", csd.TAAC);
534
    DEBUG_MSG("- NSAC: %u\n", csd.NSAC);
535
    DEBUG_MSG("- MaxBusClkFrec: %u\n", csd.MaxBusClkFrec);
536
    DEBUG_MSG("- CardComdClasses: %u\n", csd.CardComdClasses);
537
    DEBUG_MSG("- RdBlockLen: %u\n", csd.RdBlockLen);
538
    DEBUG_MSG("- PartBlockRead: %u\n", csd.PartBlockRead);
539
    DEBUG_MSG("- WrBlockMisalign: %u\n", csd.WrBlockMisalign);
540
    DEBUG_MSG("- RdBlockMisalign: %u\n", csd.RdBlockMisalign);
541
    DEBUG_MSG("- DSRImpl: %u\n", csd.DSRImpl);
542
    DEBUG_MSG("- Reserved2: %u\n", csd.Reserved2);
543
    DEBUG_MSG("- DeviceSize: %u\n", csd.DeviceSize);
544
    DEBUG_MSG("- MaxRdCurrentVDDMin: %u\n", csd.MaxRdCurrentVDDMin);
545
    DEBUG_MSG("- MaxRdCurrentVDDMax: %u\n", csd.MaxRdCurrentVDDMax);
546
    DEBUG_MSG("- MaxWrCurrentVDDMin: %u\n", csd.MaxWrCurrentVDDMin);
547
    DEBUG_MSG("- MaxWrCurrentVDDMax: %u\n", csd.MaxWrCurrentVDDMax);
548
    DEBUG_MSG("- DeviceSizeMul: %u\n", csd.DeviceSizeMul);
549
    DEBUG_MSG("- EraseGrSize: %u\n", csd.EraseGrSize);
550
    DEBUG_MSG("- EraseGrMul: %u\n", csd.EraseGrMul);
551
    DEBUG_MSG("- WrProtectGrSize: %u\n", csd.WrProtectGrSize);
552
    DEBUG_MSG("- WrProtectGrEnable: %u\n", csd.WrProtectGrEnable);
553
    DEBUG_MSG("- ManDeflECC: %u\n", csd.ManDeflECC);
554
    DEBUG_MSG("- WrSpeedFact: %u\n", csd.WrSpeedFact);
555
    DEBUG_MSG("- MaxWrBlockLen: %u\n", csd.MaxWrBlockLen);
556
    DEBUG_MSG("- WriteBlockPaPartial: %u\n", csd.WriteBlockPaPartial);
557
    DEBUG_MSG("- Reserved3: %u\n", csd.Reserved3);
558
    DEBUG_MSG("- ContentProtectAppli: %u\n", csd.ContentProtectAppli);
559
    DEBUG_MSG("- FileFormatGrouop: %u\n", csd.FileFormatGrouop);
560
    DEBUG_MSG("- CopyFlag: %u\n", csd.CopyFlag);
561
    DEBUG_MSG("- PermWrProtect: %u\n", csd.PermWrProtect);
562
    DEBUG_MSG("- TempWrProtect: %u\n", csd.TempWrProtect);
563
    DEBUG_MSG("- FileFormat: %u\n", csd.FileFormat);
564
    DEBUG_MSG("- ECC: %u\n", csd.ECC);
565
    DEBUG_MSG("- msd_CRC: 0x%02x\n", csd.msd_CRC);
566
    DEBUG_MSG("- Reserved4: %u\n", csd.Reserved4);
567
    DEBUG_MSG("--------------------\n");
568
  }
569
}
570
 
571
void SDCARD_Messages(FRESULT res)
572
{
573
 switch (res){
1013 ilmenator 574
    case FR_OK:                 DEBUG_MSG("Operation completed successfully\n");break;
1009 ilmenator 575
    case FR_INVALID_DRIVE:      DEBUG_MSG("Invalid Drive\n");break;
576
    case FR_NOT_READY:          DEBUG_MSG("Drive not ready\n");break;
577
    case FR_NOT_ENABLED:        DEBUG_MSG("Drive has no work area\n");break;
578
    case FR_DISK_ERR:           DEBUG_MSG("Disk Function Error\n");break;
579
    case FR_MKFS_ABORTED:       DEBUG_MSG("Drive Format Aborted!\n");break;
580
    case FR_NO_PATH:            DEBUG_MSG("Could not find the path.\n");break;
581
    case FR_INVALID_NAME:       DEBUG_MSG("The path name is invalid.\n");break;
582
    case FR_DENIED:             DEBUG_MSG("Directory table or disk full.\n");break;
1013 ilmenator 583
    case FR_EXIST:              DEBUG_MSG("A file or directory with the same name already exists.\n");break;
584
    case FR_WRITE_PROTECTED:    DEBUG_MSG("The drive is write protected.\n");break;
1009 ilmenator 585
    case FR_INT_ERR:            DEBUG_MSG("FAR structure or internal error.\n");break;
586
    case FR_NO_FILESYSTEM:      DEBUG_MSG("The drive does not contain a valid FAT12/16/32 volume.\n");break;
1013 ilmenator 587
    default:                    DEBUG_MSG("Unknown Error\n");
1009 ilmenator 588
  }
589
}  
590
 
591
void SDCARD_Format(void)
592
{
593
#if _USE_MKFS && !_FS_READONLY
594
  DEBUG_MSG("Formatting SDCARD....\n");
595
  SDCARD_Messages(f_mkfs(0,0,0));
596
#else
597
 
598
  DEBUG_MSG("Please set _MKFS=1 and _FS_READONLY=0 in ffconf.h\n");
599
#endif
600
 
601
}
602
 
603
///////////////////////////////////////////////////////////////////
604
// These time and date functions and other bits of following code were adapted from 
605
// Rickey's world of Microelectronics under the creative commons 2.5 license.
606
// http://www.8051projects.net/mmc-sd-interface-fat16/final-code.php
607
void ShowFatTime( WORD ThisTime, char* msg )
608
{
609
   BYTE AM = 1;
610
 
611
   int Hour, Minute, Second;
612
 
613
   Hour = ThisTime >> 11;        // bits 15 through 11 hold Hour...
614
   Minute = ThisTime & 0x07E0;   // bits 10 through 5 hold Minute... 0000 0111 1110 0000
615
   Minute = Minute >> 5;
616
   Second = ThisTime & 0x001F;   //bits 4 through 0 hold Second...   0000 0000 0001 1111
617
 
618
   if( Hour > 11 )
619
   {
620
      AM = 0;
621
      if( Hour > 12 )
622
         Hour -= 12;
623
   }
624
 
625
   sprintf( msg, "%02d:%02d:%02d %s", Hour, Minute, Second*2,
626
         (AM)?"AM":"PM");
627
   return;
628
}
629
 
630
void ShowFatDate( WORD ThisDate, char* msg )
631
{
632
 
633
   int Year, Month, Day;
634
 
635
   Year = ThisDate >> 9;         // bits 15 through 9 hold year...
636
   Month = ThisDate & 0x01E0;    // bits 8 through 5 hold month... 0000 0001 1110 0000
637
   Month = Month >> 5;
638
   Day = ThisDate & 0x001F;      //bits 4 through 0 hold day...    0000 0000 0001 1111
639
   sprintf( msg, "%02d/%02d/%02d", Month, Day, Year-20);
640
   return;
641
}
642
 
643
void SDCARD_Dir(void)
644
{
645
  FRESULT res;
646
  DWORD free_clust;
647
  FILINFO fno;
648
  DIR dir;
649
  int i;
650
  char *fn;
651
 
652
#if _USE_LFN
653
  static char lfn[_MAX_LFN * (_DF1S ? 2 : 1) + 1];
654
  fno.lfname = lfn;
655
  fno.lfsize = sizeof(lfn);
656
#endif
657
 
658
 
659
  if (disk_label[0]==' ')
660
        DEBUG_MSG("Volume in Drive 0 has no label.\n");
661
  else
662
        DEBUG_MSG("Volume in Drive 0 %s\n",disk_label);
663
 
664
  DEBUG_MSG("Directory of 0:%s\n\n", dir_path);
665
 
666
  if( (res=f_opendir(&dir, dir_path)) != FR_OK ) {
667
    DEBUG_MSG("Failed to open directory %s - error status: %d\n",dir_path, res);
668
    return; // error
669
  }
670
 
671
  while (( f_readdir(&dir,&fno) == FR_OK) && fno.fname[0]) {
672
 
673
#if _USE_LFN
674
    fn = *fno.lfname ? fno.lfname : fno.fname;
675
#else
676
 
677
    fn = fno.fname;
678
#endif
679
 
680
    char date[10];
681
        ShowFatDate(fno.fdate,(char*)&date);
682
        char time[12];
683
        ShowFatTime(fno.ftime,(char*)&time);
684
        DEBUG_MSG("[%s%s%s%s%s%s%s] %s  %s   %s %u %s\n",
685
                (fno.fattrib & AM_RDO ) ? "r" : ".",
686
                (fno.fattrib & AM_HID ) ? "h" : ".",
687
                (fno.fattrib & AM_SYS ) ? "s" : ".",
688
                (fno.fattrib & AM_VOL ) ? "v" : ".",
689
                (fno.fattrib & AM_LFN ) ? "l" : ".",
690
                (fno.fattrib & AM_DIR ) ? "d" : ".",
691
                (fno.fattrib & AM_ARC ) ? "a" : ".",
692
                date,time,
693
                (fno.fattrib & AM_DIR) ? "<DIR>" : " ",
694
                fno.fsize,fn);
695
  }
696
  if (f_getfree("", &free_clust, &dir.fs))
697
  {
698
        DEBUG_MSG("f_getfree() failed...\n");
699
        return;
700
  }
701
  DEBUG_MSG("%u KB total disk space.\n",(DWORD)(fs.max_clust-2)*fs.csize/2);
702
  DEBUG_MSG("%u KB available on the disk.\n\n",free_clust*fs.csize/2);
703
  return;
704
}
705
 
706
 
707
void SDCARD_FileSystem(void)
708
{
709
        DIR dir;
710
        FRESULT res;
711
    if( (res=f_opendir(&dir, "/")) != FR_OK ) {
712
      DEBUG_MSG("Failed to open directory %s - error status: %d\n",dir_path, res);
713
      return; // error
714
    }
715
 
716
    DEBUG_MSG("%u sector/s per cluster, %u clusters.\n", dir.fs->csize, dir.fs->max_clust);
717
    DEBUG_MSG("%u sectors per FAT, first FAT at sector #%u, root dir at #%u.\n", dir.fs->sects_fat, dir.fs->fatbase, dir.fs->dirbase);
718
    DEBUG_MSG("%u root dir entries (not valid for FAT32)\n", dir.fs->n_rootdir);
719
    char file_system[20];
720
    if( dir.fs->fs_type == FS_FAT12 )
721
      strcpy(file_system, "FAT12");
722
    else if( dir.fs->fs_type == FS_FAT16 )
723
      strcpy(file_system, "FAT16");
724
    else if( dir.fs->fs_type == FS_FAT32 )
725
      strcpy(file_system, "FAT32");
726
    else
727
      strcpy(file_system, "unknown FS");
728
    DEBUG_MSG("Filesystem: 0x%02x (%s)\n", dir.fs->fs_type, file_system);
729
 
730
}
731
 
732
void fullpath(char *source, char*dest)
733
{
734
  if (source[0]=='/') {
735
    strcpy(dest, source);
736
  } else {      
737
    strcpy(dest,dir_path);
738
        if (dest[1]!='\0')
739
          strcat(dest,"/");
740
    strcat(dest,source);
741
  }
742
}
743
 
744
void SDCARD_CD(char *directory)
745
{
1010 tk 746
  char new_path[MAX_PATH];
1009 ilmenator 747
  DIR dir;
748
  fullpath(directory,(char *)&new_path);
749
  if((f_opendir(&dir, new_path)) != FR_OK ) {
750
    DEBUG_MSG("The system cannot find the path specified");
751
  } else {
752
    strcpy(dir_path,new_path);
753
  }
754
  return;
755
}
756
 
757
void SDCARD_Delete(char *directory)
758
{
1010 tk 759
  char new_path[MAX_PATH];
1009 ilmenator 760
  fullpath(directory,(char *)&new_path);
761
  if((f_unlink(new_path)) != FR_OK ) {
762
    DEBUG_MSG("The system cannot find the file/dir specified");
763
  } else {
764
    DEBUG_MSG("File or Directory deleted.");
765
  }
766
  return;
767
}
768
 
769
void SDCARD_Mkdir(char *directory)
770
{
1010 tk 771
  char new_path[MAX_PATH];
1009 ilmenator 772
  fullpath(directory,(char *)&new_path);
773
  SDCARD_Messages(f_mkdir(new_path));
774
  return;
775
}
776
 
777
void SDCARD_Pwd(void)
778
{
779
  DEBUG_MSG("%s\n",dir_path);
780
  return;
781
}
782
 
783
 
784
void SDCARD_Rename(char* source, char* dest)
785
{  
1010 tk 786
  char new_source[MAX_PATH];
787
  char new_dest[MAX_PATH];
1009 ilmenator 788
 
789
  fullpath(source,(char *)&new_source);
790
  fullpath(dest,(char *)&new_dest);
791
 
792
  DEBUG_MSG("Renaming/Moving from: %s to %s",new_source,new_dest);
793
  SDCARD_Messages(f_rename(new_source,new_dest));
794
  return;
795
}
796
 
797
void SDCARD_Copy(char* source, char* dest)
798
{
799
 
800
  FRESULT res;
801
  s32 status = 0;
1010 tk 802
  char new_source[MAX_PATH];
803
  char new_dest[MAX_PATH];
1009 ilmenator 804
 
805
  fullpath(source,(char *)&new_source);
806
  fullpath(dest,(char *)&new_dest);
807
 
808
  if( (res=f_open(&fsrc, new_source, FA_OPEN_EXISTING | FA_READ)) != FR_OK ) {
809
    DEBUG_MSG("%s doesn't exist!\n", source);
810
  } else {
811
    if( (res=f_open(&fdst, new_dest, FA_CREATE_ALWAYS | FA_WRITE)) != FR_OK ) {
812
      DEBUG_MSG("Cannot create %s - file exists or invalid path\n", dest);
813
          return;
814
    }
815
  }
816
  DEBUG_MSG("Copying %s to %s\n",new_source,new_dest);
817
 
818
  mios32_sys_time_t t;
819
  t.seconds=0;
820
  t.fraction_ms=0;
821
 
822
  MIOS32_SYS_TimeSet(t);
823
 
824
  UINT successcount;
825
  UINT successcount_wr;
826
  u32 num_bytes = 0;
827
  do {
828
    if( (res=f_read(&fsrc, tmp_buffer, _MAX_SS, &successcount)) != FR_OK ) {
829
          DEBUG_MSG("Failed to read sector at position 0x%08x, status: %u\n", fsrc.fptr, res);
830
          successcount=0;
831
          status=-1;
832
    } else if( f_write(&fdst, tmp_buffer, successcount, &successcount_wr) != FR_OK ) {
833
          DEBUG_MSG("Failed to write sector at position 0x%08x, status: %u\n", fdst.fptr, res);
834
          status=-1;
835
    } else {
836
        num_bytes += successcount_wr;
837
    }
838
  } while( status==0 && successcount > 0 );
839
  mios32_sys_time_t t1=MIOS32_SYS_TimeGet();
840
 
841
  DEBUG_MSG("Copied: %d bytes in %d.%d seconds (%d KB/s)\n",num_bytes,t1.seconds,t1.fraction_ms,
842
                (long long)((((long long)num_bytes*1000)/((t1.seconds*1000)+t1.fraction_ms))/1000));
843
 
844
  f_close(&fdst);
845
}
846
 
847
 
1010 tk 848
void SDCARD_Benchmark(u32 num_sectors)
1009 ilmenator 849
{
850
 
851
  FRESULT res;
852
  s32 status = 0;
1010 tk 853
  char source[MAX_PATH];
854
  char dest[MAX_PATH];
1009 ilmenator 855
  strcpy(source,"/benchmrk.tmp");
856
  strcpy(dest,"/benchmrk.cpy");
857
  int f;
858
 
859
  for(f=0;f<_MAX_SS;f++)
860
        tmp_buffer[f]='X';
861
 
862
  DEBUG_MSG("benchmark: Starting\n");
863
 
864
  mios32_sys_time_t t;
865
  t.seconds=0;
866
  t.fraction_ms=0;
867
 
868
  if( (res=f_open(&fsrc, source, FA_CREATE_ALWAYS | FA_WRITE)) != FR_OK ) {
869
    DEBUG_MSG("benchmark: Cannot create %s - file exists or invalid path\n", source);
870
        return;
871
  }
872
 
873
  UINT successcount;
874
  UINT successcount_wr;
875
  u32 num_bytes = 0;
876
 
877
  MIOS32_SYS_TimeSet(t);
878
 
879
  for (f=0;f<num_sectors;f++) {
880
    if( f_write(&fsrc, tmp_buffer, _MAX_SS, &successcount_wr) != FR_OK ) {
881
          DEBUG_MSG("Failed to write sector at position 0x%08x, status: %u\n", fsrc.fptr, res);
882
          status=-1;
883
          break;
884
        } else {
885
                num_bytes += successcount_wr;
886
        }
887
  }
888
  f_close(&fsrc);
889
 
890
  mios32_sys_time_t t1=MIOS32_SYS_TimeGet();
891
 
892
  DEBUG_MSG("Write: %d bytes in %d.%d seconds (%d KB/s)\n", (num_bytes), t1.seconds,t1.fraction_ms,
893
                (long long)((((long long)num_bytes*1000)/((t1.seconds*1000)+t1.fraction_ms))/1000));
894
 
895
 
896
  if( (res=f_open(&fsrc, source, FA_OPEN_EXISTING | FA_READ)) != FR_OK ) {
897
    DEBUG_MSG("%s doesn't exist!\n", source);
898
        return;
899
  }
900
 
901
  num_bytes = 0;
902
 
903
  MIOS32_SYS_TimeSet(t);
904
 
905
  do {
906
    if( (res=f_read(&fsrc, tmp_buffer, _MAX_SS, &successcount)) != FR_OK ) {
907
          DEBUG_MSG("Failed to read sector at position 0x%08x, status: %u\n", fsrc.fptr, res);
908
        } else {
909
        num_bytes += successcount;
910
    }
911
  } while( successcount > 0 );
912
 
913
  t1 = MIOS32_SYS_TimeGet();
914
 
915
  DEBUG_MSG("Read: %d bytes in %d.%d seconds (%d KB/s)\n",num_bytes,t1.seconds,t1.fraction_ms,
916
                (long long)((((long long)num_bytes*1000)/((t1.seconds*1000)+t1.fraction_ms))/1000));
917
 
918
  f_close(&fsrc);
919
 
920
  if( (res=f_open(&fsrc, source, FA_OPEN_EXISTING | FA_READ)) != FR_OK ) {
921
    DEBUG_MSG("%s doesn't exist!\n", source);
922
  } else {
923
    if( (res=f_open(&fdst, dest, FA_CREATE_ALWAYS | FA_WRITE)) != FR_OK ) {
924
      DEBUG_MSG("Cannot create %s - file exists or invalid path\n", dest);
925
          return;
926
    }
927
  }
928
 
929
  MIOS32_SYS_TimeSet(t);
930
 
931
  num_bytes = 0;
932
  do {
933
    if( (res=f_read(&fsrc, tmp_buffer, _MAX_SS, &successcount)) != FR_OK ) {
934
          DEBUG_MSG("Failed to read sector at position 0x%08x, status: %u\n", fsrc.fptr, res);
935
          successcount=0;
936
          status=-1;
937
    } else if( f_write(&fdst, tmp_buffer, successcount, &successcount_wr) != FR_OK ) {
938
          DEBUG_MSG("Failed to write sector at position 0x%08x, status: %u\n", fdst.fptr, res);
939
          status=-1;
940
    } else {
941
        num_bytes += successcount_wr;
942
    }
943
  } while( status==0 && successcount > 0 );
944
 
945
  t1 = MIOS32_SYS_TimeGet();
946
 
947
  DEBUG_MSG("Copy: %d bytes in %d.%d seconds (%d KB/s)\n",num_bytes,t1.seconds,t1.fraction_ms,
948
                (long long)((((long long)num_bytes*1000)/((t1.seconds*1000)+t1.fraction_ms))/1000));
949
 
950
  f_close(&fdst);
951
  f_unlink(source);
952
  f_unlink(dest);
953
}
954
 
955
 
956
void SDCARD_ReadFile(char* source)
957
{
958
  FRESULT res;
959
  s32 status = 0;
1010 tk 960
  char new_source[MAX_PATH];
1009 ilmenator 961
  //u8 new_dest[MAX_PATH];
962
 
963
  fullpath(source,(char *)&new_source);
964
  //fullpath(dest,(char *)&new_dest);
965
 
966
  if( (res=f_open(&fsrc, new_source, FA_OPEN_EXISTING | FA_READ)) != FR_OK ) {
967
    DEBUG_MSG("%s doesn't exist!\n", source);
968
  }
969
 
970
  //DEBUG_MSG("Copying %s to %s\n",new_source,new_dest);
1013 ilmenator 971
  dump_to_stdout("korg.xml");
972
  //return 0;
1009 ilmenator 973
 
974
  mios32_sys_time_t t;
975
  t.seconds=0;
976
  t.fraction_ms=0;
977
 
978
  MIOS32_SYS_TimeSet(t);
979
 
980
  UINT successcount;
981
  UINT successcount_wr;
982
  u32 num_bytes = 0;
983
  u16 loop = 0;
984
  char string[_MAX_SS];
985
  do {
986
    if( (res=f_read(&fsrc, tmp_buffer, _MAX_SS, &successcount)) != FR_OK ) {
987
          DEBUG_MSG("Failed to read sector at position 0x%08x, status: %u\n", fsrc.fptr, res);
988
          successcount=0;
989
          status=-1;
990
//    } else if( f_write(&fdst, tmp_buffer, successcount, &successcount_wr) != FR_OK ) {
991
//          DEBUG_MSG("Failed to write sector at position 0x%08x, status: %u\n", fdst.fptr, res);
992
//          status=-1;
993
    } else {
994
          DEBUG_MSG("Read from file, status: %u\n", res);
995
//        do {
996
//        } while 
997
          if( successcount < 3) {
998
            for (loop=0;loop<_MAX_SS;loop++)
999
              //string[loop]=tmp_buffer[loop];
1000
              DEBUG_MSG("%c ", tmp_buffer[loop]);
1001
          }
1002
 
1010 tk 1003
      DEBUG_MSG(" -- %d\n", strlen((char *)tmp_buffer));
1009 ilmenator 1004
       num_bytes += successcount_wr;
1005
    }
1006
  } while( status==0 && successcount > 0 );
1007
  mios32_sys_time_t t1=MIOS32_SYS_TimeGet();
1008
 
1009
//  DEBUG_MSG("Copied: %d bytes in %d.%d seconds (%d KB/s)\n",num_bytes,t1.seconds,t1.fraction_ms,
1010
//                (long long)((((long long)num_bytes*1000)/((t1.seconds*1000)+t1.fraction_ms))/1000));
1011
 
1012
  f_close(&fdst);  
1013
 
1014
 
1015
}
1016
 
1017
 
1018
/////////////////////////////////////////////////////////////////////////////
1019
// MIOS Terminal Parser
1020
/////////////////////////////////////////////////////////////////////////////
1021
void APP_TERMINAL_Parse(mios32_midi_port_t port, u8 byte)
1022
{
1023
  // temporary change debug port (will be restored at the end of this function)
1024
  mios32_midi_port_t prev_debug_port = MIOS32_MIDI_DebugPortGet();
1025
  MIOS32_MIDI_DebugPortSet(port);
1026
 
1027
  if( byte == '\r' ) {
1028
    // ignore
1029
  } else if( byte == '\n' ) {
1030
    // example for parsing the command:
1031
    char *separators = " \t";
1032
    char *brkt;
1033
    char *parameter[10];
1034
    if( parameter[0] = strtok_r(line_buffer, separators, &brkt) ) {
1035
          u8 f;
1036
          for(f=1;f<10;f++) {
1037
            if( (parameter[f] = strtok_r(NULL, separators, &brkt)) == NULL)
1038
                  break;
1039
          }
1040
      MUTEX_SDCARD_TAKE
1041
      if( strncmp(parameter[0], "help", 4) == 0 ) {
1042
        DEBUG_MSG("Following commands are available:");
1043
        DEBUG_MSG("  cid:                  Display CID structure\n");
1044
        DEBUG_MSG("  csd:                  Display CSD structure\n");
1045
        DEBUG_MSG("  filesys:              Display filesystem info\n");
1046
        DEBUG_MSG("  dir:                  Display files in current directory\n");
1047
        DEBUG_MSG("  cd <dir>:             Print or Change current directory\n");
1048
        DEBUG_MSG("  mkdir <dir>:          Create new directory\n");
1049
        DEBUG_MSG("  rename <src> <dest>:  Rename/Move file or directory\n");
1050
        DEBUG_MSG("  copy <src> <dest>:    Copy file\n");
1051
        DEBUG_MSG("  delete <file/dir>:    Delete file or directory\n");
1052
        DEBUG_MSG("  benchmark <x>:        Benchmark (read/write/copy xMB file)\n");
1053
        DEBUG_MSG("  format <yes>:         Format sdcard *destroys all contents of card*\n");
1054
        DEBUG_MSG("  read <src>:           Read file\n");
1055
      } else if( strncmp(parameter[0], "format", 6) == 0 ) {
1056
                  if( strncmp(parameter[1], "yes", 3) == 0 )
1057
                        SDCARD_Format();
1058
                  else
1059
                    DEBUG_MSG("Please type \"format yes\" to format sd/mmc card");
1060
      } else if( strncmp(parameter[0], "cid", 3) == 0 ) {
1061
                SDCARD_Read_CID();
1062
      } else if( strncmp(parameter[0], "csd", 3) == 0 ) {
1063
                SDCARD_Read_CSD();
1064
      } else if( strncmp(parameter[0], "filesys", 7) == 0 ) {
1065
                SDCARD_FileSystem();
1066
      } else if( strncmp(parameter[0], "dir", 3) == 0 ) {
1067
                SDCARD_Dir();
1068
      } else if( strncmp(parameter[0], "cd", 2) == 0 ) {
1069
            if(parameter[1])
1070
              SDCARD_CD(parameter[1]);
1071
                else
1072
              SDCARD_Pwd();
1073
      } else if( strncmp(parameter[0], "mkdir", 5) == 0 ) {
1074
            if(parameter[1])
1075
              SDCARD_Mkdir(parameter[1]);
1076
            else
1077
              DEBUG_MSG("mkdir: No directory specified");
1078
      } else if( strncmp(parameter[0], "delete", 6) == 0 ) {
1079
            if(parameter[1])
1080
              SDCARD_Delete(parameter[1]);
1081
            else
1082
              DEBUG_MSG("delete: No file/directory specified");
1083
      } else if( strncmp(parameter[0], "rename", 6) == 0 ) {
1084
            if(parameter[1] && parameter[2])
1085
              SDCARD_Rename(parameter[1],parameter[2]);
1086
            else
1087
              DEBUG_MSG("rename: <source> and <destination> filenames required");
1088
      } else if( strncmp(parameter[0], "copy", 4) == 0 ) {
1089
            if(parameter[1] && parameter[2])
1090
              SDCARD_Copy(parameter[1],parameter[2]);
1091
            else
1092
              DEBUG_MSG("copy: <source> and <destination> filenames required");
1093
      } else if( strncmp(parameter[0], "benchmark", 9) == 0 ) {
1094
                int bench=strtol(parameter[1],&parameter[2],0);
1095
                if (bench<1)
1096
              bench=1;
1097
                SDCARD_Benchmark(bench*2048);
1098
      } else if( strncmp(parameter[0], "read", 4) == 0 ) {
1099
            if(parameter[1])
1100
              SDCARD_ReadFile(parameter[1]);
1101
            else
1102
              DEBUG_MSG("read: <source> filename required");
1103
      } else {
1104
        DEBUG_MSG("Unknown command - type 'help' to list available commands!\n");
1105
      }
1106
          MUTEX_SDCARD_GIVE
1107
    }
1108
 
1109
    line_ix = 0;
1110
 
1111
  } else if( line_ix < (100-1) ) {
1112
    line_buffer[line_ix++] = byte;
1113
    line_buffer[line_ix] = 0;
1114
  }
1115
 
1116
  // restore debug port
1117
  MIOS32_MIDI_DebugPortSet(prev_debug_port);
1118
 
1119
  return;
1010 tk 1120
}