这篇文章本来是和基于Blinker的ESP8266+CC2541蓝牙接入以及其他一起写的,只是后来有点事情耽误了,所以这篇在后面才发出来,主要是写了hidKbdM-用于CC2541的HID键盘和鼠标固件,CC2541得和Arduino正确连接,并加上USB Host Shield(MAX3421EEHJ+),实现将USB键盘,鼠标转换至蓝牙。实质上是做了(暂未实践)分析使用ESP32将有线键盘转换为蓝牙无线键盘中的实践工作。
实物是这样的,到处都有售,不带运费的价格通常已经在10元以内了,相当的便宜了。

IMG_20191208_172119.webp

IMG_20191208_172128.webp

还有其他的官方好玩的案例:
TI 德州仪器 SimpleLink SensorTag 小众测评

前提工作

有一些注意事项:

  1. 底板 3.3V LDO,输入电压 3.6~6V,输入电压禁止超过 7V!
  2. 接口电平 3.3V,可以直接连接各种单片机(51,AVR,PIC,ARM,MSP430 等),5V 单片机也可直接连接,无需 MAX232 也不能经过 MAX232!

在开始下面的烧写工作前,还需要做的就是把接口引出来,方便调试和使用。

文档里面写了引脚的图:

QQ20191208-155934@2x.webp

QQ20191208-160006@2x.webp

QQ20191208-160016@2x.webp

我们需要引出的是7,8,11。差不多就像是下面这样:

IMG_20200112_153543.webp

后来我觉得那样容易掉下来,我又改成这样了:看自己的实际情况吧,怎么方便就怎么弄。

IMG_20200112_170317.webp

然后你得有TTL的转换设备,并注意TTL的电平电压问题。可以使用Arduino或者ESP8266的软串口。

#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX 配置10、11为软串口

还得要有开发环境TI cc2541协议栈开发环境的搭建
IAR Embedded Workbench for 8051 v9.20 和BLE-stack v1.4.2

都准备得差不多了,就可以开始了。

hidKbdM-用于CC2541的HID键盘和鼠标固件

在BLE-STACK中,有HIDEmuKbd例程,已经解决了大量我们会遇到的问题。扫清了很多的障碍,工程本身可以作为键盘连接安卓,苹果设备,但是这还是不够我们的需要,我们需要键盘和鼠标都可以进行模拟。所以有了另外的一个开源项目:ramadc/cc254x-hidKbdM,就是标题中的用于CC2541的HID键盘和鼠标固件。
文档里面已经包含了很多的信息了,但是似乎并不够。

如果你不想安装IAR,也不想捣鼓代码,那么可以使用编译好的固件,预构建的固件作为HEX文件包含在CC2540DB和CC2541DB的bin文件夹中。由于现在大多数HM-10模块都使用CC2541,因此CC2540的固件编译已停止。但是,由于它们共享相同的代码库,因此您可以自己编译固件。编译的固件包括:

  • HM-10_CC254x_DisplayOnly.hex:早期版本,即将更新。(5/8/2014)-已过时
  • HM-10_CC254x_KeyboardOnly.hex:早期版本,即将更新(5/8/2014)-已过时
  • HM-10_CC2541_Experimental.hex:支持命令模式和转换模式的固件。密码000000.(23/12/2014)

下面是我对文档的一些补充说明:

文档里面说的波特率并不是9600 bps的速率发送,是57600。
来着另外一个论坛的教程,Turning HM-10, HM-11 into Bluetooth HID modules,提到了:

Mind that it's originally really quiet, to check it out after uploading use serial monitor from Arduino IDE. Use standard RX/TX pins (from the module, aka voltage dividing board) via USB-TTL adapter. Connect at 57600 with 'Newline' (README.md mentions 9600 but it's bollocks, it's 57600 in the code). It is in command mode by default. Try commands S,S and S,A, it's the only commands that output something (SLEEP and ACTIVE accordingly). Then pair it wirelessly and enter command mode: type $$$+enter and then any string (I used 123+enter, it should type 123).

在代码里面也有说到:

  // configure UART
  uartConfig.configured           = TRUE;
  uartConfig.baudRate             = HAL_UART_BR_57600;
  uartConfig.flowControl          = HAL_UART_FLOW_OFF;
  uartConfig.flowControlThreshold = 0;
  uartConfig.rx.maxBufSize        = 20;
  uartConfig.tx.maxBufSize        = 128;
  uartConfig.idleTimeout          = 0;
  uartConfig.intEnable            = TRUE;
  uartConfig.callBackFunc         = (halUARTCBack_t)uartCallback;
  //uartConfig.callBackFunc         = NULL;

还具有的功能就是可以进行一定的指令操作:
使用$$$则切换为:translate mode
使用@@@则切换为:command mode

在command模式才可以进行下面的一些指令操作!
在translate 模式下,设备会自动将ASCII字符转换为HID密钥代码,并模拟按下和释放的键。当前所覆盖的字符仅限于前128个ASCII字符。其他键(例如F1-F12,PrintScreen等)只能在命令模式下发送。

20200112225828.webp

在命令模式下,设备解析主机发送的命令,后跟CR或LF字符(rn)(换行)。下面列出了一些命令供参考:
同时注意符号为英文的符号。

KU [value]:释放具有与HID密钥代码相对应的8位值的密钥
KD [value]:按下一个与HID键码相对应的8位值的键
M[status][X][Y][Z]:发送鼠标按钮和鼠标坐标
KUPDATE:将报告发送给主机
S,R:重置设备
S,DC:与主机断开连接
SN,[value]:更改扫描响应数据的字符串和设备名称。[值]的长度必须少于20个字符。重新启动设备以查看更改。

有些指令操作后会有响应提示,如修改广播的名字SN,cyqsd ,会返回:

Name is being set, reset to set new name

除了上面的在文档里面的指令,还有几条在代码注释里面的,我也一并粘贴上来了。

//Buffer being processed stored in rxBuffer, does not include CRLF
/*
Command sets, chosen options need to be stored in non-volatile memory
- SC,<value>  + set connection mode of device
+ <value> is a single digit number
+ 1 Do not auto-connect to last paired, 2 auto-connect to last paired
- SN,<value>  + set device name
+ <value> device's new name
- S,R Reset the device
- S,ID print ID of module
- S,N print the current Bluetooth name
- S,D Set device to be discoverable
- S,DC  Disconnect device from host
*/

更多的信息可以直接看协议栈的代码,本文在后面的合并代码的小节中展示了一些。

CCLoader

在上一个小节中,我们使用了一个叫hidKbdM的开源项目,得到了用于烧写的hex文件,那么肯定要烧写到CC2541里面才可以使用啊,一般情况下:捣鼓CC25X系列的玩意得要有个CC Debugger 蓝牙zigbee仿真器,没有的话可以用万能的Arduino来代替,将Arduino刷入CCLoader即可。(和IOS上面的越狱控制中心同名)。需要注意的是CCLoader只能写入.bin文件,而SmartRF Flash Programmer只能写入hex文件,你可以将hex文件和容易的转换为bin文件,但是反之,可能会需要地址。在上一节中可以直接使用hex文件进行转换,然后用本节的CCLoader写入也可以到后文中的手动合并项目将IAR的输出文件类型修改为bin,然后用CCLoader写入。、

CCLoader使用开源项目RedBearLab/CCLoader

issues并不多,但是似乎提到的问题我都遇到了
Error message : waiting for response from arduino. #6
ESP8266 Support #16

我使用的是标准的Arduino Uno,直接写入就好。

20200112161310.webp

引脚要注意检查一下,是不是相同。

// Debug control pins & the indicate LED
int DD = 6;
int DC = 5;
int RESET = 4;
int LED = 13;

连接的线路和前面的准备工作差不多,只是这次是连接的Arduino Uno,在使用Arduino为ATmega 328P烧写Bootloader,就进行了类似的操作。

使用CCLoader的时候还得注意一下,只能用COM1-16,不能再多了,因为代码里面是下面这样写的:

char comports[16][20]={"\\\\.\\COM1",  "\\\\.\\COM2",  "\\\\.\\COM3",  "\\\\.\\COM4",
                       "\\\\.\\COM5",  "\\\\.\\COM6",  "\\\\.\\COM7",  "\\\\.\\COM8",
                       "\\\\.\\COM9",  "\\\\.\\COM10", "\\\\.\\COM11", "\\\\.\\COM12",
                       "\\\\.\\COM13", "\\\\.\\COM14", "\\\\.\\COM15", "\\\\.\\COM16"};

如下所示将三根线连接到Arduino:
具体的连接可以看道瑞X-doria KidFit儿童手环CC2541二次开发,里面已经写了如何接线。

  • DEBUG_DATA DD->针脚6
  • DEBUG_CLOCK DC->针脚5
  • RESET_N->引脚4

220621437c10.webp

现在将CCLoader上传到Arduino。

打开命令行并输入:

cd <CCLoader所在的目录>

Windows:

CCLoader.exe <COM Port> <Firmware.bin> 0

最后一个参数,如果是Arduino Uno就是0,Arduino Leonardo或者其他为1.
大概像是下面这样:

C:\Users\cyqsd\Desktop>CCloader.exe 3 CC2541hm10v550.bin 0

Mac的话:

./ccloader /dev/ttyUSB0 CC2541hm10v550.bin 0

可能需要几分钟来上传。不过可能为这样:

Enable transmission...
Request sent already!
/********************************************************************/
* If there is no respond last for 3s, please press "Ctrl+C" to exit!
* And pay attention to :
*   1. The connection between computer and Arduino;
*   2. The connection between Arduino and CC2540;
*   3. Whether the device you using is Leonardo or not;
*   4. Other unexpected errors.
/********************************************************************/

Waiting for respond from Arduino...

No chip detected!
Upload Failed!
File closed!
Comport closed!

检查一下线路连接,或者其他问题。
正常应该是这样:

C:\Users\Administrator\Desktop>CCLoader.exe 3 HidEmuKbd.bin 0
Copyright (c) 2013 RedBearLab.com
CCLoader.exe version 0.5
Comport : COM3
Bin file: HidEmuKbd.bin
Device  : Default (e.g. UNO)

Comport open!
<Baud:115200> <data:8> <parity:none> <stopbit:1> <DTR:off> <RTS:off>

File open!
!!WARNING: File's size isn't the integer multiples of 512 bytes, and
           the last block will be filled in up to 512 bytes with 0xFF!
Block total: 224

Enable transmission...
Request sent already!
/********************************************************************/
* If there is no respond last for 3s, please press "Ctrl+C" to exit!
* And pay attention to :
*   1. The connection between computer and Arduino;
*   2. The connection between Arduino and CC2540;
*   3. Whether the device you using is Leonardo or not;
*   4. Other unexpected errors.
/********************************************************************/

Waiting for respond from Arduino...

Uploading firmware...

1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  21  22  2
3  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40  41  42  4
3  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60  61  62  6
3  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80  81  82  8
3  84  85  86  87  88  89  90  91  92  93  94  95  96  97  98  99  100  101  102
  103  104  105  106  107  108  109  110  111  112  113  114  115  116  117  118
  119  120  121  122  123  124  125  126  127  128  129  130  131  132  133  134
  135  136  137  138  139  140  141  142  143  144  145  146  147  148  149  150
  151  152  153  154  155  156  157  158  159  160  161  162  163  164  165  166
  167  168  169  170  171  172  173  174  175  176  177  178  179  180  181  182
  183  184  185  186  187  188  189  190  191  192  193  194  195  196  197  198
  199  200  201  202  203  204  205  206  207  208  209  210  211  212  213  214
  215  216  217  218  219  220  221  222  223  224  Upload successfully!
File closed!
Comport closed!

20200112212405.webp

20200112212537.webp

不过还是有WARNING,这是因为:

Remain = fsize % 512;    
if(Remain != 0)
{
    BlkTot = fsize / 512 + 1;
    printf("!!WARNING: File's size isn't the integer multiples of 512 bytes, and \n");
    printf("           the last block will be filled in up to 512 bytes with 0xFF! \n");
}
else
{
    BlkTot = fsize / 512;
}
printf("Block total: %d\n\n", BlkTot);

理论上讲还是没有问题的。

手动合并项目

因为开源协议和版权的问题Github上面的开源代码, 并没有整合协议栈,我们如果想要自己对代码进行修改,进行重新编译,就需要手动将两个项目合并一下。
截至目前BLE-STACK的最新版本是:v1.5.1,对于我们来说太新了。
BLE-STACK是符合CC2540/CC2541的Bluetooth 5.0,使用的Bluetooth 4.0定义的功能与以前的1.4.x版本相同。
我们停留在4.X就好了,总比高功耗的2.X好,如:HC-05。
在cc254x-hidKbdM项目中使用的是IAR Embedded Workbench for 8051 v9.20 和BLE-stack v1.4.2。我们尽量相同。
下面步骤的截图我就偷懒了,我用的上次手环的截图,因为是一样的,就是版本不同了。对了,官网只有最新版,旧版本只能去第三方网站下载。

20191006163943.png

20191006163933.png

20191006165301.png

20191006165312.png

20191006165353.png

先是找到目录,比如我安装在了:

D:\Texas Instruments\BLE-CC254x-1.4.2.2

然后再进入:

D:\Texas Instruments\BLE-CC254x-1.4.2.2\Projects\ble

将项目文件ramadc/cc254x-hidKbdM下载并解压至上面的目录,看起来像是这样:

D:\Texas Instruments\BLE-CC254x-1.4.2.2\Projects\ble\cc254x-hidKbdM-master

然后找到cc254x-hidKbdM-master\CC2541DB\HIDKbdMouse.eww,就是使用IAR的正常步骤。
通过左边的目录树找到hiddev.h这个文件:

20200112171357.webp

加上下面的两行。

#include "bcomdef.h"
#include "gatt.h"

差不多是这样:

20200112160739.webp

还要设置一下Debugger为烧写设备。

20200113022847.webp

将参数HAL_UART_ISR设置为:HAL_UART_ISR=2。我的已经设置为2了,打开检查一下就是了,不然串口会不正常。

20200113022906.webp

代码里面是这样写的:

/*
Setting up UART
- To use UART, HAL_UART=TRUE, preferrably POWER_SAVING is not enabled
- To use interrupts, HAL_UART_ISR = (1 or 2), HAL_UART_DMA=FALSE
- To use DMA, HAL_UART_ISR = 0, HAL_UART_DMA = (1 or 2)

+ HAL_UART_ISR = 1: Use USART 0
+ HAL_UART_ISR = 2: Use USART 1

Set PERCFG.UxCFG to choose alternative 1 or 2

For keyfob, USART 0 alt. 1 is being used:
- HAL_UART_ISR = 1
For HM-10, USART 1 alt. 2 is being used:
- HAL_UART_ISR = 2
For HM-11, RX on P0.2, TX on P0.3 => USART 0 alt. 1 is being used:
- HAL_UART_ISR = 1
*/

然后编译,调试,或者导出HEX,或者导出HEX转换为Bin,用CCLoader写进去。

20200112160632.webp

20200112160758.webp

下面是额外的说明:

这里需要说的是使用德州仪器自带的HIDEmuKbd案例,你可以使用这个案例来尝试设备。与前面的步骤相同,唯一的就是如果想要正常搜索到设备,只需要修改:

uint8 initial_advertising_enable = FALSE;

改为TRUE,则可以正常搜索到。

在hidKbdM项目中的hidKbdMouse.c。预置了很多信息,可以观察一下,有兴趣也可以直接看代码研究。

static uint8 default_scanData[] =
{
  0x15,                             // length of this data => (name's size = 20 bytes) + 1
  GAP_ADTYPE_LOCAL_NAME_COMPLETE,   // AD Type = Complete local name
  'H',
  'I',
  'D',
  ' ',
  'K',
  'e',
  'y',
  'b',
  'o',
  'a',
  'r',
  'd',
  ' ',
  '&',
  ' ',
  'M',
  'o',
  'u',
  's',
  'e'
};

将一些信息抛出可以方便调试:

20200113003247.webp

Host must send S,S\n to put device into sleep every time.
UART at 57600, no flow

一些需要注意的配置:

// TRUE if boot mouse enabled
static uint8 hidBootMouseEnabled = FALSE;

实际使用

我尝试了不同的设备,
在我的Macbook上面使用没有问题,只是搜索连接的时候没有显示广播名。连接以后没有问题。

截屏2020-01-13上午1.03.22.webp

安卓上面时而能搜索到,时而不能,如果搜索并连接上,使用还是没有问题的。

Screenshot_20200113-003004.webp

这个还是使用的hidKbdM例程,只是我把广播名字改了。

Screenshot_20200113-002553.webp

Windows7是使用的CSR8510 A10的USB蓝牙,只能支持到蓝牙4.0,既不能搜索到,也当然不能连接上。问题不大,反正只是测试。
,具体可以看高通-CSR8510 Chipset

20200113013313.webp

将CC2541恢复为HM-10

这个小标题其实可以专门另开一篇文章了,这一小节讲的是如果不玩CC2541了,只是想让他成为一个普通的AT固件的设备,我们怎么恢复呢?因为原来的AT-09的固件锁了Debug的接口,再想要往里面写东西就需要擦除了在写进去。但是找不到AT-09原厂的AT固件。HM-10与其类似,也可以通用。

当提取的时候会提示:

CC2541 - ID0058: Debug interface locked! (Erase chip to unlock it)

这一节看了arduino论坛上的一篇文章。如何在CC2541上烧写正版HM-10固件(从CC41制作正版HM-10):
Topic: How to flash genuine HM-10 firmware on CC2541 (make genuine HM-10 from CC41)

事实上,我在前面的尝试过程中遇到的情况和我开始想的有些不同,在CCLoader一小节中我也已经提到了,我刷入了很多个bin文件进行了尝试,比如CC2541hm10v540.bin,这个就是正常的,然后Demo.bin和还有一些根本就只是灯微亮。

他们多次提到了这个网址,http://www.jnhuamao.cn/download_rom_en.asp?id=66#,显然这是一家中国公司个国外网页,提供技术支持下载,其中就包含了各种模块升级用的bin文件。可以使用CCLoader进行烧录,理论上也是可行的,我也尝试了。
官方是提供了一个串口烧录bootloader的工具,将板子的TTL连接到电脑进行烧写,不过需要已经有他们的固件,并且调试至升级模式。有一个HowToUpgradeFirmware_en.pdf
需要连接到波特率9600, N, 8,1。
输入AT+SBLUP
会响应OK+SBLUP。这就进入了upgrade模式,就可以使用官方的升级工具了。

20200112222814.webp

理论上Projects\ble\util\SBL\iar\cc254x\sbl.eww这个也是可行的,这个我就暂时没有去尝试了,因为有CC Debugger了,直接烧写Hex。

所幸的是再看楼主帖子后面的回复中看到了有朋友想要提取出来的完整的Hex文件想进行恢复,直接可以用SmartRF Flash Programmer进行烧录,我不就是想要这个吗。
后面就有热心的网友,果然贴出来了。
文件名为:
HM-10v604_full_with_bootloader.hex

硬件上没有问题的话,烧录进去应该是正常的,最起码串口。不过我的无法搜索到蓝牙,还可以执行恢复出厂的AT指令-恢复默认设置(Renew)

发送指令

AT+RENEW 

然后应答

OK+RENEW

再看的时候就是正常的了。

IMG_20200113_012341.webp

IMG_20200113_012330.webp

下面引用了AT指令文档的一些信息,因为有的可能只是普通的CC2541刷的HM-10的固件。

  1. LED指示蓝牙连接状态,闪烁表示没有蓝牙连接,常亮表示蓝牙已连接并打开了端口,STATE脚输出高电平为已连接,其他状态为低电平。
  2. 设置模块为主模式:模块已经为软件设置主从模式,通过串口发送 AT+ROLE1(回车或者加rn),返回OK,则表示设置成功,此时模块 LED 灯进入快闪。主模块连接从模块需要通过 AT 指令进行连接(详情请参照 BT05 AT指令集)。

QQ20191208-160033@2x.webp

NRF51822

隔壁的nRF51822也可以做类似的工作,有空的话可以折腾,我就暂时不去折腾了。
Re: [Updated] Wireless GH60

本文从2019-10-13甚至更早就断断续续的开始写了,直到现在才发布出来。写博客这个工作贵在坚持了。接下来可能就不会再接着写CC2541了,可能是nRF51822或者其他的了,ESP8266和CC2541都将会暂时告一段落,不继续折腾了。亦或是写Hadoop,Spark,Storm了。

文章目录