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;
628 FileBrowser::FileBrowser()
633 m_includeHiddenFiles(false),
634 m_namesStorage(nullptr)
639 FileBrowser::~FileBrowser()
648 void FileBrowser::clear()
653 free(m_namesStorage);
654 m_namesStorage =
nullptr;
663 if (m_dir ==
nullptr || strcmp(path, m_dir) != 0) {
665 m_dir = strdup(path);
676 if (!m_dir || strlen(subdir) == 0)
678 if (strcmp(subdir,
"..") == 0) {
680 auto lastSlash = strrchr(m_dir,
'/');
682 if (lastSlash != m_dir)
690 auto oldLen = strcmp(m_dir,
"/") == 0 ? 0 : strlen(m_dir);
691 char * newDir = (
char*) malloc(oldLen + 1 + strlen(subdir) + 1);
692 strcpy(newDir, m_dir);
693 newDir[oldLen] =
'/';
694 strcpy(newDir + oldLen + 1, subdir);
702 int FileBrowser::countDirEntries(
int * namesLength)
705 if (strcmp(m_dir,
"/") == 0) {
717 auto dirp = opendir(m_dir);
719 auto dp = readdir(dirp);
722 if (strcmp(
".", dp->d_name) && strcmp(
"..", dp->d_name) && dp->d_type != DT_UNKNOWN) {
723 *namesLength += strlen(dp->d_name) + 1;
740 for (
int i = 0; i < m_count; ++i)
741 if (strcmp(name, m_items[i].name) == 0)
744 for (
int i = 0; i < m_count; ++i)
745 if (strcasecmp(name, m_items[i].name) == 0)
755 char fullpath[strlen(m_dir) + 1 + strlen(name) + 1];
756 sprintf(fullpath,
"%s/%s", m_dir, name);
757 auto fr = fopen(fullpath,
"rb");
759 fseek(fr, 0, SEEK_END);
769 char fullpath[strlen(m_dir) + 1 + strlen(name) + 1];
770 sprintf(fullpath,
"%s/%s", m_dir, name);
772 if (stat(fullpath, &s))
774 auto tm = *localtime((time_t*)&s.st_ctime);
775 *year = 1900 + tm.tm_year;
776 *month = 1 + tm.tm_mon;
779 *minutes = tm.tm_min;
780 *seconds = imin(tm.tm_sec, 59);
787 char fullpath[strlen(m_dir) + 1 + strlen(name) + 1];
788 sprintf(fullpath,
"%s/%s", m_dir, name);
790 if (stat(fullpath, &s))
792 auto tm = *localtime((time_t*)&s.st_mtime);
793 *year = 1900 + tm.tm_year;
794 *month = 1 + tm.tm_mon;
797 *minutes = tm.tm_min;
798 *seconds = imin(tm.tm_sec, 59);
805 char fullpath[strlen(m_dir) + 1 + strlen(name) + 1];
806 sprintf(fullpath,
"%s/%s", m_dir, name);
808 if (stat(fullpath, &s))
810 auto tm = *localtime((time_t*)&s.st_atime);
811 *year = 1900 + tm.tm_year;
812 *month = 1 + tm.tm_mon;
815 *minutes = tm.tm_min;
816 *seconds = imin(tm.tm_sec, 59);
822 int DirComp(
const void * i1,
const void * i2)
827 return d1->
isDir ? -1 : +1;
839 int c = countDirEntries(&namesAlloc);
841 m_namesStorage = (
char*) malloc(namesAlloc);
842 char * sname = m_namesStorage;
844 if (strcmp(m_dir,
"/") == 0) {
847 if (s_SPIFFSMounted) {
848 m_items[m_count].
name = s_SPIFFSMountPath + 1;
849 m_items[m_count].
isDir =
true;
852 if (s_SDCardMounted) {
853 m_items[m_count].
name = s_SDCardMountPath + 1;
854 m_items[m_count].
isDir =
true;
861 m_items[0].
name =
"..";
862 m_items[0].
isDir =
true;
865 int hiddenFilesCount = 0;
866 auto dirp = opendir(m_dir);
868 auto dp = readdir(dirp);
871 if (strcmp(
".", dp->d_name) && strcmp(
"..", dp->d_name) && dp->d_type != DT_UNKNOWN) {
872 DirItem * di = m_items + m_count;
874 auto slashPos = strchr(dp->d_name,
'/');
877 auto len = slashPos - dp->d_name;
878 strncpy(sname, dp->d_name, len);
887 bool isHidden = dp->d_name[0] ==
'.';
888 if (!isHidden || m_includeHiddenFiles) {
889 strcpy(sname, dp->d_name);
891 di->
isDir = (dp->d_type == DT_DIR);
892 sname += strlen(sname) + 1;
912 qsort(m_items, m_count,
sizeof(
DirItem), DirComp);
922 int dirnameLen = strlen(dirname);
923 if (dirnameLen > 0) {
926 char fullpath[strlen(m_dir) + 3 + 2 * dirnameLen + 1];
929 auto next = name + 1;
930 while (*next && *next !=
'\\' && *next !=
'/')
932 strcpy(fullpath, m_dir);
933 if (dirname != name) {
934 strcat(fullpath,
"/");
935 strncat(fullpath, dirname, name - dirname - 1);
937 strcat(fullpath,
"/");
938 strncat(fullpath, name, next - name);
939 strcat(fullpath,
"/.");
940 strncat(fullpath, name, next - name);
941 replacePathSep(fullpath,
'/');
942 FILE * f = fopen(fullpath,
"wb");
950 char fullpath[strlen(m_dir) + 1 + dirnameLen + 1];
951 sprintf(fullpath,
"%s/%s", m_dir, dirname);
952 replacePathSep(fullpath,
'/');
953 mkdir(fullpath, ACCESSPERMS);
964 char fullpath[strlen(m_dir) + 1 + strlen(name) + 1];
965 sprintf(fullpath,
"%s/%s", m_dir, name);
966 int r = unlink(fullpath);
978 char hidpath[strlen(m_dir) + 3 + 2 * strlen(name) + 1];
979 sprintf(hidpath,
"%s/%s/.%s", m_dir, name, name);
982 auto dirp = opendir(fullpath);
984 auto dp = readdir(dirp);
987 if (strcmp(
".", dp->d_name) && strcmp(
"..", dp->d_name) && dp->d_type != DT_UNKNOWN) {
988 char sfullpath[strlen(fullpath) + 1 + strlen(dp->d_name) + 1];
989 sprintf(sfullpath,
"%s/%s", fullpath, dp->d_name);
1002 char oldfullpath[strlen(m_dir) + 1 + strlen(oldName) + 1];
1003 sprintf(oldfullpath,
"%s/%s", m_dir, oldName);
1005 char newfullpath[strlen(m_dir) + 1 + strlen(newName) + 1];
1006 sprintf(newfullpath,
"%s/%s", m_dir, newName);
1008 ::rename(oldfullpath, newfullpath);
1015 constexpr
int FLEN = 6;
1016 auto ret = (
char*) malloc(strlen(m_dir) + 1 + FLEN + 4 + 1);
1018 char name[FLEN + 1] = { 0 };
1019 for (
int i = 0; i < FLEN; ++i)
1020 name[i] = 65 + (rand() % 26);
1021 sprintf(ret,
"%s/%s.TMP", m_dir, name);
1022 if (!
exists(name,
false))
1030 constexpr
size_t BUFLEN = 512;
1032 char fullpath[strlen(m_dir) + 1 + strlen(name) + 1];
1033 sprintf(fullpath,
"%s/%s", m_dir, name);
1038 bool retval =
false;
1042 if (::
rename(fullpath, tempFilename) == 0) {
1043 void * buf = malloc(BUFLEN);
1045 auto fr = fopen(tempFilename,
"rb");
1047 auto fw = fopen(fullpath,
"wb");
1051 auto l = fread(buf, 1, tmin(size, BUFLEN), fr);
1054 fwrite(buf, 1, l, fw);
1059 for (; size > 0; --size)
1069 unlink(tempFilename);
1080 return (outPath ? snprintf(outPath, maxlen,
"%s/%s", m_dir, name) : snprintf(
nullptr, 0,
"%s/%s", m_dir, name)) + 1;
1086 char fullpath[strlen(m_dir) + 1 + strlen(filename) + 1];
1087 strcpy(fullpath, m_dir);
1088 strcat(fullpath,
"/");
1089 strcat(fullpath, filename);
1091 replacePathSep(fullpath,
'/');
1093 return fopen(fullpath, mode);
1105 if (strncmp(path,
"/spiffs", 7) == 0 || (s_SPIFFSMounted && strncmp(path, s_SPIFFSMountPath, strlen(s_SPIFFSMountPath)) == 0)) {
1107 }
else if (s_SDCardMounted && strncmp(path, s_SDCardMountPath, strlen(s_SDCardMountPath)) == 0) {
1117 esp_task_wdt_init(45,
false);
1122 char drv[3] = {(char)(
'0' + drive),
':', 0};
1125 void * buffer = malloc(FF_MAX_SS);
1130 DWORD plist[] = { 100, 0, 0, 0 };
1131 if (f_fdisk(drive, plist, buffer) != FR_OK) {
1137 if (f_mkfs(drv, FM_ANY, 16 * 1024, buffer, FF_MAX_SS) != FR_OK) {
1151 bool r = (esp_spiffs_format(
nullptr) == ESP_OK);
1162 bool FileBrowser::mountSDCard(
bool formatOnFail,
char const * mountPath,
size_t maxFiles,
int allocationUnitSize,
int MISO,
int MOSI,
int CLK,
int CS)
1164 switch (getChipPackage()) {
1177 s_SDCardMountPath = mountPath;
1178 s_SDCardMaxFiles = maxFiles;
1179 s_SDCardAllocationUnitSize = allocationUnitSize;
1180 s_SDCardMISO = MISO;
1181 s_SDCardMOSI = MOSI;
1185 sdmmc_host_t host = SDSPI_HOST_DEFAULT();
1186 sdspi_slot_config_t slot_config = SDSPI_SLOT_CONFIG_DEFAULT();
1187 slot_config.gpio_miso = int2gpio(MISO);
1188 slot_config.gpio_mosi = int2gpio(MOSI);
1189 slot_config.gpio_sck = int2gpio(CLK);
1190 slot_config.gpio_cs = int2gpio(CS);
1191 esp_vfs_fat_sdmmc_mount_config_t mount_config;
1192 mount_config.format_if_mount_failed = formatOnFail;
1193 mount_config.max_files = maxFiles;
1194 mount_config.allocation_unit_size = allocationUnitSize;
1196 s_SDCardMounted = (esp_vfs_fat_sdmmc_mount(mountPath, &host, &slot_config, &mount_config, &card) == ESP_OK);
1197 return s_SDCardMounted;
1203 if (s_SDCardMounted) {
1204 esp_vfs_fat_sdmmc_unmount();
1205 s_SDCardMounted =
false;
1213 return mountSDCard(
false, s_SDCardMountPath, s_SDCardMaxFiles, s_SDCardAllocationUnitSize, s_SDCardMISO, s_SDCardMOSI, s_SDCardCLK, s_SDCardCS);
1219 s_SPIFFSMountPath = mountPath;
1220 s_SPIFFSMaxFiles = maxFiles;
1221 esp_vfs_spiffs_conf_t conf = {
1222 .base_path = mountPath,
1223 .partition_label =
nullptr,
1224 .max_files = maxFiles,
1225 .format_if_mount_failed =
true 1227 s_SPIFFSMounted = (esp_vfs_spiffs_register(&conf) == ESP_OK);
1228 return s_SPIFFSMounted;
1234 if (s_SPIFFSMounted) {
1235 esp_vfs_spiffs_unregister(
nullptr);
1236 s_SPIFFSMounted =
false;
1244 return mountSPIFFS(
false, s_SPIFFSMountPath, s_SPIFFSMaxFiles);
1255 DWORD free_clusters;
1256 char drv[3] = {(char)(
'0' + drive),
':', 0};
1257 if (f_getfree(drv, &free_clusters, &fs) != FR_OK)
1259 int64_t total_sectors = (fs->n_fatent - 2) * fs->csize;
1260 int64_t free_sectors = free_clusters * fs->csize;
1261 *total = total_sectors * fs->ssize;
1262 *used = *total - free_sectors * fs->ssize;
1268 size_t stotal = 0, sused = 0;
1269 if (esp_spiffs_info(NULL, &stotal, &sused) != ESP_OK)
1290 void LightMemoryPool::mark(
int pos, int16_t size,
bool allocated)
1292 m_mem[pos] = size & 0xff;
1293 m_mem[pos + 1] = ((size >> 8) & 0x7f) | (allocated ? 0x80 : 0);
1297 int16_t LightMemoryPool::getSize(
int pos)
1299 return m_mem[pos] | ((m_mem[pos + 1] & 0x7f) << 8);
1303 bool LightMemoryPool::isFree(
int pos)
1305 return (m_mem[pos + 1] & 0x80) == 0;
1309 LightMemoryPool::LightMemoryPool(
int poolSize)
1311 m_poolSize = poolSize + 2;
1312 m_mem = (uint8_t*) heap_caps_malloc(m_poolSize, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
1313 mark(0, m_poolSize - 2,
false);
1317 LightMemoryPool::~LightMemoryPool()
1319 heap_caps_free(m_mem);
1323 void * LightMemoryPool::alloc(
int size)
1325 for (
int pos = 0; pos < m_poolSize; ) {
1326 int16_t blockSize = getSize(pos);
1328 if (blockSize == size) {
1330 mark(pos, size,
true);
1331 return m_mem + pos + 2;
1332 }
else if (blockSize > size) {
1334 int remainingSize = blockSize - size - 2;
1335 if (remainingSize > 0)
1336 mark(pos + 2 + size, remainingSize,
false);
1339 mark(pos, size,
true);
1340 return m_mem + pos + 2;
1344 int nextBlockPos = pos + 2 + blockSize;
1345 if (nextBlockPos < m_poolSize && isFree(nextBlockPos)) {
1347 mark(pos, blockSize + getSize(nextBlockPos) + 2,
false);
1350 pos += blockSize + 2;
1355 pos += blockSize + 2;
1362 bool LightMemoryPool::memCheck()
1365 while (pos < m_poolSize) {
1366 int16_t blockSize = getSize(pos);
1367 pos += blockSize + 2;
1369 return pos == m_poolSize;
1373 int LightMemoryPool::totFree()
1376 for (
int pos = 0; pos < m_poolSize; ) {
1377 int16_t blockSize = getSize(pos);
1380 pos += blockSize + 2;
1386 int LightMemoryPool::totAllocated()
1389 for (
int pos = 0; pos < m_poolSize; ) {
1390 int16_t blockSize = getSize(pos);
1393 pos += blockSize + 2;
1399 int LightMemoryPool::largestFree()
1402 for (
int pos = 0; pos < m_poolSize; ) {
1403 int16_t blockSize = getSize(pos);
1404 if (isFree(pos) && blockSize > r)
1406 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.
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)