?lang_form? ?lang_select? ?lang_submit? ?lang_endform?
{HEADER END}
{BLAME START}

library

?curdirlinks? -

Blame information for rev 32

Line No. Rev Author Line
1 32 kaklik /*********************************************************************
2 *
3 * Microchip File System (MPFS) File Access API
4 * Module for Microchip TCP/IP Stack
5 * -Provides single API for accessing web pages and other files
6 * from internal program memory or an external serial EEPROM memory
7 * -Reference: AN833
8 *
9 *********************************************************************
10 * FileName: MPFS.c
11 * Dependencies: SPIEEPROM
12 * Processor: PIC18, PIC24F, PIC24H, dsPIC30F, dsPIC33F, PIC32
13 * Compiler: Microchip C32 v1.05 or higher
14 * Microchip C30 v3.12 or higher
15 * Microchip C18 v3.30 or higher
16 * HI-TECH PICC-18 PRO 9.63PL2 or higher
17 * Company: Microchip Technology, Inc.
18 *
19 * Software License Agreement
20 *
21 * Copyright (C) 2002-2009 Microchip Technology Inc. All rights
22 * reserved.
23 *
24 * Microchip licenses to you the right to use, modify, copy, and
25 * distribute:
26 * (i) the Software when embedded on a Microchip microcontroller or
27 * digital signal controller product ("Device") which is
28 * integrated into Licensee's product; or
29 * (ii) ONLY the Software driver source files ENC28J60.c, ENC28J60.h,
30 * ENCX24J600.c and ENCX24J600.h ported to a non-Microchip device
31 * used in conjunction with a Microchip ethernet controller for
32 * the sole purpose of interfacing with the ethernet controller.
33 *
34 * You should refer to the license agreement accompanying this
35 * Software for additional information regarding your rights and
36 * obligations.
37 *
38 * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
39 * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
40 * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
41 * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
42 * MICROCHIP BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR
43 * CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
44 * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
45 * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
46 * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
47 * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
48 * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
49 *
50 *
51 * Author Date Comment
52 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
53 * Nilesh Rajbharti 8/14/01 Original (Rev. 1.0)
54 * Nilesh Rajbharti 2/9/02 Cleanup
55 * Nilesh Rajbharti 5/22/02 Rev 2.0 (See version.log for detail)
56 * Howard Schlunder 3/31/05 Changed MPFS_ENTRY and mpfs_Flags for C30
57 ********************************************************************/
58 #define __MPFS_C
59  
60 #include "TCPIP Stack/TCPIP.h"
61  
62 #if defined(STACK_USE_MPFS)
63  
64 // This file system supports short file names i.e. 8 + 3.
65 #define MAX_FILE_NAME_LEN (12u)
66  
67 #define MPFS_DATA (0x00u)
68 #define MPFS_DELETED (0x01u)
69 #define MPFS_DLE (0x03u)
70 #define MPFS_ETX (0x04u)
71  
72 /*
73 * MPFS Structure:
74 *
75 * MPFS_Start:
76 * <MPFS_DATA><Address1><FileName1>
77 * <MPFS_DATA><Address2><FileName2>
78 * ...
79 * <MPFS_ETX><Addressn><FileNamen>
80 * Address1:
81 * <Data1>[<Data2>...<Datan>]<MPFS_ETX><MPFS_INVALID>
82 * ...
83 *
84 * Note: If File data contains either MPFS_DLE or MPFS_ETX
85 * extra MPFS_DLE is stuffed before that byte.
86 */
87 #if defined(MPFS_USE_EEPROM) || defined(MPFS_USE_SPI_FLASH)
88 typedef struct _MPFS_ENTRY
89 {
90 BYTE Flag __attribute__((__packed__));
91 MPFS Address __attribute__((__packed__));
92 BYTE Name[MAX_FILE_NAME_LEN] __attribute__((__packed__));
93 } MPFS_ENTRY;
94 #else //Use program memory
95 typedef struct _MPFS_ENTRY
96 {
97 BYTE Flag;
98 MPFS Address;
99 BYTE Name[MAX_FILE_NAME_LEN];
100 } MPFS_ENTRY;
101 #if defined(__C30__)
102 static DWORD ReadProgramMemory(DWORD address);
103 #endif
104 #endif
105  
106 static union
107 {
108 struct
109 {
110 unsigned char bNotAvailable : 1;
111 } bits;
112 BYTE Val;
113 } mpfsFlags;
114  
115 BYTE mpfsOpenCount;
116  
117 #if !defined(MPFS_USE_EEPROM) && !defined(MPFS_USE_SPI_FLASH)
118 // An address where MPFS data starts in program memory.
119 extern ROM MPFS_ENTRY MPFS_Start[];
120 #else
121 #define MPFS_Start MPFS_RESERVE_BLOCK
122 #endif
123  
124 MPFS _currentHandle;
125 MPFS _currentFile;
126 WORD _currentCount;
127  
128  
129 /*********************************************************************
130 * Function: BOOL MPFSInit(void)
131 *
132 * PreCondition: None
133 *
134 * Input: None
135 *
136 * Output: TRUE, if MPFS Storage access is initialized and
137 * MPFS is ready to be used.
138 * FALSE otherwise
139 *
140 * Side Effects: None
141 *
142 * Overview: None
143 *
144 * Note: None
145 ********************************************************************/
146 BOOL MPFSInit(void)
147 {
148 mpfsOpenCount = 0;
149 mpfsFlags.Val = 0;
150  
151 #if defined(MPFS_USE_EEPROM)
152 // Initialize the EEPROM access routines.
153 XEEInit();
154 #elif defined(MPFS_USE_SPI_FLASH)
155 // Initialize the SPI Flash access routines.
156 SPIFlashInit();
157 #endif
158  
159 return TRUE;
160 }
161  
162  
163 /*********************************************************************
164 * Function: MPFS MPFSOpen(BYTE* file)
165 *
166 * PreCondition: None
167 *
168 * Input: file - NULL terminated file name.
169 *
170 * Output: A handle if file is found
171 * MPFS_INVALID if file is not found.
172 *
173 * Side Effects: None
174 *
175 * Overview: None
176 *
177 * Note: None
178 ********************************************************************/
179 MPFS MPFSOpen(BYTE* file)
180 {
181 MPFS_ENTRY entry;
182 MPFS FAT;
183 BYTE fileNameLen;
184  
185 if( mpfsFlags.bits.bNotAvailable )
186 return MPFS_NOT_AVAILABLE;
187  
188 #if defined(MPFS_USE_EEPROM) || defined(MPFS_USE_SPI_FLASH)
189 FAT = MPFS_Start;
190 #else
191 FAT = (MPFS)MPFS_Start;
192 #endif
193  
194 // If string is empty, do not attempt to find it in FAT.
195 if ( *file == '\0' )
196 return MPFS_INVALID;
197  
198 file = (BYTE*)strupr((char*)file);
199  
200 while(1)
201 {
202 // Bring current FAT entry into RAM.
203 #if defined(MPFS_USE_EEPROM)
204 XEEReadArray(FAT, (unsigned char*)&entry, sizeof(entry));
205 #elif defined(MPFS_USE_SPI_FLASH)
206 SPIFlashReadArray(FAT, (BYTE*)&entry, sizeof(entry));
207 #else
208 #if defined(__C30__)
209 memcpypgm2ram(&entry, (ROM void*)(WORD)FAT, sizeof(entry));
210 #else
211 memcpypgm2ram(&entry, (ROM void*)FAT, sizeof(entry));
212 #endif
213 #endif
214  
215 // Make sure that it is a valid entry.
216 if (entry.Flag == MPFS_DATA)
217 {
218 // Does the file name match ?
219 fileNameLen = strlen((char*)file);
220 if ( fileNameLen > MAX_FILE_NAME_LEN )
221 fileNameLen = MAX_FILE_NAME_LEN;
222  
223 if( memcmp((void*)file, (void*)entry.Name, fileNameLen) == 0 )
224 {
225 _currentFile = (MPFS)entry.Address;
226 mpfsOpenCount++;
227 return entry.Address;
228 }
229  
230 // File does not match. Try next entry...
231 FAT += sizeof(entry);
232 }
233 else if ( entry.Flag == MPFS_ETX )
234 {
235 if ( entry.Address != (MPFS)MPFS_INVALID )
236 FAT = (MPFS)entry.Address;
237 else
238 break;
239 }
240 else
241 return (MPFS)MPFS_INVALID;
242 }
243 return (MPFS)MPFS_INVALID;
244 }
245  
246 MPFS MPFSOpenROM(ROM BYTE* file)
247 {
248 BYTE nameRAM[MAX_FILE_NAME_LEN+1];
249  
250 memcpypgm2ram(nameRAM, (ROM void*)file, strlenpgm((ROM char*)file));
251 nameRAM[strlenpgm((ROM char*)file)] = '\0';
252  
253 return MPFSOpen(nameRAM);
254 }
255  
256 /*********************************************************************
257 * Function: void MPFSClose(void)
258 *
259 * PreCondition: None
260 *
261 * Input: handle - File handle to be closed
262 *
263 * Output: None
264 *
265 * Side Effects: None
266 *
267 * Overview: None
268 *
269 * Note: None
270 ********************************************************************/
271 void MPFSClose(void)
272 {
273 _currentCount = 0;
274 mpfsFlags.bits.bNotAvailable = FALSE;
275 if ( mpfsOpenCount )
276 mpfsOpenCount--;
277 }
278  
279  
280 /*********************************************************************
281 * Function: BOOL MPFSGetBegin(MPFS hFile)
282 *
283 * PreCondition: MPFSOpen() != MPFS_INVALID &&
284 *
285 * Input: hFile - handle of file that is to be read
286 *
287 * Output: TRUE if successful
288 * !TRUE otherwise
289 *
290 * Side Effects: None
291 *
292 * Overview: Prepares MPFS storage media for subsequent reads.
293 *
294 * Note: None
295 ********************************************************************/
296 #if defined(MPFS_USE_EEPROM)
297 BOOL MPFSGetBegin(MPFS hFile)
298 {
299 _currentHandle = hFile;
300 return (XEEBeginRead(hFile) == XEE_SUCCESS);
301 }
302 #endif
303  
304 /*********************************************************************
305 * Function: BYTE MPFSGet(void)
306 *
307 * PreCondition: MPFSOpen() != MPFS_INVALID &&
308 * MPFSGetBegin() == TRUE
309 *
310 * Input: None
311 *
312 * Output: Data byte from current address.
313 *
314 * Side Effects: None
315 *
316 * Overview: Reads a byte from current address.
317 *
318 * Note: Caller must call MPFSIsEOF() to check for end of
319 * file condition
320 ********************************************************************/
321 BYTE MPFSGet(void)
322 {
323 BYTE t;
324  
325 #if defined(MPFS_USE_EEPROM)
326 t = XEERead();
327 _currentHandle++;
328 #elif defined(MPFS_USE_SPI_FLASH)
329 SPIFlashReadArray(_currentHandle++, (BYTE*)&t, 1);
330 #else
331 #if defined(__C30__)
332 {
333 DWORD_VAL i;
334  
335 // The uppermost byte, ((DWORD_VAL*)&_currentHandle)->v[3]), is the byte lane to read from.
336 // 16 bit PICs have a 24 bit wide Flash program word. Bytes 0-2 are the actual address, but
337 // odd addresses aren't implemented.
338 i.Val = ReadProgramMemory(_currentHandle & 0x00FFFFFF);
339 t = i.v[((DWORD_VAL*)&_currentHandle)->v[3]++];
340 if(((DWORD_VAL*)&_currentHandle)->v[3] >= 3)
341 {
342 _currentHandle = (_currentHandle + 2) & 0x00FFFFFF;
343 }
344 }
345 #else
346 t = (BYTE)*_currentHandle;
347 _currentHandle++;
348 #endif
349 #endif
350  
351 if(t == MPFS_DLE)
352 {
353 #if defined(MPFS_USE_EEPROM)
354 t = XEERead();
355 _currentHandle++;
356 #elif defined(MPFS_USE_SPI_FLASH)
357 SPIFlashReadArray(_currentHandle++, (BYTE*)&t, 1);
358 #else
359 #if defined(__C30__)
360 {
361 DWORD_VAL i;
362  
363 // The uppermost byte, ((DWORD_VAL*)&_currentHandle)->v[3]), is the byte lane to read from.
364 // 16 bit PICs have a 24 bit wide Flash program word. Bytes 0-2 are the actual address, but
365 // odd addresses aren't implemented.
366 i.Val = ReadProgramMemory(_currentHandle & 0x00FFFFFF);
367 t = i.v[((DWORD_VAL*)&_currentHandle)->v[3]++];
368 if(((DWORD_VAL*)&_currentHandle)->v[3] >= 3)
369 {
370 _currentHandle = (_currentHandle + 2) & 0x00FFFFFF;
371 }
372 }
373 #else
374 t = (BYTE)*_currentHandle;
375 _currentHandle++;
376 #endif
377 #endif
378 }
379 else if(t == MPFS_ETX)
380 {
381 _currentHandle = MPFS_INVALID;
382 }
383  
384 return t;
385 }
386  
387  
388 #if defined(__C30__) && !defined(MPFS_USE_EEPROM)
389 /*********************************************************************
390 * Function: static DWORD ReadProgramMemory(DWORD address)
391 *
392 * PreCondition: None
393 *
394 * Input: Program memory address to read from. Should be
395 * an even number.
396 *
397 * Output: Program word at the specified address. For the
398 * PIC24, dsPIC, etc. which have a 24 bit program
399 * word size, the upper byte is 0x00.
400 *
401 * Side Effects: None
402 *
403 * Overview: Modifies and restores TBLPAG. Make sure that if
404 * using interrupts and the PSV feature of the CPU
405 * in an ISR that the TBLPAG register is preloaded
406 * with the correct value (rather than assuming
407 * TBLPAG is always pointing to the .const section.
408 *
409 * Note: None
410 ********************************************************************/
411 static DWORD ReadProgramMemory(DWORD address)
412 {
413 DWORD dwResult;
414 WORD wTBLPAGSave;
415  
416 wTBLPAGSave = TBLPAG;
417 TBLPAG = ((WORD*)&address)[1];
418 ((WORD*)&dwResult)[1] = __builtin_tblrdh((WORD)address);
419 ((WORD*)&dwResult)[0] = __builtin_tblrdl((WORD)address);
420 TBLPAG = wTBLPAGSave;
421  
422 return dwResult;
423 }
424 #endif
425  
426  
427 /*********************************************************************
428 * Function: MPFS MPFSGetEnd(void)
429 *
430 * PreCondition: MPFSOpen() != MPFS_INVALID &&
431 * MPFSGetBegin() = TRUE
432 *
433 * Input: None
434 *
435 * Output: Current mpfs handle.
436 *
437 * Side Effects: None
438 *
439 * Overview: Ends on-going read cycle.
440 * MPFS handle that is returned must be used
441 * for subsequent begin gets..
442 *
443 * Note: None
444 ********************************************************************/
445 #if defined(MPFS_USE_EEPROM)
446 MPFS MPFSGetEnd(void)
447 {
448 XEEEndRead();
449 return _currentHandle;
450 }
451 #endif
452  
453  
454 /*********************************************************************
455 * Function: MPFS MPFSFormat(void)
456 *
457 * PreCondition: None
458 *
459 * Input: None
460 *
461 * Output: A valid MPFS handle that can be used for MPFSPut
462 *
463 * Side Effects: None
464 *
465 * Overview: Prepares MPFS image to get re-written
466 * Declares MPFS as in use.
467 *
468 * Note: MPFS will be unaccessible until MPFSClose is
469 * called.
470 ********************************************************************/
471 MPFS MPFSFormat(void)
472 {
473 mpfsFlags.bits.bNotAvailable = TRUE;
474 #if defined(MPFS_USE_SPI_FLASH)
475 SPIFlashBeginWrite(MPFS_RESERVE_BLOCK);
476 #endif
477 return (MPFS)MPFS_RESERVE_BLOCK;
478 }
479  
480  
481 /*********************************************************************
482 * Function: BOOL MPFSPutBegin(MPFS handle)
483 *
484 * PreCondition: MPFSInit() and MPFSFormat() are already called.
485 *
486 * Input: handle - handle to where put to begin
487 *
488 * Output: TRUE if successful
489 * !TRUE otherwise
490 *
491 * Side Effects: None
492 *
493 * Overview: Prepares MPFS image to get re-written
494 *
495 * Note: MPFS will be unaccessible until MPFSClose is
496 * called.
497 ********************************************************************/
498 #if defined(MPFS_USE_EEPROM)
499 BOOL MPFSPutBegin(MPFS handle)
500 {
501 //_currentCount = 0;
502 _currentHandle = handle;
503 _currentCount = (BYTE)handle;
504 _currentCount &= (MPFS_WRITE_PAGE_SIZE-1);
505 return (XEEBeginWrite(handle) == XEE_SUCCESS);
506 }
507 #endif
508  
509  
510 /*********************************************************************
511 * Function: BOOL MPFSPut(BYTE b)
512 *
513 * PreCondition: MPFSFormat() or MPFSCreate() must be called
514 * MPFSPutBegin() is already called.
515 *
516 * Input: b - data to write.
517 *
518 * Output: TRUE if successfull
519 * !TRUE if failed.
520 *
521 * Side Effects: Original MPFS handle is no longer valid.
522 * Updated MPFS handle must be obtained by calling
523 * MPFSPutEnd().
524 *
525 * Overview: None
526 *
527 * Note: Actual write may not get started until internal
528 * write page is full. To ensure that previously
529 * data gets written, caller must call MPFSPutEnd()
530 * after last call to MPFSPut().
531 ********************************************************************/
532 BOOL MPFSPut(BYTE b)
533 {
534 #if defined(MPFS_USE_EEPROM)
535 if ( XEEWrite(b) )
536 return FALSE;
537  
538 _currentCount++;
539 _currentHandle++;
540 if ( _currentCount >= MPFS_WRITE_PAGE_SIZE )
541 {
542 MPFSPutEnd();
543 XEEBeginWrite(_currentHandle);
544 }
545 #elif defined(MPFS_USE_SPI_FLASH)
546 SPIFlashWrite(b);
547 #endif
548 return TRUE;
549 }
550  
551 /*********************************************************************
552 * Function: MPFS MPFSPutEnd(void)
553 *
554 * PreCondition: MPFSPutBegin() is already called.
555 *
556 * Input: None
557 *
558 * Output: Up-to-date MPFS handle
559 *
560 * Side Effects: Original MPFS handle is no longer valid.
561 * Updated MPFS handle must be obtained by calling
562 * MPFSPutEnd().
563 *
564 * Overview: None
565 *
566 * Note: Actual write may not get started until internal
567 * write page is full. To ensure that previously
568 * data gets written, caller must call MPFSPutEnd()
569 * after last call to MPFSPut().
570 ********************************************************************/
571 MPFS MPFSPutEnd(void)
572 {
573 #if defined(MPFS_USE_EEPROM)
574 _currentCount = 0;
575 XEEEndWrite();
576 while(XEEIsBusy());
577 #endif
578  
579 return _currentHandle;
580 }
581  
582 /*********************************************************************
583 * Function: MPFS MPFSSeek(MPFS offset)
584 *
585 * PreCondition: MPFSGetBegin() is already called.
586 *
587 * Input: offset - Offset from current pointer
588 *
589 * Output: New MPFS handle located to given offset
590 *
591 * Side Effects: None.
592 *
593 * Overview: None
594 *
595 * Note: None.
596 ********************************************************************/
597 MPFS MPFSSeek(MPFS offset)
598 {
599 MPFS i;
600  
601 MPFSGetBegin(_currentFile);
602  
603 i = (MPFS)0;
604 while(i++ != offset)
605 MPFSGet();
606  
607 MPFSGetEnd();
608  
609 return _currentHandle;
610 }
611  
612  
613 /*********************************************************************
614 * Function: BOOL MPFSGetLong(DWORD *ul)
615 *
616 * PreCondition: MPFSOpen() and MPFSBeginGet()
617 *
618 * Input: ul: pointer to an DWORD to read
619 *
620 * Output: TRUE on success
621 * FALSE on EOF
622 *
623 * Side Effects: None
624 *
625 * Overview: Reads an DWORD value from an MPFS file
626 *
627 * Note: None
628 ********************************************************************/
629 BOOL MPFSGetLong(DWORD *ul)
630 {
631 BYTE* b = (BYTE*)ul;
632 *(b) = MPFSGet();
633 if(MPFSIsEOF())
634 return FALSE;
635 *(b+1) = MPFSGet();
636 *(b+2) = MPFSGet();
637 *(b+3) = MPFSGet();
638  
639 return TRUE;
640 }
641  
642 #endif //#if defined(STACK_USE_MPFS)
{BLAME END}
{FOOTER START}

Powered by WebSVN v2.8.3