100% found this document useful (1 vote)
151 views16 pages

SD Good Code

This document contains source code for an example program that reads files from an SD card using a FAT file system. It initializes variables and structures for working with the file system, defines constants, and contains function prototypes and implementations for reading directories, getting error strings, and handling interrupts required by the file system driver.

Uploaded by

treax
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
151 views16 pages

SD Good Code

This document contains source code for an example program that reads files from an SD card using a FAT file system. It initializes variables and structures for working with the file system, defines constants, and contains function prototypes and implementations for reading directories, getting error strings, and handling interrupts required by the file system driver.

Uploaded by

treax
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 16

sd_card.

1 //###########################################################################
2 //
3 // FILE: sd_card.c
4 //
5 // TITLE: Example program for reading files from an SD card.
6 //
7 //! \addtogroup cpu01_example_list
8 //! <h1>SD card using FAT file system (sd_card)</h1>
9 //!
10 //! This example application demonstrates reading a file system from
11 //! an SD card. It makes use of FatFs, a FAT file system driver.
12 //!
13 //! For additional details about FatFs, see the following site:
14 //! http://elm-chan.org/fsw/ff/00index_e.html
15 //!
16 //! The application may be operated via a serial terminal attached to
17 //! UART0. The RS232 communication parameters should be set to 115,200 bits
18 //! per second, and 8-n-1 mode. When the program is started a message will be
19 //! printed to the terminal. Type ``help'' for command help.
20 //!
21 //
22 //###########################################################################
23 // $TI Release: F2837xD Support Library v210 $
24 // $Release Date: Tue Nov 1 14:46:15 CDT 2016 $
25 // $Copyright: Copyright (C) 2013-2016 Texas Instruments Incorporated -
26 // http://www.ti.com/ ALL RIGHTS RESERVED $
27 //###########################################################################
28
29 //
30 // Included Files
31 //
32 #include "F28x_Project.h"
33 #include <string.h>
34 #include "inc/hw_ints.h"
35 #include "inc/hw_memmap.h"
36 #include "inc/hw_types.h"
37 #include "driverlib/interrupt.h"
38 #include "driverlib/sysctl.h"
39 #include "driverlib/systick.h"
40 #include "utils/cmdline.h"
41 #include "utils/uartstdio.h"
42 #include "utils/ustdlib.h"
43 #include "third_party/fatfs/src/ff.h"
44 #include "third_party/fatfs/src/diskio.h"
45
46 //
47 // Defines
48 //
49 #define PATH_BUF_SIZE 80 // Defines the size of the buffers that hold the
50 // path, or temporary data from the SD card.
51 // There are two buffers allocated of this size.
52 // The buffer size must be large enough to hold
53 // the longest expected full path name,
54 // including the file name, and a trailing null
55 // character.
56 #define CMD_BUF_SIZE 64 // Defines the size of the buffer that holds
57 // the command line.
58 #define FRESULT_ENTRY(f) { (f), (# f) } // A macro to make it easy to
59 // add result codes to the table
60 #define NAME_TOO_LONG_ERROR 1 // Error reasons returned
61 #define OPENDIR_ERROR 2 // by ChangeDirectory().
62 #define NUM_FRESULT_CODES (sizeof(g_sFresultStrings) / sizeof(tFresultString))

Page 1
sd_card.c

63 #define TICKS_PER_SECOND 100


64 #define NUM_LIST_STRINGS 48
65 #define MAX_FILENAME_STRING_LEN (4 + 8 + 1 + 3 + 1)
66 #define NUM_STATUS_STRINGS 6
67 #define MAX_STATUS_STRING_LEN (36 + 1)
68
69 //
70 // Globals
71 //
72 static char g_cCwdBuf[PATH_BUF_SIZE] = "/"; // This buffer holds the full path
73 // to the current working
74 // directory. Initially it is
75 // root ("/").
76 static char g_cTmpBuf[PATH_BUF_SIZE]; // A temporary data buffer used
77 // when manipulating file paths,or
78 // reading data from the SD card.
79 static char g_cCmdBuf[CMD_BUF_SIZE]; // The buffer that holds the
80 // command line.
81 static FATFS g_sFatFs;
82 static DIR g_sDirObject;
83 static FILINFO g_sFileInfo;
84 static FIL g_sFileObject;
85
86
87
88 static FATFS FatFs;
89 static FIL Fil;
90
91
92
93
94 //
95 // A structure that holds a mapping between an FRESULT numerical code,
96 // and a string representation. FRESULT codes are returned from the FatFs
97 // FAT file system driver.
98 //
99 typedef struct
100 {
101 FRESULT fresult;
102 char *pcResultStr;
103 }
104 tFresultString;
105
106 //
107 // A table that holds a mapping between the numerical FRESULT code and
108 // it's name as a string. This is used for looking up error codes for
109 // printing to the console.
110 //
111 tFresultString g_sFresultStrings[] =
112 {
113 FRESULT_ENTRY(FR_OK),
114 FRESULT_ENTRY(FR_NOT_READY),
115 FRESULT_ENTRY(FR_NO_FILE),
116 FRESULT_ENTRY(FR_NO_PATH),
117 FRESULT_ENTRY(FR_INVALID_NAME),
118 FRESULT_ENTRY(FR_INVALID_DRIVE),
119 FRESULT_ENTRY(FR_DENIED),
120 FRESULT_ENTRY(FR_EXIST),
121 FRESULT_ENTRY(FR_RW_ERROR),
122 FRESULT_ENTRY(FR_WRITE_PROTECTED),
123 FRESULT_ENTRY(FR_NOT_ENABLED),
124 FRESULT_ENTRY(FR_NO_FILESYSTEM),

Page 2
sd_card.c

125 FRESULT_ENTRY(FR_INVALID_OBJECT),
126 FRESULT_ENTRY(FR_MKFS_ABORTED)
127 };
128
129 const char *g_ppcDirListStrings[NUM_LIST_STRINGS]; // Storage for the filename
130 // listbox widget string
131 // table.
132
133 //
134 // Storage for the names of the files in the current directory. Filenames
135 // are stored in format "(D) filename.ext" for directories or
136 // "(F) filename.ext" for files.
137 //
138 char g_pcFilenames[NUM_LIST_STRINGS][MAX_FILENAME_STRING_LEN];
139
140 //
141 // Storage for the strings which appear in the status box at the bottom of the
142 // display.
143 //
144 char g_pcStatus[NUM_STATUS_STRINGS][MAX_STATUS_STRING_LEN];
145
146 //
147 // Storage for the status listbox widget string table.
148 //
149 const char *g_ppcStatusStrings[NUM_STATUS_STRINGS] =
150 {
151 g_pcStatus[0],
152 g_pcStatus[1],
153 g_pcStatus[2],
154 g_pcStatus[3],
155 g_pcStatus[4],
156 g_pcStatus[5]
157 };
158 unsigned long g_ulStatusStringIndex = 0;
159
160 //
161 // Forward declarations for functions called by the widgets used in the user
162 // interface.
163 //
164 static FRESULT ChangeToDirectory(char *pcDirectory, unsigned long *pulReason);
165 static const char *StringFromFresult(FRESULT fresult);
166
167 //
168 // Function Prototypes
169 //
170 extern void UARTStdioIntHandler(void);
171
172 //
173 // StringFromFresult - This function returns a string representation of an
174 // error code that was returned from a function call to
175 // FatFs. It can be used for printing human readable
176 // error messages.
177 //
178 static const char *
179 StringFromFresult(FRESULT fresult)
180 {
181 unsigned int uIdx;
182
183 //
184 // Enter a loop to search the error code table for a matching
185 // error code.
186 //

Page 3
sd_card.c

187 for(uIdx = 0; uIdx < NUM_FRESULT_CODES; uIdx++)


188 {
189 //
190 // If a match is found, then return the string name of the
191 // error code.
192 //
193 if(g_sFresultStrings[uIdx].fresult == fresult)
194 {
195 return(g_sFresultStrings[uIdx].pcResultStr);
196 }
197 }
198
199 //
200 // At this point no matching code was found, so return a
201 // string indicating unknown error.
202 //
203 return("UNKNOWN ERROR CODE");
204 }
205
206 //
207 // SysTickHandler - This is the handler for this SysTick interrupt. FatFs
208 // requires a timer tick every 10 ms for internal timing
209 // purposes.
210 //
211 __interrupt void
212 SysTickHandler(void)
213 {
214 //
215 // Call the FatFs tick timer.
216 //
217 disk_timerproc();
218 PieCtrlRegs.PIEACK.all |= 1;
219 }
220
221 //
222 // Cmd_ls - This function implements the "ls" command. It opens the current
223 // directory and enumerates through the contents, and prints a line
224 // for each item it finds. It shows details such as file attributes,
225 // time and date, and the file size, along with the name. It shows a
226 // summary of file sizes at the end along with free space.
227 //
228 int
229 Cmd_ls(int argc, char *argv[])
230 {
231 unsigned long ulTotalSize, ulItemCount, ulFileCount, ulDirCount;
232 FRESULT fresult;
233 FATFS *pFatFs;
234
235 //
236 // Open the current directory for access.
237 //
238 fresult = f_opendir(&g_sDirObject, g_cCwdBuf);
239
240 //
241 // Check for error and return if there is a problem.
242 //
243 if(fresult != FR_OK)
244 {
245 return(fresult);
246 }
247
248 ulTotalSize = 0;

Page 4
sd_card.c

249 ulFileCount = 0;
250 ulDirCount = 0;
251 ulItemCount = 0;
252
253 //
254 // Give an extra blank line before the listing.
255 //
256 UARTprintf("\n");
257
258 //
259 // Enter loop to enumerate through all directory entries.
260 //
261 for(;;)
262 {
263 //
264 // Read an entry from the directory.
265 //
266 fresult = f_readdir(&g_sDirObject, &g_sFileInfo);
267
268 //
269 // Check for error and return if there is a problem.
270 //
271 if(fresult != FR_OK)
272 {
273 return(fresult);
274 }
275
276 //
277 // If the file name is blank, then this is the end of the
278 // listing.
279 //
280 if(!g_sFileInfo.fname[0])
281 {
282 break;
283 }
284
285 //
286 // Print the entry information on a single line with formatting
287 // to show the attributes, date, time, size, and name.
288 //
289 UARTprintf("%c%c%c%c%c %u/%02u/%02u %02u:%02u %9u %s\n",
290 (g_sFileInfo.fattrib & AM_DIR) ? (uint32_t)'D' : (uint32_t)'-',
291 (g_sFileInfo.fattrib & AM_RDO) ? (uint32_t)'R' : (uint32_t)'-',
292 (g_sFileInfo.fattrib & AM_HID) ? (uint32_t)'H' : (uint32_t)'-',
293 (g_sFileInfo.fattrib & AM_SYS) ? (uint32_t)'S' : (uint32_t)'-',
294 (g_sFileInfo.fattrib & AM_ARC) ? (uint32_t)'A' : (uint32_t)'-',
295 (uint32_t)((g_sFileInfo.fdate >> 9) + 1980),
296 (uint32_t)((g_sFileInfo.fdate >> 5) & 15),
297 (uint32_t)(g_sFileInfo.fdate & 31),
298 (uint32_t)((g_sFileInfo.ftime >> 11)),
299 (uint32_t)((g_sFileInfo.ftime >> 5) & 63),
300 (uint32_t)(g_sFileInfo.fsize),
301 g_sFileInfo.fname);
302
303 //
304 // Add the information as a line in the listbox widget.
305 //
306 if(ulItemCount < NUM_LIST_STRINGS)
307 {
308 usprintf(g_pcFilenames[ulItemCount], "(%c) %12s",
309 (g_sFileInfo.fattrib & AM_DIR) ? 'D' : 'F',
310 g_sFileInfo.fname);

Page 5
sd_card.c

311 }
312
313 //
314 // If the attribute is directory, then increment the directory count.
315 //
316 if(g_sFileInfo.fattrib & AM_DIR)
317 {
318 ulDirCount++;
319 }
320 //
321 // Otherwise, it is a file. Increment the file count, and
322 // add in the file size to the total.
323 //
324 else
325 {
326 ulFileCount++;
327 ulTotalSize += g_sFileInfo.fsize;
328 }
329
330 //
331 // Move to the next entry in the item array we use to populate the
332 // list box.
333 //
334 ulItemCount++;
335
336 //
337 // Wait for the UART transmit buffer to empty.
338 //
339 // UARTFlushTx(false);
340 }
341
342 //
343 // Print summary lines showing the file, dir, and size totals.
344 //
345 UARTprintf("\n%4u File(s),%10u bytes total\n%4u Dir(s)",
346 ulFileCount, ulTotalSize, ulDirCount);
347
348 //
349 // Get the free space.
350 //
351 fresult = f_getfree("/", &ulTotalSize, &pFatFs);
352
353 //
354 // Check for error and return if there is a problem.
355 //
356 if(fresult != FR_OK)
357 {
358 return(fresult);
359 }
360
361 //
362 // Display the amount of free space that was calculated.
363 //
364 UARTprintf(", %10uK bytes free\n", ulTotalSize * pFatFs->sects_clust / 2);
365
366 //
367 // Wait for the UART transmit buffer to empty.
368 //
369 // UARTFlushTx(false);
370
371 //
372 // Made it to here, return with no errors.

Page 6
sd_card.c

373 //
374 return(0);
375 }
376
377 //
378 // ChangeToDirectory - This function implements the "cd" command. It takes an
379 // argument that specifies the directory to make the
380 // current working directory. Path separators must use a
381 // forward slash "/". The argument to cd can be one of the
382 // following:
383 // * root ("/")
384 // * a fully specified path ("/my/path/to/mydir")
385 // * a single directory name that is in the current
386 // directory ("mydir")
387 // * parent directory ("..")
388 // It does not understand relative paths, so don't try
389 // something like this: ("../my/new/path")
390 // Once the new directory is specified, it attempts to open
391 // the directory to make sure it exists. If the new path
392 // is opened successfully, then the current working
393 // directory (cwd) is changed to the new path. In cases of
394 // error, the pulReason parameter will be written with one
395 // of the following values:
396 //
397 static FRESULT
398 ChangeToDirectory(char *pcDirectory, unsigned long *pulReason)
399 {
400 unsigned int uIdx;
401 FRESULT fresult;
402
403 //
404 // Copy the current working path into a temporary buffer so
405 // it can be manipulated.
406 //
407 strcpy(g_cTmpBuf, g_cCwdBuf);
408
409 //
410 // If the first character is /, then this is a fully specified
411 // path, and it should just be used as-is.
412 //
413 if(pcDirectory[0] == '/')
414 {
415 //
416 // Make sure the new path is not bigger than the cwd buffer.
417 //
418 if(strlen(pcDirectory) + 1 > sizeof(g_cCwdBuf))
419 {
420 *pulReason = NAME_TOO_LONG_ERROR;
421 return(FR_OK);
422 }
423 //
424 // If the new path name (in argv[1]) is not too long, then
425 // copy it into the temporary buffer so it can be checked.
426 //
427 else
428 {
429 strncpy(g_cTmpBuf, pcDirectory, sizeof(g_cTmpBuf));
430 }
431 }
432 //
433 // If the argument is .. then attempt to remove the lowest level
434 // on the CWD.

Page 7
sd_card.c

435 //
436 else if(!strcmp(pcDirectory, ".."))
437 {
438 //
439 // Get the index to the last character in the current path.
440 //
441 uIdx = strlen(g_cTmpBuf) - 1;
442
443 //
444 // Back up from the end of the path name until a separator (/)
445 // is found, or until we bump up to the start of the path.
446 //
447 while((g_cTmpBuf[uIdx] != '/') && (uIdx > 1))
448 {
449 //
450 // Back up one character.
451 //
452 uIdx--;
453 }
454
455 //
456 // Now we are either at the lowest level separator in the
457 // current path, or at the beginning of the string (root).
458 // So set the new end of string here, effectively removing
459 // that last part of the path.
460 //
461 g_cTmpBuf[uIdx] = 0;
462 }
463 //
464 // Otherwise this is just a normal path name from the current
465 // directory, and it needs to be appended to the current path.
466 //
467 else
468 {
469 //
470 // Test to make sure that when the new additional path is
471 // added on to the current path, there is room in the buffer
472 // for the full new path. It needs to include a new separator,
473 // and a trailing null character.
474 //
475 if(strlen(g_cTmpBuf) + strlen(pcDirectory) + 1 + 1 > sizeof(g_cCwdBuf))
476 {
477 *pulReason = NAME_TOO_LONG_ERROR;
478 return(FR_INVALID_OBJECT);
479 }
480 //
481 // The new path is okay, so add the separator and then append
482 // the new directory to the path.
483 //
484 else
485 {
486 //
487 // If not already at the root level, then append a /
488 //
489 if(strcmp(g_cTmpBuf, "/"))
490 {
491 strcat(g_cTmpBuf, "/");
492 }
493
494 //
495 // Append the new directory to the path.
496 //

Page 8
sd_card.c

497 strcat(g_cTmpBuf, pcDirectory);


498 }
499 }
500
501 //
502 // At this point, a candidate new directory path is in chTmpBuf.
503 // Try to open it to make sure it is valid.
504 //
505 fresult = f_opendir(&g_sDirObject, g_cTmpBuf);
506
507 //
508 // If it cant be opened, then it is a bad path. Inform
509 // user and return.
510 //
511 if(fresult != FR_OK)
512 {
513 *pulReason = OPENDIR_ERROR;
514 return(fresult);
515 }
516 //
517 // Otherwise, it is a valid new path, so copy it into the CWD and update
518 // the screen.
519 //
520 else
521 {
522 strncpy(g_cCwdBuf, g_cTmpBuf, sizeof(g_cCwdBuf));
523 }
524
525 //
526 // Return success.
527 //
528 return(FR_OK);
529 }
530
531 //
532 // Cmd_cd - This function implements the "cd" command. It takes an argument
533 // that specifies the directory to make the current working directory.
534 // Path separators must use a forward slash "/". The argument to cd
535 // can be one of the following:
536 // * root ("/")
537 // * a fully specified path ("/my/path/to/mydir")
538 // * a single directory name that is in the current directory("mydir")
539 // * parent directory ("..")
540 // It does not understand relative paths, so dont try something like
541 // this: ("../my/new/path")
542 // Once the new directory is specified, it attempts to open the
543 // directory to make sure it exists. If the new path is opened
544 // successfully, then the current working directory (cwd) is changed
545 // to the new path.
546 //
547 int
548 Cmd_cd(int argc, char *argv[])
549 {
550 unsigned long ulReason;
551 FRESULT fresult;
552
553 //
554 // Try to change to the directory provided on the command line.
555 //
556 fresult = ChangeToDirectory(argv[1], &ulReason);
557
558 //

Page 9
sd_card.c

559 // If an error was reported, try to offer some helpful information.


560 //
561 if(fresult != FR_OK)
562 {
563 switch(ulReason)
564 {
565 case OPENDIR_ERROR:
566 UARTprintf("Error opening new directory.\n");
567 break;
568
569 case NAME_TOO_LONG_ERROR:
570 UARTprintf("Resulting path name is too long.\n");
571 break;
572
573 default:
574 UARTprintf("An unrecognized error was reported.\n");
575 break;
576 }
577 }
578
579 //
580 // Return the appropriate error code.
581 //
582 return(fresult);
583 }
584
585 //
586 // Cmd_pwd - This function implements the "pwd" command. It simply prints the
587 // current working directory.
588 //
589 int
590 Cmd_pwd(int argc, char *argv[])
591 {
592 //
593 // Print the CWD to the console.
594 //
595 UARTprintf("%s\n", g_cCwdBuf);
596
597 //
598 // Wait for the UART transmit buffer to empty.
599 //
600 // UARTFlushTx(false);
601
602 //
603 // Return success.
604 //
605 return(0);
606 }
607
608 //
609 // Cmd_cat - This function implements the "cat" command. It reads the contents
610 // of a file and prints it to the console. This should only be used
611 // on text files. If it is used on a binary file, then a bunch of
612 // garbage is likely to printed on the console.
613 //
614 int
615 Cmd_cat(int argc, char *argv[])
616 {
617 FRESULT fresult;
618 unsigned short usBytesRead;
619
620 //

Page 10
sd_card.c

621 // First, check to make sure that the current path (CWD), plus
622 // the file name, plus a separator and trailing null, will all
623 // fit in the temporary buffer that will be used to hold the
624 // file name. The file name must be fully specified, with path,
625 // to FatFs.
626 //
627 if(strlen(g_cCwdBuf) + strlen(argv[1]) + 1 + 1 > sizeof(g_cTmpBuf))
628 {
629 UARTprintf("Resulting path name is too long\n");
630 return(0);
631 }
632
633 //
634 // Copy the current path to the temporary buffer so it can be manipulated.
635 //
636 strcpy(g_cTmpBuf, g_cCwdBuf);
637
638 //
639 // If not already at the root level, then append a separator.
640 //
641 if(strcmp("/", g_cCwdBuf))
642 {
643 strcat(g_cTmpBuf, "/");
644 }
645
646 //
647 // Now finally, append the file name to result in a fully specified file.
648 //
649 strcat(g_cTmpBuf, argv[1]);
650
651 //
652 // Open the file for reading.
653 //
654 fresult = f_open(&g_sFileObject, g_cTmpBuf, FA_READ);
655
656 //
657 // If there was some problem opening the file, then return
658 // an error.
659 //
660 if(fresult != FR_OK)
661 {
662 return(fresult);
663 }
664
665 //
666 // Enter a loop to repeatedly read data from the file and display it,
667 // until the end of the file is reached.
668 //
669 do
670 {
671 //
672 // Read a block of data from the file. Read as much as can fit
673 // in the temporary buffer, including a space for the trailing null.
674 //
675 fresult = f_read(&g_sFileObject, g_cTmpBuf, sizeof(g_cTmpBuf) - 1,
676 &usBytesRead);
677
678 //
679 // If there was an error reading, then print a newline and
680 // return the error to the user.
681 //
682 if(fresult != FR_OK)

Page 11
sd_card.c

683 {
684 UARTprintf("\n");
685 return(fresult);
686 }
687
688 //
689 // Null terminate the last block that was read to make it a
690 // null terminated string that can be used with printf.
691 //
692 g_cTmpBuf[usBytesRead] = 0;
693
694 //
695 // Print the last chunk of the file that was received.
696 //
697 UARTprintf("%s", g_cTmpBuf);
698
699 //
700 // Continue reading until less than the full number of bytes are
701 // read. That means the end of the buffer was reached.
702 //
703 }
704 while(usBytesRead == sizeof(g_cTmpBuf) - 1);
705
706 //
707 // Return success.
708 //
709 return(0);
710 }
711
712 //
713 // Cmd_help - This function implements the "help" command. It prints a simple
714 // list of the available commands with a brief description.
715 //
716 int
717 Cmd_help(int argc, char *argv[])
718 {
719 tCmdLineEntry *pEntry;
720
721 //
722 // Print some header text.
723 //
724 UARTprintf("\nAvailable commands\n");
725 UARTprintf("------------------\n");
726
727 //
728 // Point at the beginning of the command table.
729 //
730 pEntry = &g_psCmdTable[0];
731
732 //
733 // Enter a loop to read each entry from the command table. The
734 // end of the table has been reached when the command name is NULL.
735 //
736 while(pEntry->pcCmd)
737 {
738 //
739 // Print the command name and the brief description.
740 //
741 UARTprintf("%s%s\n", pEntry->pcCmd, pEntry->pcHelp);
742
743 //
744 // Advance to the next entry in the table.

Page 12
sd_card.c

745 //
746 pEntry++;
747 }
748
749 //
750 // Return success.
751 //
752 return(0);
753 }
754
755 //
756 // This is the table that holds the command names, implementing functions,
757 // and brief description.
758 //
759 tCmdLineEntry g_psCmdTable[] =
760 {
761 { "help", Cmd_help, " : Display list of commands" },
762 { "h", Cmd_help, " : alias for help" },
763 { "?", Cmd_help, " : alias for help" },
764 { "ls", Cmd_ls, " : Display list of files" },
765 { "chdir", Cmd_cd, ": Change directory" },
766 { "cd", Cmd_cd, " : alias for chdir" },
767 { "pwd", Cmd_pwd, " : Show current working directory" },
768 { "cat", Cmd_cat, " : Show contents of a text file" },
769 { 0, 0, 0 }
770 };
771
772 //
773 // __error__ - The error routine that is called if the driver library
774 // encounters an error.
775 //
776 #ifdef DEBUG
777 void
778 __error__(char *pcFilename, unsigned long ulLine)
779 {
780 }
781 #endif
782
783 //
784 // ConfigureUART - Configure the UART and its pins. This must be called
785 // before UARTprintf().
786 //
787 void
788 ConfigureUART(void)
789 {
790 //
791 // Enable UART0
792 //
793 SysCtlPeripheralEnable(SYSCTL_PERIPH_SCI1);
794
795 //
796 // Configure GPIO Pins for UART mode.
797 //
798 EALLOW;
799 GpioCtrlRegs.GPAMUX2.bit.GPIO28 = 1;
800 GpioCtrlRegs.GPAPUD.bit.GPIO28 = 0;
801 GpioCtrlRegs.GPAQSEL2.bit.GPIO28 = 3;
802 GpioCtrlRegs.GPADIR.bit.GPIO28 = 0;
803
804 GpioCtrlRegs.GPAMUX2.bit.GPIO29 = 1;
805 GpioCtrlRegs.GPAPUD.bit.GPIO29 = 0;
806 GpioCtrlRegs.GPADIR.bit.GPIO29 = 1;

Page 13
sd_card.c

807 EDIS;
808
809 //
810 // Initialize the UART for console I/O.
811 //
812 UARTStdioConfig(0, 115200, SysCtlLowSpeedClockGet(SYSTEM_CLOCK_SPEED));
813 }
814
815 //
816 // Main - It performs initialization, then runs a command processing loop to
817 // read commands from the console.
818 //
819 int
820 main(void)
821 {
822 int nStatus;
823 FRESULT fresult;
824
825 //
826 // Set the clocking to run from the PLL at 50MHz
827 //
828 SysCtlClockSet(SYSCTL_OSCSRC_OSC2 | SYSCTL_PLL_ENABLE | SYSCTL_IMULT(10) |
829 SYSCTL_SYSDIV(2));
830 SysCtlAuxClockSet(SYSCTL_OSCSRC_OSC2 | SYSCTL_PLL_ENABLE |
831 SYSCTL_IMULT(12) | SYSCTL_SYSDIV(2)); //60 MHz
832
833 #ifdef _FLASH
834 //
835 // Copy time critical code and Flash setup code to RAM
836 // This includes the following functions: InitFlash();
837 // The RamfuncsLoadStart, RamfuncsLoadSize, and RamfuncsRunStart
838 // symbols are created by the linker. Refer to the device .cmd file.
839 //
840 memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
841
842 //
843 // Call Flash Initialization to setup flash waitstates
844 // This function must reside in RAM
845 //
846 InitFlash();
847 #endif
848
849 //
850 // Initialize interrupt controller and vector table
851 //
852 InitPieCtrl();
853 InitPieVectTable();
854
855 //
856 // Set the system tick to fire 100 times per second.
857 //
858 SysTickInit();
859 SysTickPeriodSet(SysCtlClockGet(SYSTEM_CLOCK_SPEED) / 100);
860 SysTickIntRegister(SysTickHandler);
861 SysTickIntEnable();
862 SysTickEnable();
863
864 //
865 // Enable Interrupts
866 //
867 IntMasterEnable();
868

Page 14
sd_card.c

869 //
870 // Configure UART0 for debug output.
871 //
872 ConfigureUART();
873
874 //
875 // Print hello message to user.
876 //
877 UARTprintf("\n\nSD Card Example Program\n");
878 UARTprintf("Type \'help\' for help.\n");
879
880 //
881 // Mount the file system, using logical disk 0.
882 //
883
884
885 WORD bw;
886 fresult = f_mount(0, &FatFs);
887 fresult = f_open(&Fil, "arun.txt", FA_WRITE | FA_CREATE_ALWAYS);
888
889
890
891
892
893 fresult = f_lseek(&g_sFileObject,4);
894 fresult = f_write(&Fil, "test", 4, &bw);
895 f_sync(&Fil);
896
897
898
899
900 //fresult = f_mount(0, &g_sFatFs);
901 if(fresult != FR_OK)
902 {
903 UARTprintf("f_mount error: %s\n", StringFromFresult(fresult));
904 return(1);
905 }
906
907 //
908 // Enter an (almost) infinite loop for reading and processing commands from
909 // the user.
910 //
911 while(1)
912 {
913 //
914 // Print a prompt to the console. Show the CWD.
915 //
916 UARTprintf("\n%s> ", g_cCwdBuf);
917
918 //
919 // Get a line of text from the user.
920 //
921 UARTgets(g_cCmdBuf, sizeof(g_cCmdBuf));
922
923 //
924 // Pass the line from the user to the command processor.
925 // It will be parsed and valid commands executed.
926 //
927 nStatus = CmdLineProcess(g_cCmdBuf);
928
929 //
930 // Handle the case of bad command.

Page 15
sd_card.c

931 //
932 if(nStatus == CMDLINE_BAD_CMD)
933 {
934 UARTprintf("Bad command!\n");
935 }
936 //
937 // Handle the case of too many arguments.
938 //
939 else if(nStatus == CMDLINE_TOO_MANY_ARGS)
940 {
941 UARTprintf("Too many arguments for command processor!\n");
942 }
943
944 //
945 // Otherwise the command was executed. Print the error
946 // code if one was returned.
947 //
948 else if(nStatus != 0)
949 {
950 UARTprintf("Command returned error code %s\n",
951 StringFromFresult((FRESULT)nStatus));
952 }
953 }
954 }
955
956 //
957 // End of file
958 //
959

Page 16

You might also like