LPCOpen Platform  v1.03
LPCOpen Platform for NXP LPC Microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ramdisk.c
Go to the documentation of this file.
1 /*
2  * @brief USB Mass Storage data RAM module
3  *
4  * @note
5  * Copyright(C) NXP Semiconductors, 2012
6  * All rights reserved.
7  *
8  * @par
9  * Software that is described herein is for illustrative purposes only
10  * which provides customers with programming information regarding the
11  * LPC products. This software is supplied "AS IS" without any warranties of
12  * any kind, and NXP Semiconductors and its licensor disclaim any and
13  * all warranties, express or implied, including all implied warranties of
14  * merchantability, fitness for a particular purpose and non-infringement of
15  * intellectual property rights. NXP Semiconductors assumes no responsibility
16  * or liability for the use of the software, conveys no license or rights under any
17  * patent, copyright, mask work right, or any other intellectual property rights in
18  * or to any products. NXP Semiconductors reserves the right to make changes
19  * in the software without notification. NXP Semiconductors also makes no
20  * representation or warranty that such application will be suitable for the
21  * specified use without further testing or modification.
22  *
23  * @par
24  * Permission to use, copy, modify, and distribute this software and its
25  * documentation is hereby granted, under NXP Semiconductors' and its
26  * licensor's relevant copyrights in the software, without fee, provided that it
27  * is used in conjunction with NXP Semiconductors microcontrollers. This
28  * copyright, permission, and disclaimer notice must appear in all copies of
29  * this code.
30  */
31 
32  // FIXME is this file needed? outside of norm
41 #include "usbmsdev.h"
42 #include "ramdisk.h"
43 
44 /*****************************************************************************
45  * Private types/enumerations/variables
46  ****************************************************************************/
47 
48 static int InitializedFlag = 0; // clear this flag once the fatutil code has been completed
49 
50 #define USBDATARAM LOCATE_AT(DATA_RAM_START_ADDRESS)
51 USBDATARAM uint8_t DiskImage[DATA_RAM_PHYSICAL_SIZE];
52 
53 /* Initial Image to be loaded into DiskImage */
54 static const uint8_t FAT12_header[] = {
55  0xeb, 0x3c, 0x90, 0x4d, 0x53, 0x44, 0x4f, 0x53, 0x35, 0x2e, 0x30, 0x00, 0x02, 0x01, 0x01, 0x00,
56  0x01, 0x10, 0x00, 0x10, 0x00, 0xf8, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
57  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x74, 0x19, 0x02, 0x27, 0x4c, 0x50, 0x43, 0x31, 0x31,
58  0x78, 0x78, 0x20, 0x55, 0x53, 0x42, 0x46, 0x41, 0x54, 0x31, 0x32, 0x20, 0x20, 0x20, 0x33, 0xc9,
59  0x8e, 0xd1, 0xbc, 0xf0, 0x7b, 0x8e, 0xd9, 0xb8, 0x00, 0x20, 0x8e, 0xc0, 0xfc, 0xbd, 0x00, 0x7c,
60  0x38, 0x4e, 0x24, 0x7d, 0x24, 0x8b, 0xc1, 0x99, 0xe8, 0x3c, 0x01, 0x72, 0x1c, 0x83, 0xeb, 0x3a,
61  0x66, 0xa1, 0x1c, 0x7c, 0x26, 0x66, 0x3b, 0x07, 0x26, 0x8a, 0x57, 0xfc, 0x75, 0x06, 0x80, 0xca,
62  0x02, 0x88, 0x56, 0x02, 0x80, 0xc3, 0x10, 0x73, 0xeb, 0x33, 0xc9, 0x8a, 0x46, 0x10, 0x98, 0xf7,
63  0x66, 0x16, 0x03, 0x46, 0x1c, 0x13, 0x56, 0x1e, 0x03, 0x46, 0x0e, 0x13, 0xd1, 0x8b, 0x76, 0x11,
64  0x60, 0x89, 0x46, 0xfc, 0x89, 0x56, 0xfe, 0xb8, 0x20, 0x00, 0xf7, 0xe6, 0x8b, 0x5e, 0x0b, 0x03,
65  0xc3, 0x48, 0xf7, 0xf3, 0x01, 0x46, 0xfc, 0x11, 0x4e, 0xfe, 0x61, 0xbf, 0x00, 0x00, 0xe8, 0xe6,
66  0x00, 0x72, 0x39, 0x26, 0x38, 0x2d, 0x74, 0x17, 0x60, 0xb1, 0x0b, 0xbe, 0xa1, 0x7d, 0xf3, 0xa6,
67  0x61, 0x74, 0x32, 0x4e, 0x74, 0x09, 0x83, 0xc7, 0x20, 0x3b, 0xfb, 0x72, 0xe6, 0xeb, 0xdc, 0xa0,
68  0xfb, 0x7d, 0xb4, 0x7d, 0x8b, 0xf0, 0xac, 0x98, 0x40, 0x74, 0x0c, 0x48, 0x74, 0x13, 0xb4, 0x0e,
69  0xbb, 0x07, 0x00, 0xcd, 0x10, 0xeb, 0xef, 0xa0, 0xfd, 0x7d, 0xeb, 0xe6, 0xa0, 0xfc, 0x7d, 0xeb,
70  0xe1, 0xcd, 0x16, 0xcd, 0x19, 0x26, 0x8b, 0x55, 0x1a, 0x52, 0xb0, 0x01, 0xbb, 0x00, 0x00, 0xe8,
71  0x3b, 0x00, 0x72, 0xe8, 0x5b, 0x8a, 0x56, 0x24, 0xbe, 0x0b, 0x7c, 0x8b, 0xfc, 0xc7, 0x46, 0xf0,
72  0x3d, 0x7d, 0xc7, 0x46, 0xf4, 0x29, 0x7d, 0x8c, 0xd9, 0x89, 0x4e, 0xf2, 0x89, 0x4e, 0xf6, 0xc6,
73  0x06, 0x96, 0x7d, 0xcb, 0xea, 0x03, 0x00, 0x00, 0x20, 0x0f, 0xb6, 0xc8, 0x66, 0x8b, 0x46, 0xf8,
74  0x66, 0x03, 0x46, 0x1c, 0x66, 0x8b, 0xd0, 0x66, 0xc1, 0xea, 0x10, 0xeb, 0x5e, 0x0f, 0xb6, 0xc8,
75  0x4a, 0x4a, 0x8a, 0x46, 0x0d, 0x32, 0xe4, 0xf7, 0xe2, 0x03, 0x46, 0xfc, 0x13, 0x56, 0xfe, 0xeb,
76  0x4a, 0x52, 0x50, 0x06, 0x53, 0x6a, 0x01, 0x6a, 0x10, 0x91, 0x8b, 0x46, 0x18, 0x96, 0x92, 0x33,
77  0xd2, 0xf7, 0xf6, 0x91, 0xf7, 0xf6, 0x42, 0x87, 0xca, 0xf7, 0x76, 0x1a, 0x8a, 0xf2, 0x8a, 0xe8,
78  0xc0, 0xcc, 0x02, 0x0a, 0xcc, 0xb8, 0x01, 0x02, 0x80, 0x7e, 0x02, 0x0e, 0x75, 0x04, 0xb4, 0x42,
79  0x8b, 0xf4, 0x8a, 0x56, 0x24, 0xcd, 0x13, 0x61, 0x61, 0x72, 0x0b, 0x40, 0x75, 0x01, 0x42, 0x03,
80  0x5e, 0x0b, 0x49, 0x75, 0x06, 0xf8, 0xc3, 0x41, 0xbb, 0x00, 0x00, 0x60, 0x66, 0x6a, 0x00, 0xeb,
81  0xb0, 0x4e, 0x54, 0x4c, 0x44, 0x52, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0d, 0x0a, 0x52, 0x65,
82  0x6d, 0x6f, 0x76, 0x65, 0x20, 0x64, 0x69, 0x73, 0x6b, 0x73, 0x20, 0x6f, 0x72, 0x20, 0x6f, 0x74,
83  0x68, 0x65, 0x72, 0x20, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2e, 0xff, 0x0d, 0x0a, 0x44, 0x69, 0x73,
84  0x6b, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0xff, 0x0d, 0x0a, 0x50, 0x72, 0x65, 0x73, 0x73, 0x20,
85  0x61, 0x6e, 0x79, 0x20, 0x6b, 0x65, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x72, 0x65, 0x73, 0x74, 0x61,
86  0x72, 0x74, 0x0d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0xcb, 0xd8, 0x55, 0xaa,
87  0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
88 };
89 
90 static const uint8_t FAT12_root_dir[] = {
91  0x4c, 0x50, 0x43, 0x55, 0x53, 0x42, 0x6c, 0x69, 0x62, 0x20, 0x20, 0x28, 0x00, 0x00, 0x00, 0x00,
92  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93  0x52, 0x45, 0x41, 0x44, 0x4d, 0x45, 0x20, 0x20, 0x54, 0x58, 0x54, 0x21, 0x00, 0x00, 0x00, 0x00,
94  0x21, 0x00, 0xbb, 0x32, 0x00, 0x00, 0xdc, 0x83, 0xbb, 0x32, 0x02, 0x00, 0x5d, 0x00, 0x00, 0x00,
95  0x41, 0x69, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x65, 0x00, 0x78, 0x00, 0x0f, 0x00, 0x2f, 0x2e, 0x00,
96  0x68, 0x00, 0x74, 0x00, 0x6d, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
97  0x49, 0x4e, 0x44, 0x45, 0x58, 0x20, 0x20, 0x20, 0x48, 0x54, 0x4d, 0x20, 0x00, 0x00, 0x0f, 0x93,
98  0x4a, 0x41, 0x4a, 0x41, 0x00, 0x00, 0x0f, 0x93, 0x4a, 0x41, 0x05, 0x00, 0x68, 0x01, 0x00, 0x00,
99 };
100 
101 static const uint8_t FAT12_file_readme_txt[] = {
102  0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x55, 0x53, 0x42, 0x20, 0x4d, 0x65,
103  0x6d, 0x6f, 0x72, 0x79, 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x20, 0x64, 0x65, 0x6d, 0x6f,
104  0x6e, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
105 };
106 
107 static const uint8_t FAT12_file_index_htm[] = {
108  0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0a,
109  0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0a, 0x09, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0a, 0x09,
110  0x09, 0x3c, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65,
111  0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0x22, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x68, 0x31, 0x20, 0x7b,
112  0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x72, 0x65, 0x64, 0x3b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61,
113  0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3b, 0x7d, 0x0a, 0x09, 0x09,
114  0x09, 0x68, 0x32, 0x20, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x62, 0x6c, 0x75, 0x65, 0x3b,
115  0x7d, 0x0a, 0x09, 0x09, 0x09, 0x70, 0x20, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x67, 0x72,
116  0x65, 0x65, 0x6e, 0x3b, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x7b, 0x62,
117  0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x3a, 0x20, 0x52, 0x47, 0x42, 0x28, 0x32,
118  0x31, 0x35, 0x2c, 0x32, 0x33, 0x32, 0x2c, 0x32, 0x34, 0x34, 0x29, 0x3b, 0x7d, 0x0a, 0x09, 0x09,
119  0x3c, 0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3e, 0x0a, 0x09, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64,
120  0x3e, 0x0a, 0x0a, 0x09, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x0a, 0x0a, 0x09, 0x09, 0x3c, 0x68,
121  0x31, 0x3e, 0x4e, 0x58, 0x50, 0x20, 0x4c, 0x50, 0x43, 0x34, 0x33, 0x58, 0x58, 0x20, 0x44, 0x75,
122  0x61, 0x6c, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x55, 0x53, 0x42, 0x2f, 0x6c, 0x77, 0x49, 0x50,
123  0x20, 0x44, 0x65, 0x6d, 0x6f, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x68, 0x72,
124  0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x70, 0x3e, 0x46, 0x6f, 0x72, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20,
125  0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x76, 0x69, 0x73, 0x69,
126  0x74, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x77, 0x77, 0x77, 0x2e, 0x6c, 0x70,
127  0x63, 0x77, 0x61, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x22, 0x3e, 0x20, 0x77, 0x77, 0x77, 0x2e,
128  0x6c, 0x70, 0x63, 0x77, 0x61, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x20, 0x3c, 0x2f, 0x61, 0x3e,
129  0x20, 0x3c, 0x2f, 0x70, 0x3e, 0x0a, 0x0a, 0x09, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x0a,
130  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
131 };
132 
133 static const struct FAT12_img {
134  const uint8_t *data;
135  int offset;
136  int size;
137 } FAT12_img[] = {
138  /* Each sector is of size 512 Bytes i.e., 0x200 Bytes */
139  {FAT12_header, 0, sizeof(FAT12_header)}, /* FAT12 at sector 0,1 */
140  {FAT12_root_dir, 0x400, sizeof(FAT12_root_dir)}, /* Root dir at sector 2 */
141  {FAT12_file_readme_txt, 0x600, sizeof(FAT12_file_readme_txt)}, /* README.TXT file data */
142  {FAT12_file_index_htm, 0xC00, sizeof(FAT12_file_index_htm)}, /* INDEX.HTM file data */
143 };
144 
145 /*****************************************************************************
146  * Public types/enumerations/variables
147  ****************************************************************************/
148 
149 /*****************************************************************************
150  * Private functions
151  ****************************************************************************/
152 
153 /*****************************************************************************
154  * Public functions
155  ****************************************************************************/
156 
157 /* DataRAM write blocks function */
158 void DataRam_WriteBlocks(USB_ClassInfo_MS_Device_t *const MSInterfaceInfo,
159  const uint32_t BlockAddress,
160  uint16_t TotalBlocks)
161 {
162  uint32_t i;
163 
164  if (!InitializedFlag) {
166  }
167 
168  for (i = 0; i < TotalBlocks; i++) {
169  while (!Endpoint_IsReadWriteAllowed(MSInterfaceInfo->Config.PortNumber)) ;
170 
171  // Fake the read if the address is past the physical limit of the DiskImage buffer
172  if (BlockAddress + i >= DATA_RAM_PHYSICAL_SIZE / VIRTUAL_MEMORY_BLOCK_SIZE) {
174  Endpoint_ClearOUT(MSInterfaceInfo->Config.PortNumber);
175  continue;
176  }
177 
178  Endpoint_Read_Stream_LE(MSInterfaceInfo->Config.PortNumber, &DiskImage[(BlockAddress + i) * VIRTUAL_MEMORY_BLOCK_SIZE],
179  VIRTUAL_MEMORY_BLOCK_SIZE,
180  NULL);
181  Endpoint_ClearOUT(MSInterfaceInfo->Config.PortNumber);
182  }
183 }
184 
185 /* DataRAM read blocks function */
186 void DataRam_ReadBlocks(USB_ClassInfo_MS_Device_t *const MSInterfaceInfo,
187  const uint32_t BlockAddress,
188  uint16_t TotalBlocks)
189 {
190  uint32_t i;
191 
192  if (!InitializedFlag) {
194  }
195 
196  for (i = 0; i < TotalBlocks; i++) {
197  // Fake the write if the address is past the physical limit of the DiskImage buffer
198  if (BlockAddress + i >= DATA_RAM_PHYSICAL_SIZE / VIRTUAL_MEMORY_BLOCK_SIZE) {
200  Endpoint_ClearIN(MSInterfaceInfo->Config.PortNumber);
201  continue;
202  }
203 
204  Endpoint_Write_Stream_LE(MSInterfaceInfo->Config.PortNumber, &DiskImage[(BlockAddress + i) * VIRTUAL_MEMORY_BLOCK_SIZE],
205  VIRTUAL_MEMORY_BLOCK_SIZE,
206  NULL);
207  Endpoint_ClearIN(MSInterfaceInfo->Config.PortNumber);
208  }
209 }
210 
211 uint32_t MassStorage_GetAddressInImage(uint32_t startblock, uint16_t requestblocks, uint16_t *availableblocks)
212 {
213  if (!InitializedFlag) {
215  }
216 
217  if ((startblock + requestblocks) <= DATA_RAM_PHYSICAL_SIZE / DATA_RAM_BLOCK_SIZE) {
218  *availableblocks = requestblocks;
219  }
220  else {
221  if (startblock >= DATA_RAM_PHYSICAL_SIZE / DATA_RAM_BLOCK_SIZE) {
222  *availableblocks = 0;
223  }
224  else {*availableblocks = DATA_RAM_PHYSICAL_SIZE / DATA_RAM_BLOCK_SIZE - startblock; }
225  }
226 
227  if (*availableblocks != 0) {
228  return (uint32_t) &DiskImage[startblock * DATA_RAM_BLOCK_SIZE];
229  }
230  else {
231  return (uint32_t) &DiskImage[(DATA_RAM_PHYSICAL_SIZE / DATA_RAM_BLOCK_SIZE - 1) * DATA_RAM_BLOCK_SIZE];
232  }
233 }
234 
236 {
237  if (!InitializedFlag) {
238  int i;
239  InitializedFlag = 1;
240  memset(DiskImage, 0, sizeof(DiskImage));
241  for (i = 0; i < sizeof(FAT12_img) / sizeof(FAT12_img[0]); i++)
242  memcpy(&DiskImage[FAT12_img[i].offset], FAT12_img[i].data, FAT12_img[i].size);
243  }
244 }
245