├── .gitignore ├── MusicIcon.jpg ├── plugins ├── eq5.053 ├── pcm.053 ├── pshift.053 ├── rtmidi.053 ├── admxleft.053 ├── admxmono.053 ├── admxrght.053 ├── admxster.053 ├── admxswap.053 ├── patchefl.053 ├── patches.053 ├── patchesd.053 ├── patchesf.053 ├── patchesl.053 ├── vs_plg_to_bin.bat └── vs_plg_to_bin.pl ├── SFEMP3Shield ├── SFEMP3Shield.h ├── keywords.txt └── Examples │ └── MP3ButtonPlayer2 │ └── MP3ButtonPlayer2.ino ├── SdFat ├── library.properties └── src │ ├── SpiDriver │ ├── boards │ │ ├── UnoGpioPinMap.h │ │ ├── Teensy2GpioPinMap.h │ │ ├── LeonardoGpioPinMap.h │ │ ├── BobuinoGpioPinMap.h │ │ ├── Standard1284GpioPinMap.h │ │ ├── AvrDevelopersGpioPinMap.h │ │ ├── SleepingBeautyGpioPinMap.h │ │ ├── Teensy2ppGpioPinMap.h │ │ ├── GpioPinMap.h │ │ └── MegaGpioPinMap.h │ ├── SdSpiBaseDriver.h │ ├── SdSpiESP8266.cpp │ ├── SdSpiSTM32F1.cpp │ ├── SoftSPI.h │ ├── SdSpiTeensy3.cpp │ ├── SdSpiSAM3X.cpp │ └── SdSpiDriver.h │ ├── FatLib │ ├── FatLib.h │ ├── FmtNumber.h │ ├── FatApiConstants.h │ ├── BaseBlockDriver.h │ ├── ArduinoStream.h │ ├── iostream.h │ ├── bufstream.h │ ├── fstream.cpp │ ├── FatLibConfig.h │ ├── ostream.cpp │ ├── FatFilePrint.cpp │ ├── FatFileSFN.cpp │ ├── ostream.h │ ├── ArduinoFiles.h │ ├── fstream.h │ ├── istream.cpp │ └── FatFileSystem.h │ ├── BlockDriver.h │ ├── FreeStack.h │ ├── MinimumSerial.h │ ├── SysCall.h │ ├── MinimumSerial.cpp │ ├── SdCard │ ├── SdSpiCardEX.cpp │ ├── SdioCardEX.cpp │ └── SdioCard.h │ └── SdFatConfig.h ├── SFEMP3Shield.html ├── license ├── readme.md └── history.md /.gitignore: -------------------------------------------------------------------------------- 1 | /html 2 | -------------------------------------------------------------------------------- /MusicIcon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpflaga/Sparkfun-MP3-Player-Shield-Arduino-Library/HEAD/MusicIcon.jpg -------------------------------------------------------------------------------- /plugins/eq5.053: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpflaga/Sparkfun-MP3-Player-Shield-Arduino-Library/HEAD/plugins/eq5.053 -------------------------------------------------------------------------------- /plugins/pcm.053: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpflaga/Sparkfun-MP3-Player-Shield-Arduino-Library/HEAD/plugins/pcm.053 -------------------------------------------------------------------------------- /plugins/pshift.053: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpflaga/Sparkfun-MP3-Player-Shield-Arduino-Library/HEAD/plugins/pshift.053 -------------------------------------------------------------------------------- /plugins/rtmidi.053: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpflaga/Sparkfun-MP3-Player-Shield-Arduino-Library/HEAD/plugins/rtmidi.053 -------------------------------------------------------------------------------- /plugins/admxleft.053: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpflaga/Sparkfun-MP3-Player-Shield-Arduino-Library/HEAD/plugins/admxleft.053 -------------------------------------------------------------------------------- /plugins/admxmono.053: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpflaga/Sparkfun-MP3-Player-Shield-Arduino-Library/HEAD/plugins/admxmono.053 -------------------------------------------------------------------------------- /plugins/admxrght.053: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpflaga/Sparkfun-MP3-Player-Shield-Arduino-Library/HEAD/plugins/admxrght.053 -------------------------------------------------------------------------------- /plugins/admxster.053: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpflaga/Sparkfun-MP3-Player-Shield-Arduino-Library/HEAD/plugins/admxster.053 -------------------------------------------------------------------------------- /plugins/admxswap.053: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpflaga/Sparkfun-MP3-Player-Shield-Arduino-Library/HEAD/plugins/admxswap.053 -------------------------------------------------------------------------------- /plugins/patchefl.053: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpflaga/Sparkfun-MP3-Player-Shield-Arduino-Library/HEAD/plugins/patchefl.053 -------------------------------------------------------------------------------- /plugins/patches.053: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpflaga/Sparkfun-MP3-Player-Shield-Arduino-Library/HEAD/plugins/patches.053 -------------------------------------------------------------------------------- /plugins/patchesd.053: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpflaga/Sparkfun-MP3-Player-Shield-Arduino-Library/HEAD/plugins/patchesd.053 -------------------------------------------------------------------------------- /plugins/patchesf.053: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpflaga/Sparkfun-MP3-Player-Shield-Arduino-Library/HEAD/plugins/patchesf.053 -------------------------------------------------------------------------------- /plugins/patchesl.053: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpflaga/Sparkfun-MP3-Player-Shield-Arduino-Library/HEAD/plugins/patchesl.053 -------------------------------------------------------------------------------- /SFEMP3Shield/SFEMP3Shield.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpflaga/Sparkfun-MP3-Player-Shield-Arduino-Library/HEAD/SFEMP3Shield/SFEMP3Shield.h -------------------------------------------------------------------------------- /SdFat/library.properties: -------------------------------------------------------------------------------- 1 | name=SdFat 2 | version=1.0.1 3 | author=Bill Greiman 4 | maintainer=Bill Greiman 5 | sentence=FAT16/FAT32 file system for SD cards. 6 | paragraph=FAT16/FAT32 file system for SD cards. 7 | category=Data Storage 8 | url=https://github.com/greiman/SdFat 9 | architectures=* 10 | -------------------------------------------------------------------------------- /SFEMP3Shield.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | A web page that points a browser to a different page 4 | 5 | 6 | 7 | 8 | Your browser didn't automatically redirect. Open html/index.html manually. 9 | 10 | 11 | -------------------------------------------------------------------------------- /license: -------------------------------------------------------------------------------- 1 | This program is free software: you can redistribute it and/or modify 2 | it under the terms of the GNU General Public License as published by 3 | the Free Software Foundation, either version 3 of the License, or 4 | (at your option) any later version. 5 | 6 | This program is distributed in the hope that it will be useful, 7 | but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | GNU General Public License for more details. 10 | 11 | You should have received a copy of the GNU General Public License 12 | along with this program. If not, see . -------------------------------------------------------------------------------- /SdFat/src/SpiDriver/boards/UnoGpioPinMap.h: -------------------------------------------------------------------------------- 1 | #ifndef UnoGpioPinMap_h 2 | #define UnoGpioPinMap_h 3 | static const GpioPinMap_t GpioPinMap[] = { 4 | GPIO_PIN(D, 0), // D0 5 | GPIO_PIN(D, 1), // D1 6 | GPIO_PIN(D, 2), // D2 7 | GPIO_PIN(D, 3), // D3 8 | GPIO_PIN(D, 4), // D4 9 | GPIO_PIN(D, 5), // D5 10 | GPIO_PIN(D, 6), // D6 11 | GPIO_PIN(D, 7), // D7 12 | GPIO_PIN(B, 0), // D8 13 | GPIO_PIN(B, 1), // D9 14 | GPIO_PIN(B, 2), // D10 15 | GPIO_PIN(B, 3), // D11 16 | GPIO_PIN(B, 4), // D12 17 | GPIO_PIN(B, 5), // D13 18 | GPIO_PIN(C, 0), // D14 19 | GPIO_PIN(C, 1), // D15 20 | GPIO_PIN(C, 2), // D16 21 | GPIO_PIN(C, 3), // D17 22 | GPIO_PIN(C, 4), // D18 23 | GPIO_PIN(C, 5) // D19 24 | }; 25 | #endif // UnoGpioPinMap_h -------------------------------------------------------------------------------- /SdFat/src/SpiDriver/boards/Teensy2GpioPinMap.h: -------------------------------------------------------------------------------- 1 | #ifndef Teensy2GpioPinMap_h 2 | #define Teensy2GpioPinMap_h 3 | static const GpioPinMap_t GpioPinMap[] = { 4 | GPIO_PIN(B, 0), // D0 5 | GPIO_PIN(B, 1), // D1 6 | GPIO_PIN(B, 2), // D2 7 | GPIO_PIN(B, 3), // D3 8 | GPIO_PIN(B, 7), // D4 9 | GPIO_PIN(D, 0), // D5 10 | GPIO_PIN(D, 1), // D6 11 | GPIO_PIN(D, 2), // D7 12 | GPIO_PIN(D, 3), // D8 13 | GPIO_PIN(C, 6), // D9 14 | GPIO_PIN(C, 7), // D10 15 | GPIO_PIN(D, 6), // D11 16 | GPIO_PIN(D, 7), // D12 17 | GPIO_PIN(B, 4), // D13 18 | GPIO_PIN(B, 5), // D14 19 | GPIO_PIN(B, 6), // D15 20 | GPIO_PIN(F, 7), // D16 21 | GPIO_PIN(F, 6), // D17 22 | GPIO_PIN(F, 5), // D18 23 | GPIO_PIN(F, 4), // D19 24 | GPIO_PIN(F, 1), // D20 25 | GPIO_PIN(F, 0), // D21 26 | GPIO_PIN(D, 4), // D22 27 | GPIO_PIN(D, 5), // D23 28 | GPIO_PIN(E, 6), // D24 29 | }; 30 | #endif // Teensy2GpioPinMap_h 31 | -------------------------------------------------------------------------------- /SdFat/src/SpiDriver/boards/LeonardoGpioPinMap.h: -------------------------------------------------------------------------------- 1 | #ifndef LeonardoGpioPinMap_h 2 | #define LeonardoGpioPinMap_h 3 | static const GpioPinMap_t GpioPinMap[] = { 4 | GPIO_PIN(D, 2), // D0 5 | GPIO_PIN(D, 3), // D1 6 | GPIO_PIN(D, 1), // D2 7 | GPIO_PIN(D, 0), // D3 8 | GPIO_PIN(D, 4), // D4 9 | GPIO_PIN(C, 6), // D5 10 | GPIO_PIN(D, 7), // D6 11 | GPIO_PIN(E, 6), // D7 12 | GPIO_PIN(B, 4), // D8 13 | GPIO_PIN(B, 5), // D9 14 | GPIO_PIN(B, 6), // D10 15 | GPIO_PIN(B, 7), // D11 16 | GPIO_PIN(D, 6), // D12 17 | GPIO_PIN(C, 7), // D13 18 | GPIO_PIN(B, 3), // D14 19 | GPIO_PIN(B, 1), // D15 20 | GPIO_PIN(B, 2), // D16 21 | GPIO_PIN(B, 0), // D17 22 | GPIO_PIN(F, 7), // D18 23 | GPIO_PIN(F, 6), // D19 24 | GPIO_PIN(F, 5), // D20 25 | GPIO_PIN(F, 4), // D21 26 | GPIO_PIN(F, 1), // D22 27 | GPIO_PIN(F, 0), // D23 28 | GPIO_PIN(D, 4), // D24 29 | GPIO_PIN(D, 7), // D25 30 | GPIO_PIN(B, 4), // D26 31 | GPIO_PIN(B, 5), // D27 32 | GPIO_PIN(B, 6), // D28 33 | GPIO_PIN(D, 6) // D29 34 | }; 35 | #endif // LeonardoGpioPinMap_h 36 | -------------------------------------------------------------------------------- /SdFat/src/SpiDriver/boards/BobuinoGpioPinMap.h: -------------------------------------------------------------------------------- 1 | #ifndef BobuinoGpioPinMap_h 2 | #define BobuinoGpioPinMap_h 3 | static const GpioPinMap_t GpioPinMap[] = { 4 | GPIO_PIN(B, 0), // D0 5 | GPIO_PIN(B, 1), // D1 6 | GPIO_PIN(B, 2), // D2 7 | GPIO_PIN(B, 3), // D3 8 | GPIO_PIN(B, 4), // D4 9 | GPIO_PIN(B, 5), // D5 10 | GPIO_PIN(B, 6), // D6 11 | GPIO_PIN(B, 7), // D7 12 | GPIO_PIN(D, 0), // D8 13 | GPIO_PIN(D, 1), // D9 14 | GPIO_PIN(D, 2), // D10 15 | GPIO_PIN(D, 3), // D11 16 | GPIO_PIN(D, 4), // D12 17 | GPIO_PIN(D, 5), // D13 18 | GPIO_PIN(D, 6), // D14 19 | GPIO_PIN(D, 7), // D15 20 | GPIO_PIN(C, 0), // D16 21 | GPIO_PIN(C, 1), // D17 22 | GPIO_PIN(C, 2), // D18 23 | GPIO_PIN(C, 3), // D19 24 | GPIO_PIN(C, 4), // D20 25 | GPIO_PIN(C, 5), // D21 26 | GPIO_PIN(C, 6), // D22 27 | GPIO_PIN(C, 7), // D23 28 | GPIO_PIN(A, 0), // D24 29 | GPIO_PIN(A, 1), // D25 30 | GPIO_PIN(A, 2), // D26 31 | GPIO_PIN(A, 3), // D27 32 | GPIO_PIN(A, 4), // D28 33 | GPIO_PIN(A, 5), // D29 34 | GPIO_PIN(A, 6), // D30 35 | GPIO_PIN(A, 7) // D31 36 | }; 37 | #endif // BobuinoGpioPinMap_h -------------------------------------------------------------------------------- /SdFat/src/SpiDriver/boards/Standard1284GpioPinMap.h: -------------------------------------------------------------------------------- 1 | #ifndef Standard1284GpioPinMap_h 2 | #define Standard1284GpioPinMap_h 3 | static const GpioPinMap_t GpioPinMap[] = { 4 | GPIO_PIN(B, 0), // D0 5 | GPIO_PIN(B, 1), // D1 6 | GPIO_PIN(B, 2), // D2 7 | GPIO_PIN(B, 3), // D3 8 | GPIO_PIN(B, 4), // D4 9 | GPIO_PIN(B, 5), // D5 10 | GPIO_PIN(B, 6), // D6 11 | GPIO_PIN(B, 7), // D7 12 | GPIO_PIN(D, 0), // D8 13 | GPIO_PIN(D, 1), // D9 14 | GPIO_PIN(D, 2), // D10 15 | GPIO_PIN(D, 3), // D11 16 | GPIO_PIN(D, 4), // D12 17 | GPIO_PIN(D, 5), // D13 18 | GPIO_PIN(D, 6), // D14 19 | GPIO_PIN(D, 7), // D15 20 | GPIO_PIN(C, 0), // D16 21 | GPIO_PIN(C, 1), // D17 22 | GPIO_PIN(C, 2), // D18 23 | GPIO_PIN(C, 3), // D19 24 | GPIO_PIN(C, 4), // D20 25 | GPIO_PIN(C, 5), // D21 26 | GPIO_PIN(C, 6), // D22 27 | GPIO_PIN(C, 7), // D23 28 | GPIO_PIN(A, 0), // D24 29 | GPIO_PIN(A, 1), // D25 30 | GPIO_PIN(A, 2), // D26 31 | GPIO_PIN(A, 3), // D27 32 | GPIO_PIN(A, 4), // D28 33 | GPIO_PIN(A, 5), // D29 34 | GPIO_PIN(A, 6), // D30 35 | GPIO_PIN(A, 7) // D31 36 | }; 37 | #endif // Standard1284GpioPinMap_h -------------------------------------------------------------------------------- /SdFat/src/SpiDriver/boards/AvrDevelopersGpioPinMap.h: -------------------------------------------------------------------------------- 1 | #ifndef AvrDevelopersGpioPinMap_h 2 | #define AvrDevelopersGpioPinMap_h 3 | static const GpioPinMap_t GpioPinMap[] = { 4 | GPIO_PIN(B, 0), // D0 5 | GPIO_PIN(B, 1), // D1 6 | GPIO_PIN(B, 2), // D2 7 | GPIO_PIN(B, 3), // D3 8 | GPIO_PIN(B, 4), // D4 9 | GPIO_PIN(B, 5), // D5 10 | GPIO_PIN(B, 6), // D6 11 | GPIO_PIN(B, 7), // D7 12 | GPIO_PIN(D, 0), // D8 13 | GPIO_PIN(D, 1), // D9 14 | GPIO_PIN(D, 2), // D10 15 | GPIO_PIN(D, 3), // D11 16 | GPIO_PIN(D, 4), // D12 17 | GPIO_PIN(D, 5), // D13 18 | GPIO_PIN(D, 6), // D14 19 | GPIO_PIN(D, 7), // D15 20 | GPIO_PIN(C, 0), // D16 21 | GPIO_PIN(C, 1), // D17 22 | GPIO_PIN(C, 2), // D18 23 | GPIO_PIN(C, 3), // D19 24 | GPIO_PIN(C, 4), // D20 25 | GPIO_PIN(C, 5), // D21 26 | GPIO_PIN(C, 6), // D22 27 | GPIO_PIN(C, 7), // D23 28 | GPIO_PIN(A, 7), // D24 29 | GPIO_PIN(A, 6), // D25 30 | GPIO_PIN(A, 5), // D26 31 | GPIO_PIN(A, 4), // D27 32 | GPIO_PIN(A, 3), // D28 33 | GPIO_PIN(A, 2), // D29 34 | GPIO_PIN(A, 1), // D30 35 | GPIO_PIN(A, 0) // D31 36 | }; 37 | #endif // AvrDevelopersGpioPinMap_h -------------------------------------------------------------------------------- /SdFat/src/SpiDriver/boards/SleepingBeautyGpioPinMap.h: -------------------------------------------------------------------------------- 1 | #ifndef SleepingBeautyGpioPinMap_h 2 | #define SleepingBeautyGpioPinMap_h 3 | static const GpioPinMap_t GpioPinMap[] = { 4 | GPIO_PIN(D, 0), // D0 5 | GPIO_PIN(D, 1), // D1 6 | GPIO_PIN(D, 2), // D2 7 | GPIO_PIN(D, 3), // D3 8 | GPIO_PIN(B, 0), // D4 9 | GPIO_PIN(B, 1), // D5 10 | GPIO_PIN(B, 2), // D6 11 | GPIO_PIN(B, 3), // D7 12 | GPIO_PIN(D, 6), // D8 13 | GPIO_PIN(D, 5), // D9 14 | GPIO_PIN(B, 4), // D10 15 | GPIO_PIN(B, 5), // D11 16 | GPIO_PIN(B, 6), // D12 17 | GPIO_PIN(B, 7), // D13 18 | GPIO_PIN(C, 7), // D14 19 | GPIO_PIN(C, 6), // D15 20 | GPIO_PIN(A, 5), // D16 21 | GPIO_PIN(A, 4), // D17 22 | GPIO_PIN(A, 3), // D18 23 | GPIO_PIN(A, 2), // D19 24 | GPIO_PIN(A, 1), // D20 25 | GPIO_PIN(A, 0), // D21 26 | GPIO_PIN(D, 4), // D22 27 | GPIO_PIN(D, 7), // D23 28 | GPIO_PIN(C, 2), // D24 29 | GPIO_PIN(C, 3), // D25 30 | GPIO_PIN(C, 4), // D26 31 | GPIO_PIN(C, 5), // D27 32 | GPIO_PIN(C, 1), // D28 33 | GPIO_PIN(C, 0), // D29 34 | GPIO_PIN(A, 6), // D30 35 | GPIO_PIN(A, 7) // D31 36 | }; 37 | #endif // SleepingBeautyGpioPinMap_h -------------------------------------------------------------------------------- /SdFat/src/FatLib/FatLib.h: -------------------------------------------------------------------------------- 1 | /* FatLib Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the FatLib Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the FatLib Library. If not, see 18 | * . 19 | */ 20 | #ifndef FatLib_h 21 | #define FatLib_h 22 | #include "ArduinoFiles.h" 23 | #include "ArduinoStream.h" 24 | #include "FatFileSystem.h" 25 | #include "FatLibConfig.h" 26 | #include "FatVolume.h" 27 | #include "FatFile.h" 28 | #include "StdioStream.h" 29 | #include "fstream.h" 30 | //------------------------------------------------------------------------------ 31 | /** FatFileSystem version YYYYMMDD */ 32 | #define FAT_LIB_VERSION 20150131 33 | #endif // FatLib_h 34 | -------------------------------------------------------------------------------- /plugins/vs_plg_to_bin.bat: -------------------------------------------------------------------------------- 1 | vs_plg_to_bin.pl C:\projects\VSIDE\vs1053-pcm110\vs1053pcm.plg .\pcm.053 2 | vs_plg_to_bin.pl C:\projects\VSIDE\vs1053b-admix130\admix-left.plg .\admxleft.053 3 | vs_plg_to_bin.pl C:\projects\VSIDE\vs1053b-admix130\admix-mono.plg .\admxmono.053 4 | vs_plg_to_bin.pl C:\projects\VSIDE\vs1053b-admix130\admix-right.plg .\admxrght.053 5 | vs_plg_to_bin.pl C:\projects\VSIDE\vs1053b-admix130\admix-stereo.plg .\admxster.053 6 | vs_plg_to_bin.pl C:\projects\VSIDE\vs1053b-admix130\admix-swap.plg .\admxswap.053 7 | vs_plg_to_bin.pl C:\projects\VSIDE\vs1053b-patches240\vs1053b-patches-flac.plg .\patchesf.053 8 | vs_plg_to_bin.pl C:\projects\VSIDE\vs1053b-patches240\vs1053b-patches.plg .\patches.053 9 | vs_plg_to_bin.pl C:\projects\VSIDE\vs1053b-patches240\vs1053b-patches-latm.plg .\patchesl.053 10 | vs_plg_to_bin.pl C:\projects\VSIDE\vs1053b-patches240\vs1053b-patches-flac-latm.plg .\patchefl.053 11 | vs_plg_to_bin.pl C:\projects\VSIDE\vs1053b-patches240\vs1053b-patches-dsd.plg .\patchesd.053 12 | vs_plg_to_bin.pl C:\projects\VSIDE\vs1053b-rtmidistart\rtmidistart.plg .\rtmidi.053 13 | vs_plg_to_bin.pl C:\projects\VSIDE\vs1053b-eq5-100\vs1053b-eq5.plg .\eq5.053 14 | vs_plg_to_bin.pl C:\projects\VSIDE\pitchshifter131\code\ps1053b.plg .\pshift.053 15 | 16 | -------------------------------------------------------------------------------- /SdFat/src/BlockDriver.h: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2016 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | /** 21 | * \file 22 | * \brief Define block driver. 23 | */ 24 | #ifndef BlockDriver_h 25 | #define BlockDriver_h 26 | #include "FatLib/BaseBlockDriver.h" 27 | #include "SdCard/SdSpiCard.h" 28 | //----------------------------------------------------------------------------- 29 | /** typedef for BlockDriver */ 30 | #if ENABLE_EXTENDED_TRANSFER_CLASS || ENABLE_SDIO_CLASS 31 | typedef BaseBlockDriver BlockDriver; 32 | #else // ENABLE_EXTENDED_TRANSFER_CLASS || ENABLE_SDIO_CLASS 33 | typedef SdSpiCard BlockDriver; 34 | #endif // ENABLE_EXTENDED_TRANSFER_CLASS || ENABLE_SDIO_CLASS 35 | #endif // BlockDriver_h 36 | -------------------------------------------------------------------------------- /SdFat/src/FatLib/FmtNumber.h: -------------------------------------------------------------------------------- 1 | /* FatLib Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the FatLib Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the FatLib Library. If not, see 18 | * . 19 | */ 20 | #ifndef FmtNumber_h 21 | #define FmtNumber_h 22 | // #include 23 | inline bool isDigit(char c) { 24 | return '0' <= c && c <= '9'; 25 | } 26 | inline bool isSpace(char c) { 27 | return c == ' ' || (0X9 <= c && c <= 0XD); 28 | } 29 | #include 30 | #include 31 | char* fmtDec(uint16_t n, char* p); 32 | char* fmtDec(uint32_t n, char* p); 33 | char* fmtFloat(float value, char* p, uint8_t prec); 34 | char* fmtFloat(float value, char* ptr, uint8_t prec, char expChar); 35 | char* fmtHex(uint32_t n, char* p); 36 | float scale10(float v, int8_t n); 37 | float scanFloat(const char* str, char** ptr); 38 | #endif // FmtNumber_h 39 | -------------------------------------------------------------------------------- /SdFat/src/SpiDriver/boards/Teensy2ppGpioPinMap.h: -------------------------------------------------------------------------------- 1 | #ifndef Teensypp2GpioPinMap_h 2 | #define Teensypp2GpioPinMap_h 3 | static const GpioPinMap_t GpioPinMap[] = { 4 | GPIO_PIN(D, 0), // D0 5 | GPIO_PIN(D, 1), // D1 6 | GPIO_PIN(D, 2), // D2 7 | GPIO_PIN(D, 3), // D3 8 | GPIO_PIN(D, 4), // D4 9 | GPIO_PIN(D, 5), // D5 10 | GPIO_PIN(D, 6), // D6 11 | GPIO_PIN(D, 7), // D7 12 | GPIO_PIN(E, 0), // D8 13 | GPIO_PIN(E, 1), // D9 14 | GPIO_PIN(C, 0), // D10 15 | GPIO_PIN(C, 1), // D11 16 | GPIO_PIN(C, 2), // D12 17 | GPIO_PIN(C, 3), // D13 18 | GPIO_PIN(C, 4), // D14 19 | GPIO_PIN(C, 5), // D15 20 | GPIO_PIN(C, 6), // D16 21 | GPIO_PIN(C, 7), // D17 22 | GPIO_PIN(E, 6), // D18 23 | GPIO_PIN(E, 7), // D19 24 | GPIO_PIN(B, 0), // D20 25 | GPIO_PIN(B, 1), // D21 26 | GPIO_PIN(B, 2), // D22 27 | GPIO_PIN(B, 3), // D23 28 | GPIO_PIN(B, 4), // D24 29 | GPIO_PIN(B, 5), // D25 30 | GPIO_PIN(B, 6), // D26 31 | GPIO_PIN(B, 7), // D27 32 | GPIO_PIN(A, 0), // D28 33 | GPIO_PIN(A, 1), // D29 34 | GPIO_PIN(A, 2), // D30 35 | GPIO_PIN(A, 3), // D31 36 | GPIO_PIN(A, 4), // D32 37 | GPIO_PIN(A, 5), // D33 38 | GPIO_PIN(A, 6), // D34 39 | GPIO_PIN(A, 7), // D35 40 | GPIO_PIN(E, 4), // D36 41 | GPIO_PIN(E, 5), // D37 42 | GPIO_PIN(F, 0), // D38 43 | GPIO_PIN(F, 1), // D39 44 | GPIO_PIN(F, 2), // D40 45 | GPIO_PIN(F, 3), // D41 46 | GPIO_PIN(F, 4), // D42 47 | GPIO_PIN(F, 5), // D43 48 | GPIO_PIN(F, 6), // D44 49 | GPIO_PIN(F, 7), // D45 50 | }; 51 | #endif // Teensypp2GpioPinMap_h 52 | -------------------------------------------------------------------------------- /SdFat/src/SpiDriver/boards/GpioPinMap.h: -------------------------------------------------------------------------------- 1 | #ifndef GpioPinMap_h 2 | #define GpioPinMap_h 3 | #if defined(__AVR_ATmega168__)\ 4 | ||defined(__AVR_ATmega168P__)\ 5 | ||defined(__AVR_ATmega328P__) 6 | // 168 and 328 Arduinos 7 | #include "UnoGpioPinMap.h" 8 | #elif defined(__AVR_ATmega1280__)\ 9 | || defined(__AVR_ATmega2560__) 10 | // Mega ADK 11 | #include "MegaGpioPinMap.h" 12 | #elif defined(__AVR_ATmega32U4__) 13 | #ifdef CORE_TEENSY 14 | #include "Teensy2GpioPinMap.h" 15 | #else // CORE_TEENSY 16 | // Leonardo or Yun 17 | #include "LeonardoGpioPinMap.h" 18 | #endif // CORE_TEENSY 19 | #elif defined(__AVR_AT90USB646__)\ 20 | || defined(__AVR_AT90USB1286__) 21 | // Teensy++ 1.0 & 2.0 22 | #include "Teensy2ppGpioPinMap.h" 23 | #elif defined(__AVR_ATmega1284P__)\ 24 | || defined(__AVR_ATmega1284__)\ 25 | || defined(__AVR_ATmega644P__)\ 26 | || defined(__AVR_ATmega644__)\ 27 | || defined(__AVR_ATmega64__)\ 28 | || defined(__AVR_ATmega32__)\ 29 | || defined(__AVR_ATmega324__)\ 30 | || defined(__AVR_ATmega16__) 31 | #ifdef ARDUINO_1284P_AVR_DEVELOPERS 32 | #include "AvrDevelopersGpioPinMap.h" 33 | #elif defined(BOBUINO_PINOUT) || defined(ARDUINO_1284P_BOBUINO) 34 | #include "BobuinoGpioPinMap.h" 35 | #elif defined(ARDUINO_1284P_SLEEPINGBEAUTY) 36 | #include "SleepingBeautyGpioPinMap.h" 37 | #elif defined(STANDARD_PINOUT) || defined(ARDUINO_1284P_STANDARD) 38 | #include "Standard1284GpioPinMap.h" 39 | #else // ARDUINO_1284P_AVR_DEVELOPERS 40 | #error Undefined variant 1284, 644, 324 41 | #endif // ARDUINO_1284P_AVR_DEVELOPERS 42 | #else // 1284P, 1284, 644 43 | #error Unknown board type. 44 | #endif // end all boards 45 | #endif // GpioPinMap_h 46 | -------------------------------------------------------------------------------- /SdFat/src/FreeStack.h: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2015 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | #ifndef FreeStack_h 21 | #define FreeStack_h 22 | /** 23 | * \file 24 | * \brief FreeStack() function. 25 | */ 26 | #if defined(__AVR__) || defined(DOXYGEN) 27 | /** boundary between stack and heap. */ 28 | extern char *__brkval; 29 | /** End of bss section.*/ 30 | extern char __bss_end; 31 | /** Amount of free stack space. 32 | * \return The number of free bytes. 33 | */ 34 | static int FreeStack() { 35 | char* sp = reinterpret_cast(SP); 36 | return __brkval ? sp - __brkval : sp - &__bss_end; 37 | // char top; 38 | // return __brkval ? &top - __brkval : &top - &__bss_end; 39 | } 40 | #elif defined(PLATFORM_ID) // Particle board 41 | static int FreeStack() { 42 | return System.freeMemory(); 43 | } 44 | #elif defined(__arm__) 45 | extern "C" char* sbrk(int incr); 46 | static int FreeStack() { 47 | char top = 't'; 48 | return &top - reinterpret_cast(sbrk(0)); 49 | } 50 | #else 51 | #warning FreeStack is not defined for this system. 52 | static int FreeStack() { 53 | return 0; 54 | } 55 | #endif 56 | #endif // FreeStack_h 57 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Available via Arduino IDE Library Manager 2 | 3 | This project and support has been migrated to [Arduino_Library-vs1053_for_SdFat](https://github.com/mpflaga/Arduino_Library-vs1053_for_SdFat), where "VS1053 for use wiht SdFat" is availabe directly from the Arduino IDE Library manager for download. 4 | 5 | This instance of the project is effectively closed, please submit all issues and pull requests to [Arduino_Library-vs1053_for_SdFat](https://github.com/mpflaga/Arduino_Library-vs1053_for_SdFat) 6 | 7 | # Arduino VS1053 Library 8 | 9 | The Arduino SFEMP3Shield Library is a real time non-blocking interrupt driven library for VSLI's VS10xx. (e.i. VS1053), implemented as a Slave co-processor to audio decode streams of Ogg Vorbis/MP3/AAC/WMA/FLAC/WAVMIDI formats, across the SPI bus of the Arduino. Principally this library is developed for the VS1053\. where it may be compatible with other VS10xx's 10 | 11 | Initially developed on a ATmega328 Arduino UNO/Duemilanove with a SparkFun MP3 Player Shield, additional support has been provided for Seeduino MP3 Player Shield. Documentation is provided as to how to implement this, along with Arduino Mega and other home grown designs. Where this driver is modular in concept to allow ready porting to other Arduino or Wiring platforms. 12 | 13 | # Support & Trouble shooting. 14 | 15 | Extensive support can be found at [ GitHub project page ](http://mpflaga.github.io/Sparkfun-MP3-Player-Shield-Arduino-Library/) along with trouble shooting of common problems. As the code has been written with plenty of insightful comments, describing key components, features and reasoning’s in Doxygen markdown style as to directly auto generate html supporting documentation. Which can be found at [ GitHub project page ](http://mpflaga.github.io/Sparkfun-MP3-Player-Shield-Arduino-Library/). Please read through this document and referring linked resources. As it contains additional resources. 16 | -------------------------------------------------------------------------------- /SdFat/src/MinimumSerial.h: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2012 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | /** 21 | * \file 22 | * \brief Minimal AVR Serial driver. 23 | */ 24 | #ifndef MinimumSerial_h 25 | #define MinimumSerial_h 26 | #include "SysCall.h" 27 | //============================================================================== 28 | /** 29 | * \class MinimumSerial 30 | * \brief mini serial class for the %SdFat library. 31 | */ 32 | class MinimumSerial : public Print { 33 | public: 34 | /** \return true for hardware serial */ 35 | operator bool() { return true; } 36 | /** 37 | * \return one if data is available. 38 | */ 39 | int available(); 40 | /** 41 | * Set baud rate for serial port zero and enable in non interrupt mode. 42 | * Do not call this function if you use another serial library. 43 | * \param[in] baud rate 44 | */ 45 | void begin(uint32_t baud); 46 | /** Wait for write done. */ 47 | void flush(); 48 | /** 49 | * Unbuffered read 50 | * \return -1 if no character is available or an available character. 51 | */ 52 | int read(); 53 | /** 54 | * Unbuffered write 55 | * 56 | * \param[in] b byte to write. 57 | * \return 1 58 | */ 59 | size_t write(uint8_t b); 60 | using Print::write; 61 | }; 62 | #endif // MinimumSerial_h 63 | -------------------------------------------------------------------------------- /SdFat/src/SpiDriver/boards/MegaGpioPinMap.h: -------------------------------------------------------------------------------- 1 | #ifndef MegaGpioPinMap_h 2 | #define MegaGpioPinMap_h 3 | static const GpioPinMap_t GpioPinMap[] = { 4 | GPIO_PIN(E, 0), // D0 5 | GPIO_PIN(E, 1), // D1 6 | GPIO_PIN(E, 4), // D2 7 | GPIO_PIN(E, 5), // D3 8 | GPIO_PIN(G, 5), // D4 9 | GPIO_PIN(E, 3), // D5 10 | GPIO_PIN(H, 3), // D6 11 | GPIO_PIN(H, 4), // D7 12 | GPIO_PIN(H, 5), // D8 13 | GPIO_PIN(H, 6), // D9 14 | GPIO_PIN(B, 4), // D10 15 | GPIO_PIN(B, 5), // D11 16 | GPIO_PIN(B, 6), // D12 17 | GPIO_PIN(B, 7), // D13 18 | GPIO_PIN(J, 1), // D14 19 | GPIO_PIN(J, 0), // D15 20 | GPIO_PIN(H, 1), // D16 21 | GPIO_PIN(H, 0), // D17 22 | GPIO_PIN(D, 3), // D18 23 | GPIO_PIN(D, 2), // D19 24 | GPIO_PIN(D, 1), // D20 25 | GPIO_PIN(D, 0), // D21 26 | GPIO_PIN(A, 0), // D22 27 | GPIO_PIN(A, 1), // D23 28 | GPIO_PIN(A, 2), // D24 29 | GPIO_PIN(A, 3), // D25 30 | GPIO_PIN(A, 4), // D26 31 | GPIO_PIN(A, 5), // D27 32 | GPIO_PIN(A, 6), // D28 33 | GPIO_PIN(A, 7), // D29 34 | GPIO_PIN(C, 7), // D30 35 | GPIO_PIN(C, 6), // D31 36 | GPIO_PIN(C, 5), // D32 37 | GPIO_PIN(C, 4), // D33 38 | GPIO_PIN(C, 3), // D34 39 | GPIO_PIN(C, 2), // D35 40 | GPIO_PIN(C, 1), // D36 41 | GPIO_PIN(C, 0), // D37 42 | GPIO_PIN(D, 7), // D38 43 | GPIO_PIN(G, 2), // D39 44 | GPIO_PIN(G, 1), // D40 45 | GPIO_PIN(G, 0), // D41 46 | GPIO_PIN(L, 7), // D42 47 | GPIO_PIN(L, 6), // D43 48 | GPIO_PIN(L, 5), // D44 49 | GPIO_PIN(L, 4), // D45 50 | GPIO_PIN(L, 3), // D46 51 | GPIO_PIN(L, 2), // D47 52 | GPIO_PIN(L, 1), // D48 53 | GPIO_PIN(L, 0), // D49 54 | GPIO_PIN(B, 3), // D50 55 | GPIO_PIN(B, 2), // D51 56 | GPIO_PIN(B, 1), // D52 57 | GPIO_PIN(B, 0), // D53 58 | GPIO_PIN(F, 0), // D54 59 | GPIO_PIN(F, 1), // D55 60 | GPIO_PIN(F, 2), // D56 61 | GPIO_PIN(F, 3), // D57 62 | GPIO_PIN(F, 4), // D58 63 | GPIO_PIN(F, 5), // D59 64 | GPIO_PIN(F, 6), // D60 65 | GPIO_PIN(F, 7), // D61 66 | GPIO_PIN(K, 0), // D62 67 | GPIO_PIN(K, 1), // D63 68 | GPIO_PIN(K, 2), // D64 69 | GPIO_PIN(K, 3), // D65 70 | GPIO_PIN(K, 4), // D66 71 | GPIO_PIN(K, 5), // D67 72 | GPIO_PIN(K, 6), // D68 73 | GPIO_PIN(K, 7) // D69 74 | }; 75 | #endif // MegaGpioPinMap_h 76 | -------------------------------------------------------------------------------- /SdFat/src/SpiDriver/SdSpiBaseDriver.h: -------------------------------------------------------------------------------- 1 | /* Arduino SdCard Library 2 | * Copyright (C) 2016 by William Greiman 3 | * 4 | * This file is part of the Arduino SdSpiCard Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdSpiCard Library. If not, see 18 | * . 19 | */ 20 | #ifndef SdSpiBaseDriver_h 21 | #define SdSpiBaseDriver_h 22 | /** 23 | * \class SdSpiBaseDriver 24 | * \brief SPI base driver. 25 | */ 26 | class SdSpiBaseDriver { 27 | public: 28 | /** Set SPI options for access to SD/SDHC cards. 29 | * 30 | */ 31 | virtual void activate() = 0; 32 | /** Initialize the SPI bus. 33 | * 34 | * \param[in] chipSelectPin SD card chip select pin. 35 | */ 36 | virtual void begin(uint8_t chipSelectPin) = 0; 37 | /** 38 | * End SPI transaction. 39 | */ 40 | virtual void deactivate() = 0; 41 | /** Receive a byte. 42 | * 43 | * \return The byte. 44 | */ 45 | virtual uint8_t receive() = 0; 46 | /** Receive multiple bytes. 47 | * 48 | * \param[out] buf Buffer to receive the data. 49 | * \param[in] n Number of bytes to receive. 50 | * 51 | * \return Zero for no error or nonzero error code. 52 | */ 53 | virtual uint8_t receive(uint8_t* buf, size_t n) = 0; 54 | /** Send a byte. 55 | * 56 | * \param[in] data Byte to send 57 | */ 58 | virtual void send(uint8_t data) = 0; 59 | /** Send multiple bytes. 60 | * 61 | * \param[in] buf Buffer for data to be sent. 62 | * \param[in] n Number of bytes to send. 63 | */ 64 | virtual void send(const uint8_t* buf, size_t n) = 0; 65 | /** Set CS low. */ 66 | virtual void select() = 0; 67 | /** Save SPI settings. 68 | * \param[in] spiSettings SPI speed, mode, and bit order. 69 | */ 70 | virtual void setSpiSettings(SPISettings spiSettings) = 0; 71 | /** Set CS high. */ 72 | virtual void unselect() = 0; 73 | }; 74 | #endif // SdSpiBaseDriver_h 75 | -------------------------------------------------------------------------------- /SFEMP3Shield/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map SFEMP3Shield 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | SFEMP3Shield KEYWORD1 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | ADMixerLoad KEYWORD2 15 | ADMixerVol KEYWORD2 16 | available KEYWORD2 17 | begin KEYWORD2 18 | end KEYWORD2 19 | currentPosition KEYWORD2 20 | disableTestSineWave KEYWORD2 21 | enableTestSineWave KEYWORD2 22 | getAudioInfo KEYWORD2 23 | getBassAmplitude KEYWORD2 24 | getBassFrequency KEYWORD2 25 | getEarSpeaker KEYWORD2 26 | getMonoMode KEYWORD2 27 | getDifferentialOutput KEYWORD2 28 | getPlaySpeed KEYWORD2 29 | getState KEYWORD2 30 | getTrebleAmplitude KEYWORD2 31 | getTrebleFrequency KEYWORD2 32 | getVolume KEYWORD2 33 | getVUlevel KEYWORD2 34 | getVUmeter KEYWORD2 35 | isFnMusic KEYWORD2 36 | isPlaying KEYWORD2 37 | memoryTest KEYWORD2 38 | pauseDataStream KEYWORD2 39 | pauseMusic KEYWORD2 40 | playMP3 KEYWORD2 41 | playTrack KEYWORD2 42 | resumeDataStream KEYWORD2 43 | resumeMusic KEYWORD2 44 | SendSingleMIDInote KEYWORD2 45 | setBassAmplitude KEYWORD2 46 | setBassFrequency KEYWORD2 47 | setBitRate KEYWORD2 48 | setEarSpeaker KEYWORD2 49 | setMonoMode KEYWORD2 50 | setDifferentialOutput KEYWORD2 51 | setPlaySpeed KEYWORD2 52 | setTrebleAmplitude KEYWORD2 53 | setTrebleFrequency KEYWORD2 54 | setVolume KEYWORD2 55 | setVUmeter KEYWORD2 56 | skip KEYWORD2 57 | skipTo KEYWORD2 58 | stopTrack KEYWORD2 59 | trackAlbum KEYWORD2 60 | trackArtist KEYWORD2 61 | trackTitle KEYWORD2 62 | vs_init KEYWORD2 63 | 64 | 65 | ####################################### 66 | # Constants (LITERAL1) 67 | ####################################### 68 | 69 | ####################################### 70 | # Instances (KEYWORD3) 71 | ####################################### 72 | MP3player KEYWORD3 73 | -------------------------------------------------------------------------------- /SdFat/src/SysCall.h: -------------------------------------------------------------------------------- 1 | /* FatLib Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the FatLib Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the FatLib Library. If not, see 18 | * . 19 | */ 20 | #ifndef SysCall_h 21 | #define SysCall_h 22 | /** 23 | * \file 24 | * \brief SysCall class 25 | */ 26 | #if defined(ARDUINO) 27 | #include 28 | #include 29 | #elif defined(PLATFORM_ID) // Only defined if a Particle device 30 | #include "application.h" 31 | #else // defined(ARDUINO) 32 | #error "Unknown system" 33 | #endif // defined(ARDUINO) 34 | //----------------------------------------------------------------------------- 35 | #ifdef ESP8266 36 | // undefine F macro if ESP8266. 37 | #undef F 38 | #endif // ESP8266 39 | //----------------------------------------------------------------------------- 40 | #ifndef F 41 | /** Define macro for strings stored in flash. */ 42 | #define F(str) (str) 43 | #endif // F 44 | //----------------------------------------------------------------------------- 45 | /** \return the time in milliseconds. */ 46 | inline uint16_t curTimeMS() { 47 | return millis(); 48 | } 49 | //----------------------------------------------------------------------------- 50 | /** 51 | * \class SysCall 52 | * \brief SysCall - Class to wrap system calls. 53 | */ 54 | class SysCall { 55 | public: 56 | /** Halt execution of this thread. */ 57 | static void halt() { 58 | while (1) { 59 | yield(); 60 | } 61 | } 62 | /** Yield to other threads. */ 63 | static void yield(); 64 | }; 65 | 66 | #if defined(ESP8266) 67 | inline void SysCall::yield() { 68 | // Avoid ESP8266 bug 69 | delay(0); 70 | } 71 | #elif defined(ARDUINO) 72 | inline void SysCall::yield() { 73 | // Use the external Arduino yield() function. 74 | ::yield(); 75 | } 76 | #elif defined(PLATFORM_ID) // Only defined if a Particle device 77 | inline void SysCall::yield() { 78 | Particle.process(); 79 | } 80 | #else // ESP8266 81 | inline void SysCall::yield() {} 82 | #endif // ESP8266 83 | #endif // SysCall_h 84 | -------------------------------------------------------------------------------- /plugins/vs_plg_to_bin.pl: -------------------------------------------------------------------------------- 1 | 2 | #!/usr/bin/perl 3 | 4 | #** @file vs_plg_to_bin.pl 5 | # @verbatim 6 | ##################################################################### 7 | # This program is not guaranteed to work at all, and by using this # 8 | # program you release the author of any and all liability. # 9 | # # 10 | # You may use this code as long as you are in compliance with the # 11 | # license (see the LICENSE file) and this notice, disclaimer and # 12 | # comment box remain intact and unchanged. # 13 | # # 14 | # Purpose: to convert plugin for VLSI's Vdsp's to binary images # 15 | # as provided by VLSI's and or VIDE. # 16 | # # 17 | # example usage: vs_plg_to_bin.pl .\vs1053pcm.plg .\pcm.053 # 18 | # # 19 | ##################################################################### 20 | # @endverbatim 21 | #* 22 | use strict; 23 | use warnings; 24 | 25 | #** @var $inF 26 | # Input Arguement of Filename to be processed. 27 | #* 28 | my $inF = $ARGV[0] or die "Need input file.\n"; 29 | if ($inF !~ m/.plg$/i) { 30 | print "Input file must be plg extension.\n"; 31 | exit(1); 32 | } 33 | 34 | #** @var 35 | # Output Arguement of Filename to be created. 36 | #* 37 | my $outF = $ARGV[1] || $inF; # create the name of the output file name, if not provided. 38 | $outF =~ s/.plg$/.vs/i; 39 | 40 | open(my $infile, '<', $inF) or die "Could not open '$inF' $!\n"; 41 | 42 | while (my $line = <$infile>) # read each line 43 | { 44 | chomp $line; 45 | if ($line =~ m/short\splugin\[/i) # looking for begin of actual data. 46 | { 47 | open(my $outfile, '>:raw', $outF) or die "Unable to open: $!"; 48 | # In the above line ':raw' in the call to open tells it to put 49 | # the filehandle into binary mode on platforms where that matters 50 | # (it is equivalent to using binmode). 51 | 52 | while (my $line = <$infile>) # read each of the remaining line 53 | { 54 | while ($line =~ m/0x([0-9A-F]{1,4})/gi) # global matching for other instances on same line. 55 | { 56 | print "0x" . $1 . " "; 57 | print $outfile pack('s<', hex($1)); 58 | # In the above line, hex converts the string of hex found to a scalar integer 59 | # The pack formats the scalar, the 's' tells it to output a signed short (16 bits), 60 | # and the '>' forces it to big-endian mode, and '<' is little-endian. 61 | } 62 | print "\n"; 63 | } 64 | close($outfile); 65 | } 66 | } 67 | close($infile); 68 | -------------------------------------------------------------------------------- /SdFat/src/FatLib/FatApiConstants.h: -------------------------------------------------------------------------------- 1 | /* FatLib Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the FatLib Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the FatLib Library. If not, see 18 | * . 19 | */ 20 | #ifndef FatApiConstants_h 21 | #define FatApiConstants_h 22 | //------------------------------------------------------------------------------ 23 | // use the gnu style oflag in open() 24 | /** open() oflag for reading */ 25 | const uint8_t O_READ = 0X01; 26 | /** open() oflag - same as O_IN */ 27 | const uint8_t O_RDONLY = O_READ; 28 | /** open() oflag for write */ 29 | const uint8_t O_WRITE = 0X02; 30 | /** open() oflag - same as O_WRITE */ 31 | const uint8_t O_WRONLY = O_WRITE; 32 | /** open() oflag for reading and writing */ 33 | const uint8_t O_RDWR = (O_READ | O_WRITE); 34 | /** open() oflag mask for access modes */ 35 | const uint8_t O_ACCMODE = (O_READ | O_WRITE); 36 | /** The file offset shall be set to the end of the file prior to each write. */ 37 | const uint8_t O_APPEND = 0X04; 38 | /** synchronous writes - call sync() after each write */ 39 | const uint8_t O_SYNC = 0X08; 40 | /** truncate the file to zero length */ 41 | const uint8_t O_TRUNC = 0X10; 42 | /** set the initial position at the end of the file */ 43 | const uint8_t O_AT_END = 0X20; 44 | /** create the file if nonexistent */ 45 | const uint8_t O_CREAT = 0X40; 46 | /** If O_CREAT and O_EXCL are set, open() shall fail if the file exists */ 47 | const uint8_t O_EXCL = 0X80; 48 | 49 | // FatFile class static and const definitions 50 | // flags for ls() 51 | /** ls() flag for list all files including hidden. */ 52 | const uint8_t LS_A = 1; 53 | /** ls() flag to print modify. date */ 54 | const uint8_t LS_DATE = 2; 55 | /** ls() flag to print file size. */ 56 | const uint8_t LS_SIZE = 4; 57 | /** ls() flag for recursive list of subdirectories */ 58 | const uint8_t LS_R = 8; 59 | 60 | // flags for timestamp 61 | /** set the file's last access date */ 62 | const uint8_t T_ACCESS = 1; 63 | /** set the file's creation date and time */ 64 | const uint8_t T_CREATE = 2; 65 | /** Set the file's write date and time */ 66 | const uint8_t T_WRITE = 4; 67 | #endif // FatApiConstants_h 68 | -------------------------------------------------------------------------------- /SdFat/src/MinimumSerial.cpp: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2012 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | #include "SysCall.h" 21 | #if defined(UDR0) || defined(DOXYGEN) 22 | #include "MinimumSerial.h" 23 | const uint16_t MIN_2X_BAUD = F_CPU/(4*(2*0XFFF + 1)) + 1; 24 | //------------------------------------------------------------------------------ 25 | int MinimumSerial::available() { 26 | return UCSR0A & (1 << RXC0) ? 1 : 0; 27 | } 28 | //------------------------------------------------------------------------------ 29 | void MinimumSerial::begin(uint32_t baud) { 30 | uint16_t baud_setting; 31 | // don't worry, the compiler will squeeze out F_CPU != 16000000UL 32 | if ((F_CPU != 16000000UL || baud != 57600) && baud > MIN_2X_BAUD) { 33 | // Double the USART Transmission Speed 34 | UCSR0A = 1 << U2X0; 35 | baud_setting = (F_CPU / 4 / baud - 1) / 2; 36 | } else { 37 | // hardcoded exception for compatibility with the bootloader shipped 38 | // with the Duemilanove and previous boards and the firmware on the 8U2 39 | // on the Uno and Mega 2560. 40 | UCSR0A = 0; 41 | baud_setting = (F_CPU / 8 / baud - 1) / 2; 42 | } 43 | // assign the baud_setting 44 | UBRR0H = baud_setting >> 8; 45 | UBRR0L = baud_setting; 46 | // enable transmit and receive 47 | UCSR0B |= (1 << TXEN0) | (1 << RXEN0); 48 | } 49 | //------------------------------------------------------------------------------ 50 | void MinimumSerial::flush() { 51 | while (((1 << UDRIE0) & UCSR0B) || !(UCSR0A & (1 << UDRE0))) {} 52 | } 53 | //------------------------------------------------------------------------------ 54 | int MinimumSerial::read() { 55 | if (UCSR0A & (1 << RXC0)) { 56 | return UDR0; 57 | } 58 | return -1; 59 | } 60 | //------------------------------------------------------------------------------ 61 | size_t MinimumSerial::write(uint8_t b) { 62 | while (((1 << UDRIE0) & UCSR0B) || !(UCSR0A & (1 << UDRE0))) {} 63 | UDR0 = b; 64 | return 1; 65 | } 66 | #endif // defined(UDR0) || defined(DOXYGEN) 67 | -------------------------------------------------------------------------------- /SdFat/src/SdCard/SdSpiCardEX.cpp: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2016 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | #include "SdSpiCard.h" 21 | bool SdSpiCardEX::readBlock(uint32_t block, uint8_t* dst) { 22 | if (m_curState != READ_STATE || block != m_curBlock) { 23 | if (!syncBlocks()) { 24 | return false; 25 | } 26 | if (!SdSpiCard::readStart(block)) { 27 | return false; 28 | } 29 | m_curBlock = block; 30 | m_curState = READ_STATE; 31 | } 32 | if (!SdSpiCard::readData(dst)) { 33 | return false; 34 | } 35 | m_curBlock++; 36 | return true; 37 | } 38 | //----------------------------------------------------------------------------- 39 | bool SdSpiCardEX::readBlocks(uint32_t block, uint8_t* dst, size_t nb) { 40 | for (size_t i = 0; i < nb; i++) { 41 | if (!readBlock(block + i, dst + i*512UL)) { 42 | return false; 43 | } 44 | } 45 | return true; 46 | } 47 | //----------------------------------------------------------------------------- 48 | bool SdSpiCardEX::syncBlocks() { 49 | if (m_curState == READ_STATE) { 50 | m_curState = IDLE_STATE; 51 | if (!SdSpiCard::readStop()) { 52 | return false; 53 | } 54 | } else if (m_curState == WRITE_STATE) { 55 | m_curState = IDLE_STATE; 56 | if (!SdSpiCard::writeStop()) { 57 | return false; 58 | } 59 | } 60 | return true; 61 | } 62 | //----------------------------------------------------------------------------- 63 | bool SdSpiCardEX::writeBlock(uint32_t block, const uint8_t* src) { 64 | if (m_curState != WRITE_STATE || m_curBlock != block) { 65 | if (!syncBlocks()) { 66 | return false; 67 | } 68 | if (!SdSpiCard::writeStart(block)) { 69 | return false; 70 | } 71 | m_curBlock = block; 72 | m_curState = WRITE_STATE; 73 | } 74 | if (!SdSpiCard::writeData(src)) { 75 | return false; 76 | } 77 | m_curBlock++; 78 | return true; 79 | } 80 | //----------------------------------------------------------------------------- 81 | bool SdSpiCardEX::writeBlocks(uint32_t block, 82 | const uint8_t* src, size_t nb) { 83 | for (size_t i = 0; i < nb; i++) { 84 | if (!writeBlock(block + i, src + i*512UL)) { 85 | return false; 86 | } 87 | } 88 | return true; 89 | } 90 | -------------------------------------------------------------------------------- /SdFat/src/FatLib/BaseBlockDriver.h: -------------------------------------------------------------------------------- 1 | /* FatLib Library 2 | * Copyright (C) 2016 by William Greiman 3 | * 4 | * This file is part of the FatLib Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the FatLib Library. If not, see 18 | * . 19 | */ 20 | #ifndef BaseBlockDriver_h 21 | #define BaseBlockDriver_h 22 | #include "FatLibConfig.h" 23 | /** 24 | * \class BaseBlockDriver 25 | * \brief Base block driver. 26 | */ 27 | class BaseBlockDriver { 28 | public: 29 | /** 30 | * Read a 512 byte block from an SD card. 31 | * 32 | * \param[in] block Logical block to be read. 33 | * \param[out] dst Pointer to the location that will receive the data. 34 | * \return The value true is returned for success and 35 | * the value false is returned for failure. 36 | */ 37 | virtual bool readBlock(uint32_t block, uint8_t* dst) = 0; 38 | /** End multi-block transfer and go to idle state. 39 | * \return The value true is returned for success and 40 | * the value false is returned for failure. 41 | */ 42 | virtual bool syncBlocks() = 0; 43 | /** 44 | * Writes a 512 byte block to an SD card. 45 | * 46 | * \param[in] block Logical block to be written. 47 | * \param[in] src Pointer to the location of the data to be written. 48 | * \return The value true is returned for success and 49 | * the value false is returned for failure. 50 | */ 51 | virtual bool writeBlock(uint32_t block, const uint8_t* src) = 0; 52 | #if USE_MULTI_BLOCK_IO 53 | /** 54 | * Read multiple 512 byte blocks from an SD card. 55 | * 56 | * \param[in] block Logical block to be read. 57 | * \param[in] nb Number of blocks to be read. 58 | * \param[out] dst Pointer to the location that will receive the data. 59 | * \return The value true is returned for success and 60 | * the value false is returned for failure. 61 | */ 62 | virtual bool readBlocks(uint32_t block, uint8_t* dst, size_t nb) = 0; 63 | /** 64 | * Write multiple 512 byte blocks to an SD card. 65 | * 66 | * \param[in] block Logical block to be written. 67 | * \param[in] nb Number of blocks to be written. 68 | * \param[in] src Pointer to the location of the data to be written. 69 | * \return The value true is returned for success and 70 | * the value false is returned for failure. 71 | */ 72 | virtual bool writeBlocks(uint32_t block, const uint8_t* src, size_t nb) = 0; 73 | #endif // USE_MULTI_BLOCK_IO 74 | }; 75 | #endif // BaseBlockDriver_h 76 | -------------------------------------------------------------------------------- /SdFat/src/SpiDriver/SdSpiESP8266.cpp: -------------------------------------------------------------------------------- 1 | /* Arduino SdSpiAltDriver Library 2 | * Copyright (C) 2016 by William Greiman 3 | * 4 | * STM32F1 code for Maple and Maple Mini support, 2015 by Victor Perez 5 | * 6 | * This file is part of the Arduino SdSpiAltDriver Library 7 | * 8 | * This Library is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This Library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with the Arduino SdSpiAltDriver Library. If not, see 20 | * . 21 | */ 22 | #if defined(ESP8266) 23 | #include "SdSpiDriver.h" 24 | //------------------------------------------------------------------------------ 25 | /** Initialize the SPI bus. 26 | * 27 | * \param[in] chipSelectPin SD card chip select pin. 28 | */ 29 | void SdSpiAltDriver::begin(uint8_t csPin) { 30 | m_csPin = csPin; 31 | pinMode(m_csPin, OUTPUT); 32 | digitalWrite(m_csPin, HIGH); 33 | SPI.begin(); 34 | } 35 | //------------------------------------------------------------------------------ 36 | /** Set SPI options for access to SD/SDHC cards. 37 | * 38 | */ 39 | void SdSpiAltDriver::activate() { 40 | SPI.beginTransaction(m_spiSettings); 41 | } 42 | //------------------------------------------------------------------------------ 43 | void SdSpiAltDriver::deactivate() { 44 | // Note: endTransaction is an empty function on ESP8266. 45 | SPI.endTransaction(); 46 | } 47 | //------------------------------------------------------------------------------ 48 | /** Receive a byte. 49 | * 50 | * \return The byte. 51 | */ 52 | uint8_t SdSpiAltDriver::receive() { 53 | return SPI.transfer(0XFF); 54 | } 55 | //------------------------------------------------------------------------------ 56 | /** Receive multiple bytes. 57 | * 58 | * \param[out] buf Buffer to receive the data. 59 | * \param[in] n Number of bytes to receive. 60 | * 61 | * \return Zero for no error or nonzero error code. 62 | */ 63 | uint8_t SdSpiAltDriver::receive(uint8_t* buf, size_t n) { 64 | // Works without 32-bit alignment of buf. 65 | SPI.transferBytes(0, buf, n); 66 | return 0; 67 | } 68 | //------------------------------------------------------------------------------ 69 | /** Send a byte. 70 | * 71 | * \param[in] b Byte to send 72 | */ 73 | void SdSpiAltDriver::send(uint8_t b) { 74 | SPI.transfer(b); 75 | } 76 | //------------------------------------------------------------------------------ 77 | /** Send multiple bytes. 78 | * 79 | * \param[in] buf Buffer for data to be sent. 80 | * \param[in] n Number of bytes to send. 81 | */ 82 | void SdSpiAltDriver::send(const uint8_t* buf , size_t n) { 83 | // Adjust to 32-bit alignment. 84 | while ((reinterpret_cast(buf) & 0X3) && n) { 85 | SPI.transfer(*buf++); 86 | n--; 87 | } 88 | SPI.transferBytes(const_cast(buf), 0, n); 89 | } 90 | #endif // defined(ESP8266) 91 | -------------------------------------------------------------------------------- /SdFat/src/SdCard/SdioCardEX.cpp: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2016 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | #include "SdioCard.h" 21 | 22 | // limit of K66 due to errata KINETIS_K_0N65N. 23 | const uint32_t MAX_SDHC_COUNT = 0XFFFF; 24 | 25 | // Max RU is 1024 blocks. 26 | const uint32_t RU_MASK = 0X03FF; 27 | 28 | bool SdioCardEX::readBlock(uint32_t lba, uint8_t* dst) { 29 | if (m_curState != READ_STATE || lba != m_curLba) { 30 | if (!syncBlocks()) { 31 | return false; 32 | } 33 | m_limitLba = (lba + MAX_SDHC_COUNT) & ~RU_MASK; 34 | if (!SdioCard::readStart(lba, m_limitLba - lba)) { 35 | return false; 36 | } 37 | m_curLba = lba; 38 | m_curState = READ_STATE; 39 | } 40 | if (!SdioCard::readData(dst)) { 41 | return false; 42 | } 43 | m_curLba++; 44 | if (m_curLba >= m_limitLba) { 45 | m_curState = IDLE_STATE; 46 | } 47 | return true; 48 | } 49 | //----------------------------------------------------------------------------- 50 | bool SdioCardEX::readBlocks(uint32_t lba, uint8_t* dst, size_t nb) { 51 | for (size_t i = 0; i < nb; i++) { 52 | if (!readBlock(lba + i, dst + i*512UL)) { 53 | return false; 54 | } 55 | } 56 | return true; 57 | } 58 | //----------------------------------------------------------------------------- 59 | bool SdioCardEX::syncBlocks() { 60 | if (m_curState == READ_STATE) { 61 | m_curState = IDLE_STATE; 62 | if (!SdioCard::readStop()) { 63 | return false; 64 | } 65 | } else if (m_curState == WRITE_STATE) { 66 | m_curState = IDLE_STATE; 67 | if (!SdioCard::writeStop()) { 68 | return false; 69 | } 70 | } 71 | return true; 72 | } 73 | //----------------------------------------------------------------------------- 74 | bool SdioCardEX::writeBlock(uint32_t lba, const uint8_t* src) { 75 | if (m_curState != WRITE_STATE || m_curLba != lba) { 76 | if (!syncBlocks()) { 77 | return false; 78 | } 79 | m_limitLba = (lba + MAX_SDHC_COUNT) & ~RU_MASK; 80 | if (!SdioCard::writeStart(lba , m_limitLba - lba)) { 81 | return false; 82 | } 83 | m_curLba = lba; 84 | m_curState = WRITE_STATE; 85 | } 86 | if (!SdioCard::writeData(src)) { 87 | return false; 88 | } 89 | m_curLba++; 90 | if (m_curLba >= m_limitLba) { 91 | m_curState = IDLE_STATE; 92 | } 93 | return true; 94 | } 95 | //----------------------------------------------------------------------------- 96 | bool SdioCardEX::writeBlocks(uint32_t lba, const uint8_t* src, size_t nb) { 97 | for (size_t i = 0; i < nb; i++) { 98 | if (!writeBlock(lba + i, src + i*512UL)) { 99 | return false; 100 | } 101 | } 102 | return true; 103 | } 104 | -------------------------------------------------------------------------------- /SdFat/src/FatLib/ArduinoStream.h: -------------------------------------------------------------------------------- 1 | /* FatLib Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the FatLib Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the FatLib Library. If not, see 18 | * . 19 | */ 20 | #ifndef ArduinoStream_h 21 | #define ArduinoStream_h 22 | /** 23 | * \file 24 | * \brief ArduinoInStream and ArduinoOutStream classes 25 | */ 26 | #include "FatLibConfig.h" 27 | #if ENABLE_ARDUINO_FEATURES 28 | #include "bufstream.h" 29 | //============================================================================== 30 | /** 31 | * \class ArduinoInStream 32 | * \brief Input stream for Arduino Stream objects 33 | */ 34 | class ArduinoInStream : public ibufstream { 35 | public: 36 | /** 37 | * Constructor 38 | * \param[in] hws hardware stream 39 | * \param[in] buf buffer for input line 40 | * \param[in] size size of input buffer 41 | */ 42 | ArduinoInStream(Stream &hws, char* buf, size_t size) { 43 | m_hw = &hws; 44 | m_line = buf; 45 | m_size = size; 46 | } 47 | /** read a line. */ 48 | void readline() { 49 | size_t i = 0; 50 | uint32_t t; 51 | m_line[0] = '\0'; 52 | while (!m_hw->available()) { 53 | yield(); 54 | } 55 | 56 | while (1) { 57 | t = millis(); 58 | while (!m_hw->available()) { 59 | if ((millis() - t) > 10) { 60 | goto done; 61 | } 62 | } 63 | if (i >= (m_size - 1)) { 64 | setstate(failbit); 65 | return; 66 | } 67 | m_line[i++] = m_hw->read(); 68 | m_line[i] = '\0'; 69 | } 70 | done: 71 | init(m_line); 72 | } 73 | 74 | protected: 75 | /** Internal - do not use. 76 | * \param[in] off 77 | * \param[in] way 78 | * \return true/false. 79 | */ 80 | bool seekoff(off_type off, seekdir way) { 81 | (void)off; 82 | (void)way; 83 | return false; 84 | } 85 | /** Internal - do not use. 86 | * \param[in] pos 87 | * \return true/false. 88 | */ 89 | bool seekpos(pos_type pos) { 90 | (void)pos; 91 | return false; 92 | } 93 | 94 | private: 95 | char *m_line; 96 | size_t m_size; 97 | Stream* m_hw; 98 | }; 99 | //============================================================================== 100 | /** 101 | * \class ArduinoOutStream 102 | * \brief Output stream for Arduino Print objects 103 | */ 104 | class ArduinoOutStream : public ostream { 105 | public: 106 | /** constructor 107 | * 108 | * \param[in] pr Print object for this ArduinoOutStream. 109 | */ 110 | explicit ArduinoOutStream(Print& pr) : m_pr(&pr) {} 111 | 112 | protected: 113 | /// @cond SHOW_PROTECTED 114 | /** 115 | * Internal do not use 116 | * \param[in] c 117 | */ 118 | void putch(char c) { 119 | if (c == '\n') { 120 | m_pr->write('\r'); 121 | } 122 | m_pr->write(c); 123 | } 124 | void putstr(const char* str) { 125 | m_pr->write(str); 126 | } 127 | bool seekoff(off_type off, seekdir way) { 128 | (void)off; 129 | (void)way; 130 | return false; 131 | } 132 | bool seekpos(pos_type pos) { 133 | (void)pos; 134 | return false; 135 | } 136 | bool sync() { 137 | return true; 138 | } 139 | pos_type tellpos() { 140 | return 0; 141 | } 142 | /// @endcond 143 | private: 144 | ArduinoOutStream() {} 145 | Print* m_pr; 146 | }; 147 | #endif // ENABLE_ARDUINO_FEATURES 148 | #endif // ArduinoStream_h 149 | -------------------------------------------------------------------------------- /SdFat/src/FatLib/iostream.h: -------------------------------------------------------------------------------- 1 | /* FatLib Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the FatLib Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the FatLib Library. If not, see 18 | * . 19 | */ 20 | #ifndef iostream_h 21 | #define iostream_h 22 | /** 23 | * \file 24 | * \brief \ref iostream class 25 | */ 26 | #include "istream.h" 27 | #include "ostream.h" 28 | /** Skip white space 29 | * \param[in] is the Stream 30 | * \return The stream 31 | */ 32 | inline istream& ws(istream& is) { 33 | is.skipWhite(); 34 | return is; 35 | } 36 | /** insert endline 37 | * \param[in] os The Stream 38 | * \return The stream 39 | */ 40 | inline ostream& endl(ostream& os) { 41 | os.put('\n'); 42 | #if ENDL_CALLS_FLUSH 43 | os.flush(); 44 | #endif // ENDL_CALLS_FLUSH 45 | return os; 46 | } 47 | /** flush manipulator 48 | * \param[in] os The stream 49 | * \return The stream 50 | */ 51 | inline ostream& flush(ostream& os) { 52 | os.flush(); 53 | return os; 54 | } 55 | /** 56 | * \struct setfill 57 | * \brief type for setfill manipulator 58 | */ 59 | struct setfill { 60 | /** fill character */ 61 | char c; 62 | /** constructor 63 | * 64 | * \param[in] arg new fill character 65 | */ 66 | explicit setfill(char arg) : c(arg) {} 67 | }; 68 | /** setfill manipulator 69 | * \param[in] os the stream 70 | * \param[in] arg set setfill object 71 | * \return the stream 72 | */ 73 | inline ostream &operator<< (ostream &os, const setfill &arg) { 74 | os.fill(arg.c); 75 | return os; 76 | } 77 | /** setfill manipulator 78 | * \param[in] obj the stream 79 | * \param[in] arg set setfill object 80 | * \return the stream 81 | */ 82 | inline istream &operator>>(istream &obj, const setfill &arg) { 83 | obj.fill(arg.c); 84 | return obj; 85 | } 86 | //------------------------------------------------------------------------------ 87 | /** \struct setprecision 88 | * \brief type for setprecision manipulator 89 | */ 90 | struct setprecision { 91 | /** precision */ 92 | unsigned int p; 93 | /** constructor 94 | * \param[in] arg new precision 95 | */ 96 | explicit setprecision(unsigned int arg) : p(arg) {} 97 | }; 98 | /** setprecision manipulator 99 | * \param[in] os the stream 100 | * \param[in] arg set setprecision object 101 | * \return the stream 102 | */ 103 | inline ostream &operator<< (ostream &os, const setprecision &arg) { 104 | os.precision(arg.p); 105 | return os; 106 | } 107 | /** setprecision manipulator 108 | * \param[in] is the stream 109 | * \param[in] arg set setprecision object 110 | * \return the stream 111 | */ 112 | inline istream &operator>>(istream &is, const setprecision &arg) { 113 | is.precision(arg.p); 114 | return is; 115 | } 116 | //------------------------------------------------------------------------------ 117 | /** \struct setw 118 | * \brief type for setw manipulator 119 | */ 120 | struct setw { 121 | /** width */ 122 | unsigned w; 123 | /** constructor 124 | * \param[in] arg new width 125 | */ 126 | explicit setw(unsigned arg) : w(arg) {} 127 | }; 128 | /** setw manipulator 129 | * \param[in] os the stream 130 | * \param[in] arg set setw object 131 | * \return the stream 132 | */ 133 | inline ostream &operator<< (ostream &os, const setw &arg) { 134 | os.width(arg.w); 135 | return os; 136 | } 137 | /** setw manipulator 138 | * \param[in] is the stream 139 | * \param[in] arg set setw object 140 | * \return the stream 141 | */ 142 | inline istream &operator>>(istream &is, const setw &arg) { 143 | is.width(arg.w); 144 | return is; 145 | } 146 | //============================================================================== 147 | /** 148 | * \class iostream 149 | * \brief Input/Output stream 150 | */ 151 | class iostream : public istream, public ostream { 152 | }; 153 | #endif // iostream_h 154 | -------------------------------------------------------------------------------- /SdFat/src/SpiDriver/SdSpiSTM32F1.cpp: -------------------------------------------------------------------------------- 1 | /* Arduino SdSpiAltDriver Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the Arduino SdSpiAltDriver Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdSpiAltDriver Library. If not, see 18 | * . 19 | */ 20 | #if defined(__STM32F1__) 21 | #include "SdSpiDriver.h" 22 | #define USE_STM32F1_DMAC 1 23 | //------------------------------------------------------------------------------ 24 | static SPIClass m_SPI1(1); 25 | #if BOARD_NR_SPI > 1 26 | static SPIClass m_SPI2(2); 27 | #endif // BOARD_NR_SPI > 1 28 | #if BOARD_NR_SPI > 2 29 | static SPIClass m_SPI3(3); 30 | #endif // BOARD_NR_SPI > 2 31 | // 32 | static SPIClass* pSpi[] = 33 | #if BOARD_NR_SPI == 1 34 | {&m_SPI1}; 35 | #elif BOARD_NR_SPI == 2 36 | {&m_SPI1, &m_SPI2}; 37 | #elif BOARD_NR_SPI == 3 38 | {&m_SPI1, &m_SPI2, &m_SPI3}; 39 | #else // BOARD_NR_SPI 40 | #error "BOARD_NR_SPI too large" 41 | #endif // BOARD_NR_SPI 42 | //------------------------------------------------------------------------------ 43 | /** Set SPI options for access to SD/SDHC cards. 44 | * 45 | * \param[in] divisor SCK clock divider relative to the APB1 or APB2 clock. 46 | */ 47 | void SdSpiAltDriver::activate() { 48 | pSpi[m_spiPort]->beginTransaction(m_spiSettings); 49 | } 50 | //------------------------------------------------------------------------------ 51 | /** Initialize the SPI bus. 52 | * 53 | * \param[in] chipSelectPin SD card chip select pin. 54 | */ 55 | void SdSpiAltDriver::begin(uint8_t csPin) { 56 | m_csPin = csPin; 57 | pinMode(m_csPin, OUTPUT); 58 | digitalWrite(m_csPin, HIGH); 59 | pSpi[m_spiPort]->begin(); 60 | } 61 | //------------------------------------------------------------------------------ 62 | /** 63 | * End SPI transaction. 64 | */ 65 | void SdSpiAltDriver::deactivate() { 66 | pSpi[m_spiPort]->endTransaction(); 67 | } 68 | //------------------------------------------------------------------------------ 69 | /** Receive a byte. 70 | * 71 | * \return The byte. 72 | */ 73 | uint8_t SdSpiAltDriver::receive() { 74 | return pSpi[m_spiPort]->transfer(0XFF); 75 | } 76 | //------------------------------------------------------------------------------ 77 | /** Receive multiple bytes. 78 | * 79 | * \param[out] buf Buffer to receive the data. 80 | * \param[in] n Number of bytes to receive. 81 | * 82 | * \return Zero for no error or nonzero error code. 83 | */ 84 | uint8_t SdSpiAltDriver::receive(uint8_t* buf, size_t n) { 85 | int rtn = 0; 86 | #if USE_STM32F1_DMAC 87 | rtn = pSpi[m_spiPort]->dmaTransfer(0, const_cast(buf), n); 88 | #else // USE_STM32F1_DMAC 89 | // pSpi[m_spiPort]->read(buf, n); fails ?? use byte transfer 90 | for (size_t i = 0; i < n; i++) { 91 | buf[i] = pSpi[m_spiPort]->transfer(0XFF); 92 | } 93 | #endif // USE_STM32F1_DMAC 94 | return rtn; 95 | } 96 | //------------------------------------------------------------------------------ 97 | /** Send a byte. 98 | * 99 | * \param[in] b Byte to send 100 | */ 101 | void SdSpiAltDriver::send(uint8_t b) { 102 | pSpi[m_spiPort]->transfer(b); 103 | } 104 | //------------------------------------------------------------------------------ 105 | /** Send multiple bytes. 106 | * 107 | * \param[in] buf Buffer for data to be sent. 108 | * \param[in] n Number of bytes to send. 109 | */ 110 | void SdSpiAltDriver::send(const uint8_t* buf , size_t n) { 111 | #if USE_STM32F1_DMAC 112 | pSpi[m_spiPort]->dmaSend(const_cast(buf), n); 113 | #else // #if USE_STM32F1_DMAC 114 | pSpi[m_spiPort]->write(buf, n); 115 | #endif // USE_STM32F1_DMAC 116 | } 117 | //----------------------------------------------------------------------------- 118 | void SdSpiAltDriver::setPort(uint8_t portNumber) { 119 | m_spiPort = portNumber < 1 || portNumber > BOARD_NR_SPI ? 0 : portNumber -1; 120 | } 121 | #endif // defined(__STM32F1__) 122 | -------------------------------------------------------------------------------- /SdFat/src/FatLib/bufstream.h: -------------------------------------------------------------------------------- 1 | /* FatLib Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the FatLib Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the FatLib Library. If not, see 18 | * . 19 | */ 20 | #ifndef bufstream_h 21 | #define bufstream_h 22 | /** 23 | * \file 24 | * \brief \ref ibufstream and \ref obufstream classes 25 | */ 26 | #include 27 | #include "iostream.h" 28 | //============================================================================== 29 | /** 30 | * \class ibufstream 31 | * \brief parse a char string 32 | */ 33 | class ibufstream : public istream { 34 | public: 35 | /** Constructor */ 36 | ibufstream() : m_buf(0), m_len(0) {} 37 | /** Constructor 38 | * \param[in] str pointer to string to be parsed 39 | * Warning: The string will not be copied so must stay in scope. 40 | */ 41 | explicit ibufstream(const char* str) { 42 | init(str); 43 | } 44 | /** Initialize an ibufstream 45 | * \param[in] str pointer to string to be parsed 46 | * Warning: The string will not be copied so must stay in scope. 47 | */ 48 | void init(const char* str) { 49 | m_buf = str; 50 | m_len = strlen(m_buf); 51 | m_pos = 0; 52 | clear(); 53 | } 54 | 55 | protected: 56 | /// @cond SHOW_PROTECTED 57 | int16_t getch() { 58 | if (m_pos < m_len) { 59 | return m_buf[m_pos++]; 60 | } 61 | setstate(eofbit); 62 | return -1; 63 | } 64 | void getpos(FatPos_t *pos) { 65 | pos->position = m_pos; 66 | } 67 | bool seekoff(off_type off, seekdir way) { 68 | (void)off; 69 | (void)way; 70 | return false; 71 | } 72 | bool seekpos(pos_type pos) { 73 | if (pos < m_len) { 74 | m_pos = pos; 75 | return true; 76 | } 77 | return false; 78 | } 79 | void setpos(FatPos_t *pos) { 80 | m_pos = pos->position; 81 | } 82 | pos_type tellpos() { 83 | return m_pos; 84 | } 85 | /// @endcond 86 | private: 87 | const char* m_buf; 88 | size_t m_len; 89 | size_t m_pos; 90 | }; 91 | //============================================================================== 92 | /** 93 | * \class obufstream 94 | * \brief format a char string 95 | */ 96 | class obufstream : public ostream { 97 | public: 98 | /** constructor */ 99 | obufstream() : m_in(0) {} 100 | /** Constructor 101 | * \param[in] buf buffer for formatted string 102 | * \param[in] size buffer size 103 | */ 104 | obufstream(char *buf, size_t size) { 105 | init(buf, size); 106 | } 107 | /** Initialize an obufstream 108 | * \param[in] buf buffer for formatted string 109 | * \param[in] size buffer size 110 | */ 111 | void init(char *buf, size_t size) { 112 | m_buf = buf; 113 | buf[0] = '\0'; 114 | m_size = size; 115 | m_in = 0; 116 | } 117 | /** \return a pointer to the buffer */ 118 | char* buf() { 119 | return m_buf; 120 | } 121 | /** \return the length of the formatted string */ 122 | size_t length() { 123 | return m_in; 124 | } 125 | 126 | protected: 127 | /// @cond SHOW_PROTECTED 128 | void putch(char c) { 129 | if (m_in >= (m_size - 1)) { 130 | setstate(badbit); 131 | return; 132 | } 133 | m_buf[m_in++] = c; 134 | m_buf[m_in] = '\0'; 135 | } 136 | void putstr(const char *str) { 137 | while (*str) { 138 | putch(*str++); 139 | } 140 | } 141 | bool seekoff(off_type off, seekdir way) { 142 | (void)off; 143 | (void)way; 144 | return false; 145 | } 146 | bool seekpos(pos_type pos) { 147 | if (pos > m_in) { 148 | return false; 149 | } 150 | m_in = pos; 151 | m_buf[m_in] = '\0'; 152 | return true; 153 | } 154 | bool sync() { 155 | return true; 156 | } 157 | 158 | pos_type tellpos() { 159 | return m_in; 160 | } 161 | /// @endcond 162 | private: 163 | char *m_buf; 164 | size_t m_size; 165 | size_t m_in; 166 | }; 167 | #endif // bufstream_h 168 | -------------------------------------------------------------------------------- /SdFat/src/FatLib/fstream.cpp: -------------------------------------------------------------------------------- 1 | /* FatLib Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the FatLib Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the FatLib Library. If not, see 18 | * . 19 | */ 20 | #include "fstream.h" 21 | //============================================================================== 22 | /// @cond SHOW_PROTECTED 23 | int16_t FatStreamBase::getch() { 24 | uint8_t c; 25 | int8_t s = read(&c, 1); 26 | if (s != 1) { 27 | if (s < 0) { 28 | setstate(badbit); 29 | } else { 30 | setstate(eofbit); 31 | } 32 | return -1; 33 | } 34 | if (c != '\r' || (getmode() & ios::binary)) { 35 | return c; 36 | } 37 | s = read(&c, 1); 38 | if (s == 1 && c == '\n') { 39 | return c; 40 | } 41 | if (s == 1) { 42 | seekCur(-1); 43 | } 44 | return '\r'; 45 | } 46 | //------------------------------------------------------------------------------ 47 | void FatStreamBase::open(const char* path, ios::openmode mode) { 48 | uint8_t flags; 49 | switch (mode & (app | in | out | trunc)) { 50 | case app | in: 51 | case app | in | out: 52 | flags = O_RDWR | O_APPEND | O_CREAT; 53 | break; 54 | 55 | case app: 56 | case app | out: 57 | flags = O_WRITE | O_APPEND | O_CREAT; 58 | break; 59 | 60 | case in: 61 | flags = O_READ; 62 | break; 63 | 64 | case in | out: 65 | flags = O_RDWR; 66 | break; 67 | 68 | case in | out | trunc: 69 | flags = O_RDWR | O_TRUNC | O_CREAT; 70 | break; 71 | 72 | case out: 73 | case out | trunc: 74 | flags = O_WRITE | O_TRUNC | O_CREAT; 75 | break; 76 | 77 | default: 78 | goto fail; 79 | } 80 | if (mode & ios::ate) { 81 | flags |= O_AT_END; 82 | } 83 | if (!FatFile::open(path, flags)) { 84 | goto fail; 85 | } 86 | setmode(mode); 87 | clear(); 88 | return; 89 | 90 | fail: 91 | FatFile::close(); 92 | setstate(failbit); 93 | return; 94 | } 95 | //------------------------------------------------------------------------------ 96 | void FatStreamBase::putch(char c) { 97 | if (c == '\n' && !(getmode() & ios::binary)) { 98 | write('\r'); 99 | } 100 | write(c); 101 | if (getWriteError()) { 102 | setstate(badbit); 103 | } 104 | } 105 | //------------------------------------------------------------------------------ 106 | void FatStreamBase::putstr(const char* str) { 107 | size_t n = 0; 108 | while (1) { 109 | char c = str[n]; 110 | if (c == '\0' || (c == '\n' && !(getmode() & ios::binary))) { 111 | if (n > 0) { 112 | write(str, n); 113 | } 114 | if (c == '\0') { 115 | break; 116 | } 117 | write('\r'); 118 | str += n; 119 | n = 0; 120 | } 121 | n++; 122 | } 123 | if (getWriteError()) { 124 | setstate(badbit); 125 | } 126 | } 127 | //------------------------------------------------------------------------------ 128 | /** Internal do not use 129 | * \param[in] off 130 | * \param[in] way 131 | */ 132 | bool FatStreamBase::seekoff(off_type off, seekdir way) { 133 | pos_type pos; 134 | switch (way) { 135 | case beg: 136 | pos = off; 137 | break; 138 | 139 | case cur: 140 | pos = curPosition() + off; 141 | break; 142 | 143 | case end: 144 | pos = fileSize() + off; 145 | break; 146 | 147 | default: 148 | return false; 149 | } 150 | return seekpos(pos); 151 | } 152 | //------------------------------------------------------------------------------ 153 | /** Internal do not use 154 | * \param[in] pos 155 | */ 156 | bool FatStreamBase::seekpos(pos_type pos) { 157 | return seekSet(pos); 158 | } 159 | //------------------------------------------------------------------------------ 160 | int FatStreamBase::write(const void* buf, size_t n) { 161 | return FatFile::write(buf, n); 162 | } 163 | //------------------------------------------------------------------------------ 164 | void FatStreamBase::write(char c) { 165 | write(&c, 1); 166 | } 167 | /// @endcond 168 | -------------------------------------------------------------------------------- /SFEMP3Shield/Examples/MP3ButtonPlayer2/MP3ButtonPlayer2.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * \file MP3ButtonPlayer2.ino 3 | * 4 | * \brief Example sketch of using the MP3Shield Arduino driver using buttons, 5 | * with arduino recommended(simpler) debounce library 6 | * \remarks comments are implemented with Doxygen Markdown format 7 | * 8 | * \author Michael P. Flaga 9 | * 10 | * This sketch demonstrates the use of digital input pins used as buttons as 11 | * NEXT, PLAY and STOP to control the tracks that are to be played. 12 | * Where PLAY or STOP will begin or cancel the stream of track000.mp3 through 13 | * track999.mp3, as indexed by NEXT, begining with 0. 14 | 15 | * \note Use this example uses the bounce2 library to provide debouncing fuctions. Advocated by Arduino's website at http://playground.arduino.cc/code/bounce 16 | */ 17 | 18 | // libraries 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | /** 25 | * \breif Macro for the debounced NEXT pin, with pull-up 26 | */ 27 | #define B_NEXT A0 28 | 29 | /** 30 | * \breif Macro for the debounced STOP pin, with pull-up 31 | */ 32 | #define B_STOP A1 33 | 34 | /** 35 | * \breif Macro for the debounced PLAY pin, with pull-up 36 | */ 37 | #define B_PLAY A2 38 | 39 | /** 40 | * \breif Macro for the Debounce Period [milliseconds] 41 | */ 42 | #define BUTTON_DEBOUNCE_PERIOD 20 //ms 43 | 44 | /** 45 | * \brief Object instancing the SdFat library. 46 | * 47 | * principal object for handling all SdCard functions. 48 | */ 49 | SdFat sd; 50 | 51 | /** 52 | * \brief Object instancing the SFEMP3Shield library. 53 | * 54 | * principal object for handling all the attributes, members and functions for the library. 55 | */ 56 | SFEMP3Shield MP3player; 57 | 58 | /** 59 | * \brief Object instancing the Next Button. 60 | */ 61 | Bounce b_Next = Bounce(); 62 | 63 | /** 64 | * \brief Object instancing the Stop Button library. 65 | */ 66 | Bounce b_Stop = Bounce(); 67 | 68 | /** 69 | * \brief Object instancing the Play Button library. 70 | */ 71 | Bounce b_Play = Bounce(); 72 | 73 | /** 74 | * \brief Index of the current track playing. 75 | * 76 | * Value indicates current playing track, used to populate "x" for playing the 77 | * filename of "track00x.mp3" for track000.mp3 through track254.mp3 78 | */ 79 | int8_t current_track = 0; 80 | 81 | //------------------------------------------------------------------------------ 82 | /** 83 | * \brief Setup the Arduino Chip's feature for our use. 84 | * 85 | * After Arduino's kernel has booted initialize basic features for this 86 | * application, such as Serial port and MP3player objects with .begin. 87 | */ 88 | void setup() { 89 | Serial.begin(115200); 90 | 91 | pinMode(B_NEXT, INPUT_PULLUP); 92 | pinMode(B_STOP, INPUT_PULLUP); 93 | pinMode(B_PLAY, INPUT_PULLUP); 94 | 95 | b_Next.attach(B_NEXT); 96 | b_Next.interval(BUTTON_DEBOUNCE_PERIOD); 97 | b_Stop.attach(B_STOP); 98 | b_Stop.interval(BUTTON_DEBOUNCE_PERIOD); 99 | b_Play.attach(B_PLAY); 100 | b_Play.interval(BUTTON_DEBOUNCE_PERIOD); 101 | 102 | if(!sd.begin(9, SPI_HALF_SPEED)) sd.initErrorHalt(); 103 | if (!sd.chdir("/")) sd.errorHalt("sd.chdir"); 104 | 105 | MP3player.begin(); 106 | MP3player.setVolume(10,10); 107 | 108 | Serial.println(F("Looking for Buttons to be depressed...")); 109 | } 110 | 111 | 112 | //------------------------------------------------------------------------------ 113 | /** 114 | * \brief Main Loop the Arduino Chip 115 | * 116 | * This is called at the end of Arduino kernel's main loop before recycling. 117 | * And is where the user's is executed. 118 | * 119 | * \note If the means of refilling is not interrupt based then the 120 | * MP3player object is serviced with the availaible function. 121 | */ 122 | void loop() { 123 | 124 | // Below is only needed if not interrupt driven. Safe to remove if not using. 125 | #if defined(USE_MP3_REFILL_MEANS) \ 126 | && ( (USE_MP3_REFILL_MEANS == USE_MP3_SimpleTimer) \ 127 | || (USE_MP3_REFILL_MEANS == USE_MP3_Polled) ) 128 | 129 | MP3player.available(); 130 | #endif 131 | 132 | if (b_Play.update()) { 133 | if (b_Play.read() == LOW) { 134 | Serial.print(F("B_PLAY pressed, Start Playing Track # ")); 135 | Serial.println(current_track); 136 | MP3player.playTrack(current_track); 137 | } 138 | } 139 | 140 | if (b_Stop.update()) { 141 | if (b_Stop.read() == LOW) { 142 | Serial.print(F("B_STOP pressed, Stopping Track #")); 143 | Serial.println(current_track); 144 | MP3player.stopTrack(); 145 | } 146 | } 147 | 148 | if (b_Next.update()) { 149 | if (b_Next.read() == LOW) { 150 | Serial.print(F("B_NEXT pressed, Start Playing Next Track #")); 151 | Serial.println(++current_track); 152 | MP3player.stopTrack(); 153 | MP3player.playTrack(current_track); 154 | } 155 | } 156 | 157 | //Do something. Have fun with it. 158 | 159 | } 160 | -------------------------------------------------------------------------------- /SdFat/src/FatLib/FatLibConfig.h: -------------------------------------------------------------------------------- 1 | /* FatLib Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the FatLib Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the FatLib Library. If not, see 18 | * . 19 | */ 20 | /** 21 | * \file 22 | * \brief configuration definitions 23 | */ 24 | #ifndef FatLibConfig_h 25 | #define FatLibConfig_h 26 | #include 27 | // Allow this file to override defaults. 28 | #include "SdFatConfig.h" 29 | 30 | #ifdef __AVR__ 31 | #include 32 | #endif // __AVR__ 33 | //------------------------------------------------------------------------------ 34 | /** 35 | * Set USE_LONG_FILE_NAMES nonzero to use long file names (LFN). 36 | * Long File Name are limited to a maximum length of 255 characters. 37 | * 38 | * This implementation allows 7-bit characters in the range 39 | * 0X20 to 0X7E. The following characters are not allowed: 40 | * 41 | * < (less than) 42 | * > (greater than) 43 | * : (colon) 44 | * " (double quote) 45 | * / (forward slash) 46 | * \ (backslash) 47 | * | (vertical bar or pipe) 48 | * ? (question mark) 49 | * * (asterisk) 50 | * 51 | */ 52 | #ifndef USE_LONG_FILE_NAMES 53 | #define USE_LONG_FILE_NAMES 1 54 | #endif // USE_LONG_FILE_NAMES 55 | //------------------------------------------------------------------------------ 56 | /** 57 | * Set USE_SEPARATE_FAT_CACHE non-zero to use a second 512 byte cache 58 | * for FAT table entries. Improves performance for large writes that 59 | * are not a multiple of 512 bytes. 60 | */ 61 | #ifndef USE_SEPARATE_FAT_CACHE 62 | #ifdef __arm__ 63 | #define USE_SEPARATE_FAT_CACHE 1 64 | #else // __arm__ 65 | #define USE_SEPARATE_FAT_CACHE 0 66 | #endif // __arm__ 67 | #endif // USE_SEPARATE_FAT_CACHE 68 | //------------------------------------------------------------------------------ 69 | /** 70 | * Set USE_MULTI_BLOCK_IO non-zero to use multi-block SD read/write. 71 | * 72 | * Don't use mult-block read/write on small AVR boards. 73 | */ 74 | #ifndef USE_MULTI_BLOCK_IO 75 | #if defined(RAMEND) && RAMEND < 3000 76 | #define USE_MULTI_BLOCK_IO 0 77 | #else // RAMEND 78 | #define USE_MULTI_BLOCK_IO 1 79 | #endif // RAMEND 80 | #endif // USE_MULTI_BLOCK_IO 81 | //------------------------------------------------------------------------------ 82 | /** 83 | * Set MAINTAIN_FREE_CLUSTER_COUNT nonzero to keep the count of free clusters 84 | * updated. This will increase the speed of the freeClusterCount() call 85 | * after the first call. Extra flash will be required. 86 | */ 87 | #ifndef MAINTAIN_FREE_CLUSTER_COUNT 88 | #define MAINTAIN_FREE_CLUSTER_COUNT 0 89 | #endif // MAINTAIN_FREE_CLUSTER_COUNT 90 | //------------------------------------------------------------------------------ 91 | /** 92 | * Set DESTRUCTOR_CLOSES_FILE non-zero to close a file in its destructor. 93 | * 94 | * Causes use of lots of heap in ARM. 95 | */ 96 | #ifndef DESTRUCTOR_CLOSES_FILE 97 | #define DESTRUCTOR_CLOSES_FILE 0 98 | #endif // DESTRUCTOR_CLOSES_FILE 99 | //------------------------------------------------------------------------------ 100 | /** 101 | * Call flush for endl if ENDL_CALLS_FLUSH is non-zero 102 | * 103 | * The standard for iostreams is to call flush. This is very costly for 104 | * SdFat. Each call to flush causes 2048 bytes of I/O to the SD. 105 | * 106 | * SdFat has a single 512 byte buffer for I/O so it must write the current 107 | * data block to the SD, read the directory block from the SD, update the 108 | * directory entry, write the directory block to the SD and read the data 109 | * block back into the buffer. 110 | * 111 | * The SD flash memory controller is not designed for this many rewrites 112 | * so performance may be reduced by more than a factor of 100. 113 | * 114 | * If ENDL_CALLS_FLUSH is zero, you must call flush and/or close to force 115 | * all data to be written to the SD. 116 | */ 117 | #ifndef ENDL_CALLS_FLUSH 118 | #define ENDL_CALLS_FLUSH 0 119 | #endif // ENDL_CALLS_FLUSH 120 | //------------------------------------------------------------------------------ 121 | /** 122 | * Allow FAT12 volumes if FAT12_SUPPORT is non-zero. 123 | * FAT12 has not been well tested. 124 | */ 125 | #ifndef FAT12_SUPPORT 126 | #define FAT12_SUPPORT 0 127 | #endif // FAT12_SUPPORT 128 | //------------------------------------------------------------------------------ 129 | /** 130 | * Enable Extra features for Arduino. 131 | */ 132 | // #define ENABLE_ARDUINO_FEATURES 0 ////////////////////////FIX THIS ///////////////// 133 | #ifndef ENABLE_ARDUINO_FEATURES 134 | #include 135 | #if defined(ARDUINO) || defined(PLATFORM_ID) || defined(DOXYGEN) 136 | #define ENABLE_ARDUINO_FEATURES 1 137 | #else // #if defined(ARDUINO) || defined(DOXYGEN) 138 | #define ENABLE_ARDUINO_FEATURES 0 139 | #endif // defined(ARDUINO) || defined(DOXYGEN) 140 | #endif // ENABLE_ARDUINO_FEATURES 141 | #endif // FatLibConfig_h 142 | -------------------------------------------------------------------------------- /history.md: -------------------------------------------------------------------------------- 1 | Revision History 2 | --------------- 3 | 4 | ## 1.02.15 5 | * implemented 1.0.1 into repo 6 | 7 | ## 1.02.14 8 | * implemented sdfatlib20131225 into repo 9 | 10 | ## 1.02.13 11 | * ifdef'ed out space for Leonardo's less program space. 12 | * made FilePlayer.ino more equal to that of MP3Shield_Library_Demo.ino 13 | 14 | ## 1.02.12 15 | * implemented sdfatlib20130629 into repo 16 | * removed unused code in FilePlayer.ino 17 | 18 | ## 1.02.11 19 | * Added support for Bass Enhancer VSBE 20 | 21 | ## 1.02.10 22 | * implemented sdfatlib20130313 into repo 23 | * updated VLSI Patches and Plugins. 24 | * fixed MP3ButtonPlayer2.ino example 25 | 26 | ## 1.02.09 27 | * added demo of button using button2.h library for debounce 28 | (see gisthub for improved button.h library) 29 | 30 | ## 1.02.08 31 | * added support for BareTouch pinout in config 32 | 33 | ## 1.02.07 34 | * added SendSingleMIDInote() that sends a MIDI beep. It will suspend current playing stream to send beep and then resume prior stream 35 | 36 | ## 1.02.06 37 | * added PERF_MON_PIN to enable allowing measurement of the CPU utilization and description of performance document 38 | 39 | ## 1.02.05 40 | * implemented sdfatlib20130629 into repo 41 | * minor corrects of SdFatUtil's FreeRam() reporting correct value. 42 | 43 | ## 1.02.04 44 | * improved SPI handling to guard against other SPI effects and speed 45 | * increased SPI rate for 16Mg vs 8Mg FCPU, as to read at correct speeds. 46 | 47 | ## 1.02.03 48 | * cleared interrupt during refill, if used. As to allow others. Such as timer0 was falling behind during the SdCard track.read(). 49 | * Along with displaying current second at command prompt, for verifying time. 50 | 51 | ## 1.02.02 52 | * updated SdFatLib to sdfatlib20130313 53 | * added const to PROGMEM uint16_t bitrate_table for avr-gcc 4.7.2 compatibility 54 | * added ASCII range check to strip off non-ASCII, such as CR or LF, on FilePlayer.ino 55 | 56 | ## 1.02.01 57 | * added new example FilePlayer.ino, more elaborate command to play all files. 58 | * updated ram usage prints. 59 | * added missing MinimumSerial files from new SdFatLib 60 | 61 | ## 1.02.00 62 | * Roll up of all below changes for release 63 | 64 | ## 1.01.01 65 | * added getState() as to report other possible states, such as paused but playing. 66 | * added check to enableRefill() 67 | * added GetDifferentialOutput() and SetDifferentialOutput() feature to change the output, 68 | as to create a differential left/right output with a maximum output of 3V. 69 | * changed case of get.. and set.. functions all to lower case for consistency. 70 | * added VU meter support 71 | * added chdir("/") to example and fixed enableTestSineWave freq 72 | * Added skip, pauseMusic, resumeMusic and optional time offset to playMP3 along with examples. 73 | * corrected typo's in Differential and initialized. 74 | * updated test for mp3 75 | * added example WebPlayer.ino 76 | * sdfatlib20121219 replaced sdfatlib20120719 77 | 78 | 79 | ## 1.01.00 80 | * changed sdFat to be instanced from INO file using sd.begin() for simpler use. 81 | * added end() feature to put VS10xx into low power mode, along with corresponding checks. 82 | 83 | ## 1.00.02 84 | * Fixed SkipTo() feature and added menu command. 85 | 86 | ## 1.00.01 87 | * added support for Leonardo's interrupt switching and documentation. 88 | * added documentation Gravitech's MP3-4NANO 89 | * added Mono Mode and menu command, because of Nano's single speaker. 90 | * added ADMixerLoad and ADMixerVol features 91 | 92 | ## 1.00.00 93 | * formatted comments with Doxygen markdown. 94 | * rearranged location of functions for organizing documentation 95 | * extracted read of MP3 files bit-rate to member function. 96 | * cleaned up some type casting. 97 | * added history.md and license files 98 | * improved tolerance of bit-rate read from mp3 file header. 99 | * moved setting Playing to true after file is opened and bitrate is read. 100 | 101 | ## 0.09.00 102 | 103 | * Added SFEMP3ShieldConfig.h to support alternate hardware for none INT0 DREQ based 104 | cards and or Shields. By using Timers, or software pollings, such as with Mega and Seediunos. 105 | 106 | ## 0.08.00 107 | 108 | * moved MP3 functions into class and cleaned up syntax 109 | * finished bitrate_table[] table with last row, that was missed. 110 | * added "d" command to print directory of SdCard 111 | * added "+/-" command to change volume by 1.0 dB 112 | * added print of FreeRam() to show amount of static RAM available. 113 | * save 220 bytes by using F() function to put strings into Flash and not use RAM: 114 | * i.e. Serial.Print(F("Hello)"); 115 | * note: FreeRam() is supplied with SdFatUtil.h 116 | 117 | ## 0.07.03 118 | * Added apply patch/plugins from SdCard file to VS1xxx. 119 | 120 | ## 0.07.02 121 | * Added quick check if trackname is mp3 extension. 122 | 123 | ## 0.07.01 124 | * chomp'd non ASCII characters from file names. 125 | 126 | ## 0.07.00 127 | * added functions to read track title,artist,album 128 | * fixed silly use of static where it shouldn't have been 129 | 130 | ## 0.06.00 131 | * fixed for Arduino Mega use by calling SDfatlib properly. 132 | * Blame Nathan for bad implentation of SDFatlib 133 | 134 | ## 0.05.00 135 | * added skipTo() and related functions to skip around in track 136 | 137 | ## 0.04.00 138 | * added functions to cancel and resume external interrupt in case something else is on the SPI bus 139 | 140 | ## 0.03.00 141 | * added isPlaying function to query shield status 142 | 143 | ## 0.02.00 144 | * included pre-modified SDFat Library 145 | 146 | ## 0.01.00 147 | * Initial Release, using external interrupt driven. 148 | 149 | -------------------------------------------------------------------------------- /SdFat/src/FatLib/ostream.cpp: -------------------------------------------------------------------------------- 1 | /* FatLib Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the FatLib Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the FatLib Library. If not, see 18 | * . 19 | */ 20 | #include 21 | #include "ostream.h" 22 | #ifndef PSTR 23 | #define PSTR(x) x 24 | #endif 25 | //------------------------------------------------------------------------------ 26 | void ostream::do_fill(unsigned len) { 27 | for (; len < width(); len++) { 28 | putch(fill()); 29 | } 30 | width(0); 31 | } 32 | //------------------------------------------------------------------------------ 33 | void ostream::fill_not_left(unsigned len) { 34 | if ((flags() & adjustfield) != left) { 35 | do_fill(len); 36 | } 37 | } 38 | //------------------------------------------------------------------------------ 39 | char* ostream::fmtNum(uint32_t n, char *ptr, uint8_t base) { 40 | char a = flags() & uppercase ? 'A' - 10 : 'a' - 10; 41 | do { 42 | uint32_t m = n; 43 | n /= base; 44 | char c = m - base * n; 45 | *--ptr = c < 10 ? c + '0' : c + a; 46 | } while (n); 47 | return ptr; 48 | } 49 | //------------------------------------------------------------------------------ 50 | void ostream::putBool(bool b) { 51 | if (flags() & boolalpha) { 52 | if (b) { 53 | putPgm(PSTR("true")); 54 | } else { 55 | putPgm(PSTR("false")); 56 | } 57 | } else { 58 | putChar(b ? '1' : '0'); 59 | } 60 | } 61 | //------------------------------------------------------------------------------ 62 | void ostream::putChar(char c) { 63 | fill_not_left(1); 64 | putch(c); 65 | do_fill(1); 66 | } 67 | //------------------------------------------------------------------------------ 68 | void ostream::putDouble(double n) { 69 | uint8_t nd = precision(); 70 | double round = 0.5; 71 | char sign; 72 | char buf[13]; // room for sign, 10 digits, '.', and zero byte 73 | char *end = buf + sizeof(buf) - 1; 74 | char *str = end; 75 | // terminate string 76 | *end = '\0'; 77 | 78 | // get sign and make nonnegative 79 | if (n < 0.0) { 80 | sign = '-'; 81 | n = -n; 82 | } else { 83 | sign = flags() & showpos ? '+' : '\0'; 84 | } 85 | // check for larger than uint32_t 86 | if (n > 4.0E9) { 87 | putPgm(PSTR("BIG FLT")); 88 | return; 89 | } 90 | // round up and separate int and fraction parts 91 | for (uint8_t i = 0; i < nd; ++i) { 92 | round *= 0.1; 93 | } 94 | n += round; 95 | uint32_t intPart = n; 96 | double fractionPart = n - intPart; 97 | 98 | // format intPart and decimal point 99 | if (nd || (flags() & showpoint)) { 100 | *--str = '.'; 101 | } 102 | str = fmtNum(intPart, str, 10); 103 | 104 | // calculate length for fill 105 | uint8_t len = sign ? 1 : 0; 106 | len += nd + end - str; 107 | 108 | // extract adjust field 109 | fmtflags adj = flags() & adjustfield; 110 | if (adj == internal) { 111 | if (sign) { 112 | putch(sign); 113 | } 114 | do_fill(len); 115 | } else { 116 | // do fill for internal or right 117 | fill_not_left(len); 118 | if (sign) { 119 | *--str = sign; 120 | } 121 | } 122 | putstr(str); 123 | // output fraction 124 | while (nd-- > 0) { 125 | fractionPart *= 10.0; 126 | int digit = static_cast(fractionPart); 127 | putch(digit + '0'); 128 | fractionPart -= digit; 129 | } 130 | // do fill if not done above 131 | do_fill(len); 132 | } 133 | //------------------------------------------------------------------------------ 134 | void ostream::putNum(int32_t n) { 135 | bool neg = n < 0 && flagsToBase() == 10; 136 | if (neg) { 137 | n = -n; 138 | } 139 | putNum(n, neg); 140 | } 141 | //------------------------------------------------------------------------------ 142 | void ostream::putNum(uint32_t n, bool neg) { 143 | char buf[13]; 144 | char* end = buf + sizeof(buf) - 1; 145 | char* num; 146 | char* str; 147 | uint8_t base = flagsToBase(); 148 | *end = '\0'; 149 | str = num = fmtNum(n, end, base); 150 | if (base == 10) { 151 | if (neg) { 152 | *--str = '-'; 153 | } else if (flags() & showpos) { 154 | *--str = '+'; 155 | } 156 | } else if (flags() & showbase) { 157 | if (flags() & hex) { 158 | *--str = flags() & uppercase ? 'X' : 'x'; 159 | } 160 | *--str = '0'; 161 | } 162 | uint8_t len = end - str; 163 | fmtflags adj = flags() & adjustfield; 164 | if (adj == internal) { 165 | while (str < num) { 166 | putch(*str++); 167 | } 168 | } 169 | if (adj != left) { 170 | do_fill(len); 171 | } 172 | putstr(str); 173 | do_fill(len); 174 | } 175 | //------------------------------------------------------------------------------ 176 | void ostream::putPgm(const char* str) { 177 | int n; 178 | for (n = 0; pgm_read_byte(&str[n]); n++) {} 179 | fill_not_left(n); 180 | for (uint8_t c; (c = pgm_read_byte(str)); str++) { 181 | putch(c); 182 | } 183 | do_fill(n); 184 | } 185 | //------------------------------------------------------------------------------ 186 | void ostream::putStr(const char *str) { 187 | unsigned n = strlen(str); 188 | fill_not_left(n); 189 | putstr(str); 190 | do_fill(n); 191 | } 192 | -------------------------------------------------------------------------------- /SdFat/src/SpiDriver/SoftSPI.h: -------------------------------------------------------------------------------- 1 | /* Arduino DigitalIO Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the Arduino DigitalIO Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino DigitalIO Library. If not, see 18 | * . 19 | */ 20 | /** 21 | * @file 22 | * @brief Software SPI. 23 | * 24 | * @defgroup softSPI Software SPI 25 | * @details Software SPI Template Class. 26 | * @{ 27 | */ 28 | 29 | #ifndef SoftSPI_h 30 | #define SoftSPI_h 31 | #include "DigitalPin.h" 32 | //------------------------------------------------------------------------------ 33 | /** Nop for timing. */ 34 | #define nop asm volatile ("nop\n\t") 35 | //------------------------------------------------------------------------------ 36 | /** Pin Mode for MISO is input.*/ 37 | #define MISO_MODE INPUT 38 | /** Pullups disabled for MISO are disabled. */ 39 | #define MISO_LEVEL false 40 | /** Pin Mode for MOSI is output.*/ 41 | #define MOSI_MODE OUTPUT 42 | /** Pin Mode for SCK is output. */ 43 | #define SCK_MODE OUTPUT 44 | //------------------------------------------------------------------------------ 45 | /** 46 | * @class SoftSPI 47 | * @brief Fast software SPI. 48 | */ 49 | template 50 | class SoftSPI { 51 | public: 52 | //---------------------------------------------------------------------------- 53 | /** Initialize SoftSPI pins. */ 54 | void begin() { 55 | fastPinConfig(MisoPin, MISO_MODE, MISO_LEVEL); 56 | fastPinConfig(MosiPin, MOSI_MODE, !MODE_CPHA(Mode)); 57 | fastPinConfig(SckPin, SCK_MODE, MODE_CPOL(Mode)); 58 | } 59 | //---------------------------------------------------------------------------- 60 | /** Soft SPI receive byte. 61 | * @return Data byte received. 62 | */ 63 | inline __attribute__((always_inline)) 64 | uint8_t receive() { 65 | uint8_t data = 0; 66 | receiveBit(7, &data); 67 | receiveBit(6, &data); 68 | receiveBit(5, &data); 69 | receiveBit(4, &data); 70 | receiveBit(3, &data); 71 | receiveBit(2, &data); 72 | receiveBit(1, &data); 73 | receiveBit(0, &data); 74 | return data; 75 | } 76 | //---------------------------------------------------------------------------- 77 | /** Soft SPI send byte. 78 | * @param[in] data Data byte to send. 79 | */ 80 | inline __attribute__((always_inline)) 81 | void send(uint8_t data) { 82 | sendBit(7, data); 83 | sendBit(6, data); 84 | sendBit(5, data); 85 | sendBit(4, data); 86 | sendBit(3, data); 87 | sendBit(2, data); 88 | sendBit(1, data); 89 | sendBit(0, data); 90 | } 91 | //---------------------------------------------------------------------------- 92 | /** Soft SPI transfer byte. 93 | * @param[in] txData Data byte to send. 94 | * @return Data byte received. 95 | */ 96 | inline __attribute__((always_inline)) 97 | uint8_t transfer(uint8_t txData) { 98 | uint8_t rxData = 0; 99 | transferBit(7, &rxData, txData); 100 | transferBit(6, &rxData, txData); 101 | transferBit(5, &rxData, txData); 102 | transferBit(4, &rxData, txData); 103 | transferBit(3, &rxData, txData); 104 | transferBit(2, &rxData, txData); 105 | transferBit(1, &rxData, txData); 106 | transferBit(0, &rxData, txData); 107 | return rxData; 108 | } 109 | 110 | private: 111 | //---------------------------------------------------------------------------- 112 | inline __attribute__((always_inline)) 113 | bool MODE_CPHA(uint8_t mode) {return (mode & 1) != 0;} 114 | inline __attribute__((always_inline)) 115 | bool MODE_CPOL(uint8_t mode) {return (mode & 2) != 0;} 116 | inline __attribute__((always_inline)) 117 | void receiveBit(uint8_t bit, uint8_t* data) { 118 | if (MODE_CPHA(Mode)) { 119 | fastDigitalWrite(SckPin, !MODE_CPOL(Mode)); 120 | } 121 | nop; 122 | nop; 123 | fastDigitalWrite(SckPin, 124 | MODE_CPHA(Mode) ? MODE_CPOL(Mode) : !MODE_CPOL(Mode)); 125 | if (fastDigitalRead(MisoPin)) *data |= 1 << bit; 126 | if (!MODE_CPHA(Mode)) { 127 | fastDigitalWrite(SckPin, MODE_CPOL(Mode)); 128 | } 129 | } 130 | //---------------------------------------------------------------------------- 131 | inline __attribute__((always_inline)) 132 | void sendBit(uint8_t bit, uint8_t data) { 133 | if (MODE_CPHA(Mode)) { 134 | fastDigitalWrite(SckPin, !MODE_CPOL(Mode)); 135 | } 136 | fastDigitalWrite(MosiPin, data & (1 << bit)); 137 | fastDigitalWrite(SckPin, 138 | MODE_CPHA(Mode) ? MODE_CPOL(Mode) : !MODE_CPOL(Mode)); 139 | nop; 140 | nop; 141 | if (!MODE_CPHA(Mode)) { 142 | fastDigitalWrite(SckPin, MODE_CPOL(Mode)); 143 | } 144 | } 145 | //---------------------------------------------------------------------------- 146 | inline __attribute__((always_inline)) 147 | void transferBit(uint8_t bit, uint8_t* rxData, uint8_t txData) { 148 | if (MODE_CPHA(Mode)) { 149 | fastDigitalWrite(SckPin, !MODE_CPOL(Mode)); 150 | } 151 | fastDigitalWrite(MosiPin, txData & (1 << bit)); 152 | fastDigitalWrite(SckPin, 153 | MODE_CPHA(Mode) ? MODE_CPOL(Mode) : !MODE_CPOL(Mode)); 154 | if (fastDigitalRead(MisoPin)) *rxData |= 1 << bit; 155 | if (!MODE_CPHA(Mode)) { 156 | fastDigitalWrite(SckPin, MODE_CPOL(Mode)); 157 | } 158 | } 159 | //---------------------------------------------------------------------------- 160 | }; 161 | #endif // SoftSPI_h 162 | /** @} */ 163 | -------------------------------------------------------------------------------- /SdFat/src/FatLib/FatFilePrint.cpp: -------------------------------------------------------------------------------- 1 | /* FatLib Library 2 | * Copyright (C) 2012 by William Greiman 3 | * 4 | * This file is part of the FatLib Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the FatLib Library. If not, see 18 | * . 19 | */ 20 | #include 21 | #include "FatFile.h" 22 | #include "FmtNumber.h" 23 | //------------------------------------------------------------------------------ 24 | // print uint8_t with width 2 25 | static void print2u(print_t* pr, uint8_t v) { 26 | char c0 = '?'; 27 | char c1 = '?'; 28 | if (v < 100) { 29 | c1 = v/10; 30 | c0 = v - 10*c1 + '0'; 31 | c1 += '0'; 32 | } 33 | pr->write(c1); 34 | pr->write(c0); 35 | } 36 | //------------------------------------------------------------------------------ 37 | static void printU32(print_t* pr, uint32_t v) { 38 | char buf[11]; 39 | char* ptr = buf + sizeof(buf); 40 | *--ptr = 0; 41 | pr->write(fmtDec(v, ptr)); 42 | } 43 | //------------------------------------------------------------------------------ 44 | static void printHex(print_t* pr, uint8_t w, uint16_t h) { 45 | char buf[5]; 46 | char* ptr = buf + sizeof(buf); 47 | *--ptr = 0; 48 | for (uint8_t i = 0; i < w; i++) { 49 | char c = h & 0XF; 50 | *--ptr = c < 10 ? c + '0' : c + 'A' - 10; 51 | h >>= 4; 52 | } 53 | pr->write(ptr); 54 | } 55 | //------------------------------------------------------------------------------ 56 | void FatFile::dmpFile(print_t* pr, uint32_t pos, size_t n) { 57 | char text[17]; 58 | text[16] = 0; 59 | if (n >= 0XFFF0) { 60 | n = 0XFFF0; 61 | } 62 | if (!seekSet(pos)) { 63 | return; 64 | } 65 | for (size_t i = 0; i <= n; i++) { 66 | if ((i & 15) == 0) { 67 | if (i) { 68 | pr->write(' '); 69 | pr->write(text); 70 | if (i == n) { 71 | break; 72 | } 73 | } 74 | pr->write('\r'); 75 | pr->write('\n'); 76 | if (i >= n) { 77 | break; 78 | } 79 | printHex(pr, 4, i); 80 | pr->write(' '); 81 | } 82 | int16_t h = read(); 83 | if (h < 0) { 84 | break; 85 | } 86 | pr->write(' '); 87 | printHex(pr, 2, h); 88 | text[i&15] = ' ' <= h && h < 0X7F ? h : '.'; 89 | } 90 | pr->write('\r'); 91 | pr->write('\n'); 92 | } 93 | //------------------------------------------------------------------------------ 94 | void FatFile::ls(print_t* pr, uint8_t flags, uint8_t indent) { 95 | FatFile file; 96 | rewind(); 97 | while (file.openNext(this, O_READ)) { 98 | // indent for dir level 99 | if (!file.isHidden() || (flags & LS_A)) { 100 | for (uint8_t i = 0; i < indent; i++) { 101 | pr->write(' '); 102 | } 103 | if (flags & LS_DATE) { 104 | file.printModifyDateTime(pr); 105 | pr->write(' '); 106 | } 107 | if (flags & LS_SIZE) { 108 | file.printFileSize(pr); 109 | pr->write(' '); 110 | } 111 | file.printName(pr); 112 | if (file.isDir()) { 113 | pr->write('/'); 114 | } 115 | pr->write('\r'); 116 | pr->write('\n'); 117 | if ((flags & LS_R) && file.isDir()) { 118 | file.ls(pr, flags, indent + 2); 119 | } 120 | } 121 | file.close(); 122 | } 123 | } 124 | //------------------------------------------------------------------------------ 125 | bool FatFile::printCreateDateTime(print_t* pr) { 126 | dir_t dir; 127 | if (!dirEntry(&dir)) { 128 | DBG_FAIL_MACRO; 129 | goto fail; 130 | } 131 | printFatDate(pr, dir.creationDate); 132 | pr->write(' '); 133 | printFatTime(pr, dir.creationTime); 134 | return true; 135 | 136 | fail: 137 | return false; 138 | } 139 | //------------------------------------------------------------------------------ 140 | void FatFile::printFatDate(print_t* pr, uint16_t fatDate) { 141 | printU32(pr, FAT_YEAR(fatDate)); 142 | pr->write('-'); 143 | print2u(pr, FAT_MONTH(fatDate)); 144 | pr->write('-'); 145 | print2u(pr, FAT_DAY(fatDate)); 146 | } 147 | //------------------------------------------------------------------------------ 148 | void FatFile::printFatTime(print_t* pr, uint16_t fatTime) { 149 | print2u(pr, FAT_HOUR(fatTime)); 150 | pr->write(':'); 151 | print2u(pr, FAT_MINUTE(fatTime)); 152 | pr->write(':'); 153 | print2u(pr, FAT_SECOND(fatTime)); 154 | } 155 | //------------------------------------------------------------------------------ 156 | /** Template for FatFile::printField() */ 157 | template 158 | static int printFieldT(FatFile* file, char sign, Type value, char term) { 159 | char buf[3*sizeof(Type) + 3]; 160 | char* str = &buf[sizeof(buf)]; 161 | 162 | if (term) { 163 | *--str = term; 164 | if (term == '\n') { 165 | *--str = '\r'; 166 | } 167 | } 168 | #ifdef OLD_FMT 169 | do { 170 | Type m = value; 171 | value /= 10; 172 | *--str = '0' + m - 10*value; 173 | } while (value); 174 | #else // OLD_FMT 175 | str = fmtDec(value, str); 176 | #endif // OLD_FMT 177 | if (sign) { 178 | *--str = sign; 179 | } 180 | return file->write(str, &buf[sizeof(buf)] - str); 181 | } 182 | //------------------------------------------------------------------------------ 183 | 184 | int FatFile::printField(float value, char term, uint8_t prec) { 185 | char buf[24]; 186 | char* str = &buf[sizeof(buf)]; 187 | if (term) { 188 | *--str = term; 189 | if (term == '\n') { 190 | *--str = '\r'; 191 | } 192 | } 193 | str = fmtFloat(value, str, prec); 194 | return write(str, buf + sizeof(buf) - str); 195 | } 196 | //------------------------------------------------------------------------------ 197 | int FatFile::printField(uint16_t value, char term) { 198 | return printFieldT(this, 0, value, term); 199 | } 200 | //------------------------------------------------------------------------------ 201 | int FatFile::printField(int16_t value, char term) { 202 | char sign = 0; 203 | if (value < 0) { 204 | sign = '-'; 205 | value = -value; 206 | } 207 | return printFieldT(this, sign, (uint16_t)value, term); 208 | } 209 | //------------------------------------------------------------------------------ 210 | int FatFile::printField(uint32_t value, char term) { 211 | return printFieldT(this, 0, value, term); 212 | } 213 | //------------------------------------------------------------------------------ 214 | int FatFile::printField(int32_t value, char term) { 215 | char sign = 0; 216 | if (value < 0) { 217 | sign = '-'; 218 | value = -value; 219 | } 220 | return printFieldT(this, sign, (uint32_t)value, term); 221 | } 222 | //------------------------------------------------------------------------------ 223 | bool FatFile::printModifyDateTime(print_t* pr) { 224 | dir_t dir; 225 | if (!dirEntry(&dir)) { 226 | DBG_FAIL_MACRO; 227 | goto fail; 228 | } 229 | printFatDate(pr, dir.lastWriteDate); 230 | pr->write(' '); 231 | printFatTime(pr, dir.lastWriteTime); 232 | return true; 233 | 234 | fail: 235 | return false; 236 | } 237 | //------------------------------------------------------------------------------ 238 | size_t FatFile::printFileSize(print_t* pr) { 239 | char buf[11]; 240 | char *ptr = buf + sizeof(buf); 241 | *--ptr = 0; 242 | ptr = fmtDec(fileSize(), ptr); 243 | while (ptr > buf) { 244 | *--ptr = ' '; 245 | } 246 | return pr->write(buf); 247 | } 248 | -------------------------------------------------------------------------------- /SdFat/src/SdFatConfig.h: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2012 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | /** 21 | * \file 22 | * \brief configuration definitions 23 | */ 24 | #ifndef SdFatConfig_h 25 | #define SdFatConfig_h 26 | #include 27 | #ifdef __AVR__ 28 | #include 29 | #endif // __AVR__ 30 | //------------------------------------------------------------------------------ 31 | /** 32 | * Set USE_LONG_FILE_NAMES nonzero to use long file names (LFN). 33 | * Long File Name are limited to a maximum length of 255 characters. 34 | * 35 | * This implementation allows 7-bit characters in the range 36 | * 0X20 to 0X7E except the following characters are not allowed: 37 | * 38 | * < (less than) 39 | * > (greater than) 40 | * : (colon) 41 | * " (double quote) 42 | * / (forward slash) 43 | * \ (backslash) 44 | * | (vertical bar or pipe) 45 | * ? (question mark) 46 | * * (asterisk) 47 | * 48 | */ 49 | #define USE_LONG_FILE_NAMES 1 50 | //------------------------------------------------------------------------------ 51 | /** 52 | * If the symbol ENABLE_EXTENDED_TRANSFER_CLASS is nonzero, the class SdFatEX 53 | * will be defined. If the symbol ENABLE_SOFTWARE_SPI_CLASS is also nonzero, 54 | * the class SdFatSoftSpiEX will be defined. 55 | * 56 | * These classes used extended multi-block SD I/O for better performance. 57 | * the SPI bus may not be shared with other devices in this mode. 58 | */ 59 | #define ENABLE_EXTENDED_TRANSFER_CLASS 0 60 | //----------------------------------------------------------------------------- 61 | /** 62 | * If the symbol USE_STANDARD_SPI_LIBRARY is nonzero, the classes SdFat and 63 | * SdFatEX use the standard Arduino SPI.h library. If USE_STANDARD_SPI_LIBRARY 64 | * is zero, an optimized custom SPI driver is used if it exists. 65 | */ 66 | #define USE_STANDARD_SPI_LIBRARY 0 67 | //----------------------------------------------------------------------------- 68 | /** 69 | * If the symbol ENABLE_SOFTWARE_SPI_CLASS is nonzero, the class SdFatSoftSpi 70 | * will be defined. If ENABLE_EXTENDED_TRANSFER_CLASS is also nonzero, 71 | * the class SdFatSoftSpiEX will be defined. 72 | */ 73 | #define ENABLE_SOFTWARE_SPI_CLASS 0 74 | //------------------------------------------------------------------------------ 75 | /** 76 | * Set MAINTAIN_FREE_CLUSTER_COUNT nonzero to keep the count of free clusters 77 | * updated. This will increase the speed of the freeClusterCount() call 78 | * after the first call. Extra flash will be required. 79 | */ 80 | #define MAINTAIN_FREE_CLUSTER_COUNT 0 81 | //------------------------------------------------------------------------------ 82 | /** 83 | * To enable SD card CRC checking set USE_SD_CRC nonzero. 84 | * 85 | * Set USE_SD_CRC to 1 to use a smaller CRC-CCITT function. This function 86 | * is slower for AVR but may be fast for ARM and other processors. 87 | * 88 | * Set USE_SD_CRC to 2 to used a larger table driven CRC-CCITT function. This 89 | * function is faster for AVR but may be slower for ARM and other processors. 90 | */ 91 | #define USE_SD_CRC 0 92 | //------------------------------------------------------------------------------ 93 | /** 94 | * Handle Watchdog Timer for WiFi modules. 95 | * 96 | * Yield will be called before accessing the SPI bus if it has been more 97 | * than WDT_YIELD_TIME_MICROS microseconds since the last yield call by SdFat. 98 | */ 99 | #if defined(PLATFORM_ID) || defined(ESP8266) 100 | // If Particle device or ESP8266 call yield. 101 | #define WDT_YIELD_TIME_MICROS 100000 102 | #else 103 | #define WDT_YIELD_TIME_MICROS 0 104 | #endif 105 | //------------------------------------------------------------------------------ 106 | /** 107 | * Set FAT12_SUPPORT nonzero to enable use if FAT12 volumes. 108 | * FAT12 has not been well tested and requires additional flash. 109 | */ 110 | #define FAT12_SUPPORT 0 111 | //------------------------------------------------------------------------------ 112 | /** 113 | * Set DESTRUCTOR_CLOSES_FILE nonzero to close a file in its destructor. 114 | * 115 | * Causes use of lots of heap in ARM. 116 | */ 117 | #define DESTRUCTOR_CLOSES_FILE 0 118 | //------------------------------------------------------------------------------ 119 | /** 120 | * Call flush for endl if ENDL_CALLS_FLUSH is nonzero 121 | * 122 | * The standard for iostreams is to call flush. This is very costly for 123 | * SdFat. Each call to flush causes 2048 bytes of I/O to the SD. 124 | * 125 | * SdFat has a single 512 byte buffer for SD I/O so it must write the current 126 | * data block to the SD, read the directory block from the SD, update the 127 | * directory entry, write the directory block to the SD and read the data 128 | * block back into the buffer. 129 | * 130 | * The SD flash memory controller is not designed for this many rewrites 131 | * so performance may be reduced by more than a factor of 100. 132 | * 133 | * If ENDL_CALLS_FLUSH is zero, you must call flush and/or close to force 134 | * all data to be written to the SD. 135 | */ 136 | #define ENDL_CALLS_FLUSH 0 137 | //------------------------------------------------------------------------------ 138 | /** 139 | * Set USE_SEPARATE_FAT_CACHE nonzero to use a second 512 byte cache 140 | * for FAT table entries. This improves performance for large writes 141 | * that are not a multiple of 512 bytes. 142 | */ 143 | #ifdef __arm__ 144 | #define USE_SEPARATE_FAT_CACHE 1 145 | #else // __arm__ 146 | #define USE_SEPARATE_FAT_CACHE 0 147 | #endif // __arm__ 148 | //------------------------------------------------------------------------------ 149 | /** 150 | * Set USE_MULTI_BLOCK_IO nonzero to use multi-block SD read/write. 151 | * 152 | * Don't use mult-block read/write on small AVR boards. 153 | */ 154 | #if defined(RAMEND) && RAMEND < 3000 155 | #define USE_MULTI_BLOCK_IO 0 156 | #else // RAMEND 157 | #define USE_MULTI_BLOCK_IO 1 158 | #endif // RAMEND 159 | //----------------------------------------------------------------------------- 160 | /** Enable SDIO driver if available. */ 161 | #if defined(__MK64FX512__) || defined(__MK66FX1M0__) 162 | #define ENABLE_SDIO_CLASS 1 163 | #define ENABLE_SDIOEX_CLASS 1 164 | #else // ENABLE_SDIO_CLASS 165 | #define ENABLE_SDIO_CLASS 0 166 | #endif // ENABLE_SDIO_CLASS 167 | //------------------------------------------------------------------------------ 168 | /** 169 | * Determine the default SPI configuration. 170 | */ 171 | #if defined(__STM32F1__) 172 | // has multiple SPI ports 173 | #define SD_HAS_CUSTOM_SPI 2 174 | #elif defined(__AVR__)\ 175 | || defined(__SAM3X8E__) || defined(__SAM3X8H__)\ 176 | || (defined(__arm__) && defined(CORE_TEENSY))\ 177 | || defined(ESP8266) 178 | #define SD_HAS_CUSTOM_SPI 1 179 | #else // SD_HAS_CUSTOM_SPI 180 | // Use standard SPI library. 181 | #define SD_HAS_CUSTOM_SPI 0 182 | #endif // SD_HAS_CUSTOM_SPI 183 | //------------------------------------------------------------------------------ 184 | /** 185 | * Check if API to select HW SPI port is needed. 186 | */ 187 | #if (USE_STANDARD_SPI_LIBRARY || SD_HAS_CUSTOM_SPI < 2) 188 | #define IMPLEMENT_SPI_PORT_SELECTION 0 189 | #else // USE_STANDARD_SPI_LIBRARY 190 | #define IMPLEMENT_SPI_PORT_SELECTION 1 191 | #endif // USE_STANDARD_SPI_LIBRARY 192 | #endif // SdFatConfig_h 193 | -------------------------------------------------------------------------------- /SdFat/src/SpiDriver/SdSpiTeensy3.cpp: -------------------------------------------------------------------------------- 1 | /* Arduino SdSpiAltDriver Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the Arduino SdSpiAltDriver Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdSpiAltDriver Library. If not, see 18 | * . 19 | */ 20 | #include "SdSpiDriver.h" 21 | #if defined(__arm__) && defined(CORE_TEENSY) 22 | // SPI definitions 23 | #include "kinetis.h" 24 | 25 | //------------------------------------------------------------------------------ 26 | void SdSpiAltDriver::activate() { 27 | SPI.beginTransaction(m_spiSettings); 28 | } 29 | //------------------------------------------------------------------------------ 30 | void SdSpiAltDriver::begin(uint8_t chipSelectPin) { 31 | m_csPin = chipSelectPin; 32 | pinMode(m_csPin, OUTPUT); 33 | digitalWrite(m_csPin, HIGH); 34 | SPI.begin(); 35 | } 36 | //------------------------------------------------------------------------------ 37 | void SdSpiAltDriver::deactivate() { 38 | SPI.endTransaction(); 39 | } 40 | //============================================================================== 41 | #ifdef KINETISK 42 | 43 | // use 16-bit frame if SPI_USE_8BIT_FRAME is zero 44 | #define SPI_USE_8BIT_FRAME 0 45 | // Limit initial fifo to three entries to avoid fifo overrun 46 | #define SPI_INITIAL_FIFO_DEPTH 3 47 | // define some symbols that are not in mk20dx128.h 48 | #ifndef SPI_SR_RXCTR 49 | #define SPI_SR_RXCTR 0XF0 50 | #endif // SPI_SR_RXCTR 51 | #ifndef SPI_PUSHR_CONT 52 | #define SPI_PUSHR_CONT 0X80000000 53 | #endif // SPI_PUSHR_CONT 54 | #ifndef SPI_PUSHR_CTAS 55 | #define SPI_PUSHR_CTAS(n) (((n) & 7) << 28) 56 | #endif // SPI_PUSHR_CTAS 57 | //------------------------------------------------------------------------------ 58 | /** SPI receive a byte */ 59 | uint8_t SdSpiAltDriver::receive() { 60 | SPI0_MCR |= SPI_MCR_CLR_RXF; 61 | SPI0_SR = SPI_SR_TCF; 62 | SPI0_PUSHR = 0xFF; 63 | while (!(SPI0_SR & SPI_SR_TCF)) {} 64 | return SPI0_POPR; 65 | } 66 | //------------------------------------------------------------------------------ 67 | /** SPI receive multiple bytes */ 68 | uint8_t SdSpiAltDriver::receive(uint8_t* buf, size_t n) { 69 | // clear any data in RX FIFO 70 | SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF | SPI_MCR_PCSIS(0x1F); 71 | #if SPI_USE_8BIT_FRAME 72 | // initial number of bytes to push into TX FIFO 73 | int nf = n < SPI_INITIAL_FIFO_DEPTH ? n : SPI_INITIAL_FIFO_DEPTH; 74 | for (int i = 0; i < nf; i++) { 75 | SPI0_PUSHR = 0XFF; 76 | } 77 | // limit for pushing dummy data into TX FIFO 78 | uint8_t* limit = buf + n - nf; 79 | while (buf < limit) { 80 | while (!(SPI0_SR & SPI_SR_RXCTR)) {} 81 | SPI0_PUSHR = 0XFF; 82 | *buf++ = SPI0_POPR; 83 | } 84 | // limit for rest of RX data 85 | limit += nf; 86 | while (buf < limit) { 87 | while (!(SPI0_SR & SPI_SR_RXCTR)) {} 88 | *buf++ = SPI0_POPR; 89 | } 90 | #else // SPI_USE_8BIT_FRAME 91 | // use 16 bit frame to avoid TD delay between frames 92 | // get one byte if n is odd 93 | if (n & 1) { 94 | *buf++ = receive(); 95 | n--; 96 | } 97 | // initial number of words to push into TX FIFO 98 | int nf = n/2 < SPI_INITIAL_FIFO_DEPTH ? n/2 : SPI_INITIAL_FIFO_DEPTH; 99 | for (int i = 0; i < nf; i++) { 100 | SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | 0XFFFF; 101 | } 102 | uint8_t* limit = buf + n - 2*nf; 103 | while (buf < limit) { 104 | while (!(SPI0_SR & SPI_SR_RXCTR)) {} 105 | SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | 0XFFFF; 106 | uint16_t w = SPI0_POPR; 107 | *buf++ = w >> 8; 108 | *buf++ = w & 0XFF; 109 | } 110 | // limit for rest of RX data 111 | limit += 2*nf; 112 | while (buf < limit) { 113 | while (!(SPI0_SR & SPI_SR_RXCTR)) {} 114 | uint16_t w = SPI0_POPR; 115 | *buf++ = w >> 8; 116 | *buf++ = w & 0XFF; 117 | } 118 | #endif // SPI_USE_8BIT_FRAME 119 | return 0; 120 | } 121 | //------------------------------------------------------------------------------ 122 | /** SPI send a byte */ 123 | void SdSpiAltDriver::send(uint8_t b) { 124 | SPI0_MCR |= SPI_MCR_CLR_RXF; 125 | SPI0_SR = SPI_SR_TCF; 126 | SPI0_PUSHR = b; 127 | while (!(SPI0_SR & SPI_SR_TCF)) {} 128 | } 129 | //------------------------------------------------------------------------------ 130 | /** SPI send multiple bytes */ 131 | void SdSpiAltDriver::send(const uint8_t* buf , size_t n) { 132 | // clear any data in RX FIFO 133 | SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF | SPI_MCR_PCSIS(0x1F); 134 | #if SPI_USE_8BIT_FRAME 135 | // initial number of bytes to push into TX FIFO 136 | int nf = n < SPI_INITIAL_FIFO_DEPTH ? n : SPI_INITIAL_FIFO_DEPTH; 137 | // limit for pushing data into TX fifo 138 | const uint8_t* limit = buf + n; 139 | for (int i = 0; i < nf; i++) { 140 | SPI0_PUSHR = *buf++; 141 | } 142 | // write data to TX FIFO 143 | while (buf < limit) { 144 | while (!(SPI0_SR & SPI_SR_RXCTR)) {} 145 | SPI0_PUSHR = *buf++; 146 | SPI0_POPR; 147 | } 148 | // wait for data to be sent 149 | while (nf) { 150 | while (!(SPI0_SR & SPI_SR_RXCTR)) {} 151 | SPI0_POPR; 152 | nf--; 153 | } 154 | #else // SPI_USE_8BIT_FRAME 155 | // use 16 bit frame to avoid TD delay between frames 156 | // send one byte if n is odd 157 | if (n & 1) { 158 | send(*buf++); 159 | n--; 160 | } 161 | // initial number of words to push into TX FIFO 162 | int nf = n/2 < SPI_INITIAL_FIFO_DEPTH ? n/2 : SPI_INITIAL_FIFO_DEPTH; 163 | // limit for pushing data into TX fifo 164 | const uint8_t* limit = buf + n; 165 | for (int i = 0; i < nf; i++) { 166 | uint16_t w = (*buf++) << 8; 167 | w |= *buf++; 168 | SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | w; 169 | } 170 | // write data to TX FIFO 171 | while (buf < limit) { 172 | uint16_t w = *buf++ << 8; 173 | w |= *buf++; 174 | while (!(SPI0_SR & SPI_SR_RXCTR)) {} 175 | SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | w; 176 | SPI0_POPR; 177 | } 178 | // wait for data to be sent 179 | while (nf) { 180 | while (!(SPI0_SR & SPI_SR_RXCTR)) {} 181 | SPI0_POPR; 182 | nf--; 183 | } 184 | #endif // SPI_USE_8BIT_FRAME 185 | } 186 | #else // KINETISK 187 | //============================================================================== 188 | // Use standard SPI library if not KINETISK 189 | //------------------------------------------------------------------------------ 190 | /** Receive a byte. 191 | * 192 | * \return The byte. 193 | */ 194 | uint8_t SdSpiAltDriver::receive() { 195 | return SPI.transfer(0XFF); 196 | } 197 | /** Receive multiple bytes. 198 | * 199 | * \param[out] buf Buffer to receive the data. 200 | * \param[in] n Number of bytes to receive. 201 | * 202 | * \return Zero for no error or nonzero error code. 203 | */ 204 | uint8_t SdSpiAltDriver::receive(uint8_t* buf, size_t n) { 205 | for (size_t i = 0; i < n; i++) { 206 | buf[i] = SPI.transfer(0XFF); 207 | } 208 | return 0; 209 | } 210 | /** Send a byte. 211 | * 212 | * \param[in] b Byte to send 213 | */ 214 | void SdSpiAltDriver::send(uint8_t b) { 215 | SPI.transfer(b); 216 | } 217 | /** Send multiple bytes. 218 | * 219 | * \param[in] buf Buffer for data to be sent. 220 | * \param[in] n Number of bytes to send. 221 | */ 222 | void SdSpiAltDriver::send(const uint8_t* buf , size_t n) { 223 | for (size_t i = 0; i < n; i++) { 224 | SPI.transfer(buf[i]); 225 | } 226 | } 227 | #endif // KINETISK 228 | #endif // defined(__arm__) && defined(CORE_TEENSY) 229 | -------------------------------------------------------------------------------- /SdFat/src/FatLib/FatFileSFN.cpp: -------------------------------------------------------------------------------- 1 | /* FatLib Library 2 | * Copyright (C) 2012 by William Greiman 3 | * 4 | * This file is part of the FatLib Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the FatLib Library. If not, see 18 | * . 19 | */ 20 | #include "FatFile.h" 21 | #include "FatFileSystem.h" 22 | //------------------------------------------------------------------------------ 23 | bool FatFile::getSFN(char* name) { 24 | dir_t* dir; 25 | if (!isOpen()) { 26 | DBG_FAIL_MACRO; 27 | goto fail; 28 | } 29 | if (isRoot()) { 30 | name[0] = '/'; 31 | name[1] = '\0'; 32 | return true; 33 | } 34 | // cache entry 35 | dir = cacheDirEntry(FatCache::CACHE_FOR_READ); 36 | if (!dir) { 37 | DBG_FAIL_MACRO; 38 | goto fail; 39 | } 40 | // format name 41 | dirName(dir, name); 42 | return true; 43 | 44 | fail: 45 | return false; 46 | } 47 | //------------------------------------------------------------------------------ 48 | size_t FatFile::printSFN(print_t* pr) { 49 | char name[13]; 50 | if (!getSFN(name)) { 51 | DBG_FAIL_MACRO; 52 | goto fail; 53 | } 54 | return pr->write(name); 55 | 56 | fail: 57 | return 0; 58 | } 59 | #if !USE_LONG_FILE_NAMES 60 | //------------------------------------------------------------------------------ 61 | bool FatFile::getName(char* name, size_t size) { 62 | return size < 13 ? 0 : getSFN(name); 63 | } 64 | //------------------------------------------------------------------------------ 65 | // format directory name field from a 8.3 name string 66 | bool FatFile::parsePathName(const char* path, fname_t* fname, 67 | const char** ptr) { 68 | uint8_t uc = 0; 69 | uint8_t lc = 0; 70 | uint8_t bit = FNAME_FLAG_LC_BASE; 71 | // blank fill name and extension 72 | for (uint8_t i = 0; i < 11; i++) { 73 | fname->sfn[i] = ' '; 74 | } 75 | 76 | for (uint8_t i = 0, n = 7;; path++) { 77 | uint8_t c = *path; 78 | if (c == 0 || isDirSeparator(c)) { 79 | // Done. 80 | break; 81 | } 82 | if (c == '.' && n == 7) { 83 | n = 10; // max index for full 8.3 name 84 | i = 8; // place for extension 85 | 86 | // bit for extension. 87 | bit = FNAME_FLAG_LC_EXT; 88 | } else { 89 | if (!legal83Char(c) || i > n) { 90 | DBG_FAIL_MACRO; 91 | goto fail; 92 | } 93 | if ('a' <= c && c <= 'z') { 94 | c += 'A' - 'a'; 95 | lc |= bit; 96 | } else if ('A' <= c && c <= 'Z') { 97 | uc |= bit; 98 | } 99 | fname->sfn[i++] = c; 100 | } 101 | } 102 | // must have a file name, extension is optional 103 | if (fname->sfn[0] == ' ') { 104 | DBG_FAIL_MACRO; 105 | goto fail; 106 | } 107 | // Set base-name and extension bits. 108 | fname->flags = lc & uc ? 0 : lc; 109 | while (isDirSeparator(*path)) { 110 | path++; 111 | } 112 | *ptr = path; 113 | return true; 114 | 115 | fail: 116 | return false; 117 | } 118 | //------------------------------------------------------------------------------ 119 | // open with filename in fname 120 | #define SFN_OPEN_USES_CHKSUM 0 121 | bool FatFile::open(FatFile* dirFile, fname_t* fname, uint8_t oflag) { 122 | bool emptyFound = false; 123 | #if SFN_OPEN_USES_CHKSUM 124 | uint8_t chksum; 125 | #endif 126 | uint8_t lfnOrd = 0; 127 | uint16_t emptyIndex; 128 | uint16_t index = 0; 129 | dir_t* dir; 130 | ldir_t* ldir; 131 | 132 | dirFile->rewind(); 133 | while (1) { 134 | if (!emptyFound) { 135 | emptyIndex = index; 136 | } 137 | dir = dirFile->readDirCache(true); 138 | if (!dir) { 139 | if (dirFile->getError()) { 140 | DBG_FAIL_MACRO; 141 | goto fail; 142 | } 143 | // At EOF if no error. 144 | break; 145 | } 146 | if (dir->name[0] == DIR_NAME_FREE) { 147 | emptyFound = true; 148 | break; 149 | } 150 | if (dir->name[0] == DIR_NAME_DELETED) { 151 | lfnOrd = 0; 152 | emptyFound = true; 153 | } else if (DIR_IS_FILE_OR_SUBDIR(dir)) { 154 | if (!memcmp(fname->sfn, dir->name, 11)) { 155 | // don't open existing file if O_EXCL 156 | if (oflag & O_EXCL) { 157 | DBG_FAIL_MACRO; 158 | goto fail; 159 | } 160 | #if SFN_OPEN_USES_CHKSUM 161 | if (lfnOrd && chksum != lfnChecksum(dir->name)) { 162 | DBG_FAIL_MACRO; 163 | goto fail; 164 | } 165 | #endif // SFN_OPEN_USES_CHKSUM 166 | if (!openCachedEntry(dirFile, index, oflag, lfnOrd)) { 167 | DBG_FAIL_MACRO; 168 | goto fail; 169 | } 170 | return true; 171 | } else { 172 | lfnOrd = 0; 173 | } 174 | } else if (DIR_IS_LONG_NAME(dir)) { 175 | ldir = reinterpret_cast(dir); 176 | if (ldir->ord & LDIR_ORD_LAST_LONG_ENTRY) { 177 | lfnOrd = ldir->ord & 0X1F; 178 | #if SFN_OPEN_USES_CHKSUM 179 | chksum = ldir->chksum; 180 | #endif // SFN_OPEN_USES_CHKSUM 181 | } 182 | } else { 183 | lfnOrd = 0; 184 | } 185 | index++; 186 | } 187 | // don't create unless O_CREAT and O_WRITE 188 | if (!(oflag & O_CREAT) || !(oflag & O_WRITE)) { 189 | DBG_FAIL_MACRO; 190 | goto fail; 191 | } 192 | if (emptyFound) { 193 | index = emptyIndex; 194 | } else { 195 | if (!dirFile->addDirCluster()) { 196 | DBG_FAIL_MACRO; 197 | goto fail; 198 | } 199 | } 200 | if (!dirFile->seekSet(32UL*index)) { 201 | DBG_FAIL_MACRO; 202 | goto fail; 203 | } 204 | dir = dirFile->readDirCache(); 205 | if (!dir) { 206 | DBG_FAIL_MACRO; 207 | goto fail; 208 | } 209 | // initialize as empty file 210 | memset(dir, 0, sizeof(dir_t)); 211 | memcpy(dir->name, fname->sfn, 11); 212 | 213 | // Set base-name and extension lower case bits. 214 | dir->reservedNT = (DIR_NT_LC_BASE | DIR_NT_LC_EXT) & fname->flags; 215 | 216 | // set timestamps 217 | if (m_dateTime) { 218 | // call user date/time function 219 | m_dateTime(&dir->creationDate, &dir->creationTime); 220 | } else { 221 | // use default date/time 222 | dir->creationDate = FAT_DEFAULT_DATE; 223 | dir->creationTime = FAT_DEFAULT_TIME; 224 | } 225 | dir->lastAccessDate = dir->creationDate; 226 | dir->lastWriteDate = dir->creationDate; 227 | dir->lastWriteTime = dir->creationTime; 228 | 229 | // Force write of entry to device. 230 | dirFile->m_vol->cacheDirty(); 231 | 232 | // open entry in cache. 233 | return openCachedEntry(dirFile, index, oflag, 0); 234 | 235 | fail: 236 | return false; 237 | } 238 | //------------------------------------------------------------------------------ 239 | size_t FatFile::printName(print_t* pr) { 240 | return printSFN(pr); 241 | } 242 | //------------------------------------------------------------------------------ 243 | bool FatFile::remove() { 244 | dir_t* dir; 245 | // Can't remove if LFN or not open for write. 246 | if (!isFile() || isLFN() || !(m_flags & O_WRITE)) { 247 | DBG_FAIL_MACRO; 248 | goto fail; 249 | } 250 | // Free any clusters. 251 | if (m_firstCluster && !m_vol->freeChain(m_firstCluster)) { 252 | DBG_FAIL_MACRO; 253 | goto fail; 254 | } 255 | // Cache directory entry. 256 | dir = cacheDirEntry(FatCache::CACHE_FOR_WRITE); 257 | if (!dir) { 258 | DBG_FAIL_MACRO; 259 | goto fail; 260 | } 261 | // Mark entry deleted. 262 | dir->name[0] = DIR_NAME_DELETED; 263 | 264 | // Set this file closed. 265 | m_attr = FILE_ATTR_CLOSED; 266 | 267 | // Write entry to device. 268 | return m_vol->cacheSync(); 269 | 270 | fail: 271 | return false; 272 | } 273 | #endif // !USE_LONG_FILE_NAMES 274 | -------------------------------------------------------------------------------- /SdFat/src/FatLib/ostream.h: -------------------------------------------------------------------------------- 1 | /* FatLib Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the FatLib Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the FatLib Library. If not, see 18 | * . 19 | */ 20 | #ifndef ostream_h 21 | #define ostream_h 22 | /** 23 | * \file 24 | * \brief \ref ostream class 25 | */ 26 | #include "ios.h" 27 | //============================================================================== 28 | /** 29 | * \class ostream 30 | * \brief Output Stream 31 | */ 32 | class ostream : public virtual ios { 33 | public: 34 | ostream() {} 35 | 36 | /** call manipulator 37 | * \param[in] pf function to call 38 | * \return the stream 39 | */ 40 | ostream& operator<< (ostream& (*pf)(ostream& str)) { 41 | return pf(*this); 42 | } 43 | /** call manipulator 44 | * \param[in] pf function to call 45 | * \return the stream 46 | */ 47 | ostream& operator<< (ios_base& (*pf)(ios_base& str)) { 48 | pf(*this); 49 | return *this; 50 | } 51 | /** Output bool 52 | * \param[in] arg value to output 53 | * \return the stream 54 | */ 55 | ostream &operator<< (bool arg) { 56 | putBool(arg); 57 | return *this; 58 | } 59 | /** Output string 60 | * \param[in] arg string to output 61 | * \return the stream 62 | */ 63 | ostream &operator<< (const char *arg) { 64 | putStr(arg); 65 | return *this; 66 | } 67 | /** Output string 68 | * \param[in] arg string to output 69 | * \return the stream 70 | */ 71 | ostream &operator<< (const signed char *arg) { 72 | putStr((const char*)arg); 73 | return *this; 74 | } 75 | /** Output string 76 | * \param[in] arg string to output 77 | * \return the stream 78 | */ 79 | ostream &operator<< (const unsigned char *arg) { 80 | putStr((const char*)arg); 81 | return *this; 82 | } 83 | /** Output character 84 | * \param[in] arg character to output 85 | * \return the stream 86 | */ 87 | ostream &operator<< (char arg) { 88 | putChar(arg); 89 | return *this; 90 | } 91 | /** Output character 92 | * \param[in] arg character to output 93 | * \return the stream 94 | */ 95 | ostream &operator<< (signed char arg) { 96 | putChar(static_cast(arg)); 97 | return *this; 98 | } 99 | /** Output character 100 | * \param[in] arg character to output 101 | * \return the stream 102 | */ 103 | ostream &operator<< (unsigned char arg) { 104 | putChar(static_cast(arg)); 105 | return *this; 106 | } 107 | /** Output double 108 | * \param[in] arg value to output 109 | * \return the stream 110 | */ 111 | ostream &operator<< (double arg) { 112 | putDouble(arg); 113 | return *this; 114 | } 115 | /** Output float 116 | * \param[in] arg value to output 117 | * \return the stream 118 | */ 119 | ostream &operator<< (float arg) { 120 | putDouble(arg); 121 | return *this; 122 | } 123 | /** Output signed short 124 | * \param[in] arg value to output 125 | * \return the stream 126 | */ 127 | ostream &operator<< (short arg) { // NOLINT 128 | putNum((int32_t)arg); 129 | return *this; 130 | } 131 | /** Output unsigned short 132 | * \param[in] arg value to output 133 | * \return the stream 134 | */ 135 | ostream &operator<< (unsigned short arg) { // NOLINT 136 | putNum((uint32_t)arg); 137 | return *this; 138 | } 139 | /** Output signed int 140 | * \param[in] arg value to output 141 | * \return the stream 142 | */ 143 | ostream &operator<< (int arg) { 144 | putNum((int32_t)arg); 145 | return *this; 146 | } 147 | /** Output unsigned int 148 | * \param[in] arg value to output 149 | * \return the stream 150 | */ 151 | ostream &operator<< (unsigned int arg) { 152 | putNum((uint32_t)arg); 153 | return *this; 154 | } 155 | /** Output signed long 156 | * \param[in] arg value to output 157 | * \return the stream 158 | */ 159 | ostream &operator<< (long arg) { // NOLINT 160 | putNum((int32_t)arg); 161 | return *this; 162 | } 163 | /** Output unsigned long 164 | * \param[in] arg value to output 165 | * \return the stream 166 | */ 167 | ostream &operator<< (unsigned long arg) { // NOLINT 168 | putNum((uint32_t)arg); 169 | return *this; 170 | } 171 | /** Output pointer 172 | * \param[in] arg value to output 173 | * \return the stream 174 | */ 175 | ostream& operator<< (const void* arg) { 176 | putNum(reinterpret_cast(arg)); 177 | return *this; 178 | } 179 | #if (defined(ARDUINO) && ENABLE_ARDUINO_FEATURES) || defined(DOXYGEN) 180 | /** Output a string from flash using the Arduino F() macro. 181 | * \param[in] arg pointing to flash string 182 | * \return the stream 183 | */ 184 | ostream &operator<< (const __FlashStringHelper *arg) { 185 | putPgm(reinterpret_cast(arg)); 186 | return *this; 187 | } 188 | #endif // (defined(ARDUINO) && ENABLE_ARDUINO_FEATURES) || defined(DOXYGEN) 189 | /** 190 | * Puts a character in a stream. 191 | * 192 | * The unformatted output function inserts the element \a ch. 193 | * It returns *this. 194 | * 195 | * \param[in] ch The character 196 | * \return A reference to the ostream object. 197 | */ 198 | ostream& put(char ch) { 199 | putch(ch); 200 | return *this; 201 | } 202 | // ostream& write(char *str, streamsize count); 203 | /** 204 | * Flushes the buffer associated with this stream. The flush function 205 | * calls the sync function of the associated file. 206 | * \return A reference to the ostream object. 207 | */ 208 | ostream& flush() { 209 | if (!sync()) { 210 | setstate(badbit); 211 | } 212 | return *this; 213 | } 214 | /** 215 | * \return the stream position 216 | */ 217 | pos_type tellp() { 218 | return tellpos(); 219 | } 220 | /** 221 | * Set the stream position 222 | * \param[in] pos The absolute position in which to move the write pointer. 223 | * \return Is always *this. Failure is indicated by the state of *this. 224 | */ 225 | ostream& seekp(pos_type pos) { 226 | if (!seekpos(pos)) { 227 | setstate(failbit); 228 | } 229 | return *this; 230 | } 231 | /** 232 | * Set the stream position. 233 | * 234 | * \param[in] off An offset to move the write pointer relative to way. 235 | * \a off is a signed 32-bit int so the offset is limited to +- 2GB. 236 | * \param[in] way One of ios::beg, ios::cur, or ios::end. 237 | * \return Is always *this. Failure is indicated by the state of *this. 238 | */ 239 | ostream& seekp(off_type off, seekdir way) { 240 | if (!seekoff(off, way)) { 241 | setstate(failbit); 242 | } 243 | return *this; 244 | } 245 | 246 | protected: 247 | /// @cond SHOW_PROTECTED 248 | /** Put character with binary/text conversion 249 | * \param[in] ch character to write 250 | */ 251 | virtual void putch(char ch) = 0; 252 | virtual void putstr(const char *str) = 0; 253 | virtual bool seekoff(off_type pos, seekdir way) = 0; 254 | virtual bool seekpos(pos_type pos) = 0; 255 | virtual bool sync() = 0; 256 | 257 | virtual pos_type tellpos() = 0; 258 | /// @endcond 259 | private: 260 | void do_fill(unsigned len); 261 | void fill_not_left(unsigned len); 262 | char* fmtNum(uint32_t n, char *ptr, uint8_t base); 263 | void putBool(bool b); 264 | void putChar(char c); 265 | void putDouble(double n); 266 | void putNum(uint32_t n, bool neg = false); 267 | void putNum(int32_t n); 268 | void putPgm(const char* str); 269 | void putStr(const char* str); 270 | }; 271 | #endif // ostream_h 272 | -------------------------------------------------------------------------------- /SdFat/src/SpiDriver/SdSpiSAM3X.cpp: -------------------------------------------------------------------------------- 1 | /* Arduino SdSpiAltDriver Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the Arduino SdSpiAltDriver Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdSpiAltDriver Library. If not, see 18 | * . 19 | */ 20 | #include "SdSpiDriver.h" 21 | #if defined(__SAM3X8E__) || defined(__SAM3X8H__) 22 | /** Use SAM3X DMAC if nonzero */ 23 | #define USE_SAM3X_DMAC 1 24 | /** Use extra Bus Matrix arbitration fix if nonzero */ 25 | #define USE_SAM3X_BUS_MATRIX_FIX 0 26 | /** Time in ms for DMA receive timeout */ 27 | #define SAM3X_DMA_TIMEOUT 100 28 | /** chip select register number */ 29 | #define SPI_CHIP_SEL 3 30 | /** DMAC receive channel */ 31 | #define SPI_DMAC_RX_CH 1 32 | /** DMAC transmit channel */ 33 | #define SPI_DMAC_TX_CH 0 34 | /** DMAC Channel HW Interface Number for SPI TX. */ 35 | #define SPI_TX_IDX 1 36 | /** DMAC Channel HW Interface Number for SPI RX. */ 37 | #define SPI_RX_IDX 2 38 | //------------------------------------------------------------------------------ 39 | /** Disable DMA Controller. */ 40 | static void dmac_disable() { 41 | DMAC->DMAC_EN &= (~DMAC_EN_ENABLE); 42 | } 43 | /** Enable DMA Controller. */ 44 | static void dmac_enable() { 45 | DMAC->DMAC_EN = DMAC_EN_ENABLE; 46 | } 47 | /** Disable DMA Channel. */ 48 | static void dmac_channel_disable(uint32_t ul_num) { 49 | DMAC->DMAC_CHDR = DMAC_CHDR_DIS0 << ul_num; 50 | } 51 | /** Enable DMA Channel. */ 52 | static void dmac_channel_enable(uint32_t ul_num) { 53 | DMAC->DMAC_CHER = DMAC_CHER_ENA0 << ul_num; 54 | } 55 | /** Poll for transfer complete. */ 56 | static bool dmac_channel_transfer_done(uint32_t ul_num) { 57 | return (DMAC->DMAC_CHSR & (DMAC_CHSR_ENA0 << ul_num)) ? false : true; 58 | } 59 | //------------------------------------------------------------------------------ 60 | void SdSpiAltDriver::begin(uint8_t csPin) { 61 | m_csPin = csPin; 62 | pinMode(m_csPin, OUTPUT); 63 | digitalWrite(m_csPin, HIGH); 64 | SPI.begin(); 65 | #if USE_SAM3X_DMAC 66 | pmc_enable_periph_clk(ID_DMAC); 67 | dmac_disable(); 68 | DMAC->DMAC_GCFG = DMAC_GCFG_ARB_CFG_FIXED; 69 | dmac_enable(); 70 | #if USE_SAM3X_BUS_MATRIX_FIX 71 | MATRIX->MATRIX_WPMR = 0x4d415400; 72 | MATRIX->MATRIX_MCFG[1] = 1; 73 | MATRIX->MATRIX_MCFG[2] = 1; 74 | MATRIX->MATRIX_SCFG[0] = 0x01000010; 75 | MATRIX->MATRIX_SCFG[1] = 0x01000010; 76 | MATRIX->MATRIX_SCFG[7] = 0x01000010; 77 | #endif // USE_SAM3X_BUS_MATRIX_FIX 78 | #endif // USE_SAM3X_DMAC 79 | } 80 | //------------------------------------------------------------------------------ 81 | // start RX DMA 82 | static void spiDmaRX(uint8_t* dst, uint16_t count) { 83 | dmac_channel_disable(SPI_DMAC_RX_CH); 84 | DMAC->DMAC_CH_NUM[SPI_DMAC_RX_CH].DMAC_SADDR = (uint32_t)&SPI0->SPI_RDR; 85 | DMAC->DMAC_CH_NUM[SPI_DMAC_RX_CH].DMAC_DADDR = (uint32_t)dst; 86 | DMAC->DMAC_CH_NUM[SPI_DMAC_RX_CH].DMAC_DSCR = 0; 87 | DMAC->DMAC_CH_NUM[SPI_DMAC_RX_CH].DMAC_CTRLA = count | 88 | DMAC_CTRLA_SRC_WIDTH_BYTE | DMAC_CTRLA_DST_WIDTH_BYTE; 89 | DMAC->DMAC_CH_NUM[SPI_DMAC_RX_CH].DMAC_CTRLB = DMAC_CTRLB_SRC_DSCR | 90 | DMAC_CTRLB_DST_DSCR | DMAC_CTRLB_FC_PER2MEM_DMA_FC | 91 | DMAC_CTRLB_SRC_INCR_FIXED | DMAC_CTRLB_DST_INCR_INCREMENTING; 92 | DMAC->DMAC_CH_NUM[SPI_DMAC_RX_CH].DMAC_CFG = DMAC_CFG_SRC_PER(SPI_RX_IDX) | 93 | DMAC_CFG_SRC_H2SEL | DMAC_CFG_SOD | DMAC_CFG_FIFOCFG_ASAP_CFG; 94 | dmac_channel_enable(SPI_DMAC_RX_CH); 95 | } 96 | //------------------------------------------------------------------------------ 97 | // start TX DMA 98 | static void spiDmaTX(const uint8_t* src, uint16_t count) { 99 | static uint8_t ff = 0XFF; 100 | uint32_t src_incr = DMAC_CTRLB_SRC_INCR_INCREMENTING; 101 | if (!src) { 102 | src = &ff; 103 | src_incr = DMAC_CTRLB_SRC_INCR_FIXED; 104 | } 105 | dmac_channel_disable(SPI_DMAC_TX_CH); 106 | DMAC->DMAC_CH_NUM[SPI_DMAC_TX_CH].DMAC_SADDR = (uint32_t)src; 107 | DMAC->DMAC_CH_NUM[SPI_DMAC_TX_CH].DMAC_DADDR = (uint32_t)&SPI0->SPI_TDR; 108 | DMAC->DMAC_CH_NUM[SPI_DMAC_TX_CH].DMAC_DSCR = 0; 109 | DMAC->DMAC_CH_NUM[SPI_DMAC_TX_CH].DMAC_CTRLA = count | 110 | DMAC_CTRLA_SRC_WIDTH_BYTE | DMAC_CTRLA_DST_WIDTH_BYTE; 111 | 112 | DMAC->DMAC_CH_NUM[SPI_DMAC_TX_CH].DMAC_CTRLB = DMAC_CTRLB_SRC_DSCR | 113 | DMAC_CTRLB_DST_DSCR | DMAC_CTRLB_FC_MEM2PER_DMA_FC | 114 | src_incr | DMAC_CTRLB_DST_INCR_FIXED; 115 | 116 | DMAC->DMAC_CH_NUM[SPI_DMAC_TX_CH].DMAC_CFG = DMAC_CFG_DST_PER(SPI_TX_IDX) | 117 | DMAC_CFG_DST_H2SEL | DMAC_CFG_SOD | DMAC_CFG_FIFOCFG_ALAP_CFG; 118 | 119 | dmac_channel_enable(SPI_DMAC_TX_CH); 120 | } 121 | //------------------------------------------------------------------------------ 122 | // initialize SPI controller 123 | void SdSpiAltDriver::activate() { 124 | SPI.beginTransaction(m_spiSettings); 125 | 126 | Spi* pSpi = SPI0; 127 | // Save the divisor 128 | uint32_t scbr = pSpi->SPI_CSR[SPI_CHIP_SEL] & 0XFF00; 129 | // Disable SPI 130 | pSpi->SPI_CR = SPI_CR_SPIDIS; 131 | // reset SPI 132 | pSpi->SPI_CR = SPI_CR_SWRST; 133 | // no mode fault detection, set master mode 134 | pSpi->SPI_MR = SPI_PCS(SPI_CHIP_SEL) | SPI_MR_MODFDIS | SPI_MR_MSTR; 135 | // mode 0, 8-bit, 136 | pSpi->SPI_CSR[SPI_CHIP_SEL] = scbr | SPI_CSR_CSAAT | SPI_CSR_NCPHA; 137 | // enable SPI 138 | pSpi->SPI_CR |= SPI_CR_SPIEN; 139 | } 140 | //------------------------------------------------------------------------------ 141 | void SdSpiAltDriver::deactivate() { 142 | SPI.endTransaction(); 143 | } 144 | //------------------------------------------------------------------------------ 145 | static inline uint8_t spiTransfer(uint8_t b) { 146 | Spi* pSpi = SPI0; 147 | 148 | pSpi->SPI_TDR = b; 149 | while ((pSpi->SPI_SR & SPI_SR_RDRF) == 0) {} 150 | b = pSpi->SPI_RDR; 151 | return b; 152 | } 153 | //------------------------------------------------------------------------------ 154 | /** SPI receive a byte */ 155 | uint8_t SdSpiAltDriver::receive() { 156 | return spiTransfer(0XFF); 157 | } 158 | //------------------------------------------------------------------------------ 159 | /** SPI receive multiple bytes */ 160 | uint8_t SdSpiAltDriver::receive(uint8_t* buf, size_t n) { 161 | Spi* pSpi = SPI0; 162 | int rtn = 0; 163 | #if USE_SAM3X_DMAC 164 | // clear overrun error 165 | uint32_t s = pSpi->SPI_SR; 166 | 167 | spiDmaRX(buf, n); 168 | spiDmaTX(0, n); 169 | 170 | uint32_t m = millis(); 171 | while (!dmac_channel_transfer_done(SPI_DMAC_RX_CH)) { 172 | if ((millis() - m) > SAM3X_DMA_TIMEOUT) { 173 | dmac_channel_disable(SPI_DMAC_RX_CH); 174 | dmac_channel_disable(SPI_DMAC_TX_CH); 175 | rtn = 2; 176 | break; 177 | } 178 | } 179 | if (pSpi->SPI_SR & SPI_SR_OVRES) { 180 | rtn |= 1; 181 | } 182 | #else // USE_SAM3X_DMAC 183 | for (size_t i = 0; i < n; i++) { 184 | pSpi->SPI_TDR = 0XFF; 185 | while ((pSpi->SPI_SR & SPI_SR_RDRF) == 0) {} 186 | buf[i] = pSpi->SPI_RDR; 187 | } 188 | #endif // USE_SAM3X_DMAC 189 | return rtn; 190 | } 191 | //------------------------------------------------------------------------------ 192 | /** SPI send a byte */ 193 | void SdSpiAltDriver::send(uint8_t b) { 194 | spiTransfer(b); 195 | } 196 | //------------------------------------------------------------------------------ 197 | void SdSpiAltDriver::send(const uint8_t* buf , size_t n) { 198 | Spi* pSpi = SPI0; 199 | #if USE_SAM3X_DMAC 200 | spiDmaTX(buf, n); 201 | while (!dmac_channel_transfer_done(SPI_DMAC_TX_CH)) {} 202 | #else // #if USE_SAM3X_DMAC 203 | while ((pSpi->SPI_SR & SPI_SR_TXEMPTY) == 0) {} 204 | for (size_t i = 0; i < n; i++) { 205 | pSpi->SPI_TDR = buf[i]; 206 | while ((pSpi->SPI_SR & SPI_SR_TDRE) == 0) {} 207 | } 208 | #endif // #if USE_SAM3X_DMAC 209 | while ((pSpi->SPI_SR & SPI_SR_TXEMPTY) == 0) {} 210 | // leave RDR empty 211 | uint8_t b = pSpi->SPI_RDR; 212 | } 213 | #endif // defined(__SAM3X8E__) || defined(__SAM3X8H__) 214 | -------------------------------------------------------------------------------- /SdFat/src/FatLib/ArduinoFiles.h: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2012 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | /** 21 | * \file 22 | * \brief PrintFile class 23 | */ 24 | #ifndef ArduinoFiles_h 25 | #define ArduinoFiles_h 26 | #include "FatLibConfig.h" 27 | #if ENABLE_ARDUINO_FEATURES 28 | #include "FatFile.h" 29 | #include 30 | //------------------------------------------------------------------------------ 31 | /** Arduino SD.h style flag for open for read. */ 32 | #define FILE_READ O_READ 33 | /** Arduino SD.h style flag for open at EOF for read/write with create. */ 34 | #define FILE_WRITE (O_RDWR | O_CREAT | O_AT_END) 35 | //============================================================================== 36 | /** 37 | * \class PrintFile 38 | * \brief FatFile with Print. 39 | */ 40 | class PrintFile : public FatFile, public Print { 41 | public: 42 | PrintFile() {} 43 | /** Create a file object and open it in the current working directory. 44 | * 45 | * \param[in] path A path for a file to be opened. 46 | * 47 | * \param[in] oflag Values for \a oflag are constructed by a 48 | * bitwise-inclusive OR of open flags. see 49 | * FatFile::open(FatFile*, const char*, uint8_t). 50 | */ 51 | PrintFile(const char* path, uint8_t oflag) : FatFile(path, oflag) {} 52 | #if DESTRUCTOR_CLOSES_FILE 53 | ~PrintFile() {} 54 | #endif // DESTRUCTOR_CLOSES_FILE 55 | using FatFile::clearWriteError; 56 | using FatFile::getWriteError; 57 | using FatFile::read; 58 | using FatFile::write; 59 | /** \return number of bytes available from the current position to EOF 60 | * or INT_MAX if more than INT_MAX bytes are available. 61 | */ 62 | int available() { 63 | uint32_t n = FatFile::available(); 64 | return n > INT_MAX ? INT_MAX : n; 65 | } 66 | /** Ensure that any bytes written to the file are saved to the SD card. */ 67 | void flush() { 68 | FatFile::sync(); 69 | } 70 | /** Return the next available byte without consuming it. 71 | * 72 | * \return The byte if no error and not at eof else -1; 73 | */ 74 | int peek() { 75 | return FatFile::peek(); 76 | } 77 | /** Read the next byte from a file. 78 | * 79 | * \return For success return the next byte in the file as an int. 80 | * If an error occurs or end of file is reached return -1. 81 | */ 82 | // int read() { 83 | // return FatFile::read(); 84 | // } 85 | /** Write a byte to a file. Required by the Arduino Print class. 86 | * \param[in] b the byte to be written. 87 | * Use getWriteError to check for errors. 88 | * \return 1 for success and 0 for failure. 89 | */ 90 | size_t write(uint8_t b) { 91 | return FatFile::write(b); 92 | } 93 | /** Write data to an open file. Form required by Print. 94 | * 95 | * \note Data is moved to the cache but may not be written to the 96 | * storage device until sync() is called. 97 | * 98 | * \param[in] buf Pointer to the location of the data to be written. 99 | * 100 | * \param[in] size Number of bytes to write. 101 | * 102 | * \return For success write() returns the number of bytes written, always 103 | * \a nbyte. If an error occurs, write() returns -1. Possible errors 104 | * include write() is called before a file has been opened, write is called 105 | * for a read-only file, device is full, a corrupt file system or an 106 | * I/O error. 107 | */ 108 | size_t write(const uint8_t *buf, size_t size) { 109 | return FatFile::write(buf, size); 110 | } 111 | }; 112 | //============================================================================== 113 | /** 114 | * \class File 115 | * \brief Arduino SD.h style File API 116 | */ 117 | class File : public FatFile, public Stream { 118 | public: 119 | File() {} 120 | /** Create a file object and open it in the current working directory. 121 | * 122 | * \param[in] path A path with a valid 8.3 DOS name for a file to be opened. 123 | * 124 | * \param[in] oflag Values for \a oflag are constructed by a 125 | * bitwise-inclusive OR of open flags. see 126 | * FatFile::open(FatFile*, const char*, uint8_t). 127 | */ 128 | File(const char* path, uint8_t oflag) { 129 | open(path, oflag); 130 | } 131 | using FatFile::clearWriteError; 132 | using FatFile::getWriteError; 133 | using FatFile::read; 134 | using FatFile::write; 135 | /** The parenthesis operator. 136 | * 137 | * \return true if a file is open. 138 | */ 139 | operator bool() { 140 | return isOpen(); 141 | } 142 | /** \return number of bytes available from the current position to EOF 143 | * or INT_MAX if more than INT_MAX bytes are available. 144 | */ 145 | int available() { 146 | uint32_t n = FatFile::available(); 147 | return n > INT_MAX ? INT_MAX : n; 148 | } 149 | /** Ensure that any bytes written to the file are saved to the SD card. */ 150 | void flush() { 151 | FatFile::sync(); 152 | } 153 | /** This function reports if the current file is a directory or not. 154 | * \return true if the file is a directory. 155 | */ 156 | bool isDirectory() { 157 | return isDir(); 158 | } 159 | /** No longer implemented due to Long File Names. 160 | * 161 | * Use getName(char* name, size_t size). 162 | * \return a pointer to replacement suggestion. 163 | */ 164 | const char* name() const { 165 | return "use getName()"; 166 | } 167 | /** Return the next available byte without consuming it. 168 | * 169 | * \return The byte if no error and not at eof else -1; 170 | */ 171 | int peek() { 172 | return FatFile::peek(); 173 | } 174 | /** \return the current file position. */ 175 | uint32_t position() { 176 | return curPosition(); 177 | } 178 | /** Opens the next file or folder in a directory. 179 | * 180 | * \param[in] mode open mode flags. 181 | * \return a File object. 182 | */ 183 | File openNextFile(uint8_t mode = O_READ) { 184 | File tmpFile; 185 | tmpFile.openNext(this, mode); 186 | return tmpFile; 187 | } 188 | /** Read the next byte from a file. 189 | * 190 | * \return For success return the next byte in the file as an int. 191 | * If an error occurs or end of file is reached return -1. 192 | */ 193 | int read() { 194 | return FatFile::read(); 195 | } 196 | /** Rewind a file if it is a directory */ 197 | void rewindDirectory() { 198 | if (isDir()) { 199 | rewind(); 200 | } 201 | } 202 | /** 203 | * Seek to a new position in the file, which must be between 204 | * 0 and the size of the file (inclusive). 205 | * 206 | * \param[in] pos the new file position. 207 | * \return true for success else false. 208 | */ 209 | bool seek(uint32_t pos) { 210 | return seekSet(pos); 211 | } 212 | /** \return the file's size. */ 213 | uint32_t size() { 214 | return fileSize(); 215 | } 216 | /** Write a byte to a file. Required by the Arduino Print class. 217 | * \param[in] b the byte to be written. 218 | * Use getWriteError to check for errors. 219 | * \return 1 for success and 0 for failure. 220 | */ 221 | size_t write(uint8_t b) { 222 | return FatFile::write(b); 223 | } 224 | /** Write data to an open file. Form required by Print. 225 | * 226 | * \note Data is moved to the cache but may not be written to the 227 | * storage device until sync() is called. 228 | * 229 | * \param[in] buf Pointer to the location of the data to be written. 230 | * 231 | * \param[in] size Number of bytes to write. 232 | * 233 | * \return For success write() returns the number of bytes written, always 234 | * \a nbyte. If an error occurs, write() returns -1. Possible errors 235 | * include write() is called before a file has been opened, write is called 236 | * for a read-only file, device is full, a corrupt file system or an 237 | * I/O error. 238 | */ 239 | size_t write(const uint8_t *buf, size_t size) { 240 | return FatFile::write(buf, size); 241 | } 242 | }; 243 | #endif // ENABLE_ARDUINO_FEATURES 244 | #endif // ArduinoFiles_h 245 | -------------------------------------------------------------------------------- /SdFat/src/FatLib/fstream.h: -------------------------------------------------------------------------------- 1 | /* FatLib Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the FatLib Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the FatLib Library. If not, see 18 | * . 19 | */ 20 | #ifndef fstream_h 21 | #define fstream_h 22 | /** 23 | * \file 24 | * \brief \ref fstream, \ref ifstream, and \ref ofstream classes 25 | */ 26 | #include "FatFile.h" 27 | #include "iostream.h" 28 | //============================================================================== 29 | /** 30 | * \class FatStreamBase 31 | * \brief Base class for C++ style streams 32 | */ 33 | class FatStreamBase : protected FatFile, virtual public ios { 34 | protected: 35 | /// @cond SHOW_PROTECTED 36 | int16_t getch(); 37 | void putch(char c); 38 | void putstr(const char *str); 39 | void open(const char* path, ios::openmode mode); 40 | /** Internal do not use 41 | * \return mode 42 | */ 43 | ios::openmode getmode() { 44 | return m_mode; 45 | } 46 | /** Internal do not use 47 | * \param[in] mode 48 | */ 49 | void setmode(ios::openmode mode) { 50 | m_mode = mode; 51 | } 52 | bool seekoff(off_type off, seekdir way); 53 | bool seekpos(pos_type pos); 54 | int write(const void* buf, size_t n); 55 | void write(char c); 56 | /// @endcond 57 | private: 58 | ios::openmode m_mode; 59 | }; 60 | //============================================================================== 61 | /** 62 | * \class fstream 63 | * \brief file input/output stream. 64 | */ 65 | class fstream : public iostream, FatStreamBase { 66 | public: 67 | using iostream::peek; 68 | fstream() {} 69 | /** Constructor with open 70 | * 71 | * \param[in] path path to open 72 | * \param[in] mode open mode 73 | */ 74 | explicit fstream(const char* path, openmode mode = in | out) { 75 | open(path, mode); 76 | } 77 | #if DESTRUCTOR_CLOSES_FILE 78 | ~fstream() {} 79 | #endif // DESTRUCTOR_CLOSES_FILE 80 | /** Clear state and writeError 81 | * \param[in] state new state for stream 82 | */ 83 | void clear(iostate state = goodbit) { 84 | ios::clear(state); 85 | FatFile::clearWriteError(); 86 | } 87 | /** Close a file and force cached data and directory information 88 | * to be written to the storage device. 89 | */ 90 | void close() { 91 | FatFile::close(); 92 | } 93 | /** Open a fstream 94 | * \param[in] path file to open 95 | * \param[in] mode open mode 96 | * 97 | * Valid open modes are (at end, ios::ate, and/or ios::binary may be added): 98 | * 99 | * ios::in - Open file for reading. 100 | * 101 | * ios::out or ios::out | ios::trunc - Truncate to 0 length, if existent, 102 | * or create a file for writing only. 103 | * 104 | * ios::app or ios::out | ios::app - Append; open or create file for 105 | * writing at end-of-file. 106 | * 107 | * ios::in | ios::out - Open file for update (reading and writing). 108 | * 109 | * ios::in | ios::out | ios::trunc - Truncate to zero length, if existent, 110 | * or create file for update. 111 | * 112 | * ios::in | ios::app or ios::in | ios::out | ios::app - Append; open or 113 | * create text file for update, writing at end of file. 114 | */ 115 | void open(const char* path, openmode mode = in | out) { 116 | FatStreamBase::open(path, mode); 117 | } 118 | /** \return True if stream is open else false. */ 119 | bool is_open() { 120 | return FatFile::isOpen(); 121 | } 122 | 123 | protected: 124 | /// @cond SHOW_PROTECTED 125 | /** Internal - do not use 126 | * \return 127 | */ 128 | int16_t getch() { 129 | return FatStreamBase::getch(); 130 | } 131 | /** Internal - do not use 132 | * \param[out] pos 133 | */ 134 | void getpos(FatPos_t* pos) { 135 | FatFile::getpos(pos); 136 | } 137 | /** Internal - do not use 138 | * \param[in] c 139 | */ 140 | void putch(char c) { 141 | FatStreamBase::putch(c); 142 | } 143 | /** Internal - do not use 144 | * \param[in] str 145 | */ 146 | void putstr(const char *str) { 147 | FatStreamBase::putstr(str); 148 | } 149 | /** Internal - do not use 150 | * \param[in] pos 151 | */ 152 | bool seekoff(off_type off, seekdir way) { 153 | return FatStreamBase::seekoff(off, way); 154 | } 155 | bool seekpos(pos_type pos) { 156 | return FatStreamBase::seekpos(pos); 157 | } 158 | void setpos(FatPos_t* pos) { 159 | FatFile::setpos(pos); 160 | } 161 | bool sync() { 162 | return FatStreamBase::sync(); 163 | } 164 | pos_type tellpos() { 165 | return FatStreamBase::curPosition(); 166 | } 167 | /// @endcond 168 | }; 169 | //============================================================================== 170 | /** 171 | * \class ifstream 172 | * \brief file input stream. 173 | */ 174 | class ifstream : public istream, FatStreamBase { 175 | public: 176 | using istream::peek; 177 | ifstream() {} 178 | /** Constructor with open 179 | * \param[in] path file to open 180 | * \param[in] mode open mode 181 | */ 182 | explicit ifstream(const char* path, openmode mode = in) { 183 | open(path, mode); 184 | } 185 | #if DESTRUCTOR_CLOSES_FILE 186 | ~ifstream() {} 187 | #endif // DESTRUCTOR_CLOSES_FILE 188 | /** Close a file and force cached data and directory information 189 | * to be written to the storage device. 190 | */ 191 | void close() { 192 | FatFile::close(); 193 | } 194 | /** \return True if stream is open else false. */ 195 | bool is_open() { 196 | return FatFile::isOpen(); 197 | } 198 | /** Open an ifstream 199 | * \param[in] path file to open 200 | * \param[in] mode open mode 201 | * 202 | * \a mode See fstream::open() for valid modes. 203 | */ 204 | void open(const char* path, openmode mode = in) { 205 | FatStreamBase::open(path, mode | in); 206 | } 207 | 208 | protected: 209 | /// @cond SHOW_PROTECTED 210 | /** Internal - do not use 211 | * \return 212 | */ 213 | int16_t getch() { 214 | return FatStreamBase::getch(); 215 | } 216 | /** Internal - do not use 217 | * \param[out] pos 218 | */ 219 | void getpos(FatPos_t* pos) { 220 | FatFile::getpos(pos); 221 | } 222 | /** Internal - do not use 223 | * \param[in] pos 224 | */ 225 | bool seekoff(off_type off, seekdir way) { 226 | return FatStreamBase::seekoff(off, way); 227 | } 228 | bool seekpos(pos_type pos) { 229 | return FatStreamBase::seekpos(pos); 230 | } 231 | void setpos(FatPos_t* pos) { 232 | FatFile::setpos(pos); 233 | } 234 | pos_type tellpos() { 235 | return FatStreamBase::curPosition(); 236 | } 237 | /// @endcond 238 | }; 239 | //============================================================================== 240 | /** 241 | * \class ofstream 242 | * \brief file output stream. 243 | */ 244 | class ofstream : public ostream, FatStreamBase { 245 | public: 246 | ofstream() {} 247 | /** Constructor with open 248 | * \param[in] path file to open 249 | * \param[in] mode open mode 250 | */ 251 | explicit ofstream(const char* path, ios::openmode mode = out) { 252 | open(path, mode); 253 | } 254 | #if DESTRUCTOR_CLOSES_FILE 255 | ~ofstream() {} 256 | #endif // DESTRUCTOR_CLOSES_FILE 257 | /** Clear state and writeError 258 | * \param[in] state new state for stream 259 | */ 260 | void clear(iostate state = goodbit) { 261 | ios::clear(state); 262 | FatFile::clearWriteError(); 263 | } 264 | /** Close a file and force cached data and directory information 265 | * to be written to the storage device. 266 | */ 267 | void close() { 268 | FatFile::close(); 269 | } 270 | /** Open an ofstream 271 | * \param[in] path file to open 272 | * \param[in] mode open mode 273 | * 274 | * \a mode See fstream::open() for valid modes. 275 | */ 276 | void open(const char* path, openmode mode = out) { 277 | FatStreamBase::open(path, mode | out); 278 | } 279 | /** \return True if stream is open else false. */ 280 | bool is_open() { 281 | return FatFile::isOpen(); 282 | } 283 | 284 | protected: 285 | /// @cond SHOW_PROTECTED 286 | /** 287 | * Internal do not use 288 | * \param[in] c 289 | */ 290 | void putch(char c) { 291 | FatStreamBase::putch(c); 292 | } 293 | void putstr(const char* str) { 294 | FatStreamBase::putstr(str); 295 | } 296 | bool seekoff(off_type off, seekdir way) { 297 | return FatStreamBase::seekoff(off, way); 298 | } 299 | bool seekpos(pos_type pos) { 300 | return FatStreamBase::seekpos(pos); 301 | } 302 | /** 303 | * Internal do not use 304 | * \param[in] b 305 | */ 306 | bool sync() { 307 | return FatStreamBase::sync(); 308 | } 309 | pos_type tellpos() { 310 | return FatStreamBase::curPosition(); 311 | } 312 | /// @endcond 313 | }; 314 | //------------------------------------------------------------------------------ 315 | #endif // fstream_h 316 | -------------------------------------------------------------------------------- /SdFat/src/FatLib/istream.cpp: -------------------------------------------------------------------------------- 1 | /* FatLib Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the FatLib Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the FatLib Library. If not, see 18 | * . 19 | */ 20 | // #include 21 | #include 22 | #include 23 | #include "istream.h" 24 | //------------------------------------------------------------------------------ 25 | int istream::get() { 26 | int c; 27 | m_gcount = 0; 28 | c = getch(); 29 | if (c < 0) { 30 | setstate(failbit); 31 | } else { 32 | m_gcount = 1; 33 | } 34 | return c; 35 | } 36 | //------------------------------------------------------------------------------ 37 | istream& istream::get(char& c) { 38 | int tmp = get(); 39 | if (tmp >= 0) { 40 | c = tmp; 41 | } 42 | return *this; 43 | } 44 | //------------------------------------------------------------------------------ 45 | istream& istream::get(char *str, streamsize n, char delim) { 46 | int c; 47 | FatPos_t pos; 48 | m_gcount = 0; 49 | while ((m_gcount + 1) < n) { 50 | c = getch(&pos); 51 | if (c < 0) { 52 | break; 53 | } 54 | if (c == delim) { 55 | setpos(&pos); 56 | break; 57 | } 58 | str[m_gcount++] = c; 59 | } 60 | if (n > 0) { 61 | str[m_gcount] = '\0'; 62 | } 63 | if (m_gcount == 0) { 64 | setstate(failbit); 65 | } 66 | return *this; 67 | } 68 | //------------------------------------------------------------------------------ 69 | void istream::getBool(bool *b) { 70 | if ((flags() & boolalpha) == 0) { 71 | getNumber(b); 72 | return; 73 | } 74 | #ifdef __AVR__ 75 | PGM_P truePtr = PSTR("true"); 76 | PGM_P falsePtr = PSTR("false"); 77 | #else // __AVR__ 78 | const char* truePtr = "true"; 79 | const char* falsePtr = "false"; 80 | #endif // __AVR 81 | const uint8_t true_len = 4; 82 | const uint8_t false_len = 5; 83 | bool trueOk = true; 84 | bool falseOk = true; 85 | uint8_t i = 0; 86 | int c = readSkip(); 87 | while (1) { 88 | #ifdef __AVR__ 89 | falseOk = falseOk && c == pgm_read_byte(falsePtr + i); 90 | trueOk = trueOk && c == pgm_read_byte(truePtr + i); 91 | #else // __AVR__ 92 | falseOk = falseOk && c == falsePtr[i]; 93 | trueOk = trueOk && c == truePtr[i]; 94 | #endif // __AVR__ 95 | if (trueOk == false && falseOk == false) { 96 | break; 97 | } 98 | i++; 99 | if (trueOk && i == true_len) { 100 | *b = true; 101 | return; 102 | } 103 | if (falseOk && i == false_len) { 104 | *b = false; 105 | return; 106 | } 107 | c = getch(); 108 | } 109 | setstate(failbit); 110 | } 111 | //------------------------------------------------------------------------------ 112 | void istream::getChar(char* ch) { 113 | int16_t c = readSkip(); 114 | if (c < 0) { 115 | setstate(failbit); 116 | } else { 117 | *ch = c; 118 | } 119 | } 120 | //------------------------------------------------------------------------------ 121 | // 122 | // http://www.exploringbinary.com/category/numbers-in-computers/ 123 | // 124 | int16_t const EXP_LIMIT = 100; 125 | static const uint32_t uint32_max = (uint32_t)-1; 126 | bool istream::getDouble(double* value) { 127 | bool got_digit = false; 128 | bool got_dot = false; 129 | bool neg; 130 | int16_t c; 131 | bool expNeg = false; 132 | int16_t exp = 0; 133 | int16_t fracExp = 0; 134 | uint32_t frac = 0; 135 | FatPos_t endPos; 136 | double pow10; 137 | double v; 138 | 139 | getpos(&endPos); 140 | c = readSkip(); 141 | neg = c == '-'; 142 | if (c == '-' || c == '+') { 143 | c = getch(); 144 | } 145 | while (1) { 146 | if (isdigit(c)) { 147 | got_digit = true; 148 | if (frac < uint32_max/10) { 149 | frac = frac * 10 + (c - '0'); 150 | if (got_dot) { 151 | fracExp--; 152 | } 153 | } else { 154 | if (!got_dot) { 155 | fracExp++; 156 | } 157 | } 158 | } else if (!got_dot && c == '.') { 159 | got_dot = true; 160 | } else { 161 | break; 162 | } 163 | if (fracExp < -EXP_LIMIT || fracExp > EXP_LIMIT) { 164 | goto fail; 165 | } 166 | c = getch(&endPos); 167 | } 168 | if (!got_digit) { 169 | goto fail; 170 | } 171 | if (c == 'e' || c == 'E') { 172 | c = getch(); 173 | expNeg = c == '-'; 174 | if (c == '-' || c == '+') { 175 | c = getch(); 176 | } 177 | while (isdigit(c)) { 178 | if (exp > EXP_LIMIT) { 179 | goto fail; 180 | } 181 | exp = exp * 10 + (c - '0'); 182 | c = getch(&endPos); 183 | } 184 | } 185 | v = static_cast(frac); 186 | exp = expNeg ? fracExp - exp : fracExp + exp; 187 | expNeg = exp < 0; 188 | if (expNeg) { 189 | exp = -exp; 190 | } 191 | pow10 = 10.0; 192 | while (exp) { 193 | if (exp & 1) { 194 | if (expNeg) { 195 | // check for underflow 196 | if (v < FLT_MIN * pow10 && frac != 0) { 197 | goto fail; 198 | } 199 | v /= pow10; 200 | } else { 201 | // check for overflow 202 | if (v > FLT_MAX / pow10) { 203 | goto fail; 204 | } 205 | v *= pow10; 206 | } 207 | } 208 | pow10 *= pow10; 209 | exp >>= 1; 210 | } 211 | setpos(&endPos); 212 | *value = neg ? -v : v; 213 | return true; 214 | 215 | fail: 216 | // error restore position to last good place 217 | setpos(&endPos); 218 | setstate(failbit); 219 | return false; 220 | } 221 | //------------------------------------------------------------------------------ 222 | 223 | istream& istream::getline(char *str, streamsize n, char delim) { 224 | FatPos_t pos; 225 | int c; 226 | m_gcount = 0; 227 | if (n > 0) { 228 | str[0] = '\0'; 229 | } 230 | while (1) { 231 | c = getch(&pos); 232 | if (c < 0) { 233 | break; 234 | } 235 | if (c == delim) { 236 | m_gcount++; 237 | break; 238 | } 239 | if ((m_gcount + 1) >= n) { 240 | setpos(&pos); 241 | setstate(failbit); 242 | break; 243 | } 244 | str[m_gcount++] = c; 245 | str[m_gcount] = '\0'; 246 | } 247 | if (m_gcount == 0) { 248 | setstate(failbit); 249 | } 250 | return *this; 251 | } 252 | //------------------------------------------------------------------------------ 253 | bool istream::getNumber(uint32_t posMax, uint32_t negMax, uint32_t* num) { 254 | int16_t c; 255 | int8_t any = 0; 256 | int8_t have_zero = 0; 257 | uint8_t neg; 258 | uint32_t val = 0; 259 | uint32_t cutoff; 260 | uint8_t cutlim; 261 | FatPos_t endPos; 262 | uint8_t f = flags() & basefield; 263 | uint8_t base = f == oct ? 8 : f != hex ? 10 : 16; 264 | getpos(&endPos); 265 | c = readSkip(); 266 | 267 | neg = c == '-' ? 1 : 0; 268 | if (c == '-' || c == '+') { 269 | c = getch(); 270 | } 271 | 272 | if (base == 16 && c == '0') { // TESTSUITE 273 | c = getch(&endPos); 274 | if (c == 'X' || c == 'x') { 275 | c = getch(); 276 | // remember zero in case no hex digits follow x/X 277 | have_zero = 1; 278 | } else { 279 | any = 1; 280 | } 281 | } 282 | // set values for overflow test 283 | cutoff = neg ? negMax : posMax; 284 | cutlim = cutoff % base; 285 | cutoff /= base; 286 | 287 | while (1) { 288 | if (isdigit(c)) { 289 | c -= '0'; 290 | } else if (isalpha(c)) { 291 | c -= isupper(c) ? 'A' - 10 : 'a' - 10; 292 | } else { 293 | break; 294 | } 295 | if (c >= base) { 296 | break; 297 | } 298 | if (val > cutoff || (val == cutoff && c > cutlim)) { 299 | // indicate overflow error 300 | any = -1; 301 | break; 302 | } 303 | val = val * base + c; 304 | c = getch(&endPos); 305 | any = 1; 306 | } 307 | setpos(&endPos); 308 | if (any > 0 || (have_zero && any >= 0)) { 309 | *num = neg ? -val : val; 310 | return true; 311 | } 312 | setstate(failbit); 313 | return false; 314 | } 315 | //------------------------------------------------------------------------------ 316 | void istream::getStr(char *str) { 317 | FatPos_t pos; 318 | uint16_t i = 0; 319 | uint16_t m = width() ? width() - 1 : 0XFFFE; 320 | if (m != 0) { 321 | getpos(&pos); 322 | int c = readSkip(); 323 | 324 | while (i < m) { 325 | if (c < 0) { 326 | break; 327 | } 328 | if (isspace(c)) { 329 | setpos(&pos); 330 | break; 331 | } 332 | str[i++] = c; 333 | c = getch(&pos); 334 | } 335 | } 336 | str[i] = '\0'; 337 | if (i == 0) { 338 | setstate(failbit); 339 | } 340 | width(0); 341 | } 342 | //------------------------------------------------------------------------------ 343 | istream& istream::ignore(streamsize n, int delim) { 344 | int c; 345 | m_gcount = 0; 346 | while (m_gcount < n) { 347 | c = getch(); 348 | if (c < 0) { 349 | break; 350 | } 351 | m_gcount++; 352 | if (c == delim) { 353 | break; 354 | } 355 | } 356 | return *this; 357 | } 358 | //------------------------------------------------------------------------------ 359 | int istream::peek() { 360 | int16_t c; 361 | FatPos_t pos; 362 | m_gcount = 0; 363 | getpos(&pos); 364 | c = getch(); 365 | if (c < 0) { 366 | if (!bad()) { 367 | setstate(eofbit); 368 | } 369 | } else { 370 | setpos(&pos); 371 | } 372 | return c; 373 | } 374 | //------------------------------------------------------------------------------ 375 | int16_t istream::readSkip() { 376 | int16_t c; 377 | do { 378 | c = getch(); 379 | } while (isspace(c) && (flags() & skipws)); 380 | return c; 381 | } 382 | //------------------------------------------------------------------------------ 383 | /** used to implement ws() */ 384 | void istream::skipWhite() { 385 | int c; 386 | FatPos_t pos; 387 | do { 388 | c = getch(&pos); 389 | } while (isspace(c)); 390 | setpos(&pos); 391 | } 392 | -------------------------------------------------------------------------------- /SdFat/src/SpiDriver/SdSpiDriver.h: -------------------------------------------------------------------------------- 1 | /* SdFat Library 2 | * Copyright (C) 2016 by William Greiman 3 | * 4 | * This file is part of the FatLib Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the FatLib Library. If not, see 18 | * . 19 | */ 20 | /** 21 | * \file 22 | * \brief SpiDriver classes 23 | */ 24 | #ifndef SdSpiDriver_h 25 | #define SdSpiDriver_h 26 | #include 27 | #include "SPI.h" 28 | #include "SdSpiBaseDriver.h" 29 | #include "SdFatConfig.h" 30 | //----------------------------------------------------------------------------- 31 | /** 32 | * \class SdSpiLibDriver 33 | * \brief SdSpiLibDriver - use standard SPI library. 34 | */ 35 | #if ENABLE_SOFTWARE_SPI_CLASS 36 | class SdSpiLibDriver : public SdSpiBaseDriver { 37 | #else // ENABLE_SOFTWARE_SPI_CLASS 38 | class SdSpiLibDriver { 39 | #endif // ENABLE_SOFTWARE_SPI_CLASS 40 | public: 41 | /** Activate SPI hardware. */ 42 | void activate() { 43 | SPI.beginTransaction(m_spiSettings); 44 | } 45 | /** Deactivate SPI hardware. */ 46 | void deactivate() { 47 | SPI.endTransaction(); 48 | } 49 | /** Initialize the SPI bus. 50 | * 51 | * \param[in] csPin SD card chip select pin. 52 | */ 53 | void begin(uint8_t csPin) { 54 | m_csPin = csPin; 55 | digitalWrite(csPin, HIGH); 56 | pinMode(csPin, OUTPUT); 57 | SPI.begin(); 58 | } 59 | /** Receive a byte. 60 | * 61 | * \return The byte. 62 | */ 63 | uint8_t receive() { 64 | return SPI.transfer( 0XFF); 65 | } 66 | /** Receive multiple bytes. 67 | * 68 | * \param[out] buf Buffer to receive the data. 69 | * \param[in] n Number of bytes to receive. 70 | * 71 | * \return Zero for no error or nonzero error code. 72 | */ 73 | uint8_t receive(uint8_t* buf, size_t n) { 74 | for (size_t i = 0; i < n; i++) { 75 | buf[i] = SPI.transfer(0XFF); 76 | } 77 | return 0; 78 | } 79 | /** Send a byte. 80 | * 81 | * \param[in] data Byte to send 82 | */ 83 | void send(uint8_t data) { 84 | SPI.transfer(data); 85 | } 86 | /** Send multiple bytes. 87 | * 88 | * \param[in] buf Buffer for data to be sent. 89 | * \param[in] n Number of bytes to send. 90 | */ 91 | void send(const uint8_t* buf, size_t n) { 92 | for (size_t i = 0; i < n; i++) { 93 | SPI.transfer(buf[i]); 94 | } 95 | } 96 | /** Set CS low. */ 97 | void select() { 98 | digitalWrite(m_csPin, LOW); 99 | } 100 | /** Save SPISettings. 101 | * 102 | * \param[in] spiSettings SPI speed, mode, and byte order. 103 | */ 104 | void setSpiSettings(SPISettings spiSettings) { 105 | m_spiSettings = spiSettings; 106 | } 107 | /** Set CS high. */ 108 | void unselect() { 109 | digitalWrite(m_csPin, HIGH); 110 | } 111 | 112 | private: 113 | SPISettings m_spiSettings; 114 | uint8_t m_csPin; 115 | }; 116 | //----------------------------------------------------------------------------- 117 | /** 118 | * \class SdSpiAltDriver 119 | * \brief Optimized SPI class for access to SD and SDHC flash memory cards. 120 | */ 121 | #if ENABLE_SOFTWARE_SPI_CLASS 122 | class SdSpiAltDriver : public SdSpiBaseDriver { 123 | #else // ENABLE_SOFTWARE_SPI_CLASS 124 | class SdSpiAltDriver { 125 | #endif // ENABLE_SOFTWARE_SPI_CLASS 126 | public: 127 | /** Activate SPI hardware. */ 128 | void activate(); 129 | /** Deactivate SPI hardware. */ 130 | void deactivate(); 131 | /** Initialize the SPI bus. 132 | * 133 | * \param[in] csPin SD card chip select pin. 134 | */ 135 | void begin(uint8_t csPin); 136 | /** Receive a byte. 137 | * 138 | * \return The byte. 139 | */ 140 | uint8_t receive(); 141 | /** Receive multiple bytes. 142 | * 143 | * \param[out] buf Buffer to receive the data. 144 | * \param[in] n Number of bytes to receive. 145 | * 146 | * \return Zero for no error or nonzero error code. 147 | */ 148 | uint8_t receive(uint8_t* buf, size_t n); 149 | /** Send a byte. 150 | * 151 | * \param[in] data Byte to send 152 | */ 153 | void send(uint8_t data); 154 | /** Send multiple bytes. 155 | * 156 | * \param[in] buf Buffer for data to be sent. 157 | * \param[in] n Number of bytes to send. 158 | */ 159 | void send(const uint8_t* buf, size_t n); 160 | /** Set CS low. */ 161 | void select() { 162 | digitalWrite(m_csPin, LOW); 163 | } 164 | /** Save SPISettings. 165 | * 166 | * \param[in] spiSettings SPI speed, mode, and byte order. 167 | */ 168 | void setSpiSettings(SPISettings spiSettings) { 169 | m_spiSettings = spiSettings; 170 | } 171 | /** Set CS high. */ 172 | void unselect() { 173 | digitalWrite(m_csPin, HIGH); 174 | } 175 | #if IMPLEMENT_SPI_PORT_SELECTION || defined(DOXYGEN) 176 | /** Set SPI port number. 177 | * \param[in] portNumber Hardware SPI port number. 178 | */ 179 | void setPort(uint8_t portNumber); 180 | 181 | private: 182 | uint8_t m_spiPort; 183 | #else // IMPLEMENT_SPI_PORT_SELECTION 184 | private: 185 | #endif // IMPLEMENT_SPI_PORT_SELECTION 186 | SPISettings m_spiSettings; 187 | uint8_t m_csPin; 188 | }; 189 | //------------------------------------------------------------------------------ 190 | #if ENABLE_SOFTWARE_SPI_CLASS || defined(DOXYGEN) 191 | #ifdef ARDUINO 192 | #include "SoftSPI.h" 193 | #elif defined(PLATFORM_ID) // Only defined if a Particle device 194 | #include "SoftSPIParticle.h" 195 | #endif // ARDUINO 196 | /** 197 | * \class SdSpiSoftDriver 198 | * \brief Software SPI class for access to SD and SDHC flash memory cards. 199 | */ 200 | template 201 | class SdSpiSoftDriver : public SdSpiBaseDriver { 202 | public: 203 | /** Dummy activate SPI hardware for software SPI */ 204 | void activate() {} 205 | /** Dummy deactivate SPI hardware for software SPI */ 206 | void deactivate() {} 207 | /** Initialize the SPI bus. 208 | * 209 | * \param[in] csPin SD card chip select pin. 210 | */ 211 | void begin(uint8_t csPin) { 212 | m_csPin = csPin; 213 | pinMode(m_csPin, OUTPUT); 214 | digitalWrite(m_csPin, HIGH); 215 | m_spi.begin(); 216 | } 217 | /** Receive a byte. 218 | * 219 | * \return The byte. 220 | */ 221 | uint8_t receive() { 222 | return m_spi.receive(); 223 | } 224 | /** Receive multiple bytes. 225 | * 226 | * \param[out] buf Buffer to receive the data. 227 | * \param[in] n Number of bytes to receive. 228 | * 229 | * \return Zero for no error or nonzero error code. 230 | */ 231 | uint8_t receive(uint8_t* buf, size_t n) { 232 | for (size_t i = 0; i < n; i++) { 233 | buf[i] = receive(); 234 | } 235 | return 0; 236 | } 237 | /** Send a byte. 238 | * 239 | * \param[in] data Byte to send 240 | */ 241 | void send(uint8_t data) { 242 | m_spi.send(data); 243 | } 244 | /** Send multiple bytes. 245 | * 246 | * \param[in] buf Buffer for data to be sent. 247 | * \param[in] n Number of bytes to send. 248 | */ 249 | void send(const uint8_t* buf , size_t n) { 250 | for (size_t i = 0; i < n; i++) { 251 | send(buf[i]); 252 | } 253 | } 254 | /** Set CS low. */ 255 | void select() { 256 | digitalWrite(m_csPin, LOW); 257 | } 258 | /** Save SPISettings. 259 | * 260 | * \param[in] spiSettings SPI speed, mode, and byte order. 261 | */ 262 | void setSpiSettings(SPISettings spiSettings) { 263 | (void)spiSettings; 264 | } 265 | /** Set CS high. */ 266 | void unselect() { 267 | digitalWrite(m_csPin, HIGH); 268 | } 269 | 270 | private: 271 | uint8_t m_csPin; 272 | SoftSPI m_spi; 273 | }; 274 | #endif // ENABLE_SOFTWARE_SPI_CLASS || defined(DOXYGEN) 275 | //----------------------------------------------------------------------------- 276 | // Choose SPI driver for SdFat and SdFatEX classes. 277 | #if USE_STANDARD_SPI_LIBRARY || !SD_HAS_CUSTOM_SPI 278 | /** SdFat uses Arduino library SPI. */ 279 | typedef SdSpiLibDriver SdFatSpiDriver; 280 | #else // USE_STANDARD_SPI_LIBRARY || !SD_HAS_CUSTOM_SPI 281 | /** SdFat uses custom fast SPI. */ 282 | typedef SdSpiAltDriver SdFatSpiDriver; 283 | #endif // USE_STANDARD_SPI_LIBRARY || !SD_HAS_CUSTOM_SPI 284 | 285 | /** typedef for for SdSpiCard class. */ 286 | #if ENABLE_SOFTWARE_SPI_CLASS 287 | // Need virtual driver. 288 | typedef SdSpiBaseDriver SdSpiDriver; 289 | #else // ENABLE_SOFTWARE_SPI_CLASS 290 | // Don't need virtual driver. 291 | typedef SdFatSpiDriver SdSpiDriver; 292 | #endif // ENABLE_SOFTWARE_SPI_CLASS 293 | //============================================================================= 294 | // Use of in-line for AVR to save flash. 295 | #ifdef __AVR__ 296 | //------------------------------------------------------------------------------ 297 | inline void SdSpiAltDriver::begin(uint8_t csPin) { 298 | m_csPin = csPin; 299 | pinMode(m_csPin, OUTPUT); 300 | digitalWrite(m_csPin, HIGH); 301 | SPI.begin(); 302 | } 303 | //------------------------------------------------------------------------------ 304 | inline void SdSpiAltDriver::activate() { 305 | SPI.beginTransaction(m_spiSettings); 306 | } 307 | //------------------------------------------------------------------------------ 308 | inline void SdSpiAltDriver::deactivate() { 309 | SPI.endTransaction(); 310 | } 311 | //------------------------------------------------------------------------------ 312 | inline uint8_t SdSpiAltDriver::receive() { 313 | SPDR = 0XFF; 314 | while (!(SPSR & (1 << SPIF))) {} 315 | return SPDR; 316 | } 317 | //------------------------------------------------------------------------------ 318 | inline uint8_t SdSpiAltDriver::receive(uint8_t* buf, size_t n) { 319 | if (n-- == 0) { 320 | return 0; 321 | } 322 | SPDR = 0XFF; 323 | for (size_t i = 0; i < n; i++) { 324 | while (!(SPSR & (1 << SPIF))) {} 325 | uint8_t b = SPDR; 326 | SPDR = 0XFF; 327 | buf[i] = b; 328 | } 329 | while (!(SPSR & (1 << SPIF))) {} 330 | buf[n] = SPDR; 331 | return 0; 332 | } 333 | //------------------------------------------------------------------------------ 334 | inline void SdSpiAltDriver::send(uint8_t data) { 335 | SPDR = data; 336 | while (!(SPSR & (1 << SPIF))) {} 337 | } 338 | //------------------------------------------------------------------------------ 339 | inline void SdSpiAltDriver::send(const uint8_t* buf , size_t n) { 340 | if (n == 0) { 341 | return; 342 | } 343 | SPDR = buf[0]; 344 | if (n > 1) { 345 | uint8_t b = buf[1]; 346 | size_t i = 2; 347 | while (1) { 348 | while (!(SPSR & (1 << SPIF))) {} 349 | SPDR = b; 350 | if (i == n) { 351 | break; 352 | } 353 | b = buf[i++]; 354 | } 355 | } 356 | while (!(SPSR & (1 << SPIF))) {} 357 | } 358 | #endif // __AVR__ 359 | #endif // SdSpiDriver_h 360 | -------------------------------------------------------------------------------- /SdFat/src/FatLib/FatFileSystem.h: -------------------------------------------------------------------------------- 1 | /* FatLib Library 2 | * Copyright (C) 2013 by William Greiman 3 | * 4 | * This file is part of the FatLib Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the FatLib Library. If not, see 18 | * . 19 | */ 20 | #ifndef FatFileSystem_h 21 | #define FatFileSystem_h 22 | #include "FatVolume.h" 23 | #include "FatFile.h" 24 | #include "ArduinoStream.h" 25 | #include "ArduinoFiles.h" 26 | /** 27 | * \file 28 | * \brief FatFileSystem class 29 | */ 30 | //------------------------------------------------------------------------------ 31 | /** 32 | * \class FatFileSystem 33 | * \brief Integration class for the FatLib library. 34 | */ 35 | class FatFileSystem : public FatVolume { 36 | public: 37 | /** 38 | * Initialize an FatFileSystem object. 39 | * \param[in] blockDev Device block driver. 40 | * \param[in] part partition to initialize. 41 | * \return The value true is returned for success and 42 | * the value false is returned for failure. 43 | */ 44 | bool begin(BlockDriver* blockDev, uint8_t part = 0) { 45 | m_blockDev = blockDev; 46 | vwd()->close(); 47 | return (part ? init(part) : init(1) || init(0)) 48 | && vwd()->openRoot(this) && FatFile::setCwd(vwd()); 49 | } 50 | #if ENABLE_ARDUINO_FEATURES 51 | /** List the directory contents of the volume working directory to Serial. 52 | * 53 | * \param[in] flags The inclusive OR of 54 | * 55 | * LS_DATE - %Print file modification date 56 | * 57 | * LS_SIZE - %Print file size. 58 | * 59 | * LS_R - Recursive list of subdirectories. 60 | */ 61 | void ls(uint8_t flags = 0) { 62 | ls(&Serial, flags); 63 | } 64 | /** List the directory contents of a directory to Serial. 65 | * 66 | * \param[in] path directory to list. 67 | * 68 | * \param[in] flags The inclusive OR of 69 | * 70 | * LS_DATE - %Print file modification date 71 | * 72 | * LS_SIZE - %Print file size. 73 | * 74 | * LS_R - Recursive list of subdirectories. 75 | */ 76 | void ls(const char* path, uint8_t flags = 0) { 77 | ls(&Serial, path, flags); 78 | } 79 | /** open a file 80 | * 81 | * \param[in] path location of file to be opened. 82 | * \param[in] mode open mode flags. 83 | * \return a File object. 84 | */ 85 | File open(const char *path, uint8_t mode = FILE_READ) { 86 | File tmpFile; 87 | tmpFile.open(vwd(), path, mode); 88 | return tmpFile; 89 | } 90 | /** open a file 91 | * 92 | * \param[in] path location of file to be opened. 93 | * \param[in] mode open mode flags. 94 | * \return a File object. 95 | */ 96 | File open(const String &path, uint8_t mode = FILE_READ) { 97 | return open(path.c_str(), mode ); 98 | } 99 | #endif // ENABLE_ARDUINO_FEATURES 100 | /** Change a volume's working directory to root 101 | * 102 | * Changes the volume's working directory to the SD's root directory. 103 | * Optionally set the current working directory to the volume's 104 | * working directory. 105 | * 106 | * \param[in] set_cwd Set the current working directory to this volume's 107 | * working directory if true. 108 | * 109 | * \return The value true is returned for success and 110 | * the value false is returned for failure. 111 | */ 112 | bool chdir(bool set_cwd = false) { 113 | vwd()->close(); 114 | return vwd()->openRoot(this) && (set_cwd ? FatFile::setCwd(vwd()) : true); 115 | } 116 | /** Change a volume's working directory 117 | * 118 | * Changes the volume working directory to the \a path subdirectory. 119 | * Optionally set the current working directory to the volume's 120 | * working directory. 121 | * 122 | * Example: If the volume's working directory is "/DIR", chdir("SUB") 123 | * will change the volume's working directory from "/DIR" to "/DIR/SUB". 124 | * 125 | * If path is "/", the volume's working directory will be changed to the 126 | * root directory 127 | * 128 | * \param[in] path The name of the subdirectory. 129 | * 130 | * \param[in] set_cwd Set the current working directory to this volume's 131 | * working directory if true. 132 | * 133 | * \return The value true is returned for success and 134 | * the value false is returned for failure. 135 | */ 136 | //---------------------------------------------------------------------------- 137 | bool chdir(const char *path, bool set_cwd = false) { 138 | FatFile dir; 139 | if (path[0] == '/' && path[1] == '\0') { 140 | return chdir(set_cwd); 141 | } 142 | if (!dir.open(vwd(), path, O_READ)) { 143 | goto fail; 144 | } 145 | if (!dir.isDir()) { 146 | goto fail; 147 | } 148 | m_vwd = dir; 149 | if (set_cwd) { 150 | FatFile::setCwd(vwd()); 151 | } 152 | return true; 153 | 154 | fail: 155 | return false; 156 | } 157 | //---------------------------------------------------------------------------- 158 | /** Set the current working directory to a volume's working directory. 159 | * 160 | * This is useful with multiple SD cards. 161 | * 162 | * The current working directory is changed to this 163 | * volume's working directory. 164 | * 165 | * This is like the Windows/DOS \: command. 166 | */ 167 | void chvol() { 168 | FatFile::setCwd(vwd()); 169 | } 170 | //---------------------------------------------------------------------------- 171 | /** 172 | * Test for the existence of a file. 173 | * 174 | * \param[in] path Path of the file to be tested for. 175 | * 176 | * \return true if the file exists else false. 177 | */ 178 | bool exists(const char* path) { 179 | return vwd()->exists(path); 180 | } 181 | //---------------------------------------------------------------------------- 182 | /** List the directory contents of the volume working directory. 183 | * 184 | * \param[in] pr Print stream for list. 185 | * 186 | * \param[in] flags The inclusive OR of 187 | * 188 | * LS_DATE - %Print file modification date 189 | * 190 | * LS_SIZE - %Print file size. 191 | * 192 | * LS_R - Recursive list of subdirectories. 193 | */ 194 | void ls(print_t* pr, uint8_t flags = 0) { 195 | vwd()->ls(pr, flags); 196 | } 197 | //---------------------------------------------------------------------------- 198 | /** List the directory contents of a directory. 199 | * 200 | * \param[in] pr Print stream for list. 201 | * 202 | * \param[in] path directory to list. 203 | * 204 | * \param[in] flags The inclusive OR of 205 | * 206 | * LS_DATE - %Print file modification date 207 | * 208 | * LS_SIZE - %Print file size. 209 | * 210 | * LS_R - Recursive list of subdirectories. 211 | */ 212 | void ls(print_t* pr, const char* path, uint8_t flags) { 213 | FatFile dir; 214 | dir.open(vwd(), path, O_READ); 215 | dir.ls(pr, flags); 216 | } 217 | //---------------------------------------------------------------------------- 218 | /** Make a subdirectory in the volume working directory. 219 | * 220 | * \param[in] path A path with a valid 8.3 DOS name for the subdirectory. 221 | * 222 | * \param[in] pFlag Create missing parent directories if true. 223 | * 224 | * \return The value true is returned for success and 225 | * the value false is returned for failure. 226 | */ 227 | bool mkdir(const char* path, bool pFlag = true) { 228 | FatFile sub; 229 | return sub.mkdir(vwd(), path, pFlag); 230 | } 231 | //---------------------------------------------------------------------------- 232 | /** Remove a file from the volume working directory. 233 | * 234 | * \param[in] path A path with a valid 8.3 DOS name for the file. 235 | * 236 | * \return The value true is returned for success and 237 | * the value false is returned for failure. 238 | */ 239 | bool remove(const char* path) { 240 | return FatFile::remove(vwd(), path); 241 | } 242 | //---------------------------------------------------------------------------- 243 | /** Rename a file or subdirectory. 244 | * 245 | * \param[in] oldPath Path name to the file or subdirectory to be renamed. 246 | * 247 | * \param[in] newPath New path name of the file or subdirectory. 248 | * 249 | * The \a newPath object must not exist before the rename call. 250 | * 251 | * The file to be renamed must not be open. The directory entry may be 252 | * moved and file system corruption could occur if the file is accessed by 253 | * a file object that was opened before the rename() call. 254 | * 255 | * \return The value true is returned for success and 256 | * the value false is returned for failure. 257 | */ 258 | bool rename(const char *oldPath, const char *newPath) { 259 | FatFile file; 260 | if (!file.open(vwd(), oldPath, O_READ)) { 261 | return false; 262 | } 263 | return file.rename(vwd(), newPath); 264 | } 265 | //---------------------------------------------------------------------------- 266 | /** Remove a subdirectory from the volume's working directory. 267 | * 268 | * \param[in] path A path with a valid 8.3 DOS name for the subdirectory. 269 | * 270 | * The subdirectory file will be removed only if it is empty. 271 | * 272 | * \return The value true is returned for success and 273 | * the value false is returned for failure. 274 | */ 275 | bool rmdir(const char* path) { 276 | FatFile sub; 277 | if (!sub.open(vwd(), path, O_READ)) { 278 | return false; 279 | } 280 | return sub.rmdir(); 281 | } 282 | //---------------------------------------------------------------------------- 283 | /** Truncate a file to a specified length. The current file position 284 | * will be maintained if it is less than or equal to \a length otherwise 285 | * it will be set to end of file. 286 | * 287 | * \param[in] path A path with a valid 8.3 DOS name for the file. 288 | * \param[in] length The desired length for the file. 289 | * 290 | * \return The value true is returned for success and 291 | * the value false is returned for failure. 292 | */ 293 | bool truncate(const char* path, uint32_t length) { 294 | FatFile file; 295 | if (!file.open(vwd(), path, O_WRITE)) { 296 | return false; 297 | } 298 | return file.truncate(length); 299 | } 300 | /** \return a pointer to the FatVolume object. */ 301 | FatVolume* vol() { 302 | return this; 303 | } 304 | /** \return a pointer to the volume working directory. */ 305 | FatFile* vwd() { 306 | return &m_vwd; 307 | } 308 | /** Wipe all data from the volume. You must reinitialize the volume before 309 | * accessing it again. 310 | * \param[in] pr print stream for status dots. 311 | * \return true for success else false. 312 | */ 313 | bool wipe(print_t* pr = 0) { 314 | vwd()->close(); 315 | return FatVolume::wipe(pr); 316 | } 317 | 318 | private: 319 | FatFile m_vwd; 320 | }; 321 | #endif // FatFileSystem_h 322 | -------------------------------------------------------------------------------- /SdFat/src/SdCard/SdioCard.h: -------------------------------------------------------------------------------- 1 | /* Arduino SdCard Library 2 | * Copyright (C) 2016 by William Greiman 3 | * 4 | * This file is part of the Arduino SdSpiCard Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdSpiCard Library. If not, see 18 | * . 19 | */ 20 | #ifndef SdioCard_h 21 | #define SdioCard_h 22 | #include "SysCall.h" 23 | #include "BlockDriver.h" 24 | /** 25 | * \class SdioCard 26 | * \brief Raw SDIO access to SD and SDHC flash memory cards. 27 | */ 28 | class SdioCard : public BaseBlockDriver { 29 | public: 30 | /** Initialize the SD card. 31 | * \return true for success else false. 32 | */ 33 | bool begin(); 34 | /** 35 | * Determine the size of an SD flash memory card. 36 | * 37 | * \return The number of 512 byte data blocks in the card 38 | * or zero if an error occurs. 39 | */ 40 | uint32_t cardSize(); 41 | /** Erase a range of blocks. 42 | * 43 | * \param[in] firstBlock The address of the first block in the range. 44 | * \param[in] lastBlock The address of the last block in the range. 45 | * 46 | * \note This function requests the SD card to do a flash erase for a 47 | * range of blocks. The data on the card after an erase operation is 48 | * either 0 or 1, depends on the card vendor. The card must support 49 | * single block erase. 50 | * 51 | * \return The value true is returned for success and 52 | * the value false is returned for failure. 53 | */ 54 | bool erase(uint32_t firstBlock, uint32_t lastBlock); 55 | /** 56 | * \return code for the last error. See SdInfo.h for a list of error codes. 57 | */ 58 | uint8_t errorCode(); 59 | /** \return error data for last error. */ 60 | uint32_t errorData(); 61 | /** \return error line for last error. Tmp function for debug. */ 62 | uint32_t errorLine(); 63 | /** 64 | * Check for busy with CMD13. 65 | * 66 | * \return true if busy else false. 67 | */ 68 | bool isBusy(); 69 | /** \return the SD clock frequency in kHz. */ 70 | uint32_t kHzSdClk(); 71 | /** 72 | * Read a 512 byte block from an SD card. 73 | * 74 | * \param[in] lba Logical block to be read. 75 | * \param[out] dst Pointer to the location that will receive the data. 76 | * \return The value true is returned for success and 77 | * the value false is returned for failure. 78 | */ 79 | bool readBlock(uint32_t lba, uint8_t* dst); 80 | /** 81 | * Read multiple 512 byte blocks from an SD card. 82 | * 83 | * \param[in] lba Logical block to be read. 84 | * \param[in] nb Number of blocks to be read. 85 | * \param[out] dst Pointer to the location that will receive the data. 86 | * \return The value true is returned for success and 87 | * the value false is returned for failure. 88 | */ 89 | bool readBlocks(uint32_t lba, uint8_t* dst, size_t nb); 90 | /** 91 | * Read a card's CID register. The CID contains card identification 92 | * information such as Manufacturer ID, Product name, Product serial 93 | * number and Manufacturing date. 94 | * 95 | * \param[out] cid pointer to area for returned data. 96 | * 97 | * \return true for success or false for failure. 98 | */ 99 | bool readCID(void* cid); 100 | /** 101 | * Read a card's CSD register. The CSD contains Card-Specific Data that 102 | * provides information regarding access to the card's contents. 103 | * 104 | * \param[out] csd pointer to area for returned data. 105 | * 106 | * \return true for success or false for failure. 107 | */ 108 | bool readCSD(void* csd); 109 | /** Read one data block in a multiple block read sequence 110 | * 111 | * \param[out] dst Pointer to the location for the data to be read. 112 | * 113 | * \return The value true is returned for success and 114 | * the value false is returned for failure. 115 | */ 116 | bool readData(uint8_t *dst); 117 | /** Read OCR register. 118 | * 119 | * \param[out] ocr Value of OCR register. 120 | * \return true for success else false. 121 | */ 122 | bool readOCR(uint32_t* ocr); 123 | /** Start a read multiple blocks sequence. 124 | * 125 | * \param[in] lba Address of first block in sequence. 126 | * 127 | * \note This function is used with readData() and readStop() for optimized 128 | * multiple block reads. SPI chipSelect must be low for the entire sequence. 129 | * 130 | * \return The value true is returned for success and 131 | * the value false is returned for failure. 132 | */ 133 | bool readStart(uint32_t lba); 134 | /** Start a read multiple blocks sequence. 135 | * 136 | * \param[in] lba Address of first block in sequence. 137 | * \param[in] count Maximum block count. 138 | * \note This function is used with readData() and readStop() for optimized 139 | * multiple block reads. SPI chipSelect must be low for the entire sequence. 140 | * 141 | * \return The value true is returned for success and 142 | * the value false is returned for failure. 143 | */ 144 | bool readStart(uint32_t lba, uint32_t count); 145 | /** End a read multiple blocks sequence. 146 | * 147 | * \return The value true is returned for success and 148 | * the value false is returned for failure. 149 | */ 150 | bool readStop(); 151 | /** \return success if sync successful. Not for user apps. */ 152 | bool syncBlocks(); 153 | /** Return the card type: SD V1, SD V2 or SDHC 154 | * \return 0 - SD V1, 1 - SD V2, or 3 - SDHC. 155 | */ 156 | uint8_t type(); 157 | /** 158 | * Writes a 512 byte block to an SD card. 159 | * 160 | * \param[in] lba Logical block to be written. 161 | * \param[in] src Pointer to the location of the data to be written. 162 | * \return The value true is returned for success and 163 | * the value false is returned for failure. 164 | */ 165 | bool writeBlock(uint32_t lba, const uint8_t* src); 166 | /** 167 | * Write multiple 512 byte blocks to an SD card. 168 | * 169 | * \param[in] lba Logical block to be written. 170 | * \param[in] nb Number of blocks to be written. 171 | * \param[in] src Pointer to the location of the data to be written. 172 | * \return The value true is returned for success and 173 | * the value false is returned for failure. 174 | */ 175 | bool writeBlocks(uint32_t lba, const uint8_t* src, size_t nb); 176 | /** Write one data block in a multiple block write sequence. 177 | * \param[in] src Pointer to the location of the data to be written. 178 | * \return The value true is returned for success and 179 | * the value false is returned for failure. 180 | */ 181 | bool writeData(const uint8_t* src); 182 | /** Start a write multiple blocks sequence. 183 | * 184 | * \param[in] lba Address of first block in sequence. 185 | * 186 | * \note This function is used with writeData() and writeStop() 187 | * for optimized multiple block writes. 188 | * 189 | * \return The value true is returned for success and 190 | * the value false is returned for failure. 191 | */ 192 | bool writeStart(uint32_t lba); 193 | /** Start a write multiple blocks sequence. 194 | * 195 | * \param[in] lba Address of first block in sequence. 196 | * \param[in] count Maximum block count. 197 | * \note This function is used with writeData() and writeStop() 198 | * for optimized multiple block writes. 199 | * 200 | * \return The value true is returned for success and 201 | * the value false is returned for failure. 202 | */ 203 | bool writeStart(uint32_t lba, uint32_t count); 204 | 205 | /** End a write multiple blocks sequence. 206 | * 207 | * \return The value true is returned for success and 208 | * the value false is returned for failure. 209 | */ 210 | bool writeStop(); 211 | }; 212 | //============================================================================== 213 | /** 214 | * \class SdioCardEX 215 | * \brief Extended SD I/O block driver. 216 | */ 217 | class SdioCardEX : public SdioCard { 218 | public: 219 | /** Initialize the SD card 220 | * 221 | * \return The value true is returned for success and 222 | * the value false is returned for failure. 223 | */ 224 | bool begin() { 225 | m_curState = IDLE_STATE; 226 | return SdioCard::begin(); 227 | } 228 | /** Erase a range of blocks. 229 | * 230 | * \param[in] firstBlock The address of the first block in the range. 231 | * \param[in] lastBlock The address of the last block in the range. 232 | * 233 | * \note This function requests the SD card to do a flash erase for a 234 | * range of blocks. The data on the card after an erase operation is 235 | * either 0 or 1, depends on the card vendor. The card must support 236 | * single block erase. 237 | * 238 | * \return The value true is returned for success and 239 | * the value false is returned for failure. 240 | */ 241 | bool erase(uint32_t firstBlock, uint32_t lastBlock) { 242 | return syncBlocks() && SdioCard::erase(firstBlock, lastBlock); 243 | } 244 | /** 245 | * Read a 512 byte block from an SD card. 246 | * 247 | * \param[in] block Logical block to be read. 248 | * \param[out] dst Pointer to the location that will receive the data. 249 | * \return The value true is returned for success and 250 | * the value false is returned for failure. 251 | */ 252 | bool readBlock(uint32_t block, uint8_t* dst); 253 | /** End multi-block transfer and go to idle state. 254 | * \return The value true is returned for success and 255 | * the value false is returned for failure. 256 | */ 257 | bool syncBlocks(); 258 | /** 259 | * Writes a 512 byte block to an SD card. 260 | * 261 | * \param[in] block Logical block to be written. 262 | * \param[in] src Pointer to the location of the data to be written. 263 | * \return The value true is returned for success and 264 | * the value false is returned for failure. 265 | */ 266 | bool writeBlock(uint32_t block, const uint8_t* src); 267 | /** 268 | * Read multiple 512 byte blocks from an SD card. 269 | * 270 | * \param[in] block Logical block to be read. 271 | * \param[in] nb Number of blocks to be read. 272 | * \param[out] dst Pointer to the location that will receive the data. 273 | * \return The value true is returned for success and 274 | * the value false is returned for failure. 275 | */ 276 | bool readBlocks(uint32_t block, uint8_t* dst, size_t nb); 277 | /** 278 | * Write multiple 512 byte blocks to an SD card. 279 | * 280 | * \param[in] block Logical block to be written. 281 | * \param[in] nb Number of blocks to be written. 282 | * \param[in] src Pointer to the location of the data to be written. 283 | * \return The value true is returned for success and 284 | * the value false is returned for failure. 285 | */ 286 | bool writeBlocks(uint32_t block, const uint8_t* src, size_t nb); 287 | 288 | private: 289 | static const uint32_t IDLE_STATE = 0; 290 | static const uint32_t READ_STATE = 1; 291 | static const uint32_t WRITE_STATE = 2; 292 | uint32_t m_curLba; 293 | uint32_t m_limitLba; 294 | uint8_t m_curState; 295 | }; 296 | #endif // SdioCard_h 297 | --------------------------------------------------------------------------------