LPCOpen Platform
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  {
27  {0xEB, 0x3C, 0x90}, /* Jump instruction to the boot code */
28  "MSWIN4.1", /* Name of system that formatted the volume */
29  BYTESPERSECTOR, /* Bytes per sector (should be 512) */
30  SECTORSPERCLUSTER, /* Sectors per cluster (FAT-12 = 1) */
31  RESERVEDSECTORCNT, /* Reserved sectors (FAT-12 = 1) */
32  NUMFATS, /* FAT tables on the disk (should be 2) */
33  ROOTENTRIES, /* Max directory entries in root directory */
34  VIRTUAL_MEMORY_BLOCKS, /* FAT-12 total number of sectors on the disk */
35  FAT_MEDIA, /* Media type {fixed, removable, etc.} */
36  SECTORSPERFAT, /* Sector size of FAT table (FAT-12 = 9) */
37  63, /* # of sectors per cylindrical track */
38  0xFF, /* # of heads per volume (1.4Mb 3.5" = 2) */
39  1, /* # of preceding hidden sectors (0) */
40  0, /* # of FAT-32 sectors (0 for FAT-12) */
41  0x80, /* A drive number for the media (OS specific) */
42  0, /* Reserved space for Windows NT (set to 0) */
43  41, /* (0x29) Indicates following: */
44  654449012, /* Volume serial # (for tracking this disk) */
45  {"Jennic USB "}, /* Volume label (RDL or "NO NAME    ") */
46  {"FAT12 "}, /* Deceptive FAT type Label */
47  },
48 
49  {0}, /* Boot code */
50  0xaa55, /* BootSectorSignature */
51 
52 // {
53 // {0xF8, 0x0F, {0xFF}}, /* 1st FAT */
54 //#if NUMFATS > 1
55 // {0xF8, 0x0F, {0xFF}}, /* 2nd FAT */
56 //#endif
57 //#if NUMFATS > 2
58 // {{0}}, /* 3rd FAT */
59 //#endif
60 // },
61 // {
62 // {
63 // {"LPC134x "}, /* File name (capital letters, padded w/spaces) */
64 // {"USB"}, /* Extension (same format as name, no '.') */
65 // 0x28, /* Holds the attributes code */
66 // {0}, /* Reserved for Windows NT (Set to zero!) */
67 // {0,0,0}, /* Time of last write */
68 // {0,0,0}, /* Date of last write */
69 // 0, /* Pointer to the first cluster of the file */
70 // 0, /* File size in bytes */
71 // },
72 // {
73 // {"FIRMWARE"}, /* File name (capital letters, padded w/spaces) */
74 // {"BIN"}, /* Extension (same format as name, no '.') */
75 // 0x20, /* Holds the attributes code */
76 // {0}, /* Reserved for Windows NT (Set to zero!) */
77 // {0,0,0}, /* Time of last write */
78 // {0,0,0}, /* Date of last write */
79 // 0, /* Pointer to the first cluster of the file */
80 // 0, /* File size in bytes */
81 // },
82 // },
83 };
84 #endif
85 // Return an unsigned short containing the 12-bit FAT entry code
86 // at FATindex unsigned short
87 int16_t GetFAT12Entry(DISKIMAGE *DiskImagePtr, int FATindex)
88 {
89  unsigned short FATEntryCode; // The return value
90  int FatOffset = ((FATindex * 3) / 2); // Calculate the offset
91  if (FATindex % 2 == 1) // If the index is odd
92  { // Pull out a unsigned short from a unsigned char array
93  FATEntryCode = *((unsigned short *) &DiskImagePtr->Fat[0].FATByte[FatOffset]);
94  FATEntryCode >>= 4; // Extract the high-order 12 bits
95  }
96  else // If the index is even
97  { // Pull out a unsigned short from a unsigned char array
98  FATEntryCode = *((unsigned short *) &DiskImagePtr->Fat[0].FATByte[FatOffset]);
99  FATEntryCode &= 0x0fff; // Extract the low-order 12 bits
100  }
101  return FATEntryCode;
102 } // End GetFatEntry
103 
104 void SetFAT12Entry(DISKIMAGE *DiskImagePtr, int FATindex, unsigned short FAT12ClusEntryVal)
105 {
106  int FATOffset = ((FATindex * 3) / 2); // Calculate the offset
107  int FATData = *((unsigned char *)&DiskImagePtr->Fat[0].FATByte[FATOffset]);
108  if (FATindex % 2 == 0) // If the index is even
109  {
110  FAT12ClusEntryVal &= 0x0FFF; // mask to 12 bits
111  FATData &= 0xF000; // mask complement
112  }
113  else // Index is odd
114  {
115  FAT12ClusEntryVal <<= 4; // move 12-bits high
116  FATData &= 0x000F; // mask complement
117  }
118 
119  // Update FAT entry value in the FAT table
120  *((unsigned char *) &DiskImagePtr->Fat[0].FATByte[FATOffset]) = FATData | FAT12ClusEntryVal;
121 } // End SetFatEntry
122 
123 void InitializeFAT12(DISKIMAGE *DiskImagePtr)
124 {
125  int i;
126 
127  SetFAT12Entry(DiskImagePtr, 1, 0xfff);
128  for(i = 0; i < ((DiskImagePtr->BootSector.BPB_TotSec16 - StartDataRegion / BytesPerSector) / DiskImagePtr->BootSector.BPB_SecPerClus); i++)
129  {
130  if (!i)
131  DiskImagePtr->DirectoryEntries[1].startCluster = 2; // Startcluster is always 2 as defined by FAT12
132  else
133  {
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 
146 void InitializeFAT32(DISKIMAGE *DiskImagePtr)
147 {
148 }
149 
151 {
152  int RootDirSectors, DataSec, CountofClusters;
153 
154  RootDirSectors = ((DiskImagePtr->BootSector.BPB_RootEntCnt * 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 }
187 {
189  TotalSectors = DiskImagePtr->BootSector.BPB_TotSec16;
190  SectorsPerFat = DiskImagePtr->BootSector.BPB_FATSz16;
191  NumFats = DiskImagePtr->BootSector.BPB_NumFATs;
192  RootEntries = DiskImagePtr->BootSector.BPB_RootEntCnt;
193  BytesPerSector = DiskImagePtr->BootSector.BPB_BytsPerSec;
195 }
196 
197 void CreateDiskImage(DISKIMAGE *DiskImagePtr)
198 {
199  int i;
200 
201  // Initialize all directory entries
202  for(i = 0; i < ROOTENTRIES; i++)
203  memset((void *)&DiskImagePtr->DirectoryEntries[i], 0, sizeof(DiskImagePtr->DirectoryEntries[0]));
204 
205  // Set the volume label
206  strncpy((char *)DiskImagePtr->DirectoryEntries[0].Name, "USBlib ", 8);
207  strncpy((char *)DiskImagePtr->DirectoryEntries[0].Extension, " ", 3);
208  DiskImagePtr->DirectoryEntries[0].Attributes = 0x28;
209  DiskImagePtr->DirectoryEntries[0].Time.hour = TIME_HOUR;
210  DiskImagePtr->DirectoryEntries[0].Time.min = TIME_MIN;
211  DiskImagePtr->DirectoryEntries[0].Time.sec = TIME_SEC;
212  DiskImagePtr->DirectoryEntries[0].Date.year = DATE_YEAR;
213  DiskImagePtr->DirectoryEntries[0].Date.month = DATE_MONTH;
214  DiskImagePtr->DirectoryEntries[0].Date.day = DATE_DAY;
215 
216  // Initialize the binary data file
217  strncpy((char *)DiskImagePtr->DirectoryEntries[1].Name, "FIRMWARE", 8);
218  strncpy((char *)DiskImagePtr->DirectoryEntries[1].Extension, "BIN", 3);
219  DiskImagePtr->DirectoryEntries[1].Attributes = 0x20;
220  //DiskImagePtr->DirectoryEntries[1].Reserved[0] = 0x18;
221  DiskImagePtr->DirectoryEntries[1].Time.hour = TIME_HOUR;
222  DiskImagePtr->DirectoryEntries[1].Time.min = TIME_MIN;
223  DiskImagePtr->DirectoryEntries[1].Time.sec = TIME_SEC;
224  DiskImagePtr->DirectoryEntries[1].Date.year = DATE_YEAR;
225  DiskImagePtr->DirectoryEntries[1].Date.month = DATE_MONTH;
226  DiskImagePtr->DirectoryEntries[1].Date.day = DATE_DAY;
227 
228  DiskImagePtr->DirectoryEntries[1].fileSize = 0;
229 #if (FATTYPE == FAT12)
230  InitializeFAT12(DiskImagePtr);
231 #endif
232 #if (FATTYPE == FAT16)
233  InitializeFAT16(DiskImagePtr);
234 #endif
235 #if (FATTYPE == FAT32)
236  InitializeFAT32(DiskImagePtr);
237 #endif
238 
239 }
240 
241 void InitializeDiskImage(DISKIMAGE *DiskImagePtr,
242  int VolumeSize,
243  int BytesPerSector,
244  int NumFATs,
245  int SectorsPerFAT,
246  int RootEntries)
247 {
248  DiskImagePtr->BootSector.BPB_FATSz16 = SectorsPerFAT;
249  DiskImagePtr->BootSector.BPB_NumFATs = NumFATs;
250  DiskImagePtr->BootSector.BPB_RootEntCnt = RootEntries;
251  DiskImagePtr->BootSector.BPB_BytsPerSec = BytesPerSector;
253  DiskImagePtr->BootSector.BPB_Media = 0xf8;
255 
256  DiskImagePtr->BootSector.BPB_TotSec16 = VolumeSize / BytesPerSector;
257 
258 }
259