From 4909b7075b9474c70a6e97a1ef180c0d65169fcd Mon Sep 17 00:00:00 2001 From: Ken Van Hoeylandt Date: Sun, 21 Jun 2026 18:14:08 +0200 Subject: [PATCH] WIP --- .../source/binding_parser.py | 1 + .../DevicetreeCompiler/source/generator.py | 80 ++++++++++++++----- .../DevicetreeCompiler/source/models.py | 1 + Devices/cyd-2432s024c/cyd,2432s024c.dts | 3 +- Devices/cyd-2432s024r/cyd,2432s024r.dts | 3 +- Devices/cyd-2432s028r/cyd,2432s028r.dts | 3 +- Devices/cyd-2432s028rv3/cyd,2432s028rv3.dts | 3 +- Devices/cyd-2432s032c/cyd,2432s032c.dts | 3 +- Devices/cyd-3248s035c/cyd,3248s035c.dts | 3 +- Devices/cyd-4848s040c/cyd,4848s040c.dts | 3 +- Devices/cyd-8048s043c/cyd,8048s043c.dts | 3 +- Devices/cyd-e32r28t/cyd,e32r28t.dts | 3 +- Devices/cyd-e32r32p/cyd,e32r32p.dts | 3 +- .../elecrow,crowpanel-advance-28.dts | 3 +- .../elecrow,crowpanel-advance-35.dts | 3 +- .../elecrow,crowpanel-advance-50.dts | 3 +- .../elecrow,crowpanel-basic-28.dts | 3 +- .../elecrow,crowpanel-basic-35.dts | 3 +- .../elecrow,crowpanel-basic-50.dts | 3 +- .../guition,jc2432w328c.dts | 3 +- .../guition,jc3248w535c.dts | 5 +- .../guition,jc8048w550c.dts | 3 +- Devices/lilygo-tdeck/Source/Init.cpp | 1 - Devices/lilygo-tdeck/lilygo,tdeck.dts | 4 +- Devices/lilygo-thmi/lilygo,thmi.dts | 2 + .../lilygo-tlora-pager/lilygo,tlora-pager.dts | 1 - .../m5stack,cardputer-adv.dts | 3 +- .../m5stack-cardputer/m5stack,cardputer.dts | 3 +- Devices/m5stack-core2/m5stack,core2.dts | 1 - Devices/m5stack-cores3/m5stack,cores3.dts | 1 - Devices/m5stack-papers3/m5stack,papers3.dts | 3 +- .../m5stack-stackchan/m5stack,stackchan.dts | 1 - Devices/m5stack-sticks3/m5stack,sticks3.dts | 3 +- Devices/unphone/unphone.dts | 3 +- .../waveshare,s3-lcd-13.dts | 3 +- .../waveshare,s3-touch-lcd-128.dts | 3 +- .../waveshare,s3-touch-lcd-147.dts | 5 +- .../waveshare,s3-touch-lcd-43.dts | 3 +- .../wireless-tag,wt32-sc01-plus.dts | 3 +- .../bindings/espressif,esp32-grove.yaml | 4 +- .../bindings/espressif,esp32-i2c-master.yaml | 4 +- .../bindings/espressif,esp32-i2c.yaml | 4 +- .../bindings/espressif,esp32-i2s.yaml | 10 +-- .../bindings/espressif,esp32-sdmmc.yaml | 24 +++--- .../bindings/espressif,esp32-sdspi.yaml | 10 +-- .../bindings/espressif,esp32-spi.yaml | 13 +-- .../bindings/espressif,esp32-uart.yaml | 8 +- .../include/tactility/drivers/esp32_sdspi.h | 1 - .../include/tactility/drivers/esp32_spi.h | 23 +++++- .../tactility/drivers/esp32_sdspi_fs.h | 2 +- .../source/drivers/bluetooth/esp32_ble.cpp | 2 +- .../source/drivers/esp32_i2c.cpp | 3 +- .../source/drivers/esp32_sdspi.cpp | 22 ++++- .../source/drivers/esp32_sdspi_fs.cpp | 10 ++- .../source/drivers/esp32_spi.cpp | 38 +++++++-- TactilityKernel/bindings/spi-peripheral.yaml | 8 +- .../tactility/drivers/spi_peripheral.h | 10 +-- TactilityKernel/include/tactility/error.h | 1 + .../source/drivers/spi_peripheral.cpp | 55 +------------ 59 files changed, 227 insertions(+), 209 deletions(-) diff --git a/Buildscripts/DevicetreeCompiler/source/binding_parser.py b/Buildscripts/DevicetreeCompiler/source/binding_parser.py index 2b4889431..538d3c06d 100644 --- a/Buildscripts/DevicetreeCompiler/source/binding_parser.py +++ b/Buildscripts/DevicetreeCompiler/source/binding_parser.py @@ -45,6 +45,7 @@ def parse_binding(file_path: str, binding_dirs: list[str]) -> Binding: required=details.get('required', False), description=details.get('description', '').strip(), default=details.get('default', None), + element_type=details.get('element-type', None), ) properties_dict[name] = prop filename = os.path.basename(file_path) diff --git a/Buildscripts/DevicetreeCompiler/source/generator.py b/Buildscripts/DevicetreeCompiler/source/generator.py index d372357bc..7980f31ce 100644 --- a/Buildscripts/DevicetreeCompiler/source/generator.py +++ b/Buildscripts/DevicetreeCompiler/source/generator.py @@ -20,10 +20,8 @@ def write_define(file, define: DefineC, verbose: bool): def get_device_node_name_safe(device: Device): if device.node_name == "/": return "root" - name = device.node_name.replace("-", "_") - if device.node_address is not None: - name += "_" + device.node_address.replace("-", "_") - return name + else: + return device.node_name.replace("-", "_") def get_device_type_name(device: Device, bindings: list[Binding]): device_binding = find_device_binding(device, bindings) @@ -82,7 +80,7 @@ def property_to_string(property: DeviceProperty, devices: list[Device]) -> str: return "{ " + ",".join(value_list) + " }" elif type == "phandle": return find_phandle(devices, property.value) - elif type == "phandle-array": + elif type == "phandles": value_list = list() if isinstance(property.value, list): for item in property.value: @@ -90,16 +88,31 @@ def property_to_string(property: DeviceProperty, devices: list[Device]) -> str: value_list.append(property_to_string(DeviceProperty(name="", type=item.type, value=item.value), devices)) else: value_list.append(str(item)) - value_list.append("{ 0 }") return "{ " + ",".join(value_list) + " }" elif isinstance(property.value, str): # If it's a string, assume it's a #define and show it as-is return property.value else: - raise Exception(f"Unsupported phandle-array type for {property.value}") + raise Exception(f"Unsupported phandles type for {property.name} with value {property.value} ") else: raise DevicetreeException(f"property_to_string() has an unsupported type: {type}") +def resolve_phandle_array_entries(device_property, devices): + """Convert a phandle-array DTS property into a list of C initializer strings.""" + entries = [] + if device_property.type == "phandle-array": + items = device_property.value + elif device_property.type == "values": + items = [PropertyValue(type="values", value=device_property.value)] + else: + return [] + for item in items: + if isinstance(item, PropertyValue): + entries.append(property_to_string(DeviceProperty(name="", type=item.type, value=item.value), devices)) + else: + entries.append(str(item)) + return entries + def resolve_parameters_from_bindings(device: Device, bindings: list[Binding], devices: list[Device]) -> list: compatible_property = find_device_property(device, "compatible") if compatible_property is None: @@ -122,11 +135,32 @@ def resolve_parameters_from_bindings(device: Device, bindings: list[Binding], de if device_property.name not in binding_property_names: raise DevicetreeException(f"Device '{device.node_name}' has invalid property '{device_property.name}'") - # Allocate total expected configuration arguments - result = [0] * len(binding_properties) - for index, binding_property in enumerate(binding_properties): + node_name = get_device_node_name_safe(device) + result = [] + phandle_arrays = [] + for binding_property in binding_properties: device_property = find_device_property(device, binding_property.name) - # No property specified in DTS, use binding defaults + + if binding_property.type == "phandle-array": + if binding_property.element_type is None: + raise DevicetreeException(f"phandle-array property '{binding_property.name}' requires 'element-type' in binding") + prop_safe = binding_property.name.replace("-", "_") + array_var = f"{node_name}_{prop_safe}" + if device_property is not None: + entries = resolve_phandle_array_entries(device_property, devices) + phandle_arrays.append((array_var, binding_property.element_type, entries)) + result.append(f"({binding_property.element_type}*){array_var}") + result.append(str(len(entries))) + elif binding_property.default is not None: + result.append("NULL") + result.append("0") + elif binding_property.required: + raise DevicetreeException(f"device {device.node_name} doesn't have property '{binding_property.name}'") + else: + result.append("NULL") + result.append("0") + continue + if device_property is None: if binding_property.default is not None: temp_prop = DeviceProperty( @@ -134,30 +168,38 @@ def resolve_parameters_from_bindings(device: Device, bindings: list[Binding], de type=binding_property.type, value=binding_property.default ) - result[index] = property_to_string(temp_prop, devices) + result.append(property_to_string(temp_prop, devices)) elif binding_property.required: raise DevicetreeException(f"device {device.node_name} doesn't have property '{binding_property.name}'") elif binding_property.type == "bool" or binding_property.type == "boolean": if binding_property.default == "true" or binding_property.default == None: - result[index] = "true" - else: # Explicit or implied false - result[index] = "false" + result.append("true") + else: + result.append("false") else: raise DevicetreeException(f"Device {device.node_name} doesn't have property '{binding_property.name}' and no default value is set") else: - result[index] = property_to_string(device_property, devices) - return result + result.append(property_to_string(device_property, devices)) + + return result, phandle_arrays def write_config(file, device: Device, bindings: list[Binding], devices: list[Device], type_name: str): node_name = get_device_node_name_safe(device) config_type = f"{type_name}_config_dt" config_variable_name = f"{node_name}_config" + + config_params, phandle_arrays = resolve_parameters_from_bindings(device, bindings, devices) + + # Write phandle-array variables before the config struct + for array_var, element_type, entries in phandle_arrays: + entries_str = ", ".join(entries) + file.write(f"static {element_type} {array_var}[] = {{ {entries_str} }};\n") + file.write(f"static const {config_type} {config_variable_name}" " = {\n") - config_params = resolve_parameters_from_bindings(device, bindings, devices) # Indent all params for index, config_param in enumerate(config_params): config_params[index] = f"\t{config_param}" - # Join with command and newline + # Join with comma and newline if len(config_params) > 0: config_params_joined = ",\n".join(config_params) file.write(f"{config_params_joined}\n") diff --git a/Buildscripts/DevicetreeCompiler/source/models.py b/Buildscripts/DevicetreeCompiler/source/models.py index 761d25caf..e1b8aeabd 100644 --- a/Buildscripts/DevicetreeCompiler/source/models.py +++ b/Buildscripts/DevicetreeCompiler/source/models.py @@ -39,6 +39,7 @@ class BindingProperty: required: bool description: str default: object = None + element_type: str = None @dataclass class Binding: diff --git a/Devices/cyd-2432s024c/cyd,2432s024c.dts b/Devices/cyd-2432s024c/cyd,2432s024c.dts index d9d390de9..621aaca5d 100644 --- a/Devices/cyd-2432s024c/cyd,2432s024c.dts +++ b/Devices/cyd-2432s024c/cyd,2432s024c.dts @@ -44,9 +44,8 @@ pin-miso = <&gpio0 19 GPIO_FLAG_NONE>; pin-sclk = <&gpio0 18 GPIO_FLAG_NONE>; - sdcard { + sdcard@0 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 5 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; }; diff --git a/Devices/cyd-2432s024r/cyd,2432s024r.dts b/Devices/cyd-2432s024r/cyd,2432s024r.dts index 5ae5207bc..db1aaed33 100644 --- a/Devices/cyd-2432s024r/cyd,2432s024r.dts +++ b/Devices/cyd-2432s024r/cyd,2432s024r.dts @@ -43,9 +43,8 @@ pin-sclk = <&gpio0 18 GPIO_FLAG_NONE>; cs-gpios = <&gpio0 5 GPIO_FLAG_NONE>; - sdcard { + sdcard@0 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 5 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; }; diff --git a/Devices/cyd-2432s028r/cyd,2432s028r.dts b/Devices/cyd-2432s028r/cyd,2432s028r.dts index 41f635429..8d27feee2 100644 --- a/Devices/cyd-2432s028r/cyd,2432s028r.dts +++ b/Devices/cyd-2432s028r/cyd,2432s028r.dts @@ -52,9 +52,8 @@ pin-sclk = <&gpio0 18 GPIO_FLAG_NONE>; cs-gpios = <&gpio0 5 GPIO_FLAG_NONE>; - sdcard { + sdcard@0 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 5 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; }; diff --git a/Devices/cyd-2432s028rv3/cyd,2432s028rv3.dts b/Devices/cyd-2432s028rv3/cyd,2432s028rv3.dts index 97ab5a6ec..492dba5cb 100644 --- a/Devices/cyd-2432s028rv3/cyd,2432s028rv3.dts +++ b/Devices/cyd-2432s028rv3/cyd,2432s028rv3.dts @@ -52,9 +52,8 @@ pin-miso = <&gpio0 19 GPIO_FLAG_NONE>; pin-sclk = <&gpio0 18 GPIO_FLAG_NONE>; - sdcard { + sdcard@0 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 5 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; }; diff --git a/Devices/cyd-2432s032c/cyd,2432s032c.dts b/Devices/cyd-2432s032c/cyd,2432s032c.dts index 0f7cf44cb..bd0f62bfd 100644 --- a/Devices/cyd-2432s032c/cyd,2432s032c.dts +++ b/Devices/cyd-2432s032c/cyd,2432s032c.dts @@ -44,9 +44,8 @@ pin-miso = <&gpio0 19 GPIO_FLAG_NONE>; pin-sclk = <&gpio0 18 GPIO_FLAG_NONE>; - sdcard { + sdcard@0 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 5 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; }; diff --git a/Devices/cyd-3248s035c/cyd,3248s035c.dts b/Devices/cyd-3248s035c/cyd,3248s035c.dts index f02d78794..2f71a5cf5 100644 --- a/Devices/cyd-3248s035c/cyd,3248s035c.dts +++ b/Devices/cyd-3248s035c/cyd,3248s035c.dts @@ -54,9 +54,8 @@ pin-miso = <&gpio0 19 GPIO_FLAG_NONE>; pin-sclk = <&gpio0 18 GPIO_FLAG_NONE>; - sdcard { + sdcard@0 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 5 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; }; diff --git a/Devices/cyd-4848s040c/cyd,4848s040c.dts b/Devices/cyd-4848s040c/cyd,4848s040c.dts index e3649e7c7..fa6cd8baf 100644 --- a/Devices/cyd-4848s040c/cyd,4848s040c.dts +++ b/Devices/cyd-4848s040c/cyd,4848s040c.dts @@ -36,9 +36,8 @@ pin-miso = <&gpio0 41 GPIO_FLAG_NONE>; pin-sclk = <&gpio0 48 GPIO_FLAG_NONE>; - sdcard { + sdcard@0 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 42 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; }; diff --git a/Devices/cyd-8048s043c/cyd,8048s043c.dts b/Devices/cyd-8048s043c/cyd,8048s043c.dts index 63e93d34a..730eb9884 100644 --- a/Devices/cyd-8048s043c/cyd,8048s043c.dts +++ b/Devices/cyd-8048s043c/cyd,8048s043c.dts @@ -45,9 +45,8 @@ pin-miso = <&gpio0 13 GPIO_FLAG_NONE>; pin-sclk = <&gpio0 12 GPIO_FLAG_NONE>; - sdcard { + sdcard@0 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 10 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; }; diff --git a/Devices/cyd-e32r28t/cyd,e32r28t.dts b/Devices/cyd-e32r28t/cyd,e32r28t.dts index 942205083..be36a8dac 100644 --- a/Devices/cyd-e32r28t/cyd,e32r28t.dts +++ b/Devices/cyd-e32r28t/cyd,e32r28t.dts @@ -42,9 +42,8 @@ pin-miso = <&gpio0 19 GPIO_FLAG_NONE>; pin-sclk = <&gpio0 18 GPIO_FLAG_NONE>; - sdcard { + sdcard@0 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 5 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; }; diff --git a/Devices/cyd-e32r32p/cyd,e32r32p.dts b/Devices/cyd-e32r32p/cyd,e32r32p.dts index 383c8d879..af6ade973 100644 --- a/Devices/cyd-e32r32p/cyd,e32r32p.dts +++ b/Devices/cyd-e32r32p/cyd,e32r32p.dts @@ -51,9 +51,8 @@ pin-miso = <&gpio0 19 GPIO_FLAG_NONE>; pin-sclk = <&gpio0 18 GPIO_FLAG_NONE>; - sdcard { + sdcard@0 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 5 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; }; diff --git a/Devices/elecrow-crowpanel-advance-28/elecrow,crowpanel-advance-28.dts b/Devices/elecrow-crowpanel-advance-28/elecrow,crowpanel-advance-28.dts index 166075d3d..6388a74e9 100644 --- a/Devices/elecrow-crowpanel-advance-28/elecrow,crowpanel-advance-28.dts +++ b/Devices/elecrow-crowpanel-advance-28/elecrow,crowpanel-advance-28.dts @@ -50,9 +50,8 @@ pin-miso = <&gpio0 4 GPIO_FLAG_NONE>; pin-sclk = <&gpio0 5 GPIO_FLAG_NONE>; - sdcard { + sdcard@0 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 7 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; }; diff --git a/Devices/elecrow-crowpanel-advance-35/elecrow,crowpanel-advance-35.dts b/Devices/elecrow-crowpanel-advance-35/elecrow,crowpanel-advance-35.dts index 314594ed8..ba9055274 100644 --- a/Devices/elecrow-crowpanel-advance-35/elecrow,crowpanel-advance-35.dts +++ b/Devices/elecrow-crowpanel-advance-35/elecrow,crowpanel-advance-35.dts @@ -50,9 +50,8 @@ pin-miso = <&gpio0 4 GPIO_FLAG_NONE>; pin-sclk = <&gpio0 5 GPIO_FLAG_NONE>; - sdcard { + sdcard@0 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 7 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; }; diff --git a/Devices/elecrow-crowpanel-advance-50/elecrow,crowpanel-advance-50.dts b/Devices/elecrow-crowpanel-advance-50/elecrow,crowpanel-advance-50.dts index f6e536231..331297d1d 100644 --- a/Devices/elecrow-crowpanel-advance-50/elecrow,crowpanel-advance-50.dts +++ b/Devices/elecrow-crowpanel-advance-50/elecrow,crowpanel-advance-50.dts @@ -37,9 +37,8 @@ pin-miso = <&gpio0 4 GPIO_FLAG_NONE>; pin-sclk = <&gpio0 5 GPIO_FLAG_NONE>; - sdcard { + sdcard@0 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 0 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; }; diff --git a/Devices/elecrow-crowpanel-basic-28/elecrow,crowpanel-basic-28.dts b/Devices/elecrow-crowpanel-basic-28/elecrow,crowpanel-basic-28.dts index dc95198b9..8ed72e950 100644 --- a/Devices/elecrow-crowpanel-basic-28/elecrow,crowpanel-basic-28.dts +++ b/Devices/elecrow-crowpanel-basic-28/elecrow,crowpanel-basic-28.dts @@ -53,9 +53,8 @@ pin-miso = <&gpio0 19 GPIO_FLAG_NONE>; pin-sclk = <&gpio0 18 GPIO_FLAG_NONE>; - sdcard { + sdcard@0 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 5 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; }; diff --git a/Devices/elecrow-crowpanel-basic-35/elecrow,crowpanel-basic-35.dts b/Devices/elecrow-crowpanel-basic-35/elecrow,crowpanel-basic-35.dts index 11cf4f456..dfd3d36e3 100644 --- a/Devices/elecrow-crowpanel-basic-35/elecrow,crowpanel-basic-35.dts +++ b/Devices/elecrow-crowpanel-basic-35/elecrow,crowpanel-basic-35.dts @@ -53,9 +53,8 @@ pin-miso = <&gpio0 19 GPIO_FLAG_NONE>; pin-sclk = <&gpio0 18 GPIO_FLAG_NONE>; - sdcard { + sdcard@0 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 5 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; }; diff --git a/Devices/elecrow-crowpanel-basic-50/elecrow,crowpanel-basic-50.dts b/Devices/elecrow-crowpanel-basic-50/elecrow,crowpanel-basic-50.dts index 2f8106745..9ce72f33f 100644 --- a/Devices/elecrow-crowpanel-basic-50/elecrow,crowpanel-basic-50.dts +++ b/Devices/elecrow-crowpanel-basic-50/elecrow,crowpanel-basic-50.dts @@ -37,9 +37,8 @@ pin-miso = <&gpio0 13 GPIO_FLAG_NONE>; pin-sclk = <&gpio0 12 GPIO_FLAG_NONE>; - sdcard { + sdcard@0 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 10 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; }; diff --git a/Devices/guition-jc2432w328c/guition,jc2432w328c.dts b/Devices/guition-jc2432w328c/guition,jc2432w328c.dts index c96a6a8f7..2b7c7ac99 100644 --- a/Devices/guition-jc2432w328c/guition,jc2432w328c.dts +++ b/Devices/guition-jc2432w328c/guition,jc2432w328c.dts @@ -54,9 +54,8 @@ pin-miso = <&gpio0 19 GPIO_FLAG_NONE>; pin-sclk = <&gpio0 18 GPIO_FLAG_NONE>; - sdcard { + sdcard@0 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 5 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; }; diff --git a/Devices/guition-jc3248w535c/guition,jc3248w535c.dts b/Devices/guition-jc3248w535c/guition,jc3248w535c.dts index 13a14ef43..f2d9542e3 100644 --- a/Devices/guition-jc3248w535c/guition,jc3248w535c.dts +++ b/Devices/guition-jc3248w535c/guition,jc3248w535c.dts @@ -8,6 +8,7 @@ #include #include #include +#include / { compatible = "root"; @@ -64,13 +65,13 @@ spi1 { compatible = "espressif,esp32-spi"; host = ; + cs-gpios = <&gpio0 10 GPIO_FLAG_NONE>; pin-mosi = <&gpio0 11 GPIO_FLAG_NONE>; pin-miso = <&gpio0 13 GPIO_FLAG_NONE>; pin-sclk = <&gpio0 12 GPIO_FLAG_NONE>; - sdcard { + sdcard@0 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 10 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; }; diff --git a/Devices/guition-jc8048w550c/guition,jc8048w550c.dts b/Devices/guition-jc8048w550c/guition,jc8048w550c.dts index dba67451e..31840e3dd 100644 --- a/Devices/guition-jc8048w550c/guition,jc8048w550c.dts +++ b/Devices/guition-jc8048w550c/guition,jc8048w550c.dts @@ -55,9 +55,8 @@ pin-miso = <&gpio0 13 GPIO_FLAG_NONE>; pin-sclk = <&gpio0 12 GPIO_FLAG_NONE>; - sdcard { + sdcard@0 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 10 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; }; diff --git a/Devices/lilygo-tdeck/Source/Init.cpp b/Devices/lilygo-tdeck/Source/Init.cpp index b0635dbe5..14386e363 100644 --- a/Devices/lilygo-tdeck/Source/Init.cpp +++ b/Devices/lilygo-tdeck/Source/Init.cpp @@ -11,7 +11,6 @@ static const auto LOGGER = tt::Logger("T-Deck"); -// Power on constexpr auto TDECK_POWERON_GPIO = GPIO_NUM_10; static bool powerOn() { diff --git a/Devices/lilygo-tdeck/lilygo,tdeck.dts b/Devices/lilygo-tdeck/lilygo,tdeck.dts index 331a7e99d..e5448ee00 100644 --- a/Devices/lilygo-tdeck/lilygo,tdeck.dts +++ b/Devices/lilygo-tdeck/lilygo,tdeck.dts @@ -45,6 +45,7 @@ compatible = "espressif,esp32-spi"; host = ; cs-gpios = <&gpio0 12 GPIO_FLAG_NONE>, // Display + <&gpio0 9 GPIO_FLAG_NONE>, // Radio <&gpio0 39 GPIO_FLAG_NONE>; // SD card pin-mosi = <&gpio0 41 GPIO_FLAG_NONE>; pin-miso = <&gpio0 38 GPIO_FLAG_NONE>; @@ -54,9 +55,8 @@ compatible = "display-placeholder"; }; - sdcard@1 { + sdcard@2 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 39 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; }; diff --git a/Devices/lilygo-thmi/lilygo,thmi.dts b/Devices/lilygo-thmi/lilygo,thmi.dts index 93e080900..256f06973 100644 --- a/Devices/lilygo-thmi/lilygo,thmi.dts +++ b/Devices/lilygo-thmi/lilygo,thmi.dts @@ -6,6 +6,8 @@ #include #include #include +#include +#include / { compatible = "root"; diff --git a/Devices/lilygo-tlora-pager/lilygo,tlora-pager.dts b/Devices/lilygo-tlora-pager/lilygo,tlora-pager.dts index d6b38f7ec..b72631095 100644 --- a/Devices/lilygo-tlora-pager/lilygo,tlora-pager.dts +++ b/Devices/lilygo-tlora-pager/lilygo,tlora-pager.dts @@ -43,7 +43,6 @@ sdcard@0 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 21 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; diff --git a/Devices/m5stack-cardputer-adv/m5stack,cardputer-adv.dts b/Devices/m5stack-cardputer-adv/m5stack,cardputer-adv.dts index a004ab1e9..7d82145e2 100644 --- a/Devices/m5stack-cardputer-adv/m5stack,cardputer-adv.dts +++ b/Devices/m5stack-cardputer-adv/m5stack,cardputer-adv.dts @@ -69,9 +69,8 @@ pin-miso = <&gpio0 39 GPIO_FLAG_NONE>; pin-sclk = <&gpio0 40 GPIO_FLAG_NONE>; - sdcard { + sdcard@0 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 12 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; }; diff --git a/Devices/m5stack-cardputer/m5stack,cardputer.dts b/Devices/m5stack-cardputer/m5stack,cardputer.dts index f652eb60a..024db4d38 100644 --- a/Devices/m5stack-cardputer/m5stack,cardputer.dts +++ b/Devices/m5stack-cardputer/m5stack,cardputer.dts @@ -55,9 +55,8 @@ pin-miso = <&gpio0 39 GPIO_FLAG_NONE>; pin-sclk = <&gpio0 40 GPIO_FLAG_NONE>; - sdcard { + sdcard@0 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 12 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; }; diff --git a/Devices/m5stack-core2/m5stack,core2.dts b/Devices/m5stack-core2/m5stack,core2.dts index 0269b04dc..95c6c13b9 100644 --- a/Devices/m5stack-core2/m5stack,core2.dts +++ b/Devices/m5stack-core2/m5stack,core2.dts @@ -61,7 +61,6 @@ sdcard@0 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 4 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; diff --git a/Devices/m5stack-cores3/m5stack,cores3.dts b/Devices/m5stack-cores3/m5stack,cores3.dts index c6eba128b..c9057f907 100644 --- a/Devices/m5stack-cores3/m5stack,cores3.dts +++ b/Devices/m5stack-cores3/m5stack,cores3.dts @@ -86,7 +86,6 @@ sdcard@0 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 4 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; diff --git a/Devices/m5stack-papers3/m5stack,papers3.dts b/Devices/m5stack-papers3/m5stack,papers3.dts index 3a3afde9e..6ff6dcd3c 100644 --- a/Devices/m5stack-papers3/m5stack,papers3.dts +++ b/Devices/m5stack-papers3/m5stack,papers3.dts @@ -49,9 +49,8 @@ pin-sclk = <&gpio0 39 GPIO_FLAG_NONE>; max-transfer-size = <4096>; - sdcard { + sdcard@0 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 47 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; }; diff --git a/Devices/m5stack-stackchan/m5stack,stackchan.dts b/Devices/m5stack-stackchan/m5stack,stackchan.dts index b81830f65..b20828af4 100644 --- a/Devices/m5stack-stackchan/m5stack,stackchan.dts +++ b/Devices/m5stack-stackchan/m5stack,stackchan.dts @@ -120,7 +120,6 @@ sdcard@0 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 4 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; diff --git a/Devices/m5stack-sticks3/m5stack,sticks3.dts b/Devices/m5stack-sticks3/m5stack,sticks3.dts index 14a3b34a4..3b73d85b9 100644 --- a/Devices/m5stack-sticks3/m5stack,sticks3.dts +++ b/Devices/m5stack-sticks3/m5stack,sticks3.dts @@ -71,9 +71,8 @@ pin-miso = <&gpio0 4 GPIO_FLAG_NONE>; pin-sclk = <&gpio0 5 GPIO_FLAG_NONE>; - sdcard { + sdcard@0 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 7 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; }; diff --git a/Devices/unphone/unphone.dts b/Devices/unphone/unphone.dts index 99d7bd125..b7a53c21a 100644 --- a/Devices/unphone/unphone.dts +++ b/Devices/unphone/unphone.dts @@ -6,6 +6,8 @@ #include #include #include +#include +#include / { compatible = "root"; @@ -49,7 +51,6 @@ sdcard@2 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 43 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; }; diff --git a/Devices/waveshare-s3-lcd-13/waveshare,s3-lcd-13.dts b/Devices/waveshare-s3-lcd-13/waveshare,s3-lcd-13.dts index 85a10de7b..389d019b8 100644 --- a/Devices/waveshare-s3-lcd-13/waveshare,s3-lcd-13.dts +++ b/Devices/waveshare-s3-lcd-13/waveshare,s3-lcd-13.dts @@ -56,9 +56,8 @@ pin-miso = <&gpio0 16 GPIO_FLAG_NONE>; pin-sclk = <&gpio0 21 GPIO_FLAG_NONE>; - sdcard { + sdcard@0 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 17 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; }; diff --git a/Devices/waveshare-s3-touch-lcd-128/waveshare,s3-touch-lcd-128.dts b/Devices/waveshare-s3-touch-lcd-128/waveshare,s3-touch-lcd-128.dts index 22298c064..6240644bb 100644 --- a/Devices/waveshare-s3-touch-lcd-128/waveshare,s3-touch-lcd-128.dts +++ b/Devices/waveshare-s3-touch-lcd-128/waveshare,s3-touch-lcd-128.dts @@ -57,9 +57,8 @@ pin-miso = <&gpio0 15 GPIO_FLAG_NONE>; pin-sclk = <&gpio0 17 GPIO_FLAG_NONE>; - sdcard { + sdcard@0 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 18 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; }; diff --git a/Devices/waveshare-s3-touch-lcd-147/waveshare,s3-touch-lcd-147.dts b/Devices/waveshare-s3-touch-lcd-147/waveshare,s3-touch-lcd-147.dts index 4f6ee5bd8..c1dde4935 100644 --- a/Devices/waveshare-s3-touch-lcd-147/waveshare,s3-touch-lcd-147.dts +++ b/Devices/waveshare-s3-touch-lcd-147/waveshare,s3-touch-lcd-147.dts @@ -6,6 +6,7 @@ #include #include #include +#include // Reference: https://www.waveshare.com/wiki/ESP32-S3-Touch-LCD-1.47 / { @@ -44,13 +45,13 @@ spi1 { compatible = "espressif,esp32-spi"; host = ; + cs-gpios = <&gpio0 14 GPIO_FLAG_NONE>; pin-mosi = <&gpio0 15 GPIO_FLAG_NONE>; pin-miso = <&gpio0 17 GPIO_FLAG_NONE>; pin-sclk = <&gpio0 16 GPIO_FLAG_NONE>; - sdcard { + sdcard@0 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 14 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; }; diff --git a/Devices/waveshare-s3-touch-lcd-43/waveshare,s3-touch-lcd-43.dts b/Devices/waveshare-s3-touch-lcd-43/waveshare,s3-touch-lcd-43.dts index b868a57b1..49bca91be 100644 --- a/Devices/waveshare-s3-touch-lcd-43/waveshare,s3-touch-lcd-43.dts +++ b/Devices/waveshare-s3-touch-lcd-43/waveshare,s3-touch-lcd-43.dts @@ -37,9 +37,8 @@ pin-miso = <&gpio0 13 GPIO_FLAG_NONE>; pin-sclk = <&gpio0 12 GPIO_FLAG_NONE>; - sdcard { + sdcard@0 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 10 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; }; diff --git a/Devices/wireless-tag-wt32-sc01-plus/wireless-tag,wt32-sc01-plus.dts b/Devices/wireless-tag-wt32-sc01-plus/wireless-tag,wt32-sc01-plus.dts index f0a6c2b65..e95def9c5 100644 --- a/Devices/wireless-tag-wt32-sc01-plus/wireless-tag,wt32-sc01-plus.dts +++ b/Devices/wireless-tag-wt32-sc01-plus/wireless-tag,wt32-sc01-plus.dts @@ -36,9 +36,8 @@ pin-miso = <&gpio0 38 GPIO_FLAG_NONE>; pin-sclk = <&gpio0 39 GPIO_FLAG_NONE>; - sdcard { + sdcard@0 { compatible = "espressif,esp32-sdspi"; - pin-cs = <&gpio0 41 GPIO_FLAG_NONE>; frequency-khz = <20000>; }; }; diff --git a/Platforms/platform-esp32/bindings/espressif,esp32-grove.yaml b/Platforms/platform-esp32/bindings/espressif,esp32-grove.yaml index 7c6608736..34a76e7cd 100644 --- a/Platforms/platform-esp32/bindings/espressif,esp32-grove.yaml +++ b/Platforms/platform-esp32/bindings/espressif,esp32-grove.yaml @@ -8,11 +8,11 @@ properties: required: true description: "One of enum Esp32GroveMode" pinSdaTx: - type: phandle-array + type: phandles required: true description: SDA (I2C) or TX (UART) pin pinSclRx: - type: phandle-array + type: phandles required: true description: SCL (I2C) or RX (UART) pin uartPort: diff --git a/Platforms/platform-esp32/bindings/espressif,esp32-i2c-master.yaml b/Platforms/platform-esp32/bindings/espressif,esp32-i2c-master.yaml index 7424f5787..ad8b7280e 100644 --- a/Platforms/platform-esp32/bindings/espressif,esp32-i2c-master.yaml +++ b/Platforms/platform-esp32/bindings/espressif,esp32-i2c-master.yaml @@ -22,8 +22,8 @@ properties: Clock source for the I2C peripheral. If not specified, a default clock source will be used. pin-sda: - type: phandle-array + type: phandles required: true pin-scl: - type: phandle-array + type: phandles required: true diff --git a/Platforms/platform-esp32/bindings/espressif,esp32-i2c.yaml b/Platforms/platform-esp32/bindings/espressif,esp32-i2c.yaml index 96a2de0fc..8e49df801 100644 --- a/Platforms/platform-esp32/bindings/espressif,esp32-i2c.yaml +++ b/Platforms/platform-esp32/bindings/espressif,esp32-i2c.yaml @@ -16,8 +16,8 @@ properties: required: true description: Initial clock frequency in Hz pin-sda: - type: phandle-array + type: phandles required: true pin-scl: - type: phandle-array + type: phandles required: true diff --git a/Platforms/platform-esp32/bindings/espressif,esp32-i2s.yaml b/Platforms/platform-esp32/bindings/espressif,esp32-i2s.yaml index a0f5c1862..6406e63e7 100644 --- a/Platforms/platform-esp32/bindings/espressif,esp32-i2s.yaml +++ b/Platforms/platform-esp32/bindings/espressif,esp32-i2s.yaml @@ -12,22 +12,22 @@ properties: The port number, defined by i2s_port_t. Depending on the hardware, these values are available: I2S_NUM_0, I2S_NUM_1 pin-bclk: - type: phandle-array + type: phandles required: true description: Bit clock pin pin-ws: - type: phandle-array + type: phandles required: true description: Word (slot) select pin pin-data-out: - type: phandle-array + type: phandles default: GPIO_PIN_SPEC_NONE description: Data output pin pin-data-in: - type: phandle-array + type: phandles default: GPIO_PIN_SPEC_NONE description: Data input pin pin-mclk: - type: phandle-array + type: phandles default: GPIO_PIN_SPEC_NONE description: Master clock pin diff --git a/Platforms/platform-esp32/bindings/espressif,esp32-sdmmc.yaml b/Platforms/platform-esp32/bindings/espressif,esp32-sdmmc.yaml index 0de6815d7..2426c83a9 100644 --- a/Platforms/platform-esp32/bindings/espressif,esp32-sdmmc.yaml +++ b/Platforms/platform-esp32/bindings/espressif,esp32-sdmmc.yaml @@ -4,40 +4,40 @@ compatible: "espressif,esp32-sdmmc" properties: pin-clk: - type: phandle-array + type: phandles required: true pin-cmd: - type: phandle-array + type: phandles required: true pin-d0: - type: phandle-array + type: phandles required: true pin-d1: - type: phandle-array + type: phandles default: GPIO_PIN_SPEC_NONE pin-d2: - type: phandle-array + type: phandles default: GPIO_PIN_SPEC_NONE pin-d3: - type: phandle-array + type: phandles default: GPIO_PIN_SPEC_NONE pin-d4: - type: phandle-array + type: phandles default: GPIO_PIN_SPEC_NONE pin-d5: - type: phandle-array + type: phandles default: GPIO_PIN_SPEC_NONE pin-d6: - type: phandle-array + type: phandles default: GPIO_PIN_SPEC_NONE pin-d7: - type: phandle-array + type: phandles default: GPIO_PIN_SPEC_NONE pin-cd: - type: phandle-array + type: phandles default: GPIO_PIN_SPEC_NONE pin-wp: - type: phandle-array + type: phandles default: GPIO_PIN_SPEC_NONE bus-width: type: int diff --git a/Platforms/platform-esp32/bindings/espressif,esp32-sdspi.yaml b/Platforms/platform-esp32/bindings/espressif,esp32-sdspi.yaml index 45c4d0e06..5ad74507c 100644 --- a/Platforms/platform-esp32/bindings/espressif,esp32-sdspi.yaml +++ b/Platforms/platform-esp32/bindings/espressif,esp32-sdspi.yaml @@ -5,20 +5,16 @@ compatible: "espressif,esp32-sdspi" bus: spi properties: - pin-cs: - type: phandle-array - required: true - description: Chip select GPIO pin-cd: - type: phandle-array + type: phandles default: GPIO_PIN_SPEC_NONE description: Card detect GPIO pin-wp: - type: phandle-array + type: phandles default: GPIO_PIN_SPEC_NONE description: Write protect GPIO pin-int: - type: phandle-array + type: phandles default: GPIO_PIN_SPEC_NONE description: Interrupt GPIO frequency-khz: diff --git a/Platforms/platform-esp32/bindings/espressif,esp32-spi.yaml b/Platforms/platform-esp32/bindings/espressif,esp32-spi.yaml index d2aa437d6..95e16a878 100644 --- a/Platforms/platform-esp32/bindings/espressif,esp32-spi.yaml +++ b/Platforms/platform-esp32/bindings/espressif,esp32-spi.yaml @@ -12,22 +12,22 @@ properties: The SPI host (controller) to use. Defined by spi_host_device_t (e.g. SPI2_HOST, SPI3_HOST). pin-sclk: - type: phandle-array + type: phandles default: GPIO_PIN_SPEC_NONE pin-mosi: - type: phandle-array + type: phandles default: GPIO_PIN_SPEC_NONE description: MOSI (Data 0) pin pin-miso: - type: phandle-array + type: phandles default: GPIO_PIN_SPEC_NONE description: MISO (Data 1) pin pin-wp: - type: phandle-array + type: phandles default: GPIO_PIN_SPEC_NONE description: WP (Data 2) pin pin-hd: - type: phandle-array + type: phandles default: GPIO_PIN_SPEC_NONE description: HD (Data 3) pin max-transfer-size: @@ -38,5 +38,6 @@ properties: 0 means the platform decides the limit. cs-gpios: type: phandle-array - default: { 0 } + element-type: "struct GpioPinSpec" + default: "{ }" description: Null-terminated array of chip select GPIO pin specs for peripherals on this bus diff --git a/Platforms/platform-esp32/bindings/espressif,esp32-uart.yaml b/Platforms/platform-esp32/bindings/espressif,esp32-uart.yaml index 2016a2267..0d83aa16c 100644 --- a/Platforms/platform-esp32/bindings/espressif,esp32-uart.yaml +++ b/Platforms/platform-esp32/bindings/espressif,esp32-uart.yaml @@ -12,18 +12,18 @@ properties: The port number, defined by uart_port_t. Depending on the hardware, these values are available: UART_NUM_0, UART_NUM_1, UART_NUM_2 pin-tx: - type: phandle-array + type: phandles required: true description: TX pin pin-rx: - type: phandle-array + type: phandles required: true description: RX pin pin-cts: - type: phandle-array + type: phandles default: GPIO_PIN_SPEC_NONE description: CTS pin pin-rts: - type: phandle-array + type: phandles default: GPIO_PIN_SPEC_NONE description: RTS pin diff --git a/Platforms/platform-esp32/include/tactility/drivers/esp32_sdspi.h b/Platforms/platform-esp32/include/tactility/drivers/esp32_sdspi.h index eba9b4161..fc025ccf2 100644 --- a/Platforms/platform-esp32/include/tactility/drivers/esp32_sdspi.h +++ b/Platforms/platform-esp32/include/tactility/drivers/esp32_sdspi.h @@ -9,7 +9,6 @@ extern "C" { #endif struct Esp32SdspiConfig { - struct GpioPinSpec pin_cs; struct GpioPinSpec pin_cd; struct GpioPinSpec pin_wp; struct GpioPinSpec pin_int; diff --git a/Platforms/platform-esp32/include/tactility/drivers/esp32_spi.h b/Platforms/platform-esp32/include/tactility/drivers/esp32_spi.h index 3de540b99..c49051fae 100644 --- a/Platforms/platform-esp32/include/tactility/drivers/esp32_spi.h +++ b/Platforms/platform-esp32/include/tactility/drivers/esp32_spi.h @@ -23,10 +23,29 @@ struct Esp32SpiConfig { struct GpioPinSpec pin_hd; /** Data transfer size limit in bytes. 0 means the platform decides the limit. */ int max_transfer_size; - /** Null-terminated array of chip select GPIO pin specs */ - struct GpioPinSpec cs_gpios[]; + /** Array of chip select GPIO pin specs */ + struct GpioPinSpec* cs_gpios; + /** The item count of cs_gpios */ + uint8_t cs_gpios_count; }; +/** + * @brief Get the CS pin spec for a child device on this SPI bus. + * Uses the child device's address as index into the parent's cs_gpios array. + * @param[in] child_device a child device of an SPI controller + * @param[out] out_pin the GPIO pin spec for the CS pin + * @retval ERROR_NONE on success + * @retval ERROR_INVALID_STATE if the parent is not an SPI controller + * @retval ERROR_OUT_OF_RANGE if the device address exceeds the cs_gpios array + */ +error_t esp32_spi_get_cs_pin(struct Device* child_device, struct GpioPinSpec* out_pin); + +/** + * @brief Drive all CS pins on this SPI bus high (deselected). + * @param[in] device the SPI controller device + */ +void esp32_spi_deselect_all_cs(struct Device* device); + #ifdef __cplusplus } #endif diff --git a/Platforms/platform-esp32/private/tactility/drivers/esp32_sdspi_fs.h b/Platforms/platform-esp32/private/tactility/drivers/esp32_sdspi_fs.h index bb50eff59..92880fb9f 100644 --- a/Platforms/platform-esp32/private/tactility/drivers/esp32_sdspi_fs.h +++ b/Platforms/platform-esp32/private/tactility/drivers/esp32_sdspi_fs.h @@ -11,7 +11,7 @@ extern "C" { struct Esp32SdspiConfig; typedef void* Esp32SdspiHandle; -Esp32SdspiHandle esp32_sdspi_fs_alloc(const struct Esp32SdspiConfig* config, int spi_host, const char* mount_path); +Esp32SdspiHandle esp32_sdspi_fs_alloc(const struct Esp32SdspiConfig* config, int spi_host, int cs_pin, const char* mount_path); void esp32_sdspi_fs_free(Esp32SdspiHandle handle); sdmmc_card_t* esp32_sdspi_fs_get_card(Esp32SdspiHandle handle); diff --git a/Platforms/platform-esp32/source/drivers/bluetooth/esp32_ble.cpp b/Platforms/platform-esp32/source/drivers/bluetooth/esp32_ble.cpp index 30bc10161..0c0585219 100644 --- a/Platforms/platform-esp32/source/drivers/bluetooth/esp32_ble.cpp +++ b/Platforms/platform-esp32/source/drivers/bluetooth/esp32_ble.cpp @@ -1000,7 +1000,7 @@ const BluetoothApi nimble_bluetooth_api = { static void create_child_device(struct Device* parent, const char* name, Driver* drv, struct Device*& out) { - out = new Device { .name = name, .config = nullptr, .parent = nullptr, .internal = nullptr }; + out = new Device { .address = 0, .name = name, .config = nullptr, .parent = nullptr, .internal = nullptr }; device_construct(out); device_set_parent(out, parent); device_set_driver(out, drv); diff --git a/Platforms/platform-esp32/source/drivers/esp32_i2c.cpp b/Platforms/platform-esp32/source/drivers/esp32_i2c.cpp index dcda02c6a..f1ac27270 100644 --- a/Platforms/platform-esp32/source/drivers/esp32_i2c.cpp +++ b/Platforms/platform-esp32/source/drivers/esp32_i2c.cpp @@ -238,7 +238,8 @@ static constexpr I2cControllerApi ESP32_I2C_API = { .write = write, .write_read = write_read, .read_register = read_register, - .write_register = write_register + .write_register = write_register, + .probe = nullptr }; extern Module platform_esp32_module; diff --git a/Platforms/platform-esp32/source/drivers/esp32_sdspi.cpp b/Platforms/platform-esp32/source/drivers/esp32_sdspi.cpp index cb42d283c..38b542785 100644 --- a/Platforms/platform-esp32/source/drivers/esp32_sdspi.cpp +++ b/Platforms/platform-esp32/source/drivers/esp32_sdspi.cpp @@ -24,7 +24,6 @@ struct Esp32SdspiInternal { RecursiveMutex mutex = {}; Esp32SdspiHandle fs_handle = nullptr; FileSystem* file_system = nullptr; - GpioDescriptor* pin_cs_descriptor = nullptr; GpioDescriptor* pin_cd_descriptor = nullptr; GpioDescriptor* pin_wp_descriptor = nullptr; GpioDescriptor* pin_int_descriptor = nullptr; @@ -40,7 +39,6 @@ struct Esp32SdspiInternal { } void cleanup_pins() { - release_pin(&pin_cs_descriptor); release_pin(&pin_cd_descriptor); release_pin(&pin_wp_descriptor); release_pin(&pin_int_descriptor); @@ -68,7 +66,6 @@ static error_t start(Device* device) { auto* config = GET_CONFIG(device); bool pins_ok = - acquire_pin_or_set_null(config->pin_cs, &data->pin_cs_descriptor) && acquire_pin_or_set_null(config->pin_cd, &data->pin_cd_descriptor) && acquire_pin_or_set_null(config->pin_wp, &data->pin_wp_descriptor) && acquire_pin_or_set_null(config->pin_int, &data->pin_int_descriptor); @@ -82,8 +79,25 @@ static error_t start(Device* device) { return ERROR_RESOURCE; } + GpioPinSpec cs_pin_spec; + if (esp32_spi_get_cs_pin(device, &cs_pin_spec) != ERROR_NONE) { + LOG_E(TAG, "Failed to get CS pin from parent SPI controller"); + data->cleanup_pins(); + device_set_driver_data(device, nullptr); + data->unlock(); + delete data; + return ERROR_RESOURCE; + } + auto* spi_config = static_cast(parent->config); - data->fs_handle = esp32_sdspi_fs_alloc(config, spi_config->host, "/sdcard"); + + // Lower all CS pins + esp32_spi_deselect_all_cs(parent); + // Manually set the CS pin fo + gpio_set_direction(static_cast(cs_pin_spec.pin), GPIO_MODE_OUTPUT); + gpio_set_level(static_cast(cs_pin_spec.pin), 255); + + data->fs_handle = esp32_sdspi_fs_alloc(config, spi_config->host, cs_pin_spec.pin, "/sdcard"); if (!data->fs_handle) { data->cleanup_pins(); device_set_driver_data(device, nullptr); diff --git a/Platforms/platform-esp32/source/drivers/esp32_sdspi_fs.cpp b/Platforms/platform-esp32/source/drivers/esp32_sdspi_fs.cpp index 78d8282cb..70d8ad832 100644 --- a/Platforms/platform-esp32/source/drivers/esp32_sdspi_fs.cpp +++ b/Platforms/platform-esp32/source/drivers/esp32_sdspi_fs.cpp @@ -17,12 +17,14 @@ struct Esp32SdspiFsData { const std::string mount_path; const Esp32SdspiConfig* config; int spi_host; + int cs_pin; sdmmc_card_t* card; - Esp32SdspiFsData(const Esp32SdspiConfig* config, int spi_host, const std::string& mount_path) : + Esp32SdspiFsData(const Esp32SdspiConfig* config, int spi_host, int cs_pin, const std::string& mount_path) : mount_path(mount_path), config(config), spi_host(spi_host), + cs_pin(cs_pin), card(nullptr) {} }; @@ -34,8 +36,8 @@ static gpio_num_t to_native_pin(GpioPinSpec pin_spec) { extern "C" { -Esp32SdspiHandle esp32_sdspi_fs_alloc(const Esp32SdspiConfig* config, int spi_host, const char* mount_path) { - return new(std::nothrow) Esp32SdspiFsData(config, spi_host, mount_path); +Esp32SdspiHandle esp32_sdspi_fs_alloc(const Esp32SdspiConfig* config, int spi_host, int cs_pin, const char* mount_path) { + return new(std::nothrow) Esp32SdspiFsData(config, spi_host, cs_pin, mount_path); } void esp32_sdspi_fs_free(Esp32SdspiHandle handle) { @@ -62,7 +64,7 @@ static error_t mount(void* data) { sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT(); slot_config.host_id = static_cast(fs_data->spi_host); - slot_config.gpio_cs = to_native_pin(config->pin_cs); + slot_config.gpio_cs = static_cast(fs_data->cs_pin); slot_config.gpio_cd = to_native_pin(config->pin_cd); slot_config.gpio_wp = to_native_pin(config->pin_wp); slot_config.gpio_int = to_native_pin(config->pin_int); diff --git a/Platforms/platform-esp32/source/drivers/esp32_spi.cpp b/Platforms/platform-esp32/source/drivers/esp32_spi.cpp index e80297d33..7d3542621 100644 --- a/Platforms/platform-esp32/source/drivers/esp32_spi.cpp +++ b/Platforms/platform-esp32/source/drivers/esp32_spi.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #define TAG "esp32_spi" @@ -22,13 +23,16 @@ struct Esp32SpiInternal { RecursiveMutex mutex = {}; bool initialized = false; - // Pin descriptors + // Bus pin descriptors GpioDescriptor* sclk_descriptor = nullptr; GpioDescriptor* mosi_descriptor = nullptr; GpioDescriptor* miso_descriptor = nullptr; GpioDescriptor* wp_descriptor = nullptr; GpioDescriptor* hd_descriptor = nullptr; + // CS pin descriptors + std::vector cs_descriptors; + explicit Esp32SpiInternal() { recursive_mutex_construct(&mutex); } @@ -44,6 +48,10 @@ struct Esp32SpiInternal { release_pin(&miso_descriptor); release_pin(&wp_descriptor); release_pin(&hd_descriptor); + for (auto*& desc : cs_descriptors) { + release_pin(&desc); + } + cs_descriptors.clear(); } }; @@ -118,22 +126,30 @@ static error_t start(Device* device) { return ERROR_RESOURCE; } - // Deselect all CS pins (drive high) before any SPI communication - const GpioPinSpec* cs = dts_config->cs_gpios; - while (cs->gpio_controller != nullptr) { + // Acquire and deselect all CS pins (drive high) + for (uint8_t i = 0; i < dts_config->cs_gpios_count; i++) { + const GpioPinSpec* cs = &dts_config->cs_gpios[i]; + if (cs->gpio_controller == nullptr) continue; GpioDescriptor* desc = gpio_descriptor_acquire(cs->gpio_controller, cs->pin, GPIO_OWNER_SPI); if (desc != nullptr) { gpio_descriptor_set_flags(desc, GPIO_FLAG_DIRECTION_OUTPUT); gpio_descriptor_set_level(desc, true); - gpio_descriptor_release(desc); + data->cs_descriptors.push_back(desc); } - cs++; } data->initialized = true; return ERROR_NONE; } +void esp32_spi_deselect_all_cs(Device* device) { + auto* data = GET_DATA(device); + if (data == nullptr) return; + for (auto* desc : data->cs_descriptors) { + gpio_descriptor_set_level(desc, true); + } +} + static error_t stop(Device* device) { LOG_I(TAG, "stop %s", device->name); auto* driver_data = GET_DATA(device); @@ -149,6 +165,16 @@ static error_t stop(Device* device) { return ERROR_NONE; } +error_t esp32_spi_get_cs_pin(Device* child_device, GpioPinSpec* out_pin) { + auto* parent = device_get_parent(child_device); + if (parent == nullptr || device_get_type(parent) != &SPI_CONTROLLER_TYPE) return ERROR_INVALID_STATE; + auto* config = GET_CONFIG(parent); + int32_t index = child_device->address; + if (index < 0 || index >= config->cs_gpios_count) return ERROR_OUT_OF_RANGE; + *out_pin = config->cs_gpios[index]; + return ERROR_NONE; +} + const static struct SpiControllerApi esp32_spi_api = { .lock = lock, .try_lock = try_lock, diff --git a/TactilityKernel/bindings/spi-peripheral.yaml b/TactilityKernel/bindings/spi-peripheral.yaml index baa052a5b..623c671d8 100644 --- a/TactilityKernel/bindings/spi-peripheral.yaml +++ b/TactilityKernel/bindings/spi-peripheral.yaml @@ -1,9 +1,5 @@ -description: SPI peripheral with chip select +description: SPI peripheral compatible: "spi-peripheral" -properties: - pin-cs: - type: phandle-array - required: true - description: Chip select GPIO +properties: {} diff --git a/TactilityKernel/include/tactility/drivers/spi_peripheral.h b/TactilityKernel/include/tactility/drivers/spi_peripheral.h index e7b1c3545..fa725569c 100644 --- a/TactilityKernel/include/tactility/drivers/spi_peripheral.h +++ b/TactilityKernel/include/tactility/drivers/spi_peripheral.h @@ -1,23 +1,17 @@ // SPDX-License-Identifier: Apache-2.0 #pragma once +#include #include -#include #ifdef __cplusplus extern "C" { #endif struct SpiPeripheralConfig { - struct GpioPinSpec pin_cs; + uint8_t _unused; }; -struct SpiPeripheralApi { - struct GpioDescriptor* (*get_cs_descriptor)(struct Device* device); -}; - -struct GpioDescriptor* spi_peripheral_get_cs_descriptor(struct Device* device); - extern const struct DeviceType SPI_PERIPHERAL_TYPE; #ifdef __cplusplus diff --git a/TactilityKernel/include/tactility/error.h b/TactilityKernel/include/tactility/error.h index 094a4c92f..58aa77b64 100644 --- a/TactilityKernel/include/tactility/error.h +++ b/TactilityKernel/include/tactility/error.h @@ -24,6 +24,7 @@ typedef int error_t; #define ERROR_NOT_SUPPORTED 10 #define ERROR_NOT_ALLOWED 11 #define ERROR_BUFFER_OVERFLOW 12 +#define ERROR_OUT_OF_RANGE 13 /** Convert an error_t to a human-readable text. Useful for logging. */ const char* error_to_string(error_t error); diff --git a/TactilityKernel/source/drivers/spi_peripheral.cpp b/TactilityKernel/source/drivers/spi_peripheral.cpp index 3b7b1b600..8e9a3956b 100644 --- a/TactilityKernel/source/drivers/spi_peripheral.cpp +++ b/TactilityKernel/source/drivers/spi_peripheral.cpp @@ -1,61 +1,12 @@ // SPDX-License-Identifier: Apache-2.0 #include -#include -#include #include #include -#include - -#define TAG "spi_peripheral" - -#define GET_CONFIG(device) ((const struct SpiPeripheralConfig*)device->config) extern "C" { -static error_t start(Device* device) { - auto* parent = device_get_parent(device); - if (parent == nullptr || device_get_type(parent) != &SPI_CONTROLLER_TYPE) { - LOG_E(TAG, "Parent is not an SPI controller"); - return ERROR_INVALID_STATE; - } - - auto* config = GET_CONFIG(device); - GpioDescriptor* cs = nullptr; - if (config->pin_cs.gpio_controller != nullptr) { - cs = gpio_descriptor_acquire(config->pin_cs.gpio_controller, config->pin_cs.pin, GPIO_OWNER_SPI); - if (cs == nullptr) { - LOG_E(TAG, "Failed to acquire CS pin"); - return ERROR_RESOURCE; - } - gpio_descriptor_set_flags(cs, GPIO_FLAG_DIRECTION_OUTPUT); - gpio_descriptor_set_level(cs, true); - } - - device_set_driver_data(device, cs); - return ERROR_NONE; -} - -static error_t stop(Device* device) { - auto* cs = static_cast(device_get_driver_data(device)); - if (cs != nullptr) { - gpio_descriptor_release(cs); - } - device_set_driver_data(device, nullptr); - return ERROR_NONE; -} - -static GpioDescriptor* get_cs_descriptor(Device* device) { - return static_cast(device_get_driver_data(device)); -} - -static const SpiPeripheralApi spi_peripheral_api = { - .get_cs_descriptor = get_cs_descriptor -}; - -GpioDescriptor* spi_peripheral_get_cs_descriptor(Device* device) { - auto* driver = device_get_driver(device); - return ((const SpiPeripheralApi*)driver->api)->get_cs_descriptor(device); -} +static error_t start(Device*) { return ERROR_NONE; } +static error_t stop(Device*) { return ERROR_NONE; } const DeviceType SPI_PERIPHERAL_TYPE = { .name = "spi_peripheral" @@ -68,7 +19,7 @@ Driver spi_peripheral_driver = { .compatible = (const char*[]) { "spi-peripheral", nullptr }, .start_device = start, .stop_device = stop, - .api = &spi_peripheral_api, + .api = nullptr, .device_type = &SPI_PERIPHERAL_TYPE, .owner = &root_module, .internal = nullptr