| LPCOpen Platform v1.03 LPCOpen Platform for NXP LPC Microcontrollers

- Main Page
- Modules
- Data Structures
- Files
- Related Pages

- File List
- Globals

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
fatutil.c
Go to the documentation of this file.
1 /*----------------------------------------------------------------------------
2 * Name: fatutil.c
3 * Purpose: FAT utilities
4 * Version: V1.00
5 **----------------------------------------------------------------------------
6 * This software is supplied "AS IS" without any warranties, express,
7 * implied or statutory, including but not limited to the implied
8 * warranties of fitness for purpose, satisfactory quality and
9 * noninfringement. NXP extends you a royalty-free right to reproduce
10 * and distribute executable files created using this software for use
11 * on NXP Semiconductors LPC microcontroller devices only. Nothing else
12 * gives you the right to use this software.
13 *
14 * Copyright (c) 2011 NXP Semiconductors. All rights reserved.
15 *---------------------------------------------------------------------------*/
16
17 #include "fatutil.h"
18 #include <string.h>
19
23 #if 0
24 DISKIMAGE Fat12_1_FAT = {
25 {
26 {0xEB, 0x3C, 0x90}, /* Jump instruction to the boot code */
27 "MSWIN4.1", /* Name of system that formatted the volume */
28 BYTESPERSECTOR, /* Bytes per sector (should be 512) */
29 SECTORSPERCLUSTER, /* Sectors per cluster (FAT-12 = 1) */
30 RESERVEDSECTORCNT, /* Reserved sectors (FAT-12 = 1) */
31 NUMFATS, /* FAT tables on the disk (should be 2) */
32 ROOTENTRIES, /* Max directory entries in root directory */
33 VIRTUAL_MEMORY_BLOCKS, /* FAT-12 total number of sectors on the disk */
34 FAT_MEDIA, /* Media type {fixed, removable, etc.} */
35 SECTORSPERFAT, /* Sector size of FAT table (FAT-12 = 9) */
36 63, /* # of sectors per cylindrical track */
37 0xFF, /* # of heads per volume (1.4Mb 3.5" = 2) */
38 1, /* # of preceding hidden sectors (0) */
39 0, /* # of FAT-32 sectors (0 for FAT-12) */
40 0x80, /* A drive number for the media (OS specific) */
41 0, /* Reserved space for Windows NT (set to 0) */
42 41, /* (0x29) Indicates following: */
43 654449012, /* Volume serial # (for tracking this disk) */
44 {"Jennic USB "}, /* Volume label (RDL or "NO NAME ") */
45 {"FAT12 "}, /* Deceptive FAT type Label */
46 },
47
48 {0}, /* Boot code */
49 0xaa55, /* BootSectorSignature */
50
51 // {
52 // {0xF8, 0x0F, {0xFF}}, /* 1st FAT */
53 // #if NUMFATS > 1
54 // {0xF8, 0x0F, {0xFF}}, /* 2nd FAT */
55 // #endif
56 // #if NUMFATS > 2
57 // {{0}}, /* 3rd FAT */
58 // #endif
59 // },
60 // {
61 // {
62 // {"LPC134x "}, /* File name (capital letters, padded w/spaces) */
63 // {"USB"}, /* Extension (same format as name, no '.') */
64 // 0x28, /* Holds the attributes code */
65 // {0}, /* Reserved for Windows NT (Set to zero!) */
66 // {0,0,0}, /* Time of last write */
67 // {0,0,0}, /* Date of last write */
68 // 0, /* Pointer to the first cluster of the file */
69 // 0, /* File size in bytes */
70 // },
71 // {
72 // {"FIRMWARE"}, /* File name (capital letters, padded w/spaces) */
73 // {"BIN"}, /* Extension (same format as name, no '.') */
74 // 0x20, /* Holds the attributes code */
75 // {0}, /* Reserved for Windows NT (Set to zero!) */
76 // {0,0,0}, /* Time of last write */
77 // {0,0,0}, /* Date of last write */
78 // 0, /* Pointer to the first cluster of the file */
79 // 0, /* File size in bytes */
80 // },
81 // },
82 };
83 #endif
84 // Return an unsigned short containing the 12-bit FAT entry code
85 // at FATindex unsigned short
86 int16_t GetFAT12Entry(DISKIMAGE *DiskImagePtr, int FATindex)
87 {
88 unsigned short FATEntryCode; // The return value
89 int FatOffset = ((FATindex * 3) / 2); // Calculate the offset
90 if (FATindex % 2 == 1) {// If the index is odd
91 // Pull out a unsigned short from a unsigned char array
92 FATEntryCode = *((unsigned short *) &DiskImagePtr->Fat[0].FATByte[FatOffset]);
93 FATEntryCode >>= 4; // Extract the high-order 12 bits
94 }
95 else { // If the index is even
96 // Pull out a unsigned short from a unsigned char array
97 FATEntryCode = *((unsigned short *) &DiskImagePtr->Fat[0].FATByte[FatOffset]);
98 FATEntryCode &= 0x0fff; // Extract the low-order 12 bits
99 }
100 return FATEntryCode;
101 } // End GetFatEntry
102
103 void SetFAT12Entry(DISKIMAGE *DiskImagePtr, int FATindex, unsigned short FAT12ClusEntryVal)
104 {
105 int FATOffset = ((FATindex * 3) / 2); // Calculate the offset
106 int FATData = *((unsigned char *) &DiskImagePtr->Fat[0].FATByte[FATOffset]);
107 if (FATindex % 2 == 0) {// If the index is even
108 FAT12ClusEntryVal &= 0x0FFF; // mask to 12 bits
109 FATData &= 0xF000; // mask complement
110 }
111 else { // Index is odd
112 FAT12ClusEntryVal <<= 4; // move 12-bits high
113 FATData &= 0x000F; // mask complement
114 }
115
116 // Update FAT entry value in the FAT table
117 *((unsigned char *) &DiskImagePtr->Fat[0].FATByte[FATOffset]) = FATData | FAT12ClusEntryVal;
118 } // End SetFatEntry
119
120 void InitializeFAT12(DISKIMAGE *DiskImagePtr)
121 {
122 int i;
123
124 SetFAT12Entry(DiskImagePtr, 1, 0xfff);
125 for (i = 0;
126 i <
127 ((DiskImagePtr->BootSector.BPB_TotSec16 - StartDataRegion /
128 BytesPerSector) / DiskImagePtr->BootSector.BPB_SecPerClus);
129 i++) {
130 if (!i) {
131 DiskImagePtr->DirectoryEntries[1].startCluster = 2; // Startcluster is always 2 as defined by FAT12
132 }
133 else {
134 SetFAT12Entry(DiskImagePtr, i + 1, i + 2); // 2 represents the startcluster (which is fixed by definition)
135 SetFAT12Entry(DiskImagePtr, i + 2, 0xfff);
136 }
137 DiskImagePtr->DirectoryEntries[1].fileSize += BYTESPERCLUSTER;
138 }
139 // InitializeDiskDiskImage(DiskImagePtr);
140 }
141
142 void InitializeFAT16(DISKIMAGE *DiskImagePtr)
143 {}
144
145 void InitializeFAT32(DISKIMAGE *DiskImagePtr)
146 {}
147
148 uint32_t CalculateCountOfClusters(DISKIMAGE *DiskImagePtr)
149 {
150 int RootDirSectors, DataSec, CountofClusters;
151
152 RootDirSectors =
153 ((DiskImagePtr->BootSector.BPB_RootEntCnt *
154 32) + (DiskImagePtr->BootSector.BPB_BytsPerSec - 1)) / DiskImagePtr->BootSector.BPB_BytsPerSec;
155
156 DataSec = DiskImagePtr->BootSector.BPB_TotSec16 -
157 (DiskImagePtr->BootSector.BPB_RsvdSecCnt +
158 (DiskImagePtr->BootSector.BPB_NumFATs *
159 DiskImagePtr->BootSector.BPB_FATSz16) +
160 RootDirSectors);
161 CountofClusters = DataSec / DiskImagePtr->BootSector.BPB_SecPerClus;
162
163 return CountofClusters;
164 }
165
166 int32_t ReservedSectorCnt = RESERVEDSECTORCNT;
167 int32_t RootEntries = ROOTENTRIES;
168 int32_t BytesPerSector = BYTESPERSECTOR;
169 int32_t NumFats = NUMFATS;
170 int32_t SectorsPerFat = SECTORSPERFAT;
171 int32_t NonDataSectors = NONDATASECTORS;
172 int32_t TotalSectors = TOTALSECTORS;
173 int32_t StartDataRegion = STARTDATAREGION;
174
175 void InitializeDiskDiskImage(DISKIMAGE *DiskImagePtr)
176 {
177 DiskImagePtr->BootSector.BPB_RsvdSecCnt = ReservedSectorCnt;
178 DiskImagePtr->BootSector.BPB_TotSec16 = TotalSectors;
179 DiskImagePtr->BootSector.BPB_FATSz16 = SectorsPerFat;
180 DiskImagePtr->BootSector.BPB_NumFATs = NumFats;
181 DiskImagePtr->BootSector.BPB_RootEntCnt = RootEntries;
182 DiskImagePtr->BootSector.BPB_BytsPerSec = BytesPerSector;
183 DiskImagePtr->BootSector.BPB_Media = 0xf8;
184 DiskImagePtr->BootSector.BPB_SecPerClus = SECTORSPERCLUSTER;
185 }
186
187 void SetDiskMetricsFromDiskImage(DISKIMAGE *DiskImagePtr)
188 {
189 ReservedSectorCnt = DiskImagePtr->BootSector.BPB_RsvdSecCnt;
190 TotalSectors = DiskImagePtr->BootSector.BPB_TotSec16;
191 SectorsPerFat = DiskImagePtr->BootSector.BPB_FATSz16;
192 NumFats = DiskImagePtr->BootSector.BPB_NumFATs;
193 RootEntries = DiskImagePtr->BootSector.BPB_RootEntCnt;
194 BytesPerSector = DiskImagePtr->BootSector.BPB_BytsPerSec;
195 StartDataRegion = (ReservedSectorCnt + NumFats * SectorsPerFat + ((RootEntries - 1) / 16 + 1)) * BytesPerSector;
196 }
197
198 void CreateDiskImage(DISKIMAGE *DiskImagePtr)
199 {
200 int i;
201
202 // Initialize all directory entries
203 for (i = 0; i < ROOTENTRIES; i++) {
204 memset((void *) &DiskImagePtr->DirectoryEntries[i], 0, sizeof(DiskImagePtr->DirectoryEntries[0]));
205 }
206
207 // Set the volume label
208 strncpy((char *) DiskImagePtr->DirectoryEntries[0].Name, "USBlib ", 8);
209 strncpy((char *) DiskImagePtr->DirectoryEntries[0].Extension, " ", 3);
210 DiskImagePtr->DirectoryEntries[0].Attributes = 0x28;
211 DiskImagePtr->DirectoryEntries[0].Time.hour = TIME_HOUR;
212 DiskImagePtr->DirectoryEntries[0].Time.min = TIME_MIN;
213 DiskImagePtr->DirectoryEntries[0].Time.sec = TIME_SEC;
214 DiskImagePtr->DirectoryEntries[0].Date.year = DATE_YEAR;
215 DiskImagePtr->DirectoryEntries[0].Date.month = DATE_MONTH;
216 DiskImagePtr->DirectoryEntries[0].Date.day = DATE_DAY;
217
218 // Initialize the binary data file
219 strncpy((char *) DiskImagePtr->DirectoryEntries[1].Name, "FIRMWARE", 8);
220 strncpy((char *) DiskImagePtr->DirectoryEntries[1].Extension, "BIN", 3);
221 DiskImagePtr->DirectoryEntries[1].Attributes = 0x20;
222 // DiskImagePtr->DirectoryEntries[1].Reserved[0] = 0x18;
223 DiskImagePtr->DirectoryEntries[1].Time.hour = TIME_HOUR;
224 DiskImagePtr->DirectoryEntries[1].Time.min = TIME_MIN;
225 DiskImagePtr->DirectoryEntries[1].Time.sec = TIME_SEC;
226 DiskImagePtr->DirectoryEntries[1].Date.year = DATE_YEAR;
227 DiskImagePtr->DirectoryEntries[1].Date.month = DATE_MONTH;
228 DiskImagePtr->DirectoryEntries[1].Date.day = DATE_DAY;
229
230 DiskImagePtr->DirectoryEntries[1].fileSize = 0;
231 #if (FATTYPE == FAT12)
232 InitializeFAT12(DiskImagePtr);
233 #endif
234 #if (FATTYPE == FAT16)
235 InitializeFAT16(DiskImagePtr);
236 #endif
237 #if (FATTYPE == FAT32)
238 InitializeFAT32(DiskImagePtr);
239 #endif
240
241 }
242
243 void InitializeDiskImage(DISKIMAGE *DiskImagePtr,
244 int VolumeSize,
245 int BytesPerSector,
246 int NumFATs,
247 int SectorsPerFAT,
248 int RootEntries)
249 {
250 DiskImagePtr->BootSector.BPB_FATSz16 = SectorsPerFAT;
251 DiskImagePtr->BootSector.BPB_NumFATs = NumFATs;
252 DiskImagePtr->BootSector.BPB_RootEntCnt = RootEntries;
253 DiskImagePtr->BootSector.BPB_BytsPerSec = BytesPerSector;
254 DiskImagePtr->BootSector.BPB_SecPerClus = SECTORSPERCLUSTER;
255 DiskImagePtr->BootSector.BPB_Media = 0xf8;
256 DiskImagePtr->BootSector.BPB_RsvdSecCnt = RESERVEDSECTORCNT;
257
258 DiskImagePtr->BootSector.BPB_TotSec16 = VolumeSize / BytesPerSector;
259
260 }
261