EFR32BG22的一个应用需要同时使用BLE和串口,而且要求:
- BLE跟手机保持连接。
- 串口能随时接收数据。
- 平均电流小于20 uA。
在Simplicity Studio 5的soc_empty例程基础上,添加EUART软件组件。通常我们串口使用USART模块,但是USART模块不能在低功耗模式EM2下运行。在EFR32xG22上有一个EUART模块,它有高速和低功耗两种模式,低功耗模式可以在EM2下保持运行。在低功耗模式下,它的时钟源可以用LFRCO(内部低频时钟源)或LFXO(外部32768Hz晶体)。由于时钟源的频率较低,所以此时它的波特率最多只能到9600。
EUART组件的配置如下图:
在app.c里添加串口收发的测试代码,主要部分如下:
void uart_callback(struct UARTDRV_HandleData *handle,
Ecode_t transferStatus,
uint8_t *data,
UARTDRV_Count_t transferCount)
{
UARTDRV_Transmit(handle, uart_buf, 1, NULL);
UARTDRV_Receive(handle, uart_buf, 1, uart_callback);
}
SL_WEAK void app_init(void)
{
UARTDRV_Receive(sl_uartdrv_eusart_euart_handle, uart_buf, 1, uart_callback);
}
编译、下载运行,串口收发正常,BLE跟手机连接也正常,貌似一切顺利、岁月静好。燃鹅,没有人替我们负重前行,生活又怎可能让我们如此轻松。
接下来,用Energy Profiler测量运行时的电流,果然就发现问题了:平均电流超过1 mA。怎么回事?赶紧用Debugger跟踪了一下程序,原来是主循环里调用sl_power_manager_sleep()后只进入了EM1模式,没有按预期进入EM2模式。
sl_power_manager_sleep()内部的流程相当复杂,它会检查各个组件的状态和当前允许进入的休眠模式,然后选择其中最浅的休眠模式来进入。这样做可以保证,不会有某个组件因为系统进入休眠模式,而工作不正常。当然,现在可以肯定是EUART组件导致了它不能进EM2,因为在例程的基础上只添加了这个组件。
EUART组件的程序也是写得相当的复杂,里面还使用了DMA组件来做数据的收发。我不想花那么多时间去替Silabs做debug的工作了,决定向他们提交support case请求帮助。
Silabs的technical support程序媛小姐姐服务态度还是挺不错的,复现了我的问题现象以后就给我发消息叫我等她的解决方案。然后,又过了一天,她把解决方法发给了我,需要修改SDK里的驱动程序和IDE工具自动生成的配置,具体如下:
修改gecko_sdk_3.2.3\platform\emdrv\uartdrv\src\uartdrv.c :
修改config\uartdrv_config.h:
按她的方法修改了程序以后,在测量运行电流,底部已经到1 uA左右了,确实进入了EM2。这个问题算是解决了,可是平均电流超过100 uA,还是有点高呀,还要继续设法降低它……