Monday, 10 August 2020 10:55

蓝牙传输介质Transport UART H4(RS232)介绍 Featured

蓝牙Transport就是蓝牙的硬件发送协议,硬件的传输介质有:UART/USB/SDIO,那么Transport就是在特定的硬件传输介质上增加了一些协议,比如我们本节将的H4就是在UART上增加了一个小协议,H4算是最简单的一个协议,只是在数据前面加一个Type,了解过蓝牙HCI的一般都会知道蓝牙协议栈(Host)跟芯片(Controller)一般是通过HCI数据来沟通,那么H4就是在HCI数据前面加上一个TYPE。一共有5中type,如下:

1)HCI COMMAND:由蓝牙协议栈发送给芯片的命令

2)HCI EVENT:由蓝牙芯片上报给蓝牙协议栈的事件

3)HCI ACL:蓝牙协议栈跟蓝牙芯片双向交互的普通数据

4)HCI SCO:蓝牙芯片跟蓝牙协议栈双向交互的通话/语音识别等音频数据

5)HCI ISO(这部分是在core5.2才添加):用于发送LE audio

一. 声明

本专栏文章我们会以连载的方式持续更新,本专栏计划更新内容如下:

第一篇:蓝牙综合介绍 ,主要介绍蓝牙的一些概念,产生背景,发展轨迹,市面蓝牙介绍,以及蓝牙开发板介绍。

第二篇:Transport层介绍,主要介绍蓝牙协议栈跟蓝牙芯片之前的硬件传输协议,比如基于UART的H4,H5,BCSP,基于USB的H2等

第三篇:传统蓝牙controller介绍,主要介绍传统蓝牙芯片的介绍,包括射频层(RF),基带层(baseband),链路管理层(LMP)等

第四篇:传统蓝牙host介绍,主要介绍传统蓝牙的协议栈,比如HCI,L2CAP,SDP,RFCOMM,HFP,SPP,HID,AVDTP,AVCTP,A2DP,AVRCP,OBEX,PBAP,MAP等等一系列的协议吧。

第五篇:低功耗蓝牙controller介绍,主要介绍低功耗蓝牙芯片,包括物理层(PHY),链路层(LL)

第六篇:低功耗蓝牙host介绍,低功耗蓝牙协议栈的介绍,包括HCI,L2CAP,ATT,GATT,SM等

第七篇:蓝牙芯片介绍,主要介绍一些蓝牙芯片的初始化流程,基于HCI vendor command的扩展

第八篇:附录,主要介绍以上常用名词的介绍以及一些特殊流程的介绍等。

另外,开发板如下所示,对于想学习蓝牙协议栈的最好人手一套。以便更好的学习蓝牙协议栈,相信我,学完这一套视频你将拥有修改任何协议栈的能力(比如Linux下的bluez,Android下的bluedroid)。

------------------------------------------------------------------------------------------------------------------------------------------

CSDN学院链接(进入选择你想要学习的课程):undefined

蓝牙交流扣扣群:970324688

Github代码:undefined

入手开发板:undefined

------------------------------------------------------------------------------------------------------------------------------------------
 

二. 前言


首先在介绍以下内容之前,我们先来介绍下我们的CSDN课程,以下介绍内容都会在 CSDN课程 手把手教你蓝牙协议栈入门(点击我)中第二小节介绍。

三. Transport H4介绍

1. 概念介绍

整个Transport在蓝牙架构中的位置如下图红框位置:

蓝牙Transport就是蓝牙的硬件发送协议,硬件的传输介质有:UART/USB/SDIO,那么Transport就是在特定的硬件传输介质上增加了一些协议,比如我们本节将的H4就是在UART上增加了一个小协议,H4算是最简单的一个协议,只是在数据前面加一个Type,了解过蓝牙HCI的一般都会知道蓝牙协议栈(Host)跟芯片(Controller)一般是通过HCI数据来沟通,那么H4就是在HCI数据前面加上一个TYPE。一共有5中type,如下:

1)HCI COMMAND:由蓝牙协议栈发送给芯片的命令

2)HCI EVENT:由蓝牙芯片上报给蓝牙协议栈的事件

3)HCI ACL:蓝牙协议栈跟蓝牙芯片双向交互的普通数据

4)HCI SCO:蓝牙芯片跟蓝牙协议栈双向交互的通话/语音识别等音频数据

5)HCI ISO(这部分是在core5.2才添加):用于发送LE audio

在Core文档截图如下:

交互数据格式为:

所以我们看下代码在这部分的实现:

1)通过宏配置协议栈的TRANSPORT type,可以看到以下代码是配置的H4

/** BT_PBUF_TRANSPORT_H2 = 0x01,BT_PBUF_TRANSPORT_H4 = 0x02,BT_PBUF_TRANSPORT_H5 = 0x03,BT_PBUF_TRANSPORT_BCSP = 0x04,*/

#define BT_TRANSPORT_TYPE 0x02

  1.  

2)举例说明HCI reset发送(HCI raw data为0x03 0x0c 0x00)

err_t hci_reset(void)
{
struct bt_pbuf_t *p;

/* 申请Transport的buffer,比HCI数据多了一个byte */
if((p = bt_pbuf_alloc(BT_TRANSPORT_TYPE, HCI_RESET_PLEN, BT_PBUF_RAM)) == NULL)
{
BT_HCI_TRACE_ERROR("ERROR:file[%s],function[%s],line[%d] bt_pbuf_alloc fail\n",__FILE__,__FUNCTION__,__LINE__);

return BT_ERR_MEM;
}

/* Assembling command packet */
p = hci_cmd_ass(p, HCI_RESET, HCI_HOST_C_N_BB, HCI_RESET_PLEN);
pcb->timer = utimer_create(HCI_RESET_TIMEOUT, hci_reset_timeout, 0);
/* Assembling cmd prameters */

/* 发送HCI raw data在底层处理增加了1个byte */
phybusif_output(p, p->tot_len,PHYBUSIF_PACKET_TYPE_CMD);
bt_pbuf_free(p);

return BT_ERR_OK;
}

3)到了Transport的处理

  1. void phybusif_output(struct bt_pbuf_t *p, uint16_t len,uint8_t packet_type)
    {
    /* 后退1个byte */
    bt_pbuf_header(p, 1);

    /* 填写上type */
    ((uint8_t *)p->payload)[0] = packet_type;


    uint8_t *tx_buffer = bt_get_tx_buffer();
    bt_pbuf_copy_partial(p, tx_buffer, p->tot_len, 0);

    BT_TRANSPORT_TRACE_DEBUG("BT TX LEN:%d\n",p->tot_len);
    bt_hex_dump(tx_buffer,p->tot_len);

    /* 通过UART发送出去 */
    uart_bt_send(tx_buffer,p->tot_len);
    }
     

2. 硬件要求

UART硬件配置要求总结:

1)数据位8bit

2)无奇偶校验

3)停止位1bit

4)需要有硬件流控

所以MCU跟蓝牙芯片的接线需要:

我们来看下代码的实现:

1)在STM32的UART初始化(只贴出关键位置)

/******************************************************************************
* func name : hw_uart_bt_init
* para : baud_rate(IN) --> Baud rate of uart1
* return : hw_uart_bt_init result
* description : Initialization of USART2.PA0->CTS PA1->RTS PA2->TX PA3->RX
******************************************************************************/
uint8_t hw_uart_bt_init(uint32_t baud_rate,uint8_t reconfig)
{
.............
/* Data format :1:8:1, no parity check, hardware flow control */
USART_InitStructure.USART_BaudRate = baud_rate;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_RTS_CTS;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
.........
return BT_ERR_OK;
}

2)在Linux的UART初始化(只贴出关键位置)

  1. uint8_t hw_uart_bt_init(uint32_t baud_rate,uint8_t reconfig)
    {
    ......

    // 8N1
    toptions.c_cflag &= ~CSTOPB;
    toptions.c_cflag |= CS8;

    toptions.c_cflag |= CREAD | CLOCAL | CRTSCTS;
    toptions.c_iflag &= ~(IXON | IXOFF | IXANY);
    toptions.c_cflag &= ~PARENB;

    toptions.c_cc[VMIN] = 1;
    toptions.c_cc[VTIME] = 0;

    .......

    return BT_ERR_OK;

    }
     

3. 纠错

如果主机或主机控制器在 RS232 通信上失去同步,则需要复位。失去同步意味着已检测到错误的 HCI 分组指示器,或 HCI 分组的长度域超出范围。如果在主机到主机控制器的通信中丢失 UART 同步,那么主机控制器将发送硬件故障(HCI hardware error)事件,以将同步错误告诉主机。主机控制器将需要从主机接收一个HCI_RESET 指令以执行复位。主机控制器也将在从主机到主机控制器的字节流中使用 HCI-RESET 指令,以实现重新同步。

如果在从主机控制器到主机的通信中失去 UART 同步,主机将发送 HCL_RESET指令以复位主机控制器。主机也将通过在从主机控制器到主机的字节流中查找HCI_Reset 指令的 HCL 指令完成事件,进行重新同步

Read 19570 times Last modified on Monday, 10 August 2020 15:17

GPS singal acquisition,replay and test equipment

Portable singal acquisition and replay

AI intelligent tongue imager

Tongue imager rafavi
 
Please support our site by viewing this advertisement.

Please support our site by viewing this advertisement

Free Content