> ## Documentation Index
> Fetch the complete documentation index at: https://dragonwingdocs.qualcomm.com/llms.txt
> Use this file to discover all available pages before exploring further.

# UART

UART（通用异步收发器）使用起始位和停止位而非时钟信号来异步传输数据。接收端 UART 以称为波特率的特定频率读取数据位。

<img src="https://mintcdn.com/qualcomm-prod/jy6NQT2Y7J_sAxdX/Linux/images/peripheral-interfaces/uart_connection_diagram.png?fit=max&auto=format&n=jy6NQT2Y7J_sAxdX&q=85&s=6b6f9aae1a381ae368928049f015f74e" width="642" height="253" data-path="Linux/images/peripheral-interfaces/uart_connection_diagram.png" />

## 关键参数

* **波特率** —— 通信速率（比特每秒）
* **起始/停止位** —— 帧定界符
* **奇偶校验位** —— 可选的错误检查
* **数据位** —— 每帧 5–9 位
* **流控** —— 通过 CTS/RTS 的硬件握手

<img src="https://mintcdn.com/qualcomm-prod/jy6NQT2Y7J_sAxdX/Linux/images/peripheral-interfaces/uart_data_frame.png?fit=max&auto=format&n=jy6NQT2Y7J_sAxdX&q=85&s=88b18550eeb400ddd30f8bfc9efc6c14" width="995" height="153" data-path="Linux/images/peripheral-interfaces/uart_data_frame.png" />

## 各子系统的传输模式

| 子系统            | 传输模式         | 波特率                                  | 备注           |
| -------------- | ------------ | ------------------------------------ | ------------ |
| **Linux**      | FIFO、CPU DMA | 300 bps – 4 Mbps                     | DMA 非常适合蓝牙模块 |
| **Boot（UEFI）** | 仅 FIFO       | 最高 115200                            | 每字符 5–8 位    |
| **aDSP**       | 仅 FIFO       | 115200、230400、460800、921600、1M、3M、6M | 每字符 5–8 位    |

## 接口组件

### 设备树源文件

| 平台                 | 文件                                     |
| ------------------ | -------------------------------------- |
| Dragonwing IQ-9075 | `arch/arm64/boot/dts/qcom/lemans.dtsi` |

### API

| 子系统   | 头文件                               |
| ----- | --------------------------------- |
| Linux | `include/linux/tty.h`             |
| Boot  | `QcomPkg/Include/HSUart.h`        |
| aDSP  | `adsp_proc/core/api/buses/uart.h` |

## 软件配置

### Linux 设备树示例

**四线 UART（带流控）：**

```dts theme={null}
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>;
    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";
};
```

GPIO pinctrl：

```dts theme={null}
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"; };
```

**QUPAC 访问控制：**

```c theme={null}
// 4-wire HS UART
{ QUPV3_0_SE7, QUPV3_PROTOCOL_UART_4W, QUPV3_MODE_FIFO, AC_HLOS, TRUE, TRUE, FALSE }

// 2-wire UART (no flow control)
{ QUPV3_0_SE5, QUPV3_PROTOCOL_UART_2W, QUPV3_MODE_FIFO, AC_HLOS, TRUE, FALSE, FALSE }
```

## 内核配置

编辑 `kernel_platform/kernel/arch/arm64/configs/qcom_defconfig`：

```
CONFIG_QCOM_GENI_SE=y
CONFIG_SERIAL_QCOM_GENI=y
```

在设备树中启用 UART 节点：

```diff theme={null}
+serial1 = &uart7;

+&uart7 {
+    status = "ok";
+};
```

## 验证

<Steps>
  <Step title="验证 UART 设备注册">
    ```bash theme={null}
    ls /dev/ttyHS*
    # Expected: /dev/ttyHS1

    dmesg | grep ttyH
    # Expected: 99c000.serial: ttyHS1 at MMIO 0x99c000 ...
    ```
  </Step>

  <Step title="配置 UART 设置">
    ```bash theme={null}
    stty -F /dev/ttyHS1 115200
    ```
  </Step>

  <Step title="运行回环测试">
    打开两个 SSH 终端。

    **终端 1（写入）：**

    ```bash theme={null}
    echo "Hello UART" > /dev/ttyHS1
    ```

    **终端 2（读取）：**

    ```bash theme={null}
    cat /dev/ttyHS1
    ```

    预期输出：`Hello UART`
  </Step>
</Steps>

## 调试

### 启用调试日志

```bash theme={null}
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

dmesg | grep -i uart
dmesg | grep ttyHS
```

## 故障排查

<AccordionGroup>
  <Accordion title="未检测到 UART 设备（/dev/ttyHS* 缺失）">
    ```bash theme={null}
    lsmod | grep qcom_geni
    cat /proc/device-tree/soc@0/geniqup@*/serial*/status
    ls -la /dev/tty*
    ```

    * 确认设备树状态为 `"ok"`
    * 确认内核配置中 `CONFIG_SERIAL_QCOM_GENI=y`
    * 检查 GPIO 引脚配置和 QUPAC 访问控制设置
  </Accordion>

  <Accordion title="数据传输失败 / 数据乱码">
    ```bash theme={null}
    # Check current UART config
    stty -F /dev/ttyHS1 -a

    # Set baud rate
    stty -F /dev/ttyHS1 115200

    # Enable/disable hardware flow control
    stty -F /dev/ttyHS1 crtscts    # enable
    stty -F /dev/ttyHS1 -crtscts   # disable
    ```

    * 确认两端波特率一致
    * 检查流控配置（CTS/RTS）
    * 先用回环模式测试
  </Accordion>

  <Accordion title="权限被拒绝">
    ```bash theme={null}
    ls -la /dev/ttyHS*
    usermod -a -G dialout $USER
    ```
  </Accordion>

  <Accordion title="CPU 占用高 / 传输缓慢">
    * 高速传输时从 FIFO 模式切换到 DMA 模式
    * 检查中断统计信息：`cat /proc/interrupts | grep uart`
    * 检查电源管理：`cat /sys/kernel/debug/pm_genpd/pm_genpd_summary`
  </Accordion>
</AccordionGroup>

### 调试检查清单

* [ ] 内核配置包含 `CONFIG_SERIAL_QCOM_GENI=y`
* [ ] UART 节点的设备树状态设为 `"ok"`
* [ ] GPIO 引脚正确配置并映射
* [ ] QUPAC 访问控制配置正确
* [ ] 两端波特率一致
* [ ] 流控设置一致
* [ ] 设备文件权限正确

## 资源

* [Linux 内核设备树绑定](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://docs.kernel.org/admin-guide/serial-console.html)
