ESP3D  3.0
Firmware for ESP boards connected to 3D Printer
sdio_esp32.cpp
Go to the documentation of this file.
1 /*
2 sdio_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_SDIO)
23 #include "../esp_sd.h"
24 #include "../../../core/genLinkedList.h"
25 #include "../../../core/settings_esp3d.h"
26 #include "FS.h"
27 #include "SD_MMC.h"
28 
29 
31 
32 #define SDMMC_FORCE_BEGIN
33 
34 uint8_t ESP_SD::getState(bool refresh)
35 {
36  static bool lastinitok = false;
37 #ifdef SDMMC_FORCE_BEGIN
38  lastinitok = false;
39 #endif //SDMMC_LIGHT_CHECK
40 #if defined(ESP_SD_DETECT_PIN) && ESP_SD_DETECT_PIN != -1
41  //no need to go further if SD detect is not correct
42  if (!((digitalRead (ESP_SD_DETECT_PIN) == ESP_SD_DETECT_VALUE) ? true : false)) {
43  _state = ESP_SDCARD_NOT_PRESENT;
44  return _state;
45  }
46 #endif //ESP_SD_DETECT_PIN
47  //if busy doing something return state
48  if (!((_state == ESP_SDCARD_NOT_PRESENT) || _state == ESP_SDCARD_IDLE)) {
49  return _state;
50  }
51  if (!refresh) {
52  return _state; //to avoid refresh=true + busy to reset SD and waste time
53  }
54 //SD is idle or not detected, let see if still the case
55  _state = ESP_SDCARD_NOT_PRESENT;
56 //refresh content if card was removed
57  if (!lastinitok) {
58  log_esp3d("last init was failed try sd_mmc begin");
59  //SD_MMC.end();
60  if (SD_MMC.begin()) {
61  log_esp3d("sd_mmc begin succeed");
62  if (SD_MMC.cardType() != CARD_NONE ) {
63  _state = ESP_SDCARD_IDLE;
64  lastinitok = true;
65  log_esp3d("sd_mmc card type succeed");
66  } else {
67  log_esp3d("sd_mmc card type failed");
68  }
69  } else {
70  log_esp3d("sd_mmc begin failed");
71  }
72  } else {
73  log_esp3d("last init was ok try card type");
74  if(SD_MMC.cardType() != CARD_NONE) {
75  log_esp3d("checking sd_mmc card type succeed");
76  _state = ESP_SDCARD_IDLE;
77  } else {
78  lastinitok = false;
79  log_esp3d("Soft sd check failed");
80  //SD_MMC.end();
81  if (SD_MMC.begin()) {
82  log_esp3d("new sd_mmc begin succeed");
83  if ( SD_MMC.cardType() != CARD_NONE ) {
84  _state = ESP_SDCARD_IDLE;
85  lastinitok = true;
86  log_esp3d("new sd_mmc card type succeed");
87  } else {
88  log_esp3d("new sd_mmc card type failed");
89  }
90  } else {
91  log_esp3d("new sd_mmc begin failed");
92  }
93  }
94  }
95  return _state;
96 }
97 
98 bool ESP_SD::begin()
99 {
100  log_esp3d("Begin SDIO");
101  _started = true;
102 #ifdef SDMMC_FORCE_BEGIN
103  _state = ESP_SDCARD_NOT_PRESENT;
104 #else
105  _state = getState(true);
106 #endif //SDMMC_FORCE_BEGIN
107 
108  return _started;
109 }
110 
111 void ESP_SD::end()
112 {
113  SD_MMC.end();
114  _state = ESP_SDCARD_NOT_PRESENT;
115  _started = false;
116 }
117 
118 uint64_t ESP_SD::totalBytes()
119 {
120  return SD_MMC.totalBytes();
121 }
122 
123 uint64_t ESP_SD::usedBytes()
124 {
125  return SD_MMC.usedBytes();
126 }
127 
128 uint64_t ESP_SD::freeBytes()
129 {
130  return (SD_MMC.totalBytes() - SD_MMC.usedBytes());
131 }
132 
133 bool ESP_SD::rename(const char *oldpath, const char *newpath)
134 {
135  return SD_MMC.rename(oldpath,newpath);
136 }
137 
138 bool ESP_SD::format(ESP3DOutput * output)
139 {
140  //not available yet
141  if (output) {
142  output->printERROR ("Not implemented!");
143  }
144  return false;
145 }
146 
147 ESP_SDFile ESP_SD::open(const char* path, uint8_t mode)
148 {
149  //do some check
150  if(((strcmp(path,"/") == 0) && ((mode == ESP_FILE_WRITE) || (mode == ESP_FILE_APPEND))) || (strlen(path) == 0)) {
151  return ESP_SDFile();
152  }
153  // path must start by '/'
154  if (path[0] != '/') {
155  return ESP_SDFile();
156  }
157  if (mode != ESP_FILE_READ) {
158  //check container exists
159  String p = path;
160  p.remove(p.lastIndexOf('/') +1);
161  if (!exists(p.c_str())) {
162  log_esp3d("Error opening: %s", path);
163  return ESP_SDFile();
164  }
165  }
166  File tmp = SD_MMC.open(path, (mode == ESP_FILE_READ)?FILE_READ:(mode == ESP_FILE_WRITE)?FILE_WRITE:FILE_APPEND);
167  ESP_SDFile esptmp(&tmp, tmp.isDirectory(),(mode == ESP_FILE_READ)?false:true, path);
168  return esptmp;
169 }
170 
171 bool ESP_SD::exists(const char* path)
172 {
173  bool res = false;
174  //root should always be there if started
175  if (strcmp(path, "/") == 0) {
176  return _started;
177  }
178  res = SD_MMC.exists(path);
179  if (!res) {
180  ESP_SDFile root = ESP_SD::open(path, ESP_FILE_READ);
181  if (root) {
182  res = root.isDirectory();
183  }
184  }
185  return res;
186 }
187 
188 bool ESP_SD::remove(const char *path)
189 {
190  return SD_MMC.remove(path);
191 }
192 
193 bool ESP_SD::mkdir(const char *path)
194 {
195  return SD_MMC.mkdir(path);
196 }
197 
198 bool ESP_SD::rmdir(const char *path)
199 {
200  if (!exists(path)) {
201  return false;
202  }
203  bool res = true;
204  GenLinkedList<String > pathlist;
205  String p = path;
206  pathlist.push(p);
207  while (pathlist.count() > 0) {
208  File dir = SD_MMC.open(pathlist.getLast().c_str());
209  File f = dir.openNextFile();
210  bool candelete = true;
211  while (f) {
212  if (f.isDirectory()) {
213  candelete = false;
214  String newdir = f.name();
215  pathlist.push(newdir);
216  f.close();
217  f = File();
218  } else {
219  SD_MMC.remove(f.name());
220  f.close();
221  f = dir.openNextFile();
222  }
223  }
224  if (candelete) {
225  if (pathlist.getLast() !="/") {
226  res = SD_MMC.rmdir(pathlist.getLast().c_str());
227  }
228  pathlist.pop();
229  }
230  dir.close();
231  }
232  p = String();
233  log_esp3d("count %d", pathlist.count());
234  return res;
235 }
236 
237 void ESP_SD::closeAll()
238 {
239  for (uint8_t i = 0; i < ESP_MAX_SD_OPENHANDLE; i++) {
240  tSDFile_handle[i].close();
241  tSDFile_handle[i] = File();
242  }
243 }
244 
245 ESP_SDFile::ESP_SDFile(void* handle, bool isdir, bool iswritemode, const char * path)
246 {
247  _isdir = isdir;
248  _dirlist = "";
249  _index = -1;
250  _filename = "";
251  _name = "";
252  _lastwrite = 0;
253  _iswritemode = iswritemode;
254  _size = 0;
255  if (!handle) {
256  return ;
257  }
258  bool set =false;
259  for (uint8_t i=0; (i < ESP_MAX_SD_OPENHANDLE) && !set; i++) {
260  if (!tSDFile_handle[i]) {
261  tSDFile_handle[i] = *((File*)handle);
262  //filename
263  _name = tSDFile_handle[i].name();
264  _filename = path;
265  if (_name.endsWith("/")) {
266  _name.remove( _name.length() - 1,1);
267  _isdir = true;
268  }
269  if (_name[0] == '/') {
270  _name.remove( 0, 1);
271  }
272  int pos = _name.lastIndexOf('/');
273  if (pos != -1) {
274  _name.remove( 0, pos+1);
275  }
276  if (_name.length() == 0) {
277  _name = "/";
278  }
279  //size
280  _size = tSDFile_handle[i].size();
281  //time
282  _lastwrite = tSDFile_handle[i].getLastWrite();
283  _index = i;
284  //log_esp3d("Opening File at index %d",_index);
285  set = true;
286  }
287  }
288 }
289 
290 void ESP_SDFile::close()
291 {
292  if (_index != -1) {
293  //log_esp3d("Closing File at index %d", _index);
294  tSDFile_handle[_index].close();
295  //reopen if mode = write
296  //udate size + date
297  if (_iswritemode && !_isdir) {
298  File ftmp = SD_MMC.open(_filename.c_str());
299  if (ftmp) {
300  _size = ftmp.size();
301  _lastwrite = ftmp.getLastWrite();
302  ftmp.close();
303  }
304  }
305  tSDFile_handle[_index] = File();
306  //log_esp3d("Closing File at index %d",_index);
307  _index = -1;
308  }
309 }
310 
312 {
313  if ((_index == -1) || !_isdir) {
314  log_esp3d("openNextFile failed");
315  return ESP_SDFile();
316  }
317  File tmp = tSDFile_handle[_index].openNextFile();
318  if (tmp) {
319  log_esp3d("tmp name :%s %s %s", tmp.name(), (tmp.isDirectory())?"isDir":"isFile", _filename.c_str());
320  String s = tmp.name() ;
321  //if (s!="/")s+="/";
322  //s += tmp.name();
323  ESP_SDFile esptmp(&tmp, tmp.isDirectory(),false, s.c_str());
324  esptmp.close();
325  return esptmp;
326  }
327  return ESP_SDFile();
328 }
329 
330 //TODO need to find reliable way
331 const char* ESP_SDFile::shortname() const
332 {
333  return _name.c_str();
334 }
335 
336 const char * ESP_SD::FilesystemName()
337 {
338  return "SDIO";
339 }
340 #endif //SD_DEVICE == ESP_SDIO
341 #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::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_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)
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)
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()