Subversion Repositories HomeAutomation

Rev

Details | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
363 johboh 1
/*********************************************************************
2
 *
3
 *               Microchip File System Implementaion on PIC18
4
 *
5
 *********************************************************************
6
 * FileName:        MPFS.c
7
 * Dependencies:    StackTsk.h
8
 *                  MPFS.h
9
 * Processor:       PIC18, PIC24F, PIC24H, dsPIC30F, dsPIC33F
10
 * Complier:        Microchip C18 v3.02 or higher
11
 *                  Microchip C30 v2.01 or higher
12
 * Company:         Microchip Technology, Inc.
13
 *
14
 * Software License Agreement
15
 *
16
 * This software is owned by Microchip Technology Inc. ("Microchip")
17
 * and is supplied to you for use exclusively as described in the
18
 * associated software agreement.  This software is protected by
19
 * software and other intellectual property laws.  Any use in
20
 * violation of the software license may subject the user to criminal
21
 * sanctions as well as civil liability.  Copyright 2006 Microchip
22
 * Technology Inc.  All rights reserved.
23
 *
24
 * This software is provided "AS IS."  MICROCHIP DISCLAIMS ALL
25
 * WARRANTIES, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, NOT LIMITED
26
 * TO MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
27
 * INFRINGEMENT.  Microchip shall in no event be liable for special,
28
 * incidental, or consequential damages.
29
 *
30
 *
31
 * Author               Date        Comment
32
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
33
 * Nilesh Rajbharti     8/14/01     Original (Rev. 1.0)
34
 * Nilesh Rajbharti     2/9/02      Cleanup
35
 * Nilesh Rajbharti     5/22/02     Rev 2.0 (See version.log for detail)
36
 * Howard Schlunder     3/31/05     Changed MPFS_ENTRY and mpfs_Flags for C30
37
********************************************************************/
38
#define THIS_IS_MPFS
39
 
40
#include <string.h>
41
#include <stdlib.h>
42
 
43
#include "..\Include\MPFS.h"
44
#include "..\Include\Helpers.h"
45
 
46
#if defined(MPFS_USE_EEPROM)
47
    #include "..\Include\XEEPROM.h"
48
#endif
49
// This file system supports short file names i.e. 8 + 3.
50
#define MAX_FILE_NAME_LEN   (12u)
51
 
52
#define MPFS_DATA          (0x00u)
53
#define MPFS_DELETED       (0x01u)
54
#define MPFS_DLE           (0x03u)
55
#define MPFS_ETX           (0x04u)
56
 
57
/*
58
 * MPFS Structure:
59
 *
60
 * MPFS_Start:
61
 *      <MPFS_DATA><Address1><FileName1>
62
 *      <MPFS_DATA><Address2><FileName2>
63
 *      ...
64
 *      <MPFS_ETX><Addressn><FileNamen>
65
 * Address1:
66
 *      <Data1>[<Data2>...<Datan>]<MPFS_ETX><MPFS_INVALID>
67
 *      ...
68
 *
69
 * Note: If File data contains either MPFS_DLE or MPFS_ETX
70
 *       extra MPFS_DLE is stuffed before that byte.
71
 */
72
#ifdef MPFS_USE_PGRM
73
typedef struct  _MPFS_ENTRY
74
{
75
    BYTE Flag;
76
    MPFS Address;
77
    BYTE Name[MAX_FILE_NAME_LEN];
78
} MPFS_ENTRY;
79
#else   //MPFS_USE_EEPROM
80
typedef struct  _MPFS_ENTRY
81
{
82
    BYTE Flag __attribute__((__packed__));
83
    MPFS Address __attribute__((__packed__));
84
    BYTE Name[MAX_FILE_NAME_LEN] __attribute__((__packed__));
85
} MPFS_ENTRY;
86
#endif
87
 
88
static union
89
{
90
    struct
91
    {
92
        unsigned char bNotAvailable : 1;
93
    } bits;
94
    BYTE Val;
95
} mpfsFlags;
96
 
97
BYTE mpfsOpenCount;
98
 
99
#if defined(MPFS_USE_PGRM)
100
 
101
    // An address where MPFS data starts in program memory.
102
    extern MPFS MPFS_Start;
103
 
104
#else
105
 
106
#define MPFS_Start     MPFS_RESERVE_BLOCK
107
 
108
#endif
109
 
110
MPFS _currentHandle;
111
MPFS _currentFile;
112
BYTE _currentCount;
113
 
114
 
115
/*********************************************************************
116
 * Function:        BOOL MPFSInit(void)
117
 *
118
 * PreCondition:    None
119
 *
120
 * Input:           None
121
 *
122
 * Output:          TRUE, if MPFS Storage access is initialized and
123
 *                          MPFS is ready to be used.
124
 *                  FALSE otherwise
125
 *
126
 * Side Effects:    None
127
 *
128
 * Overview:        None
129
 *
130
 * Note:            None
131
 ********************************************************************/
132
BOOL MPFSInit(void)
133
{
134
    mpfsOpenCount = 0;
135
    mpfsFlags.Val = 0;
136
 
137
#if defined(MPFS_USE_PGRM)
138
    return TRUE;
139
#else
140
    /*
141
     * Initialize the EEPROM access routines.
142
     * Use ~ 400 Khz.
143
     */
144
    XEEInit(EE_BAUD(CLOCK_FREQ, 400000));
145
 
146
    return TRUE;
147
#endif
148
}
149
 
150
 
151
/*********************************************************************
152
 * Function:        MPFS MPFSOpen(BYTE* file)
153
 *
154
 * PreCondition:    None
155
 *
156
 * Input:           file        - NULL terminated file name.
157
 *
158
 * Output:          A handle if file is found
159
 *                  MPFS_INVALID if file is not found.
160
 *
161
 * Side Effects:    None
162
 *
163
 * Overview:        None
164
 *
165
 * Note:            None
166
 ********************************************************************/
167
MPFS MPFSOpen(BYTE* file)
168
{
169
    MPFS_ENTRY entry;
170
    MPFS FAT;
171
    BYTE fileNameLen;
172
 
173
    if( mpfsFlags.bits.bNotAvailable )
174
        return MPFS_NOT_AVAILABLE;
175
 
176
#if defined(MPFS_USE_PGRM)
177
    FAT = (MPFS)&MPFS_Start;
178
#else
179
    FAT = MPFS_Start;
180
#endif
181
 
182
    // If string is empty, do not attempt to find it in FAT.
183
    if ( *file == '\0' )
184
        return MPFS_INVALID;
185
 
186
    file = (BYTE*)strupr((char*)file);
187
 
188
    while(1)
189
    {
190
#if defined(MPFS_USE_PGRM)
191
        // Bring current FAT entry into RAM.
192
        memcpypgm2ram(&entry, (ROM void*)FAT, sizeof(entry));
193
#else
194
        XEEReadArray(EEPROM_CONTROL, FAT, (unsigned char*)&entry, sizeof(entry));
195
#endif
196
 
197
        // Make sure that it is a valid entry.
198
        if (entry.Flag == MPFS_DATA)
199
        {
200
            // Does the file name match ?
201
            fileNameLen = strlen((char*)file);
202
            if ( fileNameLen > MAX_FILE_NAME_LEN )
203
                fileNameLen = MAX_FILE_NAME_LEN;
204
 
205
            if( memcmp((void*)file, (void*)entry.Name, fileNameLen) == 0 )
206
            {
207
                _currentFile = (MPFS)entry.Address;
208
                mpfsOpenCount++;
209
                return entry.Address;
210
            }
211
 
212
            // File does not match.  Try next entry...
213
            FAT += sizeof(entry);
214
        }
215
        else if ( entry.Flag == MPFS_ETX )
216
        {
217
            if ( entry.Address != (MPFS)MPFS_INVALID )
218
                FAT = (MPFS)entry.Address;
219
            else
220
                break;
221
        }
222
        else
223
            return (MPFS)MPFS_INVALID;
224
    }
225
    return (MPFS)MPFS_INVALID;
226
}
227
 
228
 
229
/*********************************************************************
230
 * Function:        void MPFSClose(void)
231
 *
232
 * PreCondition:    None
233
 *
234
 * Input:           handle      - File handle to be closed
235
 *
236
 * Output:          None
237
 *
238
 * Side Effects:    None
239
 *
240
 * Overview:        None
241
 *
242
 * Note:            None
243
 ********************************************************************/
244
void MPFSClose(void)
245
{
246
    _currentCount = 0;
247
    mpfsFlags.bits.bNotAvailable = FALSE;
248
    if ( mpfsOpenCount )
249
        mpfsOpenCount--;
250
}
251
 
252
 
253
/*********************************************************************
254
 * Function:        BOOL MPFSGetBegin(MPFS handle)
255
 *
256
 * PreCondition:    MPFSOpen() != MPFS_INVALID &&
257
 *
258
 * Input:           handle      - handle of file that is to be read
259
 *
260
 * Output:          TRUE if successful
261
 *                  !TRUE otherwise
262
 *
263
 * Side Effects:    None
264
 *
265
 * Overview:        Prepares MPFS storage media for subsequent reads.
266
 *
267
 * Note:            None
268
 ********************************************************************/
269
#if defined(MPFS_USE_EEPROM)
270
BOOL MPFSGetBegin(MPFS handle)
271
{
272
    _currentHandle = handle;
273
    return (XEEBeginRead(EEPROM_CONTROL, handle) == XEE_SUCCESS);
274
}
275
#endif
276
 
277
/*********************************************************************
278
 * Function:        BYTE MPFSGet(void)
279
 *
280
 * PreCondition:    MPFSOpen() != MPFS_INVALID &&
281
 *                  MPFSGetBegin() == TRUE
282
 *
283
 * Input:           None
284
 *
285
 * Output:          Data byte from current address.
286
 *
287
 * Side Effects:    None
288
 *
289
 * Overview:        Reads a byte from current address.
290
 *
291
 * Note:            Caller must call MPFSIsEOF() to check for end of
292
 *                  file condition
293
 ********************************************************************/
294
BYTE MPFSGet(void)
295
{
296
    BYTE t;
297
 
298
#if defined(MPFS_USE_PGRM)
299
    t = (BYTE)*_currentHandle;
300
#else
301
    t = XEERead();
302
#endif
303
    _currentHandle++;
304
 
305
    if ( t == MPFS_DLE )
306
    {
307
#if defined(MPFS_USE_PGRM)
308
        t = (BYTE)*_currentHandle;
309
#else
310
        t = XEERead();
311
#endif
312
        _currentHandle++;
313
    }
314
    else if ( t == MPFS_ETX )
315
    {
316
        _currentHandle = MPFS_INVALID;
317
    }
318
 
319
    return t;
320
 
321
}
322
 
323
 
324
/*********************************************************************
325
 * Function:        MPFS MPFSGetEnd(void)
326
 *
327
 * PreCondition:    MPFSOpen() != MPFS_INVALID &&
328
 *                  MPFSGetBegin() = TRUE
329
 *
330
 * Input:           None
331
 *
332
 * Output:          Current mpfs handle.
333
 *
334
 * Side Effects:    None
335
 *
336
 * Overview:        Ends on-going read cycle.
337
 *                  MPFS handle that is returned must be used
338
 *                  for subsequent begin gets..
339
 *
340
 * Note:            None
341
 ********************************************************************/
342
#if defined(MPFS_USE_EEPROM)
343
MPFS MPFSGetEnd(void)
344
{
345
    XEEEndRead();
346
    return _currentHandle;
347
}
348
#endif
349
 
350
 
351
/*********************************************************************
352
 * Function:        MPFS MPFSFormat(void)
353
 *
354
 * PreCondition:    None
355
 *
356
 * Input:           None
357
 *
358
 * Output:          A valid MPFS handle that can be used for MPFSPut
359
 *
360
 * Side Effects:    None
361
 *
362
 * Overview:        Prepares MPFS image to get re-written
363
 *                  Declares MPFS as in use.
364
 *
365
 * Note:            MPFS will be unaccessible until MPFSClose is
366
 *                  called.
367
 ********************************************************************/
368
MPFS MPFSFormat(void)
369
{
370
    mpfsFlags.bits.bNotAvailable = TRUE;
371
    return (MPFS)MPFS_RESERVE_BLOCK;
372
}
373
 
374
 
375
/*********************************************************************
376
 * Function:        BOOL MPFSPutBegin(MPFS handle)
377
 *
378
 * PreCondition:    MPFSInit() and MPFSFormat() are already called.
379
 *
380
 * Input:           handle  - handle to where put to begin
381
 *
382
 * Output:          TRUE if successful
383
 *                  !TRUE otherwise
384
 *
385
 * Side Effects:    None
386
 *
387
 * Overview:        Prepares MPFS image to get re-written
388
 *
389
 * Note:            MPFS will be unaccessible until MPFSClose is
390
 *                  called.
391
 ********************************************************************/
392
#if defined(MPFS_USE_EEPROM)
393
BOOL MPFSPutBegin(MPFS handle)
394
{
395
    //_currentCount = 0;
396
    _currentHandle = handle;
397
    _currentCount = (BYTE)handle;
398
    _currentCount &= (MPFS_WRITE_PAGE_SIZE-1);
399
    return (XEEBeginWrite(EEPROM_CONTROL, handle) == XEE_SUCCESS);
400
}
401
#endif
402
 
403
 
404
/*********************************************************************
405
 * Function:        BOOL MPFSPut(BYTE b)
406
 *
407
 * PreCondition:    MPFSFormat() or MPFSCreate() must be called
408
 *                  MPFSPutBegin() is already called.
409
 *
410
 * Input:           b       - data to write.
411
 *
412
 * Output:          TRUE if successfull
413
 *                  !TRUE if failed.
414
 *
415
 * Side Effects:    Original MPFS handle is no longer valid.
416
 *                  Updated MPFS handle must be obtained by calling
417
 *                  MPFSPutEnd().
418
 *
419
 * Overview:        None
420
 *
421
 * Note:            Actual write may not get started until internal
422
 *                  write page is full.  To ensure that previously
423
 *                  data gets written, caller must call MPFSPutEnd()
424
 *                  after last call to MPFSPut().
425
 ********************************************************************/
426
BOOL MPFSPut(BYTE b)
427
{
428
#if defined(MPFS_USE_EEPROM)
429
    if ( XEEWrite(b) )
430
        return FALSE;
431
 
432
    _currentCount++;
433
    _currentHandle++;
434
    if ( _currentCount >= MPFS_WRITE_PAGE_SIZE )
435
    {
436
        MPFSPutEnd();
437
        XEEBeginWrite(EEPROM_CONTROL, _currentHandle);
438
    }
439
#endif
440
    return TRUE;
441
}
442
 
443
/*********************************************************************
444
 * Function:        MPFS MPFSPutEnd(void)
445
 *
446
 * PreCondition:    MPFSPutBegin() is already called.
447
 *
448
 * Input:           None
449
 *
450
 * Output:          Up-to-date MPFS handle
451
 *
452
 * Side Effects:    Original MPFS handle is no longer valid.
453
 *                  Updated MPFS handle must be obtained by calling
454
 *                  MPFSPutEnd().
455
 *
456
 * Overview:        None
457
 *
458
 * Note:            Actual write may not get started until internal
459
 *                  write page is full.  To ensure that previously
460
 *                  data gets written, caller must call MPFSPutEnd()
461
 *                  after last call to MPFSPut().
462
 ********************************************************************/
463
MPFS MPFSPutEnd(void)
464
{
465
#if defined(MPFS_USE_EEPROM)
466
    _currentCount = 0;
467
    XEEEndWrite();
468
    while( XEEIsBusy(EEPROM_CONTROL) );
469
#endif
470
 
471
    return _currentHandle;
472
}
473
 
474
/*********************************************************************
475
 * Function:        MPFS MPFSSeek(MPFS_OFFSET offset)
476
 *
477
 * PreCondition:    MPFSGetBegin() is already called.
478
 *
479
 * Input:           offset      - Offset from current pointer
480
 *
481
 * Output:          New MPFS handle located to given offset
482
 *
483
 * Side Effects:    None.
484
 *
485
 * Overview:        None
486
 *
487
 * Note:            None.
488
 ********************************************************************/
489
MPFS MPFSSeek(MPFS_OFFSET offset)
490
{
491
    WORD i;
492
 
493
    MPFSGetBegin(_currentFile);
494
 
495
    i = 0;
496
    while(i++ != offset)
497
        MPFSGet();
498
 
499
    MPFSGetEnd();
500
 
501
    return _currentHandle;
502
}