标签:
周五在调试CSR8670时遇到一个严重的问题:在xIDE环境下调试时,CSR8670收到MCU发来的数据后都会正常应答。一旦脱机运行,CSR8670与MCU的通信发生异常,具体现象如下:
我们开始检查硬件是否有问题:
对比了Demo板和我们自己电路板的原理图,没发现用来配置UART功能的引脚。主要区别是Demo板用USB供电,我们自己的板子是稳压电源模块供电。
负责MCU端代码的程序猿J回忆起上一版软件在测试时没遇到这个问题。于是程序猿J快速测试了上一版软件,发现了新的现象:
看来旧的软件也存在相同的问题,于是关注点又回到了弄清楚为何在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.
于是我们在离线运行时不移除编程器,发现如下现象:
我们用示波器测量了编程器各个引脚的波形,发现编程器会以固定的时间间隔发送SPI数据给CSR8670。
我和程序猿J整理了不会发生通信异常的条件:
目前市面上很多无线蓝牙耳机类的产品用的都是CSR8670这颗芯片。这些耳机的共同特点是电池供电。
由于电池供电的产品需要在充满一次电后尽量工作较长时间,因此在器件选型和软件设计时都会要求系统尽可能降低电能的消耗。
综上所述,芯片很可能有一个低功耗模式。在低功耗模式下,UART的功能很可能受到了影响。
登录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编程器连接时通信不会异常的原因。
回顾章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被丢掉了。
为了正常接收MCU发来的指令,CSR8670可以选择如下策略中的一种:
用PSTool工具将PSKEY_DEEP_SLEEP_STATE设为0。
用PSTool工具将PSKEY_DEEP_SLEEP_STATE设为1。
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.
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.
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以上再发送命令包。
标签:
原文地址:http://blog.csdn.net/wzz4420381/article/details/51340334