LPCOpen Platform  v1.03
LPCOpen Platform for NXP LPC Microcontrollers
 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 
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 
169 int32_t NumFats = NUMFATS;
174 
176 {
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;
185 }
186 
188 {
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;
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;
255  DiskImagePtr->BootSector.BPB_Media = 0xf8;
257 
258  DiskImagePtr->BootSector.BPB_TotSec16 = VolumeSize / BytesPerSector;
259 
260 }
261