ESP3D  3.0
Firmware for ESP boards connected to 3D Printer
sd_native_esp32.cpp
Go to the documentation of this file.
1 /*
2 sd_native_esp32.cpp - ESP3D sd support class
3 
4  Copyright (c) 2014 Luc Lebosse. All rights reserved.
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Lesser General Public
8  License as published by the Free Software Foundation; either
9  version 2.1 of the License, or (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 GNU
14  Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public
17  License along with this library; if not, write to the Free Software
18  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20 #include "../../../include/esp3d_config.h"
21 #if defined (ARDUINO_ARCH_ESP32) && defined(SD_DEVICE)
22 #if (SD_DEVICE == ESP_SD_NATIVE)
23 #include "../esp_sd.h"
24 #include "../../../core/genLinkedList.h"
25 #include "../../../core/settings_esp3d.h"
26 #include "FS.h"
27 #include "SD.h"
28 
29 //base frequency
30 //or use (1000000 * ESP.getCpuFreqMHz()) TBC
31 #define ESP_SPI_FREQ 4000000
32 
34 
35 uint8_t ESP_SD::getState(bool refresh)
36 {
37 #if defined(ESP_SD_DETECT_PIN) && ESP_SD_DETECT_PIN != -1
38  //no need to go further if SD detect is not correct
39  if (!((digitalRead (ESP_SD_DETECT_PIN) == ESP_SD_DETECT_VALUE) ? true : false)) {
40  _state = ESP_SDCARD_NOT_PRESENT;
41  return _state;
42  }
43 #endif //ESP_SD_DETECT_PIN
44  //if busy doing something return state
45  if (!((_state == ESP_SDCARD_NOT_PRESENT) || _state == ESP_SDCARD_IDLE)) {
46  return _state;
47  }
48  if (!refresh) {
49  return _state; //to avoid refresh=true + busy to reset SD and waste time
50  }
51 //SD is idle or not detected, let see if still the case
52 
53  SD.end();
54  _state = ESP_SDCARD_NOT_PRESENT;
55 //using default value for speed ? should be parameter
56 //refresh content if card was removed
57  if (SD.begin((ESP_SD_CS_PIN == -1)?SS:ESP_SD_CS_PIN, SPI, ESP_SPI_FREQ / _spi_speed_divider)) {
58  if ( SD.cardSize() > 0 ) {
59  _state = ESP_SDCARD_IDLE;
60  }
61  }
62  return _state;
63 }
64 
65 bool ESP_SD::begin()
66 {
67 #if (ESP_SD_CS_PIN != -1) || (ESP_SD_MISO_PIN != -1) || (ESP_SD_MOSI_PIN != -1) || (ESP_SD_SCK_PIN != -1)
69 #endif
70  _started = true;
71  _state = ESP_SDCARD_NOT_PRESENT;
72  _spi_speed_divider = Settings_ESP3D::read_byte(ESP_SD_SPEED_DIV);
73  //sanity check
74  if (_spi_speed_divider <= 0) {
75  _spi_speed_divider = 1;
76  }
77  return _started;
78 }
79 
80 void ESP_SD::end()
81 {
82  SD.end();
83  _state = ESP_SDCARD_NOT_PRESENT;
84  _started = false;
85 }
86 
87 uint64_t ESP_SD::totalBytes()
88 {
89  return SD.totalBytes();
90 }
91 
92 uint64_t ESP_SD::usedBytes()
93 {
94  return SD.usedBytes();
95 }
96 
97 uint64_t ESP_SD::freeBytes()
98 {
99  return (SD.totalBytes() - SD.usedBytes());
100 }
101 
102 bool ESP_SD::rename(const char *oldpath, const char *newpath)
103 {
104  return SD.rename(oldpath,newpath);
105 }
106 
107 bool ESP_SD::format(ESP3DOutput * output)
108 {
109  //not available yet
110  if (output) {
111  output->printERROR ("Not implemented!");
112  }
113  return false;
114 }
115 
116 ESP_SDFile ESP_SD::open(const char* path, uint8_t mode)
117 {
118  //do some check
119  if(((strcmp(path,"/") == 0) && ((mode == ESP_FILE_WRITE) || (mode == ESP_FILE_APPEND))) || (strlen(path) == 0)) {
120  return ESP_SDFile();
121  }
122  // path must start by '/'
123  if (path[0] != '/') {
124  return ESP_SDFile();
125  }
126  if (mode != ESP_FILE_READ) {
127  //check container exists
128  String p = path;
129  p.remove(p.lastIndexOf('/') +1);
130  if (!exists(p.c_str())) {
131  log_esp3d("Error opening: %s", path);
132  return ESP_SDFile();
133  }
134  }
135  File tmp = SD.open(path, (mode == ESP_FILE_READ)?FILE_READ:(mode == ESP_FILE_WRITE)?FILE_WRITE:FILE_APPEND);
136  ESP_SDFile esptmp(&tmp, tmp.isDirectory(),(mode == ESP_FILE_READ)?false:true, path);
137  return esptmp;
138 }
139 
140 bool ESP_SD::exists(const char* path)
141 {
142  bool res = false;
143  //root should always be there if started
144  if (strcmp(path, "/") == 0) {
145  return _started;
146  }
147  res = SD.exists(path);
148  if (!res) {
149  ESP_SDFile root = ESP_SD::open(path, ESP_FILE_READ);
150  if (root) {
151  res = root.isDirectory();
152  }
153  }
154  return res;
155 }
156 
157 bool ESP_SD::remove(const char *path)
158 {
159  return SD.remove(path);
160 }
161 
162 bool ESP_SD::mkdir(const char *path)
163 {
164  return SD.mkdir(path);
165 }
166 
167 bool ESP_SD::rmdir(const char *path)
168 {
169  if (!exists(path)) {
170  return false;
171  }
172  bool res = true;
173  GenLinkedList<String > pathlist;
174  String p = path;
175  pathlist.push(p);
176  while (pathlist.count() > 0) {
177  File dir = SD.open(pathlist.getLast().c_str());
178  File f = dir.openNextFile();
179  bool candelete = true;
180  while (f) {
181  if (f.isDirectory()) {
182  candelete = false;
183  String newdir = f.name();
184  pathlist.push(newdir);
185  f.close();
186  f = File();
187  } else {
188  SD.remove(f.name());
189  f.close();
190  f = dir.openNextFile();
191  }
192  }
193  if (candelete) {
194  if (pathlist.getLast() !="/") {
195  res = SD.rmdir(pathlist.getLast().c_str());
196  }
197  pathlist.pop();
198  }
199  dir.close();
200  }
201  p = String();
202  log_esp3d("count %d", pathlist.count());
203  return res;
204 }
205 
206 void ESP_SD::closeAll()
207 {
208  for (uint8_t i = 0; i < ESP_MAX_SD_OPENHANDLE; i++) {
209  tSDFile_handle[i].close();
210  tSDFile_handle[i] = File();
211  }
212 }
213 
214 ESP_SDFile::ESP_SDFile(void* handle, bool isdir, bool iswritemode, const char * path)
215 {
216  _isdir = isdir;
217  _dirlist = "";
218  _index = -1;
219  _filename = "";
220  _name = "";
221  _lastwrite = 0;
222  _iswritemode = iswritemode;
223  _size = 0;
224  if (!handle) {
225  return ;
226  }
227  bool set =false;
228  for (uint8_t i=0; (i < ESP_MAX_SD_OPENHANDLE) && !set; i++) {
229  if (!tSDFile_handle[i]) {
230  tSDFile_handle[i] = *((File*)handle);
231  //filename
232  _name = tSDFile_handle[i].name();
233  _filename = path;
234  if (_name.endsWith("/")) {
235  _name.remove( _name.length() - 1,1);
236  _isdir = true;
237  }
238  if (_name[0] == '/') {
239  _name.remove( 0, 1);
240  }
241  int pos = _name.lastIndexOf('/');
242  if (pos != -1) {
243  _name.remove( 0, pos+1);
244  }
245  if (_name.length() == 0) {
246  _name = "/";
247  }
248  //size
249  _size = tSDFile_handle[i].size();
250  //time
251  _lastwrite = tSDFile_handle[i].getLastWrite();
252  _index = i;
253  //log_esp3d("Opening File at index %d",_index);
254  set = true;
255  }
256  }
257 }
258 
259 void ESP_SDFile::close()
260 {
261  if (_index != -1) {
262  //log_esp3d("Closing File at index %d", _index);
263  tSDFile_handle[_index].close();
264  //reopen if mode = write
265  //udate size + date
266  if (_iswritemode && !_isdir) {
267  File ftmp = SD.open(_filename.c_str());
268  if (ftmp) {
269  _size = ftmp.size();
270  _lastwrite = ftmp.getLastWrite();
271  ftmp.close();
272  }
273  }
274  tSDFile_handle[_index] = File();
275  //log_esp3d("Closing File at index %d",_index);
276  _index = -1;
277  }
278 }
279 
281 {
282  if ((_index == -1) || !_isdir) {
283  log_esp3d("openNextFile failed");
284  return ESP_SDFile();
285  }
286  File tmp = tSDFile_handle[_index].openNextFile();
287  if (tmp) {
288  log_esp3d("tmp name :%s %s %s", tmp.name(), (tmp.isDirectory())?"isDir":"isFile", _filename.c_str());
289  String s = tmp.name() ;
290  //if (s!="/")s+="/";
291  //s += tmp.name();
292  ESP_SDFile esptmp(&tmp, tmp.isDirectory(),false, s.c_str());
293  esptmp.close();
294  return esptmp;
295  }
296  return ESP_SDFile();
297 }
298 
299 //TODO need to find reliable way
300 const char* ESP_SDFile::shortname() const
301 {
302  return _name.c_str();
303 }
304 
305 const char * ESP_SD::FilesystemName()
306 {
307  return "SD native";
308 }
309 
310 #endif //SD_DEVICE == ESP_SD_NATIVE
311 #endif //ARCH_ESP32 && SD_DEVICE
GenLinkedList
Definition: genLinkedList.h:30
ESP_SDCARD_NOT_PRESENT
#define ESP_SDCARD_NOT_PRESENT
Definition: defines.h:81
ESP_SDFile::isDirectory
bool isDirectory()
Definition: esp_sd.cpp:125
ESP_SD::closeAll
static void closeAll()
ESP_SD::open
static ESP_SDFile open(const char *path, uint8_t mode=ESP_FILE_READ)
ESP_FILE_WRITE
#define ESP_FILE_WRITE
Definition: defines.h:121
ESP_GBFile::openNextFile
ESP_GBFile openNextFile()
Definition: esp_globalFS.cpp:711
ESP_FILE_READ
#define ESP_FILE_READ
Definition: defines.h:120
ESP_SD::totalBytes
static uint64_t totalBytes()
ESP_SDFile
Definition: esp_sd.h:31
GenLinkedList::getLast
T getLast()
Definition: genLinkedList.h:215
ESP_FILE_APPEND
#define ESP_FILE_APPEND
Definition: defines.h:122
ESP_SD_MISO_PIN
#define ESP_SD_MISO_PIN
Definition: pins.h:172
ESP_SD::freeBytes
static uint64_t freeBytes()
ESP_GBFile::close
void close()
Definition: esp_globalFS.cpp:390
ESP_SD::remove
static bool remove(const char *path)
GenLinkedList::push
bool push(T data)
Definition: genLinkedList.h:99
ESP_SDCARD_IDLE
#define ESP_SDCARD_IDLE
Definition: defines.h:80
ESP_SD::begin
static bool begin()
ESP_SD::rmdir
static bool rmdir(const char *path)
ESP_SD::mkdir
static bool mkdir(const char *path)
ESP_GBFile::name
const char * name() const
Definition: esp_globalFS.cpp:429
GenLinkedList::pop
T pop()
Definition: genLinkedList.h:121
ESP_SD_SPEED_DIV
#define ESP_SD_SPEED_DIV
Definition: settings_esp3d.h:68
ESP_SDFile::openNextFile
ESP_SDFile openNextFile()
ESP_SD_DETECT_VALUE
#define ESP_SD_DETECT_VALUE
Definition: configuration.h:116
ESP_SD::getState
static uint8_t getState(bool refresh)
ESP_SD_CS_PIN
#define ESP_SD_CS_PIN
Definition: pins.h:169
GenLinkedList::count
size_t count()
Definition: genLinkedList.h:93
ESP_SDFile::ESP_SDFile
ESP_SDFile(void *handle=nullptr, bool isdir=false, bool iswritemode=false, const char *path=nullptr)
ESP_SD::FilesystemName
static const char * FilesystemName()
ESP_SD::format
static bool format(ESP3DOutput *output=nullptr)
ESP3DOutput::printERROR
size_t printERROR(const char *s, int code_error=200)
Definition: esp3doutput.cpp:247
ESP_SDFile::shortname
const char * shortname() const
log_esp3d
#define log_esp3d(format,...)
Definition: debug_esp3d.h:29
ESP_SDFile::close
void close()
ESP_SD::rename
static bool rename(const char *oldpath, const char *newpath)
Settings_ESP3D::read_byte
static uint8_t read_byte(int pos, bool *haserror=NULL)
Definition: settings_esp3d.cpp:715
ESP_SD_MOSI_PIN
#define ESP_SD_MOSI_PIN
Definition: pins.h:173
ESP_SD_SCK_PIN
#define ESP_SD_SCK_PIN
Definition: pins.h:174
ESP_SD::exists
static bool exists(const char *path)
ESP_MAX_SD_OPENHANDLE
#define ESP_MAX_SD_OPENHANDLE
Definition: esp_sd.cpp:27
dir
FTPFile dir
Definition: FtpServer.cpp:103
tSDFile_handle
File tSDFile_handle[ESP_MAX_SD_OPENHANDLE]
Definition: esp_sd.cpp:38
ESP_SD_DETECT_PIN
#define ESP_SD_DETECT_PIN
Definition: configuration.h:114
ESP3DOutput
Definition: esp3doutput.h:48
ESP_SD::usedBytes
static uint64_t usedBytes()
ESP_SD::end
static void end()