我是
靠谱客的博主
有魅力小猫咪,最近开发中收集的这篇文章主要介绍
高通平台串口调试 AP与模块串口通讯调试总结,觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
1:检查AP端串口配置是否ok:
a:高通平台查看DMA传输:
echo 1 > /sys/kernel/debug/msm_serial_hsl/loopback.0 //打开回环开关
adb shell cat /dev/ttyHSL1
另起窗口
# adb shell
# echo 11111111 > /dev/ttyHSL1
若DMA通道ok,控制台会循环显示;
b:查看uart gpio是否ok:
tx高电平、rfr为低电平,rx,cts为输入;
如果tx为低电平,那么gpio肯定没有配置好,再次检查gpio配置问题;
如果以上2步都ok,那么UART应该ok了,再次检查:
adb shell cat /dev/ttyHSL1
将TX与RX短接;
另起窗口
# adb shell
# echo 11111111 > /dev/ttyHSL1
循环显示那么恭喜UART功能配置好了。
2:Termios参数配置:
影响通讯数据格式的关键
几个参数:
1:波特率-speed,通常
115200,最高4M;
2:奇偶校验-Parity,通
常为None;
3:数据位-Data,通常
8bit;
4:停止位-Stopbits,通
常1bit;
一般情况下默认为115200 8N1,也就是波特率115200,8bit数据位,无奇偶校验,1bit停止位。
为了使得AP可以与模块串口通讯,必须先了解模块的termios设置。
Ap端termios设置:
首先应用打开串口时会设置termios:
- termios.c_cflag &= ~CSIZE;
- termios.c_cflag |= CS8;
- termios.c_cflag &= ~CSTOPB;
- termios.c_cflag &= ~PARENB;
- termios.c_cflag &= ~CBAUD;
- termios.c_cflag |= B3000000;
- termios.c_cflag |= CREAD | CLOCAL;
- termios.c_cflag |= CRTSCTS; /* turn on hardware flow control */
- termios.c_iflag &= ~(IXOFF | IXON | IXANY); /* soft flow control */
驱动接口会根据termios参数来设置底层串口:
以8064 msm_seriel_hs.c为例说明:
uart接口封装:
- static struct uart_ops msm_hs_ops = {
- .tx_empty = msm_hs_tx_empty,
- .set_mctrl = msm_hs_set_mctrl_locked,
- .get_mctrl = msm_hs_get_mctrl_locked,
- .stop_tx = msm_hs_stop_tx_locked,
- .start_tx = msm_hs_start_tx_locked,
- .stop_rx = msm_hs_stop_rx_locked,
- .enable_ms = msm_hs_enable_ms_locked,
- .break_ctl = msm_hs_break_ctl,
- .startup = msm_hs_startup,
- .shutdown = msm_hs_shutdown,
- .set_termios = msm_hs_set_termios,
- .type = msm_hs_type,
- .config_port = msm_hs_config_port,
- .release_port = msm_hs_release_port,
- .request_port = msm_hs_request_port,
- .flush_buffer = msm_hs_flush_buffer_locked,
- };
下面是底层设置函数,上层打开串口,参数未固定的话驱动走的是8N1,底层调试只使用echo或者cat /dev/ttyHSL0时
波特率一律是9600,模块不是9600时那么通讯肯定会失败,所以AP需要根据模块重新设定。
波特率。
//设置termios接口
- /*
- * termios : new ktermios
- * oldtermios: old ktermios previous setting
- *
- * Configure the serial port
- */
- static void msm_hs_set_termios(struct uart_port *uport,
- struct ktermios *termios,
- struct ktermios *oldtermios)
- {
- unsigned int bps;
- unsigned long data;
- unsigned long flags;
- int ret;
- unsigned int c_cflag = termios->c_cflag;
- struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
- mutex_lock(&msm_uport->clk_mutex);
- spin_lock_irqsave(&uport->lock, flags);
- /*
- * Disable Rx channel of UARTDM
- * DMA Rx Stall happens if enqueue and flush of Rx command happens
- * concurrently. Hence before changing the baud rate/protocol
- * configuration and sending flush command to ADM, disable the Rx
- * channel of UARTDM.
- * Note: should not reset the receiver here immediately as it is not
- * suggested to do disable/reset or reset/disable at the same time.
- */
- data = msm_hs_read(uport, UARTDM_DMEN_ADDR);
- data &= ~UARTDM_RX_DM_EN_BMSK;
- msm_hs_write(uport, UARTDM_DMEN_ADDR, data);
- /* 300 is the minimum baud support by the driver */
- bps = uart_get_baud_rate(uport, termios, oldtermios, 200, 4000000);
- /* Temporary remapping 200 BAUD to 3.2 mbps */
- if (bps == 200)
- bps = 3200000;
- uport->uartclk = clk_get_rate(msm_uport->clk);
- if (!uport->uartclk)
- msm_hs_set_std_bps_locked(uport, bps);
- else
- flags = msm_hs_set_bps_locked(uport, bps, flags);//函数里面设置baud;
- data = msm_hs_read(uport, UARTDM_MR2_ADDR);
- data &= ~UARTDM_MR2_PARITY_MODE_BMSK;
- /* set parity */ //设置奇偶校验
- if (PARENB == (c_cflag & PARENB)) {
- if (PARODD == (c_cflag & PARODD)) {
- data |= ODD_PARITY;
- } else if (CMSPAR == (c_cflag & CMSPAR)) {
- data |= SPACE_PARITY;
- } else {
- data |= EVEN_PARITY;
- }
- }
- /* Set bits per char */ //设置数据位
- data &= ~UARTDM_MR2_BITS_PER_CHAR_BMSK;
- switch (c_cflag & CSIZE) {
- case CS5:
- data |= FIVE_BPC;
- break;
- case CS6:
- data |= SIX_BPC;
- break;
- case CS7:
- data |= SEVEN_BPC;
- break;
- default:
- data |= EIGHT_BPC;
- break;
- }
- /* stop bits */ //设置停止位
- if (c_cflag & CSTOPB) {
- data |= STOP_BIT_TWO;
- } else {
- /* otherwise 1 stop bit */
- data |= STOP_BIT_ONE;
- }
- data |= UARTDM_MR2_ERROR_MODE_BMSK;
- /* write parity/bits per char/stop bit configuration */
- msm_hs_write(uport, UARTDM_MR2_ADDR, data);
- /* Configure HW flow control */ //设置是否使用硬件流控
- data = msm_hs_read(uport, UARTDM_MR1_ADDR);
- data &= ~(UARTDM_MR1_CTS_CTL_BMSK |
- UARTDM_MR1_RX_RDY_CTL_BMSK);
- if (c_cflag & CRTSCTS) {
- data |= UARTDM_MR1_CTS_CTL_BMSK;
- data |= UARTDM_MR1_RX_RDY_CTL_BMSK;
- }
- msm_hs_write(uport, UARTDM_MR1_ADDR, data);
- uport->ignore_status_mask = termios->c_iflag & INPCK;
- uport->ignore_status_mask |= termios->c_iflag & IGNPAR;
- uport->ignore_status_mask |= termios->c_iflag & IGNBRK;
- uport->read_status_mask = (termios->c_cflag & CREAD);
- msm_hs_write(uport, UARTDM_IMR_ADDR, 0);
- /* Set Transmit software time out */
- uart_update_timeout(uport, c_cflag, bps);
- msm_hs_write(uport, UARTDM_CR_ADDR, RESET_RX);
- msm_hs_write(uport, UARTDM_CR_ADDR, RESET_TX);
- if (msm_uport->rx.flush == FLUSH_NONE) {
- wake_lock(&msm_uport->rx.wake_lock);
- msm_uport->rx.flush = FLUSH_IGNORE;
- /*
- * Before using dmov APIs make sure that
- * previous writel are completed. Hence
- * dsb requires here.
- */
- mb();
- msm_uport->rx_discard_flush_issued = true;
- /* do discard flush */
- msm_dmov_flush(msm_uport->dma_rx_channel, 0);
- spin_unlock_irqrestore(&uport->lock, flags);
- pr_debug("%s(): wainting for flush completion.n",
- __func__);
- ret = wait_event_timeout(msm_uport->rx.wait,
- msm_uport->rx_discard_flush_issued == false,
- RX_FLUSH_COMPLETE_TIMEOUT);
- if (!ret)
- pr_err("%s(): Discard flush completion pending.n",
- __func__);
- spin_lock_irqsave(&uport->lock, flags);
- }
- msm_hs_write(uport, UARTDM_IMR_ADDR, msm_uport->imr_reg);
- mb();
- spin_unlock_irqrestore(&uport->lock, flags);
- mutex_unlock(&msm_uport->clk_mutex);
- }
3:串口通讯问题总结:
遇见过模块不能响应AP的问题:
1:硬件流控问题,若模块使用了硬件流控,配置rfr与cts,使得模块认为
AP准备好了,可以发送数据了。
2:AP端波特率没有与模块匹配上,要是怀疑AP波特率设置是否ok,可以将串口线连接TX,
设置termios 波特率来看输出是否ok,这种方法还可以测试验证AP端各个波特率是否OK,我使用的
minicon可以验证到460800。
最后
以上就是有魅力小猫咪为你收集整理的高通平台串口调试 AP与模块串口通讯调试总结的全部内容,希望文章能够帮你解决高通平台串口调试 AP与模块串口通讯调试总结所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复