1. 前言

有时候因为CYW20819资源不足或者其他原因不能满足产品设计需求,仅想将CYW20819作为一个蓝牙模组来使用,此时主控需要通过HCI接口来控制CYW20819。

HCI接口物理层上可以是UART,SPI或者USB。在应用过程中,我们更加需要去关注HCI命令格式,比如发送什么数据代表什么意思。可以参考 HCI Control Protocol,命令解析代码芯片厂家一般都是做好了的,可以直接拿来用。

本文将介绍通过电脑上位机ClinentControl来控制 CYW20819。

2. ClientControl

ClientControl是赛普拉斯的HCI上位机,通过它可以向DEMO板通过串口发送HCI命令或者升级。

2.1 连接demo板

ClientControl是通过UART控制DEMO板的,选择WICED HCI UART,其他默认。

点击打开Open port。

2.2 发送HCI命令

ClientControl本身将集成了各种各样HCI命令,可以通过界面来操作,在这之前,也要保证DEMO板里面的固件是支持解析HCI命令的。

比如发现附近的BLE 设备,点击Start:

结果:

2.3 升级

选择编译结果里的Hcd文件:


注意CYW20819不支持升级:

3. HCI命令解析

如果将 CYW20819 当做蓝牙模组来使用,那么 CYW20819 需要支持HCI命令解析的功能。官方例子 Audio-20819EVB02 支持该功能。

3.1 开始广播

将该例子编译下载进去,是可以正常跑的,比如通过ClientControl控制DEMO开始广播,通过nRF Connect是可以扫描到的。


3.2 Audio-20819EVB02 打印问题

Audio-20819EVB02例子跑起来的时候串口打印是没有输出的,查了半天没找到问题,最后发现将波特率改小些(改为115200)可以正常运行了。

// wiced_hal_puart_configuration(3000000, PARITY_NONE, STOP_BIT_2);
wiced_hal_puart_configuration(115200, PARITY_NONE, STOP_BIT_2);

4. 代码框架

4.1 HCI串口初始化

const wiced_transport_cfg_t transport_cfg =
{.type = WICED_TRANSPORT_UART,.cfg ={.uart_cfg ={.mode = WICED_TRANSPORT_UART_HCI_MODE,.baud_rate = HCI_UART_DEFAULT_BAUD},},.rx_buff_pool_cfg ={.buffer_size = TRANS_UART_BUFFER_SIZE,.buffer_count = WICED_TRANSPORT_BUFFER_COUNT},.p_status_handler = hci_control_transport_status,.p_data_handler = hci_control_proc_rx_cmd,.p_tx_complete_cback = hci_control_transport_tx_cplt_cback};

可以看到除了初始化UART外设之后,这个结构体里面还包括三个回调函数:

  • hci_control_transport_status (外设状态回调)
  • hci_control_proc_rx_cmd (命令接收)
  • hci_control_transport_tx_cplt_cback (发送完成回调)

我们主要关注hci_control_proc_rx_cmd,这个接口是对上位机发过来的命令进行解析。

4.2 hci_control_proc_rx_cmd

该函数是 HCI Control Protocol 的部分实践。

/** Handle received command over UART. Please refer to the WICED Smart Ready* Software User Manual (WICED-Smart-Ready-SWUM100-R) for details on the* HCI UART control protocol.*/
static uint32_t hci_control_proc_rx_cmd(uint8_t *p_buffer, uint32_t length)
{uint16_t opcode;uint16_t payload_len;uint8_t *p_data = p_buffer;uint8_t buffer_processed = WICED_TRUE;if (!p_buffer){return HCI_CONTROL_STATUS_INVALID_ARGS;}// Expected minimum 4 byte as the wiced headerif ((length < 4) || (p_data == NULL)){WICED_BT_TRACE("invalid params\n");wiced_transport_free_buffer(p_buffer);return HCI_CONTROL_STATUS_INVALID_ARGS;}STREAM_TO_UINT16(opcode, p_data);      // Get OpCodeSTREAM_TO_UINT16(payload_len, p_data); // Gen Payload LengthWICED_BT_TRACE("cmd_opcode 0x%02x\n", opcode);switch ((opcode >> 8) & 0xff){case HCI_CONTROL_GROUP_DEVICE:hci_control_device_handle_command(opcode, p_data, payload_len);break;#if (WICED_APP_LE_INCLUDED == WICED_TRUE)case HCI_CONTROL_GROUP_LE:case HCI_CONTROL_GROUP_GATT:hci_control_le_handle_command(opcode, p_data, payload_len);break;
#endif#if (WICED_APP_AUDIO_SRC_INCLUDED == WICED_TRUE)case HCI_CONTROL_GROUP_AUDIO:hci_control_audio_handle_command(opcode, p_data, payload_len);break;
#endif
#if (WICED_APP_AUDIO_RC_TG_INCLUDED == WICED_TRUE)case HCI_CONTROL_GROUP_AVRC_TARGET:hci_control_avrc_handle_command(opcode, p_data, payload_len);break;
#endifcase HCI_CONTROL_GROUP_AVRC_CONTROLLER:
#if (WICED_APP_AUDIO_RC_TG_INCLUDED == WICED_TRUE)if ((avrcp_profile_role == AVRCP_TARGET_ROLE) &&(hci_control_rc_target_is_connected())){hci_control_avrc_handle_command(opcode, p_data, payload_len);}else{#endif
#if (WICED_APP_LE_SLAVE_CLIENT_INCLUDED == WICED_TRUE)if (wiced_bt_ams_client_connection_check()){hci_control_ams_handle_command(opcode, p_data, payload_len);}else
#endif
#if (WICED_APP_AUDIO_RC_CT_INCLUDED == WICED_TRUE){hci_control_avrc_handle_ctrlr_command(opcode, p_data, payload_len);}}
#endifbreak;#if (WICED_APP_TEST_INCLUDED == WICED_TRUE)case HCI_CONTROL_GROUP_TEST:hci_control_test_handle_command(opcode, p_data, payload_len);break;
#endif#if (WICED_APP_ANCS_INCLUDED == WICED_TRUE)case HCI_CONTROL_GROUP_ANCS:hci_control_ancs_handle_command(opcode, p_data, payload_len);break;
#endif#if (WICED_APP_HFP_AG_INCLUDED == WICED_TRUE)case HCI_CONTROL_GROUP_AG:hci_control_ag_handle_command(opcode, p_data, payload_len);break;
#endifcase HCI_CONTROL_GROUP_MISC:hci_control_misc_handle_command(opcode, p_data, payload_len);break;default:WICED_BT_TRACE("unknown class code (opcode:%x)\n", opcode);break;}if (buffer_processed){// Freeing the buffer in which data is receivedwiced_transport_free_buffer(p_buffer);}return HCI_CONTROL_STATUS_SUCCESS;
}

5. 写在最后

本文介绍了HCI接口的实现以及使用ClientControl控制通过HCI接口控制DEMO,本质上是 HCI Control Protocol 的实践。

【CYW20819】六、HCI接口控制相关推荐

  1. 物联网开发笔记(80)- 使用Micropython开发ESP32开发板之通过IIC接口控制TM1650四位共阴数码管模块

    一.目的 这一节我们学习如何使用我们的ESP32开发板来通过IIC接口控制TM1650四位共阴数码管模块.  二.环境 ESP32 + Thonny + TM1650四位共阴数码管模块 + 几根杜邦线 ...

  2. 物联网开发笔记(60)- 使用Micropython开发ESP32开发板之SPI接口控制Micro SD卡TF卡模块

    一.目的 这一节我们学习如何使用我们的ESP32开发板来通过SPI接口控制Micro SD卡TF卡模块. 二.环境 ESP32 + SPI接口控制Micro SD卡TF卡模块 + Thonny IDE ...

  3. SimpleFOC之ESP32(六)—— 双电机控制

    目录 说明 一.硬件介绍 1.1.原理图 1.2.ESP32drive-D方案 1.2.1.准备清单 1.2.2.硬件连接 1.3.SimpleFOCShield方案 1.3.1.SimpleFOCS ...

  4. 物联网开发笔记(96)- Micropython ESP32开发之SPI接口控制Micro SD卡TF卡模块挂载内存卡

    一.目的 这一节我们学习如何使用乐鑫的ESP32开发板连接SD卡模块,进行目录.文件的相关操作. 在早前我们也介绍过TFT SD卡的操作,这里我们重新复习一下. 物联网开发笔记(60)- 使用Micr ...

  5. Delphi面向对象学习随笔六:接口

    Delphi面向对象学习随笔六:接口   Delphi面向对象学习随笔六:接口 作者:巴哈姆特 (转载请注明出处并保持完整) 在对象化中,类的继承是一个非常强大的机制:而更加强大的继承机制应该是来自从 ...

  6. iOS开发Swift篇—(六)流程控制

    iOS开发Swift篇-(六)流程控制 一.swift中的流程控制 Swift支持的流程结构如下: 循环结构:for.for-in.while.do-while 选择结构:if.switch 注意:这 ...

  7. CoreJava 笔记总结-第六章 接口、lambda表达式与内部类

    文章目录 第六章 接口.lambda表达式与内部类 ==接口== 接口的概念 接口的属性 接口与抽象类 静态和私有方法 默认方法 解决默认方法冲突 接口与回调 `Comparator`接口 对象克隆 ...

  8. 【Java】 第六章 接口、lambda 表达式与内部类 Java核心技术卷1基础知识原书第10版 读书笔记

    第六章 接口.lambda表达式与内部类 6. 接口.lambda 表达式与内部类 6.1 接口 6.1.1 接口概念 6.1.2 接口的特性 6.1.3 接口与抽象类 6.1.4 静态方法 6.1. ...

  9. Java从入门到精通十六(函数式接口编程)

    Java从入门到精通十六(函数式接口)

最新文章

  1. 浅析「扣减库存」的方案设计
  2. Spark源码分析之九:内存管理模型
  3. Java之Number类
  4. JSP、Servlet、Tomcat、JDK、J2EE版本比较
  5. getch, getche, getchar 转
  6. win7 python2.7安装PIL库
  7. (4)理解 neutron ml2---port创建流程代码解析
  8. python大漠插件多开_[求助,]用python调用大漠插件,注册好后调用出错.完全不会了...
  9. IDL where函数与array_indices函数
  10. java实用教程第五版_java2实用教程(第5版)重要点及遗漏点(一)
  11. word中正文分栏重新换页问题
  12. MTK 6737 android6.0 user版本打开root权限(adb root权限和 apk root权限)
  13. 4.12 使用反相命令反转图片色彩 [原创Ps教程]
  14. 微信小程序中的添加收获地址的流程
  15. 3种侧链压缩方法让音乐鼓点更有力—FL Studio教程
  16. remote: HTTP Basic: Access denied的解决方法
  17. 计算机内存智能清理系统好些,告诉你电脑内存怎么清理
  18. Android 原生 TabLayout 使用全解析
  19. 学业计算机水平考试试题,信息技术学业水平考试试题
  20. 医院患者监护系统的定义与可行性分析

热门文章

  1. 原创超简单代码(1.15)
  2. IT6263,IT6264是一颗LVDS TO HDMI的桥接芯片
  3. Android之检测GPS服务和定位权限是否开启
  4. OTL电路与BTL电路有什么不同?
  5. 树莓派64位系统官方下载Debian
  6. Kubelet 中的 “PLEG is not healthy” 到底是个什么鬼?
  7. img srcset sizes 的作用
  8. LDA文本主题模型的学习笔记
  9. HTML5期末大作业:仿商城网站设计—— 绿色特产商城购物Html+Css+javascript的网页制作
  10. 《程序员羊皮卷》还未上市即告售罄的故事