00001 /*! \file WaspSD.h 00002 \brief Library for managing the SD Card 00003 00004 Copyright (C) 2009 Libelium Comunicaciones Distribuidas S.L. 00005 http://www.libelium.com 00006 00007 This program is free software: you can redistribute it and/or modify 00008 it under the terms of the GNU Lesser General Public License as published by 00009 the Free Software Foundation, either version 2.1 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU Lesser General Public License for more details. 00016 00017 You should have received a copy of the GNU Lesser General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. 00019 00020 Version: 0.6 00021 00022 Design: David Gascón 00023 00024 Implementation: David Cuartielles, Alberto Bielsa, Roland Riegel, Ingo Korb, Aske Olsson 00025 00026 */ 00027 00028 00029 00030 /*! \def WaspSD_h 00031 \brief The library flag 00032 00033 */ 00034 #ifndef WaspSD_h 00035 #define WaspSD_h 00036 00037 /****************************************************************************** 00038 * Includes 00039 ******************************************************************************/ 00040 00041 #include <inttypes.h> 00042 //the low level FAT16/32 libraries 00043 #include "sd_raw_config.h" 00044 #include "sd_raw.h" 00045 #include "partition.h" 00046 #include "fat_config.h" 00047 #include "fat.h" 00048 00049 /****************************************************************************** 00050 * Definitions & Declarations 00051 ******************************************************************************/ 00052 00053 /*! \def VERSION 00054 \brief Version Control 00055 */ 00056 #define VERSION "WaspSD 01a, (c) 2009 Libelium.com\n" 00057 00058 /*! \def FILESYSTEM_LINUX 00059 \brief determines the type of EOL character, uncomment for Windows, leave for LIN/MAC 00060 */ 00061 #define FILESYSTEM_LINUX 00062 00063 /*! \def DOS_BUFFER_SIZE 00064 \brief Buffer size for storing data 00065 */ 00066 /*! \def BIN_BUFFER_SIZE 00067 \brief Buffer size for storing binary data 00068 */ 00069 #define DOS_BUFFER_SIZE 256 00070 #define BIN_BUFFER_SIZE 100 00071 00072 /*! \def NAMES 00073 \brief shows information available from files and directories. It shows the name 00074 */ 00075 /*! \def SIZES 00076 \brief shows information available from files and directories. It shows the size 00077 */ 00078 /*! \def ATTRIBUTES 00079 \brief shows information available from files and directories. It shows the attributes 00080 */ 00081 #define NAMES 0 00082 #define SIZES 1 00083 #define ATTRIBUTES 2 00084 00085 /*! \def NOTHING_FAILED 00086 \brief Flag possible values. Nothing failed in this case 00087 */ 00088 /*! \def CARD_NOT_PRESENT 00089 \brief Flag possible values. Card not present in this case 00090 */ 00091 /*! \def INIT_FAILED 00092 \brief Flag possible values. Initialization failed in this case 00093 */ 00094 /*! \def PARTITION_FAILED 00095 \brief Flag possible values. Opening partition failed in this case 00096 */ 00097 /*! \def FILESYSTEM_FAILED 00098 \brief Flag possible values. Opening filesystem failed in this case 00099 */ 00100 /*! \def ROOT_DIR_FAILED 00101 \brief Flag possible values. Opening root directory failed in this case 00102 */ 00103 /*! \def TRUNCATED_DATA 00104 \brief Flag possible values. Data has been truncated in this case 00105 */ 00106 /*! \def FILE_OPEN_ERROR 00107 \brief Flag possible values. Opening a file failed in this case 00108 */ 00109 /*! \def FILE_CREATION_ERROR 00110 \brief Flag possible values. Creating a file failed in this case 00111 */ 00112 /*! \def DIR_CREATION_ERROR 00113 \brief Flag possible values. Creating a directory failed in this case 00114 */ 00115 /*! \def FILE_WRITING_ERROR 00116 \brief Flag possible values. Writing a file failed in this case 00117 */ 00118 #define NOTHING_FAILED 0 00119 #define CARD_NOT_PRESENT 1 00120 #define INIT_FAILED 2 00121 #define PARTITION_FAILED 4 00122 #define FILESYSTEM_FAILED 8 00123 #define ROOT_DIR_FAILED 16 00124 #define TRUNCATED_DATA 32 00125 #define FILE_OPEN_ERROR 64 00126 #define FILE_CREATION_ERROR 128 00127 #define DIR_CREATION_ERROR 256 00128 #define FILE_WRITING_ERROR 512 00129 00130 00131 /*! \def NOTHING_FAILED_em 00132 \brief Flag error messages. Nothing failed in this case 00133 */ 00134 /*! \def CARD_NOT_PRESENT_em 00135 \brief Flag possible values. Card not present in this case 00136 */ 00137 /*! \def INIT_FAILED_em 00138 \brief Flag possible values. Initialization failed in this case 00139 */ 00140 /*! \def PARTITION_FAILED_em 00141 \brief Flag possible values. Opening partition failed in this case 00142 */ 00143 /*! \def FILESYSTEM_FAILED_em 00144 \brief Flag possible values. Opening filesystem failed in this case 00145 */ 00146 /*! \def ROOT_DIR_FAILED_em 00147 \brief Flag possible values. Opening root directory failed in this case 00148 */ 00149 #define NOTHING_FAILED_em "OK" 00150 #define CARD_NOT_PRESENT_em "no SD in the slot" 00151 #define INIT_FAILED_em "MMC/SD initialization failed" 00152 #define PARTITION_FAILED_em "Opening partition failed" 00153 #define FILESYSTEM_FAILED_em "Opening filesystem failed" 00154 #define ROOT_DIR_FAILED_em "Opening root dir failed" 00155 00156 00157 /*! \def SD_ON 00158 \brief SD Power Modes. ON in this case 00159 */ 00160 /*! \def SD_OFF 00161 \brief SD Power Modes. OFF in this case 00162 */ 00163 #define SD_ON 1 00164 #define SD_OFF 2 00165 00166 /****************************************************************************** 00167 * Class 00168 ******************************************************************************/ 00169 00170 //! WaspSD Class 00171 /*! 00172 WaspSD Class defines all the variables and functions used to manage the SD Card 00173 */ 00174 class WaspSD 00175 { 00176 private: 00177 00178 public: 00179 00180 //! Variable : buffer containing the information coming from the card used to avoid calls to UART functions inside the library. Beware, there could be data longer than the buffer size 00181 /*! 00182 */ 00183 char buffer[DOS_BUFFER_SIZE]; 00184 00185 //! Variable : buffer containing the binary information coming from the card used to avoid calls to UART functions inside the library. Beware, there could be data longer than the buffer size 00186 /*! 00187 */ 00188 uint8_t bufferBin[BIN_BUFFER_SIZE]; 00189 00190 //! Variable : flag storing the state of the SD card during initialization and operation 00191 /*! 00192 */ 00193 uint16_t flag; 00194 00195 //! Variable : It stores the SD power mode. Possible values are SD_ON or SD_OFF 00196 /*! 00197 */ 00198 uint8_t _pwrMode; 00199 00200 00201 //! Structure pointer : filesystem pointer 00202 /*! 00203 */ 00204 struct fat_fs_struct* fs; 00205 00206 //! Structure pointer : partition pointer 00207 /*! 00208 */ 00209 struct partition_struct* partition; 00210 00211 //! Structure pointer : directory structure pointer 00212 /*! 00213 */ 00214 struct fat_dir_struct* dd; 00215 00216 //! Structure pointer : generic file pointer 00217 /*! 00218 */ 00219 struct fat_file_struct* fd; 00220 00221 //! Variable : amount of free bytes in the drive 00222 /*! 00223 */ 00224 offset_t diskFree; 00225 00226 //! Variable : total byte size of the drive 00227 /*! 00228 */ 00229 offset_t diskSize; 00230 00231 //! class constructor 00232 /*! 00233 It does nothing 00234 \param void 00235 \return void 00236 */ 00237 WaspSD(); 00238 00239 //! It clears the flag 00240 /*! 00241 It does nothing 00242 \param void 00243 \return 'flag' variable 00244 */ 00245 uint16_t cleanFlags(void); 00246 00247 00248 //! It checks if there is a SD Card in the slot 00249 /*! 00250 \param void 00251 \return '1' if SD is present, '0' otherwise 00252 */ 00253 uint8_t isSD (); 00254 00255 //! It powers the SD card, initialize it and prepare it to work with 00256 /*! 00257 \param void 00258 \return void 00259 \sa close(), begin() 00260 */ 00261 void ON(); 00262 00263 //! It powers off the SD card and closes the pointers 00264 /*! 00265 \param void 00266 \return void 00267 \sa close(), begin() 00268 */ 00269 void OFF(); 00270 00271 //! It initializes the use of SD cards, looks into the root partition, opens the file system and initializes the public pointer that can be used to access the filesystem 00272 /*! 00273 \param void 00274 \return human readable string indicating success or possible errors that can be printed by the user directly 00275 */ 00276 char* init(); 00277 00278 //! It closes the directory, filesystem and partition pointers 00279 /*! 00280 This function closes all the pointers in use in the library, so that they can be reused again after a call to init(). It becomes very useful if e.g. the card is removed and inserted again 00281 \param void 00282 \return void 00283 */ 00284 void close(); 00285 00286 //! It sets switch and sd_present pin as output and input 00287 /*! 00288 \param void 00289 \return void 00290 */ 00291 void begin(); 00292 00293 //! It sets power mode 00294 /*! 00295 \param uint8_t mode : SD_ON or SD_OFF 00296 \return void 00297 */ 00298 void setMode(uint8_t mode); 00299 00300 //! It packs all the data about the disk into the buffer and returns it back. The buffer will then be available and offer the data to the developers as a human-readable encoded string. 00301 /*! 00302 \param void 00303 \return human readable string indicating success or possible errors that can be printed by the user directly 00304 */ 00305 char* print_disk_info(); 00306 00307 //! It gets the total disk size 00308 /*! 00309 \param void 00310 \return the total size for the disk 00311 */ 00312 offset_t getDiskSize(); 00313 00314 //! It gets the free disk size 00315 /*! 00316 \param void 00317 \return the total available space for the disk 00318 */ 00319 offset_t getDiskFree(); 00320 00321 //! It changes the directory 00322 /*! 00323 \param const char* command : the directory we want to change to 00324 \return '1' on success, '0' if error 00325 \sa cd(struct fat_dir_entry_struct subdir_entry) 00326 */ 00327 uint8_t cd(const char* command); 00328 00329 //! It changes the directory 00330 /*! 00331 \param struct fat_dir_entry_struct subdir_entry : the directory we want to change to 00332 \return '1' on success, '0' if error 00333 \sa cd(const char* command) 00334 */ 00335 uint8_t cd(struct fat_dir_entry_struct subdir_entry); 00336 00337 //! It gets the amount of files in a directory 00338 /*! 00339 \param void 00340 \return '0' if no files, a negative value if error and a possitive value indicating the amount of files 00341 */ 00342 int8_t numFiles(); 00343 00344 //! It lists a directory 00345 /*! 00346 \param void 00347 \return 'buffer' variable containing the corresponding listing 00348 \sa ls(int offset), ls(int offset, int scope, uint8_t info) 00349 */ 00350 char* ls(void); 00351 00352 //! It lists a directory 00353 /*! 00354 \param int offset : it jumps over "offset" filenames in the list 00355 \return 'buffer' variable containing the corresponding listing 00356 \sa ls(void), ls(int offset, int scope, uint8_t info) 00357 */ 00358 char* ls(int offset); 00359 00360 //! It lists a directory 00361 /*! 00362 \param int offset : it jumps over "offset" filenames in the list 00363 \param int scope : it includes a total of "scope" filenames in the buffer 00364 \param int info : limits the amount of information to be sent back, ranges from NAMES, SIZES, to ATTRIBUTES 00365 \return 'buffer' variable containing the corresponding listing 00366 \sa ls(void), ls(int offset) 00367 */ 00368 char* ls(int offset, int scope, uint8_t info); 00369 00370 //! It tests existence of files in the dd folder 00371 /*! 00372 \param const char* name : the file to find 00373 \param struct fat_dir_entry_struct* dir_entry : the directory pointer to find the file in 00374 \return '1' if the file is availabe, '0' otherwise 00375 */ 00376 uint8_t find_file_in_dir(const char* name, struct fat_dir_entry_struct* dir_entry); 00377 00378 //! It creates a directory 00379 /*! 00380 \param const char* dirname : the directory to create 00381 \return '1' on success, '0' otherwise 00382 */ 00383 uint8_t mkdir(const char* dirname); 00384 00385 //! It checks if an entry is a file or a directory 00386 /*! 00387 \param struct fat_dir_entry_struct file_entry : the entry to check 00388 \return '1' if it is a directory, '0' otherwise 00389 \sa isDir(const char* dirname) 00390 */ 00391 uint8_t isDir(struct fat_dir_entry_struct file_entry); 00392 00393 //! It checks if an entry is a file or a directory 00394 /*! 00395 \param const char* dirname : the entry to check 00396 \return '1' if it is a directory, '0' otherwise 00397 \sa isDir(struct fat_dir_entry_struct file_entry) 00398 */ 00399 int8_t isDir(const char* dirname); 00400 00401 //! It deletes a file or a directory 00402 /*! 00403 It allows only erasing depth one directories, thus if the user calls to erase a directory with subdirs, it will exit with error without erasing the directory . 00404 It also allows erasing current directory "." under the same premises: it should contain no subdirectories or it will exit with error. 00405 Thanks to this function, together with delFile, delDir and isDir it is possible to create more complex delete functions that could iterate through any directory structure 00406 \param const char* name : the file or directory to delete 00407 \return '1' on success, '0' otherwise 00408 \sa delDir(uint8_t depth), delFile(struct fat_dir_entry_struct file_entry) 00409 */ 00410 uint8_t del(const char* name); 00411 00412 //! It deletes a directory 00413 /*! 00414 It allows only erasing depth one directories, thus if the user calls to erase a directory with subdirs, it will exit with error without erasing the directory . 00415 It also allows erasing current directory "." under the same premises: it should contain no subdirectories or it will exit with error. 00416 Thanks to this function, together with delFile, del and isDir it is possible to create more complex delete functions that could iterate through any directory structure 00417 \param uint8_t depth : is still not used, but function supports developers actualizations 00418 \return '1' on success, '0' otherwise 00419 \sa del(const char* name), delFile(struct fat_dir_entry_struct file_entry) 00420 */ 00421 uint8_t delDir(uint8_t depth); 00422 00423 //! It deletes a file 00424 /*! 00425 Thanks to this function, together with delDir, del and isDir it is possible to create more complex delete functions that could iterate through any directory structure 00426 \param struct fat_dir_entry_struct file_entry : the file to delete 00427 \return '1' on success, '0' otherwise 00428 \sa del(const char* name), delDir(uint8_t depth) 00429 */ 00430 uint8_t delFile(struct fat_dir_entry_struct file_entry); 00431 00432 //! It opens a file 00433 /*! 00434 \param const char* filename : the file to open 00435 \return '0' if error, file pointer on success 00436 */ 00437 struct fat_file_struct* openFile(const char* filename); 00438 00439 //! It closes a file 00440 /*! 00441 \param struct fat_file_struct* _fd : the file to close 00442 \return void 00443 */ 00444 void closeFile (struct fat_file_struct* _fd); 00445 00446 //! It tests the existence of a file in the current folder 00447 /*! 00448 \param const char* filename : the file to check 00449 \return '1' on success, '0' if it is a directory, '-1' otherwise 00450 */ 00451 int8_t isFile(const char* filename); 00452 00453 //! It gets the amount of lines in a file 00454 /*! 00455 \param const char* filename : the file to check 00456 \return number of lines on success, '-1' otherwise 00457 */ 00458 int32_t numln (const char* filename); 00459 00460 //! It gets the file size for filename in the current folder 00461 /*! 00462 \param const char* name : the file to check 00463 \return file size on success, '-1' otherwise 00464 */ 00465 int32_t getFileSize(const char* name); 00466 00467 //! It gets the attributes for a directory or file entry 00468 /*! 00469 \param const char* name : the file or directory to check 00470 \return returns the attributes for a directory or file entry in the current directory. 00471 The attributes are encoded with two characters: 00472 - char #1: it is either "d" for a directory or "-" for a file entry 00473 - char #2: is either "r" for read only, and "w" if the file/directory is also writeable 00474 If the file or directory is not available in the folder, it will answer "--" 00475 */ 00476 char* getAttributes(const char* name); 00477 00478 //! It dumps into the buffer the amount of bytes in scope after offset coming from filename 00479 /*! 00480 There is a limitation in size, due to DOS_BUFFER_SIZE. If the data read was bigger than that, the function will include the characters ">>" at the end and activate the TRUNCATED_DATA value in the DOS.flag. It is recommened to check this value to assure data integrity. 00481 \param const char* filename : the file to get the data from 00482 \param int32_t offset : amount of bytes to jump before start dumping the data to the buffer 00483 \param uint16_t scope : amount of bytes for dumping to the buffer 00484 \return 'buffer' variable where the data has been dumped 00485 \sa catBin (const char* filename, int32_t offset, uint16_t scope), catln (const char* filename, uint32_t offset, uint16_t scope) 00486 */ 00487 char* cat (const char* filename, int32_t offset, uint16_t scope); 00488 00489 //! It dumps into the bufferBin the amount of bytes in scope after offset coming from filename 00490 /*! 00491 \param const char* filename : the file to get the data from 00492 \param int32_t offset : amount of bytes to jump before start dumping the data to the buffer 00493 \param uint16_t scope : amount of bytes for dumping to the buffer 00494 \return 'bufferBin' variable where the data has been dumped 00495 \sa cat (const char* filename, int32_t offset, uint16_t scope), catln (const char* filename, uint32_t offset, uint16_t scope) 00496 */ 00497 uint8_t* catBin (const char* filename, int32_t offset, uint16_t scope); 00498 00499 //! It dumps into the buffer the amount of lines in scope after offset lines coming from filename 00500 /*! 00501 There is a limitation in size, due to DOS_BUFFER_SIZE. If the data read was bigger than that, the function will include the characters ">>" at the end and activate the TRUNCATED_DATA value in the DOS.flag. It is recommened to check this value to assure data integrity. 00502 \param const char* filename : the file to get the data from 00503 \param uint32_t offset : amount of lines to jump before start dumping the data to the buffer 00504 \param uint16_t scope : amount of lines for dumping to the buffer 00505 \return 'buffer' variable where the data has been dumped 00506 \sa cat (const char* filename, int32_t offset, uint16_t scope), catBin (const char* filename, int32_t offset, uint16_t scope) 00507 */ 00508 char* catln (const char* filename, uint32_t offset, uint16_t scope); 00509 00510 //! It searches for first occurrence of a string in a file 00511 /*! 00512 \param const char* filename : the file where looking for the pattern 00513 \param const char* pattern : pattern to find 00514 \param uint32_t offset : amount of bytes to jump before start looking for the pattern 00515 \return the amount of bytes to the pattern from the offset 00516 */ 00517 int32_t indexOf (const char* filename, const char* pattern, uint32_t offset); 00518 00519 //! It creates a file 00520 /*! 00521 \param const char* filename : the file to create 00522 \return '1' on success, '0' otherwise 00523 */ 00524 uint8_t create(const char* filename); 00525 00526 //! It writes strings to a file 00527 /*! 00528 \param const char* filename : the file to write to 00529 \param const char* str : the string to write into the file 00530 \param int32_t offset : amount of bytes to jump before start writing the string 00531 \return '1' on success, '0' otherwise 00532 \sa writeSD(const char* filename, uint8_t* str, int32_t offset), append(const char* filename, const char* str), append(const char* filename, uint8_t* str), appendln(const char* filename, const char* str), appendln(const char* filename, uint8_t* str) 00533 */ 00534 uint8_t writeSD(const char* filename, const char* str, int32_t offset); 00535 00536 //! It writes integer array to a file 00537 /*! 00538 \param const char* filename : the file to write to 00539 \param uint8_t* str : the integer array to write into the file 00540 \param int32_t offset : amount of bytes to jump before start writing the string 00541 \return '1' on success, '0' otherwise 00542 \sa writeSD(const char* filename, const char* str, int32_t offset), append(const char* filename, const char* str), append(const char* filename, uint8_t* str), appendln(const char* filename, const char* str), appendln(const char* filename, uint8_t* str) 00543 00544 */ 00545 uint8_t writeSD(const char* filename, uint8_t* str, int32_t offset); 00546 00547 //! It writes strings to a file of a specific length 00548 /*! 00549 \param const char* filename : the file to write to 00550 \param const char* str : the string to write into the file 00551 \param int32_t offset : amount of bytes to jump before start writing the string 00552 \param int16_t length : amount of bytes to write to the file 00553 \return '1' on success, '0' otherwise 00554 \sa writeSD(const char* filename, uint8_t* str, int32_t offset), append(const char* filename, const char* str), append(const char* filename, uint8_t* str), appendln(const char* filename, const char* str), appendln(const char* filename, uint8_t* str) 00555 */ 00556 uint8_t writeSD(const char* filename, const char* str, int32_t offset, int16_t length); 00557 00558 //! It writes strings at the end of files 00559 /*! 00560 \param const char* filename : the file to write to 00561 \param const char* str : the string to write into the file 00562 \return '1' on success, '0' otherwise 00563 \sa writeSD(const char* filename, const char* str, int32_t offset), writeSD(const char* filename, uint8_t* str, int32_t offset), append(const char* filename, uint8_t* str), appendln(const char* filename, const char* str), appendln(const char* filename, uint8_t* str) 00564 */ 00565 uint8_t append(const char* filename, const char* str); 00566 00567 //! It writes strings at the end of files of a specific length 00568 /*! 00569 \param const char* filename : the file to write to 00570 \param const char* str : the string to write into the file 00571 \param uint16_t length : the length to write 00572 \return '1' on success, '0' otherwise 00573 \sa writeSD(const char* filename, const char* str, int32_t offset), writeSD(const char* filename, uint8_t* str, int32_t offset), append(const char* filename, uint8_t* str), appendln(const char* filename, const char* str), appendln(const char* filename, uint8_t* str) 00574 */ 00575 uint8_t append(const char* filename, const char* str, uint16_t length); 00576 00577 //! It writes integer arrays at the end of files 00578 /*! 00579 \param const char* filename : the file to write to 00580 \param uint8_t* str : the integer array to write into the file 00581 \return '1' on success, '0' otherwise 00582 \sa writeSD(const char* filename, const char* str, int32_t offset), writeSD(const char* filename, uint8_t* str, int32_t offset), append(const char* filename, const char* str), appendln(const char* filename, const char* str), appendln(const char* filename, uint8_t* str) 00583 */ 00584 uint8_t append(const char* filename, uint8_t* str); 00585 00586 //! It writes strings at the end of files adding an EOL 00587 /*! 00588 \param const char* filename : the file to write to 00589 \param const char* str : the string to write into the file 00590 \return '1' on success, '0' otherwise 00591 \sa writeSD(const char* filename, const char* str, int32_t offset), writeSD(const char* filename, uint8_t* str, int32_t offset), append(const char* filename, const char* str), append(const char* filename, uint8_t* str), appendln(const char* filename, uint8_t* str) 00592 */ 00593 uint8_t appendln(const char* filename, const char* str); 00594 00595 //! It writes integer arrays at the end of files adding an EOL 00596 /*! 00597 \param const char* filename : the file to write to 00598 \param uint8_t* str : the integer array to write into the file 00599 \return '1' on success, '0' otherwise 00600 \sa writeSD(const char* filename, const char* str, int32_t offset), writeSD(const char* filename, uint8_t* str, int32_t offset), append(const char* filename, const char* str), append(const char* filename, uint8_t* str), appendln(const char* filename, const char* str) 00601 */ 00602 uint8_t appendln(const char* filename, uint8_t* str); 00603 00604 00605 //! It gets the library version 00606 /*! 00607 \param void 00608 \return the library version 00609 */ 00610 const char* getLibVersion(void) {return VERSION;}; 00611 }; 00612 00613 /// END FUNCTIONS /////////////////////////////////////////////////////////////////////// 00614 00615 extern WaspSD SD; 00616 00617 #endif 00618
1.5.6