Update repo

This commit is contained in:
2026-08-30 23:04:35 -07:00
parent 749dab5721
commit ce65a0f59a
14950 changed files with 4408250 additions and 1 deletions
@@ -0,0 +1,87 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="alternate" hreflang="ja" title="Japanese version" href="00index_j.html">
<link rel="stylesheet" href="css_e.css" type="text/css" media="screen" title="ELM Default">
<title>ELM - Generic FAT File System Module</title>
</head>
<body>
<h1>FAT File System Module</h1>
<hr>
<div class="abst">
<img src="img/layers.png" class="rset" width="245" height="255" alt="layer">
<p>FatFs module is an experimental project to implement a FAT file system to small embdded systems. The FatFs module is written in compliance with ANSI C, therefore it is independent of hardware architecture. It can be incorporated into most 8-bit microcontrollers, such as 8051, PIC, AVR, H8, Z80 and etc..., without any change. I created two modules in different configurations in consideration of various use.</p>
<h4>Features of FatFs Module</h4>
<ol>
<li>Separated buffer for FAT structure and each file, suitable for fast multiple file accsess.</li>
<li>Supports multiple drives/partitions.</li>
<li>Supports FAT12, FAT16(+FAT64) and FAT32. <small>(FAT64: FAT16 in 64KB/cluster)</small></li>
<li>Supports 8.3 format file name and NT lower case flag. (LFN is not supported)</li>
<li>Supports two partitioning rules: FDISK and Super-floppy.</li>
<li>Optimized for 8/16-bit microcontrollers.</li>
</ol>
<h4>Features of Tiny-FatFs Module (different to FatFs)</h4>
<ol>
<li>Very low memory consumption, suitable for small memory system. (RAM:1KB)</li>
<li>Supports only single drive.</li>
</ol>
</div>
<div class="para">
<h3>Application Interface</h3>
<p>FatFs/Tiny-FatFs module provides following functions.</p>
<ul>
<li><a href="en/mount.html">f_mount</a> - Register/Unregister a Work Area</li>
<li><a href="en/open.html">f_open</a> - Open/Create a File</li>
<li><a href="en/close.html">f_close</a> - Close a File</li>
<li><a href="en/read.html">f_read</a> - Read File</li>
<li><a href="en/write.html">f_write</a> - Write File</li>
<li><a href="en/lseek.html">f_lseek</a> - Move R/W Pointer</li>
<li><a href="en/sync.html">f_sync</a> - Flush Cached Data</li>
<li><a href="en/opendir.html">f_opendir</a> - Open a Directory</li>
<li><a href="en/readdir.html">f_readdir</a> - Read a Directory Item</li>
<li><a href="en/getfree.html">f_getfree</a> - Get Free Clusters</li>
<li><a href="en/stat.html">f_stat</a> - Get File Status</li>
<li><a href="en/mkdir.html">f_mkdir</a> - Create a Directory</li>
<li><a href="en/unlink.html">f_unlink</a> - Remove a File or Directory</li>
<li><a href="en/chmod.html">f_chmod</a> - Change Attribute</li>
<li><a href="en/rename.html">f_rename</a> - Rename/Move a File or Directory</li>
<li><a href="en/mkfs.html">f_mkfs</a> - Create a File System on the Drive</li>
</ul>
</div>
<div class="para">
<h3>Disk I/O Interface</h3>
<p>Since the FatFs/Tiny-FatFs module is completely separated from disk I/O layer, it requires following functions to lower layer to read/write physical disk and to get current time. These functions must be provided by user. The low level disk I/O module that have this interace must be provided by user. The sample projects are also available.</p>
<ul>
<li><a href="en/dinit.html">disk_initialize</a> - Initialize disk drive</li>
<li><a href="en/dstat.html">disk_status</a> - Get disk status</li>
<li><a href="en/dread.html">disk_read</a> - Read sector(s)</li>
<li><a href="en/dwrite.html">disk_write</a> - Write sector(s)</li>
<li><a href="en/dioctl.html">disk_ioctl</a> - Control device dependent features</li>
<li><a href="en/fattime.html">get_fattime</a> - Get current time</li>
</ul>
</div>
<div class="para">
<h3>Resources</h3>
<p>The FatFs/Tiny-FatFs module is a free software and is opened for education, research and development. You can use, modify and/or republish it for personal, non-profit or profit use without any restriction under your responsibility.</p>
<ul>
<li><a href="http://elm-chan.org/fsw/ff/00index_e.html">FatFs home page</a></li>
<li><a href="en/appnote.html">FatFs module application note</a></li>
<li><a href="img/rwtest.png">Benchmark</a> (Test Board: ATmega64/9.2MHz with <a href="img/rw_mmc.jpeg">MMC</a>/<a href="img/rw_ata.jpeg">HDD</a>/<a href="img/rw_cfc.jpeg">CFC</a>)</li>
<li><a href="http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx">FAT32 Specification</a> (Microsoft)</li>
<li><a href="http://elm-chan.org/docs/mmc/mmc_e.html">How to Use MMC/SDC</a></li>
</ul>
</div>
</body>
</html>
@@ -0,0 +1,87 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="alternate" hreflang="en" title="English version" href="00index_e.html">
<link rel="stylesheet" href="css_j.css" type="text/css" media="screen" title="ELM Default">
<title>ELM - 汎用FATファイルシステム・モジュール</title>
</head>
<body>
<h1>FATファイルシステム・モジュール</h1>
<hr>
<div class="abst">
<img src="img/layers.png" class="rset" width="245" height="255" alt="layer">
<p>小規模な組み込みシステム向けの汎用FATファイルシステム・モジュールです。ANSI C準拠でハードウェア・アーキテクチャには依存しないので、必要なワーク・エリアが確保できれば、8051, PIC, AVR, H8, Z80などほとんどの8ビット・マイコンでそのまま使用可能です。いろいろな使用形態を考慮して、高機能版(<strong>FatFs</strong>)と省メモリ版(<strong>Tiny-FatFs</strong>)の2通りを作成してみました。</p>
<h4>FatFsの特徴</h4>
<ol>
<li>ファイル・システム用とファイルI/O用バッファを分離し、複数ファイルの高速アクセスに適する</li>
<li>複数のドライブ・パーテーションをサポート</li>
<li>FAT12, FAT16(+FAT64), FAT32に対応 <small>(FAT64: FAT16 in 64KB/cluster)</small></li>
<li>8.3形式ファイル名とNT小文字フラグに対応(LFN未対応)</li>
<li>FDISKフォーマットおよびSFDフォーマットに対応</li>
<li>8/16ビットマイコン向けにコードを最適化</li>
</ol>
<h4>Tiny-FatFsの特徴(FatFsとの相違)</h4>
<ol>
<li>RAMの使用量を削減し、小メモリ・システム(RAM:1KB)にも対応</li>
<li>単一ドライブのみサポート</li>
</ol>
</div>
<div class="para">
<h3>上位レイヤI/F</h3>
<p>FatFs/Tiny-FatFsモジュールは、次のファイル操作関数を提供しています。</p>
<ul>
<li><a href="ja/mount.html">f_mount</a> - ワークエリアの登録・削除</li>
<li><a href="ja/open.html">f_open</a> - ファイルのオープン・作成</li>
<li><a href="ja/close.html">f_close</a> - ファイルのクローズ</li>
<li><a href="ja/read.html">f_read</a> - ファイルの読み込み</li>
<li><a href="ja/write.html">f_write</a> - ファイルの書き込み</li>
<li><a href="ja/lseek.html">f_lseek</a> - ファイルR/Wポインタの移動</li>
<li><a href="ja/sync.html">f_sync</a> - キャッシュされたデータのフラッシュ</li>
<li><a href="ja/opendir.html">f_opendir</a> - ディレクトリのオープン</li>
<li><a href="ja/readdir.html">f_readdir</a> - ディレクトリの読み出し</li>
<li><a href="ja/getfree.html">f_getfree</a> - ディスク空き領域の取得</li>
<li><a href="ja/stat.html">f_stat</a> - ファイル・ステータスの取得</li>
<li><a href="ja/mkdir.html">f_mkdir</a> - ディレクトリの作成</li>
<li><a href="ja/unlink.html">f_unlink</a> - ファイルまたはディレクトリの削除</li>
<li><a href="ja/chmod.html">f_chmod</a> - ファイルまたはディレクトリ属性の変更</li>
<li><a href="ja/rename.html">f_rename</a> - ファイルまたはディレクトリの名前変更・移動</li>
<li><a href="ja/mkfs.html">f_mkfs</a> - ディスクのフォーマット</li>
</ul>
</div>
<div class="para">
<h3>下位レイヤI/F</h3>
<p>FatFs/Tiny-FatFsモジュールは、物理ドライブへのアクセスや現在時刻を得るため、下位レイヤに次のインターフェースを要求します。これらのインターフェースを持つそれぞれの記録メディアに対応したディスクI/Oモジュールは、ユーザにより用意する必要があります。(サンプルもあり)</p>
<ul>
<li><a href="ja/dinit.html">disk_initialize</a> - ディスク・ドライブの初期化</li>
<li><a href="ja/dstat.html">disk_status</a> - ディスク・ドライブの状態取得</li>
<li><a href="ja/dread.html">disk_read</a> - ディスクからの読み込み</li>
<li><a href="ja/dwrite.html">disk_write</a> - ディスクへの書き込み</li>
<li><a href="ja/dioctl.html">disk_ioctl</a> - その他のドライブ制御</li>
<li><a href="ja/fattime.html">get_fattime</a> - 日付・時刻の取得</li>
</ul>
</div>
<div class="para">
<h3>資料</h3>
<p>FatFs/Tiny-FatFsモジュールはフリー・ソフトウェアとして教育・研究・開発用に公開しています。どのような利用目的(個人・非商用・商用)でも使用・改変・配布について一切の制限はありませんが、全て利用者の責任の下での利用とします。</p>
<ul>
<li><a href="http://elm-chan.org/fsw/ff/00index_j.html">FatFsホームページ</a></li>
<li><a href="ja/appnote.html">FatFsモジュール・アプリケーション・ノート</a></li>
<li><a href="img/rwtest.png">パフォーマンス・テスト</a>(テスト・ボード:ATmega64/9.2MHz with <a href="img/rw_mmc.jpeg">MMC</a>/<a href="img/rw_ata.jpeg">HDD</a>/<a href="img/rw_cfc.jpeg">CFC</a></li>
<li><a href="http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx">FAT32仕様書</a> (Microsoft)</li>
<li><a href="http://elm-chan.org/docs/mmc/mmc.html">MMCの使いかた</a></li>
</ul>
</div>
</body>
</html>
@@ -0,0 +1,55 @@
* {margin: 0; padding: 0; border-width: 0;}
body {margin: 8px; background-color: #e0ffff; font-color: black; line-height: 133%; max-width: 1024px;}
a:link {color: blue;}
a:visited {color: darkmagenta;}
a:hover {background-color: #a0ffff;}
a:active {color: darkmagenta; position: relative; top: 1px; left: 1px;}
abbr {border-width: 1px;}
p {margin: 0 0 0.3em 1em;}
em {font-style: normal; font-weight: bold; margin: 0 0.1em;}
pre em {font-style: italic; font-weight: normal;}
strong {}
pre {margin: 1em; line-height: 1.2em; background-color: white;}
tt {margin: 0 0.2em;}
ol {margin: 0 2em;}
ul {margin: 0 2em;}
dl {margin: 0 1em;}
dt {font-family: monospace;}
dl.par dt {margin: 0.5em 0 0 0 ; font-style: italic; }
dl.ret dt {margin: 0.5em 0 0 0 ; font-weight: bold;}
dd {margin: 0 2em;}
hr {border-width: 1px; margin: 1em;}
div.abst {font-family: sans-serif;}
div.para {clear: both; font-family: serif;}
.equ {text-indent: 0; margin: 1em 2em 1em;}
.indent {margin-left: 2em;}
.rset {float: right; margin: 0 0 0.5em 0.5em;}
.lset {float: left; margin: 0 0.5em 0.5em 0.5em;}
ul.flat li {list-style-type: none; margin: 0;}
a.imglnk img {border: 1px solid;}
.iequ {white-space: nowrap; font-weight: bold;}
.clr {clear: both;}
.it {font-style: italic;}
.mfd {font-size: 0.7em; padding: 0 1px; border: 1px solid; white-space : nowrap}
h1 {line-height: 1em; font-size: 2em; font-family: sans-serif; padding: 0.3em 0 0.3em;}
p.hdd {float: right; text-align: right; margin-top: 0.5em;}
hr.hds {clear: both; margin-bottom: 1em;}
h2 {font-size: 1.5em; font-family: sans-serif; margin: 0 0 0.5em;}
h3 {font-size: 1.5em; font-family: sans-serif; margin: 2em 0 0.5em;}
h4 {font-size: 1.2em; font-family: sans-serif; margin: 1.5em 0 0.2em;}
h5 {font-size: 1em; font-family: sans-serif; margin: 0.5em 0 0em;}
small {font-size: 80%;}
.indent {margin-left: 2em;}
/* Tables */
table {margin: 4px; border-collapse: collapse; border-style: solid; border-width: 2px; border-color: black; }
th {background-color: white; border-style: solid; border-width: 1px 1px 2px; border-color: black; padding: 0 3px; vertical-align: top; white-space: nowrap;}
td {background-color: white; border-style: solid; border-width: 1px; border-color: black; padding: 0 3px; vertical-align: top; line-height: 1.3em;}
table.lst td:first-child {font-family: monospace;}
table.lst2 td {font-family: monospace;}
table caption {font-family: sans-serif; font-weight: bold;}
p.foot {clear: both; text-indent: 0; margin: 1em 0.5em 1em;}
@@ -0,0 +1,58 @@
@charset "Shift_JIS";
/* Common style sheet for Tech Notes */
* {margin: 0; padding: 0; border-width: 0;}
body {margin: 8px; background-color: #e0ffff; font-color: black; line-height: 133%; letter-spacing: 1px; max-width: 1024px;}
a:link {color: blue;}
a:visited {color: darkmagenta;}
a:hover {background-color: #a0ffff;}
a:active {color: darkmagenta; position: relative; top: 1px; left: 1px;}
abbr {border-width: 1px;}
p {text-indent: 1em; margin: 0 0 0.3em 0.5em;}
em {font-style: normal; font-weight: bold; margin: 0 0.1em;}
pre em {font-style: italic; font-weight: normal;}
strong {}
pre {margin: 1em; line-height: 1.2em; letter-spacing: 0; background-color: white;}
tt {margin: 0 0.2em; letter-spacing: 0;}
ol {margin: 0 2em;}
ul {margin: 0 2em;}
dl {margin: 0 1em;}
dt {font-family: monospace;}
dl.par dt {margin: 0.5em 0 0 0 ; font-style: italic; letter-spacing: 0;}
dl.ret dt {margin: 0.5em 0 0 0 ; font-family: monospace; letter-spacing: 0; font-weight: bold;}
dd {margin: 0 2em;}
hr {border-width: 1px; margin: 1em;}
div.abst {font-family: "MS Pゴシック",sans-serif;}
div.para {clear: both; font-family: "MS P明朝",serif;}
.equ {text-indent: 0; margin: 1em 2em 1em;}
.indent {margin-left: 2em;}
.rset {float: right; margin: 0 0 0.5em 0.5em;}
.lset {float: left; margin: 0 0.5em 0.5em 0.5em;}
ul.flat li {list-style-type: none; margin: 0;}
a.imglnk img {border: 1px solid;}
.iequ {white-space: nowrap; font-weight: bold;}
.clr {clear: both;}
.it {font-style: italic;}
.mfd {font-size: 0.7em; padding: 0 1px; border: 1px solid; white-space : nowrap}
h1 {line-height: 1em; font-size: 2em; font-family: sans-serif; padding: 0.3em 0 0.3em;}
p.hdd {float: right; text-align: right; margin-top: 0.5em;}
hr.hds {clear: both; margin-bottom: 1em;}
h2 {font-size: 1.5em; font-family: sans-serif; margin: 0 0 0.5em;}
h3 {font-size: 1.5em; font-family: sans-serif; margin: 2em 0 0.5em;}
h4 {font-size: 1.2em; font-family: sans-serif; margin: 1.5em 0 0.2em;}
h5 {font-size: 1em; font-family: sans-serif; margin: 0.5em 0 0em;}
small {font-size: 80%;}
.indent {margin-left: 2em;}
/* Tables */
table {margin: 4px; border-collapse: collapse; border-style: solid; border-width: 2px; border-color: black; letter-spacing: 0;}
th {background-color: white; border-style: solid; border-width: 1px 1px 2px; border-color: black; padding: 0 3px; vertical-align: top;}
td {background-color: white; border-style: solid; border-width: 1px; border-color: black; padding: 0 3px; vertical-align: top; line-height: 1.3em;}
table.lst td:first-child {font-family: monospace; white-space: nowrap;}
table.lst2 td {font-family: monospace; white-space: nowrap;}
table caption {font-family: sans-serif; font-weight: bold;}
p.foot {clear: both; text-indent: 0; margin: 1em 0.5em 1em;}
@@ -0,0 +1,124 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_e.html">
<link rel="stylesheet" href="../css_e.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs Module Application Note</title>
</head>
<body>
<h1>FatFs Module Application Note</h1>
<hr>
<div class="para">
<h3>Considerations on porting to various platform</h3>
<p>The FatFs module is assuming following terms on portability.</p>
<ul>
<li>ANSI C<br>
The FatFs module is a middleware that written in ANSI C. There is no platform dependence, so long as the compiler is in compliance with ANSI C. However it handles the system portable FAT structures. You must take the <strong>endian</strong> into consideration. This setting is defined in ff.h (tff.h). It must be changed for your platform first or the compiler will abort with an error.</li>
<li>Size of char/short/long are 8/16/32 bit and int is 16 bit or grater.<br>
These correspondence are defined in integer.h. This will not be a problem on most compilers. When any conflict of the definitions between the integer.h and existing definitions is occured, you must resolve the confrict with care.</li>
</ul>
</div>
<div class="para">
<h3>Memory Usage (R0.04b)</h3>
<p>These are the memory usage on some target systems. The memory sizes are in unit of byte, D means number of logical drives and F means number of open files. All samples are optimezed in code size.</p>
<table class="lst2">
<tr><th></th><th>AVR</th><th>H8/300H</th><th>MSP430</th><th>TLCS-870/C</th><th>V850ES</th><th>SH2</th></tr>
<tr><td>Compiler</td><td>gcc</td><td>CH38</td><td>CL430</td><td>CC870C</td><td>CA850</td><td>SHC</td></tr>
<tr><td>_MCU_ENDIAN</td><td>1</td><td>2</td><td>2</td><td>1</td><td>1</td><td>2</td></tr>
<tr><td>FatFs Code<br>(Standard, R/W cfg.)</td><td>8722</td><td>8776</td><td></td><td></td><td>6402</td><td>7338</td></tr>
<tr><td>FatFs Code<br>(Minimum, R/W cfg.)</td><td>5814</td><td>5722</td><td></td><td></td><td>4094</td><td>4906</td></tr>
<tr><td>FatFs Code<br>(Standard, R/O cfg.)</td><td>4248</td><td>4096</td><td></td><td></td><td>3010</td><td>3506</td></tr>
<tr><td>FatFs Code<br>(Minimum, R/O cfg.)</td><td>3038</td><td>3110</td><td></td><td></td><td>2210</td><td>2698</td></tr>
<tr><td>FatFs Work (Static)</td><td>D*2 + 2</td><td>D*4 + 2</td><td></td><td></td><td>D*4 + 2</td><td>D*4 + 2</td></tr>
<tr><td>FatFs Work (Dynamic)</td><td>D*554 + F*544</td><td>D*554 + F*550</td><td></td><td></td><td>D*554 + F*550</td><td>D*554 + F*550</td></tr>
<tr><td>Tiny-FatFs Code<br>(Standard, R/W cfg.)</td><td>7264</td><td>7240</td><td>6634</td><td>8837</td><td></td><td></td></tr>
<tr><td>Tiny-FatFs Code<br>(Minimum, R/W cfg.)</td><td>4750</td><td>4806</td><td>4366</td><td>6163</td><td></td><td></td></tr>
<tr><td>Tiny-FatFs Code<br>(Standard, R/O cfg.)</td><td>3600</td><td>3548</td><td>3212</td><td>4347</td><td></td><td></td></tr>
<tr><td>Tiny-FatFs Code<br>(Minimum, R/O cfg.)</td><td>2568</td><td>2702</td><td>2394</td><td>3322</td><td></td><td></td></tr>
<tr><td>Tiny-FatFs Wrok (Static)</td><td>4</td><td>6</td><td>4</td><td>4</td><td></td><td></td></tr>
<tr><td>Tiny-FatFs Work (Dynamic)</td><td>544 + F*28</td><td>544 + F*32</td><td>544 + F*28</td><td>544 + F*28</td><td></td><td></td></tr>
</table>
</div>
<div class="para">
<h3>FatFs vs. Tiny-FatFs</h3>
<p>For most applications, such as portable audio and data logger, Tiny-FatFs is the best choice. However because the Tiny-FatFs does not support FAT32 in default, there is a limitation that can handle only tiny storage upto 2GB(4GB in FAT64). The FAT32 support can be added by <tt>_USE_FAT32</tt> option with an additional code size. The FatFs is suitable for fast multiple files access, and for multiple drive system.</p>
<div class="rset">
<table class="lst2">
<tr><th>Memory Size</th><th>FAT Type</th></tr>
<tr><td>&lt;= 64MB</td><td>FAT12</td></tr>
<tr><td>128MB - 2GB</td><td>FAT16</td></tr>
<tr><td>&gt;= 4GB</td><td>FAT32</td></tr>
</table>
</div>
<p>Rignt table shows the correspondence between memory size and FAT type for SD memroy card and they are shipped with this format. The data area is justified to the erase block boundary and the memory card works with the best performance. For that reason, the memory card should not be reformated with PC. When cluster size or FAT type is changed, the write performance can be decreased.</p>
</div>
<div class="para">
<h3>Performance effective file access</h3>
<p>For good performance on reading/writing files on the small embedded system, application program should consider what process is done in the FatFs module. The file data on the disk is transferred by f_read function in following process.</p>
<p>Figure 1. Sector miss-aligned read (short)<br>
<img src="../img/f1.png" width="490" height="73">
</p>
<p>Figure 2. Sector miss-aligned read (long)<br>
<img src="../img/f2.png" width="490" height="140">
</p>
<p>Figure 3. Sector aligned read<br>
<img src="../img/f3.png" width="490" height="119">
</p>
<p>The file I/O buffer means a sector buffer to read/write a partial data on the sector. On the FatFs, member buffer[] in the file object is used. On the Tiny-FatFs, member win[] in the file system object is used.</p>
<p>Tiny-FatFs processes all data transfer and access to the FAT/directory with only one sector buffer, so that FAT sector cached into the buffer is lost and it must reloaded at every cluster boundary. FatFs has a FAT/directory buffer separated from file I/O buffer, the frequency of FAT accesses is only 1/341, 1/256 or 1/128 (when cluster is contiguous) compared to Tiny-FatFs. Thus the Tiny-FatFs is sacrificing its performance in compensation for very small memory footprint.</p>
<p>Figure 1 shows that partial sector data is transferred via the file I/O buffer. At long data transfer shown in Figure 2, middle of transfer data that aligned to sector boundary is transferred into memory directly. Figure 3 shows that entier transfer data is aligned to the sector boundary. In this case, file I/O buffer is not used. At the unbuffered transfer, maximum extent of sectors are read with disk_read function at a time but it never across cluster boundary even if it is contiguous.</p>
<p>Therefore taking effort to sector aligned read/write accesss eliminates memcpy and the read/write performance will be improved. Besides the effect, cached FAT sector is not flushed during read/write access on the Tiny-FatFs, so that it can achieve same performance as FatFs and its small memory footprint simultanesously.</p>
</div>
<div class="para">
<h3>Critical section</h3>
<p>When write operation to the FAT file system is interrupted due to any accidental failure, such as sudden blackout, incorrect disk removal and unrecoverable data error, the FAT structure can be destroyed. Following images shows the critical section on the FatFs module.</p>
<div class="lset">
Figure 4. Long critical section<br>
<img src="../img/f4.png" width="320" height="436" alt="fig.4">
</div>
<div class="lset">
Figure 5. Minimized critical section<br>
<img src="../img/f5.png" width="320" height="436" alt="fig.5">
</div>
<br class="clr">
<p>An interruption in the red section can cause a cross link; as a result, the file/directory being changed will be lost. There is one or more possibility listed below when an interruption in the yellow section is occured.</p>
<ul>
<li>File data being rewrited is collapted.</li>
<li>A file being appended returns initial state.</li>
<li>A file created as new is gone.</li>
<li>A file created as new or in overwrite remains with length of zero.</li>
<li>Efficiency of disk use gets worse due to lost chain.</li>
</ul>
<p>Each case does not affect the files that not in write operation. To minimize risk of data loss, the critical section can be minimized like shown in Figure 5 by minimizing the time that file is opened in write mode and using f_sync function properly.</p>
</div>
<div class="para">
<h3>Problems and Ideas</h3>
<ul>
<li>Abstraction of file object<br>
Currently the file object structure is held by application layer. This is not a problem for Tiny-FatFs, it consumes the task stack only 26 bytes per file. But FatFs requires 550 bytes per file. When managed the file objects in file handle, stack consumption at application module will able to be reduced. In this case, the work area for file objects is managed in FatFs module. This has a disadvantage that direct access to the file object structure cannot be used and additional file functions, such as feof and ftell, will be needed.</li>
<li>Efficient sector buffer management<br>
The FatFs module has only one sector buffer per logical drive. There is an ineffciency on random file access with many files simultanesously. When additional memory for the sector buffer is available, the file access performance will able to be improved with an advanced cache mechanism.</li>
<li>Long file name<br>
There is an extended feature to handle long file name (LFN) up to 255 characters, in addition to 8.3 format file name, on FAT file system. To support this, 512 byte string buffer for file name and UCS-2 - Shift_JIS mutual conversion table are required. Therefore memory consumption of code and work area will be increased drastically. The FatFs module does not support this feature. The LFN on the FAT file system is a patent of Microsoft. When support it on the commercial products, you have to be licensed.</li>
<li>Porting to RTOS<br>
When use FatFs module from only one task, no consideration is needed. However when make access to a logical drive from two or more tasks simultanesously, any exclusion control will be required. The FatFs module is also ported to a free RTOS based on &mu;ITRON by <a href="http://www.toppers.jp/en/index.html">TOPPERS Project</a>.</li>
</ul>
<br>
<p>These are the problems and ideas on current revision of FatFs module. However the main target of FatFs module is 8 bit microcontrollers. These extensions requires much resource and the FatFs will unable to be ported to the 8 bit system. This may be the most serious problem on future plan.</p>
</div>
<p class="foot"><a href="../00index_e.html">Return</a></p>
</body>
</html>
@@ -0,0 +1,89 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_e.html">
<link rel="stylesheet" href="../css_e.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_chmod</title>
</head>
<body>
<div class="para">
<h2>f_chmod</h2>
<p>The f_chmod function changes the attribute of a file or directory.</p>
<pre>
FRESULT f_chmod (
const char* <em>FileName</em>, /* Pointer to the file or directory */
BYTE <em>Attribute</em>, /* Attribute flags */
BYTE <em>AttributeMask</em> /* Attribute masks */
);
</pre>
</div>
<div class="para">
<h4>Parameter</h4>
<dl class="par">
<dt>FileName</dt>
<dd>Pointer to the null-terminated string that specifies a <a href="filename.html">file or directory</a> to be changed</dd>
<dt>Attribute</dt>
<dd>Attribute flags to be set in one or more combination of the following flags. The specified flags are set and others are cleard.<br>
<table class="lst">
<tr><th>Attribute</th><th>Description</th></td>
<tr><td>AM_RDO</td><td>Read only</td></td>
<tr><td>AM_ARC</td><td>Archive</td></td>
<tr><td>AM_SYS</td><td>System</td></td>
<tr><td>AM_HID</td><td>Hidden</td></td>
</table>
</dd>
<dt>AttributeMask</dt>
<dd>Attribute mask that specifies which attribute is changed. The specified aattributes are set or cleard.</dd>
</dl>
</div>
<div class="para">
<h4>Return Values</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>The function succeeded.</dd>
<dt>FR_NO_FILE</dt>
<dd>Could not find the file.</dd>
<dt>FR_NO_PATH</dt>
<dd>Could not find the path.</dd>
<dt>FR_INVALID_NAME</dt>
<dd>The file name is invalid.</dd>
<dt>FR_INVALID_DRIVE</dt>
<dd>The drive number is invalid.</dd>
<dt>FR_NOT_READY</dt>
<dd>The disk drive cannot work due to no medium in the drive or any other reason.</dd>
<dt>FR_WRITE_PROTECTED</dt>
<dd>The medium is write protected.</dd>
<dt>FR_RW_ERROR</dt>
<dd>The function failed due to a disk error or an internal error.</dd>
<dt>FR_NOT_ENABLED</dt>
<dd>The logical drive has no work area.</dd>
<dt>FR_NO_FILESYSTEM</dt>
<dd>There is no valid FAT partition on the disk.</dd>
</dl>
</div>
<div class="para">
<h4>Description</h4>
<p>The f_chmod function changes the attribute of a file or directory. This function is not supported in read-only configuration and minimization level of &gt;=1.</p>
</div>
<div class="para">
<h4>Example</h4>
<pre>
// Set read-only flag, clear archive flag and others are retained.
f_chmod("file.txt", AR_RDO, AR_RDO | AR_ARC);
</pre>
</div>
<p class="foot"><a href="../00index_e.html">Return</a></p>
</body>
</html>
@@ -0,0 +1,60 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_e.html">
<link rel="stylesheet" href="../css_e.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_close</title>
</head>
<body>
<div class="para">
<h2>f_close</h2>
<p>The f_close function closes an open file.</p>
<pre>
FRESULT f_close (
FIL* <em>FileObject</em> /* Pointer to the file object structure */
);
</pre>
</div>
<div class="para">
<h4>Parameter</h4>
<dl class="par">
<dt>FileObject</dt>
<dd>Pointer to the open file object structure to be closed.</dd>
</dl>
</div>
<div class="para">
<h4>Return Values</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>The file object has been closed successfuly.</dd>
<dt>FR_RW_ERROR</dt>
<dd>The function failed due to a disk error or an internal error.</dd>
<dt>FR_NOT_READY</dt>
<dd>The disk drive cannot work due to no medium in the drive or any other reason.</dd>
<dt>FR_INVALID_OBJECT</dt>
<dd>The file object is invalid.</dd>
</dl>
</div>
<div class="para">
<h4>Description</h4>
<p>The f_close function closes an open file object. If any data has been written to the file, the cached information of the file is written back to the disk. After the function succeeded, the file object is no longer valid and it can be discarded. If the file object has been opened in read-only mode, it may be discarded without closing process by this function.</p>
</div>
<div class="para">
<h4>References</h4>
<p><tt><a href="open.html">f_open</a>, <a href="read.html">f_read</a>, <a href="write.html">f_write</a>, <a href="sync.html">f_sync</a>, <a href="sfile.html">FIL</a>, <a href="sfatfs.html">FATFS</a></tt></p>
</div>
<p class="foot"><a href="../00index_e.html">Return</a></p>
</body>
</html>
@@ -0,0 +1,44 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_e.html">
<link rel="stylesheet" href="../css_e.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - disk_initialize</title>
</head>
<body>
<div class="para">
<h2>disk_initialize</h2>
<p>The disk_initialize function initializes the disk drive.</p>
<pre>
DSTATUS disk_initialize (
BYTE <em>Drive</em> /* Physical drive number */
);
</pre>
</div>
<div class="para">
<h4>Parameters</h4>
<dl class="par">
<dt>Drive</dt>
<dd>Specifies the physical drive number to initialize.</dd>
</dl>
</div>
<div class="para">
<h4>Return Values</h4>
<p>This function returns a disk status as the result. For details of the disk status, refer to the <a href="dstat.html">disk_status</a> function.</p>
</div>
<div class="para">
<h4>Description</h4>
<p>The disk_initialize function initializes a physical drive. When the function succeeded, <tt>STA_NOINIT</tt> flag in the return value is cleard.</p>
</div>
<p class="foot"><a href="../00index_e.html">Return</a></p>
</body>
</html>
@@ -0,0 +1,65 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_e.html">
<link rel="stylesheet" href="../css_e.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - disk_ioctl</title>
</head>
<body>
<div class="para">
<h2>disk_ioctl</h2>
<p>The disk_ioctl function cntrols device specified features and miscellaneous functions other than disk read/write.</p>
<pre>
DRESULT disk_ioctl (
BYTE <em>Drive</em>, /* Drive number */
BYTE <em>Command</em>, /* Control command code */
void* <em>Buffer</em> /* Data transfer buffer */
);
</pre>
</div>
<div class="para">
<h4>Parameters</h4>
<dl class="par">
<dt>Drive</dt>
<dd>Specifies drive number (0-9).</dd>
<dt>Command</dt>
<dd>Specifies the command code.</dd>
<dt>Buffer</dt>
<dd>Pointer to the parameter buffer depends on the command code. When it is not used, specify a NULL pointer.</dd>
</dl>
</div>
<div class="para">
<h4>Return Value</h4>
<dl class="ret">
<dt>RES_OK (0)</dt>
<dd>The function succeeded.</dd>
<dt>RES_ERROR</dt>
<dd>Any error occured.</dd>
<dt>RES_PARERR</dt>
<dd>Invalid command code.</dd>
<dt>RES_NOTRDY</dt>
<dd>The disk dirve has not been initialized.</dd>
</dl>
</div>
<div class="para">
<h4>Description</h4>
<p>The FatFs module uses only device independent commands described below. Any device dependent function is not used. In read-only configuration, This function is not needed.</p>
<table class="lst">
<tr><th>Command</th><th>Description</td></tr>
<tr><td>GET_SECTOR_COUNT</td><td>Returns total sectors on the drive into the DWORD variable pointed by Buffer.</td></tr>
<tr><td>CTRL_SYNC</td><td>Make sure that the drive has finished to write data. When the module has a write back cache, write back the dirty sector immediately.</td></tr>
</table>
</div>
<p class="foot"><a href="../00index_e.html">Return</a></p>
</body>
</html>
@@ -0,0 +1,58 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_e.html">
<link rel="stylesheet" href="../css_e.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - disk_read</title>
</head>
<body>
<div class="para">
<h2>disk_read</h2>
<p>The disk_read function reads sector(s) from the disk drive.</p>
<pre>
DRESULT disk_read (
BYTE <em>Drive</em>, /* Physical drive number */
BYTE* <em>Buffer</em>, /* Pointer to the read buffer */
DWORD <em>SectorNumber</em>, /* Sector number to read from */
BYTE <em>SectorCount</em> /* Number of sectros to read */
);
</pre>
</div>
<div class="para">
<h4>Parameters</h4>
<dl class="par">
<dt>Drive</dt>
<dd>Specifies the physical drive number to read.</dd>
<dt>Buffer</dt>
<dd>Pointer to the read buffer to store the read data. <tt>SectorCount * 512</tt> bytes is required for the size of the read buffer.</dd>
<dt>SectorNumber</dt>
<dd>Specifies the start sector number in logical block address.</dd>
<dt>SectorCount</dt>
<dd>Specifies number of sectors to read. The value can be 1 to 255.</dd>
</dl>
</div>
<div class="para">
<h4>Return Value</h4>
<dl class="ret">
<dt>RES_OK (0)</dt>
<dd>The function succeeded.</dd>
<dt>RES_ERROR</dt>
<dd>Any error occured during the read operation.</dd>
<dt>RES_PARERR</dt>
<dd>Invalid parameter.</dd>
<dt>RES_NOTRDY</dt>
<dd>The disk dirve has not been initialized.</dd>
</dl>
</div>
<p class="foot"><a href="../00index_e.html">Return</a></p>
</body>
</html>
@@ -0,0 +1,47 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_e.html">
<link rel="stylesheet" href="../css_e.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - disk_status</title>
</head>
<body>
<div class="para">
<h2>disk_status</h2>
<p>The disk_status function gets the disk status.</p>
<pre>
DSTATUS disk_status (
BYTE <em>Drive</em> /* Physical drive number */
);
</pre>
</div>
<div class="para">
<h4>Parameters</h4>
<dl class="par">
<dt>Drive</dt>
<dd>Specifies the physical drive number to be tested.</dd>
</dl>
</div>
<div class="para">
<h4>Return Values</h4>
<p>The disk status is returned in combinatin of following flags.</p>
<dl class="ret">
<dt>STA_NOINIT</dt>
<dd>Indicates that the disk drive has not been initialiezed. This flag is set on: power-on, disk removal and disk_initialize function failed, and cleared on: disk_initialize function succeeded.</dd>
<dt>STA_NODISK</dt>
<dd>Indicates that no medium in the drive. It is always cleared on fixed disk drive.</dd>
<dt>STA_PROTECTED</dt>
<dd>Indicates that the medium is write protected. It is always cleared on the drive that does not support write protect notch.</dd>
</dl>
</div>
<p class="foot"><a href="../00index_e.html">Return</a></p>
</body>
</html>
@@ -0,0 +1,66 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_e.html">
<link rel="stylesheet" href="../css_e.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - disk_write</title>
</head>
<body>
<div class="para">
<h2>disk_write</h2>
<p>The disk_write writes sector(s) to the disk.</p>
<pre>
DRESULT disk_write (
BYTE <em>Drive</em>, /* Physical drive number */
const BYTE* <em>Buffer</em>, /* Pointer to the read buffer */
DWORD <em>SectorNumber</em>, /* Sector number to write */
BYTE <em>SectorCount</em> /* Number of sectors to write */
);
</pre>
</div>
<div class="para">
<h4>Parameters</h4>
<dl class="par">
<dt>Drive</dt>
<dd>Specifies the physical drive number to write.</dd>
<dt>Buffer</dt>
<dd>Pointer to the data to be written.</dd>
<dt>SectorNumber</dd>
<dd>Specifies the start sector number in logical block address.</dd>
<dt>SectorCount</dt>
<dd>Specifies number of sectors to write. The value can be 1 to 255.</dd>
</dl>
</div>
<div class="para">
<h4>Return Values</h4>
<dl class="ret">
<dt>RES_OK (0)</dt>
<dd>The function succeeded.</dd>
<dt>RES_ERROR</dt>
<dd>Any error occured during the write operation.</dd>
<dt>RES_WRPRT</dt>
<dd>The disk is write protected.</dd>
<dt>RES_PARERR</dt>
<dd>Invalid parameter.</dd>
<dt>RES_NOTRDY</dt>
<dd>The disk dirve has not been initialized.</dd>
</dl>
</div>
<div class="para">
<h4>Description</h4>
<p>This function is not required in read only configuration.</p>
</div>
<p class="foot"><a href="../00index_e.html">Return</a></p>
</body>
</html>
@@ -0,0 +1,50 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_e.html">
<link rel="stylesheet" href="../css_e.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - get_fattime</title>
</head>
<body>
<div class="para">
<h2>get_fattime</h2>
<p>The get_fattime function gets current time.</p>
<pre>
DWORD get_fattime (void);
</pre>
</div>
<div class="para">
<h4>Return Value</h4>
<p>Currnet time is returned with packed into a DWORD value. The bit field is as follows:</p>
<dl class="ret">
<dt>bit31:25</dt>
<dd>Year from 1980 (0..127)</dd>
<dt>bit24:21</dt>
<dd>Month (1..12)</dd>
<dt>bit20:16</dt>
<dd>Date (1..31)</dd>
<dt>bit15:11</dt>
<dd>Hour (0..23)</dd>
<dt>bit10:5</dt>
<dd>Minute (0..59)</dd>
<dt>bit4:0</dt>
<dd>Second/2 (0..29)</dd>
</dl>
</div>
<div class="para">
<h4>Description</h4>
<p>The get_fattime function must return any valid time even if the system does not support a real time clock. This fucntion is not required in read only configuration.</p>
</div>
<p class="foot"><a href="../00index_e.html">Return</a></p>
</body>
</html>
@@ -0,0 +1,58 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_e.html">
<link rel="stylesheet" href="../css_e.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - File and Path name on the FatFs module</title>
</head>
<body>
<div class="para">
<h2>File and Path name on the FatFs module</h2>
<p>The format of file and path name on the FatFs module is similer to MS-DOS. However it does not have a concept of current directory, all objects on the drive are specified in full path from the roor directory.</p>
<pre>
"[<em>logical drive#</em>:][/]<em>directory</em>/<em>file</em>"
"file1.txt" a file on drive 0
"/file1.txt" (same as above)
"dir1/dir2/file1.txt" a file on drive 0
"2:dir3/file2.txt" a file on drive 2
"2:/dir5" a directory on drive 2
"" the root directory on drive 0
"/" (same as above)
"2:" the root directory on drive 2
</pre>
<p>The FatFs module supports only 8.3 format file name and long file name is currentry not supported. For directory separator, a '/' is used, not a '\'. Heading '/' is ignored and can be omitted.</p>
<p>The logical drive number is specified in a numeral with a colon. When drive number is omitted, it means the default drive (0). As for the Tiny-FatFs, it has only one logical drive and always works as drive 0. Any drive number cannot be contained in the path name.</p>
</div>
<p><br></p>
<div class="para">
<h2>Correspondence between logical/physical drive</h2>
<p>In default, the FatFs module has work areas that called file system object for each logical drive. The logical drive is bound simply to the physical drive that has same drive number, and first partition is mounted. When <tt>_MULTI_PARTITION</tt> is specified in configuration option, each individual logical drive can be bound to any physical drive/partition. In this case, a drive number resolution table must be defined as follows:</p>
<pre>
Example: Logical drive 0-2 are assigned to three pri-partitions on the physical drive 0 (fixed disk)
Logical drive 3 is assigned to physical drive 0 (removable disk)
const PARTITION Drives[] = {
{0, 0}, /* Logical drive 0 ==> Physical drive 0, 1st partition */
{0, 1}, /* Logical drive 1 ==> Physical drive 0, 2nd partition */
{0, 2}, /* Logical drive 2 ==> Physical drive 0, 3rd partition */
{1, 0} /* Logical drive 3 ==> Physical drive 1 */
};
</pre>
<p>There are some consideration when use <tt>_MULTI_PARTITION</tt> configuration.</p>
<ul>
<li>Only pri-partition (0-3) can be mounted.</li>
<li>When the drive have no partition table (super floppy format), partition number is ignored.</li>
<li>The drive that has two or more logical drive must be fixed drive.</li>
</li>
</div>
</body>
</html>
@@ -0,0 +1,91 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_e.html">
<link rel="stylesheet" href="../css_e.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_getfree</title>
</head>
<body>
<div class="para">
<h2>f_getfree</h2>
<p>The f_getfree function gets number of the free clusters.</p>
<pre>
FRESULT f_getfree (
const char* <em>Path</em>, /* Root directory of the drive */
DWORD* <em>Clusters</em>, /* Pointer to the variable to store number of free clusters */
FATFS** <em>FileSystemObject</em> /* Pointer to pointer to file system object */
);
</pre>
</div>
<div class="para">
<h4>Parameters</h4>
<dl class="par">
<dt>Path</dt>
<dd>Pinter to the null-terminated string that specifies the <a href="filename.html">root directory</a> of the logical drive. Always specify a null-string for Tiny-FatFs.</dd>
<dt>Clusters</dt>
<dd>Pointer to the DWORD variable to store number of free clusters.</dd>
<dt>FileSystemObject</dt>
<dd>Pointer to the pointer that to be stored the pointer to corresponding file system object.</dd>
</dl>
</div>
<div class="para">
<h4>Return Values</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>The function succeeded. The <tt><em>*Clusters</em></tt> havs number of free clusters and <tt><em>*FileSystemObject</em></tt> points the file system object.</dd>
<dt>FR_INVALID_DRIVE</dt>
<dd>The drive number is invalid.</dd>
<dt>FR_NOT_READY</dt>
<dd>The disk drive cannot work due to no medium in the drive or any other reason.</dd>
<dt>FR_RW_ERROR</dt>
<dd>The function failed due to a disk error or an internal error.</dd>
<dt>FR_NOT_ENABLED</dt>
<dd>The logical drive has no work area.</dd>
<dt>FR_NO_FILESYSTEM</dt>
<dd>There is no valid FAT partition on the disk.</dd>
</dl>
</div>
<div class="para">
<h4>Descriptions</h4>
<p>The f_getfree function gets number of free clusters on the drive. The <tt>sects_clust</tt> member in the file system object refreting number of sectors per cluster, so that the free space in unit of sector can be calcurated with this. When _USE_FSINFO option is enabled, this function can return inaccurate free cluster count on FAT32 volume. When _USE_FSINFO option is disabled, this function will take a time on FAT32 volume.</p>
<p>This function is not supported in read-only configuration and minimization level of &gt;= 1.</p>
</div>
<div class="para">
<h4>Samples Code</h4>
<pre>
FATFS *fs;
DWORD clust;
// Get free clusters
res = f_getfree("", &clust, &fs);
if (res) die(res);
// Get free space
printf("%lu KB total disk space.\n"
"%lu KB available on the disk.\n",
(DWORD)(fs->max_clust - 2) * fs->sects_clust / 2,
clust * fs->sects_clust / 2);
</pre>
</div>
<div class="para">
<h4>References</h4>
<p><tt><a href="sfatfs.html">FATFS</a></tt></p>
</div>
<p class="foot"><a href="../00index_e.html">Return</a></p>
</body>
</html>
@@ -0,0 +1,86 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_e.html">
<link rel="stylesheet" href="../css_e.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_lseek</title>
</head>
<body>
<div class="para">
<h2>f_lseek</h2>
<p>The f_lseek functione moves the file read/write pointer of an open file object.</p>
<pre>
FRESULT f_lseek (
FIL* <em>FileObject</em>, /* Pointer to the file object structure *
DWORD <em>Offset</em> /* File offset in unit of byte *
);
</pre>
</div>
<div class="para">
<h4>Parameters</h4>
<dl class="par">
<dt>FileObject</dt>
<dd>Pointer to the open file object.</dd>
<dt>Offset</dt>
<dd>Number of bytes where from start of file</dd>
</dl>
</div>
<div class="para">
<h4>Return Values</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>The function succeeded.</dd>
<dt>FR_RW_ERROR</dt>
<dd>The function failed due to a disk error or an internal error.</dd>
<dt>FR_NOT_READY</dt>
<dd>The disk drive cannot work due to no medium in the drive or any other reason.</dd>
<dt>FR_INVALID_OBJECT</dt>
<dd>The file object is invalid.</dd>
</dl>
</div>
<div class="para">
<h4>Description</h4>
<p>The f_lseek function moves the file R/W pointer of an open file. The offset can be specified in only origin from top of the file. When an offset above the file size is specified in write mode, the file is extended to the offset and the data in the extended area is undefined. After the function succeeded, member fptr in the file object should be checked in order to make sure the R/W pointer has been moved correctry. In case of fptr is less than Offset, any of the followings has been occured.</p>
<ul>
<li>In read-only mode, the Offset was clipped in file size.</li>
<li>The drive gets full during the file extending process.</li>
<li>There is any error in the FAT structure.</li>
</ul>
<p>This function is not supported in minimization level of &gt;= 3.</p></div>
<div class="para">
<h4>Example</h4>
<pre>
// Move to offset of 5000 from top of the file.
res = f_lseek(&file, 5000);
// Forward 3000 bytes
res = f_lseek(&file, file.fptr + 3000);
// Rewind 2000 bytes (take care on overflow)
res = f_lseek(&file, file.fptr - 2000);
// Move to end of the file
res = f_lseek(&file, file.fsize);
</pre>
</div>
<div class="para">
<h4>References</h4>
<p><tt><a href="open.html">f_open</a>, <a href="sfile.html">FIL</a></tt></p>
</div>
<p class="foot"><a href="../00index_e.html">Return</a></p>
</body>
</html>
@@ -0,0 +1,83 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_e.html">
<link rel="stylesheet" href="../css_e.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_mkdir</title>
</head>
<body>
<div class="para">
<h2>f_mkdir</h2>
<p>The f_mkdir function creates a new directory.</p>
<pre>
FRESULT f_mkdir (
const char* <em>DirName</em> /* Pointer to the directory name */
);
</pre>
</div>
<div class="para">
<h4>Parameter</h4>
<dl class="par">
<dt>DirName</dt>
<dd>Pointer to the null-terminated string that specifies the <a href="filename.html">directory name</a> to create. </dd>
</dl>
</div>
<div class="para">
<h4>Return Value</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>The function succeeded.</dd>
<dt>FR_NO_PATH</dt>
<dd>Could not find the path.</dd>
<dt>FR_INVALID_NAME</dt>
<dd>The path name is invalid.</dd>
<dt>FR_INVALID_DRIVE</dt>
<dd>The drive number is invalid.</dd>
<dt>FR_DENIED</dt>
<dd>The directory cannot be created due to directory table or disk is full.</dd>
<dt>FR_EXIST</dt>
<dd>A file or directory that has same name is already existing.</dd>
<dt>FR_NOT_READY</dt>
<dd>The disk drive cannot work due to no medium in the drive or any other reason.</dd>
<dt>FR_WRITE_PROTECTED</dt>
<dd>The medium is write protected.</dd>
<dt>FR_RW_ERROR</dt>
<dd>The function failed due to a disk error or an internal error.</dd>
<dt>FR_NOT_ENABLED</dt>
<dd>The logical drive has no work area.</dd>
<dt>FR_NO_FILESYSTEM</dt>
<dd>There is no valid FAT partition on the disk.</dd>
</dl>
</div>
<div class="para">
<h4>Description</h4>
<p>The f_mkdir function creates a new directory. This function is not supported in read-only configuration and minimization level of &gt;= 1.</p>
<p>
</p>
</div>
<div class="para">
<h4>Example</h4>
<pre>
res = f_mkdir("sub1");
if (res) die(res);
res = f_mkdir("sub1/sub2");
if (res) die(res);
res = f_mkdir("sub1/sub2/sub3");
if (res) die(res);
</pre>
</div>
<p class="foot"><a href="../00index_e.html">Return</a></p>
</body>
</html>
@@ -0,0 +1,73 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_e.html">
<link rel="stylesheet" href="../css_e.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_mkfs</title>
</head>
<body>
<div class="para">
<h2>f_mkfs</h2>
<p>The f_mkfs fucntion creates a file system on the drive.</p>
<pre>
FRESULT f_mkfs (
BYTE <em>Drive</em>, /* Logical drive number */
BYTE <em>PartitioningRule</em>, /* Partitioning rule */
BYTE <em>AllocSize</em> /* Allocation unit size */
);
</pre>
</div>
<div class="para">
<h4>Parameters</h4>
<dl class="par">
<dt>Drive</dt>
<dd>Logical drive number (0-9) to be formatted.</dd>
<dt>PartitioningRule</dt>
<dd>When 0 is given, a partition table is created into first sector on the drive and then the file system is created on the partition. This is called FDISK format. When 1 is given, the file system starts from the first sector without partition table. This is often called super floppy (SFD) format.</dd>
<dt>AllocSize</dt>
<dd>Specifies allocation unit size (number of sectors per cluster). The value must be power of 2 in range of from 1 to 64.</dd>
</dl>
</div>
<div class="para">
<h4>Return Values</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>The function succeeded.</dd>
<dt>FR_INVALID_DRIVE</dt>
<dd>The drive number is invalid.</dd>
<dt>FR_NOT_READY</dt>
<dd>The drive cannot work due to any reason.</dd>
<dt>FR_WRITE_PROTECTED</dt>
<dd>The drive is write protected.</dd>
<dt>FR_NOT_ENABLED</dt>
<dd>The logical drive has no work area.</dd>
<dt>FR_RW_ERROR</dt>
<dd>The function failed due to a disk error or an internal error.</dd>
<dt>FR_MKFS_ABORTED</dt>
<dd>The function aborted before start in format due to a reason as follows.
<ul>
<li>The disk size is too small.</li>
<li>Invalid parameter was given to any parameter.</li>
<li>Not allowable cluster size for this drive. This can occure when number of clusters becomes around 0xFF7 and 0xFFF7.</li>
</ul>
</dd>
</dl>
</div>
<div class="para">
<h4>Description</h4>
<p>The f_mkfs function creates a FAT file system on the drive. There are two partitioning rules, FDISK and SFD, for removable media. It can be selected with a parameter and FDISK format is recommended for most case. This function currently does not support multiple partition, so that existing partitions on the physical dirve will be deleted and re-created a partition occupies entire disk space.</p>
<p>The FAT type, FAT12/FAT16/FAT32, is determined by only how many clusters on the drive and nothing else, according to FAT specification. Thus which FAT type is selected, is depends on the drive size and specified cluster size. The cluster size affects performance of file system and large cluster increases the performance, so that 64 sectors per cluster is recommended except for small drive.</p>
<p>This function is supported on only FatFs with _USE_MKFS option.<p>
</div>
<p class="foot"><a href="../00index_e.html">Return</a></p>
</body>
</html>
@@ -0,0 +1,59 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_e.html">
<link rel="stylesheet" href="../css_e.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_mount</title>
</head>
<body>
<div class="para">
<h2>f_mount</h2>
<p>The f_mount fucntion registers/unregisters a work area to the FatFs module.</p>
<pre>
FRESULT f_mount (
BYTE <em>Drive</em>, /* Logical drive number */
FATFS* <em>FileSystemObject</em> /* Pointer to the work area */
);
</pre>
</div>
<div class="para">
<h4>Parameters</h4>
<dl class="par">
<dt>Drive</dt>
<dd>Logical drive number (0-9) to register/unregister the work area. Always 0 for Tiny-FatFs.</dd>
<dt>FileSystemObject</dt>
<dd>Pointer to the work area (file system object) to be registered.</dd>
</dl>
</div>
<div class="para">
<h4>Return Values</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>The function succeeded.</dd>
<dt>FR_INVALID_DRIVE</dt>
<dd>The drive number is invalid.</dd>
</dl>
</div>
<div class="para">
<h4>Description</h4>
<p>The f_mount function registers/unregisters a work area to the FatFs module. The work area must be given to the logical drive with this function before using any file function. To unregister a work area, specify a NULL to the <em>FileSystemObject</em>, and then the work area can be discarded.</p>
<p>This function only initializes the work area and registers its address to the internal table, any access to the disk I/O layer does not occure. Actual mounting process is performed in any other file funcitons with path name when it is needed.<p>
</div>
<div class="para">
<h4>References</h4>
<p><tt><a href="sfatfs.html">FATFS</a></tt></p>
</div>
<p class="foot"><a href="../00index_e.html">Return</a></p>
</body>
</html>
@@ -0,0 +1,57 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_e.html">
<link rel="stylesheet" href="../css_e.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_mountdrv</title>
</head>
<body>
<div class="para">
<h2>f_mountdrv</h2>
<p>The f_mountdrv forces the partition mounted.</p>
<pre>
FRESULT f_mountdrv (void);
</pre>
</div>
<div class="para">
<h4>Return Values</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>The function succeeded.</dd>
<dt>FR_NOT_READY</dt>
<dd>The disk drive cannot work due to no medium in the drive or any other reason.</dd>
<dt>FR_RW_ERROR</dt>
<dd>Any error occured in low level disk I/O.</dd>
<dt>FR_NOT_ENABLED</dt>
<dd>FatFs module is not enabled.</dd>
<dt>FR_NO_FILESYSTEM</dt>
<dd>There is no valid FAT partition on the disk.</dd>
</dl>
</div>
<div class="para">
<h4>Description</h4>
<p>The f_mountdrv forces the partition mounted (initializes <tt>FATFS</tt> structure). The file system is initialized automatically in accordance with the necessity when any file function is called. This function should not be used except for recovering <tt>FR_INCORRECT_DISK_CHANGE</tt> error. Using this function, while any file is opened, can destroy the file system.</p>
<p>In this function, following processes are executed.</p><br>
<ul>
<li>Initializes lower level layer (disk I/O module).</li>
<li>Searches a FAT boot record in order of sector 0 (as SFD format) and first primary partition (as FDISK format).</li>
<li>Initializes file system object (<tt>FATFS</tt> structure).</li>
</ul>
</div>
<div class="para">
<h4>References</h4>
<p><tt><a href="sfatfs.html">FATFS</a></tt></p>
</div>
<p class="foot"><a href="../00index_e.html">Return</a></p>
</body>
</html>
@@ -0,0 +1,136 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_e.html">
<link rel="stylesheet" href="../css_e.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_open</title>
</head>
<body>
<div class="para">
<h2>f_open</h2>
<p>The f_open function creates a <em>file object</em> to be used to access the file.</p>
<pre>
FRESULT f_open (
FIL* <em>FileObject</em>, /* Pointer to the blank file object structure */
const char* <em>FileName</em>, /* Pointer to the file neme */
BYTE <em>ModeFlags</em> /* Mode flags */
);
</pre>
</div>
<div class="para">
<h4>Parameters</h4>
<dl class="par">
<dt>FileObject</dt>
<dd>Pointer to the file object structure to be created. After the f_open funciton succeeded, the file can be accessed with the file object structure until it is closed.</dd>
<dt>FileName</dt>
<dd>Pointer to a null-terminated string that specifies the <a href="filename.html">file name</a> to create or open.</dd>
<dt>ModeFlags</dt>
<dd>Specifies the type of access and open method for the file. It is specified by a combination of following flags.<br>
<table class="lst">
<tr><th>Value</th><th>Description</th></tr>
<tr><td>FA_READ</td><td>Specifies read access to the object. Data can be read from the file.<br>Combine with FA_WRITE for read-write access.</td></tr>
<tr><td>FA_WRITE</td><td>Specifies write access to the object. Data can be written to the file.<br>Combine with FA_READ for read-write access.</td></tr>
<tr><td>FA_OPEN_EXISTING</td><td>Opens the file. The function fails if the file is not existing.</td></tr>
<tr><td>FA_OPEN_ALWAYS</td><td>Opens the file, if it is existing. If not, the function creates the new file.</td></tr>
<tr><td>FA_CREATE_NEW</td><td>Creates a new file. The function fails if the file is already existing.</td></tr>
<tr><td>FA_CREATE_ALWAYS</td><td>Creates a new file. If the file is existing, it is truncated and overwritten.</td></tr>
</table>
</dd>
</dl>
</div>
<div class="para">
<h4>Return Values</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>The function succeeded and the file object is valid.</dd>
<dt>FR_NO_FILE</dt>
<dd>Could not find the file.</dd>
<dt>FR_NO_PATH</dt>
<dd>Could not find the path.</dd>
<dt>FR_INVALID_NAME</dt>
<dd>The file name is invalid.</dd>
<dt>FR_INVALID_DRIVE</dt>
<dd>The drive number is invalid.</dd>
<dt>FR_EXIST</dt>
<dd>The file is already existing.</dd>
<dt>FR_DENIED</dt>
<dd>The required access was denied due to any of following reasons: write mode open of a file that has read-only attribute, file creation under existing a same name directory or read-only file, cannot be created due to the directory table or disk full.</dd>
<dt>FR_NOT_READY</dt>
<dd>The disk drive cannot work due to no medium in the drive or any other reason.</dd>
<dt>FR_WRITE_PROTECTED</dt>
<dd>Write mode open or creation under the medium is write protected.</dd>
<dt>FR_RW_ERROR</dt>
<dd>The function failed due to a disk error or an internal error.</dd>
<dt>FR_NOT_ENABLED</dt>
<dd>The logical drive has no work area.</dd>
<dt>FR_NO_FILESYSTEM</dt>
<dd>There is no valid FAT partition on the disk.</dd>
</dl>
</div>
<div class="para">
<h4>Description</h4>
<p>The created file object is used for subsequent calls to refer to the file. When close an open file object, use <a href="close.html">f_close</a> function.</p>
<p>Before using any file function, work area (file system object) must be given to each logical drive with <a href="mount.html">f_mount</a> function. All file functions can work after this procedure.</p>
<p>The mode flags, <tt>FA_WRITE, FA_CREATE_ALWAYS, FA_CREATE_NEW, FA_OPEN_ALWAYS</tt>, are not supported in read-only configuration.</p>
</div>
<div class="para">
<h4>Example (File Copy)</h4>
<pre>
void main ()
{
FATFS fs; // Work area (file system object) for logical drive
FIL fsrc, fdst; // file objects
BYTE buffer[4096]; // file copy buffer
FRESULT res; // FatFs function common result code
WORD br, bw; // File R/W count
// Register a work area to logical drive 0
f_mount(0, &fs);
// Open source file
res = f_open(&fsrc, "srcfile.dat", FA_OPEN_EXISTING | FA_READ);
if (res) die(res);
// Create destination file
res = f_open(&fdst, "dstfile.dat", FA_CREATE_ALWAYS | FA_WRITE);
if (res) die(res);
// Copy source to destination
for (;;) {
res = f_read(&fsrc, buffer, sizeof(buffer), &br);
if (res || br == 0) break; // error or eof
res = f_write(&fdst, buffer, br, &bw);
if (res || bw &lt; br) break; // error or disk full
}
// Close all files
f_close(&fsrc);
f_close(&fdst);
// Unregister a work area before discard it
f_mount(0, NULL);
}
</pre>
</div>
<div class="para">
<h4>References</h4>
<p><tt><a href="read.html">f_read</a>, <a href="write.html">f_write</a>, <a href="close.html">f_close</a>, <a href="sfile.html">FIL</a>, <a href="sfatfs.html">FATFS</a></tt></p>
</div>
<p class="foot"><a href="../00index_e.html">Return</a></p>
</body>
</html>
@@ -0,0 +1,73 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_e.html">
<link rel="stylesheet" href="../css_e.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_opendir</title>
</head>
<body>
<div class="para">
<h2>f_opendir</h2>
<p>The f_opendir function opens a directory.</p>
<pre>
FRESULT f_opendir (
DIR* <em>DirObject</em>, /* Pointer to the blank directory object structure */
const char* <em>DirName</em> /* Pointer to the directory name */
);
</pre>
</div>
<div class="para">
<h4>Parameter</h4>
<dl class="par">
<dt>DirObject</dt>
<dd>Pointer to the blank directory object to be created.</dd>
<dt>DirName</dt>
<dd>Pinter to the null-terminated string that specifies the <a href="filename.html">directory name</a> to be opened.</dd>
</dl>
</div>
<div class="para">
<h4>Return Values</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>The function succeeded and the directory object is created. It is used for subsequent calls to read the directory entries.</dd>
<dt>FR_NO_FILE</dt>
<dd>Could not find the directory.</dd>
<dt>FR_NO_PATH</dt>
<dd>Could not find the path.</dd>
<dt>FR_INVALID_NAME</dt>
<dd>The path name is invalid.</dd>
<dt>FR_INVALID_DRIVE</dt>
<dd>The drive number is invalid.</dd>
<dt>FR_NOT_READY</dt>
<dd>The disk drive cannot work due to no medium in the drive or any other reason.</dd>
<dt>FR_RW_ERROR</dt>
<dd>The function failed due to a disk error or an internal error.</dd>
<dt>FR_NOT_ENABLED</dt>
<dd>The logical drive has no work area.</dd>
<dt>FR_NO_FILESYSTEM</dt>
<dd>There is no valid FAT partition on the disk.</dd>
</dl>
</div>
<div class="para">
<h4>Description</h4>
<p>The f_opendir function opens an exsisting directory and creates the directory object for subsequent calls. The directory object structure can be discarded at any time without any procedure. This function is not supported in minimization level of &gt;=2.</p>
</div>
<div class="para">
<h4>References</h4>
<p><tt><a href="readdir.html">f_readdir</a>, <a href="sdir.html">DIR</a></tt></p>
</div>
<p class="foot"><a href="../00index_e.html">Return</a></p>
</body>
</html>
@@ -0,0 +1,71 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_e.html">
<link rel="stylesheet" href="../css_e.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_read</title>
</head>
<body>
<div class="para">
<h2>f_read</h2>
<p>The f_read function reads data from a file.</p>
<pre>
FRESULT f_read (
FIL* <em>FileObject</em>, /* Pointer to the file object structure */
void* <em>Buffer</em>, /* Pointer to the buffer to store read data */
WORD <em>ByteToRead</em>, /* Number of bytes to read */
WORD* <em>ByteRead</em> /* Pointer to the variable to return number of bytes read */
);
</pre>
</div>
<div class="para">
<h4>Parameters</h4>
<dl class="par">
<dt>FileObject</dt>
<dd>Pointer to the open file object.</dd>
<dt>Buffer</dt>
<dd>Pointer to the buffer to store read data</dd>
<dt>ByteToRead</dt>
<dd>Number of bytes to read</dd>
<dt>ByteRead</dt>
<dd>Pointer to the WORD variable to return number of bytes read.</dd>
</dt>
</div>
<div class="para">
<h4>Return Values</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>The function succeeded.</dd>
<dt>FR_DENIED</dt>
<dd>The function denied due to the file has been opened in write only mode.</dd>
<dt>FR_RW_ERROR</dt>
<dd>The function failed due to a disk error or an internal error.</dd>
<dt>FR_NOT_READY</dt>
<dd>The disk drive cannot work due to no medium in the drive or any other reason.</dd>
<dt>FR_INVALID_OBJECT</dt>
<dd>The file object is invalid.</dd>
</dl>
</div>
<div class="para">
<h4>Description</h4>
<p>The file pointer in the file object increases in number of bytes read. The <tt>ByteRead</tt> will become less than <tt>ByteToRead</tt> when the read pointer reached to end of the file or any error occured during the read operation.</p>
</div>
<div class="para">
<h4>References</h4>
<p><tt><a href="open.html">f_open</a>, <a href="write.html">f_write</a>, <a href="close.html">f_close</a>, <a href="sfile.html">FIL</a></tt></p>
</div>
<p class="foot"><a href="../00index_e.html">Return</a></p>
</body>
</html>
@@ -0,0 +1,89 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_e.html">
<link rel="stylesheet" href="../css_e.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_readdir</title>
</head>
<body>
<div class="para">
<h2>f_readdir</h2>
<p>The f_readdir function reads directory entries.</p>
<pre>
FRESULT f_readdir (
DIR* <em>DirObject</em>, /* Pointer to the directory object structure */
FILINFO* <em>FileInfo</em> /* Pointer to the file information structure */
);
</pre>
</div>
<div class="para">
<h4>Parameters</h4>
<dl class="par">
<dt>DirObject</dt>
<dd>Pointer to the open directory strcture.</dd>
<dt>FileInfo</dt>
<dd>Pointer to the file information structure to store the read item.</dd>
</dl>
</div>
<div class="para">
<h4>Return Values</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>The function succeeded.</dd>
<dt>FR_NOT_READY</dt>
<dd>The disk drive cannot work due to no medium in the drive or any other reason.</dd>
<dt>FR_RW_ERROR</dt>
<dd>The function failed due to a disk error or an internal error.</dd>
<dt>FR_INVALID_OBJECT</dt>
<dd>The directory object is invalid.</dd>
</dl>
</div>
<div class="para">
<h4>Description</h4>
<p>The f_readdir function reads directory entries in sequence. All items in the directory can be read by calling f_readdir function repeatedly. When all directory items have been read and no item to read, the function returns a null string into <tt>f_name[]</tt> member without any error. For details of the file informations, refer to the <tt>FILINFO</tt>. This function is not supported in minimization level of &gt;=2.</p>
</div>
<div class="para">
<h4>Sample Code</h4>
<pre>
void scan_files (char* path)
{
FILINFO finfo;
DIR dirs;
int i;
if (f_opendir(&dirs, path) == FR_OK) {
i = strlen(path);
while ((f_readdir(&dirs, &finfo) == FR_OK) && finfo.fname[0]) {
if (finfo.fattrib & AM_DIR) {
sprintf(path+i, "/%s", &finfo.fname[0]);
scan_files(path);
*(path+i) = '\0';
} else {
printf("%s/%s\n", path, &finfo.fname[0]);
}
}
}
}
</pre>
</div>
<div class="para">
<h4>References</h4>
<p><tt><a href="opendir.html">f_opendir</a>, <a href="stat.html">f_stat</a>, <a href="sfileinfo.html">FILINFO</a>, <a href="sdir.html">DIR</a></tt></p>
</div>
<p class="foot"><a href="../00index_e.html">Return</a></p>
</body>
</html>
@@ -0,0 +1,84 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_e.html">
<link rel="stylesheet" href="../css_e.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_rename</title>
</head>
<body>
<div class="para">
<h2>f_rename</h2>
<p>Rename file or directory.</p>
<pre>
FRESULT f_rename (
const char* <em>OldName</em>, /* Pointer to old file/directory name */
const char* <em>NewName</em> /* Pointer to new file/directory name */
);
</pre>
</div>
<div class="para">
<h4>Parameter</h4>
<dl class="par">
<dt>OldName</dt>
<dd>Pointer to a null-terminated string specifies the old <a href="filename.html">file/directory name</a> to be renamed.</dd>
<dt>NewName</dt>
<dd>Pointer to a null-terminated string specifies the new file/directory name without drive number. Existing object nannot be specified.</dd>
</dl>
</div>
<div class="para">
<h4>Return Values</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>The function succeeded.</dd>
<dt>FR_NO_FILE</dt>
<dd>Could not find the file nor directory.</dd>
<dt>FR_NO_PATH</dt>
<dd>Could not find the path.</dd>
<dt>FR_INVALID_NAME</dt>
<dd>The file name is invalid.</dd>
<dt>FR_INVALID_DRIVE</dt>
<dd>The drive number is invalid.</dd>
<dt>FR_NOT_READY</dt>
<dd>The disk drive cannot work due to no medium in the drive or any other reason.</dd>
<dt>FR_DENIED</dt>
<dd>The new name could not be created due to any reason.</dd>
<dt>FR_WRITE_PROTECTED</dt>
<dd>The medium is write protected.</dd>
<dt>FR_RW_ERROR</dt>
<dd>The function failed due to a disk error or an internal error.</dd>
<dt>FR_NOT_ENABLED</dt>
<dd>The logical drive has no work area.</dd>
<dt>FR_NO_FILESYSTEM</dt>
<dd>There is no valid FAT partition on the disk.</dd>
</dl>
</div>
<div class="para">
<h4>Description</h4>
<p>Rename a file or directory and can move it to other directory. Logical drive number is determined by old name, new name must not contain logical drive number. This function is not supported in read-only configuration or minimization level of &gt;= 1.</p>
<p>Note: In this revision, moving any directory to other directory collapses the FAT structure on the disk.</p>
</div>
<div class="para">
<h4>Example</h4>
<pre>
// Rename file or directory
f_rename("oldname.txt", "newname.txt");
// Rename and move file to other directory simultaneously
f_rename("oldname.txt", "dir1/newname.txt");
</pre>
</div>
<p class="foot"><a href="../00index_e.html">Return</a></p>
</body>
</html>
@@ -0,0 +1,42 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_e.html">
<link rel="stylesheet" href="../css_e.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - DIR</title>
</head>
<body>
<div class="para">
<h2>DIR</h2>
<p>The <tt>DIR</tt> structure is used for the work area to read a directory by f_oepndir and f_readdir functions.</p>
<h4>FatFs</h4>
<pre>
typedef struct _DIR {
WORD id; /* Owner file system mount ID (inverted) */
WORD index; /* Current index */
FATFS* fs; /* Pointer to the owner file system object */
DWORD sclust; /* Start cluster */
DWORD clust; /* Current cluster */
DWORD sect; /* Current sector */
} DIR;
</pre>
<h4>Tiny-FatFs</h4>
<pre>
typedef struct _DIR {
WORD id; /* Owner file system mount ID (inverted) */
WORD index; /* Current index */
FATFS* fs; /* Pointer to the owner file system object */
CLUST sclust; /* Start cluster */
CLUST clust; /* Current cluster */
DWORD sect; /* Current sector */
} DIR;
</pre>
</div>
<p class="foot"><a href="../00index_e.html">Return</a></p>
</body>
</html>
@@ -0,0 +1,63 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_e.html">
<link rel="stylesheet" href="../css_e.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - FATFS</title>
</head>
<body>
<div class="para">
<h2>FATFS</h2>
<p>The <tt>FATFS</tt> structure holds dynamic work area of individual logical drives. It is given by application program and registerd/unregisterd to the FatFs module with f_mount function. Following members are in standard configuration. There is no member that can be changed from the application program.</p>
<h4>FatFs</h4>
<pre>
typedef struct _FATFS {
WORD id; /* File system mount ID */
WORD n_rootdir; /* Number of root directory entries */
DWORD winsect; /* Current sector appearing in the win[] */
DWORD sects_fat; /* Sectors per fat */
DWORD max_clust; /* Maximum cluster# + 1 */
DWORD fatbase; /* FAT start sector */
DWORD dirbase; /* Root directory start sector (cluster# for FAT32) */
DWORD database; /* Data start sector */
DWORD last_clust; /* Last allocated cluster */
DWORD free_clust; /* Number of free clusters */
BYTE fs_type; /* FAT type (0:Not mounted) */
BYTE sects_clust; /* Sectors per cluster */
BYTE n_fats; /* Number of FAT copies */
BYTE drive; /* Physical drive number */
BYTE winflag; /* win[] dirty flag (1:must be written back) */
BYTE pad1;
BYTE win[512]; /* Disk access window for Directory/FAT */
} FATFS;
</pre>
<h4>Tiny-FatFs</h4>
<pre>
typedef struct _FATFS {
WORD id; /* File system mount ID */
WORD n_rootdir; /* Number of root directory entries */
DWORD winsect; /* Current sector appearing in the win[] */
DWORD fatbase; /* FAT start sector */
DWORD dirbase; /* Root directory start sector */
DWORD database; /* Data start sector */
CLUST sects_fat; /* Sectors per fat */
CLUST max_clust; /* Maximum cluster# + 1 */
CLUST last_clust; /* Last allocated cluster */
CLUST free_clust; /* Number of free clusters */
BYTE fs_type; /* FAT type (0:Not mounted) */
BYTE sects_clust; /* Sectors per cluster */
BYTE n_fats; /* Number of FAT copies */
BYTE winflag; /* win[] dirty flag (1:must be written back) */
BYTE win[512]; /* Disk access window for Directory/FAT/File */
} FATFS;
</pre>
</div>
<p class="foot"><a href="../00index_e.html">Return</a></p>
</body>
</html>
@@ -0,0 +1,55 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_e.html">
<link rel="stylesheet" href="../css_e.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - FIL</title>
</head>
<body>
<div class="para">
<h2>FIL</h2>
<p>The FIL structure (file object) holds state of a file. It is created by f_open function and discarded by f_close function. There is no member that can be changed by the application program.</p>
<h4>FatFs</h4>
<pre>
typedef struct _FIL {
WORD id; /* Owner file system mount ID (inverted) */
BYTE flag; /* File status flags */
BYTE sect_clust; /* Left sectors in cluster */
FATFS* fs; /* Pointer to the owner file system object */
DWORD fptr; /* File R/W pointer */
DWORD fsize; /* File size */
DWORD org_clust; /* File start cluster */
DWORD curr_clust; /* Current cluster */
DWORD curr_sect; /* Current sector */
DWORD dir_sect; /* Sector containing the directory entry */
BYTE* dir_ptr; /* Ponter to the directory entry in the window */
BYTE buffer[512]; /* File R/W buffer */
} FIL;
</pre>
<h4>Tiny-FatFs</h4>
<pre>
typedef struct _FIL {
WORD id; /* Owner file system mount ID (inverted) */
BYTE flag; /* File status flags */
BYTE sect_clust; /* Left sectors in cluster */
FATFS* fs; /* Pointer to owner file system */
DWORD fptr; /* File R/W pointer */
DWORD fsize; /* File size */
CLUST org_clust; /* File start cluster */
CLUST curr_clust; /* Current cluster */
DWORD curr_sect; /* Current sector */
DWORD dir_sect; /* Sector containing the directory entry */
BYTE* dir_ptr; /* Ponter to the directory entry in the window */
} FIL;
</pre>
</div>
<p class="foot"><a href="../00index_e.html">Return</a></p>
</body>
</html>
@@ -0,0 +1,43 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_e.html">
<link rel="stylesheet" href="../css_e.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - FILINFO</title>
</head>
<body>
<div class="para">
<h2>FILINFO</h2>
<p>The <tt>FILINFO</tt> structure holds a file information returned by <tt>f_stat()</tt> and <tt>f_readdir()</tt>.</p>
<pre>
typedef struct _FILINFO {
DWORD fsize; // Size
WORD fdate; // Date
WORD ftime; // Time
BYTE fattrib; // Attribute
char fname[8+1+3+1]; // Name
} FILINFO;
</pre>
</div>
<h4>Members</h4>
<dl>
<dt>fsize</dt>
<dd>Indicates size of the file in unit of byte. This is always zero when it is a directory.</dd>
<dt>fdate</dt>
<dd>Indicates the date that the file was modified or the directory was created.</dd>
<dt>ftime</dt>
<dd>Indicates the time that the file was modified or the directory was created.</dd>
<dt>fattrib</dt>
<dd>Indicates the file/directory attribute in combination of <tt>AM_DIR</tt>, <tt>AM_RDO</tt>, <tt>AM_HID</tt>, AM_SYS</tt> and <tt>AM_ARC</tt>.</dd>
<dt>fname[]</dt>
<dd>Indicates the file/directory name in 8.3 format null-terminated string.</dd>
</dl>
<p class="foot"><a href="../00index_e.html">Return</a></p>
</body>
</html>
@@ -0,0 +1,73 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_e.html">
<link rel="stylesheet" href="../css_e.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_stat</title>
</head>
<body>
<div class="para">
<h2>f_stat</h2>
<p>The f_stat gets the file status.</p>
<pre>
FRESULT f_stat (
const char* <em>FileName</em>, /* Pointer to the file or directory name */
FILINFO* <em>FileInfo</em> /* Pointer to the FILINFO structure */
);
</pre>
</div>
<div class="para">
<h4>Parameters</h4>
<dl class="par">
<dt>FileName</dt>
<dd>Pointer to the null-terminated string that specifies the <a href="filename.html">file or directory</a> to get its information.</dd>
<dt>FileInfo</dt>
<dd>Pointer to the blank <tt>FILINFO</tt> structure to store the information.</dd>
</dl>
</div>
<div class="para">
<h4>Return Values</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>The function succeeded.</dd>
<dt>FR_NO_FILE</dt>
<dd>Could not find the file or directory.</dd>
<dt>FR_NO_PATH</dt>
<dd>Could not find the path.</dd>
<dt>FR_INVALID_NAME</dt>
<dd>The file name is invalid.</dd>
<dt>FR_INVALID_DRIVE</dt>
<dd>The drive number is invalid.</dd>
<dt>FR_NOT_READY</dt>
<dd>The disk drive cannot work due to no medium in the drive or any other reason.</dd>
<dt>FR_RW_ERROR</dt>
<dd>The function failed due to a disk error or an internal error.</dd>
<dt>FR_NOT_ENABLED</dt>
<dd>The logical drive has no work area.</dd>
<dt>FR_NO_FILESYSTEM</dt>
<dd>There is no valid FAT partition on the disk.</dd>
</dl>
</div>
<div class="para">
<h4>Description</h4>
<p>The f_stat gets the information of a file or directory. For details of the infomation, refer to the <tt>FILINFO</tt> structure. This function is not supported in minimization level of &gt;= 1.</p>
</div>
<div class="para">
<h4>References</h4>
<p><tt><a href="opendir.html">f_opendir</a>, <a href="readdir.html">f_readdir</a>, <a href="sfileinfo.html">FILINFO</a></tt></p>
</div>
<p class="foot"><a href="../00index_e.html">Return</a></p>
</body>
</html>
@@ -0,0 +1,60 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_e.html">
<link rel="stylesheet" href="../css_e.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_sync</title>
</head>
<body>
<div class="para">
<h2>f_sync</h2>
<p>The f_sync function flushes the cached information of a wriiting file.</p>
<pre>
FRESULT f_sync (
FIL* <em>FileObject</em> /* Pointer to the file object */
);
</pre>
</div>
<div class="para">
<h4>Parameters</h4>
<dl class="par">
<dt>FileObject</dt>
<dd>Pointer to the open file object to be flushed.</dd>
</dl>
</div>
<div class="para">
<h4>Return Values</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>The function succeeded.</dd>
<dt>FR_RW_ERROR</dt>
<dd>The function failed due to a disk error or an internal error.</dd>
<dt>FR_NOT_READY</dt>
<dd>The disk drive cannot work due to no medium in the drive or any other reason.</dd>
<dt>FR_INVALID_OBJECT</dt>
<dd>The file object is invalid.</dd>
</dl>
</div>
<div class="para">
<h4>Description</h4>
<p>The f_sync function performs the same process as f_close function but the file is left opened and can continue read/write/seek operations to the file. This is suitable for applications that open files for a long time in writing mode, such as data logger. Performing f_sync of periodic or immediataly after f_write can minimize risk of data loss due to sudden blackout or unintentional disk removal. This function is not supported in read-only configuration.</p>
</div>
<div class="para">
<h4>References</h4>
<p><tt><a href="close.html">f_close</a></tt></p>
</div>
<p class="foot"><a href="../00index_e.html">Return</a></p>
</body>
</html>
@@ -0,0 +1,69 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_e.html">
<link rel="stylesheet" href="../css_e.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_unlink</title>
</head>
<body>
<div class="para">
<h2>f_unlink</h2>
<p>The f_unlink removes file or directory.</p>
<pre>
FRESULT f_unlink (
const char* <em>FileName</em> /* Pointer to the file or directory name */
);
</pre>
</div>
<div class="para">
<h4>Parameters</h4>
<dl class="par">
<dt>FileName</dt>
<dd>Pointer to the null-terminated string that specifies a <a href="filename.html">file or directory</a> to be removed.</dd>
</dl>
</div>
<div class="para">
<h4>Return Values</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>The function succeeded.</dd>
<dt>FR_NO_FILE</dt>
<dd>Could not find the file or directory.</dd>
<dt>FR_NO_PATH</dt>
<dd>Could not find the path.</dd>
<dt>FR_INVALID_NAME</dt>
<dd>The path name is invalid.</dd>
<dt>FR_INVALID_DRIVE</dt>
<dd>The drive number is invalid.</dd>
<dt>FR_DENIED</dt>
<dd>The function was denied due to either of following reasons: the file or directory has read-only attribute, the directory is not empty.</dd>
<dt>FR_NOT_READY</dt>
<dd>The disk drive cannot work due to no medium in the drive or any other reason.</dd>
<dt>FR_WRITE_PROTECTED</dt>
<dd>The medium is write protected.</dd>
<dt>FR_RW_ERROR</dt>
<dd>The function failed due to a disk error or an internal error.</dd>
<dt>FR_NOT_ENABLED</dt>
<dd>The logical drive has no work area.</dd>
<dt>FR_NO_FILESYSTEM</dt>
<dd>There is no valid FAT partition on the disk.</dd>
</dl>
</div>
<div class="para">
<h4>Description</h4>
<p>The f_unlink function removes a file or directory. In read-only configuration or minimization level is &gt;= 1, this function is not supported.</p>
</div>
<p class="foot"><a href="../00index_e.html">Return</a></p>
</body>
</html>
@@ -0,0 +1,71 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_e.html">
<link rel="stylesheet" href="../css_e.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_write</title>
</head>
<body>
<div class="para">
<h2>f_write</h2>
<p>The f_write writes data to a file.</p>
<pre>
FRESULT f_write (
FIL* <em>FileObject</em>, /* Pointer to the file object structure */
const void* <em>Buffer</em>, /* Pointer to the data to be written */
WORD <em>ByteToWrite</em>, /* Number of bytes to write */
WORD* <em>ByteWritten</em> /* Pointer to the variable to return number of bytes written */
);
</pre>
</div>
<div class="para">
<h4>Parameter</h4>
<dl class="par">
<dt>FileObject</dt>
<dd>Pointer to the open file object structure.</dd>
<dt>Buffer</dt>
<dd>Pointer to the data to be written.</dd>
<dt>ByteToWrite</dt>
<dd>Specifies number of bytes to write.</dd>
<dt>ByteWritten</dt>
<dd>Pointer to the WORD variable to return number of bytes written.</dd>
</dl>
</div>
<div class="para">
<h4>Return Values</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>The function succeeded.</dd>
<dt>FR_DENIED</dt>
<dd>The function denied due to the file has been opened in read only mode.</dd>
<dt>FR_RW_ERROR</dt>
<dd>The function failed due to a disk error or an internal error.</dd>
<dt>FR_NOT_READY</dt>
<dd>The disk drive cannot work due to no medium in the drive or any other reason.</dd>
<dt>FR_INVALID_OBJECT</dt>
<dd>The file object is invalid.</dd>
</dl>
</div>
<div class="para">
<h4>Description</h4>
<p>The read/write pointer in the file object is increased in number of bytes written. The <tt>ByteWritten</tt> will become less than <tt>ByteToWrite</tt> when disk gets full during write function. This function is not supported in read-only configuration.</p>
</div>
<div class="para">
<h4>References</h4>
<p><tt><a href="open.html">f_open</a>, <a href="read.html">f_read</a>, <a href="close.html">f_close</a>, <a href="sfile.html">FIL</a></tt></p>
</div>
<p class="foot"><a href="../00index_e.html">Return</a></p>
</body>
</html>
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.
@@ -0,0 +1,125 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_j.html">
<link rel="stylesheet" href="../css_j.css" type="text/css" media="screen" title="ELM Default">
<title>FatFsモジュール アプリケーション・ノート</title>
</head>
<body>
<h1>FatFsモジュール アプリケーション・ノート</h1>
<hr>
<div class="para">
<h3>移植の際に配慮すべきこと</h3>
<p>FatFsモジュールは移植性に関して次の点を前提としています。</p>
<ul>
<li>処理系はANSI C準拠であること。<br>
FatFsモジュールはANSI C準拠で記述されているので、ANSI C準拠のコンパイラなら特に処理系依存な点はありません。ただし、FATというシステム間でポータブルな構造体を操作するため、プロセッサのエンディアンの違いは意識する必要があります。これは ff.h(tff.h) で定義されているので、最初にこれを適切に設定します(忘れている場合はエラーを出す)。</li>
<li>char/short/long のサイズは、それぞれ 8/16/32ビット で、intは 16ビット以上 であること。<br>
これは integer.h 内で typedef されています。整数の型とサイズに関しては、まっとうな処理系なら問題ないはずですが、既存の定義と衝突した場合は矛盾がないように注意しなければなりません。</li>
</ul>
</div>
<div class="para">
<h3>メモリ使用量 (R0.04b)</h3>
<p>各種環境でのモジュールのメモリ使用量の例を示します。数値の単位はバイトで、Dは論理ドライブ数、Fは同時オープン・ファイル数を示します。最適化オプションは、全てコード・サイズとしています。</p>
<table class="lst2">
<tr><th></th><th>AVR</th><th>H8/300H</th><th>MSP430</th><th>TLCS-870/C</th><th>V850ES</th><th>SH2</th></tr>
<tr><td>コンパイラ</td><td>gcc</td><td>CH38</td><td>CL430</td><td>CC870C</td><td>CA850</td><td>SHC</td></tr>
<tr><td>_MCU_ENDIAN</td><td>1</td><td>2</td><td>2</td><td>1</td><td>1</td><td>2</td></tr>
<tr><td>FatFs コード<br>(標準, R/W構成)</td><td>8722</td><td>8776</td><td></td><td></td><td>6402</td><td>7338</td></tr>
<tr><td>FatFs コード<br>(最小, R/W構成)</td><td>5814</td><td>5722</td><td></td><td></td><td>4094</td><td>4906</td></tr>
<tr><td>FatFs コード<br>(標準, R/O構成)</td><td>4248</td><td>4096</td><td></td><td></td><td>3010</td><td>3506</td></tr>
<tr><td>FatFs コード<br>(最小, R/O構成)</td><td>3038</td><td>3110</td><td></td><td></td><td>2210</td><td>2698</td></tr>
<tr><td>FatFs 静的ワーク</td><td>D*2 + 2</td><td>D*4 + 2</td><td></td><td></td><td>D*4 + 2</td><td>D*4 + 2</td></tr>
<tr><td>FatFs 動的ワーク</td><td>D*554 + F*544</td><td>D*554 + F*550</td><td></td><td></td><td>D*554 + F*550</td><td>D*554 + F*550</td></tr>
<tr><td>Tiny-FatFs コード<br>(標準, R/W構成)</td><td>7264</td><td>7240</td><td>6634</td><td>8837</td><td></td><td></td></tr>
<tr><td>Tiny-FatFs コード<br>(最小, R/W構成)</td><td>4750</td><td>4806</td><td>4366</td><td>6163</td><td></td><td></td></tr>
<tr><td>Tiny-FatFs コード<br>(標準, R/O構成)</td><td>3600</td><td>3548</td><td>3212</td><td>4347</td><td></td><td></td></tr>
<tr><td>Tiny-FatFs コード<br>(最小, R/O構成)</td><td>2568</td><td>2702</td><td>2394</td><td>3322</td><td></td><td></td></tr>
<tr><td>Tiny-FatFs 静的ワーク</td><td>4</td><td>6</td><td>4</td><td>4</td><td></td><td></td></tr>
<tr><td>Tiny-FatFs 動的ワーク</td><td>544 + F*28</td><td>544 + F*32</td><td>544 + F*28</td><td>544 + F*28</td><td></td><td></td></tr>
</table>
</div>
<div class="para">
<h3>FatFs vs. Tiny-FatFs</h3>
<p>ポータブル・オーディオやデータ・ロガーなど、よくある用途ではTiny-FatFsで十分です。しかし、Tiny-FatFsは標準構成ではFAT32に対応していないので、使用できるディスクは2GB(FAT64で4GB)までという制約があります。<tt>_FAT32</tt>オプションでFAT32対応を追加できますが、その分コード・サイズが膨らみます。フル機能のFatFsは、複数ファイルを高速アクセスする場合や、複数ドライブの対応が必要な場合に有効です。</p>
<div class="rset">
<table class="lst2">
<tr><th>メモリ容量</th><th>FATタイプ</th></tr>
<tr><td>&lt;= 64MB</td><td>FAT12</td></tr>
<tr><td>128MB2GB</td><td>FAT16</td></tr>
<tr><td>&gt;= 4GB</td><td>FAT32</td></tr>
</table>
</div>
<p>2GBまでのカードに限るなら、FAT32への対応は不要です。右の表にメモリ・カードの容量と規定のFATタイプ(SDメモリの場合)を示します。メモリ・カードの出荷時は、最大のパフォーマンスが出るようにデータ領域の境界が調整されたフォーマットになっています。したがって、PCでフォーマットするなどして規定と違うフォーマットになると、書き込み性能が大幅に低下する場合があるので注意が必要です。</p>
</div>
<div class="para">
<h3>効率の良いファイル・アクセスの方法</h3>
<p>資源の限られた組み込みシステムで効率よくアクセスするためには、ファイル・アクセスの仕組みをある程度意識した使用が求められます。FatFsモジュールでは、ディスク上のファイル・データは f_read()内で次のような手順で読み出されます。</p>
<div class="lset">図1. セクタ・ミスアライメント・リード<br>
<img src="../img/f1.png" width="490" height="73" alt="fig.1">
</div>
<br class="clr">
<div class="lset">図2. セクタ・ミスアライメント・リード<br>
<img src="../img/f2.png" width="490" height="140" alt="fig.2">
</div>
<br class="clr">
<div class="lset">図3. セクタ・アライメント・リード<br>
<img src="../img/f3.png" width="490" height="119" alt="fig.3">
</div>
<br class="clr">
<p>ここでファイルI/Oバッファとは、データ・セクタの一部を読み書きするための1セクタ長のバッファで、FatFsではそのファイル・オブジェクト内の、Tiny-FatFsではワークエリア内のバッファのことを指しています。</p>
<p>Tiny-FatFsでは、全てのデータ転送とFATやディレクトリへのアクセスをただ一つのセクタ・バッファで行っているため、データ転送によりFATのキャッシュが失われ、クラスタ境界を通過するたびにFATセクタを読み直す必要があります。FatFsの場合は、データ用バッファはFAT用とは別なので、FATセクタを読む頻度はTiny-FatFsの 1/341, 1/256 または 1/128で済みます(クラスタが連続している場合)。つまり、Tiny-FatFsは性能低下の代償を払ってRAM使用量を削減しているわけです。</p>
<p>転送領域のうちセクタ全体を含む部分は(図2)のようにファイルI/Oバッファを介さず、ディスクとの間で直接転送されます。完全なセクタ・アライメント・アクセスの場合(図3)は、ファイルI/Oバッファは全く使用されません。直接転送では、可能ならdisk_read()に複数セクタを指定して最大限のマルチ・セクタ転送が行われます。ただし、クラスタ境界をまたぐときはクラスタが隣接していたとしても転送は分割されます。</p>
<p>このように、極力セクタ・アライメント・アクセスになるように配慮すれば、無駄なメモリ・コピーが減って性能が向上します。さらに、Tiny-FatFsではFATのキャッシュが生きるようになり、省メモリ特性とFatFsの性能とが同時に得られます。</p>
</div>
<div class="para">
<h3>クリチカル・セクション</h3>
<p>ディスク上のFAT構造を操作している途中で、停電、不正なメディアの取り外し、回復不能なデータ・エラー等の障害が発生すると、処理が中途半端な状態で中断され、その結果としてFAT構造が破壊される可能性があります。次にFatFsモジュールにおけるクリチカル・セクションと、その間の障害により起きうるエラーの状態を示します。</p>
<div class="lset">
図4. 長いクリチカル・セクション<br>
<img src="../img/f4.png" width="320" height="436" alt="fig.4">
</div>
<div class="lset">
図5. 短くしたクリチカル・セクション<br>
<img src="../img/f5.png" width="320" height="436" alt="fig.5">
</div>
<br class="clr">
<p>赤で示したセクションを実行中に障害が発生した場合、クロス・リンクが発生して操作対象のファイル・ディレクトリが失われる可能性があります。黄色で示したセクションを実行中に障害が発生した場合、つぎのうちいずれかまたは複数の結果が生じる可能性があります。</p>
<ul>
<li>書き換え中のファイルの内容が破壊される。</li>
<li>追記中のファイルがオープン前の状態に戻る。</li>
<li>新規に作成されたファイルが消える。</li>
<li>新規または上書きで作成されたファイルの長さがゼロになって残る。</li>
<li>ロストチェーンの発生によりディスクの利用効率が悪化する。</li>
</ul>
<p>いずれも書き込み中や操作対象でないファイルには影響はありません。これらのクリチカル・セクションは、ファイルを書き込みモードで開いている時間を最小限にするか、f_sync()を適宜使用することで図5のようにリスクを最小化することができます。</p>
</div>
<div class="para">
<h3>現リビジョンの問題点とその改善案</h3>
<ul>
<li>ファイル・オブジェクトの抽象化<br>
現在はファイル・オブジェクトの実体をアプリケーション側で管理しているので、アプリケーション・モジュールでのスタック消費量が多くなります(Tiny-FatFsでは問題にならない)。これをハンドルで管理するなどより抽象化すればアプリケーション・モジュールでのスタック消費量を減らせるし、他のファイル・システムへの対応も容易になります。この場合、FatFs内でファイル・オブジェクトの領域を静的に確保しておくか、malloc()することになります。ただし、このようにするとファイル・オブジェクトを直接参照できなくなり、feofやftellなどムダな関数が新たに必要になります。</li>
<li>セクタ・バッファ管理の改善<br>
現在はセクタ・バッファを固定して使用しているため、無駄なディスクアクセスが多く効率が悪い。メモリの潤沢なシステムでは、複数のセクタ・バッファを使用してディスク・キャッシュを構成すれば性能を向上させることができます。</li>
<li>長いファイル名への対応<br>
FATの拡張仕様ではMS-DOSの8.3形式ファイル名に加え、255文字までの長いファイル名(LFN)を扱えるようになっていますが、現リビジョンでは未対応で8.3形式しか使用できません。これに対応するには、ファイル名だけでも500バイト以上のバッファが必要になったり、UCS-2とShift_JISの相互変換(巨大な変換テーブルを使う)が必要となるなど、メモリの消費が爆発的に増えてしまいます。なお、LFNの機能はMicrosoft社の特許になっているため、これを製品に使うにはライセンス契約が必要です。</li>
<li>RTOSへの対応<br>
FatFsモジュールを使用するタスクを一つに限るなら特に意識する必要はありませんが、同じ論理ドライブに複数のタスクから同時アクセスするには、何らかの排他制御が必要になってきます。FatFsモジュールのRTOSへの対応作業は、<a href="http://www.toppers.jp/">TOPPERSプロジェクト</a>で行われています。</li>
</ul>
<br>
<p>そして、これらの機能拡張を行うとそれだけ多くのリソースが要求されるようになり、このプロジェクトの対象とする8/16ビット・マイコンのシステムに載せられなくなってしまうという問題もあります(これが一番の問題かも知れません)。</p>
</div>
<p class="foot"><a href="../00index_j.html">戻る</a></p>
</body>
</html>
@@ -0,0 +1,89 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_j.html">
<link rel="stylesheet" href="../css_j.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_chmod</title>
</head>
<body>
<div class="para">
<h2>f_chmod</h2>
<p>ファイルまたはディレクトリの属性を変更します。</p>
<pre>
FRESULT f_chmod (
const char* <em>FileName</em>, /* ファイルまたはディレクトリ名へのポインタ */
BYTE <em>Attribute</em>, /* 設定値 */
BYTE <em>AttributeMask</em> /* 変更マスク */
);
</pre>
</div>
<div class="para">
<h4>引数</h4>
<dl class="par">
<dt>FileName</dt>
<dd>属性変更対象のファイルまたはディレクトリの<a href="filename.html">フルパス名</a>の入った<tt>'\0'</tt>で終わる文字列を指定します。</dd>
<dt>Attribute</dt>
<dd>設定する属性。指定可能な属性は次の通りで、これらの組み合わせで指定します。指定されなかった属性は解除されます。<br>
<table class="lst">
<tr><th></th><th>意味</th></td>
<tr><td>AM_RDO</td><td>リード・オンリー</td></td>
<tr><td>AM_ARC</td><td>アーカイブ</td></td>
<tr><td>AM_SYS</td><td>システム</td></td>
<tr><td>AM_HID</td><td>ヒドゥン</td></td>
</table>
</dd>
<dt>AttributeMask</dt>
<dd>変更する属性のマスク。指定した属性が設定または解除され、指定されなかった属性は状態が保持されます。<tt>Attribute</tt>と同じ値を使います。</dd>
</dl>
</div>
<div class="para">
<h4>戻り値</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>正常終了。</dd>
<dt>FR_NO_FILE</dt>
<dd>ファイルが見つからない。</dd>
<dt>FR_NO_PATH</dt>
<dd>パスが見つからない。</dd>
<dt>FR_INVALID_NAME</dt>
<dd>パス名が不正。</dd>
<dt>FR_INVALID_NAME</dt>
<dd>ドライブ番号が不正。</dd>
<dt>FR_NOT_READY</dt>
<dd>メディアがセットされていないなど、ディスク・ドライブが動作不能状態。</dd>
<dt>FR_WRITE_PROTECTED</dt>
<dd>メディアが書き込み禁止状態。</dd>
<dt>FR_RW_ERROR</dt>
<dd>ディスク・エラーまたは内部エラーによる失敗。</dd>
<dt>FR_NOT_ENABLED</dt>
<dd>その論理ドライブにワーク・エリアが与えられていない。</dd>
<dt>FR_NO_FILESYSTEM</dt>
<dd>ディスク上に有効なFATパーテーションが見つからない。</dd>
</dl>
</div>
<div class="para">
<h4>解説</h4>
<p>ファイルまたはディレクトリの属性を変更します。リード・オンリー構成および<tt>_FS_MINIMIZE &gt;= 1</tt>ではこの関数はサポートされません。</p>
</div>
<div class="para">
<h4>使用例</h4>
<pre>
// Set read-only flag , clear archive flag and others are left unchanged.
f_chmod("file.txt", AM_RDO, AM_RDO | AM_ARC);
</pre>
</div>
<p class="foot"><a href="../00index_j.html">戻る</a></p>
</body>
</html>
@@ -0,0 +1,60 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_j.html">
<link rel="stylesheet" href="../css_j.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_close</title>
</head>
<body>
<div class="para">
<h2>f_close</h2>
<p>ファイルを閉じます。</p>
<pre>
FRESULT f_close (
FIL* <em>FileObject</em> /* ファイル・オブジェクトへのポインタ */
);
</pre>
</div>
<div class="para">
<h4>引数</h4>
<dl class="par">
<dt>FileObject</dt>
<dd>閉じようとするファイルのファイル・オブジェクト構造体へのポインタを指定します。</dd>
</dl>
</div>
<div class="para">
<h4>戻り値</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>正常終了。</dd>
<dt>FR_RW_ERROR</dt>
<dd>ディスク・エラーまたは内部エラーによる失敗。</dd>
<dt>FR_NOT_READY</dt>
<dd>メディアがセットされていないなど、ディスク・ドライブが動作不能状態。</dd>
<dt>FR_INVALID_OBJECT</dt>
<dd>無効なファイル・オブジェクト。</dd>
</dl>
</div>
<div class="para">
<h4>解説</h4>
<p>ファイルを閉じます。書き込みの行われたファイルの場合、キャッシュされた状態(R/Wバッファ上のデータ、変更されたFATやディレクトリ項目)はディスクに書き戻されます。関数が正常終了すると、そのファイル・オブジェクトは無効になり、そのメモリも解放できます。読み込み専用モードで開かれたファイル・オブジェクトは、この関数によるクローズ処理を経ずに破棄することもできます。</p>
</div>
<div class="para">
<h4>参照</h4>
<tt><a href="open.html">f_open</a>, <a href="read.html">f_read</a>, <a href="write.html">f_write</a>, <a href="sync.html">f_sync</a>, <a href="sfile.html">FIL</a>, <a href="sfatfs.html">FATFS</a></tt>
</div>
<p class="foot"><a href="../00index_j.html">戻る</a></p>
</body>
</html>
@@ -0,0 +1,44 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_j.html">
<link rel="stylesheet" href="../css_j.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - disk_initialize</title>
</head>
<body>
<div class="para">
<h2>disk_initialize</h2>
<p>ディスク・ドライブを初期化します。</p>
<pre>
DSTATUS disk_initialize (
BYTE <em>Drive</em> /* 物理ドライブ番号 */
);
</pre>
</div>
<div class="para">
<h4>引数</h4>
<dl class="par">
<dt>Drive</dt>
<dd>初期化する物理ドライブ番号(0-9)を指定します。</dd>
</dl>
</div>
<div class="para">
<h4>戻り値</h4>
<p>この関数は戻り値としてディスク・ステータスを返します。ディスク・ステータスの詳細に関しては<tt><a href="dstat.html">disk_status()</a></tt>を参照してください。</p>
</div>
<div class="para">
<h4>解説</h4>
<p>ディスク・ドライブを初期化します。関数が成功すると、戻り値の<tt>STA_NOINIT</tt>フラグがクリアされます。</p>
</div>
<p class="foot"><a href="../00index_j.html">戻る</a></p>
</body>
</html>
@@ -0,0 +1,65 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_j.html">
<link rel="stylesheet" href="../css_j.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - disk_ioctl</title>
</head>
<body>
<div class="para">
<h2>disk_ioctl</h2>
<p>セクタの読み書き以外のディスク・ドライブ自体に対する様々な制御をします。</p>
<pre>
DRESULT disk_ioctl (
BYTE <em>Drive</em>, /* 物理ドライブ番号 */
BYTE <em>Command</em>, /* 制御コマンド */
void* <em>Buffer</em> /* データ受け渡しバッファ */
);
</pre>
</div>
<div class="para">
<h4>引数</h4>
<dl class="par">
<dt>Drive</dt>
<dd>物理ドライブ番号(0-9)を指定します。</dd>
<dt>Command</dt>
<dd>制御コマンド・コードを指定します。</dd>
<dt>Buffer</dt>
<dd>制御コマンドに依存したパラメータを授受するバッファを指すポインタを指定します。バッファを使用しないコマンドの場合は、NULLを指定します。</dd>
</dl>
</div>
<div class="para">
<h4>戻り値</h4>
<dl class="ret">
<dt>RES_OK (0)</dt>
<dd>正常終了。</dd>
<dt>RES_ERROR</dt>
<dd>何らかのエラーが発生した。</dd>
<dt>RES_PARERR</dt>
<dd>コマンドが不正。</dd>
<dt>RES_NOTRDY</dt>
<dd>ドライブが動作可能状態ではない、または初期化されていない。</dd>
</dl>
</div>
<div class="para">
<h4>解説</h4>
<p>物理ドライブの種類によりサポートされるコマンドは異なりますが、FatFsモジュールでは、ドライブの種類に依存した制御は行いません。次のドライブ共通コマンドを使用します。</p>
<p>リード・オンリー構成ではこの関数は必要とされません。</p>
<table class="lst">
<tr><th>コマンド</th><th>解説</td></tr>
<tr><td>GET_SECTOR_COUNT</td><td>Bufferの指すDWORD変数にドライブ上の総セクタ数を返します。</td></tr>
<tr><td>CTRL_SYNC</td><td>ドライブがデータの書き込みを完了するのを待ちます。ライト・バック・キャッシュを持っている場合は、書き込まれていないデータを即時書き戻します。</td></tr>
</table>
</div>
<p class="foot"><a href="../00index_j.html">戻る</a></p>
</body>
</html>
@@ -0,0 +1,58 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_j.html">
<link rel="stylesheet" href="../css_j.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - disk_read</title>
</head>
<body>
<div class="para">
<h2>disk_read</h2>
<p>ディスクからセクタを読み出します。</p>
<pre>
DRESULT disk_read (
BYTE <em>Drive</em>, /* 物理ドライブ番号 */
BYTE* <em>Buffer</em>, /* 読み出しバッファへのポインタ */
DWORD <em>SectorNumber</em>, /* 読み出し開始セクタ番号 */
BYTE <em>SectorCount</em> /* 読み出しセクタ数 */
);
</pre>
</div>
<div class="para">
<h4>引数</h4>
<dl class="par">
<dt>Drive</dt>
<dd>物理ドライブ番号(0-9)を指定します。</dd>
<dt>Buffer</dt>
<dd>ディスクから読み出したデータを格納するバッファ。<tt>SectorCount * 512</tt>バイトのサイズが必要です。</dd>
<dt>SectorNumber</dt>
<dd>読み出しを開始するセクタ番号。LBAで指定します。</dd>
<dt>SectorCount</dt>
<dd>読み出すセクタ数。 1~255で設定します</dd>
</dl>
</div>
<div class="para">
<h4>戻り値</h4>
<dl class="ret">
<dt>RES_OK (0)</dt>
<dd>正常終了。</dd>
<dt>RES_ERROR</dt>
<dd>読み込み中にエラーが発生した。</dd>
<dt>RES_PARERR</dt>
<dd>パラメータが不正。</dd>
<dt>RES_NOTRDY</dt>
<dd>ドライブが動作可能状態ではない(初期化されていない)。</dd>
</dl>
</div>
<p class="foot"><a href="../00index_j.html">戻る</a></p>
</body>
</html>
@@ -0,0 +1,47 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_j.html">
<link rel="stylesheet" href="../css_j.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - disk_status</title>
</head>
<body>
<div class="para">
<h2>disk_status</h2>
<p>ディスク・ドライブの状態を取得します。</p>
<pre>
DSTATUS disk_status (
BYTE <em>Drive</em> /* 物理ドライブ番号 */
);
</pre>
</div>
<div class="para">
<h4>引数</h4>
<dl class="par">
<dt>Drive</dt>
<dd>ステータスを取得する物理ドライブ番号を指定します。</dd>
</dl>
</div>
<div class="para">
<h4>戻り値</h4>
<p>物理ドライブの状態が次のフラグの組み合わせの値で返されます。</p>
<dl class="ret">
<dt>STA_NOINIT</dt>
<dd>ドライブが初期化されていないことを示すフラグ。システム・リセットやメディアの取り外し等でセットされ、disk_initialize() の正常終了でクリア、失敗でセットされます。</dd>
<dt>STA_NODISK</dt>
<dd>メディアがセットされていないことを示すフラグ。メディアが取り外されている間はセットされ、メディアがセットされている間はクリアされます。固定ディスクでは常にクリアされています。</dd>
<dt>STA_PROTECTED</dt>
<dd>メディアがライト・プロテクトされていることを示すフラグ。ライト・プロテクト機能をサポートしないメディアでは常にクリアされています。</dd>
</dl>
</div>
<p class="foot"><a href="../00index_j.html">戻る</a></p>
</body>
</html>
@@ -0,0 +1,66 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_j.html">
<link rel="stylesheet" href="../css_j.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - disk_write</title>
</head>
<body>
<div class="para">
<h2>disk_write</h2>
<p>ディスクにデータを書き込みます。</p>
<pre>
DRESULT disk_write (
BYTE <em>Drive</em>, /* 物理ドライブ番号 */
const BYTE* <em>Buffer</em>, /* 書き込むデータへのポインタ */
DWORD <em>SectorNumber</em>, /* 書き込み開始セクタ番号 */
BYTE <em>SectorCount</em> /* 書き込みセクタ数 */
);
</pre>
</div>
<div class="para">
<h4>引数</h4>
<dl class="par">
<dt>Drive</dt>
<dd>物理ドライブ番号(0-9)を指定します。</dd>
<dt>Buffer</dt>
<dd>ディスクに書き込むデータを指定します。</dd>
<dt>SectorNumber</dt>
<dd>書き込みを開始するセクタ番号。LBAで指定します。</dd>
<dt>SectorCount</dt>
<dd>書き込むセクタ数。 1~255で設定します。</dd>
</dl>
</div>
<div class="para">
<h4>戻り値</h4>
<dl class="ret">
<dt>RES_OK (0)</dt>
<dd>正常終了。</dd>
<dt>RES_ERROR</dt>
<dd>書き込み中にエラーが発生した。</dd>
<dt>RES_WRPRT</dt>
<dd>ディスクが書き込み禁止状態。</dd>
<dt>RES_PARERR</dt>
<dd>パラメータが不正。</dd>
<dt>RES_NOTRDY</dt>
<dd>ドライブが動作可能状態ではない(初期化されていない)。</dd>
</dl>
</div>
<div class="para">
<h4>解説</h4>
<p>リード・オンリー構成ではこの関数は必要とされません。</p>
</div>
<p class="foot"><a href="../00index_j.html">戻る</a></p>
</body>
</html>
@@ -0,0 +1,50 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_j.html">
<link rel="stylesheet" href="../css_j.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - get_fattime</title>
</head>
<body>
<div class="para">
<h2>get_fattime</h2>
<p>現在時刻を取得します。</p>
<pre>
DWORD get_fattime (void);
</pre>
</div>
<div class="para">
<h4>戻り値</h4>
<p>現在のローカル・タイムが<tt>DWORD</tt>値にパックされて返されます。ビット・フィールドは次に示すようになります。</p>
<dl>
<dt>bit31:25</dt>
<dd>1980年を起点とした年が 0..127 で入ります。</dd>
<dt>bit24:21</dt>
<dd>月が 1..12 の値で入ります。</dd>
<dt>bit20:16</dt>
<dd>日が 1..31 の値で入ります。</dd>
<dt>bit15:11</dt>
<dd>時が 0..23 の値で入ります。</dd>
<dt>bit10:5</dt>
<dd>分が 0..59 の値で入ります。</dd>
<dt>bit4:0</dt>
<dd>秒/2が 0..29 の値で入ります。</dd>
</dl>
</div>
<div class="para">
<h4>解説</h4>
<p>RTCをサポートしないシステムでも、何らかの日付として有効な値を返さなければなりません。リード・オンリー構成ではこの関数は必要とされません。</p>
</div>
<p class="foot"><a href="../00index_j.html">戻る</a></p>
</body>
</html>
@@ -0,0 +1,56 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_j.html">
<link rel="stylesheet" href="../css_j.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - ファイル・ディレクトリの指定方法</title>
</head>
<body>
<div class="para">
<h2>ファイル・ディレクトリの指定方法</h2>
<p>FatFsモジュールでのファイル、ディレクトリ、ドライブの指定方法はMS-DOSとほぼ同じです。ただし、MS-DOSのようなカレント・ディレクトリの概念は無いので、常にルート・ディレクトリから辿る絶対パスでの指定となります。パス名の指定方法と例は次の通りです。</p>
<pre>
"[<em>論理ドライブ番号</em>:][/]<em>ディレクトリ名</em>/<em>ファイル名</em>"
"file1.txt" ファイル(ドライブ0)
"/file1.txt" ↑と同じ
"dir1/dir2/file1.txt" ファイル(ドライブ0)
"2:dir3/file2.txt" ファイル(ドライブ2)
"2:/dir5" ディレクトリ(ドライブ2)
"" ルート・ディレクトリ(ドライブ0)
"/" ↑と同じ
"2:" ルート・ディレクトリ(ドライブ2)
</pre>
<p>FatFsモジュールは8.3形式ファイル名にのみ対応しています。長いファイル名には対応していないので、ファイル名やディレクトリ名は8.3形式の範囲内で指定します。ディレクトリ・セパレータには'/'を使用します。パス名先頭の'/'は、あってもなくても同じです。論理ドライブ番号は、'0''9'の一文字の数字とコロンで指定します。省略した場合は"0:"を指定したことになります。Tiny-FatFsでは一つのファイル・システム・オブジェクトしか持てず、常に論理ドライブ0として動作します。また、パス名中に論理ドライブ番号を使用できません。</p>
</div>
<p><br></p>
<div class="para">
<h2>論理ドライブと物理ドライブの対応</h2>
<p>標準構成では、それぞれの論理ドライブは同じ番号の物理ドライブに1:1で結びつけられていて、先頭の区画がマウントされます。構成オプションで<tt>_MULTI_PARTITION</tt>を指定すると、論理ドライブに対して個別に物理ドライブ番号・区画を指定できるようになります。この構成では、論理ドライブと区画の対応を解決するためのテーブルを次に示すように定義する必要があります。</p>
<pre>
例:論理ドライブ0~2を物理ドライブ0(固定ディスク)の3つの基本区画に割り当て、
論理ドライブ3を物理ドライブ1(リムーバブル・ディスク)に割り当てる場合。
const PARTITION Drives[] = {
{0, 0}, /* Logical drive 0 ==> Physical drive 0, 1st partition */
{0, 1}, /* Logical drive 1 ==> Physical drive 0, 2nd partition */
{0, 2}, /* Logical drive 2 ==> Physical drive 0, 3rd partition */
{1, 0} /* Logical drive 3 ==> Physical drive 1 */
};
</pre>
<p>複数区画指定を使用する場合、次の点に注意しなければなりません。
<ul>
<li>指定可能な区画は基本区画(0~3)のみ。</li>
<li>物理ドライブがSFD形式(区画テーブル無し)の場合、区画指定は無視される。</li>
<li>複数の論理ドライブを持つ物理ドライブは、固定ディスクでなければならない。</li>
</li>
</div>
</body>
</html>
@@ -0,0 +1,91 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_j.html">
<link rel="stylesheet" href="../css_j.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_getfree</title>
</head>
<body>
<div class="para">
<h2>f_getfree</h2>
<p>論理ドライブ上の未使用クラスタ数を得ます。</p>
<pre>
FRESULT f_getfree (
const char* <em>Path</em>, /* 対象ドライブのルート・ディレクトリ */
DWORD* <em>Clusters</em>, /* 空きクラスタ数を格納する変数へのポインタ */
FATFS** <em>FileSystemObject</em> /* ファイル・システム・オブジェクトを指すポインタへのポインタ */
);
</pre>
</div>
<div class="para">
<h4>引数</h4>
<dl class="par">
<dt>Path</dt>
<dd>対象の論理ドライブのルートディレクトリの<a href="filename.html">パス名</a>が入った<tt>'\0'</tt>で終わる文字列へのポインタを指定します。</dd>
<dt>Clusters</dt>
<dd>空きクラスタ数を格納する<tt>DWORD</tt>変数へのポインタを指定します。</dd>
<dt>FileSystemObject</dt>
<dd>対象ドライブのファイル・システム・オブジェクトを指すポインタが返されます。</dd>
</dl>
</div>
<div class="para">
<h4>戻り値</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>正常終了。<tt>*Clusters</tt>に空きクラスタ数が返されます。</dd>
<dt>FR_INVALID_DRIVE</dt>
<dd>ドライブ番号が不正。</dd>
<dt>FR_NOT_READY</dt>
<dd>メディアがセットされていないなど、ディスクドライブが動作不能状態。</dd>
<dt>FR_RW_ERROR</dt>
<dd>ディスク・エラーまたは内部エラーによる失敗。</dd>
<dt>FR_NOT_ENABLED</dt>
<dd>その論理ドライブにワーク・エリアが与えられていない。</dd>
<dt>FR_NO_FILESYSTEM</dt>
<dd>ディスク上に有効なFATパーテーションが見つからない。</dd>
</dl>
</div>
<div class="para">
<h4>解説</h4>
<p>論理ドライブ上の空きクラスタ数を取得します。返されたファイル・システム・オブジェクトの<tt>sects_clust</tt>メンバがクラスタあたりのセクタ数を示しているので、これを元に実際の空きサイズが計算できます。FAT32ボリュームにおいて、_USE_FSINFOが指定されている場合、不正確な値を返す場合があります。指定されていない場合、処理に時間がかかります。</p>
<p>リードオンリー構成および<tt>_FS_MINIMIZE &gt;= 1</tt>ではこの関数はサポートされません。</p>
</div>
<div class="para">
<h4>使用例</h4>
<pre>
FATFS *fs;
DWORD clust;
// Get free clusters
res = f_getfree("", &clust, &fs);
if (res) die(res);
// Get free space
printf("%lu KB total disk space.\n"
"%lu KB available on the disk.\n",
(DWORD)(fs->max_clust - 2) * fs->sects_clust / 2,
clust * fs->sects_clust / 2);
</pre>
</div>
<div class="para">
<h4>参照</h4>
<tt><a href="sfatfs.html">FATFS</a></tt>
</div>
<p class="foot"><a href="../00index_j.html">戻る</a></p>
</body>
</html>
@@ -0,0 +1,87 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_j.html">
<link rel="stylesheet" href="../css_j.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_lseek</title>
</head>
<body>
<div class="para">
<h2>f_lseek</h2>
<p>ファイルのR/Wポインタを移動します。</p>
<pre>
FRESULT f_lseek (
FIL* <em>FileObject</em>, /* ファイル・オブジェクト構造体へのポインタ */
DWORD <em>Offset</em> /* 移動先オフセット */
);
</pre>
</div>
<div class="para">
<h4>引数</h4>
<dl class="par">
<dt>FileObject</dt>
<dd>対象となるファイル・オブジェクト構造体へのポインタを指定します。</dd>
<dt>Offset</dt>
<dd>移動先のオフセット(R/Wポインタ)値。ファイル先頭からのオフセットをバイト単位で指定します。</dd>
</dl>
</div>
<div class="para">
<h4>戻り値</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>正常終了。</dd>
<dt>FR_RW_ERROR</dt>
<dd>ディスク・エラーまたは内部エラーによる失敗。</dd>
<dt>FR_NOT_READY</dt>
<dd>メディアがセットされていないなど、ディスク・ドライブが動作不能状態。</dd>
<dt>FR_INVALID_OBJECT</dt>
<dd>無効なファイル・オブジェクト。</dd>
</dl>
</div>
<div class="para">
<h4>解説</h4>
<p>ファイルR/Wポインタ(ファイル・オブジェクト内のfptrメンバで、次に読み出し・書き込みされるバイトのオフセットを示す)を移動します。オフセットの原点はファイル先頭からです。書き込みモードでファイル・サイズより大きな値を指定すると、そこまでファイルが拡張され、拡張された部分のデータは未定義となります。大容量データを遅延無く高速に書き込みたいときは、予めこの関数で必要なサイズまでファイルを拡張しておくと良いです。f_lseek関数が正常終了したあとは、ファイルR/Wポインタが正しく移動したかfptrをチェックするべきです。ファイルR/Wポインタが指定より小さいときは、次の原因が考えられます。</p>
<ul>
<li>非書き込みモードのため、ファイル・サイズでクリップされた。</li>
<li>ファイル拡張中にディスクが満杯になった。</li>
<li>FAT構造にエラーがある。</li>
</ul>
<p>_FS_MINIMIZE >= 3ではこの関数はサポートされません。</p>
</div>
<div class="para">
<h4>使用例</h4>
<pre>
// ファイル・オフセット5000へ移動
res = f_lseek(&file, 5000);
// 3000バイト進める
res = f_lseek(&file, file.fptr + 3000);
// 2000バイト戻す(オーバーフローに注意)
res = f_lseek(&file, file.fptr - 2000);
// ファイル追記の準備
res = f_lseek(&file, file.fsize);
</pre>
</div>
<div class="para">
<h4>参照</h4>
<p><tt><a href="open.html">f_open</a>, <a href="sfile.html">FIL</a></tt></p>
</div>
<p class="foot"><a href="../00index_j.html">戻る</a></p>
</body>
</html>
@@ -0,0 +1,83 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_j.html">
<link rel="stylesheet" href="../css_j.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_mkdir</title>
</head>
<body>
<div class="para">
<h2>f_mkdir</h2>
<p>ディレクトリを作成します。</p>
<pre>
FRESULT f_mkdir (
const char* <em>DirName</em> /* 作成するディレクトリ名へのポインタ */
);
</pre>
</div>
<div class="para">
<h4>引数</h4>
<dl class="par">
<dt>DirName</dt>
<dd>作成するディレクトリの<a href="filename.html">フルパス名</a>が入った<tt>'\0'</tt>で終わる文字列へのポインタを指定します。</dd>
</dl>
</div>
<div class="para">
<h4>戻り値</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>正常終了。</dd>
<dt>FR_NO_PATH</dt>
<dd>パスが見つからない。</dd>
<dt>FR_INVALID_NAME</dt>
<dd>パス名が不正。</dd>
<dt>FR_INVALID_DRIVE</dt>
<dd>ドライブ番号が不正。</dd>
<dt>FR_DENIED</dt>
<dd>ディスクやディレクトリ・エントリが満杯の場合など。</dd>
<dt>FR_EXIST</dt>
<dd>同名のディレクトリやファイルが存在する。</dd>
<dt>FR_NOT_READY</dt>
<dd>メディアがセットされていないなど、ディスク・ドライブが動作不能状態。</dd>
<dt>FR_WRITE_PROTECTED</dt>
<dd>メディアが書き込み禁止状態。</dd>
<dt>FR_RW_ERROR</dt>
<dd>ディスク・エラーまたは内部エラーによる失敗。</dd>
<dt>FR_NOT_ENABLED</dt>
<dd>その論理ドライブにワーク・エリアが与えられていない。</dd>
<dt>FR_NO_FILESYSTEM</dt>
<dd>ディスク上に有効なFATパーテーションが見つからない。</dd>
</dl>
</div>
<div class="para">
<h4>解説</h4>
<p>空のディレクトリを作成します。リード・オンリー構成および<tt>_FS_MINIMIZE &gt;= 1</tt>ではこの関数はサポートされません。</p>
<p>
</p>
</div>
<div class="para">
<h4>使用例</h4>
<pre>
res = f_mkdir("sub1");
if (res) die(res);
res = f_mkdir("sub1/sub2");
if (res) die(res);
res = f_mkdir("sub1/sub2/sub3");
if (res) die(res);
</pre>
</div>
<p class="foot"><a href="../00index_j.html">戻る</a></p>
</body>
</html>
@@ -0,0 +1,73 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_j.html">
<link rel="stylesheet" href="../css_j.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_mkfs</title>
</head>
<body>
<div class="para">
<h2>f_mkfs</h2>
<p>ドライブ上にFATファイル・システムを作成(フォーマット)します。</p>
<pre>
FRESULT f_mkfs (
BYTE <em>Drive</em>, /* Logical drive number */
BYTE <em>PartitioningRule</em>, /* Partitioning rule */
BYTE <em>AllocSize</em> /* Allocation unit size */
);
</pre>
</div>
<div class="para">
<h4>引数</h4>
<dl class="par">
<dt>Drive</dt>
<dd>フォーマットする論理ドライブ(0-9)。</dd>
<dt>PartitioningRule</dt>
<dd>0を指定すると、区画テーブルを作成したあとその区画にファイル・システムを作成します(FDISKフォーマット)。1を指定すると、先頭セクタから直接ファイル・システムを構築します(super floppy (SFD) フォーマット)。</dd>
<dt>AllocSize</dt>
<dd>クラスタ・サイズをセクタ単位で指定します。2の累乗でかつクラスタ・サイズが32Kバイトまでの範囲でなければなりません。</dd>
</dl>
</div>
<div class="para">
<h4>戻り値</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>正常終了。</dd>
<dt>FR_INVALID_DRIVE</dt>
<dd>ドライブ番号が無効。</dd>
<dt>FR_NOT_READY</dt>
<dd>メディアがセットされていないなど、物理ドライブが動作不能状態。</dd>
<dt>FR_WRITE_PROTECTED</dt>
<dd>メディアが書き込み禁止状態。</dd>
<dt>FR_NOT_ENABLED</dt>
<dd>その論理ドライブにワーク・エリアが割り当てられていない。</dd>
<dt>FR_RW_ERROR</dt>
<dd>ディスク・エラーまたは内部エラーによる失敗。</dd>
<dt>FR_MKFS_ABORTED</dt>
<dd>次の理由で開始前に処理が中断された。
<ul>
<li>ディスク・サイズが小さすぎる。</li>
<li>何らかの引数が不正。</li>
<li>そのクラスタ・サイズが使えない。クラスタ数が0xFF7と0xFFF7近辺になるとき発生する可能性がある。</li>
</ul>
</dd>
</dl>
</div>
<div class="para">
<h4>説明</h4>
<p>f_mkfs関数はFATファイル・システムをドライブ上に作成します。リムーバブル・メディアのパーテーショニング・ルールとしては、FDISK形式とSFD形式がありますが、FDISK形式が一般的です。この関数は<em>複数区画には対応していない</em>ので、その物理ドライブの既存の区画は全て削除され、全体が一つの区画になります。</p>
<p>FATタイプ(FAT12/FAT16/FAT32)は、ディスク上の<em>クラスタ数によってのみ決定</em>される[FAT仕様書より]決まりになっていて、それ以外の要因はありません。したがって、どのFATタイプになるかは、ディスク・サイズとクラスタ・サイズに依存します。クラスタ・サイズは大きいほど性能が上がるので、特に小容量のドライブでなければ64セクタを選択しておけばよいです。</p>
<p>この関数は、FatFsで構成オプション<tt>_USE_MKFS</tt>を選択したときにサポートされます。また、Tiny-FatFsではサポートされません。<p>
</div>
<p class="foot"><a href="../00index_e.html">Return</a></p>
</body>
</html>
@@ -0,0 +1,59 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_j.html">
<link rel="stylesheet" href="../css_j.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_mount</title>
</head>
<body>
<div class="para">
<h2>f_mount</h2>
<p>論理ドライブのワーク・エリアを登録・抹消します。</p>
<pre>
FRESULT f_mount (
BYTE <em>Drive</em>, /* 論理ドライブ番号 */
FATFS* <em>FileSystemObject</em> /* ワーク・エリアへのポインタ */
);
</pre>
</div>
<div class="para">
<h4>引数</h4>
<dl class="par">
<dt>Drive</dt>
<dd>論理ドライブ番号(0-9)。Tiny-FatFsでは常に0。</dd>
<dt>FileSystemObject</dt>
<dd>登録するワーク・エリア(ファイル・システム・オブジェクト)へのポインタ。</dd>
</dl>
</div>
<div class="para">
<h4>戻り値</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>正常終了。</dd>
<dt>FR_INVALID_DRIVE</dt>
<dd>ドライブ番号が無効。</dd>
</dl>
</div>
<div class="para">
<h4>解説</h4>
<p>FatFsモジュールではそれぞれの論理ドライブにファイル・システム・オブジェクトというワーク・エリアが必要です。この関数は論理ドライブにそのワーク・エリアを登録したり抹消したりします。何らかのファイル関数を使用する前にこの関数でその論理ドライブのワーク・エリアを与えておかなければなりません。<tt>FileSystemObject</tt>にヌル・ポインタを指定するとその論理ドライブのワーク・エリアの登録は抹消され、登録されていたワーク・エリアは破棄できます。</p>
<p>この関数内では物理ドライブへのアクセスは発生せず、ワーク・エリアを初期化して内部配列にそのアドレスを登録するだけです。実際のマウント動作は、他のファイル関数(パス名を指定するもの)の中で必要に応じて行われます。</p>
</div>
<div class="para">
<h4>参照</h4>
<p><tt><a href="sfatfs.html">FATFS</a></tt></p>
</div>
<p class="foot"><a href="../00index_j.html">戻る</a></p>
</body>
</html>
@@ -0,0 +1,58 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_j.html">
<link rel="stylesheet" href="../css_j.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_mountdrv</title>
</head>
<body>
<div class="para">
<h2>f_mountdrv</h2>
<p>ファイルシステムを明示的に初期化します。</p>
<pre>
FRESULT f_mountdrv (void);
</pre>
</div>
<div class="para">
<h4>戻り値</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>正常終了。</dd>
<dt>FR_NOT_READY</dt>
<dd>メディアがセットされていないなど、ディスクドライブが動作不能状態。</dd>
<dt>FR_RW_ERROR</dt>
<dd>ディスクアクセスでエラーが発生した。</dd>
<dt>FR_NOT_ENABLED</dt>
<dd>FatFsモジュールが停止状態。</dd>
<dt>FR_NO_FILESYSTEM</dt>
<dd>ディスク上に有効なFATファイルシステムが見つからない。</dd>
</dl>
</div>
<div class="para">
<h4>解説</h4>
<p>ファイルシステムを強制的に初期化(マウント)します。FatFsモジュールではマウント動作はファイル関数呼び出し時に必要に応じて内部で行われるので、通常はこの関数を使用すべきではありません。自動マウント動作中に回復不能エラー(たとえば<tt>FR_INCORRECT_DISK_CHANGE</tt>)が発生した場合、全てのファイル関数が使えなくなるので、そのときはこの関数で再マウントして回復することができます。</p>
<p>f_mountdrv関数内では次の処理が行われます。</p>
<br>
<ul>
<li>下位レイヤ(ディスクI/Oモジュール)の初期化。</li>
<li>FATブートレコードの検索。先頭セクタ(SFD)→第一基本区画(FDISK)の順に検索します。</li>
<li>ファイルシステムオブジェクト構造体の初期化。</li>
</ul>
</div>
<div class="para">
<h4>参照</h4>
<p><tt><a href="sfatfs.html">FATFS</a></tt></p>
</div>
<p class="foot"><a href="../00index_j.html">戻る</a></p>
</body>
</html>
@@ -0,0 +1,135 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_j.html">
<link rel="stylesheet" href="../css_j.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_open</title>
</head>
<body>
<div class="para">
<h2>f_open</h2>
<p>ファイルをオープンまたは作成します。</p>
<pre>
FRESULT f_open (
FIL* <em>FileObject</em>, /* 空のファイル・オブジェクト構造体へのポインタ */
const char* <em>FileName</em>, /* ファイルのフルパス名へのポインタ */
BYTE <em>ModeFlags</em> /* モードフラグ */
);
</pre>
</div>
<div class="para">
<h4>引数</h4>
<dl class="par">
<dt>FileObject</dt>
<dd>新しく作成するファイル・オブジェクト構造体へのポインタを指定します。以降、そのファイルを閉じるまでこのファイル・オブジェクトを使用してファイル操作をします。</dd>
<dt>FileName</dt>
<dd>開く(または作成する)ファイルの <a href="filename.html">ファイル名</a>が入った<tt>'\0'</tt>で終わる文字列へのポインタを指定します。</dd>
<dt>ModeFlags</dt>
<dd>ファイルのアクセス方法やオープン方法を決めるフラグです。このパラメータには次の組み合わせを指定します。<br>
<table class="lst">
<tr><th></th><th>意味</th></td>
<tr><td>FA_READ</td><td>読み出しモードで開きます。読み書きする場合は<tt>FA_WRITE</tt>と共に指定します。</td></tr>
<tr><td>FA_WRITE</td><td>書き込みモードで開きます。読み書きする場合は<tt>FA_READ</tt>と共に指定します。</td></tr>
<tr><td>FA_OPEN_EXISTING</td><td>既存のファイルを開きます。ファイルが無いときはエラーになります。</td></tr>
<tr><td>FA_OPEN_ALWAYS</td><td>既存のファイルを開きます。ファイルが無いときはファイルを作成します。</td></tr>
<tr><td>FA_CREATE_NEW</td><td>ファイルを作成します。同名のファイルがある場合は、エラーになります。</td></tr>
<tr><td>FA_CREATE_ALWAYS</td><td>ファイルを作成します。同名のファイルがある場合は、サイズを0にしてから開きます。</td></tr>
</table>
</dd>
</dl>
</div>
<div class="para">
<h4>戻り値</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>正常終了。以降、<tt>FileObject</tt>構造体を使ってこのファイルを操作できます。</dd>
<dt>FR_NO_FILE</dt>
<dd>ファイルが見つからない。</dd>
<dt>FR_NO_PATH</dt>
<dd>パスが見つからない。</dd>
<dt>FR_INVALID_NAME</dt>
<dd>ファイル名が不正。</dd>
<dt>FR_INVALID_DRIVE</dt>
<dd>ドライブ番号が不正。</dd>
<dt>FR_EXIST</dt>
<dd>同名のファイルが既にある。</dd>
<dt>FR_DENIED</dt>
<dd>アクセスが拒否された。リード・オンリー・ファイルの書き込みモード・オープン、同名のディレクトリまたはリード・オンリー・ファイルがある状態でのファイル作成、ディスクまたはディレクトリ・テーブルが満杯でファイルを作成できないなど。</dd>
<dt>FR_NOT_READY</dt>
<dd>メディアがセットされていないなど、ディスク・ドライブが動作不能状態。</dd>
<dt>FR_WRITE_PROTECTED</dt>
<dd>メディアが書き込み禁止状態で書き込み系オープンをした。</dd>
<dt>FR_RW_ERROR</dt>
<dd>ディスク・エラーまたは内部エラーによる失敗。</dd>
<dt>FR_NOT_ENABLED</dt>
<dd>その論理ドライブにワーク・エリアが割り当てられていない。</dd>
<dt>FR_NO_FILESYSTEM</dt>
<dd>ディスク上に有効なFATパーテーションが見つからない。</dd>
</dl>
</div>
<div class="para">
<h4>解説</h4>
<p>作成されたファイル・オブジェクトは、以降そのファイルに対するアクセスに使用します。ファイルを閉じるときは、<a href="close.html">f_close()</a>を使用します。</p>
<p>ファイル操作関数を使用する前にまず、<a href="mount.html">f_mount()</a>を使ってそれぞれの論理ドライブにワーク・エリア(ファイル・システム・オブジェクト)を与えなければなりません。この初期化の後、その論理ドライブに対して全てのファイル関数が使えるようになります。</p>
<p>リードオンリー構成では、<tt>FA_WRITE, FA_CREATE_ALWAYS, FA_CREATE_NEW, FA_OPEN_ALWAYS</tt>の各フラグはサポートされません。</p>
</div>
<div class="para">
<h4>使用例(ファイル・コピー)</h4>
<pre>
void main ()
{
FATFS fs; // 論理ドライブのワーク・エリア(ファイル・システム・オブジェクト)
FIL fsrc, fdst; // ファイル・オブジェクト
BYTE buffer[4096]; // file copy buffer
FRESULT res; // FatFs function common result code
WORD br, bw; // File R/W count
// ドライブ0にワーク・エリアを与える
f_mount(0, &fs);
// ソース・ファイルを開く
res = f_open(&fsrc, "srcfile.dat", FA_OPEN_EXISTING | FA_READ);
if (res) die(res);
// デスティネーション・ファイルを作成する
res = f_open(&fdst, "dstfile.dat", FA_CREATE_ALWAYS | FA_WRITE);
if (res) die(res);
// ソースからデスティネーションにコピーする
for (;;) {
res = f_read(&fsrc, buffer, sizeof(buffer), &br);
if (res || br == 0) break; // error or eof
res = f_write(&fdst, buffer, br, &bw);
if (res || bw &lt; br) break; // error or disk full
}
// 全てのファイルを閉じる
f_close(&fsrc);
f_close(&fdst);
// ワーク・エリアを開放する
f_mount(0, NULL);
}
</pre>
</div>
<div class="para">
<h4>参照</h4>
<p><tt><a href="read.html">f_read</a>, <a href="write.html">f_write</a>, <a href="close.html">f_close</a>, <a href="sfile.html">FIL</a>, <a href="sfatfs.html">FATFS</a></tt></p>
</div>
<p class="foot"><a href="../00index_j.html">戻る</a></p>
</body>
</html>
@@ -0,0 +1,73 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_j.html">
<link rel="stylesheet" href="../css_j.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_opendir</title>
</head>
<body>
<div class="para">
<h2>f_opendir</h2>
<p>ディレクトリをオープンします。</p>
<pre>
FRESULT f_opendir (
DIR* <em>DirObject</em>, /* ディレクトリ・ブジェクト構造体へのポインタ */
const char* <em>DirName</em> /* ディレクトリ名へのポインタ */
);
</pre>
</div>
<div class="para">
<h4>引数</h4>
<dl class="par">
<dt>DirObject</dt>
<dd>初期化するディレクトリ・オブジェクト構造体へのポインタを指定します。</dd>
<dt>DirName</dt>
<dd>オープンするディレクトリの<a href="filename.html">フルパス名</a>が入った<tt>'\0'</tt>で終わる文字列へのポインタを指定します。</dd>
</dl>
</div>
<div class="para">
<h4>戻り値</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>正常終了。</dd>
<dt>FR_NO_FILE</dt>
<dd>ディレクトリが見つからない。</dd>
<dt>FR_NO_PATH</dt>
<dd>パスが見つからない。</dd>
<dt>FR_INVALID_NAME</dt>
<dd>パス名が不正。</dd>
<dt>FR_INVALID_DRIVE</dt>
<dd>ドライブ番号が不正。</dd>
<dt>FR_NOT_READY</dt>
<dd>メディアがセットされていないなど、ディスク・ドライブが動作不能状態。</dd>
<dt>FR_RW_ERROR</dt>
<dd>ディスク・エラーまたは内部エラーによる失敗。</dd>
<dt>FR_NOT_ENABLED</dt>
<dd>論理ドライブにワーク・エリアが与えられていない。</dd>
<dt>FR_NO_FILESYSTEM</dt>
<dd>ディスク上に有効なFATパーテーションが見つからない。</dd>
</dl>
</div>
<div class="para">
<h4>解説</h4>
<p>ディレクトリをオープンします。正常終了したら、<tt>DirObject</tt>構造体を使ってこのディレクトリの項目を順次読み出せます。<tt>DirObject</tt>構造体は使用後は任意の時点で破棄できます。<tt>_FS_MINIMIZE >= 2</tt>ではこの関数はサポートされません。</p>
</div>
<div class="para">
<h4>参照</h4>
<p><tt><a href="readdir.html">f_readdir</a>, <a href="sdir.html">DIR</a></tt></p>
</div>
<p class="foot"><a href="../00index_j.html">戻る</a></p>
</body>
</html>
@@ -0,0 +1,71 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_j.html">
<link rel="stylesheet" href="../css_j.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_read</title>
</head>
<body>
<div class="para">
<h2>f_read</h2>
<p>ファイルからデータを読み出します。</p>
<pre>
FRESULT f_read (
FIL* <em>FileObject</em>, // ファイル・オブジェクト構造体
void* <em>Buffer</em>, // 読み出したデータを格納するバッファ
WORD <em>ByteToRead</em>, // 読み出すバイト数
WORD* <em>ByteRead</em> // 読み出されたバイト数
);
</pre>
</div>
<div class="para">
<h4>引数</h4>
<dl class="par">
<dt>FileObject</dt>
<dd>ファイル・オブジェクト構造体へのポインタを指定します。</dd>
<dt>Buffer</dt>
<dd>読み出したデータを格納するバッファを指すポインタを指定します。</dd>
<dt>ByteToRead</dt>
<dd>読み出すバイト数(0~65535)を指定します。</dd>
<dt>ByteRead</dt>
<dd>実際に読み出されたバイト数を格納する変数を指すポインタを指定します。</dd>
</dt>
</div>
<div class="para">
<h4>戻り値</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>正常終了。</dd>
<dt>FR_DENIED</dt>
<dd>非読み込みモードで開いたファイルから読み込もうとした。</dd>
<dt>FR_RW_ERROR</dt>
<dd>ディスク・エラーまたは内部エラーによる失敗。</dd>
<dt>FR_NOT_READY</dt>
<dd>メディアがセットされていないなど、ディスク・ドライブが動作不能状態。</dd>
<dt>FR_INVALID_OBJECT</dt>
<dd>無効なファイル・オブジェクト。</dd>
</dl>
</div>
<div class="para">
<h4>解説</h4>
<p>読み込み開始位置は、現在のファイルR/Wポインタからになります。ファイルR/Wポインタは読み込まれたバイト数だけ進みます。読み込み中にファイルの終端に達すると、<tt>*ByteRead</tt><tt>ByteToRead</tt>よりも小さくなります。</p>
</div>
<div class="para">
<h4>参照</h4>
<p><tt><a href="open.html">f_open</a>, <a href="write.html">f_write</a>, <a href="close.html">f_close</a>, <a href="sfile.html">FIL</a></tt></p>
</div>
<p class="foot"><a href="../00index_j.html">戻る</a></p>
</body>
</html>
@@ -0,0 +1,89 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_j.html">
<link rel="stylesheet" href="../css_j.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_readdir</title>
</head>
<body>
<div class="para">
<h2>f_readdir</h2>
<p>ディレクトリ項目を読み出します</p>
<pre>
FRESULT f_readdir (
DIR* <em>DirObject</em>, /* ディレクトリ・ブジェクト構造体へのポインタ */
FILINFO* <em>FileInfo</em> /* ファイル情報構造体へのポインタ */
);
</pre>
</div>
<div class="para">
<h4>引数</h4>
<dl class="par">
<dt>DirObject</dt>
<dd>ディレクトリ・オブジェクト構造体へのポインタを指定します。</dd>
<dt>FileInfo</dt>
<dd>読み出したディレクトリ項目を格納するファイル情報構造体へのポインタを指定します。</dd>
</dl>
</div>
<div class="para">
<h4>戻り値</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>正常終了。</dd>
<dt>FR_NOT_READY</dt>
<dd>メディアがセットされていないなど、ディスク・ドライブが動作不能状態。</dd>
<dt>FR_RW_ERROR</dt>
<dd>ディスク・エラーまたは内部エラーによる失敗。</dd>
<dt>FR_INVALID_OBJECT</dt>
<dd>無効なディレクトリ・オブジェクト。</dd>
</dl>
</div>
<div class="para">
<h4>解説</h4>
<p>ディレクトリ項目を順次読み出します。この関数を繰り返し実行することによりディレクトリの全ての項目を読み出すことができます。全ての項目を読み出し、読み出す項目がもう無いときは、<tt>f_name[]</tt>メンバにヌル文字列が返されます。得られるファイル情報の詳細については <tt>FILINFO</tt>構造体を参照してください。<tt>_FS_MINIMIZE >= 2</tt>ではこの関数はサポートされません。</p>
</div>
<div class="para">
<h4>使用例</h4>
<pre>
void scan_files (char* path)
{
FILINFO finfo;
DIR dirs;
int i;
if (f_opendir(&dirs, path) == FR_OK) {
i = strlen(path);
while ((f_readdir(&dirs, &finfo) == FR_OK) && finfo.fname[0]) {
if (finfo._attrib & AM_DIR) {
sprintf(path+i, "/%s", &finfo.fname[0]);
scan_files(path);
*(path+i) = '\0';
} else {
printf("%s/%s\n", path, &finfo.fname[0]);
}
}
}
}
</pre>
</div>
<div class="para">
<h4>参照</h4>
<p><tt><a href="opendir.html">f_opendir</a>, <a href="stat.html">f_stat</a>, <a href="sfileinfo.html">FILINFO</a>, <a href="sdir.html">DIR</a></tt></p>
</div>
<p class="foot"><a href="../00index_j.html">戻る</a></p>
</body>
</html>
@@ -0,0 +1,86 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_j.html">
<link rel="stylesheet" href="../css_j.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_rename</title>
</head>
<body>
<div class="para">
<h2>f_rename</h2>
<p>ファイルまたはディレクトリの名前の変更または移動。</p>
<pre>
FRESULT f_rename (
const char* <em>OldName</em>, /* 古いファイルまたはディレクトリ名 */
const char* <em>NewName</em> /* 新しいファイルまたはディレクトリ名 */
);
</pre>
</div>
<div class="para">
<h4>引数</h4>
<dl class="par">
<dt>OldName</dt>
<dd>変更対象のファイルまたはディレクトリの<a href="filename.html">フルパス名</a>の入った<tt>'\0'</tt>で終わる文字列へのポインタを指定します。</dd>
<dt>NewName</dt>
<dd>新しいファイルまたはディレクトリのフルパス名の入った<tt>'\0'</tt>で終わる文字列へのポインタを指定します。既に存在するものと同じ名前は使えません。また、ドライブ番号は指定できず、<tt>OldName</tt>で指定されたドライブ上のオブジェクトとして扱われます。<br>
</dl>
</div>
<div class="para">
<h4>戻り値</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>正常終了。</dd>
<dt>FR_NO_FILE</dt>
<dd>ファイルが見つからない。</dd>
<dt>FR_NO_PATH</dt>
<dd>パスが見つからない。</dd>
<dt>FR_INVALID_NAME</dt>
<dd>パス名が不正。</dd>
<dt>FR_INVALID_DRIVE</dt>
<dd>ドライブ番号が不正。</dd>
<dt>FR_DENIED</dt>
<dd>新しい名前のオブジェクトが作れない。</dd>
<dt>FR_EXIST</dt>
<dd>NewNameと同じ名前のオブジェクトが既にある。</dd>
<dt>FR_NOT_READY</dt>
<dd>メディアがセットされていないなど、ディスク・ドライブが動作不能状態。</dd>
<dt>FR_WRITE_PROTECTED</dt>
<dd>メディアが書き込み禁止状態。</dd>
<dt>FR_RW_ERROR</dt>
<dd>ディスク・エラーまたは内部エラーによる失敗。</dd>
<dt>FR_NOT_ENABLED</dt>
<dd>論理ドライブにワークエリアが割り当てられていない。</dd>
<dt>FR_NO_FILESYSTEM</dt>
<dd>ディスク上に有効なFATパーテーションが見つからない。</dd>
</dl>
</div>
<div class="para">
<h4>解説</h4>
<p>ファイルまたはディレクトリの名前を変更します。別のディレクトリへの移動(同じドライブ内のみ)も可能です。リード・オンリー構成および<tt>_FS_MINIMIZE &gt;= 1</tt>ではこの関数はサポートされません。</p>
<p>※現リビジョンでは、ディレクトリを別のディレクトリに移動するとファイル・システムが壊れます。</p>
</div>
<div class="para">
<h4>使用例</h4>
<pre>
// 名前を変更する
f_rename("oldname.txt", "newname.txt");
// 名前の変更と同時に別のディレクトリへ移動する
f_rename("oldname.txt", "dir1/newname.txt");
</pre>
</div>
<p class="foot"><a href="../00index_j.html">戻る</a></p>
</body>
</html>
@@ -0,0 +1,42 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_j.html">
<link rel="stylesheet" href="../css_j.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - DIR</title>
</head>
<body>
<div class="para">
<h2>DIR</h2>
<p><tt>DIR</tt>構造体は、f_opendir(), f_readdir()のワーク・エリアとして使用されます。</p>
<h4>FatFs</h4>
<pre>
typedef struct _DIR {
WORD id; /* Owner file system mount ID (inverted) */
WORD index; /* Current index */
FATFS* fs; /* Pointer to the owner file system object */
DWORD sclust; /* Start cluster */
DWORD clust; /* Current cluster */
DWORD sect; /* Current sector */
} DIR;
</pre>
<h4>Tiny-FatFs</h4>
<pre>
typedef struct _DIR {
WORD id; /* Owner file system mount ID (inverted) */
WORD index; /* Current index */
FATFS* fs; /* Pointer to the owner file system object */
CLUST sclust; /* Start cluster */
CLUST clust; /* Current cluster */
DWORD sect; /* Current sector */
} DIR;
</pre>
</div>
<p class="foot"><a href="../00index_j.html">戻る</a></p>
</body>
</html>
@@ -0,0 +1,63 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_j.html">
<link rel="stylesheet" href="../css_j.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - FATFS</title>
</head>
<body>
<div class="para">
<h2>FATFS</h2>
<p><tt>FATFS</tt>構造体は、個々の論理ドライブのダイナミック・ワーク・エリアを保持し、f_mount()でFatFsモジュールに登録されます。標準状態では次のようなメンバになっています。アプリケーションから書き換え可能なメンバはありません。</p>
<h4>FatFs</h4>
<pre>
typedef struct _FATFS {
WORD id; /* File system mount ID */
WORD n_rootdir; /* Number of root directory entries */
DWORD winsect; /* Current sector appearing in the win[] */
DWORD sects_fat; /* Sectors per fat */
DWORD max_clust; /* Maximum cluster# + 1 */
DWORD fatbase; /* FAT start sector */
DWORD dirbase; /* Root directory start sector (cluster# for FAT32) */
DWORD database; /* Data start sector */
DWORD last_clust; /* Last allocated cluster */
DWORD free_clust; /* Number of free clusters */
BYTE fs_type; /* FAT type (0:Not mounted) */
BYTE sects_clust; /* Sectors per cluster */
BYTE n_fats; /* Number of FAT copies */
BYTE drive; /* Physical drive number */
BYTE winflag; /* win[] dirty flag (1:must be written back) */
BYTE pad1;
BYTE win[512]; /* Disk access window for Directory/FAT */
} FATFS;
</pre>
<h4>Tiny-FatFs</h4>
<pre>
typedef struct _FATFS {
WORD id; /* File system mount ID */
WORD n_rootdir; /* Number of root directory entries */
DWORD winsect; /* Current sector appearing in the win[] */
DWORD fatbase; /* FAT start sector */
DWORD dirbase; /* Root directory start sector */
DWORD database; /* Data start sector */
CLUST sects_fat; /* Sectors per fat */
CLUST max_clust; /* Maximum cluster# + 1 */
CLUST last_clust; /* Last allocated cluster */
CLUST free_clust; /* Number of free clusters */
BYTE fs_type; /* FAT type (0:Not mounted) */
BYTE sects_clust; /* Sectors per cluster */
BYTE n_fats; /* Number of FAT copies */
BYTE winflag; /* win[] dirty flag (1:must be written back) */
BYTE win[512]; /* Disk access window for Directory/FAT/File */
} FATFS;
</pre>
</div>
<p class="foot"><a href="../00index_j.html">戻る</a></p>
</body>
</html>
@@ -0,0 +1,54 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_j.html">
<link rel="stylesheet" href="../css_j.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - FIL</title>
</head>
<body>
<div class="para">
<h2>FIL</h2>
<p><tt>FIL</tt>構造体は、f_open()で作成され、そのファイルの状態を保持します。アプリケーションから書き換え可能なメンバはありません。</p>
<h4>FatFs</h4>
<pre>
typedef struct _FIL {
WORD id; /* Owner file system mount ID (inverted) */
BYTE flag; /* File status flags */
BYTE sect_clust; /* Left sectors in cluster */
FATFS* fs; /* Pointer to the owner file system object */
DWORD fptr; /* File R/W pointer */
DWORD fsize; /* File size */
DWORD org_clust; /* File start cluster */
DWORD curr_clust; /* Current cluster */
DWORD curr_sect; /* Current sector */
DWORD dir_sect; /* Sector containing the directory entry */
BYTE* dir_ptr; /* Ponter to the directory entry in the window */
BYTE buffer[512]; /* File R/W buffer */
} FIL;
</pre>
<h4>Tiny-FatFs</h4>
<pre>
typedef struct _FIL {
WORD id; /* Owner file system mount ID (inverted) */
BYTE flag; /* File status flags */
BYTE sect_clust; /* Left sectors in cluster */
FATFS* fs; /* Pointer to owner file system */
DWORD fptr; /* File R/W pointer */
DWORD fsize; /* File size */
CLUST org_clust; /* File start cluster */
CLUST curr_clust; /* Current cluster */
DWORD curr_sect; /* Current sector */
DWORD dir_sect; /* Sector containing the directory entry */
BYTE* dir_ptr; /* Ponter to the directory entry in the window */
} FIL;
</pre>
</div>
<p class="foot"><a href="../00index_j.html">戻る</a></p>
</body>
</html>
@@ -0,0 +1,43 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_j.html">
<link rel="stylesheet" href="../css_j.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - FILINFO</title>
</head>
<body>
<div class="para">
<h2>FILINFO</h2>
<p><tt>FILINFO</tt>構造体は、<tt>f_stat(), f_readdir()</tt>で返されるファイル情報を保持します。</p>
<pre>
typedef struct _FILINFO {
DWORD fsize; /* Size [bytes] */
WORD fdate; /* Date [15-9]:Year-1980, [8-5]:Month, [4-0]:Mday */
WORD ftime; /* Time [15-11]:Hour, [10-5]:Minute, [4-0]:Sec/2 */
BYTE fattrib; /* Attribute */
char fname[8+1+3+1]; /* Name */
} FILINFO;
</pre>
</div>
<h4>メンバ</h4>
<dl>
<dt>fsize</dt>
<dd>ファイルのバイト単位のサイズが格納されます。ディレクトリの場合は常に0です。</dd>
<dt>fdate</dt>
<dd>ファイルの変更された日付、またはディレクトリの作成された日付が格納されます。</dd>
<dt>ftime</dt>
<dd>ファイルの変更された時刻、またはディレクトリの作成された時刻が格納されます。</dd>
<dt>fattrib</dt>
<dd>属性フラグが格納されます。フラグは<tt>AM_DIR, AM_RDO, AM_HID, AM_SYS, AM_ARC</tt>の組み合わせとなります。</dd>
<dt>fname[]</dt>
<dd>8.3形式の名前が<tt>'\0'</tt>で終わる文字列として格納されます。</dd>
</dl>
<p class="foot"><a href="../00index_j.html">戻る</a></p>
</body>
</html>
@@ -0,0 +1,73 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_j.html">
<link rel="stylesheet" href="../css_j.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_stat</title>
</head>
<body>
<div class="para">
<h2>f_stat</h2>
<p></p>
<pre>
FRESULT f_stat (
const char* <em>FileName</em>, /* ファイルまたはディレクトリ名へのポインタ */
FILINFO* <em>FileInfo</em> /* ファイル情報構造体へのポインタ *
);
</pre>
</div>
<div class="para">
<h4>引数</h4>
<dl class="par">
<dt>FileName</dt>
<dd>情報を得るファイルまたはディレクトリ名の<tt>'\0'</tt>で終わる文字列を指すポインタを指定します。</dd>
<dt>FileInfo</dt>
<dd>読み出したファイル情報を格納するファイル情報構造体へのポインタを指定します。</dd>
</dl>
</div>
<div class="para">
<h4>戻り値</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>正常終了。</dd>
<dt>FR_NO_FILE</dt>
<dd>ファイルまたはディレクトリが見つからない。</dd>
<dt>FR_NO_PATH</dt>
<dd>パスが見つからない。</dd>
<dt>FR_INVALID_NAME</dt>
<dd>パス名が不正。</dd>
<dt>FR_INVALID_NAME</dt>
<dd>ドライブ番号が不正。</dd>
<dt>FR_NOT_READY</dt>
<dd>メディアがセットされていないなど、ディスク・ドライブが動作不能状態。</dd>
<dt>FR_RW_ERROR</dt>
<dd>ディスク・エラーまたは内部エラーによる失敗。</dd>
<dt>FR_NOT_ENABLED</dt>
<dd>論理ドライブにワークエリアが割り当てられていない。</dd>
<dt>FR_NO_FILESYSTEM</dt>
<dd>ディスク上に有効なFATパーテーションが見つからない。</dd>
</dl>
</div>
<div class="para">
<h4>解説</h4>
<p>ファイルまたはディレクトリに関する情報を得ます。得られるファイル情報の詳細については <tt>FILINFO</tt>構造体を参照してください。<tt>_FS_MINIMIZE &gt;= 1</tt>ではこの関数はサポートされません。</p>
</div>
<div class="para">
<h4>参照</h4>
<p><tt><a href="opendir.html">f_opendir</a>, <a href="readdir.html">f_readdir</a>, <a href="sfileinfo.html">FILINFO</a>, <a href="sdir.html">DIR</a></tt></p>
</div>
<p class="foot"><a href="../00index_j.html">戻る</a></p>
</body>
</html>
@@ -0,0 +1,61 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_j.html">
<link rel="stylesheet" href="../css_j.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_sync</title>
</head>
<body>
<div class="para">
<h2>f_sync</h2>
<p>書き込み中のファイルのキャッシュされた情報をフラッシュします。</p>
<pre>
FRESULT f_sync (
FIL* <em>FileObject</em> /* ファイル・オブジェクト構造体へのポインタ */
);
</pre>
</div>
<div class="para">
<h4>引数</h4>
<dl class="par">
<dt>FileObject</dt>
<dd>syncするファイルのファイル・オブジェクト構造体へのポインタを指定します。</dd>
</dl>
</div>
<div class="para">
<h4>戻り値</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>正常終了。</dd>
<dt>FR_RW_ERROR</dt>
<dd>ディスク・エラーまたは内部エラーによる失敗。</dd>
<dt>FR_NOT_READY</dt>
<dd>メディアがセットされていないなど、ディスク・ドライブが動作不能状態。</dd>
<dt>FR_INVALID_OBJECT</dt>
<dd>ファイル・オブジェクトが無効。</dd>
</dl>
</div>
<div class="para">
<h4>解説</h4>
<p>この関数は<tt>f_close()</tt>と同じ処理を実行しますが、ファイルは引き続き開かれたままになり、読み書きを続行できます。ロギングなど、書き込みモードで長時間ファイルが開かれているアプリケーションにおいて、定期的または区切りの良いところでsyncすることにより、不意の電源断やメディアの取り外しにより失われるデータを最小にすることができます。</p>
<p>リード・オンリー構成ではこの関数はサポートされません。</p>
</div>
<div class="para">
<h4>参照</h4>
<p><tt><a href="close.html">f_close</a></tt></p>
</div>
<p class="foot"><a href="../00index_j.html">戻る</a></p>
</body>
</html>
@@ -0,0 +1,68 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_j.html">
<link rel="stylesheet" href="../css_j.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_unlink</title>
</head>
<body>
<div class="para">
<h2>f_unlink</h2>
<p>ファイルまたはディレクトリを削除します。</p>
<pre>
FRESULT f_unlink (
const char* <em>FileName</em> /* ファイルまたはディレクトリ名へのポインタ */
);
</pre>
</div>
<div class="para">
<h4>引数</h4>
<dl class="par">
<dt>FileName</dt>
<dd>削除対象の<a href="filename.html">ファイルまたはディレクトリ名</a>の入った<tt>'\0'</tt>で終わる文字列へのポインタを指定します。</dd>
</dl>
</div>
<div class="para">
<h4>戻り値</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>正常終了。</dd>
<dt>FR_NO_FILE</dt>
<dd>ファイルが見つからない。</dd>
<dt>FR_NO_PATH</dt>
<dd>パスが見つからない。</dd>
<dt>FR_INVALID_NAME</dt>
<dd>パス名が不正。</dd>
<dt>FR_INVALID_DRIVE</dt>
<dd>ドライブ番号が不正。</dd>
<dt>FR_DENIED</dt>
<dd>対象ファイル・ディレクトリがリード・オンリー状態、対象ディレクトリが空でない場合など。</dd>
<dt>FR_NOT_READY</dt>
<dd>メディアがセットされていないなど、物理ドライブが動作不能状態。</dd>
<dt>FR_WRITE_PROTECTED</dt>
<dd>メディアが書き込み禁止状態。</dd>
<dt>FR_RW_ERROR</dt>
<dd>ディスク・エラーまたは内部エラーによる失敗。</dd>
<dt>FR_NOT_ENABLED</dt>
<dd>論理ドライブにワーク・エリアが割り当てられていない。</dd>
<dt>FR_NO_FILESYSTEM</dt>
<dd>ディスク上に有効なFATパーテーションが見つからない。</dd>
</dl>
</div>
<div class="para">
<h4>解説</h4>
<p>ファイルまたはディレクトリを削除します。リード・オンリー構成や<tt>_FS_MINIMIZE &gt;= 1</tt>ではこの関数はサポートされません。</p>
</div>
<p class="foot"><a href="../00index_j.html">戻る</a></p>
</body>
</html>
@@ -0,0 +1,71 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="up" title="FatFs" href="../00index_j.html">
<link rel="stylesheet" href="../css_j.css" type="text/css" media="screen" title="ELM Default">
<title>FatFs - f_write</title>
</head>
<body>
<div class="para">
<h2>f_write</h2>
<p>ファイルにデータを書き込みます。</p>
<pre>
FRESULT f_write (
FIL* <em>FileObject</em>, /* ファイル・オブジェクト */
const void* <em>Buffer</em>, /* 書き込みデータ */
WORD <em>ByteToWrite</em>, /* 書き込むバイト数 */
WORD* <em>ByteWritten</em> /* 書き込まれたバイト数 */
);
</pre>
</div>
<div class="para">
<h4>引数</h4>
<dl class="par">
<dt>FileObject</dt>
<dd>ファイル・オブジェクト構造体へのポインタを指定します。</dd>
<dt>Buffer</dt>
<dd>書き込むデータを格納したバッファを指すポインタを指定します。</dd>
<dt>ByteToWrite</dt>
<dd>書き込むバイト数(0~65535)を指定します。</dd>
<dt>ByteWritten</dt>
<dd>書き込まれたバイト数を格納する変数を指すポインタを指定します。</dd>
</dl>
</div>
<div class="para">
<h4>戻り値</h4>
<dl class="ret">
<dt>FR_OK (0)</dt>
<dd>正常終了。</dd>
<dt>FR_DENIED</dt>
<dd>非書き込みモードで開いたファイルに書き込もうとした。</dd>
<dt>FR_RW_ERROR</dt>
<dd>ディスク・エラーまたは内部エラーによる失敗。</dd>
<dt>FR_NOT_READY</dt>
<dd>メディアがセットされていないなど、ディスク・ドライブが動作不能状態。</dd>
<dt>FR_INVALID_OBJECT</dt>
<dd>無効なファイルオブジェクト。</dd>
</dl>
</div>
<div class="para">
<h4>解説</h4>
<p>書き込み開始位置は、ファイルR/Wポインタの現在位置からになります。ファイルR/Wポインタは実際に書き込まれたバイト数だけ進みます。書き込み中にディスクが一杯になったときは、<tt>*ByteWritten</tt><tt>ByteToWrite</tt>よりも小さくなります。リード・オンリー構成ではこの関数はサポートされません。</p>
</div>
<div class="para">
<h4>参照</h4>
<p><tt><a href="open.html">f_open</a>, <a href="read.html">f_read</a>, <a href="close.html">f_close</a>, <a href="sfile.html">FIL</a></tt></p>
</div>
<p class="foot"><a href="../00index_j.html">戻る</a></p>
</body>
</html>
@@ -0,0 +1,42 @@
R0.04b, May 05, 2007
Added _USE_NTFLAG option.
Added FSInfo support.
Fixed some problems corresponds to FAT32. (Tiny-FatFs)
Fixed DBCS name can result FR_INVALID_NAME.
Fixed short seek (<= csize) collapses the file object.
R0.04a, Apr 01, 2007
Supported multiple partitions on a plysical drive. (FatFs)
Added minimization level 3.
Added a capability of extending file size to f_lseek().
Fixed an endian sensitive code in f_mkfs(). (FatFs)
Fixed a problem corresponds to FAT32 support. (Tiny-FatFs)
R0.04, Feb 04, 2007
Supported multiple drive system. (FatFs)
Changed some APIs for multiple drive system.
Added f_mkfs(). (FatFs)
Added _USE_FAT32 option. (Tiny-FatFs)
R0.03a, Dec 11, 2006
Improved cluster scan algolithm to write files fast.
Fixed f_mkdir() creates incorrect directory on FAT32.
R0.02a, Jun 10, 2006
Added a configuration option _FS_MINIMUM.
R0.02, Jun 01, 2006
Added FAT12.
Removed unbuffered mode.
Fixed a problem on small (<32M) patition.
R0.03, Sep 22, 2006
Added f_rename().
Changed option _FS_MINIMUM to _FS_MINIMIZE.
R0.01, Apr 29, 2006
First release
R0.00, Feb 26, 2006
Prototype (not released)
@@ -0,0 +1,292 @@
/*-----------------------------------------------------------------------*/
/* Dual-disk wrapper allowing operating of two different drives */
/* underneath the FatFs layer without modification of the existing */
/* single-unit drivers for those drives. */
/* */
/* This file was modified from a sample driver available from the FatFs */
/* web site. */
/*-----------------------------------------------------------------------*/
#include "inc/hw_types.h"
#include "fatfs/src/diskio.h"
#include "fatfs/src/ff.h"
/*-----------------------------------------------------------------------*/
/* Configuration */
/*-----------------------------------------------------------------------*/
/* This wrapper allows two independent, low level, single drive FatFs */
/* drivers to be used simultaneously to provide a FatFs implementation */
/* with two physical drives. Configuration is set using two #define */
/* labels, one each from the following two groups, to indicate which */
/* drivers to use for each of the logical drives supported. */
/* */
/* DISK0_EK_LM3S3748 - Logical disk 0 is an EK-LM3S3748 SD Card. */
/* DISK0_DK_LM3S9B96 - Logical disk 0 is an DK-LM3S9B96 SD Card. */
/* DISK0_RDK_IDM_SBC - Logical disk 0 is an RDK-IDM-SBC SD Card. */
/* DISK0_RDK_IDM - Logical disk 0 is an RDK-IDM SD Card. */
/* DISK0_USB_MSC - Logical disk 0 is a USB Mass Storage Class */
/* device. */
/* */
/* DISK1_EK_LM3S3748 - Logical disk 1 is an EK-LM3S3748 SD Card. */
/* DISK1_DK_LM3S9B96 - Logical disk 1 is an DK-LM3S9B96 SD Card. */
/* DISK1_RDK_IDM_SBC - Logical disk 1 is an RDK-IDM-SBC SD Card. */
/* DISK1_RDK_IDM - Logical disk 1 is an RDK-IDM SD Card. */
/* DISK1_USB_MSC - Logical disk 1 is a USB Mass Storage Class */
/* device. */
/* */
/* The same driver cannot be used to support both logical drives. */
/* */
/* Note that the USB MSC driver does not support a timer function so we */
/* need to undef DRIVEn_TIMERPROC whenever this driver is configured. */
/*-----------------------------------------------------------------------*/
#ifdef DISK0_EK_LM3S3748
#define DRIVE0_DRIVER "mmc-ek-lm3s3748.c"
#define DRIVE0_TIMERPROC
#else
#ifdef DISK0_DK_LM3S9B96
#define DRIVE0_DRIVER "mmc-dk-lm3s9b96.c"
#define DRIVE0_TIMERPROC
#else
#ifdef DISK0_RDK_IDM_SBC
#define DRIVE0_DRIVER "mmc-rdk-idm-sbc.c"
#define DRIVE0_TIMERPROC
#else
#ifdef DISK0_RDK_IDM
#define DRIVE0_DRIVER "mmc-rdk-idm.c"
#define DRIVE0_TIMERPROC
#else
#ifdef DISK0_USB_MSC
#define DRIVE0_DRIVER "fat_usbmsc.c"
#undef DRIVE0_TIMERPROC
#else
#error "Unrecognized/undefined driver for DISK0!"
#endif
#endif
#endif
#endif
#endif
#ifdef DISK1_EK_LM3S3748
#define DRIVE1_DRIVER "mmc-ek-lm3s3748.c"
#define DRIVE1_TIMERPROC
#else
#ifdef DISK1_DK_LM3S9B96
#define DRIVE1_DRIVER "mmc-dk-lm3s9b96.c"
#define DRIVE1_TIMERPROC
#else
#ifdef DISK1_RDK_IDM_SBC
#define DRIVE1_DRIVER "mmc-rdk-idm-sbc.c"
#define DRIVE1_TIMERPROC
#else
#ifdef DISK1_RDK_IDM
#define DRIVE1_DRIVER "mmc-rdk-idm.c"
#define DRIVE1_TIMERPROC
#else
#ifdef DISK1_USB_MSC
#define DRIVE1_DRIVER "fat_usbmsc.c"
#undef DRIVE0_TIMERPROC
#else
#error "Unrecognized/undefined driver for DISK1!"
#endif
#endif
#endif
#endif
#endif
/*-----------------------------------------------------------------------*/
/* The first low level driver */
/*-----------------------------------------------------------------------*/
#define disk_initialize disk0_initialize
#define disk_status disk0_status
#define disk_read disk0_read
#define disk_write disk0_write
#define disk_ioctl disk0_ioctl
#define disk_timerproc disk0_timerproc
#define get_fattime disk0_get_fattime
#include DRIVE0_DRIVER
#undef disk_initialize
#undef disk_status
#undef disk_read
#undef disk_write
#undef disk_ioctl
#undef disk_timerproc
#undef get_fattime
/*-----------------------------------------------------------------------*/
/* The second low level driver */
/*-----------------------------------------------------------------------*/
#define disk_initialize disk1_initialize
#define disk_status disk1_status
#define disk_read disk1_read
#define disk_write disk1_write
#define disk_ioctl disk1_ioctl
#define disk_timerproc disk1_timerproc
#define get_fattime disk1_get_fattime
#include DRIVE1_DRIVER
#undef disk_initialize
#undef disk_status
#undef disk_read
#undef disk_write
#undef disk_ioctl
#undef disk_timerproc
#undef get_fattime
/*-----------------------------------------------------------------------*/
/* Timer tick function. */
/*-----------------------------------------------------------------------*/
/* When using an SD card driver, this function must be called every 10mS */
/* by the application code. Note that this is not part of the device */
/* driver interface that is called directly by FatFs. */
/* */
void disk_timerproc (void)
{
#ifdef DRIVE0_TIMERPROC
disk0_timerproc();
#endif
#ifdef DRIVE1_TIMERPROC
disk1_timerproc();
#endif
}
/*-----------------------------------------------------------------------*/
/* Initialize Disk Drive */
/*-----------------------------------------------------------------------*/
DSTATUS
disk_initialize(
BYTE bValue) /* Physical drive number */
{
/* Depending upon the physical drive, call the relevant low level */
/* driver. Note that we call each with physical drive number 0 since the */
/* low level drivers typically expect this (they only support a single */
/* drive). */
if(bValue == 0)
{
return(disk0_initialize(0));
}
else
{
return(disk1_initialize(0));
}
}
/*-----------------------------------------------------------------------*/
/* Returns the current status of a drive */
/*-----------------------------------------------------------------------*/
DSTATUS disk_status (
BYTE drv) /* Physical drive number */
{
/* Depending upon the physical drive, call the relevant low level */
/* driver. Note that we call each with physical drive number 0 since the */
/* low level drivers typically expect this (they only support a single */
/* drive). */
if(drv == 0)
{
return(disk0_status(0));
}
else
{
return(disk1_status(0));
}
}
/*-----------------------------------------------------------------------*/
/* This function reads sector(s) from the disk drive */
/*-----------------------------------------------------------------------*/
DRESULT disk_read (
BYTE drv, /* Physical drive number */
BYTE* buff, /* Pointer to the data buffer to store read data */
DWORD sector, /* Sector number */
BYTE count) /* Sector count (1..255) */
{
/* Depending upon the physical drive, call the relevant low level */
/* driver. Note that we call each with physical drive number 0 since the */
/* low level drivers typically expect this (they only support a single */
/* drive). */
if(drv == 0)
{
return(disk0_read(0, buff, sector, count));
}
else
{
return(disk1_read(0, buff, sector, count));
}
}
/*-----------------------------------------------------------------------*/
/* This function writes sector(s) to the disk drive */
/*-----------------------------------------------------------------------*/
#if _READONLY == 0
DRESULT disk_write (
BYTE ucDrive, /* Physical drive number (0) */
const BYTE* buff, /* Pointer to the data to be written */
DWORD sector, /* Sector number */
BYTE count) /* Sector count (1..255) */
{
/* Depending upon the physical drive, call the relevant low level */
/* driver. Note that we call each with physical drive number 0 since the */
/* low level drivers typically expect this (they only support a single */
/* drive). */
if(ucDrive == 0)
{
return(disk0_write(0, buff, sector, count));
}
else
{
return(disk1_write(0, buff, sector, count));
}
}
#endif /* _READONLY */
/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions */
/*-----------------------------------------------------------------------*/
DRESULT disk_ioctl (
BYTE drv, /* Physical drive number (0) */
BYTE ctrl, /* Control code */
void *buff) /* Buffer to send/receive control data */
{
/* Depending upon the physical drive, call the relevant low level */
/* driver. Note that we call each with physical drive number 0 since the */
/* low level drivers typically expect this (they only support a single */
/* drive). */
if(drv == 0)
{
return(disk0_ioctl(0, ctrl, buff));
}
else
{
return(disk1_ioctl(0, ctrl, buff));
}
}
/*---------------------------------------------------------*/
/* User Provided Timer Function for FatFs module */
/*---------------------------------------------------------*/
/* This is a real time clock service to be called from */
/* FatFs module. Any valid time must be returned even if */
/* the system does not support a real time clock. */
/* */
/* Note that each driver implements the same function but, */
/* since the function doesn't take any parameter, we can't */
/* decide automatically which driver's get_fattime() to */
/* invoke. Instead, we control this with a #define */
/* which defaults to calling the first driver. */
/* */
DWORD get_fattime (void)
{
#ifndef DRIVE1_TIME_MASTER
return(disk0_get_fattime());
#else
return(disk1_get_fattime());
#endif
}
@@ -0,0 +1,150 @@
/*-----------------------------------------------------------------------*/
/*-----------------------------------------------------------------------*/
/* USB MSC module */
/*-----------------------------------------------------------------------*/
/*-----------------------------------------------------------------------*/
/*
* This file was modified from a sample available from the FatFs
* web site. It was modified to work with the USB Library.
*/
#include <stdint.h>
#include <stdbool.h>
#include "device.h"
#include "usblib.h"
#include "usbmsc.h"
#include "host/usbhost.h"
#include "host/usbhmsc.h"
#include "fatfs/src/diskio.h"
#include "fatfs/src/ff.h"
extern tUSBHMSCInstance *g_psMSCInstance;
static volatile
DSTATUS USBStat = STA_NOINIT; /* Disk status */
/*-----------------------------------------------------------------------*/
/* Initialize Disk Drive */
/*-----------------------------------------------------------------------*/
DSTATUS
disk_initialize(
BYTE bValue) /* Physical drive number (0) */
{
/* Set the not initialized flag again. If all goes well and the disk is */
/* present, this will be cleared at the end of the function. */
USBStat |= STA_NOINIT;
/* Find out if drive is ready yet. */
if (USBHMSCDriveReady(g_psMSCInstance)) return(FR_NOT_READY);
/* Clear the not init flag. */
USBStat &= ~STA_NOINIT;
return 0;
}
/*-----------------------------------------------------------------------*/
/* Returns the current status of a drive */
/*-----------------------------------------------------------------------*/
DSTATUS disk_status (
BYTE drv) /* Physical drive number (0) */
{
if (drv) return STA_NOINIT; /* Supports only single drive */
return USBStat;
}
/*-----------------------------------------------------------------------*/
/* This function reads sector(s) from the disk drive */
/*-----------------------------------------------------------------------*/
DRESULT disk_read (
BYTE drv, /* Physical drive number (0) */
BYTE* buff, /* Pointer to the data buffer to store read data */
DWORD sector, /* Physical drive nmuber (0) */
BYTE count) /* Sector count (1..255) */
{
if(USBStat & STA_NOINIT)
{
return(RES_NOTRDY);
}
/* READ BLOCK */
if (USBHMSCBlockRead(g_psMSCInstance, sector, (uint8_t *)buff, count) == 0)
return RES_OK;
return RES_ERROR;
}
/*-----------------------------------------------------------------------*/
/* This function writes sector(s) to the disk drive */
/*-----------------------------------------------------------------------*/
#if _READONLY == 0
DRESULT disk_write (
BYTE ucDrive, /* Physical drive number (0) */
const BYTE* buff, /* Pointer to the data to be written */
DWORD sector, /* Start sector number (LBA) */
BYTE count) /* Sector count (1..255) */
{
if (ucDrive || !count) return RES_PARERR;
if (USBStat & STA_NOINIT) return RES_NOTRDY;
if (USBStat & STA_PROTECT) return RES_WRPRT;
/* WRITE BLOCK */
if(USBHMSCBlockWrite(g_psMSCInstance, sector, (uint8_t *)buff,
count) == 0)
return RES_OK;
return RES_ERROR;
}
#endif /* _READONLY */
/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions */
/*-----------------------------------------------------------------------*/
DRESULT disk_ioctl (
BYTE drv, /* Physical drive number (0) */
BYTE ctrl, /* Control code */
void *buff) /* Buffer to send/receive control data */
{
if(USBStat & STA_NOINIT)
{
return(RES_NOTRDY);
}
switch(ctrl)
{
case CTRL_SYNC:
return(RES_OK);
default:
return(RES_PARERR);
}
}
/*---------------------------------------------------------*/
/* User Provided Timer Function for FatFs module */
/*---------------------------------------------------------*/
/* This is a real time clock service to be called from */
/* FatFs module. Any valid time must be returned even if */
/* the system does not support a real time clock. */
DWORD get_fattime (void)
{
return ((2007UL-1980) << 25) // Year = 2007
| (6UL << 21) // Month = June
| (5UL << 16) // Day = 5
| (11U << 11) // Hour = 11
| (38U << 5) // Min = 38
| (0U >> 1) // Sec = 0
;
}
@@ -0,0 +1,841 @@
/*-----------------------------------------------------------------------*/
/* MMC/SDC (in SPI mode) control module (C)ChaN, 2007 */
/*-----------------------------------------------------------------------*/
/* Only rcvr_spi(), xmit_spi(), disk_timerproc() and some macros */
/* are platform dependent. */
/*-----------------------------------------------------------------------*/
/*
* This file was modified from a sample available from the FatFs
* web site. It was modified to work with a F2837xD device.
*/
#include "F28x_Project.h"
//#include "F2837xD_types.h"
#include "inc/hw_types.h"
#include "fatfs/src/diskio.h"
/*
* The following header defines the hardware connections used to connect
* the SDCard. This can be found under the relevant board directory.
*/
//*****************************************************************************
//
// SDCard SPI port
//
//*****************************************************************************
//*****************************************************************************
//
// GPIO for SDCard SPI pins
//
//*****************************************************************************
//*****************************************************************************
//
// GPIO for the SDCard chip select
//
//*****************************************************************************
/* Definitions for MMC/SDC command */
#define CMD0 (0x40+0) /* GO_IDLE_STATE */
#define CMD1 (0x40+1) /* SEND_OP_COND */
#define CMD8 (0x40+8) /* SEND_IF_COND */
#define CMD9 (0x40+9) /* SEND_CSD */
#define CMD10 (0x40+10) /* SEND_CID */
#define CMD12 (0x40+12) /* STOP_TRANSMISSION */
#define CMD16 (0x40+16) /* SET_BLOCKLEN */
#define CMD17 (0x40+17) /* READ_SINGLE_BLOCK */
#define CMD18 (0x40+18) /* READ_MULTIPLE_BLOCK */
#define CMD23 (0x40+23) /* SET_BLOCK_COUNT */
#define CMD24 (0x40+24) /* WRITE_BLOCK */
#define CMD25 (0x40+25) /* WRITE_MULTIPLE_BLOCK */
#define CMD41 (0x40+41) /* SEND_OP_COND (ACMD) */
#define CMD55 (0x40+55) /* APP_CMD */
#define CMD58 (0x40+58) /* READ_OCR */
// asserts the CS pin to the card
static
void SELECT (void) //EDITED
{
//
// Select the SD card.
//
GpioDataRegs.GPDCLEAR.bit.GPIO125 = 1;
}
// De-asserts the CS pin to the card.
static
void DESELECT (void) //EDITED
{
GpioDataRegs.GPDSET.bit.GPIO125 = 1;
}
/*--------------------------------------------------------------------------
Module Private Functions
---------------------------------------------------------------------------*/
static volatile
DSTATUS Stat = STA_NOINIT; /* Disk status */
static volatile
BYTE Timer1, Timer2; /* 100Hz decrement timer */
static
BYTE CardType; /* b0:MMC, b1:SDC, b2:Block addressing */
static
BYTE PowerFlag = 0; /* indicates if "power" is on */
/*-----------------------------------------------------------------------*/
/* Transmit a byte to MMC via SPI (Platform dependent) */
/*-----------------------------------------------------------------------*/
static
void xmit_spi (BYTE dat) //EDITED
{
volatile DWORD rcvdat; //included file like integer.h for DWORD definition
/* Write the data to the tx fifo */
while(SpicRegs.SPISTS.bit.BUFFULL_FLAG); //Wait for room to write data
SpicRegs.SPITXBUF = ((DWORD)dat)<<8; //Write data
/* flush data read during the write */
while(SpicRegs.SPISTS.bit.INT_FLAG !=1); //May be possible to switch to '!SpicRegs.SPISTS.bit.INT_FLAG'
rcvdat = (SpicRegs.SPIRXBUF && 0xFF); //Clear Receive Buffer
}
/*-----------------------------------------------------------------------*/
/* Receive a byte from MMC via SPI (Platform dependent) */
/*-----------------------------------------------------------------------*/
static
BYTE rcvr_spi (void) //EDITED
{
volatile DWORD rcvdat;
//Disable transmission channel
//SpicRegs.SPICTL.bit.TALK = 0;
/* write dummy data */
while(SpicRegs.SPISTS.bit.BUFFULL_FLAG); //Wait for space to write
SpicRegs.SPITXBUF = 0xFF00; //Write dummy data
/* read data from RX fifo */
while(SpicRegs.SPISTS.bit.INT_FLAG !=1); //May be possible to switch to '!SpicRegs.SPISTS.bit.INT_FLAG'
rcvdat = (SpicRegs.SPIRXBUF & 0xFF); //Read Transferred data
return (BYTE)rcvdat;
}
static
void rcvr_spi_m (BYTE *dst)
{
*dst = rcvr_spi();
}
/*-----------------------------------------------------------------------*/
/* Wait for card ready */
/*-----------------------------------------------------------------------*/
static
BYTE wait_ready (void)
{
BYTE res;
Timer2 = 50; /* Wait for ready in timeout of 500ms */
rcvr_spi();
do{
res = rcvr_spi();
DELAY_US(175);
} while ((res != 0xFF) && Timer2);
return res;
}
/*-----------------------------------------------------------------------*/
/* Send 80 or so clock transitions with CS and DI held high. This is */
/* required after card power up to get it into SPI mode */
/*-----------------------------------------------------------------------*/
static
void send_initial_clock_train (void) //EDITED
{
volatile DWORD dat;
/* Ensure CS (STE) is held high. */
DESELECT();
/* Switch the SPI TX line to a GPIO and drive it high too. */
EALLOW;
GpioCtrlRegs.GPDLOCK.bit.GPIO122 = 0;
GpioCtrlRegs.GPDMUX2.bit.GPIO122 = 0;
GpioCtrlRegs.GPDDIR.bit.GPIO122 = 1;
GpioCtrlRegs.GPDLOCK.bit.GPIO122 = 1;
EDIS;
GpioDataRegs.GPDSET.bit.GPIO122 = 1;
/* Send 10 bytes over the SPI. This causes the clock to wiggle the */
/* required number of times. */
unsigned int i;
for(i = 0 ; i < 10 ; i++)
{
/* Write DUMMY data */
while(SpicRegs.SPISTS.bit.BUFFULL_FLAG);
SpicRegs.SPITXBUF = 0xFF00;
/* Flush data read during data write. */
while(SpicRegs.SPISTS.bit.INT_FLAG !=1); //May be possible to switch to '!SpicRegs.SPISTS.bit.INT_FLAG'
dat = (SpicRegs.SPIRXBUF & 0xFF);
}
/* Revert to hardware control of the SPI TX line. */
EALLOW;
GpioCtrlRegs.GPDLOCK.bit.GPIO122 = 0;
GpioCtrlRegs.GPDMUX2.bit.GPIO122 = 2;
GpioCtrlRegs.GPDLOCK.bit.GPIO122 = 1;
EDIS;
}
/*-----------------------------------------------------------------------*/
/* Power Control (Platform dependent) */
/*-----------------------------------------------------------------------*/
/* When the target system does not support socket power control, there */
/* is nothing to do in these functions and chk_power always returns 1. */
static
void power_on (void) //EDITED
{
/*
* This doesn't really turn the power on, but initializes the
* SPI port and pins needed to talk to the SD card.
*/
EALLOW;
/* Enable the peripherals used to drive the SDC on SPI */
CpuSysRegs.PCLKCR8.bit.SPI_C = 1;
/*
* Configure the appropriate pins to be SPI instead of GPIO. The CS
* signal is directly driven to ensure that we can hold it low through a
* complete transaction with the SD card.
*/
//Unlock the SD-Card SPI GPIOs
GpioCtrlRegs.GPDLOCK.bit.GPIO122 = 0;
GpioCtrlRegs.GPDLOCK.bit.GPIO123 = 0;
GpioCtrlRegs.GPDLOCK.bit.GPIO124 = 0;
GpioCtrlRegs.GPDLOCK.bit.GPIO125 = 0;
//Set up MUX & DIR
GpioCtrlRegs.GPDMUX2.bit.GPIO125 = 0; //Leave as GPIO for manual CS control
GpioCtrlRegs.GPDGMUX2.bit.GPIO122 = 1;
GpioCtrlRegs.GPDGMUX2.bit.GPIO123 = 1;
GpioCtrlRegs.GPDGMUX2.bit.GPIO124 = 1;
GpioCtrlRegs.GPDMUX2.bit.GPIO122 = 2;
GpioCtrlRegs.GPDMUX2.bit.GPIO123 = 2;
GpioCtrlRegs.GPDMUX2.bit.GPIO124 = 2;
GpioCtrlRegs.GPDDIR.bit.GPIO125 = 1;
//Set up GPIO Pull-up disables/enables
GpioCtrlRegs.GPDPUD.bit.GPIO122 = 0; //Needs to be normally pulled high
GpioCtrlRegs.GPDPUD.bit.GPIO123 = 0; //Needs to be normally pulled high
GpioCtrlRegs.GPDPUD.bit.GPIO124 = 1;
GpioCtrlRegs.GPDPUD.bit.GPIO125 = 1;
//Set up GPIOs in asynch mode
GpioCtrlRegs.GPDQSEL2.bit.GPIO122 = 3; // Asynch input
GpioCtrlRegs.GPDQSEL2.bit.GPIO123 = 3;
GpioCtrlRegs.GPDQSEL2.bit.GPIO124 = 3;
GpioCtrlRegs.GPDQSEL2.bit.GPIO125 = 3;
//Configure GPIOs for CPU1
GpioCtrlRegs.GPDCSEL4.bit.GPIO122 = 0;
GpioCtrlRegs.GPDCSEL4.bit.GPIO123 = 0;
GpioCtrlRegs.GPDCSEL4.bit.GPIO124 = 0;
GpioCtrlRegs.GPDCSEL4.bit.GPIO125 = 0;
//Lock the SD-Card SPI GPIOs
GpioCtrlRegs.GPDLOCK.bit.GPIO122 = 1;
GpioCtrlRegs.GPDLOCK.bit.GPIO123 = 1;
GpioCtrlRegs.GPDLOCK.bit.GPIO124 = 1;
GpioCtrlRegs.GPDLOCK.bit.GPIO125 = 1;
EDIS;
/* Deassert the SPIC chip selects for both the SD card and serial flash */
DESELECT();
/* Configure the SPI C port */
SpicRegs.SPICCR.bit.SPISWRESET = 0; //Set reset bit low
SpicRegs.SPICTL.bit.CLK_PHASE = 0;
SpicRegs.SPICCR.bit.CLKPOLARITY = 1;
SpicRegs.SPICTL.bit.MASTER_SLAVE = 1; //Master mode
SpicRegs.SPIBRR.all = 63; //update value to proper setting for correct bitrate ( current: ~500kHz)
SpicRegs.SPICCR.bit.SPICHAR = 0x7; //Set char length to 8 bits
SpicRegs.SPICTL.bit.TALK = 1;
SpicRegs.SPICCR.bit.SPISWRESET = 1; //Release SPI from reset
SpicRegs.SPIPRI.bit.FREE = 1;
SpicRegs.SPIPRI.bit.SOFT = 1;
/* Set DI and CS high and apply more than 74 pulses to SCLK for the card */
/* to be able to accept a native command. */
//send_initial_clock_train();
//DELAY_US(50);
PowerFlag = 1;
}
// set the SPI speed to the max setting
static
void set_max_speed(void) //EDIT
{
/* Disable the SPI*/
//DevCfgRegs.DC9.bit.SPI_C = 0;
SpicRegs.SPICCR.bit.SPISWRESET = 0; //Place in reset
/* Configure the SPI C port */
SpicRegs.SPICTL.bit.CLK_PHASE = 0;
SpicRegs.SPICCR.bit.CLKPOLARITY = 1;
SpicRegs.SPICTL.bit.MASTER_SLAVE = 1; //Set Master Mode
SpicRegs.SPIBRR.all = 1; // <- (No enforced limit)
SpicRegs.SPICCR.bit.SPICHAR = 0x7; //8 bit char length
SpicRegs.SPICTL.bit.TALK = 1;
/* Enable the SPI */
SpicRegs.SPICCR.bit.SPISWRESET = 1; //Release from reset
//DevCfgRegs.DC9.bit.SPI_C = 1;
}
static
void power_off (void)
{
PowerFlag = 0;
}
static
int chk_power(void) /* Socket power state: 0=off, 1=on */
{
return PowerFlag;
}
/*-----------------------------------------------------------------------*/
/* Receive a data packet from MMC */
/*-----------------------------------------------------------------------*/
static
BOOL rcvr_datablock (
BYTE *buff, /* Data buffer to store received data */
UINT btr /* Byte count (must be even number) */
)
{
BYTE token;
Timer1 = 10;
do /* Wait for data packet in timeout of 100ms */
{
token = rcvr_spi();
}
while ((token == 0xFF) && Timer1);
if(token != 0xFE) return FALSE; /* If not valid data token, retutn with error */
do /* Receive the data block into buffer */
{
rcvr_spi_m(buff++);
rcvr_spi_m(buff++);
}
while (btr -= 2);
rcvr_spi(); /* Discard CRC */
rcvr_spi();
return TRUE; /* Return with success */
}
/*-----------------------------------------------------------------------*/
/* Send a data packet to MMC */
/*-----------------------------------------------------------------------*/
#if _READONLY == 0
static
BOOL xmit_datablock (
const BYTE *buff, /* 512 byte data block to be transmitted */
BYTE token /* Data/Stop token */
)
{
BYTE resp, wc;
if (wait_ready() != 0xFF) return FALSE;
xmit_spi(token); /* Xmit data token */
if (token != 0xFD) /* Is data token */
{
wc = 256;
do /* Xmit the 512 byte data block to MMC */
{
xmit_spi(*buff++);
xmit_spi(*buff++);
}
while (--wc);
xmit_spi(0xFF); /* CRC (Dummy) */
xmit_spi(0xFF);
resp = rcvr_spi(); /* Reveive data response */
if ((resp & 0x1F) != 0x05) /* If not accepted, return with error */
return FALSE;
}
return TRUE;
}
#endif /* _READONLY */
/*-----------------------------------------------------------------------*/
/* Send a command packet to MMC */
/*-----------------------------------------------------------------------*/
static
BYTE send_cmd (
BYTE cmd, /* Command byte */
DWORD arg /* Argument */
)
{
BYTE n, res;
if (wait_ready() != 0xFF) return 0xFF;
/* Send command packet */
xmit_spi(cmd); /* Command */
xmit_spi((BYTE)(arg >> 24)); /* Argument[31..24] */
xmit_spi((BYTE)(arg >> 16)); /* Argument[23..16] */
xmit_spi((BYTE)(arg >> 8)); /* Argument[15..8] */
xmit_spi((BYTE)arg); /* Argument[7..0] */
n = 0;
if (cmd == CMD0) n = 0x95; /* CRC for CMD0(0) */
if (cmd == CMD8) n = 0x87; /* CRC for CMD8(0x1AA) */
xmit_spi(n);
/* Receive command response */
if (cmd == CMD12) rcvr_spi(); /* Skip a stuff byte when stop reading */
n = 10; /* Wait for a valid response in timeout of 10 attempts */
do
res = rcvr_spi();
while ((res & 0x80) && --n);
return res; /* Return with the response value */
}
/*-----------------------------------------------------------------------*
* Send the special command used to terminate a multi-sector read.
*
* This is the only command which can be sent while the SDCard is sending
* data. The SDCard spec indicates that the data transfer will stop 2 bytes
* after the 6 byte CMD12 command is sent and that the card will then send
* 0xFF for between 2 and 6 more bytes before the R1 response byte. This
* response will be followed by another 0xFF byte. In testing, however, it
* seems that some cards don't send the 2 to 6 0xFF bytes between the end of
* data transmission and the response code. This function, therefore, merely
* reads 10 bytes and, if the last one read is 0xFF, returns the value of the
* latest non-0xFF byte as the response code.
*
*-----------------------------------------------------------------------*/
static
BYTE send_cmd12 (void)
{
BYTE n, res, val;
/* For CMD12, we don't wait for the card to be idle before we send
* the new command.
*/
/* Send command packet - the argument for CMD12 is ignored. */
xmit_spi(CMD12);
xmit_spi(0);
xmit_spi(0);
xmit_spi(0);
xmit_spi(0);
xmit_spi(0);
/* Read up to 10 bytes from the card, remembering the value read if it's
not 0xFF */
for(n = 0; n < 10; n++)
{
val = rcvr_spi();
if(val != 0xFF)
{
res = val;
}
}
return res; /* Return with the response value */
}
/*--------------------------------------------------------------------------
Public Functions
---------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------*/
/* Initialize Disk Drive */
/*-----------------------------------------------------------------------*/
DSTATUS disk_initialize (
BYTE drv /* Physical drive nmuber (0) */
)
{
BYTE n, ty, ocr[4];
if (drv) return STA_NOINIT; /* Supports only single drive */
if (Stat & STA_NODISK) return Stat; /* No card in the socket */
power_on(); /* Force socket power on */
send_initial_clock_train();
SELECT(); /* CS = L */
ty = 0;
if (send_cmd(CMD0, 0) == 1) /* Enter Idle state */
{
Timer1 = 100; /* Initialization timeout of 1000 msec */
if (send_cmd(CMD8, 0x1AA) == 1) /* SDC Ver2+ */
{
for (n = 0; n < 4; n++) ocr[n] = rcvr_spi();
if (ocr[2] == 0x01 && ocr[3] == 0xAA) /* The card can work at vdd range of 2.7-3.6V */
{
do
{
if (send_cmd(CMD55, 0) <= 1 && send_cmd(CMD41, 1UL << 30) == 0) break; /* ACMD41 with HCS bit */
}
while (Timer1);
if (Timer1 && send_cmd(CMD58, 0) == 0) /* Check CCS bit */
{
for (n = 0; n < 4; n++) ocr[n] = rcvr_spi();
ty = (ocr[0] & 0x40) ? 6 : 2;
}
}
}
else /* SDC Ver1 or MMC */
{
ty = (send_cmd(CMD55, 0) <= 1 && send_cmd(CMD41, 0) <= 1) ? 2 : 1; /* SDC : MMC */
do
{
if (ty == 2)
{
if (send_cmd(CMD55, 0) <= 1 && send_cmd(CMD41, 0) == 0) break; /* ACMD41 */
}
else
{
if (send_cmd(CMD1, 0) == 0) break; /* CMD1 */
}
}
while (Timer1);
if (!Timer1 || send_cmd(CMD16, 512) != 0) /* Select R/W block length */
ty = 0;
}
}
CardType = ty;
DESELECT(); /* CS = H */
rcvr_spi(); /* Idle (Release DO) */
if (ty) /* Initialization succeded */
{
Stat &= ~STA_NOINIT; /* Clear STA_NOINIT */
set_max_speed();
}
else /* Initialization failed */
{
power_off();
}
return Stat;
}
/*-----------------------------------------------------------------------*/
/* Get Disk Status */
/*-----------------------------------------------------------------------*/
DSTATUS disk_status (
BYTE drv /* Physical drive number (0) */
)
{
if (drv) return STA_NOINIT; /* Supports only single drive */
return Stat;
}
/*-----------------------------------------------------------------------*/
/* Read Sector(s) */
/*-----------------------------------------------------------------------*/
DRESULT disk_read (
BYTE drv, /* Physical drive nmuber (0) */
BYTE *buff, /* Pointer to the data buffer to store read data */
DWORD sector, /* Start sector number (LBA) */
BYTE count /* Sector count (1..255) */
)
{
if (drv || !count) return RES_PARERR;
if (Stat & STA_NOINIT) return RES_NOTRDY;
if (!(CardType & 4)) sector *= 512; /* Convert to byte address if needed */
SELECT(); /* CS = L */
if (count == 1) /* Single block read */
{
if ((send_cmd(CMD17, sector) == 0) /* READ_SINGLE_BLOCK */
&& rcvr_datablock(buff, 512))
count = 0;
}
else /* Multiple block read */
{
if (send_cmd(CMD18, sector) == 0) /* READ_MULTIPLE_BLOCK */
{
do
{
if (!rcvr_datablock(buff, 512)) break;
buff += 512;
}
while (--count);
send_cmd12(); /* STOP_TRANSMISSION */
}
}
DESELECT(); /* CS = H */
rcvr_spi(); /* Idle (Release DO) */
return count ? RES_ERROR : RES_OK;
}
/*-----------------------------------------------------------------------*/
/* Write Sector(s) */
/*-----------------------------------------------------------------------*/
#if _READONLY == 0
DRESULT disk_write (
BYTE drv, /* Physical drive nmuber (0) */
const BYTE *buff, /* Pointer to the data to be written */
DWORD sector, /* Start sector number (LBA) */
BYTE count /* Sector count (1..255) */
)
{
if (drv || !count) return RES_PARERR;
if (Stat & STA_NOINIT) return RES_NOTRDY;
if (Stat & STA_PROTECT) return RES_WRPRT;
if (!(CardType & 4)) sector *= 512; /* Convert to byte address if needed */
SELECT(); /* CS = L */
if (count == 1) /* Single block write */
{
if ((send_cmd(CMD24, sector) == 0) /* WRITE_BLOCK */
&& xmit_datablock(buff, 0xFE))
count = 0;
}
else /* Multiple block write */
{
if (CardType & 2)
{
send_cmd(CMD55, 0);
send_cmd(CMD23, count); /* ACMD23 */
}
if (send_cmd(CMD25, sector) == 0) /* WRITE_MULTIPLE_BLOCK */
{
do
{
if (!xmit_datablock(buff, 0xFC)) break;
buff += 512;
}
while (--count);
if (!xmit_datablock(0, 0xFD)) /* STOP_TRAN token */
count = 1;
}
}
DESELECT(); /* CS = H */
rcvr_spi(); /* Idle (Release DO) */
return count ? RES_ERROR : RES_OK;
}
#endif /* _READONLY */
/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions */
/*-----------------------------------------------------------------------*/
DRESULT disk_ioctl (
BYTE drv, /* Physical drive nmuber (0) */
BYTE ctrl, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
DRESULT res;
BYTE n, csd[16], *ptr = buff;
WORD csize;
if (drv) return RES_PARERR;
res = RES_ERROR;
if (ctrl == CTRL_POWER)
{
switch (*ptr)
{
case 0: /* Sub control code == 0 (POWER_OFF) */
if (chk_power())
power_off(); /* Power off */
res = RES_OK;
break;
case 1: /* Sub control code == 1 (POWER_ON) */
power_on(); /* Power on */
res = RES_OK;
break;
case 2: /* Sub control code == 2 (POWER_GET) */
*(ptr+1) = (BYTE)chk_power();
res = RES_OK;
break;
default :
res = RES_PARERR;
}
}
else
{
if (Stat & STA_NOINIT) return RES_NOTRDY;
SELECT(); /* CS = L */
switch (ctrl)
{
case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */
if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16))
{
if ((csd[0] >> 6) == 1) /* SDC ver 2.00 */
{
csize = csd[9] + ((WORD)csd[8] << 8) + 1;
*(DWORD*)buff = (DWORD)csize << 10;
}
else /* MMC or SDC ver 1.XX */
{
n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
csize = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1;
*(DWORD*)buff = (DWORD)csize << (n - 9);
}
res = RES_OK;
}
break;
case GET_SECTOR_SIZE : /* Get sectors on the disk (WORD) */
*(WORD*)buff = 512;
res = RES_OK;
break;
case CTRL_SYNC : /* Make sure that data has been written */
if (wait_ready() == 0xFF)
res = RES_OK;
break;
case MMC_GET_CSD : /* Receive CSD as a data block (16 bytes) */
if (send_cmd(CMD9, 0) == 0 /* READ_CSD */
&& rcvr_datablock(ptr, 16))
res = RES_OK;
break;
case MMC_GET_CID : /* Receive CID as a data block (16 bytes) */
if (send_cmd(CMD10, 0) == 0 /* READ_CID */
&& rcvr_datablock(ptr, 16))
res = RES_OK;
break;
case MMC_GET_OCR : /* Receive OCR as an R3 resp (4 bytes) */
if (send_cmd(CMD58, 0) == 0) /* READ_OCR */
{
for (n = 0; n < 4; n++)
*ptr++ = rcvr_spi();
res = RES_OK;
}
// case MMC_GET_TYPE : /* Get card type flags (1 byte) */
// *ptr = CardType;
// res = RES_OK;
// break;
default:
res = RES_PARERR;
}
DESELECT(); /* CS = H */
rcvr_spi(); /* Idle (Release DO) */
}
return res;
}
/*-----------------------------------------------------------------------*/
/* Device Timer Interrupt Procedure (Platform dependent) */
/*-----------------------------------------------------------------------*/
/* This function must be called in period of 10ms */
void disk_timerproc (void)
{
// BYTE n, s;
BYTE n;
n = Timer1; /* 100Hz decrement timer */
if (n) Timer1 = --n;
n = Timer2;
if (n) Timer2 = --n;
}
/*---------------------------------------------------------*/
/* User Provided Timer Function for FatFs module */
/*---------------------------------------------------------*/
/* This is a real time clock service to be called from */
/* FatFs module. Any valid time must be returned even if */
/* the system does not support a real time clock. */
DWORD get_fattime (void)
{
return ((2008UL-1980) << 25) // Year = 2008
| (2UL << 21) // Month = February
| (26UL << 16) // Day = 26
| (14U << 11) // Hour = 14
| (0U << 5) // Min = 0
| (0U >> 1) // Sec = 0
;
}
@@ -0,0 +1,561 @@
/*-----------------------------------------------------------------------*/
/* MMC/SDC (in SPI mode) control module (C)ChaN, 2007 */
/*-----------------------------------------------------------------------*/
/* Only rcvr_spi(), xmit_spi(), disk_timerproc() and some macros */
/* are platform dependent. */
/*-----------------------------------------------------------------------*/
#include <avr/io.h>
#include "diskio.h"
/* Definitions for MMC/SDC command */
#define CMD0 (0x40+0) /* GO_IDLE_STATE */
#define CMD1 (0x40+1) /* SEND_OP_COND */
#define CMD8 (0x40+8) /* SEND_IF_COND */
#define CMD9 (0x40+9) /* SEND_CSD */
#define CMD10 (0x40+10) /* SEND_CID */
#define CMD12 (0x40+12) /* STOP_TRANSMISSION */
#define CMD16 (0x40+16) /* SET_BLOCKLEN */
#define CMD17 (0x40+17) /* READ_SINGLE_BLOCK */
#define CMD18 (0x40+18) /* READ_MULTIPLE_BLOCK */
#define CMD23 (0x40+23) /* SET_BLOCK_COUNT */
#define CMD24 (0x40+24) /* WRITE_BLOCK */
#define CMD25 (0x40+25) /* WRITE_MULTIPLE_BLOCK */
#define CMD41 (0x40+41) /* SEND_OP_COND (ACMD) */
#define CMD55 (0x40+55) /* APP_CMD */
#define CMD58 (0x40+58) /* READ_OCR */
/* Port Controls (Platform dependent) */
#define SELECT() PORTB &= ~1 /* MMC CS = L */
#define DESELECT() PORTB |= 1 /* MMC CS = H */
#define SOCKPORT PINB /* Socket contact port */
#define SOCKWP 0x20 /* Write protect switch (PB5) */
#define SOCKINS 0x10 /* Card detect switch (PB4) */
/*--------------------------------------------------------------------------
Module Private Functions
---------------------------------------------------------------------------*/
static volatile
DSTATUS Stat = STA_NOINIT; /* Disk status */
static volatile
BYTE Timer1, Timer2; /* 100Hz decrement timer */
static
BYTE CardType; /* b0:MMC, b1:SDC, b2:Block addressing */
/*-----------------------------------------------------------------------*/
/* Transmit a byte to MMC via SPI (Platform dependent) */
/*-----------------------------------------------------------------------*/
#define xmit_spi(dat) SPDR=(dat); loop_until_bit_is_set(SPSR,SPIF)
/*-----------------------------------------------------------------------*/
/* Receive a byte from MMC via SPI (Platform dependent) */
/*-----------------------------------------------------------------------*/
static
BYTE rcvr_spi (void)
{
SPDR = 0xFF;
loop_until_bit_is_set(SPSR, SPIF);
return SPDR;
}
/* Alternative macro to receive data fast */
#define rcvr_spi_m(dst) SPDR=0xFF; loop_until_bit_is_set(SPSR,SPIF); *(dst)=SPDR
/*-----------------------------------------------------------------------*/
/* Wait for card ready */
/*-----------------------------------------------------------------------*/
static
BYTE wait_ready (void)
{
BYTE res;
Timer2 = 50; /* Wait for ready in timeout of 500ms */
rcvr_spi();
do
res = rcvr_spi();
while ((res != 0xFF) && Timer2);
return res;
}
/*-----------------------------------------------------------------------*/
/* Power Control (Platform dependent) */
/*-----------------------------------------------------------------------*/
/* When the target system does not support socket power control, there */
/* is nothing to do in these functions and chk_power always returns 1. */
static
void power_on (void)
{
PORTE &= ~0x80; /* Socket power ON */
for (Timer1 = 3; Timer1; ); /* Wait for 30ms */
PORTB = 0b10110101; /* Enable drivers */
DDRB = 0b11000111;
SPCR = 0b01010000; /* Initialize SPI port (Mode 0) */
SPSR = 0b00000001;
}
static
void power_off (void)
{
SELECT(); /* Wait for card ready */
wait_ready();
DESELECT();
rcvr_spi();
SPCR = 0; /* Disable SPI function */
DDRB = 0b11000000; /* Disable drivers */
PORTB = 0b10110000;
PORTE |= 0x80; /* Socket power OFF */
Stat |= STA_NOINIT; /* Set STA_NOINIT */
}
static
int chk_power(void) /* Socket power state: 0=off, 1=on */
{
return (PORTE & 0x80) ? 0 : 1;
}
/*-----------------------------------------------------------------------*/
/* Receive a data packet from MMC */
/*-----------------------------------------------------------------------*/
static
BOOL rcvr_datablock (
BYTE *buff, /* Data buffer to store received data */
UINT btr /* Byte count (must be even number) */
)
{
BYTE token;
Timer1 = 10;
do { /* Wait for data packet in timeout of 100ms */
token = rcvr_spi();
} while ((token == 0xFF) && Timer1);
if(token != 0xFE) return FALSE; /* If not valid data token, retutn with error */
do { /* Receive the data block into buffer */
rcvr_spi_m(buff++);
rcvr_spi_m(buff++);
} while (btr -= 2);
rcvr_spi(); /* Discard CRC */
rcvr_spi();
return TRUE; /* Return with success */
}
/*-----------------------------------------------------------------------*/
/* Send a data packet to MMC */
/*-----------------------------------------------------------------------*/
#if _READONLY == 0
static
BOOL xmit_datablock (
const BYTE *buff, /* 512 byte data block to be transmitted */
BYTE token /* Data/Stop token */
)
{
BYTE resp, wc;
if (wait_ready() != 0xFF) return FALSE;
xmit_spi(token); /* Xmit data token */
if (token != 0xFD) { /* Is data token */
wc = 0;
do { /* Xmit the 512 byte data block to MMC */
xmit_spi(*buff++);
xmit_spi(*buff++);
} while (--wc);
xmit_spi(0xFF); /* CRC (Dummy) */
xmit_spi(0xFF);
resp = rcvr_spi(); /* Reveive data response */
if ((resp & 0x1F) != 0x05) /* If not accepted, return with error */
return FALSE;
}
return TRUE;
}
#endif /* _READONLY */
/*-----------------------------------------------------------------------*/
/* Send a command packet to MMC */
/*-----------------------------------------------------------------------*/
static
BYTE send_cmd (
BYTE cmd, /* Command byte */
DWORD arg /* Argument */
)
{
BYTE n, res;
if (wait_ready() != 0xFF) return 0xFF;
/* Send command packet */
xmit_spi(cmd); /* Command */
xmit_spi((BYTE)(arg >> 24)); /* Argument[31..24] */
xmit_spi((BYTE)(arg >> 16)); /* Argument[23..16] */
xmit_spi((BYTE)(arg >> 8)); /* Argument[15..8] */
xmit_spi((BYTE)arg); /* Argument[7..0] */
n = 0;
if (cmd == CMD0) n = 0x95; /* CRC for CMD0(0) */
if (cmd == CMD8) n = 0x87; /* CRC for CMD8(0x1AA) */
xmit_spi(n);
/* Receive command response */
if (cmd == CMD12) rcvr_spi(); /* Skip a stuff byte when stop reading */
n = 10; /* Wait for a valid response in timeout of 10 attempts */
do
res = rcvr_spi();
while ((res & 0x80) && --n);
return res; /* Return with the response value */
}
/*--------------------------------------------------------------------------
Public Functions
---------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------*/
/* Initialize Disk Drive */
/*-----------------------------------------------------------------------*/
DSTATUS disk_initialize (
BYTE drv /* Physical drive nmuber (0) */
)
{
BYTE n, ty, ocr[4];
if (drv) return STA_NOINIT; /* Supports only single drive */
if (Stat & STA_NODISK) return Stat; /* No card in the socket */
power_on(); /* Force socket power on */
for (n = 10; n; n--) rcvr_spi(); /* 80 dummy clocks */
SELECT(); /* CS = L */
ty = 0;
if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */
Timer1 = 100; /* Initialization timeout of 1000 msec */
if (send_cmd(CMD8, 0x1AA) == 1) { /* SDC Ver2+ */
for (n = 0; n < 4; n++) ocr[n] = rcvr_spi();
if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */
do {
if (send_cmd(CMD55, 0) <= 1 && send_cmd(CMD41, 1UL << 30) == 0) break; /* ACMD41 with HCS bit */
} while (Timer1);
if (Timer1 && send_cmd(CMD58, 0) == 0) { /* Check CCS bit */
for (n = 0; n < 4; n++) ocr[n] = rcvr_spi();
ty = (ocr[0] & 0x40) ? 6 : 2;
}
}
} else { /* SDC Ver1 or MMC */
ty = (send_cmd(CMD55, 0) <= 1 && send_cmd(CMD41, 0) <= 1) ? 2 : 1; /* SDC : MMC */
do {
if (ty == 2) {
if (send_cmd(CMD55, 0) <= 1 && send_cmd(CMD41, 0) == 0) break; /* ACMD41 */
} else {
if (send_cmd(CMD1, 0) == 0) break; /* CMD1 */
}
} while (Timer1);
if (!Timer1 || send_cmd(CMD16, 512) != 0) /* Select R/W block length */
ty = 0;
}
}
CardType = ty;
DESELECT(); /* CS = H */
rcvr_spi(); /* Idle (Release DO) */
if (ty) { /* Initialization succeded */
Stat &= ~STA_NOINIT; /* Clear STA_NOINIT */
} else { /* Initialization failed */
power_off();
}
return Stat;
}
/*-----------------------------------------------------------------------*/
/* Get Disk Status */
/*-----------------------------------------------------------------------*/
DSTATUS disk_status (
BYTE drv /* Physical drive nmuber (0) */
)
{
if (drv) return STA_NOINIT; /* Supports only single drive */
return Stat;
}
/*-----------------------------------------------------------------------*/
/* Read Sector(s) */
/*-----------------------------------------------------------------------*/
DRESULT disk_read (
BYTE drv, /* Physical drive nmuber (0) */
BYTE *buff, /* Pointer to the data buffer to store read data */
DWORD sector, /* Start sector number (LBA) */
BYTE count /* Sector count (1..255) */
)
{
if (drv || !count) return RES_PARERR;
if (Stat & STA_NOINIT) return RES_NOTRDY;
if (!(CardType & 4)) sector *= 512; /* Convert to byte address if needed */
SELECT(); /* CS = L */
if (count == 1) { /* Single block read */
if ((send_cmd(CMD17, sector) == 0) /* READ_SINGLE_BLOCK */
&& rcvr_datablock(buff, 512))
count = 0;
}
else { /* Multiple block read */
if (send_cmd(CMD18, sector) == 0) { /* READ_MULTIPLE_BLOCK */
do {
if (!rcvr_datablock(buff, 512)) break;
buff += 512;
} while (--count);
send_cmd(CMD12, 0); /* STOP_TRANSMISSION */
}
}
DESELECT(); /* CS = H */
rcvr_spi(); /* Idle (Release DO) */
return count ? RES_ERROR : RES_OK;
}
/*-----------------------------------------------------------------------*/
/* Write Sector(s) */
/*-----------------------------------------------------------------------*/
#if _READONLY == 0
DRESULT disk_write (
BYTE drv, /* Physical drive nmuber (0) */
const BYTE *buff, /* Pointer to the data to be written */
DWORD sector, /* Start sector number (LBA) */
BYTE count /* Sector count (1..255) */
)
{
if (drv || !count) return RES_PARERR;
if (Stat & STA_NOINIT) return RES_NOTRDY;
if (Stat & STA_PROTECT) return RES_WRPRT;
if (!(CardType & 4)) sector *= 512; /* Convert to byte address if needed */
SELECT(); /* CS = L */
if (count == 1) { /* Single block write */
if ((send_cmd(CMD24, sector) == 0) /* WRITE_BLOCK */
&& xmit_datablock(buff, 0xFE))
count = 0;
}
else { /* Multiple block write */
if (CardType & 2) {
send_cmd(CMD55, 0); send_cmd(CMD23, count); /* ACMD23 */
}
if (send_cmd(CMD25, sector) == 0) { /* WRITE_MULTIPLE_BLOCK */
do {
if (!xmit_datablock(buff, 0xFC)) break;
buff += 512;
} while (--count);
if (!xmit_datablock(0, 0xFD)) /* STOP_TRAN token */
count = 1;
}
}
DESELECT(); /* CS = H */
rcvr_spi(); /* Idle (Release DO) */
return count ? RES_ERROR : RES_OK;
}
#endif /* _READONLY */
/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions */
/*-----------------------------------------------------------------------*/
DRESULT disk_ioctl (
BYTE drv, /* Physical drive nmuber (0) */
BYTE ctrl, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
DRESULT res;
BYTE n, csd[16], *ptr = buff;
WORD csize;
if (drv) return RES_PARERR;
res = RES_ERROR;
if (ctrl == CTRL_POWER) {
switch (*ptr) {
case 0: /* Sub control code == 0 (POWER_OFF) */
if (chk_power())
power_off(); /* Power off */
res = RES_OK;
break;
case 1: /* Sub control code == 1 (POWER_ON) */
power_on(); /* Power on */
res = RES_OK;
break;
case 2: /* Sub control code == 2 (POWER_GET) */
*(ptr+1) = (BYTE)chk_power();
res = RES_OK;
break;
default :
res = RES_PARERR;
}
}
else {
if (Stat & STA_NOINIT) return RES_NOTRDY;
SELECT(); /* CS = L */
switch (ctrl) {
case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */
if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) {
if ((csd[0] >> 6) == 1) { /* SDC ver 2.00 */
csize = csd[9] + ((WORD)csd[8] << 8) + 1;
*(DWORD*)buff = (DWORD)csize << 10;
} else { /* MMC or SDC ver 1.XX */
n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
csize = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1;
*(DWORD*)buff = (DWORD)csize << (n - 9);
}
res = RES_OK;
}
break;
case GET_SECTOR_SIZE : /* Get sectors on the disk (WORD) */
*(WORD*)buff = 512;
res = RES_OK;
break;
case CTRL_SYNC : /* Make sure that data has been written */
if (wait_ready() == 0xFF)
res = RES_OK;
break;
case MMC_GET_CSD : /* Receive CSD as a data block (16 bytes) */
if (send_cmd(CMD9, 0) == 0 /* READ_CSD */
&& rcvr_datablock(ptr, 16))
res = RES_OK;
break;
case MMC_GET_CID : /* Receive CID as a data block (16 bytes) */
if (send_cmd(CMD10, 0) == 0 /* READ_CID */
&& rcvr_datablock(ptr, 16))
res = RES_OK;
break;
case MMC_GET_OCR : /* Receive OCR as an R3 resp (4 bytes) */
if (send_cmd(CMD58, 0) == 0) { /* READ_OCR */
for (n = 0; n < 4; n++)
*ptr++ = rcvr_spi();
res = RES_OK;
}
case MMC_GET_TYPE : /* Get card type flags (1 byte) */
*ptr = CardType;
res = RES_OK;
break;
default:
res = RES_PARERR;
}
DESELECT(); /* CS = H */
rcvr_spi(); /* Idle (Release DO) */
}
return res;
}
/*-----------------------------------------------------------------------*/
/* Device Timer Interrupt Procedure (Platform dependent) */
/*-----------------------------------------------------------------------*/
/* This function must be called in period of 10ms */
void disk_timerproc (void)
{
static BYTE pv;
BYTE n, s;
n = Timer1; /* 100Hz decrement timer */
if (n) Timer1 = --n;
n = Timer2;
if (n) Timer2 = --n;
n = pv;
pv = SOCKPORT & (SOCKWP | SOCKINS); /* Sample socket switch */
if (n == pv) { /* Have contacts stabled? */
s = Stat;
if (pv & SOCKWP) /* WP is H (write protected) */
s |= STA_PROTECT;
else /* WP is L (write enabled) */
s &= ~STA_PROTECT;
if (pv & SOCKINS) /* INS = H (Socket empty) */
s |= (STA_NODISK | STA_NOINIT);
else /* INS = L (Card inserted) */
s &= ~STA_NODISK;
Stat = s;
}
}
@@ -0,0 +1,158 @@
FatFs/Tiny-FatFs Module Source Files R0.04b (C)ChaN, 2007
FILES
ff.h Common include file for FatFs and application module.
ff.c FatFs module.
tff.h Common include file for Tiny-FatFs and application module.
tff.c Tiny-FatFs module.
diskio.h Common include file for (Tiny-)FatFs and disk I/O module.
integer.h Alternative type definitions for integer variables.
Low level disk I/O module is not included in this archive because the
FatFs/Tiny-FatFs module is only a generic file system layer and not depend
on any specific storage device. You have to provide a low level disk I/O
module that written to control your storage device.
CONFIGURATION OPTIONS
There are several configuration options for various envilonment and
requirement. The configuration options are defined in header files, ff.h
and tff.h.
_MCU_ENDIAN
This is the most impotant option that depends on the processor architecture.
When the target device corresponds to either or both of following terms, the
_MCU_ENDIAN must be set to 2 to force FatFs to access FAT structure in
byte-by-byte.
- Muti-byte integers (short, long) are stored in Big-Endian.
- Address miss-aligned memory access results in an incorrect behavior.
If not the case, this can be set to 1 for good code efficiency. The initial
value is 0. (must be set to 1 or 2 properly)
_FS_READONLY
When application program does not require any write function, _FS_READONLY
can be set to 1 to eliminate writing code to reduce the module size. This
setting should be reflected to configurations of low level disk I/O module
if available. The initial value is 0. (Read and Write)
_FS_MINIMIZE
When application program requires only file read/write function, _FS_MINIMIZE
can be changed to eliminate some functions to reduce the module size. The
initial value is 0. (full function)
_DRIVES
Number of drives to be used. This option is not available on Tiny-FatFs.
The initial value is 2.
_FAT32
When _FAT32 is set to 1, the FAT32 support is added with an additional
code size. This option is for only Tiny-FatFs. FatFs always supports all
FAT sub-types. The initial value is 0. (no FAT32 support)
_USE_FSINFO
When _USE_FSINFO is set to 1, FSInfo is used for FAT32 volume.
_USE_SJIS
When _USE_SJIS is set to 1, Shift_JIS code set can be used as a file name,
otherwire second byte of double-byte characters will be collapted.
The initial value is 1.
_USE_NTFLAG
When _USE_NTFLAG is set to 1, upper/lower case of the file/dir name is
preserved. Note that the files are always accessed in case insensitive.
_USE_MKFS
When _USE_MKFS is set to 1 and _FS_READONLY is set to 0, f_mkfs function
is enabled. This is for only FatFs module and not supported on Tiny-FatFs.
The initial value is 0. (f_mkfs is not available)
Following table shows which function is removed by configuratin options.
_FS_MINIMIZE _FS_READONLY _USE_MKFS
(1) (2) (3) (1) (0)
f_mount
f_open
f_close
f_read
f_write x
f_sync x
f_lseek x
f_opendir x x
f_readdir x x
f_stat x x x
f_getfree x x x x
f_unlink x x x x
f_mkdir x x x x
f_chmod x x x x
f_rename x x x x
f_mkfs x x x x x
AGREEMENTS
The FatFs/Tiny-FatFs module is a free software and there is no warranty.
The FatFs/Tiny-FatFs module is opened for education, reserch and development.
You can use and/or modify it for personal, non-profit or profit use without
any restriction under your responsibility.
REVISION HISTORY
Feb 26, 2006 R0.00 Prototype
Apr 29, 2006 R0.01 First release.
Jun 01, 2006 R0.02 Added FAT12.
Removed unbuffered mode.
Fixed a problem on small (<32M) patition.
Jun 10, 2006 R0.02a Added a configuration option _FS_MINIMUM.
Sep 22, 2006 R0.03 Added f_rename().
Changed option _FS_MINIMUM to _FS_MINIMIZE.
Dec 11, 2006 R0.03a Improved cluster scan algolithm to write files fast.
Fixed f_mkdir() creates incorrect directory on FAT32.
Feb 04, 2007 R0.04 Supported multiple drive system. (FatFs)
Changed some APIs for multiple drive system.
Added f_mkfs(). (FatFs)
Added _USE_FAT32 option. (Tiny-FatFs)
Apr 01, 2007 R0.04a Supported multiple partitions on a plysical drive. (FatFs)
Fixed an endian sensitive code in f_mkfs(). (FatFs)
Added a capability of extending the file size to f_lseek().
Added minimization level 3.
Fixed a problem that can collapse a sector when recreate an
existing file in any sub-directory at non FAT32 cfg. (Tiny-FatFs)
May 05, 2007 R0.04b Added _USE_NTFLAG option.
Added FSInfo support.
Fixed some problems corresponds to FAT32. (Tiny-FatFs)
Fixed DBCS name can result FR_INVALID_NAME.
Fixed short seek (<= csize) collapses the file object.
@@ -0,0 +1,66 @@
/*-----------------------------------------------------------------------
/ Low level disk interface modlue include file R0.04a (C)ChaN, 2007
/-----------------------------------------------------------------------*/
#ifndef _DISKIO
#define _READONLY 0 /* 1: Read-only mode */
#include "integer.h"
/* Status of Disk Functions */
typedef BYTE DSTATUS;
/* Results of Disk Functions */
typedef enum {
RES_OK = 0, /* 0: Successful */
RES_ERROR, /* 1: R/W Error */
RES_WRPRT, /* 2: Write Protected */
RES_NOTRDY, /* 3: Not Ready */
RES_PARERR /* 4: Invalid Parameter */
} DRESULT;
/*---------------------------------------*/
/* Prototypes for disk control functions */
DSTATUS disk_initialize (BYTE);
DSTATUS disk_status (BYTE);
DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE);
#if _READONLY == 0
DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE);
#endif
DRESULT disk_ioctl (BYTE, BYTE, void*);
void disk_timerproc (void);
/* Disk Status Bits (DSTATUS) */
#define STA_NOINIT 0x01 /* Drive not initialized */
#define STA_NODISK 0x02 /* No medium in the drive */
#define STA_PROTECT 0x04 /* Write protected */
/* Command code for disk_ioctrl() */
#define GET_SECTOR_COUNT 1
#define GET_SECTOR_SIZE 2
#define CTRL_SYNC 3
#define CTRL_POWER 4
#define CTRL_LOCK 5
#define CTRL_EJECT 6
#define MMC_GET_CSD 10
#define MMC_GET_CID 11
#define MMC_GET_OCR 12
#define ATA_GET_REV 20
#define ATA_GET_MODEL 21
#define ATA_GET_SN 22
#define _DISKIO
#endif
File diff suppressed because it is too large Load Diff
+331
View File
@@ -0,0 +1,331 @@
/*--------------------------------------------------------------------------/
/ FatFs - FAT file system module include file R0.04b (C)ChaN, 2007
/---------------------------------------------------------------------------/
/ FatFs module is an experimenal project to implement FAT file system to
/ cheap microcontrollers. This is a free software and is opened for education,
/ research and development under license policy of following trems.
/
/ Copyright (C) 2007, ChaN, all right reserved.
/
/ * The FatFs module is a free software and there is no warranty.
/ * You can use, modify and/or redistribute it for personal, non-profit or
/ profit use without any restriction under your responsibility.
/ * Redistributions of source code must retain the above copyright notice.
/
/---------------------------------------------------------------------------*/
#ifndef _FATFS
#define _MCU_ENDIAN 2
/* The _MCU_ENDIAN defines which access method is used to the FAT structure.
/ 1: Enable word access.
/ 2: Disable word access and use byte-by-byte access instead.
/ When the architectural byte order of the MCU is big-endian and/or address
/ miss-aligned access is prohibited, the _MCU_ENDIAN must be set to 2.
/ If it is not the case, it can be set to 1 for good code efficiency. */
#define _FS_READONLY 0
/* Setting _FS_READONLY to 1 defines read only configuration. This removes
/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename
/ and useless f_getfree. */
#define _FS_MINIMIZE 0
/* The _FS_MINIMIZE option defines minimization level to remove some functions.
/ 0: Full function.
/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod and f_rename are removed.
/ 2: f_opendir and f_readdir are removed in addition to level 1.
/ 3: f_lseek is removed in addition to level 2. */
#define _DRIVES 2
/* Number of logical drives to be used. This affects the size of internal table. */
#define _USE_MKFS 0
/* When _USE_MKFS is set to 1 and _FS_READONLY is set to 0, f_mkfs function is
/ enabled. */
#define _MULTI_PARTITION 0
/* When _MULTI_PARTITION is set to 0, each logical drive is bound to same
/ physical drive number and can mount only 1st primaly partition. When it is
/ set to 1, each logical drive can mount a partition listed in Drives[]. */
#define _USE_FSINFO 0
/* To enable FSInfo support on FAT32 volume, set _USE_FSINFO to 1. */
#define _USE_SJIS 1
/* When _USE_SJIS is set to 1, Shift-JIS code transparency is enabled, otherwise
/ only US-ASCII(7bit) code can be accepted as file/directory name. */
#define _USE_NTFLAG 1
/* When _USE_NTFLAG is set to 1, upper/lower case of the file name is preserved.
/ Note that the files are always accessed in case insensitive. */
#include "integer.h"
/* Definitions corresponds to multiple sector size (not tested) */
#define S_MAX_SIZ 512 /* Do not change */
#if S_MAX_SIZ > 512
#define S_SIZ (fs->s_size)
#else
#define S_SIZ 512
#endif
/* File system object structure */
typedef struct _FATFS {
WORD id; /* File system mount ID */
WORD n_rootdir; /* Number of root directory entries */
DWORD winsect; /* Current sector appearing in the win[] */
DWORD sects_fat; /* Sectors per fat */
DWORD max_clust; /* Maximum cluster# + 1 */
DWORD fatbase; /* FAT start sector */
DWORD dirbase; /* Root directory start sector (cluster# for FAT32) */
DWORD database; /* Data start sector */
#if !_FS_READONLY
DWORD last_clust; /* Last allocated cluster */
DWORD free_clust; /* Number of free clusters */
#if _USE_FSINFO
DWORD fsi_sector; /* fsinfo sector */
BYTE fsi_flag; /* fsinfo dirty flag (1:must be written back) */
BYTE pad2;
#endif
#endif
BYTE fs_type; /* FAT sub type */
BYTE sects_clust; /* Sectors per cluster */
#if S_MAX_SIZ > 512
WORD s_size; /* Sector size */
#endif
BYTE n_fats; /* Number of FAT copies */
BYTE drive; /* Physical drive number */
BYTE winflag; /* win[] dirty flag (1:must be written back) */
BYTE pad1;
BYTE win[S_MAX_SIZ]; /* Disk access window for Directory/FAT */
} FATFS;
/* Directory object structure */
typedef struct _DIR {
WORD id; /* Owner file system mount ID */
WORD index; /* Current index */
FATFS* fs; /* Pointer to the owner file system object */
DWORD sclust; /* Start cluster */
DWORD clust; /* Current cluster */
DWORD sect; /* Current sector */
} DIR;
/* File object structure */
typedef struct _FIL {
WORD id; /* Owner file system mount ID */
BYTE flag; /* File status flags */
BYTE sect_clust; /* Left sectors in cluster */
FATFS* fs; /* Pointer to the owner file system object */
DWORD fptr; /* File R/W pointer */
DWORD fsize; /* File size */
DWORD org_clust; /* File start cluster */
DWORD curr_clust; /* Current cluster */
DWORD curr_sect; /* Current sector */
#if _FS_READONLY == 0
DWORD dir_sect; /* Sector containing the directory entry */
BYTE* dir_ptr; /* Ponter to the directory entry in the window */
#endif
BYTE buffer[S_MAX_SIZ]; /* File R/W buffer */
} FIL;
/* File status structure */
typedef struct _FILINFO {
DWORD fsize; /* Size */
WORD fdate; /* Date */
WORD ftime; /* Time */
BYTE fattrib; /* Attribute */
char fname[8+1+3+1]; /* Name (8.3 format) */
} FILINFO;
/* Definitions corresponds to multi partition */
#if _MULTI_PARTITION != 0 /* Multiple partition cfg */
typedef struct _PARTITION {
BYTE pd; /* Physical drive # (0-255) */
BYTE pt; /* Partition # (0-3) */
} PARTITION;
extern
const PARTITION Drives[]; /* Logical drive# to physical location conversion table */
#define LD2PD(drv) (Drives[drv].pd) /* Get physical drive# */
#define LD2PT(drv) (Drives[drv].pt) /* Get partition# */
#else /* Single partition cfg */
#define LD2PD(drv) (drv) /* Physical drive# is equal to logical drive# */
#define LD2PT(drv) 0 /* Always mounts the 1st partition */
#endif
/* File function return code (FRESULT) */
typedef enum {
FR_OK = 0, /* 0 */
FR_NOT_READY, /* 1 */
FR_NO_FILE, /* 2 */
FR_NO_PATH, /* 3 */
FR_INVALID_NAME, /* 4 */
FR_INVALID_DRIVE, /* 5 */
FR_DENIED, /* 6 */
FR_EXIST, /* 7 */
FR_RW_ERROR, /* 8 */
FR_WRITE_PROTECTED, /* 9 */
FR_NOT_ENABLED, /* 10 */
FR_NO_FILESYSTEM, /* 11 */
FR_INVALID_OBJECT, /* 12 */
FR_MKFS_ABORTED /* 13 */
} FRESULT;
/*-----------------------------------------------------*/
/* FatFs module application interface */
FRESULT f_mount (BYTE, FATFS*); /* Mount/Unmount a logical drive */
FRESULT f_open (FIL*, const char*, BYTE); /* Open or create a file */
FRESULT f_read (FIL*, void*, WORD, WORD*); /* Read data from a file */
FRESULT f_write (FIL*, const void*, WORD, WORD*); /* Write data to a file */
FRESULT f_lseek (FIL*, DWORD); /* Move file pointer of a file object */
FRESULT f_close (FIL*); /* Close an open file object */
FRESULT f_opendir (DIR*, const char*); /* Open an existing directory */
FRESULT f_readdir (DIR*, FILINFO*); /* Read a directory item */
FRESULT f_stat (const char*, FILINFO*); /* Get file status */
FRESULT f_getfree (const char*, DWORD*, FATFS**); /* Get number of free clusters on the drive */
FRESULT f_sync (FIL*); /* Flush cached data of a writing file */
FRESULT f_unlink (const char*); /* Delete an existing file or directory */
FRESULT f_mkdir (const char*); /* Create a new directory */
FRESULT f_chmod (const char*, BYTE, BYTE); /* Change file/dir attriburte */
FRESULT f_rename (const char*, const char*); /* Rename/Move a file or directory */
FRESULT f_mkfs (BYTE, BYTE, BYTE); /* Create a file system on the drive */
/* User defined function to give a current time to fatfs module */
DWORD get_fattime (void); /* 31-25: Year(0-127 org.1980), 24-21: Month(1-12), 20-16: Day(1-31) */
/* 15-11: Hour(0-23), 10-5: Minute(0-59), 4-0: Second(0-29 *2) */
/* File access control and file status flags (FIL.flag) */
#define FA_READ 0x01
#define FA_OPEN_EXISTING 0x00
#if _FS_READONLY == 0
#define FA_WRITE 0x02
#define FA_CREATE_NEW 0x04
#define FA_CREATE_ALWAYS 0x08
#define FA_OPEN_ALWAYS 0x10
#define FA__WRITTEN 0x20
#define FA__DIRTY 0x40
#endif
#define FA__ERROR 0x80
/* FAT sub type (FATFS.fs_type) */
#define FS_FAT12 1
#define FS_FAT16 2
#define FS_FAT32 3
/* File attribute bits for directory entry */
#define AM_RDO 0x01 /* Read only */
#define AM_HID 0x02 /* Hidden */
#define AM_SYS 0x04 /* System */
#define AM_VOL 0x08 /* Volume label */
#define AM_LFN 0x0F /* LFN entry */
#define AM_DIR 0x10 /* Directory */
#define AM_ARC 0x20 /* Archive */
/* Offset of FAT structure members */
#define BS_jmpBoot 0
#define BS_OEMName 3
#define BPB_BytsPerSec 11
#define BPB_SecPerClus 13
#define BPB_RsvdSecCnt 14
#define BPB_NumFATs 16
#define BPB_RootEntCnt 17
#define BPB_TotSec16 19
#define BPB_Media 21
#define BPB_FATSz16 22
#define BPB_SecPerTrk 24
#define BPB_NumHeads 26
#define BPB_HiddSec 28
#define BPB_TotSec32 32
#define BS_55AA 510
#define BS_DrvNum 36
#define BS_BootSig 38
#define BS_VolID 39
#define BS_VolLab 43
#define BS_FilSysType 54
#define BPB_FATSz32 36
#define BPB_ExtFlags 40
#define BPB_FSVer 42
#define BPB_RootClus 44
#define BPB_FSInfo 48
#define BPB_BkBootSec 50
#define BS_DrvNum32 64
#define BS_BootSig32 66
#define BS_VolID32 67
#define BS_VolLab32 71
#define BS_FilSysType32 82
#define FSI_LeadSig 0
#define FSI_StrucSig 484
#define FSI_Free_Count 488
#define FSI_Nxt_Free 492
#define MBR_Table 446
#define DIR_Name 0
#define DIR_Attr 11
#define DIR_NTres 12
#define DIR_CrtTime 14
#define DIR_CrtDate 16
#define DIR_FstClusHI 20
#define DIR_WrtTime 22
#define DIR_WrtDate 24
#define DIR_FstClusLO 26
#define DIR_FileSize 28
/* Multi-byte word access macros */
#if _MCU_ENDIAN == 1 /* Use word access */
#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr))
#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr))
#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val)
#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val)
#else
#if _MCU_ENDIAN == 2 /* Use byte-by-byte access */
#define LD_WORD(ptr) (WORD)(((WORD)*(BYTE*)((ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))
#define LD_DWORD(ptr) (DWORD)(((DWORD)*(BYTE*)((ptr)+3)<<24)|((DWORD)*(BYTE*)((ptr)+2)<<16)|((WORD)*(BYTE*)((ptr)+1)<<8)|*(BYTE*)(ptr))
#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8)
#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8); *(BYTE*)((ptr)+2)=(BYTE)((DWORD)(val)>>16); *(BYTE*)((ptr)+3)=(BYTE)((DWORD)(val)>>24)
#else
#error Do not forget to set _MCU_ENDIAN properly!
#endif
#endif
#define _FATFS
#endif /* _FATFS */
@@ -0,0 +1,29 @@
#ifndef _INTEGER
typedef signed int INT;
typedef unsigned int UINT;
/* These types are assumed as 8-bit integer */
typedef signed char CHAR;
typedef unsigned char UCHAR;
typedef unsigned char BYTE;
/* These types are assumed as 16-bit integer */
typedef signed short SHORT;
typedef unsigned short USHORT;
typedef unsigned short WORD;
/* These types are assumed as 32-bit integer */
typedef signed long LONG;
typedef unsigned long ULONG;
typedef unsigned long DWORD;
#ifndef TRUE
/* Boolean type */
typedef enum { FALSE = 0, TRUE } BOOL;
#endif
#define _INTEGER
#endif
File diff suppressed because it is too large Load Diff
+292
View File
@@ -0,0 +1,292 @@
/*--------------------------------------------------------------------------/
/ Tiny-FatFs - FAT file system module include file R0.04b (C)ChaN, 2007
/---------------------------------------------------------------------------/
/ FatFs module is an experimenal project to implement FAT file system to
/ cheap microcontrollers. This is a free software and is opened for education,
/ research and development under license policy of following trems.
/
/ Copyright (C) 2007, ChaN, all right reserved.
/
/ * The FatFs module is a free software and there is no warranty.
/ * You can use, modify and/or redistribute it for personal, non-profit or
/ profit use without any restriction under your responsibility.
/ * Redistributions of source code must retain the above copyright notice.
/
/---------------------------------------------------------------------------*/
#ifndef _FATFS
#define _MCU_ENDIAN 0
/* The _MCU_ENDIAN defines which access method is used to the FAT structure.
/ 1: Enable word access.
/ 2: Disable word access and use byte-by-byte access instead.
/ When the architectural byte order of the MCU is big-endian and/or address
/ miss-aligned access is prohibited, the _MCU_ENDIAN must be set to 2.
/ If it is not the case, it can be set to 1 for good code efficiency. */
#define _FS_READONLY 0
/* Setting _FS_READONLY to 1 defines read only configuration. This removes
/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename
/ and useless f_getfree. */
#define _FS_MINIMIZE 0
/* The _FS_MINIMIZE option defines minimization level to remove some functions.
/ 0: Full function.
/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod and f_rename are removed.
/ 2: f_opendir and f_readdir are removed in addition to level 1.
/ 3: f_lseek is removed in addition to level 2. */
#define _FAT32 0
/* To enable FAT32 support in addition of FAT12/16, set _FAT32 to 1. */
#define _USE_FSINFO 0
/* To enable FSInfo support on FAT32 volume, set _USE_FSINFO to 1. */
#define _USE_SJIS 1
/* When _USE_SJIS is set to 1, Shift-JIS code transparency is enabled, otherwise
/ only US-ASCII(7bit) code can be accepted as file/directory name. */
#define _USE_NTFLAG 1
/* When _USE_NTFLAG is set to 1, upper/lower case of the file name is preserved.
/ Note that the files are always accessed in case insensitive. */
#include "integer.h"
/* Type definition for cluster number */
#if _FAT32
typedef DWORD CLUST;
#else
typedef WORD CLUST;
#undef _USE_FSINFO
#define _USE_FSINFO 0
#endif
/* File system object structure */
typedef struct _FATFS {
WORD id; /* File system mount ID */
WORD n_rootdir; /* Number of root directory entries */
DWORD winsect; /* Current sector appearing in the win[] */
DWORD fatbase; /* FAT start sector */
DWORD dirbase; /* Root directory start sector */
DWORD database; /* Data start sector */
CLUST sects_fat; /* Sectors per fat */
CLUST max_clust; /* Maximum cluster# + 1 */
#if !_FS_READONLY
CLUST last_clust; /* Last allocated cluster */
CLUST free_clust; /* Number of free clusters */
#if _USE_FSINFO
DWORD fsi_sector; /* fsinfo sector */
BYTE fsi_flag; /* fsinfo dirty flag (1:must be written back) */
BYTE pad1;
#endif
#endif
BYTE fs_type; /* FAT sub type */
BYTE sects_clust; /* Sectors per cluster */
BYTE n_fats; /* Number of FAT copies */
BYTE winflag; /* win[] dirty flag (1:must be written back) */
BYTE win[512]; /* Disk access window for Directory/FAT/File */
} FATFS;
/* Directory object structure */
typedef struct _DIR {
WORD id; /* Owner file system mount ID */
WORD index; /* Current index */
FATFS* fs; /* Pointer to the owner file system object */
CLUST sclust; /* Start cluster */
CLUST clust; /* Current cluster */
DWORD sect; /* Current sector */
} DIR;
/* File object structure */
typedef struct _FIL {
WORD id; /* Owner file system mount ID */
BYTE flag; /* File status flags */
BYTE sect_clust; /* Left sectors in cluster */
FATFS* fs; /* Pointer to owner file system */
DWORD fptr; /* File R/W pointer */
DWORD fsize; /* File size */
CLUST org_clust; /* File start cluster */
CLUST curr_clust; /* Current cluster */
DWORD curr_sect; /* Current sector */
#if !_FS_READONLY
DWORD dir_sect; /* Sector containing the directory entry */
BYTE* dir_ptr; /* Ponter to the directory entry in the window */
#endif
} FIL;
/* File status structure */
typedef struct _FILINFO {
DWORD fsize; /* Size */
WORD fdate; /* Date */
WORD ftime; /* Time */
BYTE fattrib; /* Attribute */
char fname[8+1+3+1]; /* Name (8.3 format) */
} FILINFO;
/* File function return code (FRESULT) */
typedef enum {
FR_OK = 0, /* 0 */
FR_NOT_READY, /* 1 */
FR_NO_FILE, /* 2 */
FR_NO_PATH, /* 3 */
FR_INVALID_NAME, /* 4 */
FR_INVALID_DRIVE, /* 5 */
FR_DENIED, /* 6 */
FR_EXIST, /* 7 */
FR_RW_ERROR, /* 8 */
FR_WRITE_PROTECTED, /* 9 */
FR_NOT_ENABLED, /* 10 */
FR_NO_FILESYSTEM, /* 11 */
FR_INVALID_OBJECT /* 12 */
} FRESULT;
/*-----------------------------------------------------*/
/* FatFs module application interface */
FRESULT f_mount (BYTE, FATFS*); /* Mount/Unmount a logical drive */
FRESULT f_open (FIL*, const char*, BYTE); /* Open or create a file */
FRESULT f_read (FIL*, void*, WORD, WORD*); /* Read data from a file */
FRESULT f_write (FIL*, const void*, WORD, WORD*); /* Write data to a file */
FRESULT f_lseek (FIL*, DWORD); /* Move file pointer of a file object */
FRESULT f_close (FIL*); /* Close an open file object */
FRESULT f_opendir (DIR*, const char*); /* Open an existing directory */
FRESULT f_readdir (DIR*, FILINFO*); /* Read a directory item */
FRESULT f_stat (const char*, FILINFO*); /* Get file status */
FRESULT f_getfree (const char*, DWORD*, FATFS**); /* Get number of free clusters on the drive */
FRESULT f_sync (FIL*); /* Flush cached data of a writing file */
FRESULT f_unlink (const char*); /* Delete an existing file or directory */
FRESULT f_mkdir (const char*); /* Create a new directory */
FRESULT f_chmod (const char*, BYTE, BYTE); /* Change file/dir attriburte */
FRESULT f_rename (const char*, const char*); /* Rename/Move a file or directory */
/* User defined function to give a current time to fatfs module */
DWORD get_fattime (void); /* 31-25: Year(0-127 +1980), 24-21: Month(1-12), 20-16: Day(1-31) */
/* 15-11: Hour(0-23), 10-5: Minute(0-59), 4-0: Second(0-29 *2) */
/* File access control and file status flags (FIL.flag) */
#define FA_READ 0x01
#define FA_OPEN_EXISTING 0x00
#if !_FS_READONLY
#define FA_WRITE 0x02
#define FA_CREATE_NEW 0x04
#define FA_CREATE_ALWAYS 0x08
#define FA_OPEN_ALWAYS 0x10
#define FA__WRITTEN 0x20
#endif
#define FA__ERROR 0x80
/* FAT sub type (FATFS.fs_type) */
#define FS_FAT12 1
#define FS_FAT16 2
#define FS_FAT32 3
/* File attribute bits for directory entry */
#define AM_RDO 0x01 /* Read only */
#define AM_HID 0x02 /* Hidden */
#define AM_SYS 0x04 /* System */
#define AM_VOL 0x08 /* Volume label */
#define AM_LFN 0x0F /* LFN entry */
#define AM_DIR 0x10 /* Directory */
#define AM_ARC 0x20 /* Archive */
/* Offset of FAT structure members */
#define BS_jmpBoot 0
#define BS_OEMName 3
#define BPB_BytsPerSec 11
#define BPB_SecPerClus 13
#define BPB_RsvdSecCnt 14
#define BPB_NumFATs 16
#define BPB_RootEntCnt 17
#define BPB_TotSec16 19
#define BPB_Media 21
#define BPB_FATSz16 22
#define BPB_SecPerTrk 24
#define BPB_NumHeads 26
#define BPB_HiddSec 28
#define BPB_TotSec32 32
#define BS_55AA 510
#define BS_DrvNum 36
#define BS_BootSig 38
#define BS_VolID 39
#define BS_VolLab 43
#define BS_FilSysType 54
#define BPB_FATSz32 36
#define BPB_ExtFlags 40
#define BPB_FSVer 42
#define BPB_RootClus 44
#define BPB_FSInfo 48
#define BPB_BkBootSec 50
#define BS_DrvNum32 64
#define BS_BootSig32 66
#define BS_VolID32 67
#define BS_VolLab32 71
#define BS_FilSysType32 82
#define FSI_LeadSig 0
#define FSI_StrucSig 484
#define FSI_Free_Count 488
#define FSI_Nxt_Free 492
#define MBR_Table 446
#define DIR_Name 0
#define DIR_Attr 11
#define DIR_NTres 12
#define DIR_CrtTime 14
#define DIR_CrtDate 16
#define DIR_FstClusHI 20
#define DIR_WrtTime 22
#define DIR_WrtDate 24
#define DIR_FstClusLO 26
#define DIR_FileSize 28
/* Multi-byte word access macros */
#if _MCU_ENDIAN == 1 /* Use word access */
#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr))
#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr))
#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val)
#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val)
#else
#if _MCU_ENDIAN == 2 /* Use byte-by-byte access */
#define LD_WORD(ptr) (WORD)(((WORD)*(BYTE*)((ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))
#define LD_DWORD(ptr) (DWORD)(((DWORD)*(BYTE*)((ptr)+3)<<24)|((DWORD)*(BYTE*)((ptr)+2)<<16)|((WORD)*(BYTE*)((ptr)+1)<<8)|*(BYTE*)(ptr))
#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8)
#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8); *(BYTE*)((ptr)+2)=(BYTE)((DWORD)(val)>>16); *(BYTE*)((ptr)+3)=(BYTE)((DWORD)(val)>>24)
#else
#error Do not forget to set _MCU_ENDIAN properly!
#endif
#endif
#define _FATFS
#endif /* _FATFS */