1.. _ec_host_cmd_backend_api:
2
3EC Host Command
4###############
5
6Overview
7********
8The host command protocol defines the interface for a host, or application processor, to
9communicate with a target embedded controller (EC). The EC Host command subsystem implements the
10target side of the protocol, generating responses to commands sent by the host. The host command
11protocol interface supports multiple versions, but this subsystem implementation only support
12protocol version 3.
13
14Architecture
15************
16The Host Command subsystem contains a few components:
17
18* Backend
19* General handler
20* Command handler
21
22The backend is a layer between a peripheral driver and the general handler. It is responsible for
23sending and receiving commands via chosen peripheral.
24
25The general handler validates data from the backend e.g. check sizes, checksum, etc. If the command
26is valid and the user has provided a handler for a received command id, the command handler is
27called.
28
29.. image:: ec_host_cmd.png
30   :align: center
31
32SHI (Serial Host Interface) is different to this because it is used only for communication with a
33host. SHI does not have API itself, thus the backend and peripheral driver layers are combined into
34one backend layer.
35
36.. image:: ec_host_cmd_shi.png
37   :align: center
38
39Another case is SPI. Unfortunately, the current SPI API can't be used to handle the host commands
40communication. The main issues are unknown command size sent by the host (the SPI transaction
41sends/receives specific number of bytes) and need to constant sending status byte (the SPI module
42is enabled and disabled per transaction). It forces implementing the SPI driver within a backend,
43as it is done for SHI. That means a SPI backend has to be implemented per chip family. However, it
44can be changed in the future once the SPI API is extended to host command needs. Please check `the
45discussion <https://github.com/zephyrproject-rtos/zephyr/issues/56091>`_.
46
47That approach requires configuring the SPI dts node in a special way. The main compatible string of
48a SPI node has changed to use the Host Command version of a SPI driver. The rest of the properties
49should be configured as usual. Example of the SPI node for STM32:
50
51.. code-block:: devicetree
52
53   &spi1 {
54           /* Change the compatible string to use the Host Command version of the
55            * STM32 SPI driver
56            */
57           compatible = "st,stm32-spi-host-cmd";
58           status = "okay";
59
60           dmas = <&dma2 3 3 0x38440 0x03>,
61                <&dma2 0 3 0x38480 0x03>;
62           dma-names = "tx", "rx";
63           /* This field is used to point at our CS pin */
64           cs-gpios = <&gpioa 4 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
65   };
66
67The STM32 SPI host command backend driver supports the :dtcompatible:`st,stm32h7-spi` and
68:dtcompatible:`st,stm32-spi-fifo` variant implementations. To enable these variants, append the
69corresponding compatible string. For example, to enable FIFO support and support for the STM32H7
70SoCs, modify the compatible string as shown.
71
72.. code-block:: devicetree
73
74   &spi1 {
75       compatible = "st,stm32h7-spi", "st,stm32-spi-fifo", "st,stm32-spi-host-cmd";
76       ...
77   };
78
79The chip that runs Zephyr is a SPI slave and the ``cs-gpios`` property is used to point our CS pin.
80For the SPI, it is required to set the backend chosen node ``zephyr,host-cmd-spi-backend``.
81
82The supported backend and peripheral drivers:
83
84* Simulator
85* SHI - ITE and NPCX
86* eSPI - any eSPI slave driver that support :kconfig:option:`CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD` and
87  :kconfig:option:`CONFIG_ESPI_PERIPHERAL_CUSTOM_OPCODE`
88* UART - any UART driver that supports the asynchronous API
89* SPI - STM32
90
91Initialization
92**************
93
94If the application configures one of the following backend chosen nodes and
95:kconfig:option:`CONFIG_EC_HOST_CMD_INITIALIZE_AT_BOOT` is set, then the corresponding backend
96initializes the host command subsystem by calling :c:func:`ec_host_cmd_init`:
97
98* ``zephyr,host-cmd-espi-backend``
99* ``zephyr,host-cmd-shi-backend``
100* ``zephyr,host-cmd-uart-backend``
101* ``zephyr,host-cmd-spi-backend``
102
103If no backend chosen node is configured, the application must call the :c:func:`ec_host_cmd_init`
104function directly. This way of initialization is useful if a backend is chosen in runtime
105based on e.g. GPIO state.
106
107Buffers
108*******
109
110The host command communication requires buffers for rx and tx. The buffers are be provided by the
111general handler if :kconfig:option:`CONFIG_EC_HOST_CMD_HANDLER_RX_BUFFER_SIZE` > 0 for rx buffer and
112:kconfig:option:`CONFIG_EC_HOST_CMD_HANDLER_TX_BUFFER_SIZE` > 0 for the tx buffer. The shared
113buffers are useful for applications that use multiple backends. Defining separate buffers by every
114backend would increase the memory usage. However, some buffers can be defined by a peripheral driver
115e.g. eSPI. These ones should be reused as much as possible.
116
117Logging
118*******
119
120The host command has an embedded logging system of the ongoing communication. The are a few logging
121levels:
122
123* :c:macro:`LOG_INF` is used to log a command id of a new command and not success responses. Repeats of the
124  same command are not logged
125* :c:macro:`LOG_DBG` logs every command, even repeats
126* :c:macro:`LOG_DBG` + :kconfig:option:`CONFIG_EC_HOST_CMD_LOG_DBG_BUFFERS` logs every command and responses
127  with the data buffers
128
129API Reference
130*************
131
132.. doxygengroup:: ec_host_cmd_interface
133