# UART

Source: [https://docs.qualcomm.com/doc/80-70014-8Y/topic/uart.html](https://docs.qualcomm.com/doc/80-70014-8Y/topic/uart.html)

UART 设备以异步方式发送数据。因此，时钟信号不会使发送 UART 的位输出与接收 UART 的位采样同步。发送 UART 会向正在传输的数据包中添加起始位和停止位，但不会添加时钟信号。这些位定义了数据包的开始和结束，因此接收 UART 知道何时开始读取这些位。

当接收 UART 检测到起始位时，便开始以特定频率（称为波特率）读取传入的位。波特率用于衡量数据传输速度，以每秒位数 (bps) 表示。发送 UART 与接收 UART 的波特率必须大致相同，最多相差 10% 左右，否则二者的位时序会相差甚远。两个 UART 发送和接收的数据包结构必须相同。

Figure : 两个 UART 设备之间的数据传输
            ![图片显示了两个 UART 设备之间的数据传输。](data:image/png;base64,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)

下面列出了用于确定成功传输的参数。

- **波特率**：数据的传输速度用波特率表示，以每秒位数为单位。发送 UART 与接收 UART 必须采用一致的波特率才能成功传输数据。
- **起始位**：该位是在实际数据之前添加的同步位。起始位标记数据包的开始。
- **停止位**：该位标记数据包的结束。其长度通常为两位，但往往只使用一位。
- **奇偶校验位**：该位可供接收器用于检查收到的数据是否正确。奇偶校验是一种 low-level 错误检验系统，具体分为两种类型：偶校验和奇校验。
- **数据位**：从发送方向接收方传输的实际数据。数据帧的长度可以是 5 位到 9 位之间的任何值（如果不使用奇偶校验则为 8 位，如果使用奇偶校验则为 9 位）。
- **流量控制**：通过 `cts_n/rfr_n` 线路控制。流量控制为可选项，`cts_n/rfr_n` 对也为可选项。

下图所示为 UART 数据包示例。
Figure : UART 数据包
                <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- 由 Microsoft Visio, SVG Export 生成 uart-data-packet.svg Page-1 -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="8.08333in" height="3.61841in" viewbox="0 0 582 260.526" xml:space="preserve" color-interpolation-filters="sRGB" class="st8"><v:documentproperties v:langid="2052">	<v:userdefs>		<v:ud v:nameu="msvNoAutoConnect" v:val="VT0(1):26"></v:ud>	</v:userdefs></v:documentproperties>
<style>.svg-1 .st1 { fill: #ffffff; stroke: #000000; stroke-linecap: round; stroke-linejoin: round; stroke-width: 0.999998 }
.svg-1 .st2 { fill: #000000; font-family: Arial; font-size: 0.833336em }
.svg-1 .st3 { font-family: 黑体; font-size: 1em }
.svg-1 .st4 { fill: none }
.svg-1 .st5 { stroke: #000000; stroke-linecap: round; stroke-linejoin: round; stroke-width: 0.999998 }
.svg-1 .st6 { fill: none; stroke: none; stroke-linecap: round; stroke-linejoin: round; stroke-width: 0.749999 }
.svg-1 .st7 { fill: #000000; font-family: 黑体; font-size: 0.833336em }
.svg-1 .st8 { fill: none; fill-rule: evenodd; font-size: 12px; overflow: visible; stroke-linecap: square; stroke-miterlimit: 3 }</style>
<g v:mid="0" v:index="1" v:groupcontext="foregroundPage">	<title>Page-1</title>	<v:pageproperties v:drawingscale="1" v:pagescale="1" v:drawingunits="19" v:shadowoffsetx="8.99998" v:shadowoffsety="-8.99998"></v:pageproperties>	<g id="shape1-1" v:mid="1" v:groupcontext="shape" transform="translate(18.5004,-109.171)">		<title>Rectangle</title>		<desc>1 start bit</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(3.99999,3.99999,3.99999,3.99999)"></v:textblock>		<v:textrect cx="34.9354" cy="242.289" width="69.88" height="36.473"></v:textrect>		<rect x="0" y="224.052" width="69.8717" height="36.473" class="st1"></rect>		<text x="10.77" y="245.54" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>1 <tspan class="st3">个起始位</tspan></text>		</g>	<g id="shape2-5" v:mid="2" v:groupcontext="shape" transform="translate(88.3721,-109.171)">		<title>Rectangle.2</title>		<desc>5 to 9 data bits</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(3.99999,3.99999,3.99999,3.99999)"></v:textblock>		<v:textrect cx="153.717" cy="242.289" width="307.44" height="36.473"></v:textrect>		<rect x="0" y="224.052" width="307.435" height="36.473" class="st1"></rect>		<text x="118.99" y="245.54" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>5 <tspan class="st3">到</tspan> 9 <tspan class="st3">个数据位</tspan></text>		</g>	<g id="shape3-10" v:mid="3" v:groupcontext="shape" transform="translate(395.808,-109.171)">		<title>Rectangle.3</title>		<desc>0 to 1 parity bits</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(3.99999,3.99999,3.99999,3.99999)"></v:textblock>		<v:textrect cx="41.9226" cy="242.289" width="83.85" height="36.473"></v:textrect>		<rect x="0" y="224.052" width="83.846" height="36.473" class="st1"></rect>		<text x="22.19" y="239.04" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>0 <tspan class="st3">到</tspan> 1 <tspan class="st3">个<v:lf></v:lf></tspan><tspan x="16.92" dy="1.3em" class="st3">奇偶校验位</tspan></text>		</g>	<g id="shape4-16" v:mid="4" v:groupcontext="shape" transform="translate(479.654,-109.171)">		<title>Rectangle.4</title>		<desc>1 to 2 stop bits</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(3.99999,3.99999,3.99999,3.99999)"></v:textblock>		<v:textrect cx="41.9226" cy="242.289" width="83.85" height="36.473"></v:textrect>		<rect x="0" y="224.052" width="83.846" height="36.473" class="st1"></rect>		<text x="22.19" y="239.04" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>1 <tspan class="st3">到</tspan> 2 <tspan class="st3">个<v:lf></v:lf></tspan><tspan x="26.92" dy="1.3em" class="st3">停止位</tspan></text>		</g>	<g id="shape5-22" v:mid="5" v:groupcontext="shape" transform="translate(281.509,41.1546) rotate(90)">		<title>Left Brace</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:prompt="" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<path d="M64.3 260.53 A90.7892 86.0816 90 0 1 32.15 206.27 L32.15 -10.73 L0 -10.73 L32.15 -10.73 L32.15 -227.74 A90.7892					 86.0816 90 0 1 64.3 -281.99 L64.3 260.53 Z" class="st4"></path>		<path d="M64.3 260.53 A90.7892 86.0816 90 0 1 32.15 206.27 L32.15 -10.73 L0 -10.73 L32.15 -10.73 L32.15 -227.74 A90.7892					 86.0816 90 0 1 64.3 -281.99" class="st5"></path>	</g>	<g id="shape6-25" v:mid="6" v:groupcontext="shape" transform="translate(135.286,216.261) rotate(-90)">		<title>Left Brace.9</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:prompt="" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<path d="M56.28 260.53 A75.3469 51.4493 180 0 1 28.14 229.78 L28.14 106.81 L0 106.81 L28.14 106.81 L28.14 -16.17 A75.3469					 51.4493 180 0 1 56.28 -46.91 L56.28 260.53 Z" class="st4"></path>		<path d="M56.28 260.53 A75.3469 51.4493 180 0 1 28.14 229.78 L28.14 106.81 L0 106.81 L28.14 106.81 L28.14 -16.17 A75.3469					 51.4493 180 0 1 56.28 -46.91" class="st5"></path>	</g>	<g id="shape7-28" v:mid="7" v:groupcontext="shape" transform="translate(257.32,-220.671)">		<title>工作表.7</title>		<desc>Packet</desc>		<v:userdefs></v:userdefs>		<v:textblock v:margins="rect(3.99999,3.99999,3.99999,3.99999)"></v:textblock>		<v:textrect cx="34.9354" cy="249.786" width="69.88" height="21.4796"></v:textrect>		<rect x="0" y="239.046" width="69.8717" height="21.4796" class="st6"></rect>		<text x="19.94" y="253.04" class="st7" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>数据包</text>		</g>	<g id="shape8-31" v:mid="8" v:groupcontext="shape" transform="translate(200.096,-18.3755)">		<title>工作表.8</title>		<desc>Data frame</desc>		<v:userdefs></v:userdefs>		<v:textblock v:margins="rect(3.99999,3.99999,3.99999,3.99999)"></v:textblock>		<v:textrect cx="41.9226" cy="247.638" width="83.85" height="25.7755"></v:textrect>		<rect x="0" y="234.75" width="83.846" height="25.7755" class="st6"></rect>		<text x="26.92" y="250.89" class="st7" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>数据帧</text>		</g></g>
</svg>

## UART 功能

Source: [https://docs.qualcomm.com/doc/80-70014-8Y/topic/uart.html](https://docs.qualcomm.com/doc/80-70014-8Y/topic/uart.html)

本节介绍 UART 传输模式，适用于使用低速和高速传输模式 (FIFO/DMA) 的应用。

### Linux

UART 核心支持以下功能：
- FIFO 模式和 CPU DMA 模式。
- 支持 300 bps 至 4 Mbps 的波特率。

两种传输速度模式的具体信息如下。
- 高速模式：DMA 用于在 Rx/Tx 缓冲区与系统内存之间传输数据。如果使用支持更高波特率和更大数据包的高速 UART 驱动器，可以实现更高的性能。例如，蓝牙无线技术连接模块。
- 低速模式：FIFO 模式用于在 Rx/Tx 缓冲区与系统内存之间传输数据。

### 启动

- UART 以 FIFO 模式工作。
- Rx/Tx 每个字符 5 位至 8 位。
- 最高支持 115200 的波特率。

### aDSP

- 支持 FIFO 传输模式。
- Rx/Tx 每个字符 5 位至 8 位。
- 支持的波特率：115200、230400、460800、921600、1000000、3000000 和 6000000。

## UART 接口

Source: [https://docs.qualcomm.com/doc/80-70014-8Y/topic/uart.html](https://docs.qualcomm.com/doc/80-70014-8Y/topic/uart.html)

本节提供不同子系统的 UART 驱动程序配置的路径。

### Linux

| 文件类型 | 说明 |
| --- | --- |
| 设备树源 | 有关 QUP v3 串行引擎接口设备节点以及低速和高速 UART 设备节点的芯片组配置的设备树属性，可访问 [https://git.linaro.org/kernel-org/linux-next.git/tree/arch/arm64/boot/dts/qcom/sc7280.dtsi](https://git.linaro.org/kernel-org/linux-next.git/tree/arch/arm64/boot/dts/qcom/sc7280.dtsi)。 |
| `Pinctrl` 设置 | 有关 UART 设备节点的 QUP v3 串行引擎接口的 GPIO 设置的设备树属性，可访问以下文件路径。<ul class="ul" id="uart_interface__ul_hsz_14w_41c"><br>                                    <li class="li">相应的 QUP v3 串行引擎的引脚控制表位于 <span class="ph filepath">&lt;workspace_path_of_LINUX_kernel_image&gt;\sources\kernel\kernel_platform\kernel\arch\arm64\boot\dts\qcom\&lt;chipset&gt;.dts</span>。</li><br><br>                                    <li class="li">有关用于覆盖芯片组的 DTSI 配置示例，可访问 <a href="https://github.com/torvalds/linux/blob/master/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts" target="_blank" class="xref cursorpointer" onclick="Window.BookmapComponent.navigateExternalFile('https://github.com/torvalds/linux/blob/master/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts')">https://github.com/torvalds/linux/blob/master/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts</a>。</li><br><br>                                </ul> |
| TrustZone 设置 | 有关针对不同子系统加载 QUP v3 串行引擎 UART 固件的 TrustZone 访问控制设置，可访问 /firmware/qualcomm-linux-spf-1-0\_ap\_standard\_oem\_nomodem/TZ.XF.5.0/trustzone\_images/core/settings/buses/qup\_accesscontrol/qupv3/config/&lt;chipset&gt;/QUPAC\_Access.c。 |

### 启动（仅限 UEFI）

| 文件类型 | 说明 |
| --- | --- |
| QUP v3 串行引擎配置 | 有关 boot 子系统中用于启用 UART 串行引擎的 QUP v3 串行引擎配置，可访问 /firmware/qualcomm-linux-spf-1-0\_ap\_standard\_oem\_nomodem/BOOT.MXF.1.0.c1/boot\_images/boot/QcomPkg/SocPkg/&lt;chipset&gt;/Settings/UART/UartSettings.c |
| TrustZone 设置 | 有关针对不同子系统配置 UART 的 QUP v3 串行引擎固件中的 TrustZone 访问控制设置，可访问 /firmware/qualcomm-linux-spf-1-0\_ap\_standard\_oem\_nomodem/TZ.XF.5.0/trustzone\_images/core/settings/buses/qup\_accesscontrol/qupv3/config/&lt;chipset&gt;/QUPAC\_Access.c |

### aDSP/SLPI

| 文件类型 | 说明 |
| --- | --- |
| QUP v3 串行引擎配置 | 有关 aDSP 子系统中用于启用 UART 的 QUP v3 串行引擎配置设置，可参见以下文件。<ul class="ul" id="uart_interface__ul_lrk_1hn_rzb"><br>                                    <li class="li"><span class="ph filepath">/firmware/qualcomm-linux-spf-1-0_ap_standard_oem_nomodem/ADSP.HT.5.5.c8/adsp_proc/core/settings/buses/qup_common/config/&lt;chipset&gt;/adsp/ssc/qup_devcfg.c</span></li><br><br>                                    <li class="li"><span class="ph filepath">/firmware/qualcomm-linux-spf-1-0_ap_standard_oem_nomodem/ADSP.HT.5.5.c8/adsp_proc/core/settings/buses/qup_fw/config/&lt;chipset&gt;/fw_devcfg.c</span></li><br><br>                                </ul> |
| 固件配置设置 | 有关在 aDSP 软件中配置 UART 的 QUP v3 串行引擎固件设置，可参见以下文件。<ul class="ul" id="uart_interface__ul_wpr_p5j_51c"><br>                                    <li class="li"><span class="ph filepath">/firmware/qualcomm-linux-spf-1-0_ap_standard_oem_nomodem/ADSP.HT.5.5.c8/adsp_proc/core/settings/buses/qup_fw/config/&lt;chipset&gt;/fw_devcfg.c</span></li><br><br>                                    <li class="li"><span class="ph filepath">/firmware/qualcomm-linux-spf-1-0_ap_standard_oem_nomodem/ADSP.HT.5.5.c8/adsp_proc/core/settings/buses/qup_fw/config/&lt;chipset&gt;/fw_devcfg.xml</span></li><br><br>                                </ul> |

### UART API

Source: [https://docs.qualcomm.com/doc/80-70014-8Y/topic/uart.html](https://docs.qualcomm.com/doc/80-70014-8Y/topic/uart.html)

本节列出了以下子系统的 UART API。

### Linux

- 有关 Linux API 的信息，可访问 [https://github.com/torvalds/linux/blob/master/include/linux/tty.h](https://github.com/torvalds/linux/blob/master/include/linux/tty.h)。

### 启动

有关 API 的信息，可参见 QcomPkg/Library/UartQupv3Lib/UartApi.h 文件。

- 初始化 UART 端口。
    1. 打开 UART 端口。
    2. 配置相应的时钟、中断和 GPIO。
    3. 不要从 ISR 上下文中调用函数。

        {{uart_open(uart_handle* h, uart_port_id id, uart_open_config* config); }}Copy to clipboard
- 通过异步调用从给定的缓冲区发送数据。缓冲区排队等待发送。

        uart_transmit(uart_handle h, char* buf, uint32 bytes_to_tx, void* cb_data);Copy to clipboard
- 通过异步调用为用于接收数据的缓冲区排队。
    1. 在 `uart_open` 之后立即调用 `uart_receive` 为缓冲区排队。
    2. 一次最多可有两个缓冲区排队。不要从 ISR 上下文中调用函数。

        uart_receive(uart_handle h, char* buf, uint32 buf_size, void* cb_data);Copy to clipboard
- 反初始化 UART 端口。
    1. 释放与该 UART 相关的时钟、中断和 GPIO 句柄。
    2. 取消所有待处理的传输。
    3. 不要从 ISR 上下文中调用函数。

         uart_close(uart_handle h);Copy to clipboard

### aDSP

- 初始化 UART 端口。打开 UART 端口并配置相应的时钟、中断和 GPIO。

        uart_open(uart_handle* h, uart_port_id id, uart_open_config* config); Copy to clipboard
- 通过接通所有资源的时钟为 UART 核心上电。

        uart_power_on(uart_handle h);Copy to clipboard
- 通过异步调用从给定缓冲区发送数据。缓冲区排队等待发送。

        uart_transmit(uart_handle h, uint8* buf, uint32 bytes_to_tx, void* cb_data); Copy to clipboard
- 通过异步调用为用于接收数据的缓冲区排队。

        uart_receive(uart_handle h, uint8* buf, uint32 buf_size, void* cb_data); Copy to clipboard
- 通过关闭所有资源的时钟使 UART 核心断电。客户端负责确保所有待处理的发送请求均已完成。如果启用 `wake_on_rx`，则注册唤醒中断。

        uart_power_off(uart_handle h, boolean wake_on_rx, UART_WAKEUP_CALLBACK wake_cb, void* wake_cb_data); Copy to clipboard
- 反初始化 UART 端口。释放与 UART 相关的时钟、中断和 GPIO 句柄，并取消待处理的传输。

        uart_close(uart_handle h); Copy to clipboard

## UART 软件

Source: [https://docs.qualcomm.com/doc/80-70014-8Y/topic/uart.html](https://docs.qualcomm.com/doc/80-70014-8Y/topic/uart.html)

本节提供 UART 设备树配置的相关信息，以及设备节点的相关文档。

### Linux

有关内核设备实例的信息，可访问 [https://github.com/torvalds/linux/blob/master/Documentation/devicetree/bindings/serial/qcom%2Cserial-geni-qcom.yaml](https://github.com/torvalds/linux/blob/master/Documentation/devicetree/bindings/serial/qcom%2Cserial-geni-qcom.yaml)。

有关 UART 驱动程序文件的信息，可访问 [https://github.com/torvalds/linux/blob/master/drivers/tty/serial/qcom_geni_serial.c](https://github.com/torvalds/linux/blob/master/drivers/tty/serial/qcom_geni_serial.c)

    uart7: serial@99c000 {
    /* Manufacturer model of serial driver */
    compatible = "qcom,geni-uart";
    /* SE address and size */
    reg = <0 0x0099c000 0 0x4000>;
    /*Clocks for SE */
    clocks = <&gcc GCC_QUPV3_WRAP0_S7_CLK>;
    clock-names = "se";
    /* pinctrl setting */
    pinctrl-names = "default";
    pinctrl-0 = <&qup_uart7_cts>, <&qup_uart7_rts>, <&qup_uart7_tx>, <&qup_uart7_rx>;
    interrupts = <GIC_SPI 608 IRQ_TYPE_LEVEL_HIGH>;
    power-domains = <&rpmhpd SC7280_CX>;
    operating-points-v2 = <&qup_opp_table>;
    interconnects = <&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
    <&gem_noc MASTER_APPSS_PROC 0 &cnoc2 SLAVE_QUP_0 0>;			interconnect-names = "qup-core", "qup-config";
    /* To enable QUPV3 serial engine instance for UART protocol, change Status to OK */			status = "disabled";		};	}Copy to clipboard

有关串行引擎 GPIO 的配置设置，可访问 [https://git.linaro.org/kernel-org/linux-next.git/tree/arch/arm64/boot/dts/qcom/sc7280.dtsi](https://git.linaro.org/kernel-org/linux-next.git/tree/arch/arm64/boot/dts/qcom/sc7280.dtsi)。

    qup_uart7_cts: qup-uart7-cts-state {			pins = "gpio28";			function = "qup07";		};
    		qup_uart7_rts: qup-uart7-rts-state {			pins = "gpio29";			function = "qup07";		};
    		qup_uart7_tx: qup-uart7-tx-state {			pins = "gpio30";			function = "qup07";		};
    		qup_uart7_rx: qup-uart7-rx-state {			pins = "gpio31";			function = "qup07";		};
    Copy to clipboard

必须使 QUPAC\_Access.c 文件中的 TrustZone 配置保持一致，以确保可以使用 GPIO/QUP v3。可通过以下路径访问 TrustZone 镜像：/firmware/qualcomm-linux-spf-1-0\_ap\_standard\_oem\_nomodem/TZ.XF.5.0/trustzone\_images/core/settings/buses/qup\_accesscontrol/qupv3/config/&lt;chipset&gt;/QUPAC\_Access.c。
                修改所需的设置，或者参考针对 QUP v3 串行引擎的特定实例分配的默认设置。

QUP v3 既支持启用流量控制的 4 线制 UART，也支持未启用流量控制的 2 线制 UART。以下 TrustZone 访问示例用于控制进入这两种模式。用于启用 UART 协议的 QUP v3 串行引擎配置如下：
- 针对 SE7 启用的默认配置（作为 HS UART）

        { QUPV3_0_SE7, QUPV3_PROTOCOL_UART_4W, QUPV3_MODE_FIFO, AC_HLOS, TRUE, TRUE, FALSE }, Copy to clipboard
- 针对 SE5 的 2 线制 UART 配置

        uart5: serial@994000 {
        compatible = "qcom,geni-uart";
        reg = <0 0x00994000 0 0x4000>;
        clocks = <&gcc GCC_QUPV3_WRAP0_S5_CLK>;
        clock-names = "se";
        pinctrl-names = "default";
        pinctrl-0 =  <&qup_uart5_tx>, <&qup_uart5_rx>;
        interrupts = <GIC_SPI 606 IRQ_TYPE_LEVEL_HIGH>;
        power-domains = <&rpmhpd SC7280_CX>;
        operating-points-v2 = <&qup_opp_table>;
        interconnects = <&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
            <&gem_noc MASTER_APPSS_PROC 0 &cnoc2 SLAVE_QUP_0 0>;
        interconnect-names = "qup-core", "qup-config";
        status = "disabled";
        };Copy to clipboard

        { QUPV3_0_SE5, QUPV3_PROTOCOL_UART_2W, QUPV3_MODE_FIFO,
        AC_HLOS, TRUE, FALSE, FALSE },Copy to clipboard

### 启动

在启动过程中，可使用 /firmware/qualcomm-linux-spf-1-0\_ap\_standard\_oem\_nomodem/BOOT.MXF.1.0.c1/boot\_images/boot/QcomPkg/SocPkg/&lt;chipset&gt;/Settings/UART/UartSettings.c 文件将 QUP v3 串行引擎配置为 UART。

    UART_PROPERTIES devices =
    {
       // MAIN_PORT
       0x00994000,    // Serial Engine Base address
       0x009C0000,// qup_common base address
       0x2001c161,  // GPIO TX pin Config
       0x2000c171,  // GPIO RX Pin Config
       0,           // gpio_cts_config
       0,           // gpio_rfr_config
       0,           // clock_id_index
       (void*)0,        // bus_clock_id
       (void*)CLK_QUPV3_WRAP0_S5,     // core_clock_id
       0,          // irq number not used
       0,  //TCSR base
       0,  // TCSR offset
       0   // TCSR value
    
    };
    Copy to clipboard

**GPIO 配置**
下表列出了 GPIO 配置。

| 位 | 参数 |
| :---: | --- |
| [0:3] | GPIO 功能 |
| [4:13] | GPIO 编号 |
| [14] | 方向 |
| [15:17] | 上下拉类型 |
| [18:21] | 驱动强度 |

每个 GPIO 都应基于以下位域进行配置。

    <!--
    GPIO configuration calculation
    
    GPIO DIR values
    GPIO_INPUT = 0x0
    GPIO_OUTPUT = 0x1
    
    GPIO_PULL values
    GPIO_NO_PULL = 0, /**< -- Do not specify a pull. */
    GPIO_PULL_DOWN = 0x1, /**< -- Pull the GPIO down. */
    GPIO_KEEPER_ENABLE = 0x2, /**< -- Keeper Enable. */
    GPIO_PULL_UP = 0x3, /**< -- Pull the GPIO up. */
    
    GPIO_DRV_STRENGTH values
    GPIO_2P0MA = 0, /**< -- Specify a 2 mA drive. */
    GPIO_4P0MA = 0x1, /**< -- Specify a 4 mA drive. */
    GPIO_6P0MA = 0x2, /**< -- Specify a 6 mA drive. */
    GPIO_8P0MA = 0x3, /**< -- Specify a 8 mA drive. */
    
    GPIO_FUNC_SELECT_Value
    GPIO_FS_VAL =0, //Specifies GPIO function
    
    GPIO_FS_VAL =0X1, //Specify NON GPIO function( UART/SPI/I2C)
    GPIO configuration = (GPIO_NUM & 0xFF) << 0x10 |
    (GPIO_FS_VAL & 0xF) << 0xC |
    (GPIO_DRV_STRENGTH & 0xF) << 0x8 |
    (GPIO_PULL & 0xF) << 0x4 |
    (GPIO_DIR & 0xF)
    
    -->
    /*
    | RESERVED | GPIO NUM | DRIVE | FUNC | PULL | DIR |
    -------------------------------------------------------------------------
    | 0000 | 0000 | 0001 | 1110 | 0001 | 0001 | 0010 | 0001 |
    -------------------------------------------------------------------------
    */Copy to clipboard

### aDSP

在 aDSP 子系统的启动序列期间，将执行 SSC QUP 的固件加载。因此，配置文件位于 aDSP 编译版本 (/firmware/qualcomm-linux-spf-1-0\_ap\_standard\_oem\_nomodem/ADSP.HT.5.5.c8/adsp\_proc/core/settings/buses/qup\_fw/config/&lt;chipset&gt;/fw\_devcfg.c) 中。

以下配置是在 FIFO 模式下向 SSC QUP SE5/6 中加载 UART 固件的示例。

                       offset,        protocol,   mode,  load_fw, dfs_mode
    se_cfg se0_cfg = { 0x80000, SE_PROTOCOL_I3C,    GSI,     TRUE, TRUE  };
    se_cfg se1_cfg = { 0x84000, SE_PROTOCOL_I2C,    GSI,     TRUE, TRUE  };
    se_cfg se2_cfg = { 0x88000, SE_PROTOCOL_I2C,    GSI,     TRUE, TRUE  };
    se_cfg se3_cfg = { 0x8C000, SE_PROTOCOL_I2C,    GSI,     FALSE, TRUE  };
    se_cfg se4_cfg = { 0x90000, SE_PROTOCOL_SPI,   	GSI,     TRUE, TRUE };
    se_cfg se5_cfg = { 0x94000, SE_PROTOCOL_UART,   FIFO,    TRUE,FALSE };
    se_cfg se6_cfg = { 0x98000, SE_PROTOCOL_UART,   FIFO,    TRUE,FALSE  };
    Copy to clipboard

GPIO 配置：QUP 通用驱动程序中的每个串行引擎均采用默认 GPIO 配置（根据芯片组特定的配置中的协议）。
                QUP 通用驱动程序根据串行引擎中加载的协议从 /firmware/qualcomm-linux-spf-1-0\_ap\_standard\_oem\_nomodem/ADSP.HT.5.5.c8/adsp\_proc/core/settings/buses/qup\_common/config/&lt;chipset&gt;/adsp/ssc/qup\_instance\_mapping.c 中获取 GPIO 配置。
                可按照如下所示覆盖默认 GPIO 配置。

    {      .instance_id          =  6 ,         //Instance ID
            .qup              =  QUP_SSC,    //QUP Type
            .se_index         =  5,          //SE ID
            .se_data          =  NULL,       //devcfg_map
            .protocol_io_cfg  =  {
                                    TLMM_MAP(TLMM_GPIO_KEEPER ,TLMM_GPIO_2MA,TLMM_GPIO_KEEPER ),              //SLEEP CFG
                                    TLMM_MAP(TLMM_GPIO_NO_PULL,TLMM_GPIO_6MA,TLMM_GPIO_KEEPER ),              //SPI CFG
                                    TLMM_MAP(TLMM_GPIO_NO_PULL,TLMM_GPIO_2MA,TLMM_GPIO_NO_PULL),              //UART CFG
                                    TLMM_MAP(TLMM_GPIO_PULL_UP,TLMM_GPIO_2MA,TLMM_GPIO_NO_PULL),              //I2C CFG
                                    TLMM_MAP(TLMM_GPIO_PULL_UP,TLMM_GPIO_2MA,TLMM_GPIO_KEEPER )               //I3C CFG
                                 },
            .se_exclusive     =  TRUE,
    }
    Copy to clipboard

TLMM\_MAP 是用于初始化工作和休眠状态 GPIO 配置的宏。以下为 TLMM\_MAP 宏的使用示例。

    TLMM_MAP (active state pull type, drive strength, sleep state pull type)Copy to clipboard

## UART 工具

Source: [https://docs.qualcomm.com/doc/80-70014-8Y/topic/uart.html](https://docs.qualcomm.com/doc/80-70014-8Y/topic/uart.html)

本节介绍 UART 串行接口驱动程序的各种测试工具和方法，用于确认 UART 数据传输。

### Linux

更多详细信息，可访问 [https://docs.kernel.org/admin-guide/serial-console.html](https://docs.kernel.org/admin-guide/serial-console.html)。

## UART 配置

Source: [https://docs.qualcomm.com/doc/80-70014-8Y/topic/uart.html](https://docs.qualcomm.com/doc/80-70014-8Y/topic/uart.html)

本节介绍如何在内核中启用 UART。

### Linux

需要以下驱动程序内核配置才能支持 UART 接口。
- UART 驱动程序： [https://github.com/torvalds/linux/blob/master/drivers/tty/serial/qcom_geni_serial.c](https://github.com/torvalds/linux/blob/master/drivers/tty/serial/qcom_geni_serial.c)
- 内核 `defconfig` 文件路径： &lt;workspace\_path\_of\_LINUX\_kernel\_image&gt;\sources\kernel \kernel\_platform\kernel\arch\arm64/configs/qcom\_defconfig

将启用以下内核配置。
- `CONFIG_QCOM_GENI_SE=y`
- `CONFIG_SERIAL_QCOM_GENI=y`

要启用串行节点进行环回验证，需对 /arch/arm64/boot/dts/qcom/&lt;chipset&gt;.dtsi 文件应用以下补丁。

    --- a/arch/arm64/boot/dts/qcom/<chipset>.dtsi
    +++ b/arch/arm64/boot/dts/qcom/<chipset>.dtsi
    @@ -70,6 +70,7 @@
     		spi13 = &spi13;
     		spi14 = &spi14;
     		spi15 = &spi15;
    +		serial1 = &uart7;
    }; 

    +
    +&uart7 {
    +	status = "ok";
    +}; 
    Copy to clipboard

Note: 必须编译内核配置和设备树更改。编译后的镜像加载到目标以验证接口。有关接口验证的信息，参见 [UART 验证](https://docs.qualcomm.com/doc/80-70014-8Y/topic/uart.html#uart_verification)。

### Boot/aDSP

有关定制的信息，参见 [UART 软件](https://docs.qualcomm.com/doc/80-70014-8Y/topic/uart.html#uart_software)一节。

## UART 定制

Source: [https://docs.qualcomm.com/doc/80-70014-8Y/topic/uart.html](https://docs.qualcomm.com/doc/80-70014-8Y/topic/uart.html)

有关定制 UART 软件的信息，参见 [QUP v3 访问控制定制](https://docs.qualcomm.com/doc/80-70014-8Y/topic/overview-of-wired-interfaces.html#customize-access-control-of-qup)。

## UART 验证

Source: [https://docs.qualcomm.com/doc/80-70014-8Y/topic/uart.html](https://docs.qualcomm.com/doc/80-70014-8Y/topic/uart.html)

本节介绍 UART 驱动程序的验证步骤，以及 Qualcomm 驱动程序的测试结果。

### Linux

要启用 UART 节点，应执行以下操作并进行编译。
1. 要将 UART 状态切换为 OK 并更改特定 UART 节点的别名，应编辑 [https://git.linaro.org/kernel-org/linux-next.git/tree/arch/arm64/boot/dts/qcom/sc7280.dtsi](https://git.linaro.org/kernel-org/linux-next.git/tree/arch/arm64/boot/dts/qcom/sc7280.dtsi) 文件。
Note: 必须启用 SSH shell 或串行控制台才能运行命令并在 SSH shell（控制台）窗口中显示输出。

        aliases {
        i2c0 = &i2c0;
        spi15 = &spi15;
        ++serial1 = &uart7;
        };
        uart7: serial@99c000 {
        compatible = "qcom,geni-uart";
        reg = <0 0x0099c000 0 0x4000>;
        clocks = <&gcc GCC_QUPV3_WRAP0_S7_CLK>;
        clock-names = "se";
        pinctrl-names = "default";
        pinctrl-0 = <&qup_uart7_cts>, <&qup_uart7_rts>, <&qup_uart7_tx>,
        <&qup_uart7_rx>;
        interrupts = <GIC_SPI 608 IRQ_TYPE_LEVEL_HIGH>;
        power-domains = <&rpmhpd SC7280_CX>;
        operating-points-v2 = <&qup_opp_table>;
        interconnects = <&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0
        0>,
        <&gem_noc MASTER_APPSS_PROC 0 &cnoc2 SLAVE_QUP_0 0>;
        interconnect-names = "qup-core", "qup-config";
        ++status = "ok";
        };Copy to clipboard
2. 禁用 qcom\_geni\_serial.c 文件（位于 [https://github.com/torvalds/linux/blob/master/drivers/tty/serial/qcom_geni_serial.c](https://github.com/torvalds/linux/blob/master/drivers/tty/serial/qcom_geni_serial.c)）中的 `if` 条件进行环回测试。

        //if (mctrl & TIOCM_LOOP) // Disabling the if condition for loopback test
        port->loopback = RX_TX_CTS_RTS_SORTED;Copy to clipboard

要在 Linux 内核中验证 QUP v3 UART 注册功能，应确保已向 TTY 层正确注册 UART。

1. 禁用 [https://github.com/torvalds/linux/blob/master/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts](https://github.com/torvalds/linux/blob/master/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts) 中的 UART 默认用例。

        bluetooth: bluetooth {
        
               ++      status = "disabled";
        Copy to clipboard

随即显示以下输出。

        ls /dev/ttyHS1
        /dev/ttyHS1
        dmesg | grep ttyH
        [    3.355487] 99c000.serial: ttyHS1 at MMIO 0x99c000 (irq = 137, base_baud = 0) is a MSMCopy to clipboard
2. 要验证 UART 驱动程序，应进行以下操作：
    1. 进入 SSH shell。有关如何操作 SSH 的更多信息，可访问 [https://docs.qualcomm.com/bundle/publicresource/topics/80-70014-254Y/how_to.html#how-to-ssh-](https://docs.qualcomm.com/bundle/publicresource/topics/80-70014-254Y/how_to.html#how-to-ssh-)。
    2. 注册 UART。

            ls /dev/ttyHSCopy to clipboard

以下为示例输出。

            /lib # ls /dev/ttyHS*
            /dev/ttyHS1
            Copy to clipboard

`ttyHS1` 端口根据为 `serial1 = &uart7` 添加的别名和已启用的串行引擎实例进行映射。

随后将列出在内核中注册的 UART 设备。UART 驱动程序遵循测试步骤来启用环回。

在 DUT 上启用 UART 节点后，运行以下命令来验证 DTSI 文件中启用的 UART 实例。 
Note: 打开两个 shell 或终端以读写 UART 环回的数据。

1. 进入 SSH shell。有关如何操作 SSH 的更多信息，可访问 [https://docs.qualcomm.com/bundle/publicresource/topics/80-70014-254Y/how_to.html#how-to-ssh-](https://docs.qualcomm.com/bundle/publicresource/topics/80-70014-254Y/how_to.html#how-to-ssh-)。
2. 通过 `echo` 命令传输数据。

        echo "This Document Is Very Much Helpful" > /dev/ttyHS1Copy to clipboard
3. 将任何数据转储或读取到 UART 设备节点。

        cat /dev/ttyHS1Copy to clipboard

## UART 调试

Source: [https://docs.qualcomm.com/doc/80-70014-8Y/topic/uart.html](https://docs.qualcomm.com/doc/80-70014-8Y/topic/uart.html)

本节介绍如何启用 UART 软件驱动程序中的调试日志。

### Linux

通过动态调试方法启用 UART 驱动程序日志。在 &lt;workspace\_path\_of\_LINUX\_kernel\_image&gt;\sources\kernel \kernel\_platform\kernel\arch\arm64/configs/qcom\_defconfig 中启用 `CONFIG_DYNAMIC_DEBUG`，以支持内核驱动程序的动态调试。

要在内核日志 (`dmesg`) 中启用和查看 UART 驱动程序日志，应运行以下命令。

    mount -t debugfs none /sys/kernel/debug
    echo -n "file qcom_geni_serial.c +p" > /sys/kernel/debug/dynamic_debug/control
    echo -n "file qcom-geni-se.c +p" > /sys/kernel/debug/dynamic_debug/control
    echo -n "file serial_core.c +p" > /sys/kernel/debug/dynamic_debug/control
    echo -n "file gpi.c +p" > /sys/kernel/debug/dynamic_debug/control
    Copy to clipboard

## UART 示例

Source: [https://docs.qualcomm.com/doc/80-70014-8Y/topic/uart.html](https://docs.qualcomm.com/doc/80-70014-8Y/topic/uart.html)

有关上游设备树参考的信息，可访问 [https://git.linaro.org/kernel-org/linux-next.git/tree/arch/arm64/boot/dts/qcom/sc7280.dtsi](https://git.linaro.org/kernel-org/linux-next.git/tree/arch/arm64/boot/dts/qcom/sc7280.dtsi)。

有关 Qualcomm Linux 芯片产品设备树节点的信息，可访问 [https://git.linaro.org/kernel-org/linux-next.git/tree/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts](https://git.linaro.org/kernel-org/linux-next.git/tree/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts)。

Last Published: Aug 22, 2024

[Previous Topic
入门指南](https://docs.qualcomm.com/bundle/publicresource/80-70014-8Y/topics/get-started.md) [Next Topic
SPI](https://docs.qualcomm.com/bundle/publicresource/80-70014-8Y/topics/spi.md)