CSR8670脱机运行后串口通信异常

1. UART通信异常

1.1. 现象

周五在调试CSR8670时遇到一个严重的问题:在xIDE环境下调试时,CSR8670收到MCU发来的数据后都会正常应答。一旦脱机运行,CSR8670与MCU的通信发生异常,具体现象如下:

  • MCU发送一条x字节的命令给CSR8670,UART task收到的命令的长度不足x字节,最先发送的若干字节丢失
  • MCU以较短间隔发送多条x字节的命令给CSR8670,UART task收到的第一条命令的长度不足x字节,之后每条命令的长度都是x字节

1.2. 检查硬件

我们开始检查硬件是否有问题:

  • 用示波器测量TXD的波形,波形正常。
  • 解析TXD、RXD传输的协议,符合协议。
  • 降低波特率,现象仍存在。
  • 将CSR8670和MCU之间的TXD和RXD直接用飞线连接,并把电路板上的连接断开,现象仍存在。
  • 将软件烧录到CSR的官方Demo板运行,现象消失。

对比了Demo板和我们自己电路板的原理图,没发现用来配置UART功能的引脚。主要区别是Demo板用USB供电,我们自己的板子是稳压电源模块供电。

1.3. 检查软件

负责MCU端代码的程序猿J回忆起上一版软件在测试时没遇到这个问题。于是程序猿J快速测试了上一版软件,发现了新的现象:

  • 新旧版本软件的通信异常的现象相同
  • 一旦CSR8670与手机连接成功,UART通信恢复正常
  • 在CSR8670没有与其他设备建立蓝牙连接的情况下,UART通信异常

1.4. 检查编程器

看来旧的软件也存在相同的问题,于是关注点又回到了弄清楚为何在xIDE环境下调试时都能正常应答。在线调试必须连接USB-SPI编程器,脱机运行不需要连接编程器。

USB-SPI Convert:

Custom firmware, stored in flash memory, takes USB packets containing SPI commands and forwards the commands over SPI. The DSP:

  • serialises the SPI commands
  • uses the PIO pins to create the SPI_MOSI, SPI_CSB and SPI_CLK signals
  • reads the SPI_MISO line

USBSPI automatically reduces the SPI bit rate when it sees SPI data corruption.

Voltage level is set by default to 3.3V.

于是我们在离线运行时不移除编程器,发现如下现象:

  • 连接上USB-SPI编程器,UART通信恢复正常
  • 移除USB-SPI编程器,UART通信发生异常

我们用示波器测量了编程器各个引脚的波形,发现编程器会以固定的时间间隔发送SPI数据给CSR8670。

1.5. 谁是真凶

我和程序猿J整理了不会发生通信异常的条件:

  • USB供电
  • 连接了USB-SPI编程器
  • 手机或其他设备与CSR8670建立了蓝牙链接

目前市面上很多无线蓝牙耳机类的产品用的都是CSR8670这颗芯片。这些耳机的共同特点是电池供电。

由于电池供电的产品需要在充满一次电后尽量工作较长时间,因此在器件选型和软件设计时都会要求系统尽可能降低电能的消耗。

综上所述,芯片很可能有一个低功耗模式。在低功耗模式下,UART的功能很可能受到了影响。

2. 省电模式

登录CSR开发者账户,搜索关键词low power,查询结果中有一篇文章BlueCore Power Saving Mode。

The BlueCore chips have hardware support for two methods of reducing power consumption when the chip is idle:

  • Shallow Sleep: The chip processor’s clock speed is reduced. At best this can reduce current consumption to approximately 2 mA on BlueCore01b, less on BlueCore2 chips. The processor’s speed

    can be restored within a few machine instructions, with a latency that depends on the slowed clock rate.

  • Deep Sleep: Much of the chip’s circuitry is shut down. At best, this can reduce the chip’s current consumption to approximately 100μA on BlueCore01b, less on BlueCore2 chips. However, it takes at least 10 milliseconds to enter Deep Sleep and at least another 10 milliseconds to exit Deep Sleep.

The document describes features specific to BlueCore chips; Bluetooth’s own standard power saving support (Hold, Sniff and Park modes) are mentioned only where they interact with the chip’s power saving modes.

这两种模式的功耗是不一样的。在deep sleep的描述中提到了芯片的多个电路是关闭的,其中可能也包括UART相关的电路。

In Deep Sleep, the processor, the fast (16MHz) clock and much of the digital and analogue hardware are shut down. This has a major effect on power consumption

When the device enters Deep Sleep, it sets an alarm clock (a timed event from a counter that is clocked by the slow clock). The timed event normally wakes the chip, but it can be woken prematurely by activity on the UART or USB.

在deep sleep模式下,芯片每1ms被唤醒一次,也可以被UART或USB激活。

Deep Sleep cannot be used when the chip has a USB host connection and the connection is in its USB “active” state.

这就是Demo板的UART通信不会发生异常的原因。

Once the system is in Deep Sleep, only a limited set of stimuli can rouse it:

  • Expiry of a timer (clocked from the chip’s slow clock)
  • When configured to provide a UART, any activity on the data-receive pin. (Including asserting a break condition, e.g., to force a reboot.)
  • When configured to provide a UART, activity on the CTS line (This is configured with the PS Key PSKEY_DEEP_SLEEP_WAKE_CTS.)
  • BlueCore2-External can be configured to wake on PIO activity
  • When configured to provide a USB host connection, any activity on the data lines
  • Any activity on the chip’s SPI port (pstool.exe relies on this to read and write PS Keys if the chip is in Deep Sleep.)
  • System reboot

SPI口的数据能够激活芯片,这就是USB-SPI编程器连接时通信不会异常的原因。

3. 异常分析

回顾章1.1的现象,为什么会丢失的数据总在前几个字节?

在非Deep Sleep状态下,CSR8670收到MCU的指令后会向UART task提交2次MESSAGE_MORE_DATA。

在Deep Sleep状态下,CSR8670可能只把第2个MESSAGE_MORE_DATA发给UART task,第1个MESSAGE_MORE_DATA被丢掉了。

3. 修复异常

为了正常接收MCU发来的指令,CSR8670可以选择如下策略中的一种:

  • 不使用Deep Sleep
  • 在MCU发来指令前从Deep Sleep唤醒

3.1. 不使用Deep Sleep

用PSTool工具将PSKEY_DEEP_SLEEP_STATE设为0。

3.2. 使用Deep Sleep

用PSTool工具将PSKEY_DEEP_SLEEP_STATE设为1。

3.2.1. 用CTS line上的信号唤醒

The PS Key PSKEY_DEEP_SLEEP_WAKE_CTS (0x23c) can be set to allow a transition on the UART CTS line to wake the host from Deep Sleep; this can provide an alternative to sending a short “wake up” packet.

3.2.2. 用PIO唤醒

The PIO port continues to drive output signals when the chip drops into Deep Sleep.

for a button on a headset, a common technique is to route the button’s signal to an input PIO pin and also to the UART CTS line. Activity on the CTS line can then wake the chip.

3.2.3. 用唤醒包唤醒

The chip is eligible to enter Deep Sleep if there has been no UART traffic from the host for at least one second and if there is no data waiting to be passed to the host.

The “one second” is actually the value of the PS Key PSKEY_UART_SLEEP_TIMEOUT (0x0222).

MCU可以先发送一个唤醒包,发送完毕后等待10ms以上再发送命令包。

时间: 2025-01-19 21:55:09

CSR8670脱机运行后串口通信异常的相关文章

交通信号灯远电力101通讯规约 设备运行数据 透传模块串口通信

方案需求 智慧交通信号控制系统是基于交通大数据的智能自动化应用系统.系统在大数据的基础上,对道路车流量.人流量.路况态势进行判断.智慧交通信号控制系统接入流量检测器.排队长度检测器.速度检测器等,对系统配时方案进行校正和验算.自动控制红绿灯时间,故障情况监测上报,远程人工在线调控红绿灯,为消防车.急救车.警务车等特殊车辆进行预警让道. 系统可根据各车道车流量反馈信息,根据相应算法设置各信号灯时间.控制系统和控制中心相连接,可以实现跨区域交通控制.在遇到救护车.消防车等突发情况下,可以由交警通过无

使用Java实现简单串口通信

最近一门课要求编写一个上位机串口通信工具,我基于Java编写了一个带有图形界面的简单串口通信工具,下面详述一下过程,供大家参考 ^_^ 一: 首先,你需要下载一个额外的支持Java串口通信操作的jar包,由于java.comm比较老了,而且不支持64位系统,这里推荐Rxtx这个jar包(32位/64位均支持). 官方下载地址:http://fizzed.com/oss/rxtx-for-java (注:可能需要FQ才能下载) 不能FQ的童鞋,可以在这里下载: http://files.cnblo

串口通信(基础)

参考文章:http://www.cnblogs.com/aierong/archive/2009/08/21/1551589.html http://www.cnblogs.com/procoder/archive/2009/04/07/1430871.html http://blog.csdn.net/cy757/article/details/4474930 SerialPort Class Windows 7 虚拟串口 VSPD 6 最近总结了串口(COM)读写操作的三种方式:第1种方式是

转:Qt编写串口通信程序全程图文讲解

转载:http://blog.csdn.net/yafeilinux/article/details/4717706  作者:yafeilinux (说明:我们的编程环境是windows xp下,在Qt Creator中进行,如果在Linux下或直接用源码编写,程序稍有不同,请自己改动.) 在Qt中并没有特定的串口控制类,现在大部分人使用的是第三方写的qextserialport类,我们这里也是使用的该类.我们可以去 http://sourceforge.net/projects/qextser

Qt 串口通信

在Qt5之前,串口通信基本依赖于第三方库,下面是我曾接触过的串口通信类库: 名称 语言 平台   QextSerialPort QT C++ Win/Linux http://sourceforge.net/projects/qextserialport/files/ QSerialPort QT C++ QT5已经集成 libserial C++ Linux http://files.cnblogs.com/kyyblabla/libserial-0.5.2.gz.7z 以上串口通信类库通信过

linux下串口通信与管理

linux下的串口与windows有一些区别,下面将介绍一下linux下串口通信管理 查看是否支持USB串口: #lsmod | grep usbserial 如果没有信息:sudo apt-get install setserial 插上USB转串口,在终端输入命令 #dmesg | grep ttyUSB0 如果出现连接成功信息,则说明系统已经识别该设备 一.找到自己的串口设备 查找自己的开发板与电脑的连接的COM口方法 Windows:设备管理器 linux: (1)dmesg #查看带有

Win10 IoT C#开发 3 - UART 串口通信

Windows 10 IoT Core 是微软针对物联网上市场的一个重要产品,既可以开发设备UI与用户交互式操作,又可以控制GPIO等接口,使得原来嵌入式繁琐的开发变得简单.通过Remote Debug功能可以进行断点追踪调试.C#语言本身也有很好的用户基础,相信Win10 IoT 不远的将来会火起来.上个月帮朋友解决了关于Win10 IoT 的一些技术问题,当前也有很多公司在尝试采用Win10 IoT进行开发,可能也会遇到这些问题,相关文档现在还非常少,这里写出来供大家参考.因为要做一个Jav

java下的串口通信-RXTX

关于java实现的串口通信,使用的是开源项目RXTX,之前sun公司也有JCL项目,不过已经很久没有更新了,RXTX项目地址:点击打开,但是两个项目的API用法是一样的,只是导入的包不一样而已.简单的入门可以参照官方的wiki. 对应你的开发环境(Linux.window.Mac)下载对应的文件(下载地址),这里说下具体的安装方法,官方给的有点啰嗦,在Eclipse下使用,下载后里面的文件: RXTXcomm.jar包放到你项目的lib文件夹下,Java Builder Path---->Add

Qt实现串口通信总结

注意: Qt5发布之前,Qt实现串口通信一般是采用第三方类库qextserialport.Qt5发布后自带了QtSerialPort 能够支持串口通信. 1.Qextserialport类介绍 在Qt5之前的版本中并没有特定的串口控制类,现在大部分人使用的是第三方写的qextserialport类,本文章主要是讲解怎样利用此类实现串口通信. 2.文件下载地址: http://sourceforge.net/projects/qextserialport/files/ 3.文件内容:     3.