qcom高速串口调试

高通平台 支持通过uart唤醒系统, 前提是使用高速串口驱动,即msm_serial_hs.c ,这个驱动中是将rx配置成

这里简单列下高速串口的配置过程。

打开驱动宏控:

kernel/arch/arm/configs/msm8909-1gb_defconfig

+CONFIG_SERIAL_MSM_HS=y

添加 高速串口配置

修改 kernel/arch/arm/boot/dts/qcom/msm8909.dtsi

+blsp1_uart2:  uart@78b0000  { 
+       compatible  =  "qcom,msm-hsuart-v14"; 
+       reg  =  <0x78b0000  0x200>, 
+             <0x7884000  0x23000>; 
+       reg-names  =  "core_mem",  "bam_mem"; 
+       interrupt-names  =  "core_irq",  "bam_irq",  "wakeup_irq"; 
+       #address-cells  =  <0>; 
+       interrupt-parent  =  <&blsp1_uart2>; 
+       interrupts  =  <0  1  2>; 
+       #interrupt-cells  =  <1>; 
+       interrupt-map-mask  =  <0xffffffff>; 
+       interrupt-map  =  <0  &intc  0  108  0 
+                       1  &intc  0  238  0 
+                       2  &msm_gpio  21  0>; 
+       qcom,bam-tx-ep-pipe-index  =  <2>; 
+       qcom,bam-rx-ep-pipe-index  =  <3>; 
+       qcom,master-id  =  <86>; 
+       clocks  =  <&clock_gcc  clk_gcc_blsp1_uart2_apps_clk>, 
+       <&clock_gcc  clk_gcc_blsp1_ahb_clk>; 
+       clock-names  =  "core_clk",  "iface_clk"; 
+       qcom,msm-bus,name  =  "blsp1_uart"; 
+       qcom,msm-bus,num-cases  =  <2>; 
+       qcom,msm-bus,num-paths  =  <1>; 
+       qcom,msm-bus,vectors-KBps  = 
+       <86  512  0  0>, 
+       <86  512  500  800>; 
+      qcom,rx-char-to-inject = <0xFD>;
+      qcom,inject-rx-on-wakeup;
+       pinctrl-names  =  "sleep",  "default"; 
+       pinctrl-0  =  <&hsuart_sleep>; 
+       pinctrl-1  =  <&hsuart_active>; 
+       status  =  "ok"; 
+}; 

添加pinctrl 配置:

kernel/arch/arm/boot/dts/qcom/msm8909-pinctrl.dtsi

+        blsp1_uart2_active  { 
+               qcom,pins  =  <&gp  20>,  <&gp  21>; 
+               qcom,num-grp-pins  =  <2>; 
+               qcom,pin-func  =  <3>; 
+               label  =  "blsp1_uart2_active"; 
+               hsuart_active:  default  { 
+               drive-strength  =  <16>; 
+               bias-disable; 
+               }; 
+       }; 
+       blsp1_uart2_sleep  { 
+               qcom,pins  =  <&gp  20>,  <&gp  21>; 
+               qcom,num-grp-pins  =  <2>; 
+               qcom,pin-func  =  <0>; 
+               label  =  "blsp1_uart2_sleep"; 
+               hsuart_sleep:  sleep  { 
+               drive-strength  =  <2>; 
+               bias-disable; 
+               }; 
+       }; 

下面简单描述下,uart唤醒系统的实现,在上述的高速串口驱动,有如下的配置选项: 

+        blsp1_uart2_active  { 
+               qcom,pins  =  <&gp  20>,  <&gp  21>; 
+               qcom,num-grp-pins  =  <2>; 
+               qcom,pin-func  =  <3>; 
+               label  =  "blsp1_uart2_active"; 
+               hsuart_active:  default  { 
+               drive-strength  =  <16>; 
+               bias-disable; 
+               }; 
+       }; 
+       blsp1_uart2_sleep  { 
+               qcom,pins  =  <&gp  20>,  <&gp  21>; 
+               qcom,num-grp-pins  =  <2>; 
+               qcom,pin-func  =  <0>; 
+               label  =  "blsp1_uart2_sleep"; 
+               hsuart_sleep:  sleep  { 
+               drive-strength  =  <2>; 
+               bias-disable; 
+               }; 
+       }; 

这里配置了gpio21(rq)可唤醒中断。

qcom,rx-char-to-inject = <0xFD>;

qcom,inject-rx-on-wakeup;

这个配置是在中断触发后,像tty上添加一个字节,内容为 0xfd, 它的作用 后面会做描述:

在驱动中对这个中断的处理:

中断申请:


static int msm_hs_startup(struct uart_port *uport)
{
    if (is_use_low_power_wakeup(msm_uport)) {
        ret = request_threaded_irq(msm_uport->wakeup.irq, NULL,
        msm_hs_wakeup_isr,
        IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
        "msm_hs_wakeup", msm_uport);
        if (unlikely(ret)) {
        MSM_HS_ERR("%s():Err getting uart wakeup_irq\n",
        __func__);
        goto free_uart_irq;
    }

    msm_uport->wakeup.freed = false;
    disable_irq(msm_uport->wakeup.irq);
    msm_uport->wakeup.enabled = false;

    ret = irq_set_irq_wake(msm_uport->wakeup.irq, 1);
    if (unlikely(ret)) {
     MSM_HS_ERR("%s():Err setting wakeup irq\n", __func__);
    goto free_uart_irq;
   }

}

中断处理函数:

static irqreturn_t msm_hs_wakeup_isr(int irq, void *dev)
{
    unsigned int wakeup = 0;
    unsigned long flags;
    struct msm_hs_port *msm_uport = (struct msm_hs_port *)dev;
    struct uart_port *uport = &msm_uport->uport;
    struct tty_struct *tty = NULL;



    msm_hs_resource_vote(msm_uport);
    spin_lock_irqsave(&uport->lock, flags);

    MSM_HS_DBG("%s(): ignore %d\n", __func__,
            msm_uport->wakeup.ignore);
    if (msm_uport->wakeup.ignore)
        msm_uport->wakeup.ignore = 0;
    else
        wakeup = 1;
		/* 这里根据 设备树中是否 设置了qcom,inject-rx-on-wakeup 来决定是否 插入 0xfd 这个字节*/
    if (wakeup) {
        /*
         * Port was clocked off during rx, wake up and
         * optionally inject char into tty rx
         */
        if (msm_uport->wakeup.inject_rx) {
            tty = uport->state->port.tty;
            tty_insert_flip_char(tty->port,
                         msm_uport->wakeup.rx_to_inject,
                         TTY_NORMAL);
            MSM_HS_DBG("%s(): Inject 0x%x", __func__,
                msm_uport->wakeup.rx_to_inject);
        }
    }

    spin_unlock_irqrestore(&uport->lock, flags);
    msm_hs_resource_unvote(msm_uport);

    if (wakeup && msm_uport->wakeup.inject_rx)
        tty_flip_buffer_push(tty->port);
    return IRQ_HANDLED;
}

当RX 上有数据时,有电平变化,会触发中断,在中断处理函数中,可以唤醒系统。  

默认状态下,系统需要休眠时,需要关闭打开的串口进入 suspend状态,这时rx 就是一个可以唤醒系统的gpio;

如果靠从设备发过来的数据来触发中断唤醒系统,这时系统还未打开串口,当前的数据内容一定会丢失,所以在需要唤醒系统前,从设备应当与系统进行简单的握手来确保各自的状态再进行接下来的通讯内容。

高通平台上,默认支持了一种,用于uart蓝牙从设备来唤醒系统的, 默认驱动中添加的 0xfd的作用也是用作次目的。 下面是高通平台 蓝牙从设备与系统的通讯的过程框图。

Wake         - This byte is used to wake up the device which has to receive the data
Wake ack   - This byte is used as an acknowledgement to the wake byte, meaning I am ready to receive
Sleep         - This byte is sent to the other device when it has no data to send

软件逻辑是如此,如果要使用uart唤醒系统,可以借鉴参考这个流程,从设备可编程,与主机通讯握手(可自定义细节)成功后,再收发数据。

 

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值