FastLED 3.10.6
Loading...
Searching...
No Matches
fs_sdcard_arduino.cpp.hpp
Go to the documentation of this file.
1// Arduino SD-card implementation. This file contains external Arduino library
2// headers and definitions, so it must only be included by the SD implementation
3// translation unit rather than exposed through FastLED's header graph.
4
7#include "platforms/is_platform.h"
8
9// <SPI.h> is probed alongside the others because this block includes it
10// unconditionally below. ESP8266 satisfied the SD.h/fs.h half of this guard --
11// its core ships an unrelated <fs.h> for the flash filesystem -- while SPI was
12// not on the include path, so the platform failed to build at all with
13// "fatal error: SPI.h: No such file or directory". Every header this block
14// needs has to be in the condition that admits it.
15#if !defined(FL_IS_TEENSY) && FL_HAS_INCLUDE(<SD.h>) && FL_HAS_INCLUDE(<fs.h>) && \
16 FL_HAS_INCLUDE(<SPI.h>)
17
18// IWYU pragma: begin_keep
19#include <SPI.h>
20// IWYU pragma: end_keep
21#ifdef USE_SDFAT
22// IWYU pragma: begin_keep
23#include <SdFat.h>
24// IWYU pragma: end_keep
25#else
26// IWYU pragma: begin_keep
27#include <SD.h>
28// IWYU pragma: end_keep
29#endif
30
31
32#include "fl/stl/memory.h"
33#include "fl/fs/fs.h"
34#include "fl/stl/type_traits.h"
35#include "fl/stl/noexcept.h"
36
37namespace fl {
38
39// Forward declare the smart pointer type for FsArduino
40class FsArduino;
41FASTLED_SHARED_PTR(FsArduino);
42
43#ifdef USE_SDFAT
44class SdFatFileHandle : public filebuf {
45private:
46 SdFile _file;
47 string _path;
48
49public:
50 SdFatFileHandle(SdFile file, const char* path) : _file(fl::move(file)), _path(path) {}
51 ~SdFatFileHandle() FL_NO_EXCEPT override {
52 if (_file.isOpen()) {
53 _file.close();
54 }
55 }
56
57 bool is_open() const FL_NO_EXCEPT override {
58 return _file.isOpen();
59 }
60 bool available() const FL_NO_EXCEPT override {
61 auto f = const_cast<SdFatFileHandle*>(this);
62 return f->_file.available() > 0;
63 }
64 fl::size_t size() const FL_NO_EXCEPT override {
65 return _file.fileSize();
66 }
67 fl::size_t read(char *dst, fl::size_t bytesToRead) FL_NO_EXCEPT override {
68 return _file.read(reinterpret_cast<u8*>(dst), bytesToRead); // ok reinterpret cast
69 }
70 using filebuf::read;
71 fl::size_t write(const char *data, fl::size_t count) FL_NO_EXCEPT override {
72 (void)data; (void)count;
73 return 0;
74 }
75 fl::size_t tell() FL_NO_EXCEPT override {
76 return _file.curPosition();
77 }
78 const char* path() const FL_NO_EXCEPT override {
79 return _path.c_str();
80 }
81 bool seek(fl::size_t pos, fl::seek_dir dir) FL_NO_EXCEPT override {
82 if (dir == fl::seek_dir::beg) return _file.seekSet(pos);
83 if (dir == fl::seek_dir::cur) return _file.seekCur(pos);
84 return _file.seekEnd(pos);
85 }
86 using filebuf::seek;
87 void close() FL_NO_EXCEPT override {
88 if (_file.isOpen()) {
89 _file.close();
90 }
91 }
92 bool is_eof() const FL_NO_EXCEPT override {
93 auto f = const_cast<SdFatFileHandle*>(this);
94 return f->_file.available() <= 0;
95 }
96 bool has_error() const override { return false; }
97 void clear_error() override {}
98 int error_code() const override { return 0; }
99 const char* error_message() const override { return "No error"; }
100};
101#else
102class SDFileHandle : public filebuf {
103private:
104 File _file;
105 string _path;
106
107public:
108 SDFileHandle(File file, const char* path) : _file(file), _path(path) {}
109 ~SDFileHandle() FL_NO_EXCEPT override {
110 if (_file) {
111 _file.close();
112 }
113 }
114
115 bool is_open() const FL_NO_EXCEPT override {
116 auto f = const_cast<File&>(_file);
117 return f;
118 }
119 bool available() const FL_NO_EXCEPT override {
120 auto f = const_cast<File&>(_file);
121 return f.available() > 0;
122 }
123 fl::size_t size() const FL_NO_EXCEPT override {
124 auto f = const_cast<File&>(_file);
125 return f.size();
126 }
127 fl::size_t read(char *dst, fl::size_t bytesToRead) FL_NO_EXCEPT override {
128 return _file.read(reinterpret_cast<u8*>(dst), bytesToRead); // ok reinterpret cast
129 }
130 using filebuf::read;
131 fl::size_t write(const char *data, fl::size_t count) FL_NO_EXCEPT override {
132 (void)data; (void)count;
133 return 0;
134 }
135 fl::size_t tell() FL_NO_EXCEPT override {
136 auto f = const_cast<File&>(_file);
137 return f.position();
138 }
139 const char* path() const FL_NO_EXCEPT override {
140 return _path.c_str();
141 }
142 bool seek(fl::size_t pos, fl::seek_dir dir) FL_NO_EXCEPT override {
143 if (dir == fl::seek_dir::beg) return _file.seek(pos);
144 // Arduino SD doesn't support cur/end natively
145 if (dir == fl::seek_dir::cur) {
146 auto f = const_cast<File&>(_file);
147 return _file.seek(f.position() + pos);
148 }
149 auto f = const_cast<File&>(_file);
150 return _file.seek(f.size() + pos);
151 }
152 using filebuf::seek;
153 void close() FL_NO_EXCEPT override {
154 if (_file) {
155 _file.close();
156 }
157 }
158 bool is_eof() const FL_NO_EXCEPT override {
159 auto f = const_cast<File&>(_file);
160 return f.available() <= 0;
161 }
162 bool has_error() const override { return false; }
163 void clear_error() override {}
164 int error_code() const override { return 0; }
165 const char* error_message() const override { return "No error"; }
166};
167#endif
168
169class FsArduino : public FsImpl {
170private:
171 int _cs_pin;
172#ifdef USE_SDFAT
173 SdFat _sd;
174#endif
175
176public:
177 FsArduino(int cs_pin) : _cs_pin(cs_pin) {}
178
179 bool begin() FL_NO_EXCEPT override {
180#ifdef USE_SDFAT
181 // Use the CS pin provided in constructor
182 return _sd.begin(_cs_pin, SPI_HALF_SPEED);
183#else
184 return SD.begin(_cs_pin);
185#endif
186 }
187
188 void end() FL_NO_EXCEPT override {
189 // SD library doesn't have an end() method, but we can ensure files are closed
190 // Note: This is a limitation of the Arduino SD library
191 }
192
193 filebuf_ptr openRead(const char *name) FL_NO_EXCEPT override {
194#ifdef USE_SDFAT
195 SdFile file;
196 // Open file for reading
197 if (!file.open(name, O_READ)) {
198 return filebuf_ptr();
199 }
200 return fl::make_shared<SdFatFileHandle>(fl::move(file), name);
201#else
202 File file = SD.open(name, FILE_READ);
203 if (!file) {
204 return filebuf_ptr();
205 }
206 return fl::make_shared<SDFileHandle>(fl::move(file), name);
207#endif
208 }
209
210};
211
212// Implementation of the factory function to create SD card filesystem
213inline FsImplPtr make_sdcard_filesystem(int cs_pin) FL_NO_EXCEPT {
214 return fl::make_shared<FsArduino>(cs_pin);
215}
216
217} // namespace fl
218
219#define FASTLED_HAS_SDCARD_ARDUINO_IMPL 1
220
221#endif // !defined(FL_IS_TEENSY) && FL_HAS_INCLUDE(<SD.h>) && FL_HAS_INCLUDE(<fs.h>)
uint8_t pos
Definition Blur.ino:11
A mounted storage medium.
Definition backend.h:29
unsigned char u8
Definition stdint.h:131
int available()
constexpr remove_reference< T >::type && move(T &&t) FL_NO_EXCEPT
Definition move.h:28
seek_dir
Definition file_handle.h:20
int read()
shared_ptr< T > make_shared(Args &&... args) FL_NO_EXCEPT
Definition shared_ptr.h:414
fl::size_t size_t
Definition s16x16x4.h:62
fl::shared_ptr< filebuf > filebuf_ptr
Definition idecoder.h:15
InputGamut g FL_NO_EXCEPT
Definition rgbw.h:121
constexpr T * end(T(&array)[N]) FL_NO_EXCEPT
FsImplPtr make_sdcard_filesystem(int cs_pin)
constexpr T * begin(T(&array)[N]) FL_NO_EXCEPT
Base definition for an LED controller.
Definition crgb.hpp:179
#define FL_NO_EXCEPT
#define FASTLED_SHARED_PTR(type)
Definition shared_ptr.h:565