36 #include "esp_vfs_fat.h" 37 #include "esp_task_wdt.h" 38 #include "driver/sdspi_host.h" 39 #include "sdmmc_cmd.h" 40 #include "esp_spiffs.h" 41 #include "soc/efuse_reg.h" 44 #include "soc/adc_channel.h" 53 #pragma GCC optimize ("O2") 66 : m_start(esp_timer_get_time())
71 bool TimeOut::expired(
int valueMS)
73 return valueMS > -1 && ((esp_timer_get_time() - m_start) / 1000) > valueMS;
86 int squaredbit = 0x40000000;
89 while (squaredbit > 0) {
90 if (remainder >= (squaredbit | root)) {
91 remainder -= (squaredbit | root);
106 bool calcParity(uint8_t v)
110 return (0x6996 >> v) & 1;
119 void * realloc32(
void * ptr,
size_t size)
121 uint32_t * newBuffer = (uint32_t*) heap_caps_malloc(size, MALLOC_CAP_32BIT);
123 moveItems(newBuffer, (uint32_t*)ptr, size /
sizeof(uint32_t));
130 void free32(
void * ptr)
140 uint32_t msToTicks(
int ms)
142 return ms < 0 ? portMAX_DELAY : pdMS_TO_TICKS(ms);
152 uint32_t ver_pkg = (REG_READ(EFUSE_BLK0_RDATA3_REG) >> 9) & 7;
163 return ChipPackage::Unknown;
169 adc1_channel_t ADC1_GPIO2Channel(gpio_num_t gpio)
172 case ADC1_CHANNEL_0_GPIO_NUM:
173 return ADC1_CHANNEL_0;
174 case ADC1_CHANNEL_1_GPIO_NUM:
175 return ADC1_CHANNEL_1;
176 case ADC1_CHANNEL_2_GPIO_NUM:
177 return ADC1_CHANNEL_2;
178 case ADC1_CHANNEL_3_GPIO_NUM:
179 return ADC1_CHANNEL_3;
180 case ADC1_CHANNEL_4_GPIO_NUM:
181 return ADC1_CHANNEL_4;
182 case ADC1_CHANNEL_5_GPIO_NUM:
183 return ADC1_CHANNEL_5;
184 case ADC1_CHANNEL_6_GPIO_NUM:
185 return ADC1_CHANNEL_6;
186 case ADC1_CHANNEL_7_GPIO_NUM:
187 return ADC1_CHANNEL_7;
189 return ADC1_CHANNEL_0;
196 void configureGPIO(gpio_num_t gpio, gpio_mode_t mode)
198 PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[gpio], PIN_FUNC_GPIO);
199 gpio_set_direction(gpio, mode);
205 uint32_t getApbFrequency()
207 rtc_cpu_freq_config_t conf;
208 rtc_clk_cpu_freq_get_config(&conf);
209 return conf.freq_mhz >= 80 ? 80000000 : (conf.source_freq_mhz * 80000000 / conf.div);
215 uint32_t getCPUFrequencyMHz()
217 rtc_cpu_freq_config_t conf;
218 rtc_clk_cpu_freq_get_config(&conf);
219 return conf.freq_mhz;
226 struct esp_intr_alloc_args {
229 intr_handler_t handler;
231 intr_handle_t * ret_handle;
232 TaskHandle_t waitingTask;
236 void esp_intr_alloc_pinnedToCore_call(
void * arg)
238 auto args = (esp_intr_alloc_args*) arg;
239 esp_intr_alloc(args->source, args->flags, args->handler, args->arg, args->ret_handle);
243 void esp_intr_alloc_pinnedToCore(
int source,
int flags, intr_handler_t handler,
void * arg, intr_handle_t * ret_handle,
int core)
245 esp_intr_alloc_args args = { source, flags, handler, arg, ret_handle, xTaskGetCurrentTaskHandle() };
246 esp_ipc_call_blocking(core, esp_intr_alloc_pinnedToCore_call, &args);
254 void replacePathSep(
char * path,
char newSep)
256 for (; *path; ++path)
257 if (*path ==
'\\' || *path ==
'/')
266 static int clipLine_code(
int x,
int y, Rect
const & clipRect)
271 else if (x > clipRect.X2)
275 else if (y > clipRect.Y2)
282 bool clipLine(
int & x1,
int & y1,
int & x2,
int & y2, Rect
const & clipRect,
bool checkOnly)
288 int topLeftCode = clipLine_code(newX1, newY1, clipRect);
289 int bottomRightCode = clipLine_code(newX2, newY2, clipRect);
291 if ((topLeftCode == 0) && (bottomRightCode == 0)) {
299 }
else if (topLeftCode & bottomRightCode) {
303 int ncode = topLeftCode != 0 ? topLeftCode : bottomRightCode;
305 x = newX1 + (newX2 - newX1) * (clipRect.Y2 - newY1) / (newY2 - newY1);
307 }
else if (ncode & 4) {
308 x = newX1 + (newX2 - newX1) * (clipRect.Y1 - newY1) / (newY2 - newY1);
310 }
else if (ncode & 2) {
311 y = newY1 + (newY2 - newY1) * (clipRect.X2 - newX1) / (newX2 - newX1);
313 }
else if (ncode & 1) {
314 y = newY1 + (newY2 - newY1) * (clipRect.X1 - newX1) / (newX2 - newX1);
317 if (ncode == topLeftCode) {
320 topLeftCode = clipLine_code(newX1, newY1, clipRect);
324 bottomRightCode = clipLine_code(newX2, newY2, clipRect);
336 void removeRectangle(Stack<Rect> & rects, Rect
const & mainRect, Rect
const & rectToRemove)
338 if (!mainRect.intersects(rectToRemove) || rectToRemove.contains(mainRect))
342 if (mainRect.Y1 < rectToRemove.Y1)
343 rects.push(Rect(mainRect.X1, mainRect.Y1, mainRect.X2, rectToRemove.Y1 - 1));
346 if (mainRect.Y2 > rectToRemove.Y2)
347 rects.push(Rect(mainRect.X1, rectToRemove.Y2 + 1, mainRect.X2, mainRect.Y2));
350 if (mainRect.X1 < rectToRemove.X1)
351 rects.push(Rect(mainRect.X1, tmax(rectToRemove.Y1, mainRect.Y1), rectToRemove.X1 - 1, tmin(rectToRemove.Y2, mainRect.Y2)));
354 if (mainRect.X2 > rectToRemove.X2)
355 rects.push(Rect(rectToRemove.X2 + 1, tmax(rectToRemove.Y1, mainRect.Y1), mainRect.X2, tmin(rectToRemove.Y2, mainRect.Y2)));
362 Rect IRAM_ATTR Rect::merge(Rect
const & rect)
const 364 return Rect(imin(rect.X1,
X1), imin(rect.Y1,
Y1), imax(rect.X2,
X2), imax(rect.Y2,
Y2));
368 Rect IRAM_ATTR Rect::intersection(Rect
const & rect)
const 370 return Rect(tmax(
X1, rect.X1), tmax(
Y1, rect.Y1), tmin(
X2, rect.X2), tmin(
Y2, rect.Y2));
377 void rgb222_to_hsv(
int R,
int G,
int B,
double * h,
double * s,
double * v)
382 double cmax = tmax<double>(tmax<double>(r, g), b);
383 double cmin = tmin<double>(tmin<double>(r, g), b);
384 double diff = cmax - cmin;
388 *h = fmod((60.0 * ((g - b) / diff) + 360.0), 360.0);
390 *h = fmod((60.0 * ((b - r) / diff) + 120.0), 360.0);
392 *h = fmod((60.0 * ((r - g) / diff) + 240.0), 360.0);
393 *s = cmax == 0 ? 0 : (diff / cmax) * 100.0;
403 StringList::StringList()
413 StringList::~StringList()
419 void StringList::clear()
422 for (
int i = 0; i < m_count; ++i)
423 free((
void*) m_items[i]);
429 m_count = m_allocated = 0;
433 void StringList::copyFrom(StringList
const & src)
436 m_count = src.m_count;
437 checkAllocatedSpace(m_count);
438 for (
int i = 0; i < m_count; ++i) {
439 m_items[i] =
nullptr;
440 set(i, src.m_items[i]);
446 void StringList::copySelectionMapFrom(StringList
const & src)
448 int maskLen = (31 + m_allocated) / 32;
449 for (
int i = 0; i < maskLen; ++i)
450 m_selMap[i] = src.m_selMap[i];
454 void StringList::checkAllocatedSpace(
int requiredItems)
456 if (m_allocated < requiredItems) {
457 if (m_allocated == 0) {
459 m_allocated = requiredItems;
462 while (m_allocated < requiredItems)
465 m_items = (
char const**) realloc32(m_items, m_allocated *
sizeof(
char const *));
466 m_selMap = (uint32_t*) realloc32(m_selMap, (31 + m_allocated) / 32 *
sizeof(uint32_t));
471 void StringList::insert(
int index,
char const * str)
474 checkAllocatedSpace(m_count);
475 moveItems(m_items + index + 1, m_items + index, m_count - index - 1);
476 m_items[index] =
nullptr;
482 int StringList::append(
char const * str)
484 insert(m_count, str);
489 int StringList::appendFmt(
const char *format, ...)
493 va_start(ap, format);
494 int size = vsnprintf(
nullptr, 0, format, ap) + 1;
497 va_start(ap, format);
499 vsnprintf(buf, size, format, ap);
500 insert(m_count, buf);
507 void StringList::append(
char const * strlist[],
int count)
509 for (
int i = 0; i < count; ++i)
510 insert(m_count, strlist[i]);
515 void StringList::appendSepList(
char const * strlist,
char separator)
519 char const * start = strlist;
521 auto end = strchr(start, separator);
523 end = strchr(start, 0);
524 int len = end - start;
526 memcpy(str, start, len);
528 insert(m_count, str);
529 start += len + (*end == 0 ? 0 : 1);
535 void StringList::set(
int index,
char const * str)
538 free((
void*)m_items[index]);
539 m_items[index] = (
char const*) malloc(strlen(str) + 1);
540 strcpy((
char*)m_items[index], str);
542 m_items[index] = str;
547 void StringList::remove(
int index)
550 free((
void*)m_items[index]);
551 moveItems(m_items + index, m_items + index + 1, m_count - index - 1);
557 void StringList::takeStrings()
562 for (
int i = 0; i < m_count; ++i) {
563 char const * str = m_items[i];
564 m_items[i] =
nullptr;
571 void StringList::deselectAll()
573 for (
int i = 0; i < (31 + m_count) / 32; ++i)
578 bool StringList::selected(
int index)
580 return m_selMap[index / 32] & (1 << (index % 32));
585 int StringList::getFirstSelected()
587 for (
int i = 0; i < m_count; ++i)
594 void StringList::select(
int index,
bool value)
597 m_selMap[index / 32] |= 1 << (index % 32);
599 m_selMap[index / 32] &= ~(1 << (index % 32));
613 char const * FileBrowser::s_SPIFFSMountPath;
614 bool FileBrowser::s_SPIFFSMounted =
false;
615 size_t FileBrowser::s_SPIFFSMaxFiles;
617 char const * FileBrowser::s_SDCardMountPath;
618 bool FileBrowser::s_SDCardMounted =
false;
619 size_t FileBrowser::s_SDCardMaxFiles;
620 int FileBrowser::s_SDCardAllocationUnitSize;
621 int8_t FileBrowser::s_SDCardMISO;
622 int8_t FileBrowser::s_SDCardMOSI;
623 int8_t FileBrowser::s_SDCardCLK;
624 int8_t FileBrowser::s_SDCardCS;
625 sdmmc_card_t * FileBrowser::s_SDCard =
nullptr;
629 FileBrowser::FileBrowser()
634 m_includeHiddenFiles(false),
635 m_namesStorage(nullptr)
640 FileBrowser::FileBrowser(
char const * path)
647 FileBrowser::~FileBrowser()
656 void FileBrowser::clear()
661 free(m_namesStorage);
662 m_namesStorage =
nullptr;
671 if (m_dir ==
nullptr || strcmp(path, m_dir) != 0) {
673 m_dir = strdup(path);
684 if (!m_dir || strlen(subdir) == 0)
686 if (strcmp(subdir,
"..") == 0) {
688 auto lastSlash = strrchr(m_dir,
'/');
690 if (lastSlash != m_dir)
698 auto oldLen = strcmp(m_dir,
"/") == 0 ? 0 : strlen(m_dir);
699 char * newDir = (
char*) malloc(oldLen + 1 + strlen(subdir) + 1);
700 strcpy(newDir, m_dir);
701 newDir[oldLen] =
'/';
702 strcpy(newDir + oldLen + 1, subdir);
710 int FileBrowser::countDirEntries(
int * namesLength)
713 if (strcmp(m_dir,
"/") == 0) {
725 auto dirp = opendir(m_dir);
727 auto dp = readdir(dirp);
730 if (strcmp(
".", dp->d_name) && strcmp(
"..", dp->d_name) && dp->d_type != DT_UNKNOWN) {
731 *namesLength += strlen(dp->d_name) + 1;
748 for (
int i = 0; i < m_count; ++i)
749 if (strcmp(name, m_items[i].name) == 0)
752 for (
int i = 0; i < m_count; ++i)
753 if (strcasecmp(name, m_items[i].name) == 0)
772 char fullpath[strlen(m_dir) + 1 + strlen(name) + 1];
773 sprintf(fullpath,
"%s/%s", m_dir, name);
774 auto fr = fopen(fullpath,
"rb");
776 fseek(fr, 0, SEEK_END);
786 char fullpath[strlen(m_dir) + 1 + strlen(name) + 1];
787 sprintf(fullpath,
"%s/%s", m_dir, name);
789 if (stat(fullpath, &s))
791 auto tm = *localtime((time_t*)&s.st_ctime);
792 *year = 1900 + tm.tm_year;
793 *month = 1 + tm.tm_mon;
796 *minutes = tm.tm_min;
797 *seconds = imin(tm.tm_sec, 59);
804 char fullpath[strlen(m_dir) + 1 + strlen(name) + 1];
805 sprintf(fullpath,
"%s/%s", m_dir, name);
807 if (stat(fullpath, &s))
809 auto tm = *localtime((time_t*)&s.st_mtime);
810 *year = 1900 + tm.tm_year;
811 *month = 1 + tm.tm_mon;
814 *minutes = tm.tm_min;
815 *seconds = imin(tm.tm_sec, 59);
822 char fullpath[strlen(m_dir) + 1 + strlen(name) + 1];
823 sprintf(fullpath,
"%s/%s", m_dir, name);
825 if (stat(fullpath, &s))
827 auto tm = *localtime((time_t*)&s.st_atime);
828 *year = 1900 + tm.tm_year;
829 *month = 1 + tm.tm_mon;
832 *minutes = tm.tm_min;
833 *seconds = imin(tm.tm_sec, 59);
839 int DirComp(
const void * i1,
const void * i2)
844 return d1->
isDir ? -1 : +1;
856 int c = countDirEntries(&namesAlloc);
858 m_namesStorage = (
char*) malloc(namesAlloc);
859 char * sname = m_namesStorage;
861 if (strcmp(m_dir,
"/") == 0) {
864 if (s_SPIFFSMounted) {
865 m_items[m_count].
name = s_SPIFFSMountPath + 1;
866 m_items[m_count].
isDir =
true;
869 if (s_SDCardMounted) {
870 m_items[m_count].
name = s_SDCardMountPath + 1;
871 m_items[m_count].
isDir =
true;
878 m_items[0].
name =
"..";
879 m_items[0].
isDir =
true;
882 int hiddenFilesCount = 0;
883 auto dirp = opendir(m_dir);
885 auto dp = readdir(dirp);
888 if (strcmp(
".", dp->d_name) && strcmp(
"..", dp->d_name) && dp->d_type != DT_UNKNOWN) {
889 DirItem * di = m_items + m_count;
891 auto slashPos = strchr(dp->d_name,
'/');
894 auto len = slashPos - dp->d_name;
895 strncpy(sname, dp->d_name, len);
904 bool isHidden = dp->d_name[0] ==
'.';
905 if (!isHidden || m_includeHiddenFiles) {
906 strcpy(sname, dp->d_name);
908 di->
isDir = (dp->d_type == DT_DIR);
909 sname += strlen(sname) + 1;
929 qsort(m_items, m_count,
sizeof(
DirItem), DirComp);
939 int dirnameLen = strlen(dirname);
940 if (dirnameLen > 0) {
943 char fullpath[strlen(m_dir) + 3 + 2 * dirnameLen + 1];
946 auto next = name + 1;
947 while (*next && *next !=
'\\' && *next !=
'/')
949 strcpy(fullpath, m_dir);
950 if (dirname != name) {
951 strcat(fullpath,
"/");
952 strncat(fullpath, dirname, name - dirname - 1);
954 strcat(fullpath,
"/");
955 strncat(fullpath, name, next - name);
956 strcat(fullpath,
"/.");
957 strncat(fullpath, name, next - name);
958 replacePathSep(fullpath,
'/');
959 FILE * f = fopen(fullpath,
"wb");
967 char fullpath[strlen(m_dir) + 1 + dirnameLen + 1];
968 sprintf(fullpath,
"%s/%s", m_dir, dirname);
969 replacePathSep(fullpath,
'/');
970 mkdir(fullpath, ACCESSPERMS);
981 char fullpath[strlen(m_dir) + 1 + strlen(name) + 1];
982 sprintf(fullpath,
"%s/%s", m_dir, name);
983 int r = unlink(fullpath);
995 char hidpath[strlen(m_dir) + 3 + 2 * strlen(name) + 1];
996 sprintf(hidpath,
"%s/%s/.%s", m_dir, name, name);
999 auto dirp = opendir(fullpath);
1001 auto dp = readdir(dirp);
1004 if (strcmp(
".", dp->d_name) && strcmp(
"..", dp->d_name) && dp->d_type != DT_UNKNOWN) {
1005 char sfullpath[strlen(fullpath) + 1 + strlen(dp->d_name) + 1];
1006 sprintf(sfullpath,
"%s/%s", fullpath, dp->d_name);
1019 char oldfullpath[strlen(m_dir) + 1 + strlen(oldName) + 1];
1020 sprintf(oldfullpath,
"%s/%s", m_dir, oldName);
1022 char newfullpath[strlen(m_dir) + 1 + strlen(newName) + 1];
1023 sprintf(newfullpath,
"%s/%s", m_dir, newName);
1025 ::rename(oldfullpath, newfullpath);
1032 constexpr
int FLEN = 6;
1033 auto ret = (
char*) malloc(strlen(m_dir) + 1 + FLEN + 4 + 1);
1035 char name[FLEN + 1] = { 0 };
1036 for (
int i = 0; i < FLEN; ++i)
1037 name[i] = 65 + (rand() % 26);
1038 sprintf(ret,
"%s/%s.TMP", m_dir, name);
1039 if (!
exists(name,
false))
1047 constexpr
size_t BUFLEN = 512;
1049 char fullpath[strlen(m_dir) + 1 + strlen(name) + 1];
1050 sprintf(fullpath,
"%s/%s", m_dir, name);
1055 bool retval =
false;
1059 if (::
rename(fullpath, tempFilename) == 0) {
1060 void * buf = malloc(BUFLEN);
1062 auto fr = fopen(tempFilename,
"rb");
1064 auto fw = fopen(fullpath,
"wb");
1068 auto l = fread(buf, 1, tmin(size, BUFLEN), fr);
1071 fwrite(buf, 1, l, fw);
1076 for (; size > 0; --size)
1086 unlink(tempFilename);
1097 return (outPath ? snprintf(outPath, maxlen,
"%s/%s", m_dir, name) : snprintf(
nullptr, 0,
"%s/%s", m_dir, name)) + 1;
1103 char fullpath[strlen(m_dir) + 1 + strlen(filename) + 1];
1104 strcpy(fullpath, m_dir);
1105 strcat(fullpath,
"/");
1106 strcat(fullpath, filename);
1108 replacePathSep(fullpath,
'/');
1110 return fopen(fullpath, mode);
1122 if (strncmp(path,
"/spiffs", 7) == 0 || (s_SPIFFSMounted && strncmp(path, s_SPIFFSMountPath, strlen(s_SPIFFSMountPath)) == 0)) {
1124 }
else if (s_SDCardMounted && strncmp(path, s_SDCardMountPath, strlen(s_SDCardMountPath)) == 0) {
1134 esp_task_wdt_init(45,
false);
1139 char drv[3] = {(char)(
'0' + drive),
':', 0};
1142 void * buffer = malloc(FF_MAX_SS);
1147 DWORD plist[] = { 100, 0, 0, 0 };
1148 if (f_fdisk(drive, plist, buffer) != FR_OK) {
1154 if (f_mkfs(drv, FM_ANY, 16 * 1024, buffer, FF_MAX_SS) != FR_OK) {
1168 bool r = (esp_spiffs_format(
nullptr) == ESP_OK);
1179 bool FileBrowser::mountSDCard(
bool formatOnFail,
char const * mountPath,
size_t maxFiles,
int allocationUnitSize,
int MISO,
int MOSI,
int CLK,
int CS)
1181 switch (getChipPackage()) {
1194 s_SDCardMountPath = mountPath;
1195 s_SDCardMaxFiles = maxFiles;
1196 s_SDCardAllocationUnitSize = allocationUnitSize;
1197 s_SDCardMISO = MISO;
1198 s_SDCardMOSI = MOSI;
1201 s_SDCardMounted =
false;
1203 sdmmc_host_t host = SDSPI_HOST_DEFAULT();
1204 host.slot = HSPI_HOST;
1206 #if FABGL_ESP_IDF_VERSION <= FABGL_ESP_IDF_VERSION_VAL(3, 3, 5) 1208 sdspi_slot_config_t slot_config = SDSPI_SLOT_CONFIG_DEFAULT();
1209 slot_config.gpio_miso = int2gpio(MISO);
1210 slot_config.gpio_mosi = int2gpio(MOSI);
1211 slot_config.gpio_sck = int2gpio(CLK);
1212 slot_config.gpio_cs = int2gpio(CS);
1214 esp_vfs_fat_sdmmc_mount_config_t mount_config;
1215 mount_config.format_if_mount_failed = formatOnFail;
1216 mount_config.max_files = maxFiles;
1217 mount_config.allocation_unit_size = allocationUnitSize;
1219 s_SDCardMounted = (esp_vfs_fat_sdmmc_mount(mountPath, &host, &slot_config, &mount_config, &s_SDCard) == ESP_OK);
1225 host.max_freq_khz = 19000;
1227 spi_bus_config_t bus_cfg = {
1228 .mosi_io_num = int2gpio(MOSI),
1229 .miso_io_num = int2gpio(MISO),
1230 .sclk_io_num = int2gpio(CLK),
1231 .quadwp_io_num = -1,
1232 .quadhd_io_num = -1,
1233 .max_transfer_sz = 4000,
1235 auto r = spi_bus_initialize((spi_host_device_t)host.slot, &bus_cfg, 2);
1237 if (r == ESP_OK || r == ESP_ERR_INVALID_STATE) {
1238 sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT();
1239 slot_config.gpio_cs = int2gpio(CS);
1240 slot_config.host_id = (spi_host_device_t) host.slot;
1242 esp_vfs_fat_sdmmc_mount_config_t mount_config;
1243 mount_config.format_if_mount_failed = formatOnFail;
1244 mount_config.max_files = maxFiles;
1245 mount_config.allocation_unit_size = allocationUnitSize;
1247 r = esp_vfs_fat_sdspi_mount(mountPath, &host, &slot_config, &mount_config, &s_SDCard);
1249 s_SDCardMounted = (r == ESP_OK);
1254 return s_SDCardMounted;
1260 if (s_SDCardMounted) {
1261 #if FABGL_ESP_IDF_VERSION <= FABGL_ESP_IDF_VERSION_VAL(3, 3, 5) 1262 esp_vfs_fat_sdmmc_unmount();
1264 esp_vfs_fat_sdcard_unmount(s_SDCardMountPath, s_SDCard);
1266 s_SDCardMounted =
false;
1274 return mountSDCard(
false, s_SDCardMountPath, s_SDCardMaxFiles, s_SDCardAllocationUnitSize, s_SDCardMISO, s_SDCardMOSI, s_SDCardCLK, s_SDCardCS);
1280 s_SPIFFSMountPath = mountPath;
1281 s_SPIFFSMaxFiles = maxFiles;
1282 esp_vfs_spiffs_conf_t conf = {
1283 .base_path = mountPath,
1284 .partition_label =
nullptr,
1285 .max_files = maxFiles,
1286 .format_if_mount_failed =
true 1288 s_SPIFFSMounted = (esp_vfs_spiffs_register(&conf) == ESP_OK);
1289 return s_SPIFFSMounted;
1295 if (s_SPIFFSMounted) {
1296 esp_vfs_spiffs_unregister(
nullptr);
1297 s_SPIFFSMounted =
false;
1305 return mountSPIFFS(
false, s_SPIFFSMountPath, s_SPIFFSMaxFiles);
1316 DWORD free_clusters;
1317 char drv[3] = {(char)(
'0' + drive),
':', 0};
1318 if (f_getfree(drv, &free_clusters, &fs) != FR_OK)
1320 int64_t total_sectors = (fs->n_fatent - 2) * fs->csize;
1321 int64_t free_sectors = free_clusters * fs->csize;
1322 *total = total_sectors * fs->ssize;
1323 *used = *total - free_sectors * fs->ssize;
1329 size_t stotal = 0, sused = 0;
1330 if (esp_spiffs_info(NULL, &stotal, &sused) != ESP_OK)
1351 void LightMemoryPool::mark(
int pos, int16_t size,
bool allocated)
1353 m_mem[pos] = size & 0xff;
1354 m_mem[pos + 1] = ((size >> 8) & 0x7f) | (allocated ? 0x80 : 0);
1358 int16_t LightMemoryPool::getSize(
int pos)
1360 return m_mem[pos] | ((m_mem[pos + 1] & 0x7f) << 8);
1364 bool LightMemoryPool::isFree(
int pos)
1366 return (m_mem[pos + 1] & 0x80) == 0;
1370 LightMemoryPool::LightMemoryPool(
int poolSize)
1372 m_poolSize = poolSize + 2;
1373 m_mem = (uint8_t*) heap_caps_malloc(m_poolSize, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
1374 mark(0, m_poolSize - 2,
false);
1378 LightMemoryPool::~LightMemoryPool()
1380 heap_caps_free(m_mem);
1384 void * LightMemoryPool::alloc(
int size)
1386 for (
int pos = 0; pos < m_poolSize; ) {
1387 int16_t blockSize = getSize(pos);
1389 if (blockSize == size) {
1391 mark(pos, size,
true);
1392 return m_mem + pos + 2;
1393 }
else if (blockSize > size) {
1395 int remainingSize = blockSize - size - 2;
1396 if (remainingSize > 0)
1397 mark(pos + 2 + size, remainingSize,
false);
1400 mark(pos, size,
true);
1401 return m_mem + pos + 2;
1405 int nextBlockPos = pos + 2 + blockSize;
1406 if (nextBlockPos < m_poolSize && isFree(nextBlockPos)) {
1408 mark(pos, blockSize + getSize(nextBlockPos) + 2,
false);
1411 pos += blockSize + 2;
1416 pos += blockSize + 2;
1423 bool LightMemoryPool::memCheck()
1426 while (pos < m_poolSize) {
1427 int16_t blockSize = getSize(pos);
1428 pos += blockSize + 2;
1430 return pos == m_poolSize;
1434 int LightMemoryPool::totFree()
1437 for (
int pos = 0; pos < m_poolSize; ) {
1438 int16_t blockSize = getSize(pos);
1441 pos += blockSize + 2;
1447 int LightMemoryPool::totAllocated()
1450 for (
int pos = 0; pos < m_poolSize; ) {
1451 int16_t blockSize = getSize(pos);
1454 pos += blockSize + 2;
1460 int LightMemoryPool::largestFree()
1463 for (
int pos = 0; pos < m_poolSize; ) {
1464 int16_t blockSize = getSize(pos);
1465 if (isFree(pos) && blockSize > r)
1467 pos += blockSize + 2;
This file contains fabgl::PS2Controller definition.
This file contains fabgl::VGA16Controller definition.
bool truncate(char const *name, size_t size)
Truncates a file to the specified size.
void rename(char const *oldName, char const *newName)
Renames a file.
bool filePathExists(char const *filepath)
Determines if a file exists.
void remove(char const *name)
Removes a file or directory.
static bool mountSDCard(bool formatOnFail, char const *mountPath, size_t maxFiles=4, int allocationUnitSize=16 *1024, int MISO=16, int MOSI=17, int CLK=14, int CS=13)
Mounts filesystem on SD Card.
bool setDirectory(const char *path)
Sets absolute directory path.
This file contains fabgl::VGAController definition.
size_t fileSize(char const *name)
Determines file size.
bool fileUpdateDate(char const *name, int *year, int *month, int *day, int *hour, int *minutes, int *seconds)
Gets file update date and time.
#define FABGLIB_VIDEO_CPUINTENSIVE_TASKS_CORE
bool fileCreationDate(char const *name, int *year, int *month, int *day, int *hour, int *minutes, int *seconds)
Gets file creation date and time.
This file contains fabgl::VGA2Controller definition.
static void unmountSDCard()
Unmounts filesystem on SD Card.
This file contains some utility classes and functions.
FileBrowser item specificator.
char * createTempFilename()
Creates a random temporary filename, with absolute path.
int getFullPath(char const *name, char *outPath=nullptr, int maxlen=0)
Composes a full file path given a relative name.
DriveType getCurrentDriveType()
Returns the drive type of current directory.
static bool format(DriveType driveType, int drive)
Formats SPIFFS or SD Card.
DriveType
This enum defines drive types (SPIFFS or SD Card)
static bool remountSDCard()
Remounts SDCard filesystem, using the same parameters.
ChipPackage
This enum defines ESP32 module types (packages)
void makeDirectory(char const *dirname)
Creates a directory.
bool fileAccessDate(char const *name, int *year, int *month, int *day, int *hour, int *minutes, int *seconds)
Gets file access date and time.
static DriveType getDriveType(char const *path)
Returns the drive type of specified path.
void changeDirectory(const char *subdir)
Sets relative directory path.
FILE * openFile(char const *filename, char const *mode)
Opens a file from current directory.
static bool mountSPIFFS(bool formatOnFail, char const *mountPath, size_t maxFiles=4)
Mounts filesystem on SPIFFS (Flash)
bool exists(char const *name, bool caseSensitive=true)
Determines if a file or directory exists.
bool reload()
Reloads directory content.
static bool getFSInfo(DriveType driveType, int drive, int64_t *total, int64_t *used)
Gets total and free space on a filesystem.
static bool remountSPIFFS()
Remounts SPIFFS filesystem, using the same parameters.
static void unmountSPIFFS()
Unmounts filesystem on SPIFFS (Flash)