Subversion Repositories svn.mios32

Rev

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