mirror of
https://github.com/esphome/esphome.git
synced 2025-04-15 15:20:27 +01:00
[spi] Implement octal mode (#8386)
This commit is contained in:
parent
6240bfff97
commit
a866370a2e
@ -113,7 +113,7 @@ BASE_SCHEMA = display.FULL_DISPLAY_SCHEMA.extend(
|
|||||||
cs_pin_required=False,
|
cs_pin_required=False,
|
||||||
default_mode="MODE0",
|
default_mode="MODE0",
|
||||||
default_data_rate=10e6,
|
default_data_rate=10e6,
|
||||||
quad=True,
|
mode=spi.TYPE_QUAD,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -37,6 +37,7 @@ CODEOWNERS = ["@esphome/core", "@clydebarrow"]
|
|||||||
spi_ns = cg.esphome_ns.namespace("spi")
|
spi_ns = cg.esphome_ns.namespace("spi")
|
||||||
SPIComponent = spi_ns.class_("SPIComponent", cg.Component)
|
SPIComponent = spi_ns.class_("SPIComponent", cg.Component)
|
||||||
QuadSPIComponent = spi_ns.class_("QuadSPIComponent", cg.Component)
|
QuadSPIComponent = spi_ns.class_("QuadSPIComponent", cg.Component)
|
||||||
|
OctalSPIComponent = spi_ns.class_("OctalSPIComponent", cg.Component)
|
||||||
SPIDevice = spi_ns.class_("SPIDevice")
|
SPIDevice = spi_ns.class_("SPIDevice")
|
||||||
SPIDataRate = spi_ns.enum("SPIDataRate")
|
SPIDataRate = spi_ns.enum("SPIDataRate")
|
||||||
SPIMode = spi_ns.enum("SPIMode")
|
SPIMode = spi_ns.enum("SPIMode")
|
||||||
@ -78,6 +79,13 @@ CONF_INTERFACE = "interface"
|
|||||||
CONF_INTERFACE_INDEX = "interface_index"
|
CONF_INTERFACE_INDEX = "interface_index"
|
||||||
TYPE_SINGLE = "single"
|
TYPE_SINGLE = "single"
|
||||||
TYPE_QUAD = "quad"
|
TYPE_QUAD = "quad"
|
||||||
|
TYPE_OCTAL = "octal"
|
||||||
|
|
||||||
|
TYPE_CLASS = {
|
||||||
|
TYPE_SINGLE: SPIComponent,
|
||||||
|
TYPE_QUAD: QuadSPIComponent,
|
||||||
|
TYPE_OCTAL: OctalSPIComponent,
|
||||||
|
}
|
||||||
|
|
||||||
# RP2040 SPI pin assignments are complicated;
|
# RP2040 SPI pin assignments are complicated;
|
||||||
# refer to GPIO function select table in https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf
|
# refer to GPIO function select table in https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf
|
||||||
@ -230,7 +238,7 @@ def validate_spi_config(config):
|
|||||||
):
|
):
|
||||||
raise cv.Invalid("Invalid pin selections for hardware SPI interface")
|
raise cv.Invalid("Invalid pin selections for hardware SPI interface")
|
||||||
if CONF_DATA_PINS in spi and CONF_INTERFACE_INDEX not in spi:
|
if CONF_DATA_PINS in spi and CONF_INTERFACE_INDEX not in spi:
|
||||||
raise cv.Invalid("Quad mode requires a hardware interface")
|
raise cv.Invalid("Quad and octal modes requires a hardware interface")
|
||||||
|
|
||||||
return config
|
return config
|
||||||
|
|
||||||
@ -251,7 +259,7 @@ def get_spi_interface(index):
|
|||||||
return "new SPIClass(HSPI)"
|
return "new SPIClass(HSPI)"
|
||||||
|
|
||||||
|
|
||||||
SPI_SCHEMA = cv.All(
|
SPI_SINGLE_SCHEMA = cv.All(
|
||||||
cv.Schema(
|
cv.Schema(
|
||||||
{
|
{
|
||||||
cv.GenerateID(): cv.declare_id(SPIComponent),
|
cv.GenerateID(): cv.declare_id(SPIComponent),
|
||||||
@ -266,7 +274,7 @@ SPI_SCHEMA = cv.All(
|
|||||||
lower=True,
|
lower=True,
|
||||||
),
|
),
|
||||||
cv.Optional(CONF_DATA_PINS): cv.invalid(
|
cv.Optional(CONF_DATA_PINS): cv.invalid(
|
||||||
"'data_pins' should be used with 'type: quad' only"
|
"'data_pins' should be used with 'type: quad or octal' only"
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
@ -274,38 +282,41 @@ SPI_SCHEMA = cv.All(
|
|||||||
cv.only_on([PLATFORM_ESP32, PLATFORM_ESP8266, PLATFORM_RP2040]),
|
cv.only_on([PLATFORM_ESP32, PLATFORM_ESP8266, PLATFORM_RP2040]),
|
||||||
)
|
)
|
||||||
|
|
||||||
SPI_QUAD_SCHEMA = cv.All(
|
|
||||||
cv.Schema(
|
def spi_mode_schema(mode):
|
||||||
{
|
if mode == TYPE_SINGLE:
|
||||||
cv.GenerateID(): cv.declare_id(QuadSPIComponent),
|
return SPI_SINGLE_SCHEMA
|
||||||
cv.Required(CONF_CLK_PIN): pins.gpio_output_pin_schema,
|
pin_count = 4 if mode == TYPE_QUAD else 8
|
||||||
cv.Required(CONF_DATA_PINS): cv.All(
|
return cv.All(
|
||||||
cv.ensure_list(pins.internal_gpio_output_pin_number),
|
cv.Schema(
|
||||||
cv.Length(min=4, max=4),
|
{
|
||||||
),
|
cv.GenerateID(): cv.declare_id(TYPE_CLASS[mode]),
|
||||||
cv.Optional(CONF_INTERFACE, default="hardware"): cv.one_of(
|
cv.Required(CONF_CLK_PIN): pins.gpio_output_pin_schema,
|
||||||
*sum(get_hw_interface_list(), ["hardware"]),
|
cv.Required(CONF_DATA_PINS): cv.All(
|
||||||
lower=True,
|
cv.ensure_list(pins.internal_gpio_output_pin_number),
|
||||||
),
|
cv.Length(min=pin_count, max=pin_count),
|
||||||
cv.Optional(CONF_MISO_PIN): cv.invalid(
|
),
|
||||||
"'miso_pin' should not be used with quad SPI"
|
cv.Optional(CONF_INTERFACE, default="hardware"): cv.one_of(
|
||||||
),
|
*sum(get_hw_interface_list(), ["hardware"]),
|
||||||
cv.Optional(CONF_MOSI_PIN): cv.invalid(
|
lower=True,
|
||||||
"'mosi_pin' should not be used with quad SPI"
|
),
|
||||||
),
|
cv.Optional(CONF_MISO_PIN): cv.invalid(
|
||||||
}
|
f"'miso_pin' should not be used with {mode} SPI"
|
||||||
),
|
),
|
||||||
cv.only_on([PLATFORM_ESP32]),
|
cv.Optional(CONF_MOSI_PIN): cv.invalid(
|
||||||
cv.only_with_esp_idf,
|
f"'mosi_pin' should not be used with {mode} SPI"
|
||||||
)
|
),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
cv.only_on([PLATFORM_ESP32]),
|
||||||
|
cv.only_with_esp_idf,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
CONFIG_SCHEMA = cv.All(
|
CONFIG_SCHEMA = cv.All(
|
||||||
cv.ensure_list(
|
cv.ensure_list(
|
||||||
cv.typed_schema(
|
cv.typed_schema(
|
||||||
{
|
{k: spi_mode_schema(k) for k in TYPE_CLASS},
|
||||||
TYPE_SINGLE: SPI_SCHEMA,
|
|
||||||
TYPE_QUAD: SPI_QUAD_SCHEMA,
|
|
||||||
},
|
|
||||||
default_type=TYPE_SINGLE,
|
default_type=TYPE_SINGLE,
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
@ -344,19 +355,17 @@ def spi_device_schema(
|
|||||||
cs_pin_required=True,
|
cs_pin_required=True,
|
||||||
default_data_rate=cv.UNDEFINED,
|
default_data_rate=cv.UNDEFINED,
|
||||||
default_mode=cv.UNDEFINED,
|
default_mode=cv.UNDEFINED,
|
||||||
quad=False,
|
mode=TYPE_SINGLE,
|
||||||
):
|
):
|
||||||
"""Create a schema for an SPI device.
|
"""Create a schema for an SPI device.
|
||||||
:param cs_pin_required: If true, make the CS_PIN required in the config.
|
:param cs_pin_required: If true, make the CS_PIN required in the config.
|
||||||
:param default_data_rate: Optional data_rate to use as default
|
:param default_data_rate: Optional data_rate to use as default
|
||||||
:param default_mode Optional. The default SPI mode to use.
|
:param default_mode Optional. The default SPI mode to use.
|
||||||
:param quad If set, will require an SPI component configured as quad data bits.
|
:param mode Choose single, quad or octal mode.
|
||||||
:return: The SPI device schema, `extend` this in your config schema.
|
:return: The SPI device schema, `extend` this in your config schema.
|
||||||
"""
|
"""
|
||||||
schema = {
|
schema = {
|
||||||
cv.GenerateID(CONF_SPI_ID): cv.use_id(
|
cv.GenerateID(CONF_SPI_ID): cv.use_id(TYPE_CLASS[mode]),
|
||||||
QuadSPIComponent if quad else SPIComponent
|
|
||||||
),
|
|
||||||
cv.Optional(CONF_DATA_RATE, default=default_data_rate): SPI_DATA_RATE_SCHEMA,
|
cv.Optional(CONF_DATA_RATE, default=default_data_rate): SPI_DATA_RATE_SCHEMA,
|
||||||
cv.Optional(CONF_SPI_MODE, default=default_mode): cv.enum(
|
cv.Optional(CONF_SPI_MODE, default=default_mode): cv.enum(
|
||||||
SPI_MODE_OPTIONS, upper=True
|
SPI_MODE_OPTIONS, upper=True
|
||||||
|
@ -369,6 +369,7 @@ class SPIComponent : public Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
using QuadSPIComponent = SPIComponent;
|
using QuadSPIComponent = SPIComponent;
|
||||||
|
using OctalSPIComponent = SPIComponent;
|
||||||
/**
|
/**
|
||||||
* Base class for SPIDevice, un-templated.
|
* Base class for SPIDevice, un-templated.
|
||||||
*/
|
*/
|
||||||
|
@ -211,11 +211,19 @@ class SPIBusHw : public SPIBus {
|
|||||||
buscfg.data1_io_num = data_pins[1];
|
buscfg.data1_io_num = data_pins[1];
|
||||||
buscfg.data2_io_num = data_pins[2];
|
buscfg.data2_io_num = data_pins[2];
|
||||||
buscfg.data3_io_num = data_pins[3];
|
buscfg.data3_io_num = data_pins[3];
|
||||||
buscfg.data4_io_num = -1;
|
if (data_pins.size() == 8) {
|
||||||
buscfg.data5_io_num = -1;
|
buscfg.data4_io_num = data_pins[4];
|
||||||
buscfg.data6_io_num = -1;
|
buscfg.data5_io_num = data_pins[5];
|
||||||
buscfg.data7_io_num = -1;
|
buscfg.data6_io_num = data_pins[6];
|
||||||
buscfg.flags |= SPICOMMON_BUSFLAG_QUAD;
|
buscfg.data7_io_num = data_pins[7];
|
||||||
|
buscfg.flags |= SPICOMMON_BUSFLAG_OCTAL;
|
||||||
|
} else {
|
||||||
|
buscfg.data4_io_num = -1;
|
||||||
|
buscfg.data5_io_num = -1;
|
||||||
|
buscfg.data6_io_num = -1;
|
||||||
|
buscfg.data7_io_num = -1;
|
||||||
|
buscfg.flags |= SPICOMMON_BUSFLAG_QUAD;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
buscfg.max_transfer_sz = MAX_TRANSFER_SIZE;
|
buscfg.max_transfer_sz = MAX_TRANSFER_SIZE;
|
||||||
auto err = spi_bus_initialize(channel, &buscfg, SPI_DMA_CH_AUTO);
|
auto err = spi_bus_initialize(channel, &buscfg, SPI_DMA_CH_AUTO);
|
||||||
|
@ -1,22 +1,36 @@
|
|||||||
spi:
|
spi:
|
||||||
- id: spi_id_1
|
|
||||||
type: single
|
|
||||||
clk_pin:
|
|
||||||
number: GPIO0
|
|
||||||
ignore_strapping_warning: true
|
|
||||||
allow_other_uses: false
|
|
||||||
mosi_pin: GPIO6
|
|
||||||
interface: hardware
|
|
||||||
- id: quad_spi
|
- id: quad_spi
|
||||||
type: quad
|
type: quad
|
||||||
interface: spi3
|
interface: spi3
|
||||||
clk_pin: 47
|
clk_pin:
|
||||||
|
number: 47
|
||||||
data_pins:
|
data_pins:
|
||||||
- number: 40
|
- allow_other_uses: true
|
||||||
allow_other_uses: false
|
number: 40
|
||||||
- 41
|
- allow_other_uses: true
|
||||||
- 42
|
number: 41
|
||||||
- 43
|
- allow_other_uses: true
|
||||||
|
number: 42
|
||||||
|
- allow_other_uses: true
|
||||||
|
number: 43
|
||||||
|
- id: octal_spi
|
||||||
|
type: octal
|
||||||
|
interface: hardware
|
||||||
|
clk_pin:
|
||||||
|
number: 0
|
||||||
|
data_pins:
|
||||||
|
- 36
|
||||||
|
- 37
|
||||||
|
- 38
|
||||||
|
- 39
|
||||||
|
- allow_other_uses: true
|
||||||
|
number: 40
|
||||||
|
- allow_other_uses: true
|
||||||
|
number: 41
|
||||||
|
- allow_other_uses: true
|
||||||
|
number: 42
|
||||||
|
- allow_other_uses: true
|
||||||
|
number: 43
|
||||||
- id: spi_id_3
|
- id: spi_id_3
|
||||||
interface: any
|
interface: any
|
||||||
clk_pin: 8
|
clk_pin: 8
|
||||||
|
Loading…
x
Reference in New Issue
Block a user