133 lines
5.3 KiB
ReStructuredText
133 lines
5.3 KiB
ReStructuredText
.. _ec_host_cmd_backend_api:
|
|
|
|
EC Host Command
|
|
###############
|
|
|
|
Overview
|
|
********
|
|
The host command protocol defines the interface for a host, or application processor, to
|
|
communicate with a target embedded controller (EC). The EC Host command subsystem implements the
|
|
target side of the protocol, generating responses to commands sent by the host. The host command
|
|
protocol interface supports multiple versions, but this subsystem implementation only support
|
|
protocol version 3.
|
|
|
|
Architecture
|
|
************
|
|
The Host Command subsystem contains a few components:
|
|
|
|
* Backend
|
|
* General handler
|
|
* Command handler
|
|
|
|
The backend is a layer between a peripheral driver and the general handler. It is responsible for
|
|
sending and receiving commands via chosen peripheral.
|
|
|
|
The general handler validates data from the backend e.g. check sizes, checksum, etc. If the command
|
|
is valid and the user has provided a handler for a received command id, the command handler is
|
|
called.
|
|
|
|
.. image:: ec_host_cmd.png
|
|
:align: center
|
|
|
|
SHI (Serial Host Interface) is different to this because it is used only for communication with a
|
|
host. SHI does not have API itself, thus the backend and peripheral driver layers are combined into
|
|
one backend layer.
|
|
|
|
.. image:: ec_host_cmd_shi.png
|
|
:align: center
|
|
|
|
Another case is SPI. Unfortunately, the current SPI API can't be used to handle the host commands
|
|
communication. The main issues are unknown command size sent by the host (the SPI transaction
|
|
sends/receives specific number of bytes) and need to constant sending status byte (the SPI module
|
|
is enabled and disabled per transaction). It forces implementing the SPI driver within a backend,
|
|
as it is done for SHI. That means a SPI backend has to be implemented per chip family. However, it
|
|
can be changed in the future once the SPI API is extended to host command needs. Please check `the
|
|
discussion <https://github.com/zephyrproject-rtos/zephyr/issues/56091>`_.
|
|
|
|
That approach requires configuring the SPI dts node in a special way. The main compatible string of
|
|
a SPI node has changed to use the Host Command version of a SPI driver. The rest of the properties
|
|
should be configured as usual. Example of the SPI node for STM32:
|
|
|
|
.. code-block:: devicetree
|
|
|
|
&spi1 {
|
|
/* Change the compatible string to use the Host Command version of the
|
|
* STM32 SPI driver
|
|
*/
|
|
compatible = "st,stm32-spi-host-cmd";
|
|
status = "okay";
|
|
|
|
dmas = <&dma2 3 3 0x38440 0x03>,
|
|
<&dma2 0 3 0x38480 0x03>;
|
|
dma-names = "tx", "rx";
|
|
/* This field is used to point at our CS pin */
|
|
cs-gpios = <&gpioa 4 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
|
|
};
|
|
|
|
The STM32 SPI host command backend driver supports the :dtcompatible:`st,stm32h7-spi` and
|
|
:dtcompatible:`st,stm32-spi-fifo` variant implementations. To enable these variants, append the
|
|
corresponding compatible string. For example, to enable FIFO support and support for the STM32H7
|
|
SoCs, modify the compatible string as shown.
|
|
|
|
.. code-block:: devicetree
|
|
|
|
&spi1 {
|
|
compatible = "st,stm32h7-spi", "st,stm32-spi-fifo", "st,stm32-spi-host-cmd";
|
|
...
|
|
};
|
|
|
|
The chip that runs Zephyr is a SPI slave and the `cs-gpios` property is used to point our CS pin.
|
|
For the SPI, it is required to set the backend chosen node ``zephyr,host-cmd-spi-backend``.
|
|
|
|
The supported backend and peripheral drivers:
|
|
|
|
* Simulator
|
|
* SHI - ITE and NPCX
|
|
* eSPI - any eSPI slave driver that support :kconfig:option:`CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD` and
|
|
:kconfig:option:`CONFIG_ESPI_PERIPHERAL_CUSTOM_OPCODE`
|
|
* UART - any UART driver that supports the asynchronous API
|
|
* SPI - STM32
|
|
|
|
Initialization
|
|
**************
|
|
|
|
If the application configures one of the following backend chosen nodes and
|
|
:kconfig:option:`CONFIG_EC_HOST_CMD_INITIALIZE_AT_BOOT` is set, then the corresponding backend
|
|
initializes the host command subsystem by calling :c:func:`ec_host_cmd_init`:
|
|
|
|
* ``zephyr,host-cmd-espi-backend``
|
|
* ``zephyr,host-cmd-shi-backend``
|
|
* ``zephyr,host-cmd-uart-backend``
|
|
* ``zephyr,host-cmd-spi-backend``
|
|
|
|
If no backend chosen node is configured, the application must call the :c:func:`ec_host_cmd_init`
|
|
function directly. This way of initialization is useful if a backend is chosen in runtime
|
|
based on e.g. GPIO state.
|
|
|
|
Buffers
|
|
*******
|
|
|
|
The host command communication requires buffers for rx and tx. The buffers are be provided by the
|
|
general handler if :kconfig:option:`CONFIG_EC_HOST_CMD_HANDLER_RX_BUFFER_SIZE` > 0 for rx buffer and
|
|
:kconfig:option:`CONFIG_EC_HOST_CMD_HANDLER_TX_BUFFER_SIZE` > 0 for the tx buffer. The shared
|
|
buffers are useful for applications that use multiple backends. Defining separate buffers by every
|
|
backend would increase the memory usage. However, some buffers can be defined by a peripheral driver
|
|
e.g. eSPI. These ones should be reused as much as possible.
|
|
|
|
Logging
|
|
*******
|
|
|
|
The host command has an embedded logging system of the ongoing communication. The are a few logging
|
|
levels:
|
|
|
|
* `LOG_INF` is used to log a command id of a new command and not success responses. Repeats of the
|
|
same command are not logged
|
|
* `LOG_DBG` logs every command, even repeats
|
|
* `LOG_DBG` + :kconfig:option:`CONFIG_EC_HOST_CMD_LOG_DBG_BUFFERS` logs every command and responses
|
|
with the data buffers
|
|
|
|
API Reference
|
|
*************
|
|
|
|
.. doxygengroup:: ec_host_cmd_interface
|