Subversion Repositories svn.mios32

Rev

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