Skip to content

Commit e8aa2bd

Browse files
authored
Merge pull request #399 from MicroPythonOS/add-directory-support-to-fs_driver
Add directory support to fs_driver. That means the file explorer in LVGL will now work properly!!!
2 parents e6f39b0 + ec19858 commit e8aa2bd

File tree

2 files changed

+50
-5
lines changed

2 files changed

+50
-5
lines changed

api_drivers/py_api_drivers/fs_driver.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,41 @@ def _fs_write_cb(drv, fs_file, buf, btw, bw):
7474

7575
return lv.FS_RES.OK
7676

77+
def _fs_dir_open_cb(drv, path):
78+
#print(f"_fs_dir_open_cb for path '{path}'")
79+
try:
80+
import os # for ilistdir()
81+
return {'iterator' : os.ilistdir(path)}
82+
except Exception as e:
83+
print(f"_fs_dir_open_cb exception: {e}")
84+
return None
85+
86+
def _fs_dir_read_cb(drv, lv_fs_dir_t, buf, btr):
87+
try:
88+
iterator = lv_fs_dir_t.__cast__()['iterator']
89+
nextfile = iterator.__next__()
90+
#print(f"nextfile: {nextfile}")
91+
filename = nextfile[0]
92+
entry_type = nextfile[1] # Type field
93+
if entry_type == 0x4000:
94+
#print(f"{filename} is a directory")
95+
filename = f"/{filename}"
96+
# Convert filename to bytes with null terminator
97+
tmp_data_bytes = filename.encode() + b'\x00'
98+
buf.__dereference__(btr)[0:len(tmp_data_bytes)] = tmp_data_bytes
99+
return lv.FS_RES.OK
100+
except StopIteration:
101+
# Clear buffer and return FS_ERR when iteration ends
102+
buf.__dereference__(btr)[0:1] = b'\x00' # Empty string (null byte)
103+
return lv.FS_RES.NOT_EX # Next entry "does not exist"
104+
except Exception as e:
105+
print(f"_fs_dir_read_cb exception: {e}")
106+
return lv.FS_RES.UNKNOWN
107+
108+
def _fs_dir_close_cb(drv, lv_fs_dir_t):
109+
#print(f"_fs_dir_close_cb called")
110+
# No need to cleanup the iterator so nothing to do
111+
return lv.FS_RES.OK
77112

78113
def fs_register(fs_drv, letter, cache_size=500):
79114

@@ -85,6 +120,9 @@ def fs_register(fs_drv, letter, cache_size=500):
85120
fs_drv.seek_cb = _fs_seek_cb
86121
fs_drv.tell_cb = _fs_tell_cb
87122
fs_drv.close_cb = _fs_close_cb
123+
fs_drv.dir_open_cb = _fs_dir_open_cb
124+
fs_drv.dir_read_cb = _fs_dir_read_cb
125+
#fs_drv.dir_close_cb = _fs_dir_close_cb
88126

89127
if cache_size >= 0:
90128
fs_drv.cache_size = cache_size

gen/python_api_gen_mpy.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2865,12 +2865,18 @@ def create_helper_struct(struct_str):
28652865

28662866

28672867
def build_callback_func_arg(arg, index, func, func_name = None):
2868-
arg_type = get_type(arg.type, remove_quals = True)
2868+
arg_type = get_type(arg.type, remove_quals = False)
28692869
cast = '(void*)' if isinstance(arg.type, c_ast.PtrDecl) else '' # needed when field is const. casting to void overrides it
2870-
if arg_type not in lv_to_mp or not lv_to_mp[arg_type]:
2871-
try_generate_type(arg.type)
2870+
2871+
if arg_type == 'char *':
2872+
converter = 'ptr_to_mp'
2873+
else:
2874+
arg_type = get_type(arg.type, remove_quals = True)
28722875
if arg_type not in lv_to_mp or not lv_to_mp[arg_type]:
2873-
raise MissingConversionException("Callback: Missing conversion to %s" % arg_type)
2876+
try_generate_type(arg.type)
2877+
if arg_type not in lv_to_mp or not lv_to_mp[arg_type]:
2878+
raise MissingConversionException("Callback: Missing conversion to %s" % arg_type)
2879+
converter = lv_to_mp[arg_type]
28742880

28752881
arg_metadata = {'c_type': arg_type, 'py_type': get_py_type(arg_type)}
28762882

@@ -2880,8 +2886,9 @@ def build_callback_func_arg(arg, index, func, func_name = None):
28802886
arg_metadata['name'] = None
28812887

28822888
callback_metadata[func_name]['args'].append(arg_metadata)
2889+
28832890
return 'mp_args[{i}] = {convertor}({cast}arg{i});'.format(
2884-
convertor = lv_to_mp[arg_type],
2891+
convertor = converter,
28852892
i = index, cast = cast)
28862893

28872894

0 commit comments

Comments
 (0)