Subversion Repositories HomeAutomation

Rev

Rev 363 | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  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. }
  503.